UNPKG

n8n

Version:

n8n Workflow Automation Tool

180 lines • 8.48 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkflowImporter = void 0; const db_1 = require("@n8n/db"); const di_1 = require("@n8n/di"); const workflow_creation_service_1 = require("../../../../workflows/workflow-creation.service"); const workflow_service_1 = require("../../../../workflows/workflow.service"); const workflow_conflict_policy_1 = require("./workflow-conflict-policy"); const workflow_id_policy_1 = require("./workflow-id-policy"); const workflow_import_match_service_1 = require("./workflow-import-match.service"); const workflow_publisher_1 = require("./workflow-publisher"); let WorkflowImporter = class WorkflowImporter { constructor(workflowImportMatchService, workflowCreationService, workflowService, workflowPublisher) { this.workflowImportMatchService = workflowImportMatchService; this.workflowCreationService = workflowCreationService; this.workflowService = workflowService; this.workflowPublisher = workflowPublisher; } async plan(context, prepared, options) { const existingBySourceWorkflowId = await this.workflowImportMatchService.findBySourceWorkflowIds(context.projectId, prepared.map(({ sourceWorkflowId }) => sourceWorkflowId)); const items = []; const conflicts = []; const folderConflicts = []; const sourceCreateIds = []; for (const workflow of prepared) { const existing = existingBySourceWorkflowId.get(workflow.sourceWorkflowId) ?? null; const { action, blocked } = (0, workflow_conflict_policy_1.decideWorkflowConflictAction)(options.workflowConflictPolicy, existing); const item = toPlanItem(workflow, existing, action, options.workflowIdPolicy); items.push(item); if (item.action === 'create' && options.workflowIdPolicy === 'source' && !blocked) { sourceCreateIds.push(item.decidedId); } if (blocked && existing) { conflicts.push({ sourceWorkflowId: workflow.sourceWorkflowId, existingWorkflowId: existing.id, name: existing.name, }); } const targetFolderId = workflow.parentFolderId ?? context.folderId; if (targetFolderId && existing) { const existingParentFolderId = existing.parentFolder?.id ?? null; if (existingParentFolderId !== targetFolderId) { folderConflicts.push({ sourceWorkflowId: workflow.sourceWorkflowId, existingWorkflowId: existing.id, existingParentFolderId, targetFolderId, name: existing.name, }); } } } const idConflicts = await this.collectIdConflicts(sourceCreateIds); return { items, conflicts, idConflicts, folderConflicts }; } async collectIdConflicts(candidateIds) { const existing = await this.workflowImportMatchService.findOwningProjectsByWorkflowId(candidateIds); return candidateIds.flatMap((id) => { const location = existing.get(id); if (!location) return []; return [ { sourceWorkflowId: id, existingWorkflowId: id, existingProjectId: location.projectId, isArchived: location.isArchived, name: location.name, }, ]; }); } async apply(context, plan, bindings) { const workflowBindings = new Map(bindings.workflows); const outcomes = []; for (const item of plan.items) { const outcome = await this.applyItem(context, item, bindings); outcomes.push(outcome); workflowBindings.set(outcome.sourceWorkflowId, outcome.workflow.id); } return { outcomes, bindings: { ...bindings, workflows: workflowBindings } }; } async applyItem(context, item, bindings) { if (item.action === 'skip') { return { status: 'skipped', workflow: item.existing, sourceWorkflowId: item.sourceWorkflowId, publishing: { state: 'unchanged' }, }; } const savedWorkflow = await this.persistWorkflow(context, item, bindings); const { workflow, publishing } = await this.workflowPublisher.apply(context.user, item, savedWorkflow, context.publishingPolicy, context.publishBlocked); workflow.parentFolder = workflow.parentFolder ?? savedWorkflow.parentFolder ?? (item.action === 'update' ? item.existing.parentFolder : null) ?? null; return { status: item.action === 'create' ? 'created' : 'updated', workflow, sourceWorkflowId: item.sourceWorkflowId, publishing, }; } async persistWorkflow(context, item, bindings) { if (item.action === 'create') { const entity = prepareEntityForPersist(item.entity, bindings, item.decidedId); return await this.workflowCreationService.createWorkflow(context.user, entity, { projectId: context.projectId, parentFolderId: item.parentFolderId ?? context.folderId ?? undefined, publicApi: true, source: 'import', sourceWorkflowId: item.sourceWorkflowId, }); } const entity = prepareEntityForPersist(item.entity, bindings); return await this.workflowService.update(context.user, entity, item.existing.id, { publicApi: true, source: 'import', }); } }; exports.WorkflowImporter = WorkflowImporter; exports.WorkflowImporter = WorkflowImporter = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [workflow_import_match_service_1.WorkflowImportMatchService, workflow_creation_service_1.WorkflowCreationService, workflow_service_1.WorkflowService, workflow_publisher_1.WorkflowPublisher]) ], WorkflowImporter); function prepareEntityForPersist(source, bindings, decidedId) { const entity = Object.assign(new db_1.WorkflowEntity(), source, { nodes: structuredClone(source.nodes), ...(decidedId !== undefined ? { id: decidedId } : {}), }); applyCredentialBindingsInPlace(entity, bindings.credentials); return entity; } function applyCredentialBindingsInPlace(entity, credentialBindings) { for (const node of entity.nodes) { for (const details of Object.values(node.credentials ?? {})) { if (!details.id) continue; const targetId = credentialBindings.get(details.id); if (targetId) { details.id = targetId; } } } } function toPlanItem(prepared, existing, action, idPolicy) { if (existing === null) { return { action: 'create', decidedId: (0, workflow_id_policy_1.decideWorkflowId)(idPolicy, prepared.sourceWorkflowId), ...prepared, }; } switch (action) { case 'update': return { action, ...prepared, existing }; case 'skip': return { action, ...prepared, existing }; case 'create': return { action, decidedId: (0, workflow_id_policy_1.decideWorkflowId)(idPolicy, prepared.sourceWorkflowId), ...prepared, }; } } //# sourceMappingURL=workflow-importer.js.map