n8n
Version:
n8n Workflow Automation Tool
254 lines • 15 kB
JavaScript
;
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