UNPKG

n8n

Version:

n8n Workflow Automation Tool

198 lines • 10.3 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.AutoIncludedWorkflowExporter = void 0; const di_1 = require("@n8n/di"); const n8n_workflow_1 = require("n8n-workflow"); const workflow_serializer_1 = require("./workflow.serializer"); const unique_filename_allocator_1 = require("../../io/unique-filename-allocator"); const credential_requirements_extractor_1 = require("../credential/credential-requirements.extractor"); const data_table_requirements_extractor_1 = require("../data-table/data-table-requirements.extractor"); const folder_serializer_1 = require("../folder/folder.serializer"); const project_serializer_1 = require("../project/project.serializer"); const variable_requirements_extractor_1 = require("../variable/variable-requirements.extractor"); let AutoIncludedWorkflowExporter = class AutoIncludedWorkflowExporter { constructor(workflowSerializer, folderSerializer, projectSerializer, credentialRequirementsExtractor, dataTableRequirementsExtractor, variableRequirementsExtractor) { this.workflowSerializer = workflowSerializer; this.folderSerializer = folderSerializer; this.projectSerializer = projectSerializer; this.credentialRequirementsExtractor = credentialRequirementsExtractor; this.dataTableRequirementsExtractor = dataTableRequirementsExtractor; this.variableRequirementsExtractor = variableRequirementsExtractor; } export(request) { const allocators = { workflows: new Map(), folders: new Map(), project: new unique_filename_allocator_1.UniqueFilenameAllocator('projects', 'project'), }; const workflowEntriesById = new Map(request.existingWorkflowEntries.map((entry) => [entry.id, entry])); const folderEntriesById = new Map(request.existingFolderEntries.map((entry) => [entry.id, entry])); const projectEntriesById = new Map(request.existingProjectEntries.map((entry) => [entry.id, entry])); const projectTargetsById = new Map(request.projectTargetsById); for (const entry of request.existingWorkflowEntries) { allocatorFor(allocators.workflows, parentDir(entry.target), 'workflow').reservePath(entry.target); } for (const entry of request.existingFolderEntries) { allocatorFor(allocators.folders, parentDir(entry.target), 'folder').reservePath(entry.target); } for (const entry of request.existingProjectEntries) { allocators.project.reservePath(entry.target); projectTargetsById.set(entry.id, entry.target); } const workflowEntries = []; const folderEntries = []; const projectEntries = []; const credentials = []; const dataTables = []; const variables = []; const nodeTypes = []; for (const included of request.workflows) { if (workflowEntriesById.has(included.workflow.id)) continue; const baseDir = this.resolveWorkflowBaseDir({ included, writer: request.writer, folderEntriesById, projectEntriesById, projectTargetsById, folderEntries, projectEntries, allocators, }); const entry = this.writeWorkflow(included.workflow, baseDir, request.writer, allocators.workflows); workflowEntries.push(entry); workflowEntriesById.set(entry.id, entry); credentials.push(...this.credentialRequirementsExtractor.extract(included.workflow)); dataTables.push(...this.dataTableRequirementsExtractor.extract(included.workflow)); variables.push(...this.variableRequirementsExtractor.extract(included.workflow)); nodeTypes.push({ workflowId: included.workflow.id, nodes: included.workflow.nodes ?? [], }); } return { workflowEntries, folderEntries, projectEntries, requirements: { credentials, dataTables, variables, nodeTypes }, projectTargetsById, }; } resolveWorkflowBaseDir(options) { const { included } = options; if (included.placement === 'project') { const projectTarget = this.ensureProjectShell({ project: included.ownerProject, writer: options.writer, projectEntriesById: options.projectEntriesById, projectTargetsById: options.projectTargetsById, projectEntries: options.projectEntries, allocator: options.allocators.project, }); if (included.folderChain.length === 0) { return `${projectTarget}/workflows`; } const folderTarget = this.ensureFolderChain({ chain: included.folderChain, baseDir: `${projectTarget}/folders`, writer: options.writer, folderEntriesById: options.folderEntriesById, folderEntries: options.folderEntries, allocators: options.allocators.folders, }); return `${folderTarget}/workflows`; } if (included.placement === 'folder' && included.folderChain.length > 0) { const folderTarget = this.ensureFolderChain({ chain: included.folderChain, baseDir: 'folders', writer: options.writer, folderEntriesById: options.folderEntriesById, folderEntries: options.folderEntries, allocators: options.allocators.folders, }); return `${folderTarget}/workflows`; } return 'workflows'; } ensureProjectShell(options) { const existing = options.projectEntriesById.get(options.project.id); if (existing) return existing.target; const target = options.allocator.allocate(options.project.name); const serialized = this.projectSerializer.serialize(options.project); options.writer.writeDirectory(target); options.writer.writeFile(`${target}/project.json`, JSON.stringify(serialized, null, '\t')); const entry = { id: options.project.id, name: options.project.name, target }; options.projectEntries.push(entry); options.projectEntriesById.set(entry.id, entry); options.projectTargetsById.set(entry.id, entry.target); return target; } ensureFolderChain(options) { let parentTarget; let effectiveParentId = null; for (const folder of options.chain) { const existing = options.folderEntriesById.get(folder.id); if (existing) { parentTarget = existing.target; effectiveParentId = folder.id; continue; } const allocator = allocatorFor(options.allocators, parentTarget ?? options.baseDir, 'folder'); if (parentTarget) allocator.reserve('workflows'); const target = allocator.allocate(folder.name); const serialized = this.folderSerializer.serialize(folder, effectiveParentId); options.writer.writeDirectory(target); options.writer.writeFile(`${target}/folder.json`, JSON.stringify(serialized, null, '\t')); const entry = { id: folder.id, name: folder.name, target }; options.folderEntries.push(entry); options.folderEntriesById.set(entry.id, entry); parentTarget = target; effectiveParentId = folder.id; } if (!parentTarget) { throw new n8n_workflow_1.UnexpectedError('Cannot place workflow in an empty folder chain', { extra: { baseDir: options.baseDir, folderIds: options.chain.map((folder) => folder.id), }, }); } return parentTarget; } writeWorkflow(workflow, baseDir, writer, allocators) { const target = allocatorFor(allocators, baseDir, 'workflow').allocate(workflow.name); const serialized = this.workflowSerializer.serialize(workflow); writer.writeDirectory(target); writer.writeFile(`${target}/workflow.json`, JSON.stringify(serialized, null, '\t')); return { id: workflow.id, name: workflow.name, target }; } }; exports.AutoIncludedWorkflowExporter = AutoIncludedWorkflowExporter; exports.AutoIncludedWorkflowExporter = AutoIncludedWorkflowExporter = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [workflow_serializer_1.WorkflowSerializer, folder_serializer_1.FolderSerializer, project_serializer_1.ProjectSerializer, credential_requirements_extractor_1.CredentialRequirementsExtractor, data_table_requirements_extractor_1.DataTableRequirementsExtractor, variable_requirements_extractor_1.VariableRequirementsExtractor]) ], AutoIncludedWorkflowExporter); function parentDir(path) { return path.split('/').slice(0, -1).join('/'); } function allocatorFor(allocators, baseDir, fallback) { const existing = allocators.get(baseDir); if (existing) return existing; const allocator = new unique_filename_allocator_1.UniqueFilenameAllocator(baseDir, fallback); allocators.set(baseDir, allocator); return allocator; } //# sourceMappingURL=auto-included-workflow.exporter.js.map