mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
feat(If Node,Switch Node): Add negative operations
* add some not conditions to the if node
* change default to true
I think the most used behavior is
"if value1 is true" instead of "if value1 is false"
* add u and s flag to regex
* add some not conditions to the switch node
* Add If Not Empty and Object Comparation
* ⏪ Reverted setting bools to true by default
* Changed order for operations so Not items are under the normal ones
Co-authored-by: lublak <lublak.de@gmail.com>
Co-authored-by: lublak <44057030+lublak@users.noreply.github.com>
Co-authored-by: Luiz Eduardo <luizeof@gmail.com>
This commit is contained in:
parent
5c2deb4688
commit
6412546c0c
|
@ -156,6 +156,10 @@ export class If implements INodeType {
|
|||
name: 'Is Empty',
|
||||
value: 'isEmpty',
|
||||
},
|
||||
{
|
||||
name: 'Is Not Empty',
|
||||
value: 'isNotEmpty',
|
||||
},
|
||||
],
|
||||
default: 'smaller',
|
||||
description: 'Operation to decide where the the data should be mapped to.',
|
||||
|
@ -168,6 +172,7 @@ export class If implements INodeType {
|
|||
hide: {
|
||||
operation: [
|
||||
'isEmpty',
|
||||
'isNotEmpty',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -196,34 +201,50 @@ export class If implements INodeType {
|
|||
name: 'Contains',
|
||||
value: 'contains',
|
||||
},
|
||||
{
|
||||
name: 'Not Contains',
|
||||
value: 'notContains',
|
||||
},
|
||||
{
|
||||
name: 'Ends With',
|
||||
value: 'endsWith',
|
||||
},
|
||||
{
|
||||
name: 'Not Ends With',
|
||||
value: 'notEndsWith',
|
||||
},
|
||||
{
|
||||
name: 'Equal',
|
||||
value: 'equal',
|
||||
},
|
||||
{
|
||||
name: 'Not Contains',
|
||||
value: 'notContains',
|
||||
},
|
||||
{
|
||||
name: 'Not Equal',
|
||||
value: 'notEqual',
|
||||
},
|
||||
{
|
||||
name: 'Regex',
|
||||
name: 'Regex Match',
|
||||
value: 'regex',
|
||||
},
|
||||
{
|
||||
name: 'Regex Not Match',
|
||||
value: 'notRegex',
|
||||
},
|
||||
{
|
||||
name: 'Starts With',
|
||||
value: 'startsWith',
|
||||
},
|
||||
{
|
||||
name: 'Not Starts With',
|
||||
value: 'notStartsWith',
|
||||
},
|
||||
{
|
||||
name: 'Is Empty',
|
||||
value: 'isEmpty',
|
||||
},
|
||||
{
|
||||
name: 'Is Not Empty',
|
||||
value: 'isNotEmpty',
|
||||
},
|
||||
],
|
||||
default: 'equal',
|
||||
description: 'Operation to decide where the the data should be mapped to.',
|
||||
|
@ -236,7 +257,9 @@ export class If implements INodeType {
|
|||
hide: {
|
||||
operation: [
|
||||
'isEmpty',
|
||||
'isNotEmpty',
|
||||
'regex',
|
||||
'notRegex',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -251,6 +274,7 @@ export class If implements INodeType {
|
|||
show: {
|
||||
operation: [
|
||||
'regex',
|
||||
'notRegex',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -303,6 +327,7 @@ export class If implements INodeType {
|
|||
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
||||
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
||||
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
||||
notEndsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 as string).endsWith(value2 as string),
|
||||
equal: (value1: NodeParameterValue, value2: NodeParameterValue) => value1 === value2,
|
||||
notEqual: (value1: NodeParameterValue, value2: NodeParameterValue) => value1 !== value2,
|
||||
larger: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) > (value2 || 0),
|
||||
|
@ -310,7 +335,9 @@ export class If implements INodeType {
|
|||
smaller: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) < (value2 || 0),
|
||||
smallerEqual: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) <= (value2 || 0),
|
||||
startsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).startsWith(value2 as string),
|
||||
isEmpty: (value1: NodeParameterValue) => [undefined, null, ''].includes(value1 as string),
|
||||
notStartsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 as string).startsWith(value2 as string),
|
||||
isEmpty: (value1: NodeParameterValue) => (([undefined, null, ''].includes(value1 as string)) || ((typeof value1 === 'object' && value1 !== null) ? (Object.entries(value1 as string).length === 0) : false)),
|
||||
isNotEmpty: (value1: NodeParameterValue) => !(([undefined, null, ''].includes(value1 as string)) || ((typeof value1 === 'object' && value1 !== null) ? (Object.entries(value1 as string).length === 0) : false)),
|
||||
regex: (value1: NodeParameterValue, value2: NodeParameterValue) => {
|
||||
const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
|
||||
|
||||
|
@ -325,6 +352,20 @@ export class If implements INodeType {
|
|||
|
||||
return !!(value1 || '').toString().match(regex);
|
||||
},
|
||||
notRegex: (value1: NodeParameterValue, value2: NodeParameterValue) => {
|
||||
const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
|
||||
|
||||
let regex: RegExp;
|
||||
if (!regexMatch) {
|
||||
regex = new RegExp((value2 || '').toString());
|
||||
} else if (regexMatch.length === 1) {
|
||||
regex = new RegExp(regexMatch[1]);
|
||||
} else {
|
||||
regex = new RegExp(regexMatch[1], regexMatch[2]);
|
||||
}
|
||||
|
||||
return !(value1 || '').toString().match(regex);
|
||||
},
|
||||
};
|
||||
|
||||
// Converts the input data of a dateTime into a number for easy compare
|
||||
|
|
|
@ -430,30 +430,42 @@ export class Switch implements INodeType {
|
|||
name: 'Contains',
|
||||
value: 'contains',
|
||||
},
|
||||
{
|
||||
name: 'Not Contains',
|
||||
value: 'notContains',
|
||||
},
|
||||
{
|
||||
name: 'Ends With',
|
||||
value: 'endsWith',
|
||||
},
|
||||
{
|
||||
name: 'Not Ends With',
|
||||
value: 'notEndsWith',
|
||||
},
|
||||
{
|
||||
name: 'Equal',
|
||||
value: 'equal',
|
||||
},
|
||||
{
|
||||
name: 'Not Contains',
|
||||
value: 'notContains',
|
||||
},
|
||||
{
|
||||
name: 'Not Equal',
|
||||
value: 'notEqual',
|
||||
},
|
||||
{
|
||||
name: 'Regex',
|
||||
name: 'Regex Match',
|
||||
value: 'regex',
|
||||
},
|
||||
{
|
||||
name: 'Regex Not Match',
|
||||
value: 'notRegex',
|
||||
},
|
||||
{
|
||||
name: 'Starts With',
|
||||
value: 'startsWith',
|
||||
},
|
||||
{
|
||||
name: 'Not Starts With',
|
||||
value: 'notStartsWith',
|
||||
},
|
||||
],
|
||||
default: 'equal',
|
||||
description: 'Operation to decide where the the data should be mapped to.',
|
||||
|
@ -466,6 +478,7 @@ export class Switch implements INodeType {
|
|||
hide: {
|
||||
operation: [
|
||||
'regex',
|
||||
'notRegex',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -480,6 +493,7 @@ export class Switch implements INodeType {
|
|||
show: {
|
||||
operation: [
|
||||
'regex',
|
||||
'notRegex',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
@ -571,6 +585,7 @@ export class Switch implements INodeType {
|
|||
contains: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || '').toString().includes((value2 || '').toString()),
|
||||
notContains: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 || '').toString().includes((value2 || '').toString()),
|
||||
endsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).endsWith(value2 as string),
|
||||
notEndsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 as string).endsWith(value2 as string),
|
||||
equal: (value1: NodeParameterValue, value2: NodeParameterValue) => value1 === value2,
|
||||
notEqual: (value1: NodeParameterValue, value2: NodeParameterValue) => value1 !== value2,
|
||||
larger: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) > (value2 || 0),
|
||||
|
@ -578,6 +593,7 @@ export class Switch implements INodeType {
|
|||
smaller: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) < (value2 || 0),
|
||||
smallerEqual: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 || 0) <= (value2 || 0),
|
||||
startsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => (value1 as string).startsWith(value2 as string),
|
||||
notStartsWith: (value1: NodeParameterValue, value2: NodeParameterValue) => !(value1 as string).startsWith(value2 as string),
|
||||
regex: (value1: NodeParameterValue, value2: NodeParameterValue) => {
|
||||
const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
|
||||
|
||||
|
@ -592,6 +608,20 @@ export class Switch implements INodeType {
|
|||
|
||||
return !!(value1 || '').toString().match(regex);
|
||||
},
|
||||
notRegex: (value1: NodeParameterValue, value2: NodeParameterValue) => {
|
||||
const regexMatch = (value2 || '').toString().match(new RegExp('^/(.*?)/([gimusy]*)$'));
|
||||
|
||||
let regex: RegExp;
|
||||
if (!regexMatch) {
|
||||
regex = new RegExp((value2 || '').toString());
|
||||
} else if (regexMatch.length === 1) {
|
||||
regex = new RegExp(regexMatch[1]);
|
||||
} else {
|
||||
regex = new RegExp(regexMatch[1], regexMatch[2]);
|
||||
}
|
||||
|
||||
return !(value1 || '').toString().match(regex);
|
||||
},
|
||||
};
|
||||
|
||||
// Converts the input data of a dateTime into a number for easy compare
|
||||
|
@ -628,31 +658,31 @@ export class Switch implements INodeType {
|
|||
|
||||
if (mode === 'expression') {
|
||||
// One expression decides how to route item
|
||||
|
||||
|
||||
outputIndex = this.getNodeParameter('output', itemIndex) as number;
|
||||
checkIndexRange(outputIndex);
|
||||
|
||||
|
||||
returnData[outputIndex].push(item);
|
||||
} else if (mode === 'rules') {
|
||||
// Rules decide how to route item
|
||||
|
||||
|
||||
const dataType = this.getNodeParameter('dataType', 0) as string;
|
||||
|
||||
|
||||
value1 = this.getNodeParameter('value1', itemIndex) as NodeParameterValue;
|
||||
if (dataType === 'dateTime') {
|
||||
value1 = convertDateTime(value1);
|
||||
}
|
||||
|
||||
|
||||
for (ruleData of this.getNodeParameter('rules.rules', itemIndex, []) as INodeParameters[]) {
|
||||
// Check if the values passes
|
||||
|
||||
|
||||
value2 = ruleData.value2 as NodeParameterValue;
|
||||
if (dataType === 'dateTime') {
|
||||
value2 = convertDateTime(value2);
|
||||
}
|
||||
|
||||
|
||||
compareOperationResult = compareOperationFunctions[ruleData.operation as string](value1, value2);
|
||||
|
||||
|
||||
if (compareOperationResult === true) {
|
||||
// If rule matches add it to the correct output and continue with next item
|
||||
checkIndexRange(ruleData.output as number);
|
||||
|
@ -660,7 +690,7 @@ export class Switch implements INodeType {
|
|||
continue itemLoop;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if a fallback output got defined and route accordingly
|
||||
outputIndex = this.getNodeParameter('fallbackOutput', itemIndex) as number;
|
||||
if (outputIndex !== -1) {
|
||||
|
|
Loading…
Reference in a new issue