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) {
|
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 { get } from 'lodash';
|
||||||
import { ApplicationError } from 'n8n-workflow';
|
import { ApplicationError, deepCopy, Workflow } from 'n8n-workflow';
|
||||||
import type {
|
import type {
|
||||||
INodeParameterResourceLocator,
|
INodeParameterResourceLocator,
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
NodeParameterValueType,
|
NodeParameterValueType,
|
||||||
ILocalLoadOptionsFunctions,
|
ILocalLoadOptionsFunctions,
|
||||||
IWorkflowLoader,
|
IWorkflowLoader,
|
||||||
|
IWorkflowNodeContext,
|
||||||
INode,
|
INode,
|
||||||
|
INodeTypes,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { LoadWorkflowNodeContext } from './workflow-node-context';
|
||||||
|
|
||||||
export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
|
export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
|
||||||
constructor(
|
constructor(
|
||||||
|
private nodeTypes: INodeTypes,
|
||||||
private additionalData: IWorkflowExecuteAdditionalData,
|
private additionalData: IWorkflowExecuteAdditionalData,
|
||||||
private path: string,
|
private path: string,
|
||||||
private workflowLoader: IWorkflowLoader,
|
private workflowLoader: IWorkflowLoader,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getExecuteWorkflowTriggerNode(): Promise<INode | undefined> {
|
async getWorkflowNodeContext(nodeType: string): Promise<IWorkflowNodeContext | null> {
|
||||||
const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator;
|
const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator;
|
||||||
|
|
||||||
const workflowId = value as string;
|
const workflowId = value as string;
|
||||||
|
@ -24,9 +29,25 @@ export class LocalLoadOptionsContext implements ILocalLoadOptionsFunctions {
|
||||||
throw new ApplicationError('No workflowId parameter defined on node!');
|
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 {
|
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,25 +1,22 @@
|
||||||
import type {
|
import {
|
||||||
ILocalLoadOptionsFunctions,
|
EXECUTE_WORKFLOW_TRIGGER_NODE_TYPE,
|
||||||
INode,
|
type ILocalLoadOptionsFunctions,
|
||||||
ResourceMapperField,
|
type ResourceMapperField,
|
||||||
ResourceMapperFields,
|
type ResourceMapperFields,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { getFieldEntries } from '../../GenericFunctions';
|
||||||
|
|
||||||
export async function getWorkflowInputs(
|
export async function getWorkflowInputs(
|
||||||
this: ILocalLoadOptionsFunctions,
|
this: ILocalLoadOptionsFunctions,
|
||||||
): Promise<ResourceMapperFields> {
|
): 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 = [
|
fields = fieldValues.map((currentWorkflowInput) => {
|
||||||
{ name: 'field1', type: 'string' as const },
|
|
||||||
{ name: 'field2', type: 'number' as const },
|
|
||||||
{ name: 'field3', type: 'boolean' as const },
|
|
||||||
{ name: 'field4', type: 'any' as const },
|
|
||||||
];
|
|
||||||
|
|
||||||
const fields: ResourceMapperField[] = workflowInputFields.map((currentWorkflowInput) => {
|
|
||||||
const field: ResourceMapperField = {
|
const field: ResourceMapperField = {
|
||||||
id: currentWorkflowInput.name,
|
id: currentWorkflowInput.name,
|
||||||
displayName: currentWorkflowInput.name,
|
displayName: currentWorkflowInput.name,
|
||||||
|
@ -35,5 +32,6 @@ export async function getWorkflowInputs(
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
return { fields };
|
return { fields };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { json as generateSchemaFromExample, type SchemaObject } from 'generate-schema';
|
import { json as generateSchemaFromExample, type SchemaObject } from 'generate-schema';
|
||||||
import type { JSONSchema7 } from 'json-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 { jsonParse, NodeOperationError } from 'n8n-workflow';
|
||||||
|
|
||||||
import { JSON_EXAMPLE, INPUT_SOURCE, WORKFLOW_INPUTS, VALUES, TYPE_OPTIONS } from './constants';
|
import { JSON_EXAMPLE, INPUT_SOURCE, WORKFLOW_INPUTS, VALUES, TYPE_OPTIONS } from './constants';
|
||||||
|
@ -40,14 +40,14 @@ function parseJsonSchema(schema: JSONSchema7): FieldValueOption[] | string {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseJsonExample(context: IExecuteFunctions): JSONSchema7 {
|
function parseJsonExample(context: IWorkflowNodeContext): JSONSchema7 {
|
||||||
const jsonString = context.getNodeParameter(JSON_EXAMPLE, 0, '') as string;
|
const jsonString = context.getNodeParameter(JSON_EXAMPLE, 0, '') as string;
|
||||||
const json = jsonParse<SchemaObject>(jsonString);
|
const json = jsonParse<SchemaObject>(jsonString);
|
||||||
|
|
||||||
return generateSchemaFromExample(json) as JSONSchema7;
|
return generateSchemaFromExample(json) as JSONSchema7;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFieldEntries(context: IExecuteFunctions): FieldValueOption[] {
|
export function getFieldEntries(context: IWorkflowNodeContext): FieldValueOption[] {
|
||||||
const inputSource = context.getNodeParameter(INPUT_SOURCE, 0);
|
const inputSource = context.getNodeParameter(INPUT_SOURCE, 0);
|
||||||
let result: FieldValueOption[] | string = 'Internal Error: Invalid input source';
|
let result: FieldValueOption[] | string = 'Internal Error: Invalid input source';
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1067,13 +1067,17 @@ export interface ILoadOptionsFunctions extends FunctionsBase {
|
||||||
options?: IGetNodeParameterOptions,
|
options?: IGetNodeParameterOptions,
|
||||||
): NodeParameterValueType | object | undefined;
|
): NodeParameterValueType | object | undefined;
|
||||||
getCurrentNodeParameters(): INodeParameters | undefined;
|
getCurrentNodeParameters(): INodeParameters | undefined;
|
||||||
|
|
||||||
helpers: RequestHelperFunctions & SSHTunnelFunctions;
|
helpers: RequestHelperFunctions & SSHTunnelFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FieldValueOption = { name: string; type: FieldType | 'any' };
|
export type FieldValueOption = { name: string; type: FieldType | 'any' };
|
||||||
|
|
||||||
|
export type IWorkflowNodeContext = ExecuteFunctions.GetNodeParameterFn &
|
||||||
|
Pick<FunctionsBase, 'getNode'>;
|
||||||
|
|
||||||
export interface ILocalLoadOptionsFunctions {
|
export interface ILocalLoadOptionsFunctions {
|
||||||
getExecuteWorkflowTriggerNode(): Promise<INode | undefined>;
|
getWorkflowNodeContext(nodeType: string): Promise<IWorkflowNodeContext | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IWorkflowLoader {
|
export interface IWorkflowLoader {
|
||||||
|
|
Loading…
Reference in a new issue