From e9fea16301cb9ee0ff7e3af45fc50d77e2cf6a23 Mon Sep 17 00:00:00 2001 From: Jon Date: Wed, 24 Jan 2024 09:30:09 +0000 Subject: [PATCH] fix(Switch Node): Fix issue preventing some regex patterns from working (#8422) --- .../Switch/V3/test/switch.regex.workflow.json | 371 ++++++++++++++++++ .../src/NodeParameters/FilterParameter.ts | 17 +- .../workflow/test/FilterParameter.test.ts | 2 + 3 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 packages/nodes-base/nodes/Switch/V3/test/switch.regex.workflow.json diff --git a/packages/nodes-base/nodes/Switch/V3/test/switch.regex.workflow.json b/packages/nodes-base/nodes/Switch/V3/test/switch.regex.workflow.json new file mode 100644 index 0000000000000..1876c5e233e33 --- /dev/null +++ b/packages/nodes-base/nodes/Switch/V3/test/switch.regex.workflow.json @@ -0,0 +1,371 @@ +{ + "name": "Switch Regex Test", + "nodes": [ + { + "parameters": {}, + "id": "1301e15e-7a64-44bf-bc4b-d60e7b8c629a", + "name": "When clicking \"Test workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [ + 780, + 600 + ] + }, + { + "parameters": {}, + "id": "be9a3cd8-7c19-493c-aacf-a52aba064324", + "name": "Fallback", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1680, + 900 + ] + }, + { + "parameters": {}, + "id": "f7de5522-5750-4102-9b3b-0a01f7bbf6cc", + "name": "Output", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1640, + 320 + ] + }, + { + "parameters": { + "fields": { + "values": [ + { + "name": "test", + "stringValue": "value" + } + ] + }, + "options": {} + }, + "id": "55af4400-ed88-4ee2-b654-3a82bd112875", + "name": "Edit Fields", + "type": "n8n-nodes-base.set", + "typeVersion": 3.2, + "position": [ + 1020, + 600 + ] + }, + { + "parameters": { + "rules": { + "values": [ + { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "17eb6574-9578-4915-8365-772e08d2f06b", + "leftValue": "={{ $json.test }}", + "rightValue": "/^value$/g", + "operator": { + "type": "string", + "operation": "notRegex" + } + } + ], + "combinator": "and" + } + } + ] + }, + "options": { + "fallbackOutput": "extra" + } + }, + "id": "06657954-6bcb-4d60-a659-5d3e5e3d093d", + "name": "NotMatch", + "type": "n8n-nodes-base.switch", + "typeVersion": 3, + "position": [ + 1320, + 720 + ], + "alwaysOutputData": false + }, + { + "parameters": { + "rules": { + "values": [ + { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "17eb6574-9578-4915-8365-772e08d2f06b", + "leftValue": "={{ $json.test }}", + "rightValue": "/^value$/g", + "operator": { + "type": "string", + "operation": "regex" + } + } + ], + "combinator": "and" + } + } + ] + }, + "options": { + "fallbackOutput": "extra" + } + }, + "id": "07776b86-1d7c-4435-b7d8-da73a01830cf", + "name": "Match", + "type": "n8n-nodes-base.switch", + "typeVersion": 3, + "position": [ + 1320, + 340 + ], + "alwaysOutputData": false + }, + { + "parameters": { + "rules": { + "values": [ + { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "17eb6574-9578-4915-8365-772e08d2f06b", + "leftValue": "={{ $json.test }}", + "rightValue": "^value$", + "operator": { + "type": "string", + "operation": "regex" + } + } + ], + "combinator": "and" + } + } + ] + }, + "options": { + "fallbackOutput": "extra" + } + }, + "id": "9fb71a7e-23aa-44f6-ae75-cfc4dc045b81", + "name": "Match1", + "type": "n8n-nodes-base.switch", + "typeVersion": 3, + "position": [ + 1320, + 500 + ], + "alwaysOutputData": false + }, + { + "parameters": { + "rules": { + "values": [ + { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict" + }, + "conditions": [ + { + "id": "17eb6574-9578-4915-8365-772e08d2f06b", + "leftValue": "={{ $json.test }}", + "rightValue": "^value$", + "operator": { + "type": "string", + "operation": "notRegex" + } + } + ], + "combinator": "and" + } + } + ] + }, + "options": { + "fallbackOutput": "extra" + } + }, + "id": "555125fe-6509-4b68-8e3d-bf643f9b4d09", + "name": "NotMatch1", + "type": "n8n-nodes-base.switch", + "typeVersion": 3, + "position": [ + 1320, + 880 + ], + "alwaysOutputData": false + }, + { + "parameters": {}, + "id": "a8d5d282-cff3-4bbf-8293-67b1bbb08e2f", + "name": "Output1", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1640, + 480 + ] + }, + { + "parameters": {}, + "id": "3b7cf77e-f435-4863-a63d-db716cd27528", + "name": "Fallback1", + "type": "n8n-nodes-base.noOp", + "typeVersion": 1, + "position": [ + 1680, + 740 + ] + } + ], + "pinData": { + "Output": [ + { + "json": { + "test": "value" + } + } + ], + "Fallback": [ + { + "json": { + "test": "value" + } + } + ], + "Output1": [ + { + "json": { + "test": "value" + } + } + ], + "Fallback1": [ + { + "json": { + "test": "value" + } + } + ] + }, + "connections": { + "When clicking \"Test workflow\"": { + "main": [ + [ + { + "node": "Edit Fields", + "type": "main", + "index": 0 + } + ] + ] + }, + "Edit Fields": { + "main": [ + [ + { + "node": "Match", + "type": "main", + "index": 0 + }, + { + "node": "NotMatch", + "type": "main", + "index": 0 + }, + { + "node": "Match1", + "type": "main", + "index": 0 + }, + { + "node": "NotMatch1", + "type": "main", + "index": 0 + } + ] + ] + }, + "NotMatch": { + "main": [ + [], + [ + { + "node": "Fallback1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Match": { + "main": [ + [ + { + "node": "Output", + "type": "main", + "index": 0 + } + ] + ] + }, + "NotMatch1": { + "main": [ + [], + [ + { + "node": "Fallback", + "type": "main", + "index": 0 + } + ] + ] + }, + "Match1": { + "main": [ + [ + { + "node": "Output1", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1" + }, + "versionId": "1fdad78e-d569-48c8-bbb9-640e8889b8e3", + "meta": { + "templateCredsSetupCompleted": true, + "instanceId": "8c8c5237b8e37b006a7adce87f4369350c58e41f3ca9de16196d3197f69eabcd" + }, + "id": "EbLiIKvBYzJvLtX3", + "tags": [] +} diff --git a/packages/workflow/src/NodeParameters/FilterParameter.ts b/packages/workflow/src/NodeParameters/FilterParameter.ts index 9f8423f75b2a1..c66b3e5140baf 100644 --- a/packages/workflow/src/NodeParameters/FilterParameter.ts +++ b/packages/workflow/src/NodeParameters/FilterParameter.ts @@ -125,6 +125,19 @@ function parseFilterConditionValues( return { ok: true, result: { left: parsedLeftValue.newValue, right: parsedRightValue.newValue } }; } +function parseRegexPattern(pattern: string): RegExp { + const regexMatch = (pattern || '').match(new RegExp('^/(.*?)/([gimusy]*)$')); + let regex: RegExp; + + if (!regexMatch) { + regex = new RegExp((pattern || '').toString()); + } else { + regex = new RegExp(regexMatch[1], regexMatch[2]); + } + + return regex; +} + export function executeFilterCondition( condition: FilterConditionValue, filterOptions: FilterOptionsValue, @@ -183,9 +196,9 @@ export function executeFilterCondition( case 'notEndsWith': return !left.endsWith(right); case 'regex': - return new RegExp(right).test(left); + return parseRegexPattern(right).test(left); case 'notRegex': - return !new RegExp(right).test(left); + return !parseRegexPattern(right).test(left); } break; diff --git a/packages/workflow/test/FilterParameter.test.ts b/packages/workflow/test/FilterParameter.test.ts index 6c725e2ed860c..3dde0b66791ba 100644 --- a/packages/workflow/test/FilterParameter.test.ts +++ b/packages/workflow/test/FilterParameter.test.ts @@ -431,6 +431,7 @@ describe('FilterParameter', () => { { left: 'any string', right: '[0-9]', expected: false }, { left: 'any string', right: '[a-z]', expected: true }, { left: 'lowercase', right: '[A-Z]', expected: false }, + { left: 'foo', right: '/^fo{2}$/g', expected: true }, ])('string:regex("$left","$right") === $expected', ({ left, right, expected }) => { const result = executeFilter( filterFactory({ @@ -454,6 +455,7 @@ describe('FilterParameter', () => { { left: 'any string', right: '[0-9]', expected: true }, { left: 'any string', right: '[a-z]', expected: false }, { left: 'lowercase', right: '[A-Z]', expected: true }, + { left: 'foo', right: '/^fo{2}$/g', expected: false }, ])('string:notRegex("$left","$right") === $expected', ({ left, right, expected }) => { const result = executeFilter( filterFactory({