UNPKG

n8n

Version:

n8n Workflow Automation Tool

195 lines • 10.9 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.ProjectPackageImporter = void 0; const backend_common_1 = require("@n8n/backend-common"); const di_1 = require("@n8n/di"); const forbidden_error_1 = require("../../../errors/response-errors/forbidden.error"); const event_service_1 = require("../../../events/event.service"); const project_importer_1 = require("../entities/project/project-importer"); 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_gates_1 = require("./import-gates"); const import_blocked_error_1 = require("./import-blocked.error"); const package_layout_1 = require("./package-layout"); const import_orchestrator_1 = require("./import-orchestrator"); const import_result_1 = require("./import-result"); const import_telemetry_1 = require("./import-telemetry"); const n8n_package_parser_1 = require("./n8n-package-parser"); let ProjectPackageImporter = class ProjectPackageImporter { constructor(packageParser, projectImporter, importOrchestrator, workflowPublisher, eventService, licenseState) { this.packageParser = packageParser; this.projectImporter = projectImporter; this.importOrchestrator = importOrchestrator; this.workflowPublisher = workflowPublisher; this.eventService = eventService; this.licenseState = licenseState; } async import(request, reader, manifest) { this.assertAdequatePermissions(request, manifest); const projects = await this.packageParser.getProjects(reader); const projectPlan = await this.projectImporter.plan(request.user, projects, request.projectConflictPolicy); if (projectPlan.conflicts.length > 0) { throw (0, import_blocked_error_1.toImportBlockedError)(projectPlan.conflicts.map((conflict) => ({ type: 'project-conflict', ...conflict }))); } const bundledVariables = (0, package_layout_1.needsBundledVariableValues)(request, (manifest.requirements?.variables?.length ?? 0) > 0) ? await this.packageParser.getVariables(reader) : undefined; const pendingCreateIds = new Set(projectPlan.items .filter((item) => item.action === 'create') .map((item) => item.sourceProjectId)); const planned = []; for (const project of manifest.projects ?? []) { const input = await this.buildImportContextForProject(request, reader, manifest, project, pendingCreateIds.has(project.id), bundledVariables); const plan = await this.importOrchestrator.plan(input); planned.push({ project, plan }); } (0, import_gates_1.assertTagWritesAllowed)(request.apiKeyScopes, planned.map(({ plan }) => plan.tagPlan)); await this.importOrchestrator.assertNotBlocked(planned.map(({ plan }) => plan), { apiKeyScopes: request.apiKeyScopes }); const projectSummaries = await this.projectImporter.apply(request.user, projectPlan.items); const packageWorkflowBindings = new Map(planned.flatMap(({ plan }) => [...(0, workflow_importer_1.collectPlannedWorkflowBindings)(plan.workflowPlan.items)])); const applied = []; for (const { project, plan } of planned) { applied.push({ project, plan, content: await this.importOrchestrator.apply(plan, packageWorkflowBindings), }); } const published = await this.workflowPublisher.applyToPackage({ user: request.user, persisted: applied.flatMap(({ content }) => content.workflowOutcomes), policy: request.workflowPublishingPolicy, subWorkflowRequirements: manifest.requirements?.workflows, }); const workflows = []; const folders = []; const scopedBindings = []; const matched = []; const stubbed = []; const variablesMatched = []; const variablesMissing = []; const variablesCreated = []; const variablesStubbed = []; const variablesSkipped = []; const variablesUpdated = []; const tagSummaries = []; const scopes = []; for (const { project, plan, content } of applied) { workflows.push(...(0, import_result_1.toImportedWorkflowSummaries)(content.workflowOutcomes, project.id, published)); folders.push(...content.folderSummaries); scopedBindings.push(content.bindings); matched.push(...content.credentialResult.matched); stubbed.push(...content.credentialResult.stubbed); variablesMatched.push(...content.variablePlan.matched); variablesMissing.push(...content.variablePlan.missing.map(({ name }) => name)); variablesCreated.push(...content.variableResult.created); variablesStubbed.push(...content.variableResult.stubbed); variablesSkipped.push(...content.variableResult.skippedExisting); variablesUpdated.push(...content.variableResult.updated); tagSummaries.push((0, import_result_1.toTagSummary)(content.tagPlan)); scopes.push({ context: plan.input.context, imported: content, credentialRequest: plan.input.credentialRequest, dataTableRequest: plan.input.dataTableRequest, variableRequest: plan.input.variableRequest, tagRequest: plan.input.tagRequest, }); } (0, import_telemetry_1.emitPackageImportedEvent)(this.eventService, { request, manifest, scopes }); return (0, import_result_1.buildImportResult)({ package: (0, import_result_1.toPackageSummary)(manifest), workflows, folders, projects: projectSummaries, bindings: (0, n8n_packages_types_1.mergeBindings)(...scopedBindings), credentials: { matched, stubbed }, variables: (0, import_result_1.reconcileVariableSummary)({ matched: variablesMatched, missing: variablesMissing, created: variablesCreated, stubbed: variablesStubbed, skipped: variablesSkipped, updated: variablesUpdated, }), tags: (0, import_result_1.unionTagSummaries)(tagSummaries), }); } async buildImportContextForProject(request, reader, manifest, project, projectPendingCreation, bundledVariables) { const basePrefix = `${project.target}/`; const folders = await this.packageParser.getFolders(reader, basePrefix); const workflows = await this.packageParser.getWorkflows(reader, basePrefix); const requirements = (0, import_result_1.identifyRequirements)(manifest.requirements?.credentials, workflows); const credentialRequest = { requirements, matchingMode: request.credentialMatchingMode, missingMode: request.credentialMissingMode, credentialBindings: (0, import_result_1.scopeCredentialBindingsToRequirements)(request.bindings?.credentials, requirements), }; const dataTableRequest = { requirements: (0, import_result_1.identifyRequirements)(manifest.requirements?.dataTables, workflows), packageDataTables: await this.packageParser.getDataTables(reader), matchingMode: request.dataTableMatchingMode, missingMode: request.dataTableMissingMode, schemaConflictPolicy: request.dataTableSchemaConflictPolicy, }; const variableRequest = { requirements: (0, package_layout_1.placeByLayout)({ requirements: (0, import_result_1.identifyRequirements)(manifest.requirements?.variables, workflows), manifestVariables: manifest.variables, scopePrefix: basePrefix, bundledVariables, }), missingMode: request.variableMissingMode, conflictPolicy: request.variableConflictPolicy, }; const tagRequest = { requirements: manifest.requirements?.tags, missingMode: request.tagMissingMode, conflictPolicy: request.tagConflictPolicy, }; return { context: { user: request.user, projectId: project.id, folderId: null, }, folders, workflows, credentialRequest, dataTableRequest, variableRequest, tagRequest, options: request, projectPendingCreation, }; } assertAdequatePermissions(request, manifest) { (0, import_gates_1.assertPackageImportApiKeyScopes)(request.apiKeyScopes, ['project:create', 'project:update']); if ((manifest.folders?.length ?? 0) > 0) { if (!this.licenseState.isLicensed('feat:folders')) { throw new forbidden_error_1.ForbiddenError('Your license does not allow folders. Importing a package with folders requires a license that supports folders.'); } (0, import_gates_1.assertPackageImportApiKeyScopes)(request.apiKeyScopes, ['folder:create', 'folder:update']); } if ((manifest.workflows?.length ?? 0) > 0) { (0, import_gates_1.assertPackageImportApiKeyScopes)(request.apiKeyScopes, ['workflow:import']); } } }; exports.ProjectPackageImporter = ProjectPackageImporter; exports.ProjectPackageImporter = ProjectPackageImporter = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [n8n_package_parser_1.N8nPackageParser, project_importer_1.ProjectImporter, import_orchestrator_1.ImportOrchestrator, workflow_publisher_1.WorkflowPublisher, event_service_1.EventService, backend_common_1.LicenseState]) ], ProjectPackageImporter); //# sourceMappingURL=project-package-importer.js.map