first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.compareDatasets",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Core Nodes"],
|
||||
"resources": {
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.comparedatasets/"
|
||||
}
|
||||
],
|
||||
"generic": [
|
||||
{
|
||||
"label": "How to synchronize data between two systems (one-way vs. two-way sync",
|
||||
"icon": "🏬",
|
||||
"url": "https://n8n.io/blog/how-to-sync-data-between-two-systems/"
|
||||
},
|
||||
{
|
||||
"label": "Supercharging your conference registration process with n8n",
|
||||
"icon": "🎫",
|
||||
"url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/"
|
||||
},
|
||||
{
|
||||
"label": "Migrating Community Metrics to Orbit using n8n",
|
||||
"icon": "📈",
|
||||
"url": "https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/"
|
||||
},
|
||||
{
|
||||
"label": "Build your own virtual assistant with n8n: A step by step guide",
|
||||
"icon": "👦",
|
||||
"url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/"
|
||||
},
|
||||
{
|
||||
"label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n ",
|
||||
"icon": "🙌",
|
||||
"url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/"
|
||||
},
|
||||
{
|
||||
"label": "7 no-code workflow automations for Amazon Web Services",
|
||||
"url": "https://n8n.io/blog/aws-workflow-automation/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"alias": ["Join", "Concatenate", "Compare", "Dataset", "Split", "Sync", "Syncing"],
|
||||
"subcategories": {
|
||||
"Core Nodes": ["Flow"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
import {
|
||||
type IExecuteFunctions,
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeType,
|
||||
type INodeTypeDescription,
|
||||
NodeConnectionTypes,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
checkInput,
|
||||
checkInputAndThrowError,
|
||||
checkMatchFieldsInput,
|
||||
findMatches,
|
||||
} from './GenericFunctions';
|
||||
|
||||
export class CompareDatasets implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Compare Datasets',
|
||||
name: 'compareDatasets',
|
||||
icon: 'file:compare.svg',
|
||||
group: ['transform'],
|
||||
version: [1, 2, 2.1, 2.2, 2.3],
|
||||
description: 'Compare two inputs for changes',
|
||||
defaults: { name: 'Compare Datasets' },
|
||||
|
||||
inputs: [NodeConnectionTypes.Main, NodeConnectionTypes.Main],
|
||||
inputNames: ['Input A', 'Input B'],
|
||||
requiredInputs: 1,
|
||||
|
||||
outputs: [
|
||||
NodeConnectionTypes.Main,
|
||||
NodeConnectionTypes.Main,
|
||||
NodeConnectionTypes.Main,
|
||||
NodeConnectionTypes.Main,
|
||||
],
|
||||
outputNames: ['In A only', 'Same', 'Different', 'In B only'],
|
||||
properties: [
|
||||
{
|
||||
displayName:
|
||||
'Items from different branches are paired together when the fields below match. If paired, the rest of the fields are compared to determine whether the items are the same or different',
|
||||
name: 'infoBox',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Fields to Match',
|
||||
name: 'mergeByFields',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Fields to Match',
|
||||
default: { values: [{ field1: '', field2: '' }] },
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Values',
|
||||
name: 'values',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Input A Field',
|
||||
name: 'field1',
|
||||
type: 'string',
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||
placeholder: 'e.g. id',
|
||||
hint: ' Enter the field name as text',
|
||||
requiresDataPath: 'single',
|
||||
},
|
||||
{
|
||||
displayName: 'Input B Field',
|
||||
name: 'field2',
|
||||
type: 'string',
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||
placeholder: 'e.g. id',
|
||||
hint: ' Enter the field name as text',
|
||||
requiresDataPath: 'single',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'When There Are Differences',
|
||||
name: 'resolve',
|
||||
type: 'options',
|
||||
default: 'preferInput2',
|
||||
options: [
|
||||
{
|
||||
name: 'Use Input A Version',
|
||||
value: 'preferInput1',
|
||||
},
|
||||
{
|
||||
name: 'Use Input B Version',
|
||||
value: 'preferInput2',
|
||||
},
|
||||
{
|
||||
name: 'Use a Mix of Versions',
|
||||
value: 'mix',
|
||||
description: 'Output uses different inputs for different fields',
|
||||
},
|
||||
{
|
||||
name: 'Include Both Versions',
|
||||
value: 'includeBoth',
|
||||
description: 'Output contains all data (but structure more complex)',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [1, 2],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'When There Are Differences',
|
||||
name: 'resolve',
|
||||
type: 'options',
|
||||
default: 'includeBoth',
|
||||
options: [
|
||||
{
|
||||
name: 'Use Input A Version',
|
||||
value: 'preferInput1',
|
||||
},
|
||||
{
|
||||
name: 'Use Input B Version',
|
||||
value: 'preferInput2',
|
||||
},
|
||||
{
|
||||
name: 'Use a Mix of Versions',
|
||||
value: 'mix',
|
||||
description: 'Output uses different inputs for different fields',
|
||||
},
|
||||
{
|
||||
name: 'Include Both Versions',
|
||||
value: 'includeBoth',
|
||||
description: 'Output contains all data (but structure more complex)',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
hide: {
|
||||
'@version': [1, 2],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Fuzzy Compare',
|
||||
name: 'fuzzyCompare',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
"Whether to tolerate small type differences when comparing fields. E.g. the number 3 and the string '3' are treated as the same.",
|
||||
displayOptions: {
|
||||
hide: {
|
||||
'@version': [1],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Prefer',
|
||||
name: 'preferWhenMix',
|
||||
type: 'options',
|
||||
default: 'input1',
|
||||
options: [
|
||||
{
|
||||
name: 'Input A Version',
|
||||
value: 'input1',
|
||||
},
|
||||
{
|
||||
name: 'Input B Version',
|
||||
value: 'input2',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resolve: ['mix'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'For Everything Except',
|
||||
name: 'exceptWhenMix',
|
||||
type: 'string',
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||
placeholder: 'e.g. id, country',
|
||||
hint: 'Enter the names of the input fields as text, separated by commas',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resolve: ['mix'],
|
||||
},
|
||||
},
|
||||
requiresDataPath: 'multiple',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add option',
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Fields to Skip Comparing',
|
||||
name: 'skipFields',
|
||||
type: 'string',
|
||||
default: '',
|
||||
placeholder: 'e.g. updated_at, updated_by',
|
||||
hint: 'Enter the field names as text, separated by commas',
|
||||
description:
|
||||
"Fields that shouldn't be included when checking whether two items are the same",
|
||||
requiresDataPath: 'multiple',
|
||||
},
|
||||
{
|
||||
displayName: 'Fuzzy Compare',
|
||||
name: 'fuzzyCompare',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
"Whether to tolerate small type differences when comparing fields. E.g. the number 3 and the string '3' are treated as the same.",
|
||||
displayOptions: {
|
||||
show: {
|
||||
'@version': [1],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Disable Dot Notation',
|
||||
name: 'disableDotNotation',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether to disallow referencing child fields using `parent.child` in the field name',
|
||||
},
|
||||
{
|
||||
displayName: 'Multiple Matches',
|
||||
name: 'multipleMatches',
|
||||
type: 'options',
|
||||
default: 'first',
|
||||
options: [
|
||||
{
|
||||
name: 'Include First Match Only',
|
||||
value: 'first',
|
||||
description: 'Only ever output a single item per match',
|
||||
},
|
||||
{
|
||||
name: 'Include All Matches',
|
||||
value: 'all',
|
||||
description: 'Output multiple items if there are multiple matches',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const matchFields = checkMatchFieldsInput(
|
||||
this.getNodeParameter('mergeByFields.values', 0, []) as IDataObject[],
|
||||
);
|
||||
|
||||
const options = this.getNodeParameter('options', 0, {});
|
||||
|
||||
options.nodeVersion = this.getNode().typeVersion;
|
||||
|
||||
if (options.nodeVersion >= 2) {
|
||||
options.fuzzyCompare = this.getNodeParameter('fuzzyCompare', 0, false) as boolean;
|
||||
}
|
||||
|
||||
let input1 = this.getInputData(0);
|
||||
let input2 = this.getInputData(1);
|
||||
if (options.nodeVersion < 2.2) {
|
||||
input1 = checkInputAndThrowError(
|
||||
input1,
|
||||
matchFields.map((pair) => pair.field1),
|
||||
(options.disableDotNotation as boolean) || false,
|
||||
'Input A',
|
||||
);
|
||||
|
||||
input2 = checkInputAndThrowError(
|
||||
input2,
|
||||
matchFields.map((pair) => pair.field2),
|
||||
(options.disableDotNotation as boolean) || false,
|
||||
'Input B',
|
||||
);
|
||||
} else {
|
||||
input1 = checkInput(input1);
|
||||
input2 = checkInput(input2);
|
||||
}
|
||||
|
||||
const resolve = this.getNodeParameter('resolve', 0, '') as string;
|
||||
options.resolve = resolve;
|
||||
|
||||
if (resolve === 'mix') {
|
||||
options.preferWhenMix = this.getNodeParameter('preferWhenMix', 0, '') as string;
|
||||
options.exceptWhenMix = this.getNodeParameter('exceptWhenMix', 0, '') as string;
|
||||
}
|
||||
|
||||
const matches = findMatches(input1, input2, matchFields, options);
|
||||
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import difference from 'lodash/difference';
|
||||
import get from 'lodash/get';
|
||||
import intersection from 'lodash/intersection';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import omit from 'lodash/omit';
|
||||
import set from 'lodash/set';
|
||||
import union from 'lodash/union';
|
||||
import unset from 'lodash/unset';
|
||||
import { ApplicationError, type IDataObject, type INodeExecutionData } from 'n8n-workflow';
|
||||
|
||||
import { fuzzyCompare, preparePairedItemDataArray } from '@utils/utilities';
|
||||
|
||||
type PairToMatch = {
|
||||
field1: string;
|
||||
field2: string;
|
||||
};
|
||||
|
||||
type EntryMatches = {
|
||||
entry: INodeExecutionData;
|
||||
matches: INodeExecutionData[];
|
||||
};
|
||||
|
||||
type CompareFunction = <T, U>(a: T, b: U) => boolean;
|
||||
|
||||
const processNullishValueFunction = (version: number) => {
|
||||
if (version >= 2) {
|
||||
return <T>(value: T) => (value === undefined ? null : value);
|
||||
}
|
||||
return <T>(value: T) => value || null;
|
||||
};
|
||||
|
||||
function compareItems(
|
||||
item1: INodeExecutionData,
|
||||
item2: INodeExecutionData,
|
||||
fieldsToMatch: PairToMatch[],
|
||||
options: IDataObject,
|
||||
skipFields: string[],
|
||||
isEntriesEqual: CompareFunction,
|
||||
) {
|
||||
const keys = {} as IDataObject;
|
||||
fieldsToMatch.forEach((field) => {
|
||||
keys[field.field1] = item1.json[field.field1];
|
||||
});
|
||||
|
||||
const keys1 = Object.keys(item1.json);
|
||||
const keys2 = Object.keys(item2.json);
|
||||
const allUniqueKeys = union(keys1, keys2);
|
||||
|
||||
let keysToCompare;
|
||||
if (options.fuzzyCompare && (options.nodeVersion as number) >= 2.1) {
|
||||
keysToCompare = allUniqueKeys;
|
||||
} else {
|
||||
keysToCompare = intersection(keys1, keys2);
|
||||
}
|
||||
|
||||
const same = keysToCompare.reduce((acc, key) => {
|
||||
if (isEntriesEqual(item1.json[key], item2.json[key])) {
|
||||
acc[key] = item1.json[key];
|
||||
}
|
||||
return acc;
|
||||
}, {} as IDataObject);
|
||||
|
||||
const sameKeys = Object.keys(same);
|
||||
const differentKeys = difference(allUniqueKeys, sameKeys);
|
||||
|
||||
const different: IDataObject = {};
|
||||
const skipped: IDataObject = {};
|
||||
|
||||
differentKeys.forEach((key, i) => {
|
||||
const processNullishValue = processNullishValueFunction(options.nodeVersion as number);
|
||||
|
||||
switch (options.resolve) {
|
||||
case 'preferInput1':
|
||||
different[key] = processNullishValue(item1.json[key]);
|
||||
break;
|
||||
case 'preferInput2':
|
||||
different[key] = processNullishValue(item2.json[key]);
|
||||
break;
|
||||
default:
|
||||
let input1 = processNullishValue(item1.json[key]);
|
||||
let input2 = processNullishValue(item2.json[key]);
|
||||
|
||||
let [firstInputName, secondInputName] = ['input1', 'input2'];
|
||||
if ((options.nodeVersion as number) >= 2) {
|
||||
[firstInputName, secondInputName] = ['inputA', 'inputB'];
|
||||
}
|
||||
|
||||
if (
|
||||
(options.nodeVersion as number) >= 2.1 &&
|
||||
!options.disableDotNotation &&
|
||||
!skipFields.some((field) => field === key)
|
||||
) {
|
||||
const skippedFieldsWithDotNotation = skipFields.filter(
|
||||
(field) => field.startsWith(key) && field.includes('.'),
|
||||
);
|
||||
|
||||
input1 = cloneDeep(input1);
|
||||
input2 = cloneDeep(input2);
|
||||
|
||||
if (
|
||||
skippedFieldsWithDotNotation.length &&
|
||||
(typeof input1 !== 'object' || typeof input2 !== 'object')
|
||||
) {
|
||||
throw new ApplicationError(
|
||||
`The field \'${key}\' in item ${i} is not an object. It is not possible to use dot notation.`,
|
||||
{ level: 'warning' },
|
||||
);
|
||||
}
|
||||
|
||||
if (skipped[key] === undefined && skippedFieldsWithDotNotation.length) {
|
||||
skipped[key] = { [firstInputName]: {}, [secondInputName]: {} };
|
||||
}
|
||||
|
||||
for (const skippedField of skippedFieldsWithDotNotation) {
|
||||
const nestedField = skippedField.replace(`${key}.`, '');
|
||||
set(
|
||||
(skipped[key] as IDataObject)[firstInputName] as IDataObject,
|
||||
nestedField,
|
||||
get(input1, nestedField),
|
||||
);
|
||||
set(
|
||||
(skipped[key] as IDataObject)[secondInputName] as IDataObject,
|
||||
nestedField,
|
||||
get(input2, nestedField),
|
||||
);
|
||||
|
||||
unset(input1, nestedField);
|
||||
unset(input2, nestedField);
|
||||
}
|
||||
|
||||
different[key] = { [firstInputName]: input1, [secondInputName]: input2 };
|
||||
} else {
|
||||
if (skipFields.includes(key)) {
|
||||
skipped[key] = { [firstInputName]: input1, [secondInputName]: input2 };
|
||||
} else {
|
||||
different[key] = { [firstInputName]: input1, [secondInputName]: input2 };
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
json: { keys, same, different, ...(!isEmpty(skipped) && { skipped }) },
|
||||
pairedItem: [
|
||||
...preparePairedItemDataArray(item1.pairedItem),
|
||||
...preparePairedItemDataArray(item2.pairedItem),
|
||||
],
|
||||
} as INodeExecutionData;
|
||||
}
|
||||
|
||||
function combineItems(
|
||||
item1: INodeExecutionData,
|
||||
item2: INodeExecutionData,
|
||||
prefer: string,
|
||||
except: string,
|
||||
disableDotNotation: boolean,
|
||||
) {
|
||||
let exceptFields: string[];
|
||||
const [entry, match] = prefer === 'input1' ? [item1, item2] : [item2, item1];
|
||||
|
||||
if (except && Array.isArray(except) && except.length) {
|
||||
exceptFields = except;
|
||||
} else {
|
||||
exceptFields = except ? except.split(',').map((field) => field.trim()) : [];
|
||||
}
|
||||
|
||||
exceptFields.forEach((field) => {
|
||||
entry.json[field] = match.json[field];
|
||||
if (disableDotNotation) {
|
||||
entry.json[field] = match.json[field];
|
||||
} else {
|
||||
const value = get(match.json, field) || null;
|
||||
set(entry, ['json', field], value);
|
||||
}
|
||||
});
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
function findAllMatches(
|
||||
data: INodeExecutionData[],
|
||||
lookup: IDataObject,
|
||||
disableDotNotation: boolean,
|
||||
isEntriesEqual: CompareFunction,
|
||||
) {
|
||||
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 = get(entry2.json, key);
|
||||
}
|
||||
|
||||
if (!isEntriesEqual(excpectedValue, entry2FieldValue)) {
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
|
||||
return acc.concat({
|
||||
entry: entry2,
|
||||
index: i,
|
||||
});
|
||||
}, [] as IDataObject[]);
|
||||
}
|
||||
|
||||
function findFirstMatch(
|
||||
data: INodeExecutionData[],
|
||||
lookup: IDataObject,
|
||||
disableDotNotation: boolean,
|
||||
isEntriesEqual: CompareFunction,
|
||||
) {
|
||||
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 = get(entry2.json, key);
|
||||
}
|
||||
|
||||
if (!isEntriesEqual(excpectedValue, entry2FieldValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
if (index === -1) return [];
|
||||
|
||||
return [{ entry: data[index], index }];
|
||||
}
|
||||
|
||||
export function findMatches(
|
||||
input1: INodeExecutionData[],
|
||||
input2: INodeExecutionData[],
|
||||
fieldsToMatch: PairToMatch[],
|
||||
options: IDataObject,
|
||||
) {
|
||||
const data1 = [...input1];
|
||||
const data2 = [...input2];
|
||||
|
||||
const isEntriesEqual = fuzzyCompare(
|
||||
options.fuzzyCompare as boolean,
|
||||
options.nodeVersion as number,
|
||||
);
|
||||
const disableDotNotation = (options.disableDotNotation as boolean) || false;
|
||||
const multipleMatches = (options.multipleMatches as string) || 'first';
|
||||
const skipFields = ((options.skipFields as string) || '').split(',').map((field) => field.trim());
|
||||
|
||||
if (disableDotNotation && skipFields.some((field) => field.includes('.'))) {
|
||||
const fieldToSkip = skipFields.find((field) => field.includes('.'));
|
||||
const msg = `Dot notation is disabled, but field to skip comparing '${fieldToSkip}' contains dot`;
|
||||
throw new ApplicationError(msg, { level: 'warning' });
|
||||
}
|
||||
|
||||
const filteredData = {
|
||||
matched: [] as EntryMatches[],
|
||||
unmatched1: [] as INodeExecutionData[],
|
||||
unmatched2: [] as INodeExecutionData[],
|
||||
};
|
||||
|
||||
const matchedInInput2 = new Set<number>();
|
||||
|
||||
matchesLoop: for (const entry of data1) {
|
||||
const lookup: IDataObject = {};
|
||||
|
||||
fieldsToMatch.forEach((matchCase) => {
|
||||
let valueToCompare;
|
||||
if (disableDotNotation) {
|
||||
valueToCompare = entry.json[matchCase.field1];
|
||||
} else {
|
||||
valueToCompare = get(entry.json, matchCase.field1);
|
||||
}
|
||||
lookup[matchCase.field2] = valueToCompare;
|
||||
});
|
||||
|
||||
for (const fieldValue of Object.values(lookup)) {
|
||||
if (fieldValue === undefined) {
|
||||
filteredData.unmatched1.push(entry);
|
||||
continue matchesLoop;
|
||||
}
|
||||
}
|
||||
|
||||
const foundedMatches =
|
||||
multipleMatches === 'all'
|
||||
? findAllMatches(data2, lookup, disableDotNotation, isEntriesEqual)
|
||||
: findFirstMatch(data2, lookup, disableDotNotation, isEntriesEqual);
|
||||
|
||||
const matches = foundedMatches.map((match) => match.entry) as INodeExecutionData[];
|
||||
foundedMatches.map((match) => matchedInInput2.add(match.index as number));
|
||||
|
||||
if (matches.length) {
|
||||
filteredData.matched.push({ entry, matches });
|
||||
} else {
|
||||
filteredData.unmatched1.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
data2.forEach((entry, i) => {
|
||||
if (!matchedInInput2.has(i)) {
|
||||
filteredData.unmatched2.push(entry);
|
||||
}
|
||||
});
|
||||
|
||||
const same: INodeExecutionData[] = [];
|
||||
const different: INodeExecutionData[] = [];
|
||||
|
||||
filteredData.matched.forEach((entryMatches) => {
|
||||
let entryCopy: INodeExecutionData | undefined;
|
||||
|
||||
entryMatches.matches.forEach((match) => {
|
||||
let entryFromInput1 = entryMatches.entry.json;
|
||||
let entryFromInput2 = match.json;
|
||||
|
||||
if (skipFields.length) {
|
||||
if (disableDotNotation || !skipFields.some((field) => field.includes('.'))) {
|
||||
entryFromInput1 = omit(entryFromInput1, skipFields);
|
||||
entryFromInput2 = omit(entryFromInput2, skipFields);
|
||||
} else {
|
||||
entryFromInput1 = cloneDeep(entryFromInput1);
|
||||
entryFromInput2 = cloneDeep(entryFromInput2);
|
||||
|
||||
skipFields.forEach((field) => {
|
||||
unset(entryFromInput1, field);
|
||||
unset(entryFromInput2, field);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let isItemsEqual = true;
|
||||
if (options.fuzzyCompare) {
|
||||
for (const key of Object.keys(entryFromInput1)) {
|
||||
if (!isEntriesEqual(entryFromInput1[key], entryFromInput2[key])) {
|
||||
isItemsEqual = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isItemsEqual = isEntriesEqual(entryFromInput1, entryFromInput2);
|
||||
}
|
||||
|
||||
if (isItemsEqual) {
|
||||
if (!entryCopy) {
|
||||
if (options.fuzzyCompare && options.resolve === 'preferInput2') {
|
||||
entryCopy = match;
|
||||
} else {
|
||||
entryCopy = entryMatches.entry;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (options.resolve) {
|
||||
case 'preferInput1':
|
||||
different.push(entryMatches.entry);
|
||||
break;
|
||||
case 'preferInput2':
|
||||
different.push(match);
|
||||
break;
|
||||
case 'mix':
|
||||
different.push(
|
||||
combineItems(
|
||||
entryMatches.entry,
|
||||
match,
|
||||
options.preferWhenMix as string,
|
||||
options.exceptWhenMix as string,
|
||||
disableDotNotation,
|
||||
),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
different.push(
|
||||
compareItems(
|
||||
entryMatches.entry,
|
||||
match,
|
||||
fieldsToMatch,
|
||||
options,
|
||||
skipFields,
|
||||
isEntriesEqual,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!isEmpty(entryCopy)) {
|
||||
same.push(entryCopy);
|
||||
}
|
||||
});
|
||||
|
||||
return [filteredData.unmatched1, same, different, filteredData.unmatched2];
|
||||
}
|
||||
|
||||
export function checkMatchFieldsInput(data: IDataObject[]) {
|
||||
if (data.length === 1 && data[0].field1 === '' && data[0].field2 === '') {
|
||||
throw new 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 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 as PairToMatch[];
|
||||
}
|
||||
|
||||
export function checkInput(input: INodeExecutionData[]) {
|
||||
if (!input) return [];
|
||||
if (input.some((item) => isEmpty(item.json))) {
|
||||
input = input.filter((item) => !isEmpty(item.json));
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
export function checkInputAndThrowError(
|
||||
input: INodeExecutionData[],
|
||||
fields: string[],
|
||||
disableDotNotation: boolean,
|
||||
inputLabel: string,
|
||||
) {
|
||||
if (input.some((item) => isEmpty(item.json))) {
|
||||
input = input.filter((item) => !isEmpty(item.json));
|
||||
}
|
||||
if (input.length === 0) {
|
||||
return input;
|
||||
}
|
||||
for (const field of fields) {
|
||||
const isPresent = (input || []).some((entry) => {
|
||||
if (disableDotNotation) {
|
||||
return entry.json.hasOwnProperty(field);
|
||||
}
|
||||
return get(entry.json, field, undefined) !== undefined;
|
||||
});
|
||||
if (!isPresent) {
|
||||
throw new ApplicationError(
|
||||
`Field '${field}' is not present in any of items in '${inputLabel}'`,
|
||||
{ level: 'warning' },
|
||||
);
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="384" height="512"><path fill="#ed230d" d="M352 448H32c-17.69 0-32 14.31-32 32s14.31 31.1 32 31.1h320c17.69 0 32-14.31 32-31.1s-14.3-32-32-32"/><path fill="#62f730" d="M48 208h112v111.1c0 17.69 14.31 31.1 32 31.1s32-14.31 32-31.1V208h112c17.69 0 32-14.32 32-32.01S353.69 144 336 144H224V32c0-17.69-14.31-32.01-32-32.01s-32 14.34-32 32.02v112H48c-17.69 0-32 14.31-32 31.99s14.31 32 32 32"/></svg>
|
||||
|
After Width: | Height: | Size: 441 B |
@@ -0,0 +1,5 @@
|
||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
|
||||
describe('Test Compare Datasets Node', () => {
|
||||
new NodeTestHarness().setupTests();
|
||||
});
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
{
|
||||
"name": "My workflow",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "4013708d-2460-44b7-923d-e3cd36eb9287",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [-6660, 8040]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": [
|
||||
{
|
||||
"number": 0
|
||||
},
|
||||
{
|
||||
"number": 1
|
||||
},
|
||||
{
|
||||
"number": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "be417cbe-7a4f-40eb-8a26-fca253a01882",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [-6240, 8040]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "number",
|
||||
"field2": "number"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "97d65223-16c9-4d26-b31e-d818e1adbc8a",
|
||||
"name": "Compare Datasets 2.2 - Old",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.2,
|
||||
"position": [-5800, 8140]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": [
|
||||
{
|
||||
"number": 0
|
||||
},
|
||||
{
|
||||
"number": 1,
|
||||
"k": 2
|
||||
},
|
||||
{
|
||||
"number": 10
|
||||
},
|
||||
{
|
||||
"number": 11
|
||||
},
|
||||
{
|
||||
"number": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "94580b8b-b698-4c49-98b6-12973b6f4220",
|
||||
"name": "Code1",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [-6240, 8260]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "78ec40a4-775d-467b-bacb-805658190b29",
|
||||
"name": "Old - A only",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-5540, 7920]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "eaa4cc93-53c6-4d00-9407-bd5da23e868e",
|
||||
"name": "Old - Same",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-5540, 8060]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "d073db39-1902-411d-80dd-6ea8f42ac33b",
|
||||
"name": "Old - Different",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-5540, 8200]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "29f92258-4869-43c1-9cef-9c281397ccc8",
|
||||
"name": "Old - B only",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-5540, 8340]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Old - A only": [
|
||||
{
|
||||
"json": {
|
||||
"number": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"Old - Same": [
|
||||
{
|
||||
"json": {
|
||||
"number": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"Old - Different": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"number": 1
|
||||
},
|
||||
"same": {
|
||||
"number": 1
|
||||
},
|
||||
"different": {
|
||||
"k": {
|
||||
"inputA": null,
|
||||
"inputB": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Old - B only": [
|
||||
{
|
||||
"json": {
|
||||
"number": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"number": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"number": 12
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets 2.2 - Old",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets 2.2 - Old",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare Datasets 2.2 - Old": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Old - A only",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Old - Same",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Old - Different",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Old - B only",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v0"
|
||||
},
|
||||
"versionId": "49a52ed2-ec4b-44b1-9dbd-c13fac4144f2",
|
||||
"id": "ZpXvXjaKKZihfA2x",
|
||||
"meta": {
|
||||
"instanceId": "021d3c82ba2d3bc090cbf4fc81c9312668bcc34297e022bb3438c5c88a43a5ff"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
+1346
File diff suppressed because it is too large
Load Diff
+243
@@ -0,0 +1,243 @@
|
||||
{
|
||||
"name": "My workflow 11",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "ac4d8085-b10f-4579-b08d-ecf13ae71fee",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [400, 520]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": {
|
||||
"id": 1,
|
||||
"data": null,
|
||||
"data2": [],
|
||||
"bar": "bar",
|
||||
"spam": []
|
||||
}
|
||||
},
|
||||
"id": "c3c13247-1b60-4713-855e-bbddec8d02d0",
|
||||
"name": "Code2",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [660, 460]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": {
|
||||
"id": 1,
|
||||
"data": [],
|
||||
"data2": null,
|
||||
"foo": "foo"
|
||||
}
|
||||
},
|
||||
"id": "d8a8f3de-86cc-4a46-ac6b-db67c3442280",
|
||||
"name": "Code3",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [660, 600]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "includeBoth",
|
||||
"fuzzyCompare": true,
|
||||
"options": {}
|
||||
},
|
||||
"id": "b4ca1dc3-c10a-48c0-aae8-f9b3a70efdd6",
|
||||
"name": "Compare Datasets",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2,
|
||||
"position": [880, 540]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "includeBoth",
|
||||
"fuzzyCompare": true,
|
||||
"options": {}
|
||||
},
|
||||
"id": "6a15ebf3-3909-4533-ac31-aaad9ee46d88",
|
||||
"name": "Compare Datasets1",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [880, 700]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "dfaffaee-16e9-4e27-beb1-896370744c97",
|
||||
"name": "Set",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 2,
|
||||
"position": [1100, 600]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "65afc865-9046-437d-bca8-840af9996860",
|
||||
"name": "Set1",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 2,
|
||||
"position": [1100, 760]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Set": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 1
|
||||
},
|
||||
"same": {
|
||||
"id": 1,
|
||||
"data": null,
|
||||
"data2": []
|
||||
},
|
||||
"different": {
|
||||
"bar": {
|
||||
"inputA": "bar",
|
||||
"inputB": null
|
||||
},
|
||||
"spam": {
|
||||
"inputA": [],
|
||||
"inputB": null
|
||||
},
|
||||
"foo": {
|
||||
"inputA": null,
|
||||
"inputB": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set1": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 1
|
||||
},
|
||||
"same": {
|
||||
"id": 1,
|
||||
"data": null,
|
||||
"data2": [],
|
||||
"spam": []
|
||||
},
|
||||
"different": {
|
||||
"bar": {
|
||||
"inputA": "bar",
|
||||
"inputB": null
|
||||
},
|
||||
"foo": {
|
||||
"inputA": null,
|
||||
"inputB": "foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Code3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code2": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Compare Datasets1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code3": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "Compare Datasets1",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare Datasets": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare Datasets1": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "c80189a1-761e-4c6e-a871-7b34c4a044bc",
|
||||
"id": "154",
|
||||
"meta": {
|
||||
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,879 @@
|
||||
{
|
||||
"name": "compare datasets tests",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "c8767bae-66ba-495c-9d2c-4b0cc192ea22",
|
||||
"name": "Start",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [-1020, 1640]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
},
|
||||
{
|
||||
"field1": "text",
|
||||
"field2": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"multipleMatches": "first"
|
||||
}
|
||||
},
|
||||
"id": "80490760-2b76-4e22-977d-6c5142a5ec99",
|
||||
"name": "Compare",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 1,
|
||||
"position": [180, 680]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: 1,\n text: 'foo',\n data: 'A',\n data2: 555,\n memo: 'test',\n },\n {\n id: 2,\n text: 'bar bar',\n data: 'E',\n },\n {\n id: 3,\n text: 'spam',\n data: 'C',\n },\n {\n id: 4,\n text: 'not matched',\n data: 'Y',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "3f4b329b-9d7f-475b-815a-5bb7abfae247",
|
||||
"name": "Function",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-100, 600]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: 1,\n text: 'foo',\n data: 'D',\n data3: 111,\n memo: 'test'\n },\n {\n id: 1,\n text: 'foo',\n data: 'DD',\n },\n {\n id: 2,\n text: 'bar bar',\n data: 'E',\n },\n {\n id: 3,\n text: 'spam',\n data: 'F',\n },\n {\n id: 5,\n text: 'spam',\n data: 'X',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "a91e7fe8-b9fb-417f-a434-c15623246c99",
|
||||
"name": "Function1",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-100, 760]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (!(items.length === 2) && items.filter(({json}) => json.text === 'foo' || 'spam').length !== 2) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "bef942a0-21f4-469d-b019-e528140d9686",
|
||||
"name": "Function2",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 900]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (!(items.length === 1) && items[0].json.data !== 'Y') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "29b9aa7a-4d1f-442d-9487-7f46e0cba1fe",
|
||||
"name": "Function3",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 440]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (!(items.length === 1) && items[0].json.data !== 'E') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "5669e2d2-6cfe-4df2-9513-3871df1fb7f1",
|
||||
"name": "Function4",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 580]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (!(items.length === 2) && items.filter(({json}) => json.text === 'foo' || 'spam').length !== 2) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "4f7c534d-da1d-4947-8deb-9736c83e8956",
|
||||
"name": "Function5",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 740]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "916d4bb7-066f-41cb-9a4b-c4ce34643923",
|
||||
"name": "first match only by id and text",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-340, 680]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "includeBoth",
|
||||
"options": {
|
||||
"multipleMatches": "all"
|
||||
}
|
||||
},
|
||||
"id": "ecb9384d-79b2-4ea8-9a44-a1bb9064311d",
|
||||
"name": "Compare1",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 1,
|
||||
"position": [160, 1340]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: 1,\n data: 'A',\n },\n {\n id: 2,\n data: 'B',\n },\n {\n id: 3,\n data: 'C',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "d218a3b7-1f10-42d8-be27-155f15682855",
|
||||
"name": "Function6",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-120, 1260]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: 1,\n data: 'D',\n },\n {\n id: 1,\n data: 'DD',\n },\n {\n id: 2,\n data: 'E',\n },\n {\n id: 2,\n data: 'EE',\n },\n {\n id: 3,\n data: 'F',\n },\n {\n id: 3,\n data: 'FF',\n },\n {\n id: 5,\n data: 'X',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "7d8e9189-b8e7-4893-96ac-05533d846503",
|
||||
"name": "Function7",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-120, 1420]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (\n items.filter(({json}) => json.id === 5).length !== 1 \n) {\n throw new Error('Incorrect data');\n}\n\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "d030711e-4627-456d-936a-5fa433719b77",
|
||||
"name": "Function8",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [540, 1440]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (\n items.filter(({json}) => json.keys.id === 1).length !== 2 &&\n items.filter(({json}) => json.keys.id === 2).length !== 2 &&\n items.filter(({json}) => json.keys.id === 3).length !== 2\n) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "c2033b2a-7046-411a-8a8f-8ed8b46a97e3",
|
||||
"name": "Function11",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [540, 1280]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "d762ad62-1101-4ef4-912c-d1c6f5dc62fc",
|
||||
"name": "all match by id",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-360, 1340]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id.code",
|
||||
"field2": "id.code"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "mix",
|
||||
"exceptWhenMix": "data",
|
||||
"options": {
|
||||
"multipleMatches": "all"
|
||||
}
|
||||
},
|
||||
"id": "f9e2ccd7-ca40-400a-85eb-32c75169519c",
|
||||
"name": "Compare2",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 1,
|
||||
"position": [160, 1980]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'A',\n },\n {\n id: {code: 2},\n data: 'B',\n },\n {\n id: {code: 3},\n data: 'C',\n },\n {\n id: {code: 4},\n data: 'AA',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "e70cc695-01f5-456c-bdef-bcd85f4c90db",
|
||||
"name": "Function12",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-120, 1900]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'A',\n },\n {\n id: {code: 2},\n data: 'E',\n },\n {\n id: {code: 3},\n data: 'F',\n },\n {\n id: {code: 5},\n data: 'EE',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "ae9aea77-57b4-4b5a-bb1f-cedda223a357",
|
||||
"name": "Function13",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-120, 2060]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id.code",
|
||||
"field2": "id.code"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "includeBoth",
|
||||
"options": {}
|
||||
},
|
||||
"id": "83c6ebd3-dbf3-4175-bf04-313ef47b359e",
|
||||
"name": "Compare3",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 1,
|
||||
"position": [160, 2480],
|
||||
"continueOnFail": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'A',\n },\n {\n id: {code: 2},\n data: 'B',\n },\n {\n id: {code: 3},\n data: 'C',\n },\n {\n 'id.code': 'AAA',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "91d3256e-dda8-4d8f-9796-f2ab5c5e6372",
|
||||
"name": "Function18",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-100, 2400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'D',\n },\n {\n id: {code: 2},\n data: 'E',\n },\n {\n id: {code: 3},\n data: 'F',\n },\n {\n 'id.code': 'AAA',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "36651bfd-6835-429a-b6f6-eb2cf4ab0178",
|
||||
"name": "Function19",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-100, 2560]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items[0].json.data !== 'EE') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "b1929edc-cecb-4e0e-9698-e2210df4d839",
|
||||
"name": "Function14",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [420, 2240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items[0].json.data !== 'AA') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "ffa2e4be-a352-466d-90fd-6be7be8df2c4",
|
||||
"name": "Function15",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [420, 1780]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items[0].json.data !== 'A') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "3f1d1ed6-06ac-43d8-85f8-e290fd3ffbca",
|
||||
"name": "Function16",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [420, 1920]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items.filter(({json}) => json.data === 'E').length !== 1 && items.filter(({json}) => json.data === 'F').length !== 1) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "6a0501c1-922f-48a4-813b-64106da3c988",
|
||||
"name": "Function17",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [420, 2080]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (!(items.length === 3)) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "10ce1673-eb0d-4794-a104-05abf0240a8e",
|
||||
"name": "Function20",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 2560]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "57138e79-dad4-43c4-b805-9e1cda72cb76",
|
||||
"name": "matching by dot notation",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-340, 2480]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "ea46b0bd-bd94-453d-b64e-1574c31fdac4",
|
||||
"name": "matches mix prefer input 1",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-360, 1980]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items[0].json['id.code'] !== 'AAA') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "55362767-c887-4f31-9a23-fd171869e19f",
|
||||
"name": "Function21",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [440, 2420]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id.code",
|
||||
"field2": "id.code"
|
||||
}
|
||||
]
|
||||
},
|
||||
"resolve": "includeBoth",
|
||||
"options": {
|
||||
"disableDotNotation": true
|
||||
}
|
||||
},
|
||||
"id": "542ad5ce-31e7-4a26-b561-757a0fa500c9",
|
||||
"name": "Compare4",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 1,
|
||||
"position": [180, 2860],
|
||||
"continueOnFail": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'A',\n },\n {\n id: {code: 2},\n data: 'B',\n },\n {\n id: {code: 3},\n data: 'C',\n },\n {\n 'id.code': 'AAA',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "8563aa7c-3e6c-47ba-999b-1fee0489a647",
|
||||
"name": "Function22",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-80, 2780]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "const data = [\n {\n id: {code: 1},\n data: 'D',\n },\n {\n id: {code: 2},\n data: 'E',\n },\n {\n id: {code: 3},\n data: 'F',\n },\n {\n 'id.code': 'AAA',\n },\n];\n\nreturn data;"
|
||||
},
|
||||
"id": "e5dc38cb-c5c3-4ae2-8bb4-5b1ef74c0a3f",
|
||||
"name": "Function23",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [-80, 2940]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items.length !== 3) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "7739d61b-f62b-47ad-81b5-5fb38b919e01",
|
||||
"name": "Function24",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [460, 3020]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items[0].json['id.code'] !== 'AAA') {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "805f2f3d-51e7-45ad-94d3-ebb9a1c47964",
|
||||
"name": "Function25",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [460, 2880]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"functionCode": "if (items.length !== 3) {\n throw new Error('Incorrect data');\n}\n\nreturn {success: true};"
|
||||
},
|
||||
"id": "b82d6133-783d-4777-818d-dbcbe3a82042",
|
||||
"name": "Function26",
|
||||
"type": "n8n-nodes-base.function",
|
||||
"typeVersion": 1,
|
||||
"position": [460, 2740]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "1ba0048e-e032-4f6a-903c-3aaf0598f191",
|
||||
"name": "disabled dot notation1",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [-320, 2860]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Function3": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function4": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function5": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function2": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function11": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function8": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function15": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function16": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function17": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function14": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function21": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function20": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function26": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function25": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Function24": [
|
||||
{
|
||||
"json": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"Function": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function4",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function5",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"first match only by id and text": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Function1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare1": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Function11",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function8",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function6": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function7": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare1",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"all match by id": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function6",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Function7",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare2": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function15",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function16",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function17",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function14",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function12": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function13": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare2",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function18": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function19": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare3",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare3": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Function21",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function20",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Start": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "first match only by id and text",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "all match by id",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "matches mix prefer input 1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "matching by dot notation",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "disabled dot notation1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"matching by dot notation": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function18",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Function19",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"matches mix prefer input 1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function12",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Function13",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare4": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function26",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Function25",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Function24",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function22": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare4",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function23": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare4",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"disabled dot notation1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function22",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Function23",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "7169a2ae-a8dd-47a1-8339-8ca7554587a9",
|
||||
"id": "114",
|
||||
"meta": {
|
||||
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
+971
@@ -0,0 +1,971 @@
|
||||
{
|
||||
"name": "skip fields dot test",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "eb18dcd4-3251-493f-ae3f-d4a89b16cee8",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [400, 800]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"data": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "New York",
|
||||
"country": "USA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"data": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "London",
|
||||
"country": "UK"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"data": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "Paris",
|
||||
"country": "France"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "77327bfe-a4a8-49b8-a237-2f264536e5e3",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [660, 640]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"data": {
|
||||
"name": "John",
|
||||
"age": 30,
|
||||
"active": false
|
||||
},
|
||||
"address": {
|
||||
"city": "New York",
|
||||
"country": "us"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"data": {
|
||||
"name": "Jane",
|
||||
"age": 25,
|
||||
"active": false
|
||||
},
|
||||
"address": {
|
||||
"city": "London",
|
||||
"country": "uk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"data": {
|
||||
"name": "Jack",
|
||||
"age": 35,
|
||||
"active": false
|
||||
},
|
||||
"address": {
|
||||
"city": "Paris",
|
||||
"country": "fr"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "8ea09201-1ed6-4f9c-afb4-1261142a74a3",
|
||||
"name": "Code1",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [660, 920]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "750c4213-42e0-4e66-96b0-24dcb82d3d67",
|
||||
"name": "Any skipped",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1020, 220]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"skipFields": "data, address"
|
||||
}
|
||||
},
|
||||
"id": "2912ebdb-ddb8-4c53-a357-66e8b20ff947",
|
||||
"name": "skip whole object",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1020, 420]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"skipFields": "data.age, data.active, address.country"
|
||||
}
|
||||
},
|
||||
"id": "9ea72e2e-f062-4ae7-bfb1-9266848d0f3c",
|
||||
"name": "skip each key",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1020, 620]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"skipFields": "address.country"
|
||||
}
|
||||
},
|
||||
"id": "fca0048b-a493-4ca4-861b-2ca8216fbfba",
|
||||
"name": "skipped contain contry",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1040, 1060]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"skipFields": "data, address.country"
|
||||
}
|
||||
},
|
||||
"id": "498b2f65-1117-4ff2-acde-a51049fd9b89",
|
||||
"name": "skip object and key",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1040, 860],
|
||||
"continueOnFail": true
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "id",
|
||||
"field2": "id"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"skipFields": "data.age, address.country"
|
||||
}
|
||||
},
|
||||
"id": "77ad3a73-8683-41ed-9040-cef1a2895704",
|
||||
"name": "skip includes age and contry",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1040, 1260]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "be74368b-6d04-43ae-ad01-e2efbd2758c3",
|
||||
"name": "Set",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 240]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "4cb1a37a-ce93-4a3e-b613-8ae9e8265718",
|
||||
"name": "Set1",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 380]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "ab00a0a0-34be-4a65-a1de-8f69db895b76",
|
||||
"name": "Set2",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 520]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "b23e2bf9-9a4b-4f87-a21f-cd24c56af3c1",
|
||||
"name": "Set3",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 660]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "2cf57ec3-72c4-43e2-ad28-6755b19cc8f3",
|
||||
"name": "Set4",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 800]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "fdf62bd3-5e54-43cd-b70e-be159aa1722f",
|
||||
"name": "Set5",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 1,
|
||||
"position": [1340, 940]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Set": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 1
|
||||
},
|
||||
"same": {
|
||||
"id": 1
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "John",
|
||||
"age": 30,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "New York",
|
||||
"country": "USA"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "New York",
|
||||
"country": "us"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 2
|
||||
},
|
||||
"same": {
|
||||
"id": 2
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jane",
|
||||
"age": 25,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "London",
|
||||
"country": "UK"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "London",
|
||||
"country": "uk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 3
|
||||
},
|
||||
"same": {
|
||||
"id": 3
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jack",
|
||||
"age": 35,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "Paris",
|
||||
"country": "France"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "Paris",
|
||||
"country": "fr"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set1": [
|
||||
{
|
||||
"json": {
|
||||
"id": 1,
|
||||
"data": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "New York",
|
||||
"country": "USA"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 2,
|
||||
"data": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "London",
|
||||
"country": "UK"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 3,
|
||||
"data": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "Paris",
|
||||
"country": "France"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set2": [
|
||||
{
|
||||
"json": {
|
||||
"id": 1,
|
||||
"data": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "New York",
|
||||
"country": "USA"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 2,
|
||||
"data": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "London",
|
||||
"country": "UK"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 3,
|
||||
"data": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "Paris",
|
||||
"country": "France"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set3": [
|
||||
{
|
||||
"json": {
|
||||
"id": 1,
|
||||
"data": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "New York",
|
||||
"country": "USA"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 2,
|
||||
"data": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "London",
|
||||
"country": "UK"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 3,
|
||||
"data": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"address": {
|
||||
"city": "Paris",
|
||||
"country": "France"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set5": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 1
|
||||
},
|
||||
"same": {
|
||||
"id": 1
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "John",
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "John",
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "New York"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "New York"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"age": 31
|
||||
},
|
||||
"inputB": {
|
||||
"age": 30
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "USA"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "us"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 2
|
||||
},
|
||||
"same": {
|
||||
"id": 2
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jane",
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jane",
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "London"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "London"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"age": 26
|
||||
},
|
||||
"inputB": {
|
||||
"age": 25
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "UK"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "uk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 3
|
||||
},
|
||||
"same": {
|
||||
"id": 3
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jack",
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jack",
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "Paris"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "Paris"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"age": 36
|
||||
},
|
||||
"inputB": {
|
||||
"age": 35
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "France"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "fr"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Set4": [
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 1
|
||||
},
|
||||
"same": {
|
||||
"id": 1
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "John",
|
||||
"age": 31,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "John",
|
||||
"age": 30,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "New York"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "New York"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "USA"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "us"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 2
|
||||
},
|
||||
"same": {
|
||||
"id": 2
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jane",
|
||||
"age": 26,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jane",
|
||||
"age": 25,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "London"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "London"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "UK"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "uk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"keys": {
|
||||
"id": 3
|
||||
},
|
||||
"same": {
|
||||
"id": 3
|
||||
},
|
||||
"different": {
|
||||
"data": {
|
||||
"inputA": {
|
||||
"name": "Jack",
|
||||
"age": 36,
|
||||
"active": true
|
||||
},
|
||||
"inputB": {
|
||||
"name": "Jack",
|
||||
"age": 35,
|
||||
"active": false
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"inputA": {
|
||||
"city": "Paris"
|
||||
},
|
||||
"inputB": {
|
||||
"city": "Paris"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skipped": {
|
||||
"address": {
|
||||
"inputA": {
|
||||
"country": "France"
|
||||
},
|
||||
"inputB": {
|
||||
"country": "fr"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Code1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Any skipped",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "skip whole object",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "skip each key",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "skip object and key",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "skipped contain contry",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "skip includes age and contry",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Any skipped",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "skip whole object",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "skip each key",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "skip object and key",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "skipped contain contry",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "skip includes age and contry",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Any skipped": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"skip whole object": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"skip each key": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"skip object and key": {
|
||||
"main": [
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set3",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"skipped contain contry": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set4",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"skip includes age and contry": {
|
||||
"main": [
|
||||
[],
|
||||
[],
|
||||
[
|
||||
{
|
||||
"node": "Set5",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "853bfbd2-7a94-4859-98e2-ad4df10bf922",
|
||||
"id": "146",
|
||||
"meta": {
|
||||
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"name": "do not error on missing keys",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "c7c0cf66-790a-4da7-81c8-ba9e4bbcec9a",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [720, 300]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": [
|
||||
{
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"id": 2
|
||||
},
|
||||
{
|
||||
"id": 3
|
||||
},
|
||||
{
|
||||
"id": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "cec18624-ced0-4de1-8987-d4b184b136b9",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [1020, 200]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"data": []
|
||||
},
|
||||
"id": "754d549c-82ce-4625-ba2b-6f8edcbf715e",
|
||||
"name": "Code1",
|
||||
"type": "n8n-nodes-testing.testData",
|
||||
"typeVersion": 1,
|
||||
"position": [1020, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "idd",
|
||||
"field2": "idd"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "1b3660a2-a490-4524-a8ac-cd42fa2b340b",
|
||||
"name": "Compare Datasets",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.2,
|
||||
"position": [1300, 420]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mergeByFields": {
|
||||
"values": [
|
||||
{
|
||||
"field1": "idd",
|
||||
"field2": "idd"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "17e9b83b-828c-41a0-a7ba-e33cc66d37ad",
|
||||
"name": "Any skipped",
|
||||
"type": "n8n-nodes-base.compareDatasets",
|
||||
"typeVersion": 2.1,
|
||||
"position": [1300, 180],
|
||||
"continueOnFail": true
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "551ed574-607a-4d98-9b06-350df92c805e",
|
||||
"name": "No Operation, do nothing",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [1540, 200]
|
||||
},
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "00e75760-d88e-413c-b276-c759db72411f",
|
||||
"name": "No Operation, do nothing1",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"typeVersion": 1,
|
||||
"position": [1540, 360]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"No Operation, do nothing": [
|
||||
{
|
||||
"json": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"No Operation, do nothing1": [
|
||||
{
|
||||
"json": {
|
||||
"id": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"json": {
|
||||
"id": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Code1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Any skipped",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Compare Datasets",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
},
|
||||
{
|
||||
"node": "Any skipped",
|
||||
"type": "main",
|
||||
"index": 1
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Any skipped": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "No Operation, do nothing",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Compare Datasets": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "No Operation, do nothing1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "11347bae-96af-4b28-80d7-fe272a165790",
|
||||
"id": "8",
|
||||
"meta": {
|
||||
"instanceId": "6ebec4953fe56f1c009e7c3b107578b375137523af057073c0b5da17350651bd"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { INodeExecutionData } from 'n8n-workflow';
|
||||
|
||||
import { checkInput } from '../../GenericFunctions';
|
||||
|
||||
describe('Test Compare Datasets Node utils', () => {
|
||||
it('test checkInput', () => {
|
||||
const input1 = [
|
||||
{ json: {} },
|
||||
{
|
||||
json: {
|
||||
name: 'Test',
|
||||
age: 30,
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {
|
||||
name: 'Test2',
|
||||
age: 30,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
expect(checkInput(input1).length).toEqual(2);
|
||||
|
||||
const input2: INodeExecutionData[] = [{ json: {} }];
|
||||
|
||||
expect(checkInput(input2).length).toEqual(0);
|
||||
|
||||
const input3 = undefined;
|
||||
|
||||
expect(checkInput(input3 as unknown as INodeExecutionData[]).length).toEqual(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user