From 1aa0a5cc8d6e5154aa4c9604b7f7284773c6d2ee Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Fri, 14 May 2021 18:16:48 -0500 Subject: [PATCH] :zap: Make it possible to read sibling parameter --- packages/core/src/NodeExecuteFunctions.ts | 8 +++--- .../src/components/VariableSelector.vue | 2 +- packages/workflow/src/Expression.ts | 14 +++++----- packages/workflow/src/WorkflowDataProxy.ts | 28 ++++++++++++++----- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index aeeb39c810..726526afc1 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -691,7 +691,7 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx return continueOnFail(node); }, evaluateExpression: (expression: string, itemIndex: number) => { - return workflow.expression.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode); + return workflow.expression.resolveSimpleParameterValue('=' + expression, {}, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode); }, async executeWorkflow(workflowInfo: IExecuteWorkflowInfo, inputData?: INodeExecutionData[]): Promise { // tslint:disable-line:no-any return additionalData.executeWorkflow(workflowInfo, additionalData, inputData); @@ -742,7 +742,7 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx return getWorkflowMetadata(workflow); }, getWorkflowDataProxy: (itemIndex: number): IWorkflowDataProxyData => { - const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode); + const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, {}, mode); return dataProxy.getDataProxy(); }, getWorkflowStaticData(type: string): IDataObject { @@ -789,7 +789,7 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData: }, evaluateExpression: (expression: string, evaluateItemIndex: number | undefined) => { evaluateItemIndex = evaluateItemIndex === undefined ? itemIndex : evaluateItemIndex; - return workflow.expression.resolveSimpleParameterValue('=' + expression, runExecutionData, runIndex, evaluateItemIndex, node.name, connectionInputData, mode); + return workflow.expression.resolveSimpleParameterValue('=' + expression, {}, runExecutionData, runIndex, evaluateItemIndex, node.name, connectionInputData, mode); }, getContext(type: string): IContextObject { return NodeHelpers.getContext(runExecutionData, type, node); @@ -841,7 +841,7 @@ export function getExecuteSingleFunctions(workflow: Workflow, runExecutionData: return getWorkflowMetadata(workflow); }, getWorkflowDataProxy: (): IWorkflowDataProxyData => { - const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, mode); + const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, node.name, connectionInputData, {}, mode); return dataProxy.getDataProxy(); }, getWorkflowStaticData(type: string): IDataObject { diff --git a/packages/editor-ui/src/components/VariableSelector.vue b/packages/editor-ui/src/components/VariableSelector.vue index c4d031859a..2ddb7458b9 100644 --- a/packages/editor-ui/src/components/VariableSelector.vue +++ b/packages/editor-ui/src/components/VariableSelector.vue @@ -379,7 +379,7 @@ export default mixins( return returnData; } - const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, 'manual'); + const dataProxy = new WorkflowDataProxy(workflow, runExecutionData, runIndex, itemIndex, nodeName, connectionInputData, {}, 'manual'); const proxy = dataProxy.getDataProxy(); // @ts-ignore diff --git a/packages/workflow/src/Expression.ts b/packages/workflow/src/Expression.ts index 0cfc80e2a2..c653422308 100644 --- a/packages/workflow/src/Expression.ts +++ b/packages/workflow/src/Expression.ts @@ -59,7 +59,7 @@ export class Expression { * @returns {(NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[])} * @memberof Workflow */ - resolveSimpleParameterValue(parameterValue: NodeParameterValue, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[], mode: WorkflowExecuteMode, returnObjectAsString = false, selfData = {}): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] { + resolveSimpleParameterValue(parameterValue: NodeParameterValue, siblingParameters: INodeParameters, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[], mode: WorkflowExecuteMode, returnObjectAsString = false, selfData = {}): NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[] { // Check if it is an expression if (typeof parameterValue !== 'string' || parameterValue.charAt(0) !== '=') { // Is no expression so return value @@ -72,7 +72,7 @@ export class Expression { parameterValue = parameterValue.substr(1); // Generate a data proxy which allows to query workflow data - const dataProxy = new WorkflowDataProxy(this.workflow, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, -1, selfData); + const dataProxy = new WorkflowDataProxy(this.workflow, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, siblingParameters, mode, -1, selfData); const data = dataProxy.getDataProxy(); // Execute the expression @@ -179,17 +179,17 @@ export class Expression { }; // Helper function which resolves a parameter value depending on if it is simply or not - const resolveParameterValue = (value: NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[]) => { + const resolveParameterValue = (value: NodeParameterValue | INodeParameters | NodeParameterValue[] | INodeParameters[], siblingParameters: INodeParameters) => { if (isComplexParameter(value)) { return this.getParameterValue(value, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, returnObjectAsString, selfData); } else { - return this.resolveSimpleParameterValue(value as NodeParameterValue, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, returnObjectAsString, selfData); + return this.resolveSimpleParameterValue(value as NodeParameterValue, siblingParameters, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, returnObjectAsString, selfData); } }; // Check if it value is a simple one that we can get it resolved directly if (!isComplexParameter(parameterValue)) { - return this.resolveSimpleParameterValue(parameterValue as NodeParameterValue, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, returnObjectAsString, selfData); + return this.resolveSimpleParameterValue(parameterValue as NodeParameterValue, {}, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, mode, returnObjectAsString, selfData); } // The parameter value is complex so resolve depending on type @@ -198,7 +198,7 @@ export class Expression { // Data is an array const returnData = []; for (const item of parameterValue) { - returnData.push(resolveParameterValue(item)); + returnData.push(resolveParameterValue(item, {})); } if (returnObjectAsString === true && typeof returnData === 'object') { @@ -212,7 +212,7 @@ export class Expression { // Data is an object const returnData: INodeParameters = {}; for (const key of Object.keys(parameterValue)) { - returnData[key] = resolveParameterValue((parameterValue as INodeParameters)[key]); + returnData[key] = resolveParameterValue((parameterValue as INodeParameters)[key], parameterValue as INodeParameters); } if (returnObjectAsString === true && typeof returnData === 'object') { diff --git a/packages/workflow/src/WorkflowDataProxy.ts b/packages/workflow/src/WorkflowDataProxy.ts index b81a0263f0..562a4897f6 100644 --- a/packages/workflow/src/WorkflowDataProxy.ts +++ b/packages/workflow/src/WorkflowDataProxy.ts @@ -1,9 +1,11 @@ import { IDataObject, INodeExecutionData, + INodeParameters, IRunExecutionData, IWorkflowDataProxyData, NodeHelpers, + NodeParameterValue, Workflow, WorkflowExecuteMode, } from './'; @@ -18,12 +20,13 @@ export class WorkflowDataProxy { private itemIndex: number; private activeNodeName: string; private connectionInputData: INodeExecutionData[]; + private siblingParameters: INodeParameters; private mode: WorkflowExecuteMode; private selfData: IDataObject; - constructor(workflow: Workflow, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[], mode: WorkflowExecuteMode, defaultReturnRunIndex = -1, selfData = {}) { + constructor(workflow: Workflow, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[], siblingParameters: INodeParameters, mode: WorkflowExecuteMode, defaultReturnRunIndex = -1, selfData = {}) { this.workflow = workflow; this.runExecutionData = runExecutionData; this.defaultReturnRunIndex = defaultReturnRunIndex; @@ -31,6 +34,7 @@ export class WorkflowDataProxy { this.itemIndex = itemIndex; this.activeNodeName = activeNodeName; this.connectionInputData = connectionInputData; + this.siblingParameters = siblingParameters; this.mode = mode; this.selfData = selfData; } @@ -108,12 +112,22 @@ export class WorkflowDataProxy { get(target, name, receiver) { name = name.toString(); - if (!node.parameters.hasOwnProperty(name)) { - // Parameter does not exist on node - throw new Error(`Could not find parameter "${name}" on node "${nodeName}"`); - } + let returnValue: INodeParameters | NodeParameterValue | NodeParameterValue[] | INodeParameters[]; + if (name[0] === '/') { + const key = name.slice(1); + if (!that.siblingParameters.hasOwnProperty(key)) { + throw new Error(`Could not find sibling parameter "${key}" on node "${nodeName}"`); - const returnValue = node.parameters[name]; + } + returnValue = that.siblingParameters[key]; + } else { + if (!node.parameters.hasOwnProperty(name)) { + // Parameter does not exist on node + throw new Error(`Could not find parameter "${name}" on node "${nodeName}"`); + } + + returnValue = node.parameters[name]; + } if (typeof returnValue === 'string' && returnValue.charAt(0) === '=') { // The found value is an expression so resolve it @@ -361,7 +375,7 @@ export class WorkflowDataProxy { }, $item: (itemIndex: number, runIndex?: number) => { const defaultReturnRunIndex = runIndex === undefined ? -1 : runIndex; - const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData, that.mode, defaultReturnRunIndex); + const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData, that.siblingParameters, that.mode, defaultReturnRunIndex); return dataProxy.getDataProxy(); }, $items: (nodeName?: string, outputIndex?: number, runIndex?: number) => {