@n8n-as-code/core 0.2.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.
Files changed (38) hide show
  1. package/README.md +22 -0
  2. package/dist/index.d.ts +11 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +11 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/services/directory-utils.d.ts +35 -0
  7. package/dist/services/directory-utils.d.ts.map +1 -0
  8. package/dist/services/directory-utils.js +75 -0
  9. package/dist/services/directory-utils.js.map +1 -0
  10. package/dist/services/n8n-api-client.d.ts +23 -0
  11. package/dist/services/n8n-api-client.d.ts.map +1 -0
  12. package/dist/services/n8n-api-client.js +199 -0
  13. package/dist/services/n8n-api-client.js.map +1 -0
  14. package/dist/services/schema-generator.d.ts +9 -0
  15. package/dist/services/schema-generator.d.ts.map +1 -0
  16. package/dist/services/schema-generator.js +79 -0
  17. package/dist/services/schema-generator.js.map +1 -0
  18. package/dist/services/state-manager.d.ts +42 -0
  19. package/dist/services/state-manager.d.ts.map +1 -0
  20. package/dist/services/state-manager.js +99 -0
  21. package/dist/services/state-manager.js.map +1 -0
  22. package/dist/services/sync-manager.d.ts +101 -0
  23. package/dist/services/sync-manager.d.ts.map +1 -0
  24. package/dist/services/sync-manager.js +692 -0
  25. package/dist/services/sync-manager.js.map +1 -0
  26. package/dist/services/trash-service.d.ts +17 -0
  27. package/dist/services/trash-service.d.ts.map +1 -0
  28. package/dist/services/trash-service.js +41 -0
  29. package/dist/services/trash-service.js.map +1 -0
  30. package/dist/services/workflow-sanitizer.d.ts +18 -0
  31. package/dist/services/workflow-sanitizer.d.ts.map +1 -0
  32. package/dist/services/workflow-sanitizer.js +80 -0
  33. package/dist/services/workflow-sanitizer.js.map +1 -0
  34. package/dist/types.d.ts +41 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +9 -0
  37. package/dist/types.js.map +1 -0
  38. package/package.json +41 -0
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @n8n-as-code/core
2
+
3
+ The logical core of the **n8n-as-code** ecosystem.
4
+
5
+ ## 🛠 Purpose
6
+
7
+ This package contains the shared logic used by the CLI, the Agent CLI, and the VS Code extension:
8
+ - **API Client**: Communication with the n8n REST API.
9
+ - **Synchronization**: Logic for pulling, pushing, and detecting changes.
10
+ - **Sanitization**: Cleaning up n8n JSONs for better Git versioning (removing IDs, timestamps, etc.).
11
+ - **State Management**: Tracking local vs. remote state to detect conflicts.
12
+
13
+ ## 🚀 Usage
14
+
15
+ This is internal tooling primarily intended to be consumed by other `@n8n-as-code` packages.
16
+
17
+ ```bash
18
+ npm install @n8n-as-code/core
19
+ ```
20
+
21
+ ## 📄 License
22
+ MIT
@@ -0,0 +1,11 @@
1
+ export * from './types.js';
2
+ export * from './services/n8n-api-client.js';
3
+ export * from './services/workflow-sanitizer.js';
4
+ export * from './services/sync-manager.js';
5
+ export * from './services/state-manager.js';
6
+ export * from './services/schema-generator.js';
7
+ export * from './services/sync-manager.js';
8
+ export * from './services/n8n-api-client.js';
9
+ export * from './services/directory-utils.js';
10
+ export * from './types.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAI/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export * from './types.js';
2
+ export * from './services/n8n-api-client.js';
3
+ export * from './services/workflow-sanitizer.js';
4
+ export * from './services/sync-manager.js';
5
+ export * from './services/state-manager.js';
6
+ export * from './services/schema-generator.js';
7
+ export * from './services/sync-manager.js';
8
+ export * from './services/n8n-api-client.js';
9
+ export * from './services/directory-utils.js';
10
+ export * from './types.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAI/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Creates a user-friendly host slug for directory naming
3
+ * @param host The host URL
4
+ * @returns Cleaned host slug (e.g., "local_5678", "etiennel_cloud")
5
+ */
6
+ export declare function createHostSlug(host: string): string;
7
+ /**
8
+ * Creates a user-friendly slug from user information
9
+ * @param user User object with email, firstName, lastName
10
+ * @returns User slug (e.g., "etienne_l", "john_d")
11
+ */
12
+ export declare function createUserSlug(user: {
13
+ email?: string;
14
+ firstName?: string;
15
+ lastName?: string;
16
+ }): string;
17
+ /**
18
+ * Creates an instance identifier for directory naming
19
+ * @param host The host URL
20
+ * @param user User information (optional)
21
+ * @returns Instance identifier (e.g., "local_5678_etienne_l")
22
+ */
23
+ export declare function createInstanceIdentifier(host: string, user?: {
24
+ email?: string;
25
+ firstName?: string;
26
+ lastName?: string;
27
+ }): string;
28
+ /**
29
+ * Creates a fallback instance identifier using API key hash when user info is unavailable
30
+ * @param host The host URL
31
+ * @param apiKey The API key for uniqueness
32
+ * @returns Fallback instance identifier (e.g., "local_5678_abc123")
33
+ */
34
+ export declare function createFallbackInstanceIdentifier(host: string, apiKey: string): string;
35
+ //# sourceMappingURL=directory-utils.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,75 @@
1
+ import crypto from 'crypto';
2
+ /**
3
+ * Creates a user-friendly host slug for directory naming
4
+ * @param host The host URL
5
+ * @returns Cleaned host slug (e.g., "local_5678", "etiennel_cloud")
6
+ */
7
+ export function createHostSlug(host) {
8
+ // Remove protocol and trailing slashes
9
+ let cleanHost = host.replace(/^https?:\/\//, '').replace(/\/$/, '');
10
+ // Handle localhost with port
11
+ if (cleanHost.startsWith('localhost:')) {
12
+ const port = cleanHost.split(':')[1];
13
+ return `local_${port}`;
14
+ }
15
+ // For domains, extract main parts
16
+ // etiennel.app.n8n.cloud -> etiennel_cloud
17
+ // prod.example.com -> prod_example
18
+ cleanHost = cleanHost
19
+ .replace(/\.app\.n8n\.cloud$/, '_cloud')
20
+ .replace(/\.example\.com$/, '_example')
21
+ .replace(/\.com$/, '')
22
+ .replace(/\.io$/, '')
23
+ .replace(/\.net$/, '')
24
+ .replace(/\.org$/, '');
25
+ // Replace remaining dots and hyphens with underscores
26
+ return cleanHost
27
+ .replace(/[.-]/g, '_')
28
+ .toLowerCase();
29
+ }
30
+ /**
31
+ * Creates a user-friendly slug from user information
32
+ * @param user User object with email, firstName, lastName
33
+ * @returns User slug (e.g., "etienne_l", "john_d")
34
+ */
35
+ export function createUserSlug(user) {
36
+ // Prefer first name + last name initial if available
37
+ if (user.firstName && user.lastName) {
38
+ return `${user.firstName.toLowerCase()}_${user.lastName.charAt(0).toLowerCase()}`;
39
+ }
40
+ // Fallback to first name only
41
+ if (user.firstName) {
42
+ return user.firstName.toLowerCase();
43
+ }
44
+ // Fallback to email username part
45
+ if (user.email) {
46
+ return user.email.split('@')[0]
47
+ .replace(/[^a-zA-Z0-9]/g, '_')
48
+ .toLowerCase();
49
+ }
50
+ // Final fallback
51
+ return 'user';
52
+ }
53
+ /**
54
+ * Creates an instance identifier for directory naming
55
+ * @param host The host URL
56
+ * @param user User information (optional)
57
+ * @returns Instance identifier (e.g., "local_5678_etienne_l")
58
+ */
59
+ export function createInstanceIdentifier(host, user) {
60
+ const hostSlug = createHostSlug(host);
61
+ const userSlug = user ? createUserSlug(user) : 'user';
62
+ return `${hostSlug}_${userSlug}`;
63
+ }
64
+ /**
65
+ * Creates a fallback instance identifier using API key hash when user info is unavailable
66
+ * @param host The host URL
67
+ * @param apiKey The API key for uniqueness
68
+ * @returns Fallback instance identifier (e.g., "local_5678_abc123")
69
+ */
70
+ export function createFallbackInstanceIdentifier(host, apiKey) {
71
+ const hostSlug = createHostSlug(host);
72
+ const apiKeyHash = crypto.createHash('sha256').update(apiKey).digest('hex').substring(0, 6);
73
+ return `${hostSlug}_${apiKeyHash}`;
74
+ }
75
+ //# sourceMappingURL=directory-utils.js.map
@@ -0,0 +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"}
@@ -0,0 +1,23 @@
1
+ import { IN8nCredentials, IWorkflow } from '../types.js';
2
+ export declare class N8nApiClient {
3
+ private client;
4
+ constructor(credentials: IN8nCredentials);
5
+ testConnection(): Promise<boolean>;
6
+ getCurrentUser(): Promise<{
7
+ id: string;
8
+ email: string;
9
+ firstName?: string;
10
+ lastName?: string;
11
+ } | null>;
12
+ getAllWorkflows(): Promise<IWorkflow[]>;
13
+ getWorkflow(id: string): Promise<IWorkflow | null>;
14
+ createWorkflow(payload: Partial<IWorkflow>): Promise<IWorkflow>;
15
+ updateWorkflow(id: string, payload: Partial<IWorkflow>): Promise<IWorkflow>;
16
+ deleteWorkflow(id: string): Promise<boolean>;
17
+ activateWorkflow(id: string, active: boolean): Promise<boolean>;
18
+ getHealth(): Promise<{
19
+ version: string;
20
+ }>;
21
+ getNodeTypes(): Promise<any[]>;
22
+ }
23
+ //# sourceMappingURL=n8n-api-client.d.ts.map
@@ -0,0 +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;AAEzD,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAgB;gBAElB,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;IAsDvG,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAUvC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAUlD,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"}
@@ -0,0 +1,199 @@
1
+ import axios from 'axios';
2
+ import * as https from 'https';
3
+ export class N8nApiClient {
4
+ client;
5
+ constructor(credentials) {
6
+ let host = credentials.host;
7
+ if (host.endsWith('/')) {
8
+ host = host.slice(0, -1);
9
+ }
10
+ this.client = axios.create({
11
+ baseURL: host,
12
+ headers: {
13
+ 'X-N8N-API-KEY': credentials.apiKey,
14
+ 'Content-Type': 'application/json',
15
+ 'User-Agent': 'n8n-as-code'
16
+ },
17
+ // Allow self-signed certificates by default to avoid issues in local environments
18
+ httpsAgent: new https.Agent({
19
+ rejectUnauthorized: false
20
+ })
21
+ });
22
+ }
23
+ async testConnection() {
24
+ try {
25
+ await this.client.get('/api/v1/users'); // Simple endpoint to test auth
26
+ return true;
27
+ }
28
+ catch (error) {
29
+ console.error('Connection test failed:', error);
30
+ return false;
31
+ }
32
+ }
33
+ async getCurrentUser() {
34
+ try {
35
+ // Try /me first (modern n8n)
36
+ try {
37
+ const res = await this.client.get('/api/v1/users/me');
38
+ console.debug('[N8nApiClient] getCurrentUser: Successfully retrieved user from /me endpoint');
39
+ if (res.data && res.data.id) {
40
+ return {
41
+ id: res.data.id,
42
+ email: res.data.email,
43
+ firstName: res.data.firstName,
44
+ lastName: res.data.lastName
45
+ };
46
+ }
47
+ }
48
+ catch (error) {
49
+ console.debug('[N8nApiClient] getCurrentUser: /me endpoint failed:', error.message);
50
+ if (error.response) {
51
+ console.debug('[N8nApiClient] getCurrentUser: Response status:', error.response.status);
52
+ // Avoid logging potentially sensitive data, but structure might be useful
53
+ // console.debug('[N8nApiClient] getCurrentUser: Response data:', error.response.data);
54
+ }
55
+ }
56
+ // Fallback: get all users and take the first one (assuming the API key belongs to an admin or the only user)
57
+ console.debug('[N8nApiClient] getCurrentUser: Trying /api/v1/users endpoint');
58
+ try {
59
+ const res = await this.client.get('/api/v1/users');
60
+ if (res.data && res.data.data && res.data.data.length > 0) {
61
+ console.debug('[N8nApiClient] getCurrentUser: Found', res.data.data.length, 'users');
62
+ const user = res.data.data[0];
63
+ return {
64
+ id: user.id,
65
+ email: user.email,
66
+ firstName: user.firstName,
67
+ lastName: user.lastName
68
+ };
69
+ }
70
+ else {
71
+ console.debug('[N8nApiClient] getCurrentUser: No users found in response');
72
+ }
73
+ }
74
+ catch (error) {
75
+ console.debug('[N8nApiClient] getCurrentUser: /api/v1/users endpoint failed:', error.message);
76
+ if (error.response) {
77
+ console.debug('[N8nApiClient] getCurrentUser: Response status:', error.response.status);
78
+ }
79
+ }
80
+ console.debug('[N8nApiClient] getCurrentUser: All attempts failed, returning null');
81
+ return null;
82
+ }
83
+ catch (error) {
84
+ console.debug('[N8nApiClient] getCurrentUser: Unexpected error:', error.message);
85
+ return null;
86
+ }
87
+ }
88
+ async getAllWorkflows() {
89
+ try {
90
+ const res = await this.client.get('/api/v1/workflows');
91
+ return res.data.data;
92
+ }
93
+ catch (error) {
94
+ console.error('Failed to get workflows:', error);
95
+ return [];
96
+ }
97
+ }
98
+ async getWorkflow(id) {
99
+ try {
100
+ const res = await this.client.get(`/api/v1/workflows/${id}`);
101
+ return res.data;
102
+ }
103
+ catch (error) {
104
+ // 404 is expected if workflow deleted remotely
105
+ return null;
106
+ }
107
+ }
108
+ async createWorkflow(payload) {
109
+ const res = await this.client.post('/api/v1/workflows', payload);
110
+ return res.data;
111
+ }
112
+ async updateWorkflow(id, payload) {
113
+ // Use console.warn to be more visible in some environments
114
+ console.warn(`[N8nApiClient] Starting PUT /api/v1/workflows/${id}`);
115
+ const startTime = Date.now();
116
+ try {
117
+ const res = await this.client.put(`/api/v1/workflows/${id}`, payload);
118
+ const duration = Date.now() - startTime;
119
+ console.warn(`[N8nApiClient] PUT finished in ${duration}ms. Status: ${res.status}`);
120
+ return res.data;
121
+ }
122
+ catch (error) {
123
+ const duration = Date.now() - startTime;
124
+ console.error(`[N8nApiClient] PUT failed after ${duration}ms: ${error.message}`);
125
+ if (error.response) {
126
+ console.error(`[N8nApiClient] Error data:`, error.response.data);
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+ async deleteWorkflow(id) {
132
+ try {
133
+ await this.client.delete(`/api/v1/workflows/${id}`);
134
+ return true;
135
+ }
136
+ catch (error) {
137
+ console.error(`Failed to delete workflow ${id}:`, error);
138
+ return false;
139
+ }
140
+ }
141
+ async activateWorkflow(id, active) {
142
+ try {
143
+ await this.client.post(`/api/v1/workflows/${id}/activate`, { active });
144
+ return true;
145
+ }
146
+ catch (error) {
147
+ return false;
148
+ }
149
+ }
150
+ async getHealth() {
151
+ try {
152
+ // 1. Try public endpoint if available (some versions)
153
+ try {
154
+ const res = await this.client.get('/healthz');
155
+ if (res.data && res.data.version)
156
+ return { version: res.data.version };
157
+ }
158
+ catch { }
159
+ // 2. Scraping Root Page as fallback (Using raw axios to avoid API headers)
160
+ const baseURL = this.client.defaults.baseURL;
161
+ const res = await axios.get(`${baseURL}/`);
162
+ const html = res.data;
163
+ // Look for "release":"n8n@X.Y.Z" probably inside n8n:config:sentry meta (Base64 encoded)
164
+ const sentryMatch = html.match(/name="n8n:config:sentry"\s+content="([^"]+)"/);
165
+ if (sentryMatch && sentryMatch[1]) {
166
+ const decoded = Buffer.from(sentryMatch[1], 'base64').toString('utf-8');
167
+ const releaseMatch = decoded.match(/"release":"n8n@([^"]+)"/);
168
+ if (releaseMatch && releaseMatch[1]) {
169
+ return { version: releaseMatch[1] };
170
+ }
171
+ }
172
+ // Fallback: Check plain text just in case
173
+ const releaseRegex = /"release":"n8n@([^"]+)"/;
174
+ const plainMatch = html.match(releaseRegex);
175
+ if (plainMatch && plainMatch[1])
176
+ return { version: plainMatch[1] };
177
+ // Look for other common patterns
178
+ const metaMatch = html.match(/n8n version: ([0-9.]+)/i);
179
+ if (metaMatch && metaMatch[1])
180
+ return { version: metaMatch[1] };
181
+ return { version: '1.0+' };
182
+ }
183
+ catch {
184
+ return { version: 'Unknown' };
185
+ }
186
+ }
187
+ async getNodeTypes() {
188
+ try {
189
+ // Unofficial/Internal endpoint often used by frontend
190
+ const res = await this.client.get('/rest/node-types');
191
+ return res.data;
192
+ }
193
+ catch {
194
+ // Fallback: If REST API not accessible, return empty
195
+ return [];
196
+ }
197
+ }
198
+ }
199
+ //# sourceMappingURL=n8n-api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n8n-api-client.js","sourceRoot":"","sources":["../../src/services/n8n-api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare class SchemaGenerator {
2
+ constructor();
3
+ /**
4
+ * Fetches node types from n8n and generates a standard JSON Schema.
5
+ * This schema can be used by AI agents to validate node parameters.
6
+ */
7
+ generateSchema(outputPath: string): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=schema-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-generator.d.ts","sourceRoot":"","sources":["../../src/services/schema-generator.ts"],"names":[],"mappings":"AAIA,qBAAa,eAAe;;IAGxB;;;OAGG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAuE1D"}
@@ -0,0 +1,79 @@
1
+ import fs from 'fs';
2
+ export class SchemaGenerator {
3
+ constructor() { }
4
+ /**
5
+ * Fetches node types from n8n and generates a standard JSON Schema.
6
+ * This schema can be used by AI agents to validate node parameters.
7
+ */
8
+ async generateSchema(outputPath) {
9
+ // Defines the structure of an n8n workflow JSON
10
+ const schema = {
11
+ "$schema": "http://json-schema.org/draft-07/schema#",
12
+ "title": "n8n Workflow Structure",
13
+ "description": "Validation schema for n8n workflow JSON files",
14
+ "type": "object",
15
+ "required": ["nodes", "connections"],
16
+ "properties": {
17
+ "name": { "type": "string", "description": "Name of the workflow" },
18
+ "nodes": {
19
+ "type": "array",
20
+ "description": "List of nodes in the workflow",
21
+ "items": {
22
+ "type": "object",
23
+ "required": ["parameters", "id", "name", "type", "typeVersion", "position"],
24
+ "properties": {
25
+ "parameters": {
26
+ "type": "object",
27
+ "description": "Configuration parameters for the node"
28
+ },
29
+ "id": { "type": "string", "description": "Unique UUID of the node" },
30
+ "name": { "type": "string", "description": "Display name of the node" },
31
+ "type": { "type": "string", "description": "Node type identifier (e.g., n8n-nodes-base.httpRequest)" },
32
+ "typeVersion": { "type": ["number", "object"], "description": "Version of the node type" },
33
+ "position": {
34
+ "type": "array",
35
+ "minItems": 2,
36
+ "maxItems": 2,
37
+ "items": { "type": "number" },
38
+ "description": "[x, y] coordinates on the canvas"
39
+ },
40
+ "notesInFlow": { "type": "boolean" },
41
+ "notes": { "type": "string" }
42
+ }
43
+ }
44
+ },
45
+ "connections": {
46
+ "type": "object",
47
+ "description": "Connections between nodes",
48
+ "patternProperties": {
49
+ "^.*$": {
50
+ "type": "object",
51
+ "patternProperties": {
52
+ "^main$": {
53
+ "type": "array",
54
+ "items": {
55
+ "type": "array",
56
+ "items": {
57
+ "type": "object",
58
+ "required": ["node", "type", "index"],
59
+ "properties": {
60
+ "node": { "type": "string", "description": "Target node name" },
61
+ "type": { "type": "string", "enum": ["main"], "default": "main" },
62
+ "index": { "type": "number", "default": 0 }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ },
71
+ "settings": { "type": "object" },
72
+ "staticData": { "type": ["object", "null"] },
73
+ "pinData": { "type": "object" }
74
+ }
75
+ };
76
+ fs.writeFileSync(outputPath, JSON.stringify(schema, null, 2));
77
+ }
78
+ }
79
+ //# sourceMappingURL=schema-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-generator.js","sourceRoot":"","sources":["../../src/services/schema-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export interface IWorkflowState {
2
+ lastSyncedHash: string;
3
+ lastSyncedAt: string;
4
+ }
5
+ export interface IInstanceState {
6
+ workflows: Record<string, IWorkflowState>;
7
+ }
8
+ export declare class StateManager {
9
+ private stateFilePath;
10
+ constructor(directory: string);
11
+ private load;
12
+ private save;
13
+ /**
14
+ * Computes a stable hash for a workflow object.
15
+ */
16
+ static computeHash(workflow: any): string;
17
+ /**
18
+ * Gets the last known state for a workflow.
19
+ */
20
+ getWorkflowState(id: string): IWorkflowState | undefined;
21
+ /**
22
+ * Updates the last known state for a workflow.
23
+ */
24
+ updateWorkflowState(id: string, workflow: any): void;
25
+ /**
26
+ * Removes a workflow from state.
27
+ */
28
+ removeWorkflowState(id: string): void;
29
+ /**
30
+ * Gets all tracked workflow IDs.
31
+ */
32
+ getTrackedWorkflowIds(): string[];
33
+ /**
34
+ * Checks if a local content matches the last synced state.
35
+ */
36
+ isLocalSynced(id: string, localContent: any): boolean;
37
+ /**
38
+ * Checks if a remote workflow matches the last synced state.
39
+ */
40
+ isRemoteSynced(id: string, remoteWorkflow: any): boolean;
41
+ }
42
+ //# sourceMappingURL=state-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../../src/services/state-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC7C;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,aAAa,CAAS;gBAElB,SAAS,EAAE,MAAM;IAI7B,OAAO,CAAC,IAAI;IAgBZ,OAAO,CAAC,IAAI;IAIZ;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM;IAMzC;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKxD;;OAEG;IACH,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG;IAU7C;;OAEG;IACH,mBAAmB,CAAC,EAAE,EAAE,MAAM;IAM9B;;OAEG;IACH,qBAAqB,IAAI,MAAM,EAAE;IAKjC;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,GAAG,OAAO;IAWrD;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,OAAO;CAU3D"}