UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

207 lines 8.22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.description = void 0; exports.execute = execute; const get_1 = __importDefault(require("lodash/get")); const isEqual_1 = __importDefault(require("lodash/isEqual")); const lt_1 = __importDefault(require("lodash/lt")); const pick_1 = __importDefault(require("lodash/pick")); const n8n_workflow_1 = require("n8n-workflow"); const utilities_1 = require("../../../../../utils/utilities"); const utils_1 = require("../../helpers/utils"); const common_descriptions_1 = require("../common.descriptions"); const properties = [ { displayName: 'Compare', name: 'compare', type: 'options', options: [ { name: 'All Fields', value: 'allFields', }, { name: 'All Fields Except', value: 'allFieldsExcept', }, { name: 'Selected Fields', value: 'selectedFields', }, ], default: 'allFields', description: 'The fields of the input items to compare to see if they are the same', }, { displayName: 'Fields To Exclude', name: 'fieldsToExclude', type: 'string', placeholder: 'e.g. email, name', requiresDataPath: 'multiple', description: 'Fields in the input to exclude from the comparison', default: '', displayOptions: { show: { compare: ['allFieldsExcept'], }, }, }, { displayName: 'Fields To Compare', name: 'fieldsToCompare', type: 'string', placeholder: 'e.g. email, name', requiresDataPath: 'multiple', description: 'Fields in the input to add to the comparison', default: '', displayOptions: { show: { compare: ['selectedFields'], }, }, }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add Field', default: {}, displayOptions: { show: { compare: ['allFieldsExcept', 'selectedFields'], }, }, options: [ common_descriptions_1.disableDotNotationBoolean, { displayName: 'Remove Other Fields', name: 'removeOtherFields', type: 'boolean', default: false, description: 'Whether to remove any fields that are not being compared. If disabled, will keep the values from the first of the duplicates.', }, ], }, ]; const displayOptions = { show: { resource: ['itemList'], operation: ['removeDuplicates'], }, }; exports.description = (0, utilities_1.updateDisplayOptions)(displayOptions, properties); async function execute(items) { const compare = this.getNodeParameter('compare', 0); const disableDotNotation = this.getNodeParameter('options.disableDotNotation', 0, false); const removeOtherFields = this.getNodeParameter('options.removeOtherFields', 0, false); const nodeVersion = this.getNode().typeVersion; let keys = disableDotNotation ? Object.keys(items[0].json) : Object.keys((0, utilities_1.flattenKeys)(items[0].json)); for (const item of items) { for (const key of disableDotNotation ? Object.keys(item.json) : Object.keys((0, utilities_1.flattenKeys)(item.json))) { if (!keys.includes(key)) { keys.push(key); } } } if (compare === 'allFieldsExcept') { const fieldsToExclude = (0, utils_1.prepareFieldsArray)(this.getNodeParameter('fieldsToExclude', 0, ''), 'Fields To Exclude'); if (!fieldsToExclude.length) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No fields specified. Please add a field to exclude from comparison'); } if (!disableDotNotation) { keys = Object.keys((0, utilities_1.flattenKeys)(items[0].json)); } keys = keys.filter((key) => !fieldsToExclude.includes(key)); } if (compare === 'selectedFields') { const fieldsToCompare = (0, utils_1.prepareFieldsArray)(this.getNodeParameter('fieldsToCompare', 0, ''), 'Fields To Compare'); if (!fieldsToCompare.length) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No fields specified. Please add a field to compare on'); } if (!disableDotNotation) { keys = Object.keys((0, utilities_1.flattenKeys)(items[0].json)); } keys = fieldsToCompare.map((key) => key.trim()); } // This solution is O(nlogn) // add original index to the items const newItems = items.map((item, index) => ({ json: { ...item.json, __INDEX: index }, pairedItem: { item: index }, })); //sort items using the compare keys newItems.sort((a, b) => { let result = 0; for (const key of keys) { const a_value = disableDotNotation ? a.json[key] : (0, get_1.default)(a.json, key); const b_value = disableDotNotation ? b.json[key] : (0, get_1.default)(b.json, key); if (nodeVersion >= 3.1) { const a_value_tnum = (0, utils_1.typeToNumber)(a_value); const b_value_tnum = (0, utils_1.typeToNumber)(b_value); if (a_value_tnum !== b_value_tnum) { result = a_value_tnum - b_value_tnum; break; } } const equal = (0, isEqual_1.default)(a_value, b_value); if (!equal) { const lessThan = (0, lt_1.default)(a_value, b_value); result = lessThan ? -1 : 1; break; } } return result; }); for (const key of keys) { let type = undefined; for (const item of newItems) { if (key === '') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Name of field to compare is blank'); } const value = !disableDotNotation ? (0, get_1.default)(item.json, key) : item.json[key]; if (value === undefined && disableDotNotation && key.includes('.')) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `'${key}' field is missing from some input items`, { description: "If you're trying to use a nested field, make sure you turn off 'disable dot notation' in the node options", }); } else if (value === undefined) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `'${key}' field is missing from some input items`); } if (nodeVersion < 3.1 && type !== undefined && value !== undefined && type !== typeof value) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `'${key}' isn't always the same type`, { description: 'The type of this field varies between items', }); } else { type = typeof value; } } } // collect the original indexes of items to be removed const removedIndexes = []; let temp = newItems[0]; for (let index = 1; index < newItems.length; index++) { if ((0, utilities_1.compareItems)(newItems[index], temp, keys, disableDotNotation)) { removedIndexes.push(newItems[index].json.__INDEX); } else { temp = newItems[index]; } } let returnData = items.filter((_, index) => !removedIndexes.includes(index)); if (removeOtherFields) { returnData = returnData.map((item, index) => ({ json: (0, pick_1.default)(item.json, ...keys), pairedItem: { item: index }, })); } return returnData; } //# sourceMappingURL=removeDuplicates.operation.js.map