Make special variables like $node, $parameter, ... accessible

in Function Nodes
This commit is contained in:
Jan Oberhauser 2019-09-04 14:53:39 +02:00
parent c1e753e9d1
commit 48ccb36536
5 changed files with 37 additions and 6 deletions

View file

@ -23,10 +23,12 @@ import {
IWebhookData, IWebhookData,
IWebhookDescription, IWebhookDescription,
IWebhookFunctions, IWebhookFunctions,
IWorkflowDataProxyData,
IWorkflowExecuteAdditionalData, IWorkflowExecuteAdditionalData,
NodeHelpers, NodeHelpers,
NodeParameterValue, NodeParameterValue,
Workflow, Workflow,
WorkflowDataProxy,
WorkflowExecuteMode, WorkflowExecuteMode,
} from 'n8n-workflow'; } from 'n8n-workflow';
@ -403,6 +405,10 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx
getTimezone: (): string => { getTimezone: (): string => {
return getTimezone(workflow, additionalData); return getTimezone(workflow, additionalData);
}, },
getWorkflowDataProxy: (itemIndex: number): IWorkflowDataProxyData => {
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData);
return dataProxy.getDataProxy();
},
getWorkflowStaticData(type: string): IDataObject { getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node); return workflow.getStaticData(type, node);
}, },
@ -476,6 +482,10 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData:
getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any getNodeParameter: (parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object => { //tslint:disable-line:no-any
return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, fallbackValue); return getNodeParameter(workflow, runExecutionData, runIndex, connectionInputData, node, parameterName, itemIndex, fallbackValue);
}, },
getWorkflowDataProxy: (): IWorkflowDataProxyData => {
const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData);
return dataProxy.getDataProxy();
},
getWorkflowStaticData(type: string): IDataObject { getWorkflowStaticData(type: string): IDataObject {
return workflow.getStaticData(type, node); return workflow.getStaticData(type, node);
}, },

View file

@ -48,8 +48,14 @@ export class Function implements INodeType {
getNodeParameter: this.getNodeParameter, getNodeParameter: this.getNodeParameter,
helpers: this.helpers, helpers: this.helpers,
items, items,
// To be able to access data of other items
$item: (index: number) => this.getWorkflowDataProxy(index),
}; };
// Make it possible to access data via $node, $parameter, ...
// By default use data from first item
Object.assign(sandbox, sandbox.$item(0));
const vm = new NodeVM({ const vm = new NodeVM({
console: 'inherit', console: 'inherit',
sandbox, sandbox,

View file

@ -57,6 +57,10 @@ export class FunctionItem implements INodeType {
}, },
}; };
// Make it possible to access data via $node, $parameter, ...
const dataProxy = this.getWorkflowDataProxy();
Object.assign(sandbox, dataProxy);
const vm = new NodeVM({ const vm = new NodeVM({
console: 'inherit', console: 'inherit',
sandbox, sandbox,

View file

@ -154,6 +154,7 @@ export interface IExecuteFunctions {
getInputData(inputIndex?: number, inputName?: string): INodeExecutionData[]; getInputData(inputIndex?: number, inputName?: string): INodeExecutionData[];
getMode(): WorkflowExecuteMode; getMode(): WorkflowExecuteMode;
getNodeParameter(parameterName: string, itemIndex: number, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any getNodeParameter(parameterName: string, itemIndex: number, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any
getWorkflowDataProxy(itemIndex: number): IWorkflowDataProxyData;
getWorkflowStaticData(type: string): IDataObject; getWorkflowStaticData(type: string): IDataObject;
getTimezone(): string; getTimezone(): string;
prepareOutputData(outputData: INodeExecutionData[], outputIndex?: number): Promise<INodeExecutionData[][]>; prepareOutputData(outputData: INodeExecutionData[], outputIndex?: number): Promise<INodeExecutionData[][]>;
@ -170,6 +171,7 @@ export interface IExecuteSingleFunctions {
getMode(): WorkflowExecuteMode; getMode(): WorkflowExecuteMode;
getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any getNodeParameter(parameterName: string, fallbackValue?: any): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] | object; //tslint:disable-line:no-any
getTimezone(): string; getTimezone(): string;
getWorkflowDataProxy(): IWorkflowDataProxyData;
getWorkflowStaticData(type: string): IDataObject; getWorkflowStaticData(type: string): IDataObject;
helpers: { helpers: {
[key: string]: (...args: any[]) => any //tslint:disable-line:no-any [key: string]: (...args: any[]) => any //tslint:disable-line:no-any
@ -466,6 +468,14 @@ export interface IWebhookDescription {
responseData?: WebhookResponseData | string; responseData?: WebhookResponseData | string;
} }
export interface IWorkflowDataProxyData {
$binary: any; // tslint:disable-line:no-any
$data: any; // tslint:disable-line:no-any
$env: any; // tslint:disable-line:no-any
$node: any; // tslint:disable-line:no-any
$parameter: any; // tslint:disable-line:no-any
}
export type WebhookHttpMethod = 'GET' | 'POST'; export type WebhookHttpMethod = 'GET' | 'POST';
export interface IWebhookResonseData { export interface IWebhookResonseData {

View file

@ -1,8 +1,9 @@
import { import {
IDataObject, IDataObject,
INodeExecutionData, INodeExecutionData,
NodeHelpers,
IRunExecutionData, IRunExecutionData,
IWorkflowDataProxyData,
NodeHelpers,
Workflow, Workflow,
} from './'; } from './';
@ -184,12 +185,12 @@ export class WorkflowDataProxy {
return executionData[that.itemIndex].json; return executionData[that.itemIndex].json;
} else if (name === 'binary') { } else if (name === 'binary') {
// Binary-Data // Binary-Data
if (!executionData[that.itemIndex].binary) {
throw new Error(`No binary data for node "${nodeName}" has been found!`);
}
const returnData: IDataObject = {}; const returnData: IDataObject = {};
if (!executionData[that.itemIndex].binary) {
return returnData;
}
const binaryKeyData = executionData[that.itemIndex].binary!; const binaryKeyData = executionData[that.itemIndex].binary!;
for (const keyName of Object.keys(binaryKeyData)) { for (const keyName of Object.keys(binaryKeyData)) {
@ -263,7 +264,7 @@ export class WorkflowDataProxy {
* @returns * @returns
* @memberof WorkflowDataGetter * @memberof WorkflowDataGetter
*/ */
getDataProxy() { getDataProxy(): IWorkflowDataProxyData {
const that = this; const that = this;
const base = { const base = {