mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(core): Add closeFunction support to Sub-Nodes (#7708)
Github issue / Community forum post (link here to close automatically): --------- Signed-off-by: Oleg Ivaniv <me@olegivaniv.com> Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
@@ -377,6 +377,8 @@ export interface IConnections {
|
||||
|
||||
export type GenericValue = string | object | number | boolean | undefined | null;
|
||||
|
||||
export type CloseFunction = () => Promise<void>;
|
||||
|
||||
export interface IDataObject {
|
||||
[key: string]: GenericValue | IDataObject | GenericValue[] | IDataObject[];
|
||||
}
|
||||
@@ -410,7 +412,7 @@ export interface IGetExecuteTriggerFunctions {
|
||||
|
||||
export interface IRunNodeResponse {
|
||||
data: INodeExecutionData[][] | null | undefined;
|
||||
closeFunction?: () => Promise<void>;
|
||||
closeFunction?: CloseFunction;
|
||||
}
|
||||
export interface IGetExecuteFunctions {
|
||||
(
|
||||
@@ -423,6 +425,7 @@ export interface IGetExecuteFunctions {
|
||||
additionalData: IWorkflowExecuteAdditionalData,
|
||||
executeData: IExecuteData,
|
||||
mode: WorkflowExecuteMode,
|
||||
closeFunctions: CloseFunction[],
|
||||
abortSignal?: AbortSignal,
|
||||
): IExecuteFunctions;
|
||||
}
|
||||
@@ -1289,13 +1292,13 @@ export type IParameterLabel = {
|
||||
};
|
||||
|
||||
export interface IPollResponse {
|
||||
closeFunction?: () => Promise<void>;
|
||||
closeFunction?: CloseFunction;
|
||||
}
|
||||
|
||||
export interface ITriggerResponse {
|
||||
closeFunction?: () => Promise<void>;
|
||||
closeFunction?: CloseFunction;
|
||||
// To manually trigger the run
|
||||
manualTriggerFunction?: () => Promise<void>;
|
||||
manualTriggerFunction?: CloseFunction;
|
||||
// Gets added automatically at manual workflow runs resolves with
|
||||
// the first emitted data
|
||||
manualTriggerResponse?: Promise<INodeExecutionData[][]>;
|
||||
@@ -1324,6 +1327,7 @@ export namespace MultiPartFormData {
|
||||
export interface SupplyData {
|
||||
metadata?: IDataObject;
|
||||
response: unknown;
|
||||
closeFunction?: CloseFunction;
|
||||
}
|
||||
|
||||
export interface INodeType {
|
||||
|
||||
@@ -37,6 +37,7 @@ import type {
|
||||
NodeParameterValueType,
|
||||
PostReceiveAction,
|
||||
JsonObject,
|
||||
CloseFunction,
|
||||
} from './Interfaces';
|
||||
|
||||
import * as NodeHelpers from './NodeHelpers';
|
||||
@@ -94,6 +95,7 @@ export class RoutingNode {
|
||||
if (nodeType.description.credentials?.length) {
|
||||
credentialType = nodeType.description.credentials[0].name;
|
||||
}
|
||||
const closeFunctions: CloseFunction[] = [];
|
||||
const executeFunctions = nodeExecuteFunctions.getExecuteFunctions(
|
||||
this.workflow,
|
||||
this.runExecutionData,
|
||||
@@ -104,6 +106,7 @@ export class RoutingNode {
|
||||
this.additionalData,
|
||||
executeData,
|
||||
this.mode,
|
||||
closeFunctions,
|
||||
abortSignal,
|
||||
);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import type {
|
||||
IRunNodeResponse,
|
||||
NodeParameterValueType,
|
||||
ConnectionTypes,
|
||||
CloseFunction,
|
||||
} from './Interfaces';
|
||||
import { Node } from './Interfaces';
|
||||
import type { IDeferredPromise } from './DeferredPromise';
|
||||
@@ -1298,6 +1299,7 @@ export class Workflow {
|
||||
}
|
||||
|
||||
if (nodeType.execute) {
|
||||
const closeFunctions: CloseFunction[] = [];
|
||||
const context = nodeExecuteFunctions.getExecuteFunctions(
|
||||
this,
|
||||
runExecutionData,
|
||||
@@ -1308,12 +1310,31 @@ export class Workflow {
|
||||
additionalData,
|
||||
executionData,
|
||||
mode,
|
||||
closeFunctions,
|
||||
abortSignal,
|
||||
);
|
||||
const data =
|
||||
nodeType instanceof Node
|
||||
? await nodeType.execute(context)
|
||||
: await nodeType.execute.call(context);
|
||||
|
||||
const closeFunctionsResults = await Promise.allSettled(
|
||||
closeFunctions.map(async (fn) => fn()),
|
||||
);
|
||||
|
||||
const closingErrors = closeFunctionsResults
|
||||
.filter((result): result is PromiseRejectedResult => result.status === 'rejected')
|
||||
.map((result) => result.reason);
|
||||
|
||||
if (closingErrors.length > 0) {
|
||||
if (closingErrors[0] instanceof Error) throw closingErrors[0];
|
||||
throw new ApplicationError("Error on execution node's close function(s)", {
|
||||
extra: { nodeName: node.name },
|
||||
tags: { nodeType: node.type },
|
||||
cause: closingErrors,
|
||||
});
|
||||
}
|
||||
|
||||
return { data };
|
||||
} else if (nodeType.poll) {
|
||||
if (mode === 'manual') {
|
||||
|
||||
Reference in New Issue
Block a user