diff --git a/packages/cli/src/services/dynamic-node-parameters.service.ts b/packages/cli/src/services/dynamic-node-parameters.service.ts index 9e8ebb1432..57956e3b4e 100644 --- a/packages/cli/src/services/dynamic-node-parameters.service.ts +++ b/packages/cli/src/services/dynamic-node-parameters.service.ts @@ -24,6 +24,8 @@ import { Service } from 'typedi'; import { NodeTypes } from '@/node-types'; +import { WorkflowLoaderService } from './workflow-loader.service'; + type LocalResourceMappingMethod = ( this: ILocalLoadOptionsFunctions, ) => Promise; @@ -48,7 +50,10 @@ type NodeMethod = @Service() export class DynamicNodeParametersService { - constructor(private nodeTypes: NodeTypes) {} + constructor( + private nodeTypes: NodeTypes, + private workflowLoaderService: WorkflowLoaderService, + ) {} /** Returns the available options via a predefined method */ async getOptionsViaMethodName( @@ -193,8 +198,7 @@ export class DynamicNodeParametersService { ): Promise { const nodeType = this.getNodeType(nodeTypeAndVersion); const method = this.getMethod('localResourceMapping', methodName, nodeType); - const workflow = this.getWorkflow(nodeTypeAndVersion, currentNodeParameters, credentials); - const thisArgs = this.getLocalLoadOptionsContext(path, additionalData, workflow); + const thisArgs = this.getLocalLoadOptionsContext(path, additionalData); // eslint-disable-next-line @typescript-eslint/no-unsafe-return return method.call(thisArgs); } @@ -297,12 +301,7 @@ export class DynamicNodeParametersService { return new LoadOptionsContext(workflow, node, additionalData, path); } - private getLocalLoadOptionsContext( - path: string, - additionalData: IWorkflowExecuteAdditionalData, - workflow: Workflow, - ) { - const node = workflow.nodes['Temp-Node']; - return new LocalLoadOptionsContext(workflow, node, additionalData, path); + private getLocalLoadOptionsContext(path: string, additionalData: IWorkflowExecuteAdditionalData) { + return new LocalLoadOptionsContext(additionalData, path, this.workflowLoaderService); } } diff --git a/packages/cli/src/services/workflow-loader.service.ts b/packages/cli/src/services/workflow-loader.service.ts new file mode 100644 index 0000000000..ca1a9ff48c --- /dev/null +++ b/packages/cli/src/services/workflow-loader.service.ts @@ -0,0 +1,19 @@ +import { ApplicationError, type IWorkflowBase, type IWorkflowLoader } from 'n8n-workflow'; +import { Service } from 'typedi'; + +import { WorkflowRepository } from '@/databases/repositories/workflow.repository'; + +@Service() +export class WorkflowLoaderService implements IWorkflowLoader { + constructor(private readonly workflowRepository: WorkflowRepository) {} + + async get(workflowId: string): Promise { + const workflow = await this.workflowRepository.findById(workflowId); + + if (!workflow) { + throw new ApplicationError(`Failed to find workflow with ID "${workflowId}"`); + } + + return workflow; + } +} diff --git a/packages/core/src/node-execution-context/local-load-options-context.ts b/packages/core/src/node-execution-context/local-load-options-context.ts index 06ad21ed58..cef0509c6e 100644 --- a/packages/core/src/node-execution-context/local-load-options-context.ts +++ b/packages/core/src/node-execution-context/local-load-options-context.ts @@ -2,33 +2,21 @@ import { get } from 'lodash'; import { ApplicationError } from 'n8n-workflow'; import type { INodeParameterResourceLocator, - IGetNodeParameterOptions, - INode, IWorkflowExecuteAdditionalData, NodeParameterValueType, - Workflow, ILocalLoadOptionsFunctions, FieldValueOption, + IWorkflowLoader, } from 'n8n-workflow'; -import { extractValue } from '@/ExtractValue'; - -import { NodeExecutionContext } from './node-execution-context'; - -export class LocalLoadOptionsContext - extends NodeExecutionContext - implements ILocalLoadOptionsFunctions -{ +export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions { constructor( - workflow: Workflow, - node: INode, - additionalData: IWorkflowExecuteAdditionalData, - private readonly path: string, - ) { - super(workflow, node, additionalData, 'internal'); - } + private additionalData: IWorkflowExecuteAdditionalData, + private path: string, + private workflowLoader: IWorkflowLoader, + ) {} - getWorkflowInputValues(): FieldValueOption[] { + async getWorkflowInputValues(): Promise { const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator; const workflowId = value as string; @@ -36,6 +24,10 @@ export class LocalLoadOptionsContext throw new ApplicationError('No workflowId parameter defined on node!'); } + const workflow = await this.workflowLoader.get(workflowId); + + workflow.nodes.find((node) => node.type === 'n8n-nodes-base.start'); + // TODO: load the inputs from the workflow const dummyFields = [ { name: 'field1', type: 'string' as const }, @@ -47,31 +39,14 @@ export class LocalLoadOptionsContext return dummyFields; } - getCurrentNodeParameter( - parameterPath: string, - options?: IGetNodeParameterOptions, - ): NodeParameterValueType | object | undefined { + getCurrentNodeParameter(parameterPath: string): NodeParameterValueType | object | undefined { const nodeParameters = this.additionalData.currentNodeParameters; if (parameterPath.startsWith('&')) { parameterPath = `${this.path.split('.').slice(1, -1).join('.')}.${parameterPath.slice(1)}`; } - let returnData = get(nodeParameters, parameterPath); - - // This is outside the try/catch because it throws errors with proper messages - if (options?.extractValue) { - const nodeType = this.workflow.nodeTypes.getByNameAndVersion( - this.node.type, - this.node.typeVersion, - ); - returnData = extractValue( - returnData, - parameterPath, - this.node, - nodeType, - ) as NodeParameterValueType; - } + const returnData = get(nodeParameters, parameterPath); return returnData; } diff --git a/packages/nodes-base/nodes/ExecuteWorkflow/methods/resourceMapping.ts b/packages/nodes-base/nodes/ExecuteWorkflow/methods/resourceMapping.ts index cd71a44532..027d9b3c91 100644 --- a/packages/nodes-base/nodes/ExecuteWorkflow/methods/resourceMapping.ts +++ b/packages/nodes-base/nodes/ExecuteWorkflow/methods/resourceMapping.ts @@ -8,7 +8,7 @@ import type { export async function getWorkflowInputs( this: ILocalLoadOptionsFunctions, ): Promise { - const workflowInputFields = this.getWorkflowInputValues() as FieldValueOption[]; + const workflowInputFields = (await this.getWorkflowInputValues()) as FieldValueOption[]; const fields: ResourceMapperField[] = workflowInputFields.map((currentWorkflowInput) => { const field: ResourceMapperField = { diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index f619d2e8d4..647d49470c 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -1073,7 +1073,11 @@ export interface ILoadOptionsFunctions extends FunctionsBase { export type FieldValueOption = { name: string; type: FieldType | 'any' }; export interface ILocalLoadOptionsFunctions { - getWorkflowInputValues(): FieldValueOption[]; + getWorkflowInputValues(): Promise; +} + +export interface IWorkflowLoader { + get(workflowId: string): Promise; } export interface IPollFunctions