2024-02-08 06:13:29 -08:00
|
|
|
import type { DeepPartial } from '@n8n/typeorm';
|
2024-09-12 09:07:18 -07:00
|
|
|
import { NodeConnectionType } from 'n8n-workflow';
|
|
|
|
import Container from 'typedi';
|
2023-11-08 07:29:39 -08:00
|
|
|
import { v4 as uuid } from 'uuid';
|
2024-01-24 04:38:57 -08:00
|
|
|
|
2024-09-12 09:07:18 -07:00
|
|
|
import { Project } from '@/databases/entities/project';
|
|
|
|
import type { SharedWorkflow, WorkflowSharingRole } from '@/databases/entities/shared-workflow';
|
2024-08-28 08:57:46 -07:00
|
|
|
import { User } from '@/databases/entities/user';
|
2024-08-27 08:24:20 -07:00
|
|
|
import type { WorkflowEntity } from '@/databases/entities/workflow-entity';
|
2024-09-12 09:07:18 -07:00
|
|
|
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
2024-08-27 07:44:32 -07:00
|
|
|
import { SharedWorkflowRepository } from '@/databases/repositories/shared-workflow.repository';
|
2024-08-27 08:24:20 -07:00
|
|
|
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
2023-11-08 07:29:39 -08:00
|
|
|
|
|
|
|
export async function createManyWorkflows(
|
|
|
|
amount: number,
|
|
|
|
attributes: Partial<WorkflowEntity> = {},
|
|
|
|
user?: User,
|
|
|
|
) {
|
2024-01-17 07:08:50 -08:00
|
|
|
const workflowRequests = [...Array(amount)].map(
|
|
|
|
async (_) => await createWorkflow(attributes, user),
|
|
|
|
);
|
|
|
|
return await Promise.all(workflowRequests);
|
2023-11-08 07:29:39 -08:00
|
|
|
}
|
|
|
|
|
2024-04-12 08:25:59 -07:00
|
|
|
export function newWorkflow(attributes: Partial<WorkflowEntity> = {}): WorkflowEntity {
|
2023-11-08 07:29:39 -08:00
|
|
|
const { active, name, nodes, connections, versionId } = attributes;
|
|
|
|
|
|
|
|
const workflowEntity = Container.get(WorkflowRepository).create({
|
|
|
|
active: active ?? false,
|
|
|
|
name: name ?? 'test workflow',
|
|
|
|
nodes: nodes ?? [
|
|
|
|
{
|
|
|
|
id: 'uuid-1234',
|
|
|
|
name: 'Schedule Trigger',
|
|
|
|
parameters: {},
|
|
|
|
position: [-20, 260],
|
|
|
|
type: 'n8n-nodes-base.scheduleTrigger',
|
|
|
|
typeVersion: 1,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
connections: connections ?? {},
|
|
|
|
versionId: versionId ?? uuid(),
|
|
|
|
...attributes,
|
|
|
|
});
|
|
|
|
|
2024-04-12 08:25:59 -07:00
|
|
|
return workflowEntity;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Store a workflow in the DB (without a trigger) and optionally assign it to a user.
|
|
|
|
* @param attributes workflow attributes
|
|
|
|
* @param user user to assign the workflow to
|
|
|
|
*/
|
2024-05-17 01:53:15 -07:00
|
|
|
export async function createWorkflow(
|
|
|
|
attributes: Partial<WorkflowEntity> = {},
|
|
|
|
userOrProject?: User | Project,
|
|
|
|
) {
|
2024-04-12 08:25:59 -07:00
|
|
|
const workflow = await Container.get(WorkflowRepository).save(newWorkflow(attributes));
|
2023-11-08 07:29:39 -08:00
|
|
|
|
2024-05-17 01:53:15 -07:00
|
|
|
if (userOrProject instanceof User) {
|
|
|
|
const user = userOrProject;
|
|
|
|
const project = await Container.get(ProjectRepository).getPersonalProjectForUserOrFail(user.id);
|
|
|
|
await Container.get(SharedWorkflowRepository).save(
|
|
|
|
Container.get(SharedWorkflowRepository).create({
|
|
|
|
project,
|
|
|
|
workflow,
|
|
|
|
role: 'workflow:owner',
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (userOrProject instanceof Project) {
|
|
|
|
const project = userOrProject;
|
|
|
|
await Container.get(SharedWorkflowRepository).save(
|
|
|
|
Container.get(SharedWorkflowRepository).create({
|
|
|
|
project,
|
|
|
|
workflow,
|
|
|
|
role: 'workflow:owner',
|
|
|
|
}),
|
|
|
|
);
|
2023-11-08 07:29:39 -08:00
|
|
|
}
|
2024-05-17 01:53:15 -07:00
|
|
|
|
2023-11-08 07:29:39 -08:00
|
|
|
return workflow;
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function shareWorkflowWithUsers(workflow: WorkflowEntity, users: User[]) {
|
2024-05-17 01:53:15 -07:00
|
|
|
const sharedWorkflows: Array<DeepPartial<SharedWorkflow>> = await Promise.all(
|
|
|
|
users.map(async (user) => {
|
|
|
|
const project = await Container.get(ProjectRepository).getPersonalProjectForUserOrFail(
|
|
|
|
user.id,
|
|
|
|
);
|
|
|
|
return {
|
|
|
|
projectId: project.id,
|
|
|
|
workflowId: workflow.id,
|
|
|
|
role: 'workflow:editor',
|
|
|
|
};
|
|
|
|
}),
|
|
|
|
);
|
2024-01-17 07:08:50 -08:00
|
|
|
return await Container.get(SharedWorkflowRepository).save(sharedWorkflows);
|
2023-11-08 07:29:39 -08:00
|
|
|
}
|
|
|
|
|
2024-05-17 01:53:15 -07:00
|
|
|
export async function shareWorkflowWithProjects(
|
|
|
|
workflow: WorkflowEntity,
|
|
|
|
projectsWithRole: Array<{ project: Project; role?: WorkflowSharingRole }>,
|
|
|
|
) {
|
|
|
|
const newSharedWorkflow = await Promise.all(
|
|
|
|
projectsWithRole.map(async ({ project, role }) => {
|
|
|
|
return Container.get(SharedWorkflowRepository).create({
|
|
|
|
workflowId: workflow.id,
|
|
|
|
role: role ?? 'workflow:editor',
|
|
|
|
projectId: project.id,
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
return await Container.get(SharedWorkflowRepository).save(newSharedWorkflow);
|
|
|
|
}
|
|
|
|
|
2023-11-08 07:29:39 -08:00
|
|
|
export async function getWorkflowSharing(workflow: WorkflowEntity) {
|
2024-01-17 07:08:50 -08:00
|
|
|
return await Container.get(SharedWorkflowRepository).findBy({
|
2023-11-08 07:29:39 -08:00
|
|
|
workflowId: workflow.id,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Store a workflow in the DB (with a trigger) and optionally assign it to a user.
|
|
|
|
* @param user user to assign the workflow to
|
|
|
|
*/
|
|
|
|
export async function createWorkflowWithTrigger(
|
|
|
|
attributes: Partial<WorkflowEntity> = {},
|
|
|
|
user?: User,
|
|
|
|
) {
|
|
|
|
const workflow = await createWorkflow(
|
|
|
|
{
|
|
|
|
nodes: [
|
|
|
|
{
|
|
|
|
id: 'uuid-1',
|
|
|
|
parameters: {},
|
|
|
|
name: 'Start',
|
|
|
|
type: 'n8n-nodes-base.start',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [240, 300],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'uuid-2',
|
|
|
|
parameters: { triggerTimes: { item: [{ mode: 'everyMinute' }] } },
|
|
|
|
name: 'Cron',
|
|
|
|
type: 'n8n-nodes-base.cron',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [500, 300],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'uuid-3',
|
|
|
|
parameters: { options: {} },
|
|
|
|
name: 'Set',
|
|
|
|
type: 'n8n-nodes-base.set',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [780, 300],
|
|
|
|
},
|
|
|
|
],
|
2024-07-30 11:24:01 -07:00
|
|
|
connections: { Cron: { main: [[{ node: 'Set', type: NodeConnectionType.Main, index: 0 }]] } },
|
2023-11-08 07:29:39 -08:00
|
|
|
...attributes,
|
|
|
|
},
|
|
|
|
user,
|
|
|
|
);
|
|
|
|
|
|
|
|
return workflow;
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getAllWorkflows() {
|
2024-01-17 07:08:50 -08:00
|
|
|
return await Container.get(WorkflowRepository).find();
|
2023-11-08 07:29:39 -08:00
|
|
|
}
|
2023-11-27 02:56:06 -08:00
|
|
|
|
2024-04-12 08:25:59 -07:00
|
|
|
export async function getAllSharedWorkflows() {
|
|
|
|
return await Container.get(SharedWorkflowRepository).find();
|
|
|
|
}
|
|
|
|
|
2023-11-27 02:56:06 -08:00
|
|
|
export const getWorkflowById = async (id: string) =>
|
2024-01-17 07:08:50 -08:00
|
|
|
await Container.get(WorkflowRepository).findOneBy({ id });
|