mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(core): Fix node renaming in expressions
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
@@ -444,19 +445,41 @@ export class Workflow {
|
||||
// Reached the actual value
|
||||
if (typeof parameterValue === 'string' && parameterValue.charAt(0) === '=') {
|
||||
// Is expression so has to be rewritten
|
||||
|
||||
// To not run the "expensive" regex stuff when it is not needed
|
||||
// make a simple check first if it really contains the the node-name
|
||||
if (parameterValue.includes(currentName)) {
|
||||
// Really contains node-name (even though we do not know yet if really as $node-expression)
|
||||
|
||||
// In case some special characters are used in name escape them
|
||||
const currentNameEscaped = currentName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
const escapedOldName = backslashEscape(currentName); // for match
|
||||
const escapedNewName = dollarEscape(newName); // for replacement
|
||||
|
||||
parameterValue = parameterValue.replace(
|
||||
new RegExp(`(\\$node(\\.|\\["|\\['))${currentNameEscaped}((\\.|"\\]|'\\]))`, 'g'),
|
||||
`$1${newName}$3`,
|
||||
);
|
||||
const setNewName = (expression: string, oldPattern: string) =>
|
||||
expression.replace(new RegExp(oldPattern, 'g'), `$1${escapedNewName}$2`);
|
||||
|
||||
if (parameterValue.includes('$(')) {
|
||||
const oldPattern = String.raw`(\$\(['"])${escapedOldName}(['"]\))`;
|
||||
parameterValue = setNewName(parameterValue, oldPattern);
|
||||
}
|
||||
|
||||
if (parameterValue.includes('$node[')) {
|
||||
const oldPattern = String.raw`(\$node\[['"])${escapedOldName}(['"]\])`;
|
||||
parameterValue = setNewName(parameterValue, oldPattern);
|
||||
}
|
||||
|
||||
if (parameterValue.includes('$node.')) {
|
||||
const oldPattern = String.raw`(\$node\.)${escapedOldName}(\.?)`;
|
||||
parameterValue = setNewName(parameterValue, oldPattern);
|
||||
|
||||
if (hasDotNotationBannedChar(newName)) {
|
||||
const regex = new RegExp(`.${backslashEscape(newName)}( |\\.)`, 'g');
|
||||
parameterValue = parameterValue.replace(regex, `["${escapedNewName}"]$1`);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterValue.includes('$items(')) {
|
||||
const oldPattern = String.raw`(\$items\(['"])${escapedOldName}(['"],|['"]\))`;
|
||||
parameterValue = setNewName(parameterValue, oldPattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1397,3 +1420,19 @@ export class Workflow {
|
||||
return { data: null };
|
||||
}
|
||||
}
|
||||
|
||||
function hasDotNotationBannedChar(nodeName: string) {
|
||||
const DOT_NOTATION_BANNED_CHARS = /^(\d)|[\\ `!@#$%^&*()_+\-=[\]{};':"\\|,.<>?~]/g;
|
||||
|
||||
return DOT_NOTATION_BANNED_CHARS.test(nodeName);
|
||||
}
|
||||
|
||||
function backslashEscape(nodeName: string) {
|
||||
const BACKSLASH_ESCAPABLE_CHARS = /[.*+?^${}()|[\]\\]/g;
|
||||
|
||||
return nodeName.replace(BACKSLASH_ESCAPABLE_CHARS, (char) => `\\${char}`);
|
||||
}
|
||||
|
||||
function dollarEscape(nodeName: string) {
|
||||
return nodeName.replace(new RegExp('\\$', 'g'), '$$$$');
|
||||
}
|
||||
|
||||
@@ -66,6 +66,117 @@ describe('Workflow', () => {
|
||||
'={{$node["NewName"]["data"]["value2"] + \' - \' + $node["NewName"]["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with $("Node1")',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName',
|
||||
parameters: {
|
||||
value1: '={{$("Node1")["data"]["value1"] + \'Node1\'}}',
|
||||
value2: '={{$("Node1")["data"]["value2"] + \' - \' + $("Node1")["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$("NewName")["data"]["value1"] + \'Node1\'}}',
|
||||
value2: '={{$("NewName")["data"]["value2"] + \' - \' + $("NewName")["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with $items("Node1")',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName',
|
||||
parameters: {
|
||||
value1: '={{$items("Node1")["data"]["value1"] + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$items("Node1")["data"]["value2"] + \' - \' + $items("Node1")["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$items("NewName")["data"]["value1"] + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$items("NewName")["data"]["value2"] + \' - \' + $items("NewName")["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with $items("Node1", 0, 1)',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName',
|
||||
parameters: {
|
||||
value1: '={{$items("Node1", 0, 1)["data"]["value1"] + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$items("Node1", 0, 1)["data"]["value2"] + \' - \' + $items("Node1", 0, 1)["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$items("NewName", 0, 1)["data"]["value1"] + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$items("NewName", 0, 1)["data"]["value2"] + \' - \' + $items("NewName", 0, 1)["data"]["value2"]}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with dot notation that contains space and special character',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'New $ Name',
|
||||
parameters: {
|
||||
value1: "={{$node.Node1.data.value1 + 'Node1'}}",
|
||||
value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$node["New $ Name"].data.value1 + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$node["New $ Name"].data.value2 + \' - \' + $node["New $ Name"].data.value2}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with dot notation that contains space and trailing $',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName$',
|
||||
parameters: {
|
||||
value1: "={{$node.Node1.data.value1 + 'Node1'}}",
|
||||
value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$node["NewName$"].data.value1 + \'Node1\'}}',
|
||||
value2: '={{$node["NewName$"].data.value2 + \' - \' + $node["NewName$"].data.value2}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with dot notation that contains space and special character',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName $ $& $` $$$',
|
||||
parameters: {
|
||||
value1: "={{$node.Node1.data.value1 + 'Node1'}}",
|
||||
value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: '={{$node["NewName $ $& $` $$$"].data.value1 + \'Node1\'}}',
|
||||
value2:
|
||||
'={{$node["NewName $ $& $` $$$"].data.value2 + \' - \' + $node["NewName $ $& $` $$$"].data.value2}}',
|
||||
},
|
||||
},
|
||||
{
|
||||
description: 'should work with dot notation without trailing dot',
|
||||
input: {
|
||||
currentName: 'Node1',
|
||||
newName: 'NewName',
|
||||
parameters: {
|
||||
value1: "={{$node.Node1 + 'Node1'}}",
|
||||
value2: "={{$node.Node1 + ' - ' + $node.Node1}}",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
value1: "={{$node.NewName + 'Node1'}}",
|
||||
value2: "={{$node.NewName + ' - ' + $node.NewName}}",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "should work with ['nodeName']",
|
||||
input: {
|
||||
|
||||
Reference in New Issue
Block a user