mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
load on demand selected workflow inputs
This commit is contained in:
parent
dacd1907f3
commit
c83bbcf50a
|
@ -300,6 +300,11 @@ export class DynamicNodeParametersService {
|
|||
}
|
||||
|
||||
private getLocalLoadOptionsContext(path: string, additionalData: IWorkflowExecuteAdditionalData) {
|
||||
return new LocalLoadOptionsContext(additionalData, path, this.workflowLoaderService);
|
||||
return new LocalLoadOptionsContext(
|
||||
this.nodeTypes,
|
||||
additionalData,
|
||||
path,
|
||||
this.workflowLoaderService,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
import { get } from 'lodash';
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { ApplicationError, deepCopy, Workflow } from 'n8n-workflow';
|
||||
import type {
|
||||
INodeParameterResourceLocator,
|
||||
IWorkflowExecuteAdditionalData,
|
||||
NodeParameterValueType,
|
||||
ILocalLoadOptionsFunctions,
|
||||
IWorkflowLoader,
|
||||
IWorkflowNodeContext,
|
||||
INode,
|
||||
INodeTypes,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { LoadWorkflowNodeContext } from './workflow-node-context';
|
||||
|
||||
export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
|
||||
constructor(
|
||||
private nodeTypes: INodeTypes,
|
||||
private additionalData: IWorkflowExecuteAdditionalData,
|
||||
private path: string,
|
||||
private workflowLoader: IWorkflowLoader,
|
||||
) {}
|
||||
|
||||
async getExecuteWorkflowTriggerNode(): Promise<INode | undefined> {
|
||||
async getWorkflowNodeContext(nodeType: string): Promise<IWorkflowNodeContext | null> {
|
||||
const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator;
|
||||
|
||||
const workflowId = value as string;
|
||||
|
@ -24,9 +29,25 @@ export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
|
|||
throw new ApplicationError('No workflowId parameter defined on node!');
|
||||
}
|
||||
|
||||
const workflow = await this.workflowLoader.get(workflowId);
|
||||
const dbWorkflow = await this.workflowLoader.get(workflowId);
|
||||
|
||||
return workflow.nodes.find((node) => node.type === 'n8n-nodes-base.executeWorkflowTrigger');
|
||||
const workflowNode = dbWorkflow.nodes.find((node) => node.type === nodeType) as INode;
|
||||
|
||||
if (workflowNode) {
|
||||
const workflow = new Workflow({
|
||||
nodes: [workflowNode],
|
||||
connections: {},
|
||||
active: false,
|
||||
nodeTypes: this.nodeTypes,
|
||||
});
|
||||
|
||||
const workflowAdditionalData = deepCopy(this.additionalData);
|
||||
workflowAdditionalData.currentNodeParameters = workflowNode.parameters;
|
||||
|
||||
return new LoadWorkflowNodeContext(workflow, workflowNode, workflowAdditionalData);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getCurrentNodeParameter(parameterPath: string): NodeParameterValueType | object | undefined {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import type {
|
||||
IGetNodeParameterOptions,
|
||||
INode,
|
||||
IWorkflowExecuteAdditionalData,
|
||||
Workflow,
|
||||
IWorkflowNodeContext,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { NodeExecutionContext } from './node-execution-context';
|
||||
|
||||
export class LoadWorkflowNodeContext extends NodeExecutionContext implements IWorkflowNodeContext {
|
||||
readonly getNodeParameter: IWorkflowNodeContext['getNodeParameter'];
|
||||
|
||||
constructor(workflow: Workflow, node: INode, additionalData: IWorkflowExecuteAdditionalData) {
|
||||
super(workflow, node, additionalData, 'internal');
|
||||
{
|
||||
this.getNodeParameter = ((
|
||||
parameterName: string,
|
||||
itemIndex: number,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
fallbackValue?: any,
|
||||
options?: IGetNodeParameterOptions,
|
||||
) =>
|
||||
this._getNodeParameter(
|
||||
parameterName,
|
||||
itemIndex,
|
||||
fallbackValue,
|
||||
options,
|
||||
)) as IWorkflowNodeContext['getNodeParameter'];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +1,37 @@
|
|||
import type {
|
||||
ILocalLoadOptionsFunctions,
|
||||
INode,
|
||||
ResourceMapperField,
|
||||
ResourceMapperFields,
|
||||
import {
|
||||
EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE,
|
||||
type ILocalLoadOptionsFunctions,
|
||||
type ResourceMapperField,
|
||||
type ResourceMapperFields,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { getFieldEntries } from '../../GenericFunctions';
|
||||
|
||||
export async function getWorkflowInputs(
|
||||
this: ILocalLoadOptionsFunctions,
|
||||
): Promise<ResourceMapperFields> {
|
||||
const executeWorkflowTriggerNode = (await this.getExecuteWorkflowTriggerNode()) as INode;
|
||||
const nodeLoadContext = await this.getWorkflowNodeContext(EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE);
|
||||
let fields: ResourceMapperField[] = [];
|
||||
|
||||
// const fieldValues = getFieldEntries(executeWorkflowTriggerNode);
|
||||
if (nodeLoadContext) {
|
||||
const fieldValues = getFieldEntries(nodeLoadContext);
|
||||
|
||||
const workflowInputFields = [
|
||||
{ name: 'field1', type: 'string' as const },
|
||||
{ name: 'field2', type: 'number' as const },
|
||||
{ name: 'field3', type: 'boolean' as const },
|
||||
{ name: 'field4', type: 'any' as const },
|
||||
];
|
||||
fields = fieldValues.map((currentWorkflowInput) => {
|
||||
const field: ResourceMapperField = {
|
||||
id: currentWorkflowInput.name,
|
||||
displayName: currentWorkflowInput.name,
|
||||
required: false,
|
||||
defaultMatch: true,
|
||||
display: true,
|
||||
canBeUsedToMatch: true,
|
||||
};
|
||||
|
||||
const fields: ResourceMapperField[] = workflowInputFields.map((currentWorkflowInput) => {
|
||||
const field: ResourceMapperField = {
|
||||
id: currentWorkflowInput.name,
|
||||
displayName: currentWorkflowInput.name,
|
||||
required: false,
|
||||
defaultMatch: true,
|
||||
display: true,
|
||||
canBeUsedToMatch: true,
|
||||
};
|
||||
if (currentWorkflowInput.type !== 'any') {
|
||||
field.type = currentWorkflowInput.type;
|
||||
}
|
||||
|
||||
if (currentWorkflowInput.type !== 'any') {
|
||||
field.type = currentWorkflowInput.type;
|
||||
}
|
||||
|
||||
return field;
|
||||
});
|
||||
return field;
|
||||
});
|
||||
}
|
||||
return { fields };
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { json as generateSchemaFromExample, type SchemaObject } from 'generate-schema';
|
||||
import type { JSONSchema7 } from 'json-schema';
|
||||
import type { FieldValueOption, FieldType, IExecuteFunctions } from 'n8n-workflow';
|
||||
import type { FieldValueOption, FieldType, IWorkflowNodeContext } from 'n8n-workflow';
|
||||
import { jsonParse, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import { JSON_EXAMPLE, INPUT_SOURCE, WORKFLOW_INPUTS, VALUES, TYPE_OPTIONS } from './constants';
|
||||
|
@ -40,14 +40,14 @@ function parseJsonSchema(schema: JSONSchema7): FieldValueOption[] | string {
|
|||
return result;
|
||||
}
|
||||
|
||||
function parseJsonExample(context: IExecuteFunctions): JSONSchema7 {
|
||||
function parseJsonExample(context: IWorkflowNodeContext): JSONSchema7 {
|
||||
const jsonString = context.getNodeParameter(JSON_EXAMPLE, 0, '') as string;
|
||||
const json = jsonParse<SchemaObject>(jsonString);
|
||||
|
||||
return generateSchemaFromExample(json) as JSONSchema7;
|
||||
}
|
||||
|
||||
export function getFieldEntries(context: IExecuteFunctions): FieldValueOption[] {
|
||||
export function getFieldEntries(context: IWorkflowNodeContext): FieldValueOption[] {
|
||||
const inputSource = context.getNodeParameter(INPUT_SOURCE, 0);
|
||||
let result: FieldValueOption[] | string = 'Internal Error: Invalid input source';
|
||||
try {
|
||||
|
|
|
@ -1067,13 +1067,17 @@ export interface ILoadOptionsFunctions extends FunctionsBase {
|
|||
options?: IGetNodeParameterOptions,
|
||||
): NodeParameterValueType | object | undefined;
|
||||
getCurrentNodeParameters(): INodeParameters | undefined;
|
||||
|
||||
helpers: RequestHelperFunctions & SSHTunnelFunctions;
|
||||
}
|
||||
|
||||
export type FieldValueOption = { name: string; type: FieldType | 'any' };
|
||||
|
||||
export type IWorkflowNodeContext = ExecuteFunctions.GetNodeParameterFn &
|
||||
Pick<FunctionsBase, 'getNode'>;
|
||||
|
||||
export interface ILocalLoadOptionsFunctions {
|
||||
getExecuteWorkflowTriggerNode(): Promise<INode | undefined>;
|
||||
getWorkflowNodeContext(nodeType: string): Promise<IWorkflowNodeContext | null>;
|
||||
}
|
||||
|
||||
export interface IWorkflowLoader {
|
||||
|
|
Loading…
Reference in a new issue