rename workflow mappings inputs to local resource mappings

This commit is contained in:
Ivan Atanasov 2024-12-04 12:00:45 +01:00
parent 46b662fa03
commit 5efdde1f6d
No known key found for this signature in database
12 changed files with 64 additions and 70 deletions

View file

@ -93,17 +93,15 @@ export class DynamicNodeParametersController {
); );
} }
@Post('/workflow-input-mapping-fields') @Post('/local-resource-mapper-fields')
async getWorkflowInputMappingFields( async getLocalResourceMappingFields(req: DynamicNodeParametersRequest.ResourceMapperFields) {
req: DynamicNodeParametersRequest.WorkflowInputMappingFields,
) {
const { path, methodName, credentials, currentNodeParameters, nodeTypeAndVersion } = req.body; const { path, methodName, credentials, currentNodeParameters, nodeTypeAndVersion } = req.body;
if (!methodName) throw new BadRequestError('Missing `methodName` in request body'); if (!methodName) throw new BadRequestError('Missing `methodName` in request body');
const additionalData = await getBase(req.user.id, currentNodeParameters); const additionalData = await getBase(req.user.id, currentNodeParameters);
return await this.service.getWorkflowInputMappingFields( return await this.service.getLocalResourceMappingFields(
methodName, methodName,
path, path,
additionalData, additionalData,

View file

@ -385,11 +385,6 @@ export declare namespace DynamicNodeParametersRequest {
methodName: string; methodName: string;
}>; }>;
/** POST dynamic-node-parameters/workflow-input-mapping-fields */
type WorkflowInputMappingFields = BaseRequest<{
methodName: string;
}>;
/** POST /dynamic-node-parameters/action-result */ /** POST /dynamic-node-parameters/action-result */
type ActionResult = BaseRequest<{ type ActionResult = BaseRequest<{
handler: string; handler: string;

View file

@ -1,4 +1,4 @@
import { LoadOptionsContext, NodeExecuteFunctions, WorkflowInputsContext } from 'n8n-core'; import { LoadOptionsContext, NodeExecuteFunctions, LocalLoadOptionsContext } from 'n8n-core';
import type { import type {
ILoadOptions, ILoadOptions,
ILoadOptionsFunctions, ILoadOptionsFunctions,
@ -17,15 +17,15 @@ import type {
INodeTypeNameVersion, INodeTypeNameVersion,
NodeParameterValueType, NodeParameterValueType,
IDataObject, IDataObject,
IWorkflowInputsLoadOptionsFunctions, ILocalLoadOptionsFunctions,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { Workflow, RoutingNode, ApplicationError } from 'n8n-workflow'; import { Workflow, RoutingNode, ApplicationError } from 'n8n-workflow';
import { Service } from 'typedi'; import { Service } from 'typedi';
import { NodeTypes } from '@/node-types'; import { NodeTypes } from '@/node-types';
type WorkflowInputsMappingMethod = ( type LocalResourceMappingMethod = (
this: IWorkflowInputsLoadOptionsFunctions, this: ILocalLoadOptionsFunctions,
) => Promise<ResourceMapperFields>; ) => Promise<ResourceMapperFields>;
type ListSearchMethod = ( type ListSearchMethod = (
this: ILoadOptionsFunctions, this: ILoadOptionsFunctions,
@ -40,7 +40,7 @@ type ActionHandlerMethod = (
type ResourceMappingMethod = (this: ILoadOptionsFunctions) => Promise<ResourceMapperFields>; type ResourceMappingMethod = (this: ILoadOptionsFunctions) => Promise<ResourceMapperFields>;
type NodeMethod = type NodeMethod =
| WorkflowInputsMappingMethod | LocalResourceMappingMethod
| ListSearchMethod | ListSearchMethod
| LoadOptionsMethod | LoadOptionsMethod
| ActionHandlerMethod | ActionHandlerMethod
@ -183,7 +183,7 @@ export class DynamicNodeParametersService {
} }
/** Returns the available workflow input mapping fields for the ResourceMapper component */ /** Returns the available workflow input mapping fields for the ResourceMapper component */
async getWorkflowInputMappingFields( async getLocalResourceMappingFields(
methodName: string, methodName: string,
path: string, path: string,
additionalData: IWorkflowExecuteAdditionalData, additionalData: IWorkflowExecuteAdditionalData,
@ -192,9 +192,9 @@ export class DynamicNodeParametersService {
credentials?: INodeCredentials, credentials?: INodeCredentials,
): Promise<ResourceMapperFields> { ): Promise<ResourceMapperFields> {
const nodeType = this.getNodeType(nodeTypeAndVersion); const nodeType = this.getNodeType(nodeTypeAndVersion);
const method = this.getMethod('workflowInputsMapping', methodName, nodeType); const method = this.getMethod('localResourceMapping', methodName, nodeType);
const workflow = this.getWorkflow(nodeTypeAndVersion, currentNodeParameters, credentials); const workflow = this.getWorkflow(nodeTypeAndVersion, currentNodeParameters, credentials);
const thisArgs = this.getWorkflowInputsContext(path, additionalData, workflow); const thisArgs = this.getLocalLoadOptionsContext(path, additionalData, workflow);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return // eslint-disable-next-line @typescript-eslint/no-unsafe-return
return method.call(thisArgs); return method.call(thisArgs);
} }
@ -223,10 +223,10 @@ export class DynamicNodeParametersService {
nodeType: INodeType, nodeType: INodeType,
): ResourceMappingMethod; ): ResourceMappingMethod;
private getMethod( private getMethod(
type: 'workflowInputsMapping', type: 'localResourceMapping',
methodName: string, methodName: string,
nodeType: INodeType, nodeType: INodeType,
): WorkflowInputsMappingMethod; ): LocalResourceMappingMethod;
private getMethod(type: 'listSearch', methodName: string, nodeType: INodeType): ListSearchMethod; private getMethod(type: 'listSearch', methodName: string, nodeType: INodeType): ListSearchMethod;
private getMethod( private getMethod(
type: 'loadOptions', type: 'loadOptions',
@ -241,7 +241,7 @@ export class DynamicNodeParametersService {
private getMethod( private getMethod(
type: type:
| 'resourceMapping' | 'resourceMapping'
| 'workflowInputsMapping' | 'localResourceMapping'
| 'listSearch' | 'listSearch'
| 'loadOptions' | 'loadOptions'
| 'actionHandler', | 'actionHandler',
@ -297,12 +297,12 @@ export class DynamicNodeParametersService {
return new LoadOptionsContext(workflow, node, additionalData, path); return new LoadOptionsContext(workflow, node, additionalData, path);
} }
private getWorkflowInputsContext( private getLocalLoadOptionsContext(
path: string, path: string,
additionalData: IWorkflowExecuteAdditionalData, additionalData: IWorkflowExecuteAdditionalData,
workflow: Workflow, workflow: Workflow,
) { ) {
const node = workflow.nodes['Temp-Node']; const node = workflow.nodes['Temp-Node'];
return new WorkflowInputsContext(workflow, node, additionalData, path); return new LocalLoadOptionsContext(workflow, node, additionalData, path);
} }
} }

View file

@ -3,7 +3,7 @@ export { ExecuteContext } from './execute-context';
export { ExecuteSingleContext } from './execute-single-context'; export { ExecuteSingleContext } from './execute-single-context';
export { HookContext } from './hook-context'; export { HookContext } from './hook-context';
export { LoadOptionsContext } from './load-options-context'; export { LoadOptionsContext } from './load-options-context';
export { WorkflowInputsContext } from './workflow-inputs-context'; export { LocalLoadOptionsContext } from './local-load-options-context';
export { PollContext } from './poll-context'; export { PollContext } from './poll-context';
export { SupplyDataContext } from './supply-data-context'; export { SupplyDataContext } from './supply-data-context';
export { TriggerContext } from './trigger-context'; export { TriggerContext } from './trigger-context';

View file

@ -7,17 +7,17 @@ import type {
IWorkflowExecuteAdditionalData, IWorkflowExecuteAdditionalData,
NodeParameterValueType, NodeParameterValueType,
Workflow, Workflow,
IWorkflowInputsLoadOptionsFunctions, ILocalLoadOptionsFunctions,
FieldType, FieldValueOption,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { extractValue } from '@/ExtractValue'; import { extractValue } from '@/ExtractValue';
import { NodeExecutionContext } from './node-execution-context'; import { NodeExecutionContext } from './node-execution-context';
export class WorkflowInputsContext export class LocalLoadOptionsContext
extends NodeExecutionContext extends NodeExecutionContext
implements IWorkflowInputsLoadOptionsFunctions implements ILocalLoadOptionsFunctions
{ {
constructor( constructor(
workflow: Workflow, workflow: Workflow,
@ -28,12 +28,12 @@ export class WorkflowInputsContext
super(workflow, node, additionalData, 'internal'); super(workflow, node, additionalData, 'internal');
} }
getWorkflowInputValues(): Array<{ name: string; type: FieldType }> { getWorkflowInputValues(): FieldValueOption[] {
const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator; const { value } = this.getCurrentNodeParameter('workflowId') as INodeParameterResourceLocator;
const workflowId = value as string; const workflowId = value as string;
if (!workflowId) { if (!workflowId) {
throw new ApplicationError('No workflowId defined on node!'); throw new ApplicationError('No workflowId parameter defined on node!');
} }
// TODO: load the inputs from the workflow // TODO: load the inputs from the workflow
@ -41,6 +41,7 @@ export class WorkflowInputsContext
{ name: 'field1', type: 'string' as const }, { name: 'field1', type: 'string' as const },
{ name: 'field2', type: 'number' as const }, { name: 'field2', type: 'number' as const },
{ name: 'field3', type: 'boolean' as const }, { name: 'field3', type: 'boolean' as const },
{ name: 'field4', type: 'any' as const },
]; ];
return dummyFields; return dummyFields;

View file

@ -1275,10 +1275,6 @@ export declare namespace DynamicNodeParameters {
methodName: string; methodName: string;
} }
interface WorkflowInputMappingFieldsRequest extends BaseRequest {
methodName: string;
}
interface ActionResultRequest extends BaseRequest { interface ActionResultRequest extends BaseRequest {
handler: string; handler: string;
payload: IDataObject | string | undefined; payload: IDataObject | string | undefined;

View file

@ -59,14 +59,14 @@ export async function getResourceMapperFields(
); );
} }
export async function getWorkflowInputFields( export async function getLocalResourceMapperFields(
context: IRestApiContext, context: IRestApiContext,
sendData: DynamicNodeParameters.WorkflowInputMappingFieldsRequest, sendData: DynamicNodeParameters.ResourceMapperFieldsRequest,
): Promise<ResourceMapperFields> { ): Promise<ResourceMapperFields> {
return await makeRestApiRequest( return await makeRestApiRequest(
context, context,
'POST', 'POST',
'/dynamic-node-parameters/workflow-input-mapping-fields', '/dynamic-node-parameters/local-resource-mapper-fields',
sendData, sendData,
); );
} }

View file

@ -245,8 +245,8 @@ async function loadFieldsToMap(): Promise<void> {
} }
const resourceMapperMethod = props.parameter.typeOptions?.resourceMapper?.resourceMapperMethod; const resourceMapperMethod = props.parameter.typeOptions?.resourceMapper?.resourceMapperMethod;
const workflowInputsMappingMethod = const localResourceMapperMethod =
props.parameter.typeOptions?.resourceMapper?.workflowInputsMappingMethod; props.parameter.typeOptions?.resourceMapper?.localResourceMapperMethod;
let fetchedFields = null; let fetchedFields = null;
@ -266,8 +266,8 @@ async function loadFieldsToMap(): Promise<void> {
}; };
fetchedFields = await nodeTypesStore.getResourceMapperFields(requestParams); fetchedFields = await nodeTypesStore.getResourceMapperFields(requestParams);
} else { } else {
if (typeof workflowInputsMappingMethod === 'string') { if (typeof localResourceMapperMethod === 'string') {
const requestParams: DynamicNodeParameters.WorkflowInputMappingFieldsRequest = { const requestParams: DynamicNodeParameters.ResourceMapperFieldsRequest = {
nodeTypeAndVersion: { nodeTypeAndVersion: {
name: props.node?.type, name: props.node?.type,
version: props.node.typeVersion, version: props.node.typeVersion,
@ -277,9 +277,9 @@ async function loadFieldsToMap(): Promise<void> {
props.node.parameters, props.node.parameters,
) as INodeParameters, ) as INodeParameters,
path: props.path, path: props.path,
methodName: workflowInputsMappingMethod, methodName: localResourceMapperMethod,
}; };
fetchedFields = await nodeTypesStore.getWorkflowInputFields(requestParams); fetchedFields = await nodeTypesStore.getLocalResourceMapperFields(requestParams);
} }
} }

View file

@ -302,11 +302,11 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
} }
}; };
const getWorkflowInputFields = async ( const getLocalResourceMapperFields = async (
sendData: DynamicNodeParameters.WorkflowInputMappingFieldsRequest, sendData: DynamicNodeParameters.ResourceMapperFieldsRequest,
) => { ) => {
try { try {
return await nodeTypesApi.getWorkflowInputFields(rootStore.restApiContext, sendData); return await nodeTypesApi.getLocalResourceMapperFields(rootStore.restApiContext, sendData);
} catch (error) { } catch (error) {
return null; return null;
} }
@ -336,7 +336,7 @@ export const useNodeTypesStore = defineStore(STORES.NODE_TYPES, () => {
visibleNodeTypesByInputConnectionTypeNames, visibleNodeTypesByInputConnectionTypeNames,
isConfigurableNode, isConfigurableNode,
getResourceMapperFields, getResourceMapperFields,
getWorkflowInputFields, getLocalResourceMapperFields,
getNodeParameterActionResult, getNodeParameterActionResult,
getResourceLocatorResults, getResourceLocatorResults,
getNodeParameterOptions, getNodeParameterOptions,

View file

@ -201,7 +201,7 @@ export class ExecuteWorkflow implements INodeType {
typeOptions: { typeOptions: {
loadOptionsDependsOn: ['workflowId.value'], loadOptionsDependsOn: ['workflowId.value'],
resourceMapper: { resourceMapper: {
workflowInputsMappingMethod: 'getWorkflowInputs', localResourceMapperMethod: 'getWorkflowInputs',
valuesLabel: 'Workflow Inputs', valuesLabel: 'Workflow Inputs',
mode: 'add', mode: 'add',
fieldWords: { fieldWords: {
@ -265,7 +265,7 @@ export class ExecuteWorkflow implements INodeType {
}; };
methods = { methods = {
workflowInputsMapping: { localResourceMapping: {
getWorkflowInputs, getWorkflowInputs,
}, },
}; };

View file

@ -1,24 +1,30 @@
import type { import type {
FieldType, FieldValueOption,
IWorkflowInputsLoadOptionsFunctions, ILocalLoadOptionsFunctions,
ResourceMapperField, ResourceMapperField,
ResourceMapperFields, ResourceMapperFields,
} from 'n8n-workflow'; } from 'n8n-workflow';
export async function getWorkflowInputs( export async function getWorkflowInputs(
this: IWorkflowInputsLoadOptionsFunctions, this: ILocalLoadOptionsFunctions,
): Promise<ResourceMapperFields> { ): Promise<ResourceMapperFields> {
const workflowInputs = this.getWorkflowInputValues() as Array<{ name: string; type: FieldType }>; const workflowInputFields = this.getWorkflowInputValues() as FieldValueOption[];
const fields: ResourceMapperField[] = workflowInputs.map((currentWorkflowInput) => ({ const fields: ResourceMapperField[] = workflowInputFields.map((currentWorkflowInput) => {
const field: ResourceMapperField = {
id: currentWorkflowInput.name, id: currentWorkflowInput.name,
displayName: currentWorkflowInput.name, displayName: currentWorkflowInput.name,
required: false, required: false,
defaultMatch: true, defaultMatch: true,
display: true, display: true,
type: currentWorkflowInput.type,
canBeUsedToMatch: true, canBeUsedToMatch: true,
})); };
if (currentWorkflowInput.type !== 'any') {
field.type = currentWorkflowInput.type;
}
return field;
});
return { fields }; return { fields };
} }

View file

@ -1072,7 +1072,7 @@ export interface ILoadOptionsFunctions extends FunctionsBase {
export type FieldValueOption = { name: string; type: FieldType | 'any' }; export type FieldValueOption = { name: string; type: FieldType | 'any' };
export interface IWorkflowInputsLoadOptionsFunctions { export interface ILocalLoadOptionsFunctions {
getWorkflowInputValues(): FieldValueOption[]; getWorkflowInputValues(): FieldValueOption[];
} }
@ -1374,14 +1374,14 @@ export interface ResourceMapperTypeOptionsBase {
}; };
} }
// Enforce at least one of resourceMapperMethod or workflowInputsMappingMethod // Enforce at least one of resourceMapperMethod or localResourceMapperMethod
export type ResourceMapperTypeOptions = export type ResourceMapperTypeOptions =
| (ResourceMapperTypeOptionsBase & { | (ResourceMapperTypeOptionsBase & {
resourceMapperMethod: string; resourceMapperMethod: string;
workflowInputsMappingMethod?: never; localResourceMapperMethod?: never;
}) })
| (ResourceMapperTypeOptionsBase & { | (ResourceMapperTypeOptionsBase & {
workflowInputsMappingMethod: string; localResourceMapperMethod: string;
resourceMapperMethod?: never; resourceMapperMethod?: never;
}); });
@ -1647,10 +1647,8 @@ export interface INodeType {
resourceMapping?: { resourceMapping?: {
[functionName: string]: (this: ILoadOptionsFunctions) => Promise<ResourceMapperFields>; [functionName: string]: (this: ILoadOptionsFunctions) => Promise<ResourceMapperFields>;
}; };
workflowInputsMapping?: { localResourceMapping?: {
[functionName: string]: ( [functionName: string]: (this: ILocalLoadOptionsFunctions) => Promise<ResourceMapperFields>;
this: IWorkflowInputsLoadOptionsFunctions,
) => Promise<ResourceMapperFields>;
}; };
actionHandler?: { actionHandler?: {
[functionName: string]: ( [functionName: string]: (