diff --git a/packages/nodes-base/nodes/CompareDatasets/CompareDatasets.node.ts b/packages/nodes-base/nodes/CompareDatasets/CompareDatasets.node.ts index 3d7809244e..b0b7389e69 100644 --- a/packages/nodes-base/nodes/CompareDatasets/CompareDatasets.node.ts +++ b/packages/nodes-base/nodes/CompareDatasets/CompareDatasets.node.ts @@ -13,7 +13,7 @@ export class CompareDatasets implements INodeType { name: 'compareDatasets', icon: 'file:compare.svg', group: ['transform'], - version: [1, 2], + version: [1, 2, 2.1], description: 'Compare two inputs for changes', defaults: { name: 'Compare Datasets' }, // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node @@ -102,8 +102,8 @@ export class CompareDatasets implements INodeType { 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': [2], + hide: { + '@version': [1], }, }, }, @@ -169,8 +169,8 @@ export class CompareDatasets implements INodeType { 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': [2], + show: { + '@version': [1], }, }, }, @@ -214,7 +214,7 @@ export class CompareDatasets implements INodeType { options.nodeVersion = this.getNode().typeVersion; - if (options.nodeVersion === 2) { + if (options.nodeVersion >= 2) { options.fuzzyCompare = this.getNodeParameter('fuzzyCompare', 0, false) as boolean; } diff --git a/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts b/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts index 6452179e11..ee9a497faf 100644 --- a/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts +++ b/packages/nodes-base/nodes/CompareDatasets/GenericFunctions.ts @@ -22,7 +22,7 @@ type EntryMatches = { type CompareFunction = (a: T, b: U) => boolean; const processNullishValueFunction = (version: number) => { - if (version === 2) { + if (version >= 2) { return (value: T) => (value === undefined ? null : value); } return (value: T) => value || null; @@ -43,9 +43,16 @@ function compareItems( const keys1 = Object.keys(item1.json); const keys2 = Object.keys(item2.json); - const intersectionKeys = intersection(keys1, keys2); + const allUniqueKeys = union(keys1, keys2); - const same = intersectionKeys.reduce((acc, key) => { + 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]; } @@ -53,7 +60,6 @@ function compareItems( }, {} as IDataObject); const sameKeys = Object.keys(same); - const allUniqueKeys = union(keys1, keys2); const differentKeys = difference(allUniqueKeys, sameKeys); const different: IDataObject = {}; @@ -74,7 +80,7 @@ function compareItems( const input2 = processNullishValue(item2.json[key]); let [firstInputName, secondInputName] = ['input1', 'input2']; - if (options.nodeVersion === 2) { + if ((options.nodeVersion as number) >= 2) { [firstInputName, secondInputName] = ['inputA', 'inputB']; } @@ -191,12 +197,10 @@ export function findMatches( const data1 = [...input1]; const data2 = [...input2]; - let compareVersion = 1; - if (options.nodeVersion === 2) { - compareVersion = 2; - } - - const isEntriesEqual = fuzzyCompare(options.fuzzyCompare as boolean, compareVersion); + 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()); diff --git a/packages/nodes-base/nodes/CompareDatasets/test/node/workflow.compareDatasets.fuzzy.missing_keys.json b/packages/nodes-base/nodes/CompareDatasets/test/node/workflow.compareDatasets.fuzzy.missing_keys.json new file mode 100644 index 0000000000..251b72cd26 --- /dev/null +++ b/packages/nodes-base/nodes/CompareDatasets/test/node/workflow.compareDatasets.fuzzy.missing_keys.json @@ -0,0 +1,232 @@ +{ + "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": { + "jsCode": "return {id: 1, data: null, data2: [], bar: 'bar', spam: []};" + }, + "id": "c3c13247-1b60-4713-855e-bbddec8d02d0", + "name": "Code2", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [660, 460] + }, + { + "parameters": { + "jsCode": "return {id: 1, data: [], data2: null ,foo: 'foo'};" + }, + "id": "d8a8f3de-86cc-4a46-ac6b-db67c3442280", + "name": "Code3", + "type": "n8n-nodes-base.code", + "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": [] +}