mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
✨ Add functionality to evaluate expression
This commit is contained in:
parent
e9c6c64290
commit
c1853a6ff5
|
@ -49,6 +49,7 @@ The following special variables are available:
|
||||||
|
|
||||||
- **$binary**: Incoming binary data of a node
|
- **$binary**: Incoming binary data of a node
|
||||||
- **$data**: Incoming JSON data of a node
|
- **$data**: Incoming JSON data of a node
|
||||||
|
- **$evaluateExpression**: Evaluates a string as expression
|
||||||
- **$env**: Environment variables
|
- **$env**: Environment variables
|
||||||
- **$node**: Data of other nodes (output-data, parameters)
|
- **$node**: Data of other nodes (output-data, parameters)
|
||||||
- **$parameters**: Parameters of the current node
|
- **$parameters**: Parameters of the current node
|
||||||
|
|
|
@ -99,6 +99,22 @@ const channel = $node["Slack"].parameter["channel"];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Method: evaluateExpression(expression: string, itemIndex: number)
|
||||||
|
|
||||||
|
Evaluates a given string as expression.
|
||||||
|
If no `itemIndex` is provided it uses by default in the Function-Node the data of item 0 and
|
||||||
|
in the Function Item-Node the data of the current item.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
items[0].json.variable1 = evaluateExpression('{{1+2}}');
|
||||||
|
items[0].json.variable2 = evaluateExpression($node["Set"].json["myExpression"], 1);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Method: getWorkflowStaticData(type)
|
#### Method: getWorkflowStaticData(type)
|
||||||
|
|
||||||
Gives access to the static workflow data.
|
Gives access to the static workflow data.
|
||||||
|
@ -114,7 +130,7 @@ same in the whole workflow. And every node in the workflow can access it. The no
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```typescript
|
```javascript
|
||||||
// Get the global workflow static data
|
// Get the global workflow static data
|
||||||
const staticData = getWorkflowStaticData('global');
|
const staticData = getWorkflowStaticData('global');
|
||||||
// Get the static data of the node
|
// Get the static data of the node
|
||||||
|
|
|
@ -490,6 +490,9 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx
|
||||||
continueOnFail: () => {
|
continueOnFail: () => {
|
||||||
return continueOnFail(node);
|
return continueOnFail(node);
|
||||||
},
|
},
|
||||||
|
evaluateExpression: (expression: string, itemIndex: number) => {
|
||||||
|
return workflow.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, itemIndex, node.name, connectionInputData);
|
||||||
|
},
|
||||||
async executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise<any> { // tslint:disable-line:no-any
|
async executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise<any> { // tslint:disable-line:no-any
|
||||||
return additionalData.executeWorkflow(workflowInfo, additionalData, inputData);
|
return additionalData.executeWorkflow(workflowInfo, additionalData, inputData);
|
||||||
},
|
},
|
||||||
|
@ -578,6 +581,10 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData:
|
||||||
continueOnFail: () => {
|
continueOnFail: () => {
|
||||||
return continueOnFail(node);
|
return continueOnFail(node);
|
||||||
},
|
},
|
||||||
|
evaluateExpression: (expression: string, evaluateItemIndex: number | undefined) => {
|
||||||
|
evaluateItemIndex = evaluateItemIndex === undefined ? itemIndex : evaluateItemIndex;
|
||||||
|
return workflow.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, evaluateItemIndex, node.name, connectionInputData);
|
||||||
|
},
|
||||||
getContext(type: string): IContextObject {
|
getContext(type: string): IContextObject {
|
||||||
return NodeHelpers.getContext(runExecutionData, type, node);
|
return NodeHelpers.getContext(runExecutionData, type, node);
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,6 +47,9 @@ export class Function implements INodeType {
|
||||||
|
|
||||||
// Define the global objects for the custom function
|
// Define the global objects for the custom function
|
||||||
const sandbox = {
|
const sandbox = {
|
||||||
|
evaluateExpression: (expression: string, itemIndex = 0) => {
|
||||||
|
return this.evaluateExpression(expression, itemIndex);
|
||||||
|
},
|
||||||
getNodeParameter: this.getNodeParameter,
|
getNodeParameter: this.getNodeParameter,
|
||||||
getWorkflowStaticData: this.getWorkflowStaticData,
|
getWorkflowStaticData: this.getWorkflowStaticData,
|
||||||
helpers: this.helpers,
|
helpers: this.helpers,
|
||||||
|
|
|
@ -48,6 +48,9 @@ export class FunctionItem implements INodeType {
|
||||||
|
|
||||||
// Define the global objects for the custom function
|
// Define the global objects for the custom function
|
||||||
const sandbox = {
|
const sandbox = {
|
||||||
|
evaluateExpression: (expression: string, itemIndex: number | undefined) => {
|
||||||
|
return this.evaluateExpression(expression, itemIndex);
|
||||||
|
},
|
||||||
getBinaryData: (): IBinaryKeyData | undefined => {
|
getBinaryData: (): IBinaryKeyData | undefined => {
|
||||||
return item.binary;
|
return item.binary;
|
||||||
},
|
},
|
||||||
|
|
|
@ -155,6 +155,7 @@ export interface IExecuteContextData {
|
||||||
|
|
||||||
export interface IExecuteFunctions {
|
export interface IExecuteFunctions {
|
||||||
continueOnFail(): boolean;
|
continueOnFail(): boolean;
|
||||||
|
evaluateExpression(expression: string, itemIndex: number): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[];
|
||||||
executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise<any>; // tslint:disable-line:no-any
|
executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise<any>; // tslint:disable-line:no-any
|
||||||
getContext(type: string): IContextObject;
|
getContext(type: string): IContextObject;
|
||||||
getCredentials(type: string): ICredentialDataDecryptedObject | undefined;
|
getCredentials(type: string): ICredentialDataDecryptedObject | undefined;
|
||||||
|
@ -176,6 +177,7 @@ export interface IExecuteFunctions {
|
||||||
|
|
||||||
export interface IExecuteSingleFunctions {
|
export interface IExecuteSingleFunctions {
|
||||||
continueOnFail(): boolean;
|
continueOnFail(): boolean;
|
||||||
|
evaluateExpression(expression: string, itemIndex: number | undefined): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[];
|
||||||
getContext(type: string): IContextObject;
|
getContext(type: string): IContextObject;
|
||||||
getCredentials(type: string): ICredentialDataDecryptedObject | undefined;
|
getCredentials(type: string): ICredentialDataDecryptedObject | undefined;
|
||||||
getInputData(inputIndex?: number, inputName?: string): INodeExecutionData;
|
getInputData(inputIndex?: number, inputName?: string): INodeExecutionData;
|
||||||
|
@ -530,8 +532,12 @@ export interface IWorkflowDataProxyData {
|
||||||
$binary: any; // tslint:disable-line:no-any
|
$binary: any; // tslint:disable-line:no-any
|
||||||
$data: any; // tslint:disable-line:no-any
|
$data: any; // tslint:disable-line:no-any
|
||||||
$env: any; // tslint:disable-line:no-any
|
$env: any; // tslint:disable-line:no-any
|
||||||
|
$evaluateExpression: any; // tslint:disable-line:no-any
|
||||||
|
$item: any; // tslint:disable-line:no-any
|
||||||
|
$json: any; // tslint:disable-line:no-any
|
||||||
$node: any; // tslint:disable-line:no-any
|
$node: any; // tslint:disable-line:no-any
|
||||||
$parameter: any; // tslint:disable-line:no-any
|
$parameter: any; // tslint:disable-line:no-any
|
||||||
|
$workflow: any; // tslint:disable-line:no-any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWorkflowMetadata {
|
export interface IWorkflowMetadata {
|
||||||
|
|
|
@ -897,10 +897,14 @@ export class Workflow {
|
||||||
|
|
||||||
// Generate a data proxy which allows to query workflow data
|
// Generate a data proxy which allows to query workflow data
|
||||||
const dataProxy = new WorkflowDataProxy(this, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData);
|
const dataProxy = new WorkflowDataProxy(this, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData);
|
||||||
|
const data = dataProxy.getDataProxy();
|
||||||
|
data.$evaluateExpression = (expression: string) => {
|
||||||
|
return this.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, returnObjectAsString);
|
||||||
|
};
|
||||||
|
|
||||||
// Execute the expression
|
// Execute the expression
|
||||||
try {
|
try {
|
||||||
const returnValue = tmpl.tmpl(parameterValue, dataProxy.getDataProxy());
|
const returnValue = tmpl.tmpl(parameterValue, data);
|
||||||
if (returnValue !== null && typeof returnValue === 'object') {
|
if (returnValue !== null && typeof returnValue === 'object') {
|
||||||
if (Object.keys(returnValue).length === 0) {
|
if (Object.keys(returnValue).length === 0) {
|
||||||
// When expression is incomplete it returns a Proxy which causes problems.
|
// When expression is incomplete it returns a Proxy which causes problems.
|
||||||
|
|
|
@ -300,6 +300,7 @@ export class WorkflowDataProxy {
|
||||||
$binary: {}, // Placeholder
|
$binary: {}, // Placeholder
|
||||||
$data: {}, // Placeholder
|
$data: {}, // Placeholder
|
||||||
$env: this.envGetter(),
|
$env: this.envGetter(),
|
||||||
|
$evaluateExpression: (expression: string) => { }, // Placeholder
|
||||||
$item: (itemIndex: number) => {
|
$item: (itemIndex: number) => {
|
||||||
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData);
|
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData);
|
||||||
return dataProxy.getDataProxy();
|
return dataProxy.getDataProxy();
|
||||||
|
|
Loading…
Reference in a new issue