From 7c810d2bd68d0bceb95987fc0ff62306f189288f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Thu, 10 Nov 2022 10:59:38 +0100 Subject: [PATCH] :bug: Fix multiple pinned triggers behavior --- .../cli/src/workflows/workflows.controller.ts | 19 +++----------- .../cli/src/workflows/workflows.services.ts | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/packages/cli/src/workflows/workflows.controller.ts b/packages/cli/src/workflows/workflows.controller.ts index c3c9c1817d4f0..a324dea302b44 100644 --- a/packages/cli/src/workflows/workflows.controller.ts +++ b/packages/cli/src/workflows/workflows.controller.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import express from 'express'; -import { INode, IPinData, LoggerProxy, Workflow } from 'n8n-workflow'; +import { INode, LoggerProxy, Workflow } from 'n8n-workflow'; import axios from 'axios'; import * as ActiveWorkflowRunner from '@/ActiveWorkflowRunner'; @@ -18,7 +18,6 @@ import { IWorkflowResponse, IExecutionPushResponse, IWorkflowExecutionDataProcess, - IWorkflowDb, } from '@/Interfaces'; import config from '@/config'; import * as TagHelpers from '@/TagHelpers'; @@ -49,18 +48,6 @@ workflowsController.use((req, res, next) => { workflowsController.use('/', EEWorkflowController); -const isTrigger = (nodeType: string) => - ['trigger', 'webhook'].some((suffix) => nodeType.toLowerCase().includes(suffix)); - -function findFirstPinnedTrigger(workflow: IWorkflowDb, pinData?: IPinData) { - if (!pinData) return; - - // eslint-disable-next-line consistent-return - return workflow.nodes.find( - (node) => !node.disabled && isTrigger(node.type) && pinData[node.name], - ); -} - /** * POST /workflows */ @@ -351,11 +338,11 @@ workflowsController.post( const sessionId = GenericHelpers.getSessionId(req); - const pinnedTrigger = findFirstPinnedTrigger(workflowData, pinData); + const pinnedTrigger = WorkflowsService.findPinnedTrigger(workflowData, startNodes, pinData); // If webhooks nodes exist and are active we have to wait for till we receive a call if ( - pinnedTrigger === undefined && + pinnedTrigger === null && (runData === undefined || startNodes === undefined || startNodes.length === 0 || diff --git a/packages/cli/src/workflows/workflows.services.ts b/packages/cli/src/workflows/workflows.services.ts index 95489fca06d13..0148804263e9e 100644 --- a/packages/cli/src/workflows/workflows.services.ts +++ b/packages/cli/src/workflows/workflows.services.ts @@ -1,4 +1,4 @@ -import { JsonObject, jsonParse, LoggerProxy } from 'n8n-workflow'; +import { IPinData, JsonObject, jsonParse, LoggerProxy } from 'n8n-workflow'; import { FindManyOptions, FindOneOptions, In, ObjectLiteral } from 'typeorm'; import { validate as jsonSchemaValidate } from 'jsonschema'; import * as ActiveWorkflowRunner from '@/ActiveWorkflowRunner'; @@ -15,6 +15,7 @@ import { validateEntity } from '@/GenericHelpers'; import { externalHooks } from '@/Server'; import * as TagHelpers from '@/TagHelpers'; import { getSharedWorkflowIds } from '@/WorkflowHelpers'; +import { IWorkflowDb } from '..'; export interface IGetWorkflowsQueryFilter { id?: number | string; @@ -61,6 +62,28 @@ export class WorkflowsService { return Db.collections.SharedWorkflow.findOne(options); } + /** + * Find the pinned trigger to execute the workflow from, if any. + */ + static findPinnedTrigger(workflow: IWorkflowDb, startNodes?: string[], pinData?: IPinData) { + if (!pinData || !startNodes) return null; + + const isTrigger = (nodeTypeName: string) => + ['trigger', 'webhook'].some((suffix) => nodeTypeName.toLowerCase().includes(suffix)); + + const pinnedTriggers = workflow.nodes.filter( + (node) => !node.disabled && pinData[node.name] && isTrigger(node.type), + ); + + if (pinnedTriggers.length === 0) return null; + + if (startNodes?.length === 0) return pinnedTriggers[0]; // full execution + + const [startNodeName] = startNodes; + + return pinnedTriggers.find((pt) => pt.name === startNodeName) ?? null; // partial execution + } + static async get(workflow: Partial, options?: { relations: string[] }) { return Db.collections.Workflow.findOne(workflow, options); }