@n8n-as-code/core 0.2.0 → 0.3.1
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/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/services/hash-utils.d.ts +22 -0
- package/dist/services/hash-utils.d.ts.map +1 -0
- package/dist/services/hash-utils.js +31 -0
- package/dist/services/hash-utils.js.map +1 -0
- package/dist/services/n8n-api-client.d.ts.map +1 -1
- package/dist/services/n8n-api-client.js +44 -50
- package/dist/services/n8n-api-client.js.map +1 -1
- package/dist/services/resolution-manager.d.ts +73 -0
- package/dist/services/resolution-manager.d.ts.map +1 -0
- package/dist/services/resolution-manager.js +149 -0
- package/dist/services/resolution-manager.js.map +1 -0
- package/dist/services/state-manager.d.ts +18 -17
- package/dist/services/state-manager.d.ts.map +1 -1
- package/dist/services/state-manager.js +22 -53
- package/dist/services/state-manager.js.map +1 -1
- package/dist/services/sync-engine.d.ts +57 -0
- package/dist/services/sync-engine.d.ts.map +1 -0
- package/dist/services/sync-engine.js +301 -0
- package/dist/services/sync-engine.js.map +1 -0
- package/dist/services/sync-manager.d.ts +19 -83
- package/dist/services/sync-manager.d.ts.map +1 -1
- package/dist/services/sync-manager.js +208 -620
- package/dist/services/sync-manager.js.map +1 -1
- package/dist/services/watcher.d.ts +121 -0
- package/dist/services/watcher.d.ts.map +1 -0
- package/dist/services/watcher.js +609 -0
- package/dist/services/watcher.js.map +1 -0
- package/dist/services/workflow-sanitizer.d.ts +9 -4
- package/dist/services/workflow-sanitizer.d.ts.map +1 -1
- package/dist/services/workflow-sanitizer.js +55 -35
- package/dist/services/workflow-sanitizer.js.map +1 -1
- package/dist/types.d.ts +10 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -5
- package/dist/types.js.map +1 -1
- package/package.json +4 -2
|
@@ -1,21 +1,4 @@
|
|
|
1
1
|
export class WorkflowSanitizer {
|
|
2
|
-
/**
|
|
3
|
-
* Recursively sorts object keys to ensure deterministic JSON output.
|
|
4
|
-
*/
|
|
5
|
-
static sortKeys(obj) {
|
|
6
|
-
if (Array.isArray(obj)) {
|
|
7
|
-
return obj.map(this.sortKeys.bind(this));
|
|
8
|
-
}
|
|
9
|
-
else if (obj !== null && typeof obj === 'object') {
|
|
10
|
-
return Object.keys(obj)
|
|
11
|
-
.sort()
|
|
12
|
-
.reduce((acc, key) => {
|
|
13
|
-
acc[key] = this.sortKeys(obj[key]);
|
|
14
|
-
return acc;
|
|
15
|
-
}, {});
|
|
16
|
-
}
|
|
17
|
-
return obj;
|
|
18
|
-
}
|
|
19
2
|
/**
|
|
20
3
|
* Prepares a workflow JSON for storage on disk (GIT).
|
|
21
4
|
* Removes dynamic IDs, execution URLs, and standardizes key order.
|
|
@@ -30,34 +13,71 @@ export class WorkflowSanitizer {
|
|
|
30
13
|
'saveDataErrorExecution',
|
|
31
14
|
'saveManualExecutions',
|
|
32
15
|
'saveExecutionProgress',
|
|
33
|
-
'executionOrder'
|
|
16
|
+
'executionOrder',
|
|
17
|
+
'trialStartedAt'
|
|
34
18
|
];
|
|
35
19
|
keysToRemove.forEach(k => delete settings[k]);
|
|
20
|
+
// Clean nodes
|
|
21
|
+
const nodes = (workflow.nodes || []).map(node => {
|
|
22
|
+
const newNode = { ...node };
|
|
23
|
+
// Remove node-level metadata that might vary
|
|
24
|
+
delete newNode.id; // n8n 2.x often adds node IDs
|
|
25
|
+
// Standardize parameters
|
|
26
|
+
if (newNode.parameters && Object.keys(newNode.parameters).length === 0) {
|
|
27
|
+
newNode.parameters = {};
|
|
28
|
+
}
|
|
29
|
+
return newNode;
|
|
30
|
+
});
|
|
31
|
+
// Build cleaned object with ONLY the fields we want to keep
|
|
32
|
+
// Explicitly exclude version-related fields that n8n auto-generates:
|
|
33
|
+
// - versionId: UUID that changes on every update
|
|
34
|
+
// - activeVersionId: Version tracking field
|
|
35
|
+
// - versionCounter: Increments on every update
|
|
36
|
+
// - pinData: Execution pin data (not part of workflow definition)
|
|
37
|
+
// These fields cause false conflicts if included in hashing
|
|
38
|
+
//
|
|
39
|
+
// IMPORTANT: We build the object with a deterministic key order
|
|
40
|
+
// (id, name, nodes, connections, settings, tags, active)
|
|
41
|
+
// No need to call sortKeys() which would recursively sort ALL keys
|
|
42
|
+
// including inside nodes, which can cause massive diffs
|
|
36
43
|
const cleaned = {
|
|
44
|
+
id: workflow.id,
|
|
37
45
|
name: workflow.name,
|
|
38
|
-
nodes:
|
|
46
|
+
nodes: nodes,
|
|
39
47
|
connections: workflow.connections || {},
|
|
40
48
|
settings: settings,
|
|
41
49
|
tags: workflow.tags || [],
|
|
42
|
-
active: workflow.active
|
|
50
|
+
active: !!workflow.active
|
|
43
51
|
};
|
|
44
|
-
|
|
45
|
-
return this.sortKeys(cleaned);
|
|
52
|
+
return cleaned;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
55
|
* Prepares a local workflow JSON for pushing to n8n API.
|
|
49
56
|
* Removes read-only fields or fields that shouldn't be overwritten blindly (like tags if needed).
|
|
57
|
+
*
|
|
58
|
+
* n8n API v1 PUT /workflows/{id} expects a very specific schema.
|
|
59
|
+
* Based on n8n 2.2.6 API documentation, the allowed fields are:
|
|
60
|
+
* - name (string, required)
|
|
61
|
+
* - nodes (array, required)
|
|
62
|
+
* - connections (object, required)
|
|
63
|
+
* - settings (object, optional but with strict schema)
|
|
64
|
+
* - staticData (object, optional)
|
|
65
|
+
* - triggerCount (number, optional)
|
|
50
66
|
*/
|
|
51
67
|
static cleanForPush(workflow) {
|
|
68
|
+
// Start with cleanForStorage to get basic structure
|
|
52
69
|
const clean = this.cleanForStorage(workflow);
|
|
53
|
-
// n8n
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
// Remove all fields that are not in the n8n API v1 PUT schema
|
|
71
|
+
// Keep only: name, nodes, connections, settings, staticData, triggerCount
|
|
72
|
+
const allowedFields = ['name', 'nodes', 'connections', 'settings', 'staticData', 'triggerCount'];
|
|
73
|
+
const result = {};
|
|
74
|
+
for (const key of allowedFields) {
|
|
75
|
+
if (clean[key] !== undefined) {
|
|
76
|
+
result[key] = clean[key];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Ensure settings is properly filtered
|
|
80
|
+
if (result.settings) {
|
|
61
81
|
const allowedSettings = [
|
|
62
82
|
'errorWorkflow',
|
|
63
83
|
'timezone',
|
|
@@ -67,14 +87,14 @@ export class WorkflowSanitizer {
|
|
|
67
87
|
'executionOrder'
|
|
68
88
|
];
|
|
69
89
|
const filteredSettings = {};
|
|
70
|
-
for (const
|
|
71
|
-
if (
|
|
72
|
-
filteredSettings[
|
|
90
|
+
for (const settingKey of allowedSettings) {
|
|
91
|
+
if (result.settings[settingKey] !== undefined) {
|
|
92
|
+
filteredSettings[settingKey] = result.settings[settingKey];
|
|
73
93
|
}
|
|
74
94
|
}
|
|
75
|
-
|
|
95
|
+
result.settings = filteredSettings;
|
|
76
96
|
}
|
|
77
|
-
return
|
|
97
|
+
return result;
|
|
78
98
|
}
|
|
79
99
|
}
|
|
80
100
|
//# sourceMappingURL=workflow-sanitizer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-sanitizer.js","sourceRoot":"","sources":["../../src/services/workflow-sanitizer.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,iBAAiB;IAC1B
|
|
1
|
+
{"version":3,"file":"workflow-sanitizer.js","sourceRoot":"","sources":["../../src/services/workflow-sanitizer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,11 +18,14 @@ export interface ITag {
|
|
|
18
18
|
name: string;
|
|
19
19
|
}
|
|
20
20
|
export declare enum WorkflowSyncStatus {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
EXIST_ONLY_LOCALLY = "EXIST_ONLY_LOCALLY",
|
|
22
|
+
EXIST_ONLY_REMOTELY = "EXIST_ONLY_REMOTELY",
|
|
23
|
+
IN_SYNC = "IN_SYNC",
|
|
24
|
+
MODIFIED_LOCALLY = "MODIFIED_LOCALLY",
|
|
25
|
+
MODIFIED_REMOTELY = "MODIFIED_REMOTELY",
|
|
26
|
+
CONFLICT = "CONFLICT",
|
|
27
|
+
DELETED_LOCALLY = "DELETED_LOCALLY",
|
|
28
|
+
DELETED_REMOTELY = "DELETED_REMOTELY"
|
|
26
29
|
}
|
|
27
30
|
export interface IWorkflowStatus {
|
|
28
31
|
id: string;
|
|
@@ -37,5 +40,7 @@ export interface ISyncConfig {
|
|
|
37
40
|
syncInactive: boolean;
|
|
38
41
|
ignoredTags: string[];
|
|
39
42
|
instanceIdentifier?: string;
|
|
43
|
+
instanceConfigPath?: string;
|
|
44
|
+
syncMode?: 'auto' | 'manual';
|
|
40
45
|
}
|
|
41
46
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,WAAW,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,kBAAkB;IAC1B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,WAAW,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,kBAAkB;IAC1B,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,OAAO,YAAY;IACnB,gBAAgB,qBAAqB;IACrC,iBAAiB,sBAAsB;IACvC,QAAQ,aAAa;IACrB,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;CACxC;AAED,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChC"}
|
package/dist/types.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export var WorkflowSyncStatus;
|
|
2
2
|
(function (WorkflowSyncStatus) {
|
|
3
|
-
WorkflowSyncStatus["
|
|
4
|
-
WorkflowSyncStatus["
|
|
5
|
-
WorkflowSyncStatus["
|
|
6
|
-
WorkflowSyncStatus["
|
|
7
|
-
WorkflowSyncStatus["
|
|
3
|
+
WorkflowSyncStatus["EXIST_ONLY_LOCALLY"] = "EXIST_ONLY_LOCALLY";
|
|
4
|
+
WorkflowSyncStatus["EXIST_ONLY_REMOTELY"] = "EXIST_ONLY_REMOTELY";
|
|
5
|
+
WorkflowSyncStatus["IN_SYNC"] = "IN_SYNC";
|
|
6
|
+
WorkflowSyncStatus["MODIFIED_LOCALLY"] = "MODIFIED_LOCALLY";
|
|
7
|
+
WorkflowSyncStatus["MODIFIED_REMOTELY"] = "MODIFIED_REMOTELY";
|
|
8
|
+
WorkflowSyncStatus["CONFLICT"] = "CONFLICT";
|
|
9
|
+
WorkflowSyncStatus["DELETED_LOCALLY"] = "DELETED_LOCALLY";
|
|
10
|
+
WorkflowSyncStatus["DELETED_REMOTELY"] = "DELETED_REMOTELY";
|
|
8
11
|
})(WorkflowSyncStatus || (WorkflowSyncStatus = {}));
|
|
9
12
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,kBASX;AATD,WAAY,kBAAkB;IAC1B,+DAAyC,CAAA;IACzC,iEAA2C,CAAA;IAC3C,yCAAmB,CAAA;IACnB,2DAAqC,CAAA;IACrC,6DAAuC,CAAA;IACvC,2CAAqB,CAAA;IACrB,yDAAmC,CAAA;IACnC,2DAAqC,CAAA;AACzC,CAAC,EATW,kBAAkB,KAAlB,kBAAkB,QAS7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n-as-code/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Core library for n8n-as-code ecosystem",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
"validate-schema": "node ../../scripts/validate-schema.js --schema ./src/assets/n8n-nodes-index.json"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@types/json-stable-stringify": "^1.1.0",
|
|
19
20
|
"axios": "^1.6.0",
|
|
20
21
|
"chokidar": "^5.0.0",
|
|
21
22
|
"deep-equal": "^2.2.3",
|
|
23
|
+
"json-stable-stringify": "^1.3.0",
|
|
22
24
|
"zod": "^3.22.4"
|
|
23
25
|
},
|
|
24
26
|
"devDependencies": {
|
|
@@ -38,4 +40,4 @@
|
|
|
38
40
|
"publishConfig": {
|
|
39
41
|
"access": "public"
|
|
40
42
|
}
|
|
41
|
-
}
|
|
43
|
+
}
|