@n8n-as-code/sync 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/project-helpers.d.ts +93 -0
- package/dist/helpers/project-helpers.d.ts.map +1 -0
- package/dist/helpers/project-helpers.js +168 -0
- package/dist/helpers/project-helpers.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/services/directory-utils.d.ts +6 -0
- package/dist/services/directory-utils.d.ts.map +1 -1
- package/dist/services/directory-utils.js +12 -0
- package/dist/services/directory-utils.js.map +1 -1
- package/dist/services/n8n-api-client.d.ts +28 -2
- package/dist/services/n8n-api-client.d.ts.map +1 -1
- package/dist/services/n8n-api-client.js +197 -3
- package/dist/services/n8n-api-client.js.map +1 -1
- package/dist/services/resolution-manager.d.ts +2 -2
- package/dist/services/resolution-manager.js +7 -7
- package/dist/services/resolution-manager.js.map +1 -1
- package/dist/services/sync-engine.d.ts +1 -1
- package/dist/services/sync-engine.d.ts.map +1 -1
- package/dist/services/sync-engine.js +10 -10
- package/dist/services/sync-engine.js.map +1 -1
- package/dist/services/sync-manager.d.ts +6 -1
- package/dist/services/sync-manager.d.ts.map +1 -1
- package/dist/services/sync-manager.js +18 -12
- package/dist/services/sync-manager.js.map +1 -1
- package/dist/services/trash-service.d.ts +1 -1
- package/dist/services/trash-service.d.ts.map +1 -1
- package/dist/services/trash-service.js +8 -8
- package/dist/services/trash-service.js.map +1 -1
- package/dist/services/watcher.d.ts +9 -1
- package/dist/services/watcher.d.ts.map +1 -1
- package/dist/services/watcher.js +93 -22
- package/dist/services/watcher.js.map +1 -1
- package/dist/services/workflow-sanitizer.d.ts +11 -0
- package/dist/services/workflow-sanitizer.d.ts.map +1 -1
- package/dist/services/workflow-sanitizer.js +31 -1
- package/dist/services/workflow-sanitizer.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for workflow and project management
|
|
3
|
+
*
|
|
4
|
+
* This module exports reusable helper functions that can be used
|
|
5
|
+
* across different interfaces (CLI, VS Code extension, etc.)
|
|
6
|
+
*/
|
|
7
|
+
export { getDisplayProjectName, getWorkflowProjectName, getProjectDisplayName, groupWorkflowsByProject, sortWorkflowsInGroups, buildProjectGroups, formatWorkflowNameWithBadges, type IProjectGroup } from './project-helpers.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,KAAK,aAAa,EACrB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for workflow and project management
|
|
3
|
+
*
|
|
4
|
+
* This module exports reusable helper functions that can be used
|
|
5
|
+
* across different interfaces (CLI, VS Code extension, etc.)
|
|
6
|
+
*/
|
|
7
|
+
export { getDisplayProjectName, getWorkflowProjectName, getProjectDisplayName, groupWorkflowsByProject, sortWorkflowsInGroups, buildProjectGroups, formatWorkflowNameWithBadges } from './project-helpers.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAE/B,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-related helper functions for workflow organization
|
|
3
|
+
*
|
|
4
|
+
* These helpers provide reusable utilities for working with projects
|
|
5
|
+
* across different interfaces (CLI, VS Code extension, etc.)
|
|
6
|
+
*/
|
|
7
|
+
import { IProject, IWorkflow } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Gets a user-friendly display name for a project.
|
|
10
|
+
*
|
|
11
|
+
* Personal projects (type === 'personal') are displayed as "Personal"
|
|
12
|
+
* regardless of their actual name (which often includes user email).
|
|
13
|
+
*
|
|
14
|
+
* @param project The project to get a display name for
|
|
15
|
+
* @returns A user-friendly display name
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDisplayProjectName(project: IProject): string;
|
|
18
|
+
/**
|
|
19
|
+
* Gets a user-friendly display name for a workflow's project.
|
|
20
|
+
*
|
|
21
|
+
* If the workflow has no project assignment, returns the fallback.
|
|
22
|
+
*
|
|
23
|
+
* @param workflow The workflow to get a project name for
|
|
24
|
+
* @param fallback The name to use if the workflow has no project (default: "Personal")
|
|
25
|
+
* @returns A user-friendly display name
|
|
26
|
+
*/
|
|
27
|
+
export declare function getWorkflowProjectName(workflow: IWorkflow, fallback?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Gets a display name for a project from an object with project metadata.
|
|
30
|
+
* Works with IWorkflow, IWorkflowStatus, or any object with projectName and homeProject.
|
|
31
|
+
*
|
|
32
|
+
* @param obj Object containing project metadata
|
|
33
|
+
* @param fallback The name to use if no project (default: "Personal")
|
|
34
|
+
* @returns A user-friendly display name
|
|
35
|
+
*/
|
|
36
|
+
export declare function getProjectDisplayName(obj: {
|
|
37
|
+
projectName?: string;
|
|
38
|
+
homeProject?: IProject;
|
|
39
|
+
}, fallback?: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Groups workflows by their project assignment.
|
|
42
|
+
*
|
|
43
|
+
* @param workflows Array of workflows to group
|
|
44
|
+
* @returns Map of projectId -> workflows array
|
|
45
|
+
*/
|
|
46
|
+
export declare function groupWorkflowsByProject(workflows: IWorkflow[]): Map<string, IWorkflow[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Sorts workflows within each project group.
|
|
49
|
+
*
|
|
50
|
+
* Default sort order: active workflows first, then by name alphabetically.
|
|
51
|
+
*
|
|
52
|
+
* @param groups Map of projectId -> workflows to sort in-place
|
|
53
|
+
* @param compareFn Optional custom comparison function
|
|
54
|
+
*/
|
|
55
|
+
export declare function sortWorkflowsInGroups(groups: Map<string, IWorkflow[]>, compareFn?: (a: IWorkflow, b: IWorkflow) => number): void;
|
|
56
|
+
/**
|
|
57
|
+
* Interface for a project with its workflows
|
|
58
|
+
*/
|
|
59
|
+
export interface IProjectGroup {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
displayName: string;
|
|
63
|
+
project: IProject | null;
|
|
64
|
+
workflows: IWorkflow[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Converts grouped workflows into structured project groups with metadata.
|
|
68
|
+
*
|
|
69
|
+
* @param groupedWorkflows Map of projectId -> workflows
|
|
70
|
+
* @param sortProjects Whether to sort projects (no-project last)
|
|
71
|
+
* @returns Array of project groups with display information
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildProjectGroups(groupedWorkflows: Map<string, IWorkflow[]>, sortProjects?: boolean): IProjectGroup[];
|
|
74
|
+
/**
|
|
75
|
+
* Format workflow name with project and archived badges
|
|
76
|
+
*
|
|
77
|
+
* @param workflow The workflow object (must have name, projectName/homeProject, isArchived)
|
|
78
|
+
* @param options Optional formatting options
|
|
79
|
+
* @returns Workflow name with badges
|
|
80
|
+
*/
|
|
81
|
+
export declare function formatWorkflowNameWithBadges(workflow: {
|
|
82
|
+
name: string;
|
|
83
|
+
projectName?: string;
|
|
84
|
+
homeProject?: IProject;
|
|
85
|
+
isArchived?: boolean;
|
|
86
|
+
}, options?: {
|
|
87
|
+
showProjectBadge?: boolean;
|
|
88
|
+
showArchivedBadge?: boolean;
|
|
89
|
+
maxLength?: number;
|
|
90
|
+
projectBadgeStyle?: (text: string) => string;
|
|
91
|
+
archivedBadgeStyle?: (text: string) => string;
|
|
92
|
+
}): string;
|
|
93
|
+
//# sourceMappingURL=project-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/project-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAE,MAAmB,GAAG,MAAM,CAKjG;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACjC,GAAG,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,CAAA;CAAE,EACrD,QAAQ,GAAE,MAAmB,GAC9B,MAAM,CAKR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAexF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAChC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,KAAK,MAAM,GACnD,IAAI,CAcN;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,SAAS,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAC9B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAC1C,YAAY,GAAE,OAAc,GAC7B,aAAa,EAAE,CAqCjB;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CACxC,QAAQ,EAAE;IACN,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB,EACD,OAAO,CAAC,EAAE;IACN,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACjD,GACF,MAAM,CAoCR"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project-related helper functions for workflow organization
|
|
3
|
+
*
|
|
4
|
+
* These helpers provide reusable utilities for working with projects
|
|
5
|
+
* across different interfaces (CLI, VS Code extension, etc.)
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Gets a user-friendly display name for a project.
|
|
9
|
+
*
|
|
10
|
+
* Personal projects (type === 'personal') are displayed as "Personal"
|
|
11
|
+
* regardless of their actual name (which often includes user email).
|
|
12
|
+
*
|
|
13
|
+
* @param project The project to get a display name for
|
|
14
|
+
* @returns A user-friendly display name
|
|
15
|
+
*/
|
|
16
|
+
export function getDisplayProjectName(project) {
|
|
17
|
+
return project.type === 'personal' ? 'Personal' : project.name;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Gets a user-friendly display name for a workflow's project.
|
|
21
|
+
*
|
|
22
|
+
* If the workflow has no project assignment, returns the fallback.
|
|
23
|
+
*
|
|
24
|
+
* @param workflow The workflow to get a project name for
|
|
25
|
+
* @param fallback The name to use if the workflow has no project (default: "Personal")
|
|
26
|
+
* @returns A user-friendly display name
|
|
27
|
+
*/
|
|
28
|
+
export function getWorkflowProjectName(workflow, fallback = 'Personal') {
|
|
29
|
+
if (!workflow.homeProject) {
|
|
30
|
+
return fallback;
|
|
31
|
+
}
|
|
32
|
+
return getDisplayProjectName(workflow.homeProject);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets a display name for a project from an object with project metadata.
|
|
36
|
+
* Works with IWorkflow, IWorkflowStatus, or any object with projectName and homeProject.
|
|
37
|
+
*
|
|
38
|
+
* @param obj Object containing project metadata
|
|
39
|
+
* @param fallback The name to use if no project (default: "Personal")
|
|
40
|
+
* @returns A user-friendly display name
|
|
41
|
+
*/
|
|
42
|
+
export function getProjectDisplayName(obj, fallback = 'Personal') {
|
|
43
|
+
if (obj.homeProject) {
|
|
44
|
+
return getDisplayProjectName(obj.homeProject);
|
|
45
|
+
}
|
|
46
|
+
return obj.projectName || fallback;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Groups workflows by their project assignment.
|
|
50
|
+
*
|
|
51
|
+
* @param workflows Array of workflows to group
|
|
52
|
+
* @returns Map of projectId -> workflows array
|
|
53
|
+
*/
|
|
54
|
+
export function groupWorkflowsByProject(workflows) {
|
|
55
|
+
const NO_PROJECT_KEY = '__NO_PROJECT__';
|
|
56
|
+
const groups = new Map();
|
|
57
|
+
for (const workflow of workflows) {
|
|
58
|
+
const projectId = workflow.projectId || NO_PROJECT_KEY;
|
|
59
|
+
if (!groups.has(projectId)) {
|
|
60
|
+
groups.set(projectId, []);
|
|
61
|
+
}
|
|
62
|
+
groups.get(projectId).push(workflow);
|
|
63
|
+
}
|
|
64
|
+
return groups;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sorts workflows within each project group.
|
|
68
|
+
*
|
|
69
|
+
* Default sort order: active workflows first, then by name alphabetically.
|
|
70
|
+
*
|
|
71
|
+
* @param groups Map of projectId -> workflows to sort in-place
|
|
72
|
+
* @param compareFn Optional custom comparison function
|
|
73
|
+
*/
|
|
74
|
+
export function sortWorkflowsInGroups(groups, compareFn) {
|
|
75
|
+
const defaultCompare = (a, b) => {
|
|
76
|
+
// Active workflows first
|
|
77
|
+
if (a.active && !b.active)
|
|
78
|
+
return -1;
|
|
79
|
+
if (!a.active && b.active)
|
|
80
|
+
return 1;
|
|
81
|
+
// Then by name
|
|
82
|
+
return a.name.localeCompare(b.name);
|
|
83
|
+
};
|
|
84
|
+
const compare = compareFn || defaultCompare;
|
|
85
|
+
for (const [, workflows] of groups) {
|
|
86
|
+
workflows.sort(compare);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Converts grouped workflows into structured project groups with metadata.
|
|
91
|
+
*
|
|
92
|
+
* @param groupedWorkflows Map of projectId -> workflows
|
|
93
|
+
* @param sortProjects Whether to sort projects (no-project last)
|
|
94
|
+
* @returns Array of project groups with display information
|
|
95
|
+
*/
|
|
96
|
+
export function buildProjectGroups(groupedWorkflows, sortProjects = true) {
|
|
97
|
+
const NO_PROJECT_KEY = '__NO_PROJECT__';
|
|
98
|
+
const groups = [];
|
|
99
|
+
for (const [projectId, workflows] of groupedWorkflows) {
|
|
100
|
+
const isNoProject = projectId === NO_PROJECT_KEY;
|
|
101
|
+
const firstWorkflow = workflows[0];
|
|
102
|
+
const project = firstWorkflow?.homeProject || null;
|
|
103
|
+
const name = isNoProject
|
|
104
|
+
? 'Personal'
|
|
105
|
+
: project?.name || 'Unknown Project';
|
|
106
|
+
const displayName = project
|
|
107
|
+
? getDisplayProjectName(project)
|
|
108
|
+
: 'Personal';
|
|
109
|
+
groups.push({
|
|
110
|
+
id: projectId,
|
|
111
|
+
name,
|
|
112
|
+
displayName,
|
|
113
|
+
project,
|
|
114
|
+
workflows
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (sortProjects) {
|
|
118
|
+
groups.sort((a, b) => {
|
|
119
|
+
// No-project (Personal) last
|
|
120
|
+
if (a.id === NO_PROJECT_KEY)
|
|
121
|
+
return 1;
|
|
122
|
+
if (b.id === NO_PROJECT_KEY)
|
|
123
|
+
return -1;
|
|
124
|
+
// Others alphabetically by display name
|
|
125
|
+
return a.displayName.localeCompare(b.displayName);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return groups;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Format workflow name with project and archived badges
|
|
132
|
+
*
|
|
133
|
+
* @param workflow The workflow object (must have name, projectName/homeProject, isArchived)
|
|
134
|
+
* @param options Optional formatting options
|
|
135
|
+
* @returns Workflow name with badges
|
|
136
|
+
*/
|
|
137
|
+
export function formatWorkflowNameWithBadges(workflow, options) {
|
|
138
|
+
const opts = {
|
|
139
|
+
showProjectBadge: true,
|
|
140
|
+
showArchivedBadge: true,
|
|
141
|
+
projectBadgeStyle: (text) => text,
|
|
142
|
+
archivedBadgeStyle: (text) => text,
|
|
143
|
+
...options
|
|
144
|
+
};
|
|
145
|
+
let name = workflow.name;
|
|
146
|
+
const badges = [];
|
|
147
|
+
// Add project badge (only if not Personal)
|
|
148
|
+
if (opts.showProjectBadge) {
|
|
149
|
+
const projectName = getProjectDisplayName(workflow, '');
|
|
150
|
+
if (projectName && projectName !== 'Personal' && projectName !== '-') {
|
|
151
|
+
badges.push(opts.projectBadgeStyle(`[${projectName}]`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Add archived badge
|
|
155
|
+
if (opts.showArchivedBadge && workflow.isArchived) {
|
|
156
|
+
badges.push(opts.archivedBadgeStyle('[archived]'));
|
|
157
|
+
}
|
|
158
|
+
// Truncate name if needed (before adding badges)
|
|
159
|
+
if (opts.maxLength && name.length > opts.maxLength) {
|
|
160
|
+
name = name.substring(0, opts.maxLength - 3) + '...';
|
|
161
|
+
}
|
|
162
|
+
// Combine name and badges
|
|
163
|
+
if (badges.length > 0) {
|
|
164
|
+
return `${name} ${badges.join(' ')}`;
|
|
165
|
+
}
|
|
166
|
+
return name;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=project-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-helpers.js","sourceRoot":"","sources":["../../src/helpers/project-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oBAAoB,CAAC"}
|
|
@@ -32,4 +32,10 @@ export declare function createInstanceIdentifier(host: string, user?: {
|
|
|
32
32
|
* @returns Fallback instance identifier (e.g., "local_5678_abc123")
|
|
33
33
|
*/
|
|
34
34
|
export declare function createFallbackInstanceIdentifier(host: string, apiKey: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Creates a project slug for directory naming
|
|
37
|
+
* @param projectName The project name or type
|
|
38
|
+
* @returns Project slug (e.g., "personal", "marketing_project")
|
|
39
|
+
*/
|
|
40
|
+
export declare function createProjectSlug(projectName: string): string;
|
|
35
41
|
//# sourceMappingURL=directory-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-utils.d.ts","sourceRoot":"","sources":["../../src/services/directory-utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBnD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAoBtG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAK/H;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrF"}
|
|
1
|
+
{"version":3,"file":"directory-utils.d.ts","sourceRoot":"","sources":["../../src/services/directory-utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBnD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAoBtG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAK/H;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAO7D"}
|
|
@@ -72,4 +72,16 @@ export function createFallbackInstanceIdentifier(host, apiKey) {
|
|
|
72
72
|
const apiKeyHash = crypto.createHash('sha256').update(apiKey).digest('hex').substring(0, 6);
|
|
73
73
|
return `${hostSlug}_${apiKeyHash}`;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates a project slug for directory naming
|
|
77
|
+
* @param projectName The project name or type
|
|
78
|
+
* @returns Project slug (e.g., "personal", "marketing_project")
|
|
79
|
+
*/
|
|
80
|
+
export function createProjectSlug(projectName) {
|
|
81
|
+
const slug = projectName
|
|
82
|
+
.toLowerCase()
|
|
83
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
84
|
+
.replace(/^_+|_+$/g, '');
|
|
85
|
+
return slug || 'project';
|
|
86
|
+
}
|
|
75
87
|
//# sourceMappingURL=directory-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-utils.js","sourceRoot":"","sources":["../../src/services/directory-utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACvC,uCAAuC;IACvC,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEpE,6BAA6B;IAC7B,IAAI,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,OAAO,SAAS,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,kCAAkC;IAClC,2CAA2C;IAC3C,mCAAmC;IACnC,SAAS,GAAG,SAAS;SAChB,OAAO,CAAC,oBAAoB,EAAE,QAAQ,CAAC;SACvC,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC;SACtC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;SACpB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAE3B,sDAAsD;IACtD,OAAO,SAAS;SACX,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,WAAW,EAAE,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAA+D;IAC1F,qDAAqD;IACrD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,8BAA8B;IAC9B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,kCAAkC;IAClC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC1B,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;aAC7B,WAAW,EAAE,CAAC;IACvB,CAAC;IAED,iBAAiB;IACjB,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY,EAAE,IAAgE;IACnH,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAEtD,OAAO,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gCAAgC,CAAC,IAAY,EAAE,MAAc;IACzE,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5F,OAAO,GAAG,QAAQ,IAAI,UAAU,EAAE,CAAC;AACvC,CAAC"}
|
|
1
|
+
{"version":3,"file":"directory-utils.js","sourceRoot":"","sources":["../../src/services/directory-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { IN8nCredentials, IWorkflow } from '../types.js';
|
|
1
|
+
import { IN8nCredentials, IWorkflow, IProject } from '../types.js';
|
|
2
2
|
export declare class N8nApiClient {
|
|
3
3
|
private client;
|
|
4
|
+
private projectsCache;
|
|
4
5
|
constructor(credentials: IN8nCredentials);
|
|
5
6
|
testConnection(): Promise<boolean>;
|
|
6
7
|
getCurrentUser(): Promise<{
|
|
@@ -9,8 +10,33 @@ export declare class N8nApiClient {
|
|
|
9
10
|
firstName?: string;
|
|
10
11
|
lastName?: string;
|
|
11
12
|
} | null>;
|
|
12
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Fetches all projects from n8n.
|
|
15
|
+
* Public method for CLI/UI to show project selection.
|
|
16
|
+
*
|
|
17
|
+
* @returns Array of IProject
|
|
18
|
+
*/
|
|
19
|
+
getProjects(): Promise<IProject[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetches all projects from n8n and caches them.
|
|
22
|
+
* Returns a Map of projectId -> IProject for quick lookups.
|
|
23
|
+
*
|
|
24
|
+
* The cache is populated on first call and reused for subsequent calls.
|
|
25
|
+
* If the API call fails, returns an empty cache to allow graceful degradation.
|
|
26
|
+
*
|
|
27
|
+
* @returns Map of projectId to IProject
|
|
28
|
+
*/
|
|
29
|
+
private getProjectsCache;
|
|
30
|
+
getAllWorkflows(projectId?: string): Promise<IWorkflow[]>;
|
|
13
31
|
getWorkflow(id: string): Promise<IWorkflow | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Enriches a workflow with organization metadata extracted from the API response.
|
|
34
|
+
* This metadata includes project information and archived status.
|
|
35
|
+
*
|
|
36
|
+
* @param workflow Raw workflow from n8n API
|
|
37
|
+
* @returns Workflow with organization metadata
|
|
38
|
+
*/
|
|
39
|
+
private enrichWorkflowMetadata;
|
|
14
40
|
createWorkflow(payload: Partial<IWorkflow>): Promise<IWorkflow>;
|
|
15
41
|
updateWorkflow(id: string, payload: Partial<IWorkflow>): Promise<IWorkflow>;
|
|
16
42
|
deleteWorkflow(id: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"n8n-api-client.d.ts","sourceRoot":"","sources":["../../src/services/n8n-api-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"n8n-api-client.d.ts","sourceRoot":"","sources":["../../src/services/n8n-api-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnE,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAsC;gBAE/C,WAAW,EAAE,eAAe;IAoBlC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAUlC,cAAc,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;KAAE,GAAG,IAAI,CAAC;IA2C7G;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IA6DxC;;;;;;;;OAQG;YACW,gBAAgB;IAiFxB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA4BzD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAexD;;;;;;OAMG;YACW,sBAAsB;IAiC9B,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAK/D,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAoB3E,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5C,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/D,SAAS,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsCzC,YAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;CAUvC"}
|
|
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|
|
2
2
|
import * as https from 'https';
|
|
3
3
|
export class N8nApiClient {
|
|
4
4
|
client;
|
|
5
|
+
projectsCache = null;
|
|
5
6
|
constructor(credentials) {
|
|
6
7
|
let host = credentials.host;
|
|
7
8
|
if (host.endsWith('/')) {
|
|
@@ -74,10 +75,168 @@ export class N8nApiClient {
|
|
|
74
75
|
console.debug('[N8nApiClient] getCurrentUser: All attempts failed, returning null');
|
|
75
76
|
return null;
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Fetches all projects from n8n.
|
|
80
|
+
* Public method for CLI/UI to show project selection.
|
|
81
|
+
*
|
|
82
|
+
* @returns Array of IProject
|
|
83
|
+
*/
|
|
84
|
+
async getProjects() {
|
|
85
|
+
try {
|
|
86
|
+
const res = await this.client.get('/api/v1/projects');
|
|
87
|
+
const projects = res.data.data || [];
|
|
88
|
+
return projects.map((p) => ({
|
|
89
|
+
id: p.id,
|
|
90
|
+
name: p.name,
|
|
91
|
+
type: p.type,
|
|
92
|
+
createdAt: p.createdAt,
|
|
93
|
+
updatedAt: p.updatedAt
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// Check if this is a license restriction error (common on local n8n instances)
|
|
98
|
+
const isLicenseError = error.response?.status === 403 &&
|
|
99
|
+
error.response?.data?.message?.includes('license') ||
|
|
100
|
+
error.response?.data?.message?.includes('feat:projectRole:admin');
|
|
101
|
+
if (isLicenseError) {
|
|
102
|
+
console.warn(`[N8nApiClient] Projects API requires license upgrade. Using personal project fallback.`);
|
|
103
|
+
// Try to get the personal project ID from existing workflows
|
|
104
|
+
try {
|
|
105
|
+
const workflowsRes = await this.client.get('/api/v1/workflows');
|
|
106
|
+
const workflows = workflowsRes.data.data || [];
|
|
107
|
+
// Find a project ID from workflow shared data
|
|
108
|
+
for (const wf of workflows) {
|
|
109
|
+
if (wf.shared && Array.isArray(wf.shared) && wf.shared.length > 0) {
|
|
110
|
+
const projectId = wf.shared[0].projectId;
|
|
111
|
+
if (projectId) {
|
|
112
|
+
console.debug(`[N8nApiClient] Found personal project ID from workflows: ${projectId}`);
|
|
113
|
+
return [{
|
|
114
|
+
id: projectId,
|
|
115
|
+
name: 'Personal',
|
|
116
|
+
type: 'personal',
|
|
117
|
+
createdAt: new Date().toISOString(),
|
|
118
|
+
updatedAt: new Date().toISOString()
|
|
119
|
+
}];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (innerError) {
|
|
125
|
+
console.debug(`[N8nApiClient] Could not fetch workflows to discover project ID: ${innerError.message}`);
|
|
126
|
+
}
|
|
127
|
+
// Fallback: return a placeholder personal project
|
|
128
|
+
console.warn(`[N8nApiClient] No workflows found, using placeholder personal project ID`);
|
|
129
|
+
return [{
|
|
130
|
+
id: 'personal',
|
|
131
|
+
name: 'Personal',
|
|
132
|
+
type: 'personal',
|
|
133
|
+
createdAt: new Date().toISOString(),
|
|
134
|
+
updatedAt: new Date().toISOString()
|
|
135
|
+
}];
|
|
136
|
+
}
|
|
137
|
+
console.error(`[N8nApiClient] Failed to fetch projects: ${error.message}`);
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Fetches all projects from n8n and caches them.
|
|
143
|
+
* Returns a Map of projectId -> IProject for quick lookups.
|
|
144
|
+
*
|
|
145
|
+
* The cache is populated on first call and reused for subsequent calls.
|
|
146
|
+
* If the API call fails, returns an empty cache to allow graceful degradation.
|
|
147
|
+
*
|
|
148
|
+
* @returns Map of projectId to IProject
|
|
149
|
+
*/
|
|
150
|
+
async getProjectsCache() {
|
|
151
|
+
if (this.projectsCache !== null) {
|
|
152
|
+
return this.projectsCache;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const res = await this.client.get('/api/v1/projects');
|
|
156
|
+
const projects = res.data.data || [];
|
|
157
|
+
this.projectsCache = new Map();
|
|
158
|
+
for (const project of projects) {
|
|
159
|
+
this.projectsCache.set(project.id, {
|
|
160
|
+
id: project.id,
|
|
161
|
+
name: project.name,
|
|
162
|
+
type: project.type,
|
|
163
|
+
createdAt: project.createdAt,
|
|
164
|
+
updatedAt: project.updatedAt
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// Only log in debug mode to avoid noise
|
|
168
|
+
if (process.env.DEBUG) {
|
|
169
|
+
console.debug(`[N8nApiClient] Cached ${this.projectsCache.size} projects`);
|
|
170
|
+
}
|
|
171
|
+
return this.projectsCache;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// Check if this is a license restriction error (common on local n8n instances)
|
|
175
|
+
const isLicenseError = error.response?.status === 403 &&
|
|
176
|
+
error.response?.data?.message?.includes('license') ||
|
|
177
|
+
error.response?.data?.message?.includes('feat:projectRole:admin');
|
|
178
|
+
if (isLicenseError) {
|
|
179
|
+
console.warn(`[N8nApiClient] Projects API requires license upgrade. Using personal project fallback in cache.`);
|
|
180
|
+
// Try to get the personal project ID from existing workflows
|
|
181
|
+
try {
|
|
182
|
+
const workflowsRes = await this.client.get('/api/v1/workflows');
|
|
183
|
+
const workflows = workflowsRes.data.data || [];
|
|
184
|
+
// Find a project ID from workflow shared data
|
|
185
|
+
for (const wf of workflows) {
|
|
186
|
+
if (wf.shared && Array.isArray(wf.shared) && wf.shared.length > 0) {
|
|
187
|
+
const projectId = wf.shared[0].projectId;
|
|
188
|
+
if (projectId) {
|
|
189
|
+
console.debug(`[N8nApiClient] Found personal project ID from workflows for cache: ${projectId}`);
|
|
190
|
+
this.projectsCache = new Map();
|
|
191
|
+
this.projectsCache.set(projectId, {
|
|
192
|
+
id: projectId,
|
|
193
|
+
name: 'Personal',
|
|
194
|
+
type: 'personal',
|
|
195
|
+
createdAt: new Date().toISOString(),
|
|
196
|
+
updatedAt: new Date().toISOString()
|
|
197
|
+
});
|
|
198
|
+
return this.projectsCache;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (innerError) {
|
|
204
|
+
console.debug(`[N8nApiClient] Could not fetch workflows to discover project ID for cache: ${innerError.message}`);
|
|
205
|
+
}
|
|
206
|
+
// Fallback: create a placeholder personal project
|
|
207
|
+
console.warn(`[N8nApiClient] No workflows found, using placeholder personal project ID in cache`);
|
|
208
|
+
this.projectsCache = new Map();
|
|
209
|
+
this.projectsCache.set('personal', {
|
|
210
|
+
id: 'personal',
|
|
211
|
+
name: 'Personal',
|
|
212
|
+
type: 'personal',
|
|
213
|
+
createdAt: new Date().toISOString(),
|
|
214
|
+
updatedAt: new Date().toISOString()
|
|
215
|
+
});
|
|
216
|
+
return this.projectsCache;
|
|
217
|
+
}
|
|
218
|
+
// Graceful degradation: workflows will have projectId but no homeProject/projectName
|
|
219
|
+
console.warn(`[N8nApiClient] Failed to fetch projects: ${error.message}. Workflows will not have project names.`);
|
|
220
|
+
this.projectsCache = new Map();
|
|
221
|
+
return this.projectsCache;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async getAllWorkflows(projectId) {
|
|
78
225
|
try {
|
|
79
226
|
const res = await this.client.get('/api/v1/workflows');
|
|
80
|
-
|
|
227
|
+
let workflows = res.data.data;
|
|
228
|
+
// Filter by project if specified
|
|
229
|
+
if (projectId) {
|
|
230
|
+
workflows = workflows.filter((wf) => {
|
|
231
|
+
if (!wf.shared || !Array.isArray(wf.shared) || wf.shared.length === 0) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
return wf.shared[0].projectId === projectId;
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
// Enrich workflows with organization metadata
|
|
238
|
+
const enriched = await Promise.all(workflows.map((wf) => this.enrichWorkflowMetadata(wf)));
|
|
239
|
+
return enriched;
|
|
81
240
|
}
|
|
82
241
|
catch (error) {
|
|
83
242
|
console.error('Failed to get workflows:', error.message);
|
|
@@ -88,7 +247,8 @@ export class N8nApiClient {
|
|
|
88
247
|
async getWorkflow(id) {
|
|
89
248
|
try {
|
|
90
249
|
const res = await this.client.get(`/api/v1/workflows/${id}`);
|
|
91
|
-
|
|
250
|
+
// Enrich with organization metadata
|
|
251
|
+
return await this.enrichWorkflowMetadata(res.data);
|
|
92
252
|
}
|
|
93
253
|
catch (error) {
|
|
94
254
|
// 404 is expected if workflow deleted remotely
|
|
@@ -99,6 +259,40 @@ export class N8nApiClient {
|
|
|
99
259
|
throw error;
|
|
100
260
|
}
|
|
101
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Enriches a workflow with organization metadata extracted from the API response.
|
|
264
|
+
* This metadata includes project information and archived status.
|
|
265
|
+
*
|
|
266
|
+
* @param workflow Raw workflow from n8n API
|
|
267
|
+
* @returns Workflow with organization metadata
|
|
268
|
+
*/
|
|
269
|
+
async enrichWorkflowMetadata(workflow) {
|
|
270
|
+
const enriched = { ...workflow };
|
|
271
|
+
// Get projects cache
|
|
272
|
+
const projectsCache = await this.getProjectsCache();
|
|
273
|
+
// Extract project information from shared array
|
|
274
|
+
// n8n stores projectId in workflow.shared[0].projectId
|
|
275
|
+
if (workflow.shared && Array.isArray(workflow.shared) && workflow.shared.length > 0) {
|
|
276
|
+
const firstShare = workflow.shared[0];
|
|
277
|
+
if (firstShare.projectId) {
|
|
278
|
+
enriched.projectId = firstShare.projectId;
|
|
279
|
+
// Look up project details in cache
|
|
280
|
+
const project = projectsCache.get(firstShare.projectId);
|
|
281
|
+
if (project) {
|
|
282
|
+
enriched.homeProject = project;
|
|
283
|
+
enriched.projectName = project.name;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
console.debug(`[N8nApiClient] Project ${firstShare.projectId} not found in cache`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Extract archived status (direct property)
|
|
291
|
+
if (workflow.isArchived !== undefined) {
|
|
292
|
+
enriched.isArchived = workflow.isArchived;
|
|
293
|
+
}
|
|
294
|
+
return enriched;
|
|
295
|
+
}
|
|
102
296
|
async createWorkflow(payload) {
|
|
103
297
|
const res = await this.client.post('/api/v1/workflows', payload);
|
|
104
298
|
return res.data;
|