UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

272 lines 10.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.addSuffixToEntriesKeys = addSuffixToEntriesKeys; exports.findMatches = findMatches; exports.selectMergeMethod = selectMergeMethod; exports.mergeMatched = mergeMatched; exports.checkMatchFieldsInput = checkMatchFieldsInput; exports.checkInput = checkInput; exports.addSourceField = addSourceField; const assign_1 = __importDefault(require("lodash/assign")); const assignWith_1 = __importDefault(require("lodash/assignWith")); const get_1 = __importDefault(require("lodash/get")); const merge_1 = __importDefault(require("lodash/merge")); const mergeWith_1 = __importDefault(require("lodash/mergeWith")); const errors_1 = require("@n8n/errors"); const utilities_1 = require("../../../utils/utilities"); function addSuffixToEntriesKeys(data, suffix) { return data.map((entry) => { const json = {}; Object.keys(entry.json).forEach((key) => { json[`${key}_${suffix}`] = entry.json[key]; }); return { ...entry, json }; }); } function findAllMatches(data, lookup, disableDotNotation, isEntriesEqual) { return data.reduce((acc, entry2, i) => { if (entry2 === undefined) return acc; for (const key of Object.keys(lookup)) { const excpectedValue = lookup[key]; let entry2FieldValue; if (disableDotNotation) { entry2FieldValue = entry2.json[key]; } else { entry2FieldValue = (0, get_1.default)(entry2.json, key); } if (!isEntriesEqual(excpectedValue, entry2FieldValue)) { return acc; } } return acc.concat({ entry: entry2, index: i, }); }, []); } function findFirstMatch(data, lookup, disableDotNotation, isEntriesEqual) { const index = data.findIndex((entry2) => { if (entry2 === undefined) return false; for (const key of Object.keys(lookup)) { const excpectedValue = lookup[key]; let entry2FieldValue; if (disableDotNotation) { entry2FieldValue = entry2.json[key]; } else { entry2FieldValue = (0, get_1.default)(entry2.json, key); } if (!isEntriesEqual(excpectedValue, entry2FieldValue)) { return false; } } return true; }); if (index === -1) return []; return [{ entry: data[index], index }]; } function findMatches(input1, input2, fieldsToMatch, options) { const data1 = [...input1]; const data2 = [...input2]; const isEntriesEqual = (0, utilities_1.fuzzyCompare)(options.fuzzyCompare); const disableDotNotation = options.disableDotNotation || false; const multipleMatches = options.multipleMatches || 'all'; const filteredData = { matched: [], matched2: [], unmatched1: [], unmatched2: [], }; const matchedInInput2 = new Set(); matchesLoop: for (const entry1 of data1) { const lookup = {}; fieldsToMatch.forEach((matchCase) => { let valueToCompare; if (disableDotNotation) { valueToCompare = entry1.json[matchCase.field1]; } else { valueToCompare = (0, get_1.default)(entry1.json, matchCase.field1); } lookup[matchCase.field2] = valueToCompare; }); for (const fieldValue of Object.values(lookup)) { if (fieldValue === undefined) { filteredData.unmatched1.push(entry1); continue matchesLoop; } } const foundedMatches = multipleMatches === 'all' ? findAllMatches(data2, lookup, disableDotNotation, isEntriesEqual) : findFirstMatch(data2, lookup, disableDotNotation, isEntriesEqual); const matches = foundedMatches.map((match) => match.entry); foundedMatches.map((match) => matchedInInput2.add(match.index)); if (matches.length) { if (options.outputDataFrom === 'both' || options.joinMode === 'enrichInput1' || options.joinMode === 'enrichInput2') { matches.forEach((match) => { filteredData.matched.push({ entry: entry1, matches: [match], }); }); } else { filteredData.matched.push({ entry: entry1, matches, }); } } else { filteredData.unmatched1.push(entry1); } } data2.forEach((entry, i) => { if (matchedInInput2.has(i)) { filteredData.matched2.push(entry); } else { filteredData.unmatched2.push(entry); } }); return filteredData; } function selectMergeMethod(clashResolveOptions) { const mergeMode = clashResolveOptions.mergeMode; if (clashResolveOptions.overrideEmpty) { function customizer(targetValue, srcValue) { if (srcValue === undefined || srcValue === null || srcValue === '') { return targetValue; } } if (mergeMode === 'deepMerge') { return (target, ...source) => { const targetCopy = Object.assign({}, target); return (0, mergeWith_1.default)(targetCopy, ...source, customizer); }; } if (mergeMode === 'shallowMerge') { return (target, ...source) => { const targetCopy = Object.assign({}, target); return (0, assignWith_1.default)(targetCopy, ...source, customizer); }; } } else { if (mergeMode === 'deepMerge') { return (target, ...source) => (0, merge_1.default)({}, target, ...source); } if (mergeMode === 'shallowMerge') { return (target, ...source) => (0, assign_1.default)({}, target, ...source); } } return (target, ...source) => (0, merge_1.default)({}, target, ...source); } function mergeMatched(matched, clashResolveOptions, joinMode) { const returnData = []; let resolveClash = clashResolveOptions.resolveClash; const mergeIntoSingleObject = selectMergeMethod(clashResolveOptions); for (const match of matched) { let { entry, matches } = match; let json = {}; let binary = {}; let pairedItem = []; if (resolveClash === 'addSuffix') { const suffix1 = '1'; const suffix2 = '2'; [entry] = addSuffixToEntriesKeys([entry], suffix1); matches = addSuffixToEntriesKeys(matches, suffix2); json = mergeIntoSingleObject({ ...entry.json }, ...matches.map((item) => item.json)); binary = mergeIntoSingleObject({ ...entry.binary }, ...matches.map((item) => item.binary)); pairedItem = [ ...(0, utilities_1.preparePairedItemDataArray)(entry.pairedItem), ...matches.map((item) => (0, utilities_1.preparePairedItemDataArray)(item.pairedItem)).flat(), ]; } else { const preferInput1 = 'preferInput1'; const preferInput2 = 'preferInput2'; if (resolveClash === undefined) { if (joinMode !== 'enrichInput2') { resolveClash = 'preferInput2'; } else { resolveClash = 'preferInput1'; } } if (resolveClash === preferInput1) { const [firstMatch, ...restMatches] = matches; json = mergeIntoSingleObject({ ...firstMatch.json }, ...restMatches.map((item) => item.json), entry.json); binary = mergeIntoSingleObject({ ...firstMatch.binary }, ...restMatches.map((item) => item.binary), entry.binary); pairedItem = [ ...(0, utilities_1.preparePairedItemDataArray)(firstMatch.pairedItem), ...restMatches.map((item) => (0, utilities_1.preparePairedItemDataArray)(item.pairedItem)).flat(), ...(0, utilities_1.preparePairedItemDataArray)(entry.pairedItem), ]; } if (resolveClash === preferInput2) { json = mergeIntoSingleObject({ ...entry.json }, ...matches.map((item) => item.json)); binary = mergeIntoSingleObject({ ...entry.binary }, ...matches.map((item) => item.binary)); pairedItem = [ ...(0, utilities_1.preparePairedItemDataArray)(entry.pairedItem), ...matches.map((item) => (0, utilities_1.preparePairedItemDataArray)(item.pairedItem)).flat(), ]; } } returnData.push({ json, binary, pairedItem, }); } return returnData; } function checkMatchFieldsInput(data) { if (data.length === 1 && data[0].field1 === '' && data[0].field2 === '') { throw new errors_1.ApplicationError('You need to define at least one pair of fields in "Fields to Match" to match on', { level: 'warning' }); } for (const [index, pair] of data.entries()) { if (pair.field1 === '' || pair.field2 === '') { throw new errors_1.ApplicationError(`You need to define both fields in "Fields to Match" for pair ${index + 1}, field 1 = '${pair.field1}' field 2 = '${pair.field2}'`, { level: 'warning' }); } } return data; } function checkInput(input, fields, disableDotNotation, inputLabel) { for (const field of fields) { const isPresent = (input || []).some((entry) => { if (disableDotNotation) { return entry.json.hasOwnProperty(field); } return (0, get_1.default)(entry.json, field, undefined) !== undefined; }); if (!isPresent) { throw new errors_1.ApplicationError(`Field '${field}' is not present in any of items in '${inputLabel}'`, { level: 'warning' }); } } return input; } function addSourceField(data, sourceField) { return data.map((entry) => { const json = { ...entry.json, _source: sourceField, }; return { ...entry, json, }; }); } //# sourceMappingURL=utils.js.map