mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-25 11:31:38 -08:00
add workflow loader
This commit is contained in:
parent
5efdde1f6d
commit
e0c9e9eb0d
|
@ -24,6 +24,8 @@ import { Service } from 'typedi';
|
|||
|
||||
import { NodeTypes } from '@/node-types';
|
||||
|
||||
import { WorkflowLoaderService } from './workflow-loader.service';
|
||||
|
||||
type LocalResourceMappingMethod = (
|
||||
this: ILocalLoadOptionsFunctions,
|
||||
) => Promise<ResourceMapperFields>;
|
||||
|
@ -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<ResourceMapperFields> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
19
packages/cli/src/services/workflow-loader.service.ts
Normal file
19
packages/cli/src/services/workflow-loader.service.ts
Normal file
|
@ -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<IWorkflowBase> {
|
||||
const workflow = await this.workflowRepository.findById(workflowId);
|
||||
|
||||
if (!workflow) {
|
||||
throw new ApplicationError(`Failed to find workflow with ID "${workflowId}"`);
|
||||
}
|
||||
|
||||
return workflow;
|
||||
}
|
||||
}
|
|
@ -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<FieldValueOption[]> {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import type {
|
|||
export async function getWorkflowInputs(
|
||||
this: ILocalLoadOptionsFunctions,
|
||||
): Promise<ResourceMapperFields> {
|
||||
const workflowInputFields = this.getWorkflowInputValues() as FieldValueOption[];
|
||||
const workflowInputFields = (await this.getWorkflowInputValues()) as FieldValueOption[];
|
||||
|
||||
const fields: ResourceMapperField[] = workflowInputFields.map((currentWorkflowInput) => {
|
||||
const field: ResourceMapperField = {
|
||||
|
|
|
@ -1073,7 +1073,11 @@ export interface ILoadOptionsFunctions extends FunctionsBase {
|
|||
export type FieldValueOption = { name: string; type: FieldType | 'any' };
|
||||
|
||||
export interface ILocalLoadOptionsFunctions {
|
||||
getWorkflowInputValues(): FieldValueOption[];
|
||||
getWorkflowInputValues(): Promise<FieldValueOption[]>;
|
||||
}
|
||||
|
||||
export interface IWorkflowLoader {
|
||||
get(workflowId: string): Promise<IWorkflowBase>;
|
||||
}
|
||||
|
||||
export interface IPollFunctions
|
||||
|
|
Loading…
Reference in a new issue