UNPKG

n8n

Version:

n8n Workflow Automation Tool

254 lines • 15 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.N8nPackagesService = void 0; const di_1 = require("@n8n/di"); const n8n_core_1 = require("n8n-core"); const constants_1 = require("../../constants"); const forbidden_error_1 = require("../../errors/response-errors/forbidden.error"); const event_service_1 = require("../../events/event.service"); const n8n_package_parser_1 = require("./engine/n8n-package-parser"); const project_package_importer_1 = require("./engine/project-package-importer"); const workflow_package_importer_1 = require("./engine/workflow-package-importer"); const credential_exporter_1 = require("./entities/credential/credential.exporter"); const data_table_exporter_1 = require("./entities/data-table/data-table.exporter"); const folder_exporter_1 = require("./entities/folder/folder.exporter"); const package_export_errors_1 = require("./entities/package-export.errors"); const project_exporter_1 = require("./entities/project/project.exporter"); const requirements_types_1 = require("./entities/requirements.types"); const variable_exporter_1 = require("./entities/variable/variable.exporter"); const node_type_usage_1 = require("./entities/workflow/node-type-usage"); const static_sub_workflow_requirements_1 = require("./entities/workflow/static-sub-workflow-requirements"); const auto_included_workflow_resolver_1 = require("./entities/workflow/auto-included-workflow-resolver"); const auto_included_workflow_exporter_1 = require("./entities/workflow/auto-included-workflow.exporter"); const workflow_dependency_resolver_1 = require("./entities/workflow/workflow-dependency-resolver"); const workflow_requirement_exporter_1 = require("./entities/workflow/workflow-requirement.exporter"); const workflow_exporter_1 = require("./entities/workflow/workflow.exporter"); const tar_package_reader_1 = require("./io/tar/tar-package-reader"); const tar_package_writer_1 = require("./io/tar/tar-package-writer"); const n8n_packages_config_1 = require("./n8n-packages.config"); const n8n_packages_types_1 = require("./n8n-packages.types"); const constants_2 = require("./spec/constants"); const manifest_schema_1 = require("./spec/manifest.schema"); let N8nPackagesService = class N8nPackagesService { constructor(projectExporter, workflowExporter, folderExporter, credentialExporter, dataTableExporter, variableExporter, instanceSettings, packageParser, packageImportConfig, projectPackageImporter, workflowPackageImporter, eventService, workflowRequirementExporter, workflowDependencyResolver, autoIncludedWorkflowResolver, autoIncludedWorkflowExporter) { this.projectExporter = projectExporter; this.workflowExporter = workflowExporter; this.folderExporter = folderExporter; this.credentialExporter = credentialExporter; this.dataTableExporter = dataTableExporter; this.variableExporter = variableExporter; this.instanceSettings = instanceSettings; this.packageParser = packageParser; this.packageImportConfig = packageImportConfig; this.projectPackageImporter = projectPackageImporter; this.workflowPackageImporter = workflowPackageImporter; this.eventService = eventService; this.workflowRequirementExporter = workflowRequirementExporter; this.workflowDependencyResolver = workflowDependencyResolver; this.autoIncludedWorkflowResolver = autoIncludedWorkflowResolver; this.autoIncludedWorkflowExporter = autoIncludedWorkflowExporter; } async exportPackage(request) { const { missingWorkflowDependencyPolicy } = request; if (missingWorkflowDependencyPolicy === n8n_packages_types_1.MissingWorkflowDependencyPolicy.ReferenceOnly) { throw new package_export_errors_1.PackageExportBlockedError('Reference-only static sub-workflow dependencies are not supported. Export aborted.'); } const writer = new tar_package_writer_1.TarPackageWriter(); const workflowIds = request.workflowIds ?? []; const folderIds = request.folderIds ?? []; const projectIds = request.projectIds ?? []; const folderExportResult = folderIds.length > 0 ? await this.folderExporter.export({ user: request.user, folderIds, writer, }) : undefined; const workflowsForExport = this.filterWorkflowsAlreadyInFolders(folderExportResult?.workflowEntries, workflowIds); const workflowExportResult = workflowsForExport.length > 0 ? await this.workflowExporter.export({ user: request.user, workflowIds: workflowsForExport, writer, }) : undefined; const projectExportResult = projectIds.length > 0 ? await this.projectExporter.export({ user: request.user, projectIds, writer, }) : undefined; const allFoldersBeforeAutoInclude = [ ...(folderExportResult?.entries ?? []), ...(projectExportResult?.folderEntries ?? []), ]; const allProjectsBeforeAutoInclude = [...(projectExportResult?.entries ?? [])]; const allWorkflowsBeforeAutoInclude = [ ...(workflowExportResult?.entries ?? []), ...(folderExportResult?.workflowEntries ?? []), ...(projectExportResult?.workflowEntries ?? []), ]; const workflowRequirements = await this.workflowDependencyResolver.resolve({ user: request.user, workflowIds: allWorkflowsBeforeAutoInclude.map(({ id }) => id), }); let autoIncludedExportResult; if (missingWorkflowDependencyPolicy === n8n_packages_types_1.MissingWorkflowDependencyPolicy.IncludeInPackage) { const autoIncludedWorkflowResolution = await this.autoIncludedWorkflowResolver.resolve({ user: request.user, requirements: workflowRequirements, topLevelWorkflowIds: workflowExportResult?.entries.map(({ id }) => id) ?? [], folderWorkflowIds: folderExportResult?.workflowEntries.map(({ id }) => id) ?? [], projectWorkflowIds: projectExportResult?.workflowEntries.map(({ id }) => id) ?? [], }); autoIncludedExportResult = this.autoIncludedWorkflowExporter.export({ writer, workflows: autoIncludedWorkflowResolution.autoIncludedWorkflows, existingWorkflowEntries: allWorkflowsBeforeAutoInclude, existingFolderEntries: allFoldersBeforeAutoInclude, existingProjectEntries: allProjectsBeforeAutoInclude, projectTargetsById: projectExportResult?.projectTargetsById, }); } const requirements = (0, requirements_types_1.mergeRequirements)(workflowExportResult?.requirements, folderExportResult?.requirements, projectExportResult?.requirements, autoIncludedExportResult?.requirements); const includeVariableValues = request.includeVariableValues ?? true; if (includeVariableValues && requirements.variables.length > 0 && request.canExportVariableValues === false) { throw new forbidden_error_1.ForbiddenError('The exported workflows reference variables, but the API key is missing the variable:list scope needed to bundle their values. Add the scope or set includeVariableValues to false.'); } const allFolders = this.dedupeManifestEntries([ ...allFoldersBeforeAutoInclude, ...(autoIncludedExportResult?.folderEntries ?? []), ]); const allProjects = this.dedupeManifestEntries([ ...allProjectsBeforeAutoInclude, ...(autoIncludedExportResult?.projectEntries ?? []), ]); const allWorkflowsInPackage = this.dedupeManifestEntries([ ...allWorkflowsBeforeAutoInclude, ...(autoIncludedExportResult?.workflowEntries ?? []), ]); (0, static_sub_workflow_requirements_1.assertStaticSubWorkflowsIncluded)(workflowRequirements, new Set(allWorkflowsInPackage.map(({ id }) => id))); const projectTargetsById = autoIncludedExportResult?.projectTargetsById ?? projectExportResult?.projectTargetsById; const credentialExportResult = await this.credentialExporter.export({ user: request.user, requirements: requirements.credentials, writer, projectTargetsById, }); const dataTableExportResult = await this.dataTableExporter.export({ user: request.user, requirements: requirements.dataTables, writer, projectTargetsById, }); const workflowRequirementExportResult = this.workflowRequirementExporter.export({ requirements: workflowRequirements, workflows: allWorkflowsInPackage, }); const variableExportResult = await this.variableExporter.export({ user: request.user, requirements: requirements.variables, writer, includeVariableValues, projectTargetsById, }); const manifestRequirements = this.buildManifestRequirements({ credentials: credentialExportResult.requirements, dataTables: dataTableExportResult.requirements, workflows: workflowRequirementExportResult.requirements, variables: variableExportResult.requirements, nodeTypes: (0, node_type_usage_1.collectNodeTypeUsage)(requirements.nodeTypes), }); const manifest = manifest_schema_1.packageManifestSchema.parse({ packageFormatVersion: constants_2.FORMAT_VERSION, exportedAt: new Date().toISOString(), sourceN8nVersion: constants_1.N8N_VERSION, sourceId: this.instanceSettings.instanceId, ...(credentialExportResult.entries.length > 0 ? { credentials: credentialExportResult.entries } : {}), ...(dataTableExportResult.entries.length > 0 ? { dataTables: dataTableExportResult.entries } : {}), ...(variableExportResult.entries.length > 0 ? { variables: variableExportResult.entries } : {}), ...(manifestRequirements ? { requirements: manifestRequirements } : {}), ...(allWorkflowsInPackage.length > 0 ? { workflows: allWorkflowsInPackage } : {}), ...(allFolders.length > 0 ? { folders: allFolders } : {}), ...(allProjects.length > 0 ? { projects: allProjects } : {}), }); writer.writeFile('manifest.json', JSON.stringify(manifest, null, '\t')); const stream = writer.finalize(); const counts = { workflows: allWorkflowsInPackage.length, folders: allFolders.length, credentials: credentialExportResult.entries.length, dataTables: dataTableExportResult.entries.length, variables: variableExportResult.entries.length, }; this.eventService.emit('n8n-package-exported', { user: request.user, ...(allWorkflowsInPackage.length ? { workflowIds: allWorkflowsInPackage.map(({ id }) => id) } : {}), ...(allFolders.length ? { folderIds: allFolders.map(({ id }) => id) } : {}), ...(allProjects.length ? { projectIds: allProjects.map(({ id }) => id) } : {}), counts, }); return { stream, counts }; } async importPackage(request) { const reader = new tar_package_reader_1.TarPackageReader(request.packageBuffer, this.packageImportConfig); const manifest = await this.packageParser.getManifest(reader); if (isProjectPackage(manifest)) { return await this.projectPackageImporter.import(request, reader, manifest); } return await this.workflowPackageImporter.import(request, reader, manifest); } filterWorkflowsAlreadyInFolders(workflowsInFolders = [], workflowIds) { const folderWorkflowIds = new Set(workflowsInFolders.map((entry) => entry.id) ?? []); return workflowIds.filter((id) => !folderWorkflowIds.has(id)); } dedupeManifestEntries(entries) { const byId = new Map(); for (const entry of entries) { if (!byId.has(entry.id)) { byId.set(entry.id, entry); } } return [...byId.values()]; } buildManifestRequirements(input) { const { credentials, dataTables, workflows, variables, nodeTypes } = input; const requirements = { ...(credentials?.length ? { credentials } : {}), ...(dataTables?.length ? { dataTables } : {}), ...(workflows?.length ? { workflows } : {}), ...(variables?.length ? { variables } : {}), ...(nodeTypes?.length ? { nodeTypes } : {}), }; return Object.keys(requirements).length > 0 ? requirements : undefined; } }; exports.N8nPackagesService = N8nPackagesService; exports.N8nPackagesService = N8nPackagesService = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [project_exporter_1.ProjectExporter, workflow_exporter_1.WorkflowExporter, folder_exporter_1.FolderExporter, credential_exporter_1.CredentialExporter, data_table_exporter_1.DataTableExporter, variable_exporter_1.VariableExporter, n8n_core_1.InstanceSettings, n8n_package_parser_1.N8nPackageParser, n8n_packages_config_1.PackageImportConfig, project_package_importer_1.ProjectPackageImporter, workflow_package_importer_1.WorkflowPackageImporter, event_service_1.EventService, workflow_requirement_exporter_1.WorkflowRequirementExporter, workflow_dependency_resolver_1.WorkflowDependencyResolver, auto_included_workflow_resolver_1.AutoIncludedWorkflowResolver, auto_included_workflow_exporter_1.AutoIncludedWorkflowExporter]) ], N8nPackagesService); function isProjectPackage(manifest) { return (manifest.projects?.length ?? 0) > 0; } //# sourceMappingURL=n8n-packages.service.js.map