n8n
Version:
n8n Workflow Automation Tool
279 lines • 12.6 kB
JavaScript
"use strict";
const config_1 = require("@n8n/config");
const db_1 = require("@n8n/db");
const di_1 = require("@n8n/di");
const n8n_workflow_1 = require("n8n-workflow");
const zod_1 = require("zod");
const folder_not_found_error_1 = require("../../../../errors/folder-not-found.error");
const response_error_1 = require("../../../../errors/response-errors/abstract/response.error");
const bad_request_error_1 = require("../../../../errors/response-errors/bad-request.error");
const not_found_error_1 = require("../../../../errors/response-errors/not-found.error");
const event_service_1 = require("../../../../events/event.service");
const redaction_enforcement_service_1 = require("../../../../modules/redaction/redaction-enforcement.service");
const tag_service_1 = require("../../../../services/tag.service");
const workflow_creation_service_1 = require("../../../../workflows/workflow-creation.service");
const workflow_entity_mapper_1 = require("../../../../workflows/workflow-entity-mapper");
const workflow_finder_service_1 = require("../../../../workflows/workflow-finder.service");
const workflow_history_service_1 = require("../../../../workflows/workflow-history/workflow-history.service");
const workflow_service_1 = require("../../../../workflows/workflow.service");
const workflow_service_ee_1 = require("../../../../workflows/workflow.service.ee");
const global_middleware_1 = require("../../shared/middlewares/global.middleware");
const pagination_service_1 = require("../../shared/services/pagination.service");
const handleError = (error) => {
if (error instanceof folder_not_found_error_1.FolderNotFoundError) {
throw new not_found_error_1.NotFoundError(error.message);
}
if (error instanceof response_error_1.ResponseError) {
throw error;
}
if (error instanceof Error) {
throw new bad_request_error_1.BadRequestError(error.message);
}
throw error;
};
function parseTagNames(tags) {
return tags.split(',').map((tag) => tag.trim());
}
function areWorkflowTagsEnabled() {
return !di_1.Container.get(config_1.GlobalConfig).tags.disabled;
}
const publishWorkflow = [
(0, global_middleware_1.publicApiScope)('workflow:activate'),
(0, global_middleware_1.projectScope)('workflow:publish', 'workflow'),
async (req, res) => {
const { id } = req.params;
const { versionId, name, description } = req.body;
try {
const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).activateWorkflow(req.user, id, {
versionId,
name,
description,
source: 'api',
});
return res.json(workflow);
}
catch (error) {
return handleError(error);
}
},
];
const unpublishWorkflow = [
(0, global_middleware_1.publicApiScope)('workflow:deactivate'),
(0, global_middleware_1.projectScope)('workflow:unpublish', 'workflow'),
async (req, res) => {
const { id } = req.params;
try {
const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).deactivateWorkflow(req.user, id, {
source: 'api',
});
return res.json(workflow);
}
catch (error) {
return handleError(error);
}
},
];
const workflowHandlers = {
createWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:create'),
async (req, res) => {
const { projectId, parentFolderId, ...rest } = req.body;
if (rest.settings?.binaryMode !== undefined) {
delete rest.settings.binaryMode;
}
if (rest.settings?.credentialResolverId !== undefined) {
delete rest.settings.credentialResolverId;
}
const workflow = (0, workflow_entity_mapper_1.createWorkflowEntityFromPayload)(rest);
await di_1.Container.get(redaction_enforcement_service_1.RedactionEnforcementService).assertNewPolicyAllowed(workflow.settings?.redactionPolicy);
const createdWorkflow = await di_1.Container.get(workflow_creation_service_1.WorkflowCreationService).createWorkflow(req.user, workflow, {
projectId,
parentFolderId: parentFolderId ?? undefined,
publicApi: true,
source: 'api',
});
return res.json(createdWorkflow);
},
],
transferWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:move'),
(0, global_middleware_1.projectScope)('workflow:move', 'workflow'),
async (req, res) => {
const { id: workflowId } = req.params;
const body = zod_1.z.object({ destinationProjectId: zod_1.z.string() }).parse(req.body);
await di_1.Container.get(workflow_service_ee_1.EnterpriseWorkflowService).transferWorkflow(req.user, workflowId, body.destinationProjectId);
return res.status(204).send();
},
],
deleteWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:delete'),
(0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
async (req, res) => {
const { id: workflowId } = req.params;
const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).delete(req.user, workflowId, true);
if (!workflow) {
throw new not_found_error_1.NotFoundError('Not Found');
}
return res.json(workflow);
},
],
getWorkflowVersion: [
(0, global_middleware_1.publicApiScope)('workflow:read'),
(0, global_middleware_1.projectScope)('workflow:read', 'workflow'),
async (req, res) => {
const { id: workflowId, versionId } = req.params;
try {
const version = await di_1.Container.get(workflow_history_service_1.WorkflowHistoryService).getVersion(req.user, workflowId, versionId, { includePublishHistory: false });
di_1.Container.get(event_service_1.EventService).emit('user-retrieved-workflow-version', {
userId: req.user.id,
publicApi: true,
});
const { autosaved, ...versionWithoutInternalFields } = version;
return res.json(versionWithoutInternalFields);
}
catch {
throw new not_found_error_1.NotFoundError('Version not found');
}
},
],
getWorkflows: [
(0, global_middleware_1.publicApiScope)('workflow:list'),
global_middleware_1.validCursor,
async (req, res) => {
const { offset = 0, limit = 100, excludePinnedData = false, active, tags, name, projectId, } = req.query;
const { workflows, count } = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findWorkflowsForUser(req.user, ['workflow:read'], {
filters: {
name,
active,
tagNames: tags ? parseTagNames(tags) : undefined,
projectId,
},
offset,
limit,
includePinnedData: !excludePinnedData,
includeTags: areWorkflowTagsEnabled(),
includeActiveVersion: true,
});
di_1.Container.get(event_service_1.EventService).emit('user-retrieved-all-workflows', {
userId: req.user.id,
publicApi: true,
});
return res.json({
data: workflows,
nextCursor: (0, pagination_service_1.encodeNextCursor)({
offset,
limit,
numberOfTotalRecords: count,
}),
});
},
],
updateWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:update'),
(0, global_middleware_1.projectScope)('workflow:update', 'workflow'),
async (req, res) => {
const { id } = req.params;
const { parentFolderId, ...rest } = req.body;
const updateData = new db_1.WorkflowEntity();
Object.assign(updateData, rest);
const resolvedParentFolderId = parentFolderId === null ? n8n_workflow_1.PROJECT_ROOT : parentFolderId;
const { publishIfActive = true } = req.query;
if (updateData.settings?.binaryMode !== undefined) {
delete updateData.settings.binaryMode;
}
if (updateData.settings?.credentialResolverId !== undefined) {
delete updateData.settings.credentialResolverId;
}
try {
const updatedWorkflow = await di_1.Container.get(workflow_service_1.WorkflowService).update(req.user, updateData, id, {
parentFolderId: resolvedParentFolderId,
forceSave: true,
publicApi: true,
publishIfActive,
source: 'api',
});
return res.json(updatedWorkflow);
}
catch (error) {
return handleError(error);
}
},
],
publishWorkflow,
unpublishWorkflow,
activateWorkflow: [(0, global_middleware_1.deprecated)({ since: new Date('2026-07-23T00:00:00Z') }), ...publishWorkflow],
deactivateWorkflow: [
(0, global_middleware_1.deprecated)({ since: new Date('2026-07-23T00:00:00Z') }),
...unpublishWorkflow,
],
getWorkflowTags: [
(0, global_middleware_1.publicApiScope)('workflowTags:list'),
(0, global_middleware_1.projectScope)('workflow:read', 'workflow'),
async (req, res) => {
const { id } = req.params;
if (!areWorkflowTagsEnabled()) {
throw new bad_request_error_1.BadRequestError('Workflow Tags Disabled');
}
const workflow = await di_1.Container.get(workflow_finder_service_1.WorkflowFinderService).findWorkflowForUser(id, req.user, ['workflow:read']);
if (!workflow) {
throw new not_found_error_1.NotFoundError('Not Found');
}
const tags = await di_1.Container.get(tag_service_1.TagService).getAllByWorkflowId(id);
return res.json(tags);
},
],
updateWorkflowTags: [
(0, global_middleware_1.publicApiScope)('workflowTags:update'),
(0, global_middleware_1.projectScope)('workflow:update', 'workflow'),
async (req, res) => {
const { id } = req.params;
const newTags = req.body.map((newTag) => newTag.id);
if (!areWorkflowTagsEnabled()) {
throw new bad_request_error_1.BadRequestError('Workflow Tags Disabled');
}
try {
const tags = await di_1.Container.get(workflow_service_1.WorkflowService).updateWorkflowTags(req.user, id, newTags);
return res.json(tags);
}
catch (error) {
return handleError(error);
}
},
],
archiveWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:delete'),
(0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
async (req, res) => {
const { id } = req.params;
try {
const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).archiveForPublicApi(req.user, id);
if (!workflow) {
throw new not_found_error_1.NotFoundError('Workflow not found');
}
return res.json(workflow);
}
catch (error) {
return handleError(error);
}
},
],
unarchiveWorkflow: [
(0, global_middleware_1.publicApiScope)('workflow:delete'),
(0, global_middleware_1.projectScope)('workflow:delete', 'workflow'),
async (req, res) => {
const { id } = req.params;
try {
const workflow = await di_1.Container.get(workflow_service_1.WorkflowService).unarchiveForPublicApi(req.user, id);
if (!workflow) {
throw new not_found_error_1.NotFoundError('Workflow not found');
}
return res.json(workflow);
}
catch (error) {
return handleError(error);
}
},
],
};
module.exports = workflowHandlers;
//# sourceMappingURL=workflows.handler.js.map