n8n-nodes-base
Version:
Base nodes of n8n
272 lines • 10.7 kB
JavaScript
;
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