UNPKG

n8n

Version:

n8n Workflow Automation Tool

187 lines • 11 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.ImportOrchestrator = void 0; const backend_common_1 = require("@n8n/backend-common"); const di_1 = require("@n8n/di"); const node_types_1 = require("../../../node-types"); const credential_importer_1 = require("../entities/credential/credential-importer"); const credential_missing_mode_1 = require("../entities/credential/credential-missing-mode"); const data_table_importer_1 = require("../entities/data-table/data-table-importer"); const folder_importer_1 = require("../entities/folder/folder-importer"); const tag_importer_1 = require("../entities/tag/tag-importer"); const tag_types_1 = require("../entities/tag/tag.types"); const variable_importer_1 = require("../entities/variable/variable-importer"); const variable_types_1 = require("../entities/variable/variable.types"); const missing_node_type_mode_1 = require("../entities/workflow/missing-node-type-mode"); const workflow_importer_1 = require("../entities/workflow/workflow-importer"); const workflow_publisher_1 = require("../entities/workflow/workflow-publisher"); const n8n_packages_types_1 = require("../n8n-packages.types"); const import_blocked_error_1 = require("./import-blocked.error"); const import_gates_1 = require("./import-gates"); let ImportOrchestrator = class ImportOrchestrator { constructor(credentialImporter, dataTableImporter, variableImporter, tagImporter, folderImporter, workflowImporter, workflowPublisher, nodeTypes, licenseState) { this.credentialImporter = credentialImporter; this.dataTableImporter = dataTableImporter; this.variableImporter = variableImporter; this.tagImporter = tagImporter; this.folderImporter = folderImporter; this.workflowImporter = workflowImporter; this.workflowPublisher = workflowPublisher; this.nodeTypes = nodeTypes; this.licenseState = licenseState; } async assertNotBlocked(plans, options) { const creations = plans.flatMap((plan) => plan.variablePlan.creations); const overwrites = plans.flatMap((plan) => plan.variablePlan.overwrites); (0, import_gates_1.assertVariableWritesAllowed)({ licenseState: this.licenseState, apiKeyScopes: options.apiKeyScopes, hasCreations: creations.length > 0, hasOverwrites: overwrites.length > 0, }); for (const { input, variablePlan } of plans) { if (variablePlan.creations.length > 0) { await this.variableImporter.assertCanCreate(input.context, variablePlan.creations, input.projectPendingCreation ?? false); } if (variablePlan.overwrites.length > 0) { await this.variableImporter.assertCanUpdate(input.context, variablePlan.overwrites); } } const issues = plans.flatMap((plan) => plan.blockingIssues); issues.push(...(0, tag_types_1.contestedReconcileTargetFailures)(plans.map((plan) => ({ tagPlan: plan.tagPlan, workflows: plan.workflowPlan.items.filter((item) => item.action !== 'skip'), }))).map((failure) => ({ type: 'tag-unresolved', ...failure }))); for (const conflict of (0, variable_types_1.divergentOverwrites)(overwrites)) { issues.push({ type: 'variable-conflict', ...conflict }); } const quotaFailure = await this.variableImporter.quotaFailure(creations); if (quotaFailure) issues.push({ type: 'variable-limit-exceeded', ...quotaFailure }); if (issues.length > 0) throw (0, import_blocked_error_1.toImportBlockedError)(issues); } async plan(input) { const { context, folders, workflows, credentialRequest, dataTableRequest, variableRequest, tagRequest, options, } = input; await this.workflowPublisher.assertCanPublish(context.user, context.projectId, options.workflowPublishingPolicy, input.projectPendingCreation); const credentialPlan = await this.credentialImporter.plan(context, credentialRequest); const dataTablePlan = await this.dataTableImporter.plan(context, dataTableRequest); const variablePlan = await this.variableImporter.plan(context, variableRequest); const workflowPlan = await this.workflowImporter.plan(context, workflows, options); const tagPlan = await this.tagImporter.plan(context, tagRequest, workflowPlan.items.filter((item) => item.action !== 'skip')); const folderContext = { ...context, folderConflictPolicy: options.folderConflictPolicy }; const folderPlan = await this.folderImporter.plan(folderContext, folders); const missingNodeTypes = (0, missing_node_type_mode_1.collectMissingNodeTypes)(workflowPlan.items.filter((item) => item.action !== 'skip'), (nodeType) => this.nodeTypes.getSupportedVersions(nodeType)); const blockingIssues = this.collectBlockingIssues({ workflowPlan, credentialPlan, credentialRequest, folderPlan, dataTablePlan, variableRequest, variablePlan, tagPlan, missingNodeTypes, missingNodeTypeMode: options.missingNodeTypeMode, }); return { input, folderContext, credentialPlan, workflowPlan, folderPlan, dataTablePlan, variablePlan, tagPlan, missingNodeTypes, blockingIssues, }; } async apply(plan, seedWorkflowBindings) { const { input, folderContext, credentialPlan, workflowPlan, folderPlan, dataTablePlan, variablePlan, tagPlan, } = plan; const { context, credentialRequest } = input; await this.tagImporter.apply(context, tagPlan); const folderSummaries = await this.folderImporter.apply(folderContext, folderPlan); const credentialResult = await this.credentialImporter.apply(context, credentialRequest, credentialPlan); await this.dataTableImporter.apply(context, dataTablePlan); const blockedFromPublish = new Map(); for (const sourceWorkflowId of (0, credential_missing_mode_1.workflowsBlockedFromPublish)(credentialRequest.requirements, new Set(credentialResult.stubbed))) { blockedFromPublish.set(sourceWorkflowId, 'stub-credential'); } for (const sourceWorkflowId of (0, missing_node_type_mode_1.workflowsWithMissingNodeTypes)(plan.missingNodeTypes)) { blockedFromPublish.set(sourceWorkflowId, 'missing-node-type'); } const { outcomes, bindings } = await this.workflowImporter.apply({ ...context, droppedTagIds: (0, tag_types_1.droppedTagIds)(tagPlan) }, workflowPlan, (0, n8n_packages_types_1.createBindings)({ credentials: credentialResult.bindings, ...(seedWorkflowBindings ? { workflows: seedWorkflowBindings } : {}), })); const variableResult = await this.variableImporter.apply(context, variablePlan); return { workflowOutcomes: outcomes.map((outcome) => withBlockedFromPublish(outcome, blockedFromPublish.get(outcome.sourceWorkflowId))), folderSummaries, bindings, credentialResult, dataTablePlan, variablePlan, variableResult, tagPlan, }; } collectBlockingIssues({ workflowPlan, credentialPlan, credentialRequest, folderPlan, dataTablePlan, variableRequest, variablePlan, tagPlan, missingNodeTypes, missingNodeTypeMode, }) { return [ ...workflowPlan.conflicts.map((conflict) => ({ type: 'workflow-conflict', ...conflict })), ...workflowPlan.idConflicts.map((conflict) => ({ type: 'workflow-id-conflict', ...conflict })), ...workflowPlan.folderConflicts.map((conflict) => ({ type: 'workflow-folder-conflict', ...conflict })), ...folderPlan.conflicts.map((conflict) => ({ type: 'folder-conflict', ...conflict })), ...dataTablePlan.failures.map((failure) => ({ type: 'data-table-unresolved', ...failure })), ...tagPlan.failures.map((failure) => ({ type: 'tag-unresolved', ...failure })), ...this.credentialImporter .blockingFailures(credentialRequest, credentialPlan) .map(toCredentialBlockingIssue), ...this.variableImporter .blockingFailures(variableRequest, variablePlan) .map((failure) => ({ type: 'variable-unresolved', ...failure })), ...this.variableImporter .blockingConflicts(variableRequest, variablePlan) .map((conflict) => ({ type: 'variable-conflict', ...conflict })), ...(0, missing_node_type_mode_1.missingNodeTypeBlockingFailures)(missingNodeTypeMode, missingNodeTypes).map(({ type, typeVersion, usedByWorkflows }) => ({ type: 'missing-node-type', nodeType: type, typeVersion, usedByWorkflows, })), ]; } }; exports.ImportOrchestrator = ImportOrchestrator; exports.ImportOrchestrator = ImportOrchestrator = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [credential_importer_1.CredentialImporter, data_table_importer_1.DataTableImporter, variable_importer_1.VariableImporter, tag_importer_1.TagImporter, folder_importer_1.FolderImporter, workflow_importer_1.WorkflowImporter, workflow_publisher_1.WorkflowPublisher, node_types_1.NodeTypes, backend_common_1.LicenseState]) ], ImportOrchestrator); function withBlockedFromPublish(outcome, blockedFromPublish) { if (outcome.status === 'skipped' || !blockedFromPublish) return outcome; return { ...outcome, blockedFromPublish }; } function toCredentialBlockingIssue(failure) { const { kind, sourceId, targetId, expectedType, actualType, usedByWorkflows } = failure; return { type: 'credential-unresolved', kind, sourceId, ...(targetId ? { targetId } : {}), ...(expectedType ? { expectedType } : {}), ...(actualType ? { actualType } : {}), usedByWorkflows, }; } //# sourceMappingURL=import-orchestrator.js.map