@n8n-as-code/sync 0.5.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/README.md +22 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/services/directory-utils.d.ts +35 -0
- package/dist/services/directory-utils.d.ts.map +1 -0
- package/dist/services/directory-utils.js +75 -0
- package/dist/services/directory-utils.js.map +1 -0
- 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 +23 -0
- package/dist/services/n8n-api-client.d.ts.map +1 -0
- package/dist/services/n8n-api-client.js +193 -0
- package/dist/services/n8n-api-client.js.map +1 -0
- 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 +43 -0
- package/dist/services/state-manager.d.ts.map +1 -0
- package/dist/services/state-manager.js +68 -0
- package/dist/services/state-manager.js.map +1 -0
- package/dist/services/sync-engine.d.ts +56 -0
- package/dist/services/sync-engine.d.ts.map +1 -0
- package/dist/services/sync-engine.js +312 -0
- package/dist/services/sync-engine.js.map +1 -0
- package/dist/services/sync-manager.d.ts +37 -0
- package/dist/services/sync-manager.d.ts.map +1 -0
- package/dist/services/sync-manager.js +280 -0
- package/dist/services/sync-manager.js.map +1 -0
- package/dist/services/trash-service.d.ts +17 -0
- package/dist/services/trash-service.d.ts.map +1 -0
- package/dist/services/trash-service.js +41 -0
- package/dist/services/trash-service.js.map +1 -0
- package/dist/services/watcher.d.ts +135 -0
- package/dist/services/watcher.d.ts.map +1 -0
- package/dist/services/watcher.js +655 -0
- package/dist/services/watcher.js.map +1 -0
- package/dist/services/workflow-sanitizer.d.ts +23 -0
- package/dist/services/workflow-sanitizer.d.ts.map +1 -0
- package/dist/services/workflow-sanitizer.js +100 -0
- package/dist/services/workflow-sanitizer.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { N8nApiClient } from './n8n-api-client.js';
|
|
3
|
+
import { ISyncConfig, IWorkflowStatus } from '../types.js';
|
|
4
|
+
export declare class SyncManager extends EventEmitter {
|
|
5
|
+
private client;
|
|
6
|
+
private config;
|
|
7
|
+
private stateManager;
|
|
8
|
+
private watcher;
|
|
9
|
+
private syncEngine;
|
|
10
|
+
private resolutionManager;
|
|
11
|
+
constructor(client: N8nApiClient, config: ISyncConfig);
|
|
12
|
+
private ensureInitialized;
|
|
13
|
+
getWorkflowsStatus(): Promise<IWorkflowStatus[]>;
|
|
14
|
+
syncDown(): Promise<void>;
|
|
15
|
+
syncUp(): Promise<void>;
|
|
16
|
+
startWatch(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Create or update the n8nac-instance.json file
|
|
19
|
+
* This file marks the workspace as initialized and stores the instance identifier
|
|
20
|
+
*/
|
|
21
|
+
private ensureInstanceConfigFile;
|
|
22
|
+
/**
|
|
23
|
+
* Handle automatic synchronization based on status changes
|
|
24
|
+
* Only triggered in auto mode
|
|
25
|
+
*/
|
|
26
|
+
private handleAutoSync;
|
|
27
|
+
stopWatch(): void;
|
|
28
|
+
refreshState(): Promise<void>;
|
|
29
|
+
getInstanceDirectory(): string;
|
|
30
|
+
resolveConflict(id: string, filename: string, choice: 'local' | 'remote'): Promise<void>;
|
|
31
|
+
handleLocalFileChange(filePath: string): Promise<'updated' | 'created' | 'up-to-date' | 'conflict' | 'skipped'>;
|
|
32
|
+
restoreLocalFile(id: string, filename: string): Promise<boolean>;
|
|
33
|
+
deleteRemoteWorkflow(id: string, filename: string): Promise<boolean>;
|
|
34
|
+
confirmDeletion(id: string, filename: string): Promise<void>;
|
|
35
|
+
restoreRemoteWorkflow(id: string, filename: string): Promise<string>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=sync-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-manager.d.ts","sourceRoot":"","sources":["../../src/services/sync-manager.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKnD,OAAO,EAAE,WAAW,EAAiC,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1F,qBAAa,WAAY,SAAQ,YAAY;IACzC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,iBAAiB,CAAkC;gBAE/C,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW;YAUvC,iBAAiB;IAgEzB,kBAAkB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAMhD,QAAQ;IAaR,MAAM;IAaN,UAAU;IAUhB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;OAGG;YACW,cAAc;IAkD5B,SAAS;IAKH,YAAY;IAOX,oBAAoB,IAAI,MAAM;IAK/B,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,QAAQ;IASxE,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;IAwB/G,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBhE,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpE,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5D,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAI7E"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import EventEmitter from 'events';
|
|
4
|
+
import { StateManager } from './state-manager.js';
|
|
5
|
+
import { Watcher } from './watcher.js';
|
|
6
|
+
import { SyncEngine } from './sync-engine.js';
|
|
7
|
+
import { ResolutionManager } from './resolution-manager.js';
|
|
8
|
+
import { WorkflowSyncStatus } from '../types.js';
|
|
9
|
+
export class SyncManager extends EventEmitter {
|
|
10
|
+
client;
|
|
11
|
+
config;
|
|
12
|
+
stateManager = null;
|
|
13
|
+
watcher = null;
|
|
14
|
+
syncEngine = null;
|
|
15
|
+
resolutionManager = null;
|
|
16
|
+
constructor(client, config) {
|
|
17
|
+
super();
|
|
18
|
+
this.client = client;
|
|
19
|
+
this.config = config;
|
|
20
|
+
if (!fs.existsSync(this.config.directory)) {
|
|
21
|
+
fs.mkdirSync(this.config.directory, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async ensureInitialized() {
|
|
25
|
+
if (this.watcher)
|
|
26
|
+
return;
|
|
27
|
+
// Note: instanceIdentifier logic handling omitted for brevity,
|
|
28
|
+
// assuming it's handled or using default directory for now
|
|
29
|
+
// to focus on the 3-way merge integration.
|
|
30
|
+
const instanceDir = path.join(this.config.directory, this.config.instanceIdentifier || 'default');
|
|
31
|
+
if (!fs.existsSync(instanceDir))
|
|
32
|
+
fs.mkdirSync(instanceDir, { recursive: true });
|
|
33
|
+
this.stateManager = new StateManager(instanceDir);
|
|
34
|
+
this.watcher = new Watcher(this.client, {
|
|
35
|
+
directory: instanceDir,
|
|
36
|
+
pollIntervalMs: this.config.pollIntervalMs,
|
|
37
|
+
syncInactive: this.config.syncInactive,
|
|
38
|
+
ignoredTags: this.config.ignoredTags
|
|
39
|
+
});
|
|
40
|
+
this.syncEngine = new SyncEngine(this.client, this.watcher, instanceDir);
|
|
41
|
+
this.resolutionManager = new ResolutionManager(this.syncEngine, this.watcher, this.client);
|
|
42
|
+
this.watcher.on('statusChange', (data) => {
|
|
43
|
+
this.emit('change', data);
|
|
44
|
+
// Emit specific events for deletions and conflicts
|
|
45
|
+
if (data.status === WorkflowSyncStatus.DELETED_LOCALLY && data.workflowId) {
|
|
46
|
+
this.emit('local-deletion', {
|
|
47
|
+
id: data.workflowId,
|
|
48
|
+
filename: data.filename
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else if (data.status === WorkflowSyncStatus.CONFLICT && data.workflowId) {
|
|
52
|
+
// Fetch remote content for conflict notification
|
|
53
|
+
this.client.getWorkflow(data.workflowId).then(remoteContent => {
|
|
54
|
+
this.emit('conflict', {
|
|
55
|
+
id: data.workflowId,
|
|
56
|
+
filename: data.filename,
|
|
57
|
+
remoteContent
|
|
58
|
+
});
|
|
59
|
+
}).catch(err => {
|
|
60
|
+
console.error(`[SyncManager] Failed to fetch remote content for conflict: ${err.message}`);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Auto-sync in auto mode
|
|
64
|
+
console.log(`[SyncManager] statusChange event: ${data.filename}, status: ${data.status}, syncMode: ${this.config.syncMode}`);
|
|
65
|
+
if (this.config.syncMode === 'auto') {
|
|
66
|
+
console.log(`[SyncManager] Triggering auto-sync for ${data.filename}`);
|
|
67
|
+
this.handleAutoSync(data).catch(err => {
|
|
68
|
+
console.error('[SyncManager] Auto-sync error:', err);
|
|
69
|
+
this.emit('error', `Auto-sync failed: ${err.message}`);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log(`[SyncManager] Auto-sync skipped (mode: ${this.config.syncMode})`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
this.watcher.on('error', (err) => {
|
|
77
|
+
this.emit('error', err);
|
|
78
|
+
});
|
|
79
|
+
this.watcher.on('connection-lost', (err) => {
|
|
80
|
+
this.emit('connection-lost', err);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async getWorkflowsStatus() {
|
|
84
|
+
await this.ensureInitialized();
|
|
85
|
+
// Return status from watcher
|
|
86
|
+
return this.watcher.getStatusMatrix();
|
|
87
|
+
}
|
|
88
|
+
async syncDown() {
|
|
89
|
+
await this.ensureInitialized();
|
|
90
|
+
const statuses = await this.getWorkflowsStatus();
|
|
91
|
+
for (const s of statuses) {
|
|
92
|
+
if (s.status === WorkflowSyncStatus.EXIST_ONLY_REMOTELY ||
|
|
93
|
+
s.status === WorkflowSyncStatus.MODIFIED_REMOTELY) {
|
|
94
|
+
await this.syncEngine.pull(s.id, s.filename, s.status);
|
|
95
|
+
}
|
|
96
|
+
// DELETED_REMOTELY requires user confirmation via confirmDeletion()
|
|
97
|
+
// Per spec 5.2: "Halt. Trigger Deletion Validation."
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async syncUp() {
|
|
101
|
+
await this.ensureInitialized();
|
|
102
|
+
const statuses = await this.getWorkflowsStatus();
|
|
103
|
+
for (const s of statuses) {
|
|
104
|
+
if (s.status === WorkflowSyncStatus.EXIST_ONLY_LOCALLY || s.status === WorkflowSyncStatus.MODIFIED_LOCALLY) {
|
|
105
|
+
await this.syncEngine.push(s.filename, s.id, s.status);
|
|
106
|
+
}
|
|
107
|
+
else if (s.status === WorkflowSyncStatus.DELETED_LOCALLY) {
|
|
108
|
+
// Per spec: Halt and trigger deletion validation
|
|
109
|
+
throw new Error(`Local deletion detected for workflow "${s.filename}". Use confirmDeletion() to proceed with remote deletion or restoreWorkflow() to restore the file.`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async startWatch() {
|
|
114
|
+
await this.ensureInitialized();
|
|
115
|
+
await this.watcher.start();
|
|
116
|
+
// Create instance config file to mark workspace as initialized
|
|
117
|
+
this.ensureInstanceConfigFile();
|
|
118
|
+
this.emit('log', 'Watcher started.');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create or update the n8nac-instance.json file
|
|
122
|
+
* This file marks the workspace as initialized and stores the instance identifier
|
|
123
|
+
*/
|
|
124
|
+
ensureInstanceConfigFile() {
|
|
125
|
+
if (!this.config.instanceConfigPath || !this.config.instanceIdentifier) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const configData = {
|
|
129
|
+
instanceIdentifier: this.config.instanceIdentifier,
|
|
130
|
+
directory: this.config.directory,
|
|
131
|
+
lastSync: new Date().toISOString()
|
|
132
|
+
};
|
|
133
|
+
try {
|
|
134
|
+
fs.writeFileSync(this.config.instanceConfigPath, JSON.stringify(configData, null, 2), 'utf-8');
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.warn(`[SyncManager] Failed to write instance config file: ${error}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Handle automatic synchronization based on status changes
|
|
142
|
+
* Only triggered in auto mode
|
|
143
|
+
*/
|
|
144
|
+
async handleAutoSync(data) {
|
|
145
|
+
const { filename, workflowId, status } = data;
|
|
146
|
+
try {
|
|
147
|
+
switch (status) {
|
|
148
|
+
case WorkflowSyncStatus.MODIFIED_LOCALLY:
|
|
149
|
+
case WorkflowSyncStatus.EXIST_ONLY_LOCALLY:
|
|
150
|
+
// Auto-push local changes
|
|
151
|
+
this.emit('log', `🔄 Auto-sync: Pushing "${filename}"...`);
|
|
152
|
+
await this.syncEngine.push(filename, workflowId, status);
|
|
153
|
+
this.emit('log', `✅ Auto-sync: Pushed "${filename}"`);
|
|
154
|
+
// Emit event to notify that remote was updated (for webview reload)
|
|
155
|
+
if (workflowId) {
|
|
156
|
+
this.emit('remote-updated', { workflowId, filename });
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
case WorkflowSyncStatus.MODIFIED_REMOTELY:
|
|
160
|
+
case WorkflowSyncStatus.EXIST_ONLY_REMOTELY:
|
|
161
|
+
// Auto-pull remote changes
|
|
162
|
+
if (workflowId) {
|
|
163
|
+
this.emit('log', `🔄 Auto-sync: Pulling "${filename}"...`);
|
|
164
|
+
await this.syncEngine.pull(workflowId, filename, status);
|
|
165
|
+
this.emit('log', `✅ Auto-sync: Pulled "${filename}"`);
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
case WorkflowSyncStatus.CONFLICT:
|
|
169
|
+
// Conflicts require manual resolution
|
|
170
|
+
this.emit('log', `⚠️ Conflict detected for "${filename}". Manual resolution required.`);
|
|
171
|
+
// conflict event is handled in ensureInitialized above
|
|
172
|
+
break;
|
|
173
|
+
case WorkflowSyncStatus.DELETED_LOCALLY:
|
|
174
|
+
case WorkflowSyncStatus.DELETED_REMOTELY:
|
|
175
|
+
// Deletions require manual confirmation
|
|
176
|
+
// Note: local-deletion event is already emitted by the Watcher
|
|
177
|
+
// We don't re-emit it here to avoid duplicates
|
|
178
|
+
this.emit('log', `🗑️ Deletion detected for "${filename}". Manual confirmation required.`);
|
|
179
|
+
break;
|
|
180
|
+
case WorkflowSyncStatus.IN_SYNC:
|
|
181
|
+
// Already in sync, nothing to do
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
this.emit('error', `Auto-sync failed for "${filename}": ${error.message}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
stopWatch() {
|
|
190
|
+
this.watcher?.stop();
|
|
191
|
+
this.emit('log', 'Watcher stopped.');
|
|
192
|
+
}
|
|
193
|
+
async refreshState() {
|
|
194
|
+
await this.ensureInitialized();
|
|
195
|
+
// Run sequentially to avoid potential race conditions during state loading
|
|
196
|
+
await this.watcher.refreshRemoteState();
|
|
197
|
+
await this.watcher.refreshLocalState();
|
|
198
|
+
}
|
|
199
|
+
getInstanceDirectory() {
|
|
200
|
+
return path.join(this.config.directory, this.config.instanceIdentifier || 'default');
|
|
201
|
+
}
|
|
202
|
+
// Bridge for conflict resolution
|
|
203
|
+
async resolveConflict(id, filename, choice) {
|
|
204
|
+
await this.ensureInitialized();
|
|
205
|
+
if (choice === 'local') {
|
|
206
|
+
await this.resolutionManager.keepLocal(id, filename);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
await this.resolutionManager.keepRemote(id, filename);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async handleLocalFileChange(filePath) {
|
|
213
|
+
await this.ensureInitialized();
|
|
214
|
+
const filename = path.basename(filePath);
|
|
215
|
+
console.log(`[DEBUG] handleLocalFileChange: ${filename}`);
|
|
216
|
+
// Ensure we have the latest from both worlds
|
|
217
|
+
await this.refreshState();
|
|
218
|
+
const status = this.watcher.calculateStatus(filename);
|
|
219
|
+
switch (status) {
|
|
220
|
+
case WorkflowSyncStatus.IN_SYNC: return 'updated'; // If it's in-sync, we return updated for legacy compatibility in tests
|
|
221
|
+
case WorkflowSyncStatus.CONFLICT: return 'conflict';
|
|
222
|
+
case WorkflowSyncStatus.EXIST_ONLY_LOCALLY:
|
|
223
|
+
await this.syncEngine.push(filename);
|
|
224
|
+
return 'created';
|
|
225
|
+
case WorkflowSyncStatus.MODIFIED_LOCALLY:
|
|
226
|
+
const wfId = this.watcher.getFileToIdMap().get(filename);
|
|
227
|
+
await this.syncEngine.push(filename, wfId, status);
|
|
228
|
+
return 'updated';
|
|
229
|
+
default: return 'skipped';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async restoreLocalFile(id, filename) {
|
|
233
|
+
await this.ensureInitialized();
|
|
234
|
+
try {
|
|
235
|
+
// Determine the deletion type based on current status
|
|
236
|
+
const statuses = await this.getWorkflowsStatus();
|
|
237
|
+
const workflow = statuses.find(s => s.id === id);
|
|
238
|
+
if (!workflow) {
|
|
239
|
+
throw new Error(`Workflow ${id} not found in state`);
|
|
240
|
+
}
|
|
241
|
+
const deletionType = workflow.status === WorkflowSyncStatus.DELETED_LOCALLY ? 'local' : 'remote';
|
|
242
|
+
await this.resolutionManager.restoreWorkflow(id, filename, deletionType);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async deleteRemoteWorkflow(id, filename) {
|
|
250
|
+
await this.ensureInitialized();
|
|
251
|
+
try {
|
|
252
|
+
// Step 1: Archive local file (if exists)
|
|
253
|
+
await this.syncEngine.archive(filename);
|
|
254
|
+
// Step 2: Delete from API
|
|
255
|
+
await this.client.deleteWorkflow(id);
|
|
256
|
+
// Step 3: Remove from state (workflow is completely deleted)
|
|
257
|
+
await this.watcher.removeWorkflowState(id);
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Deletion Validation Methods (6.2 from spec)
|
|
265
|
+
async confirmDeletion(id, filename) {
|
|
266
|
+
await this.ensureInitialized();
|
|
267
|
+
const statuses = await this.getWorkflowsStatus();
|
|
268
|
+
const workflow = statuses.find(s => s.id === id);
|
|
269
|
+
if (!workflow) {
|
|
270
|
+
throw new Error(`Workflow ${id} not found in state`);
|
|
271
|
+
}
|
|
272
|
+
const deletionType = workflow.status === WorkflowSyncStatus.DELETED_LOCALLY ? 'local' : 'remote';
|
|
273
|
+
await this.resolutionManager.confirmDeletion(id, filename, deletionType);
|
|
274
|
+
}
|
|
275
|
+
async restoreRemoteWorkflow(id, filename) {
|
|
276
|
+
await this.ensureInitialized();
|
|
277
|
+
return await this.resolutionManager.restoreWorkflow(id, filename, 'remote');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=sync-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-manager.js","sourceRoot":"","sources":["../../src/services/sync-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class TrashService {
|
|
2
|
+
private archiveDir;
|
|
3
|
+
constructor(baseDir: string);
|
|
4
|
+
/**
|
|
5
|
+
* Moves a file to the archive directory.
|
|
6
|
+
* @param filePath Absolute path to the file to move
|
|
7
|
+
* @param filename Name to use in the archive
|
|
8
|
+
*/
|
|
9
|
+
archiveFile(filePath: string, filename: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Saves a workflow object to the archive directory.
|
|
12
|
+
* @param workflow The workflow object to save
|
|
13
|
+
* @param filename Base filename
|
|
14
|
+
*/
|
|
15
|
+
archiveWorkflow(workflow: any, filename: string): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=trash-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trash-service.d.ts","sourceRoot":"","sources":["../../src/services/trash-service.ts"],"names":[],"mappings":"AAGA,qBAAa,YAAY;IACrB,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,MAAM;IAI3B;;;;OAIG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBtE;;;;OAIG;IACG,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAa1E"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export class TrashService {
|
|
4
|
+
archiveDir;
|
|
5
|
+
constructor(baseDir) {
|
|
6
|
+
this.archiveDir = path.join(baseDir, '.archive');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Moves a file to the archive directory.
|
|
10
|
+
* @param filePath Absolute path to the file to move
|
|
11
|
+
* @param filename Name to use in the archive
|
|
12
|
+
*/
|
|
13
|
+
async archiveFile(filePath, filename) {
|
|
14
|
+
if (!fs.existsSync(this.archiveDir)) {
|
|
15
|
+
fs.mkdirSync(this.archiveDir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
18
|
+
const archivedName = `${timestamp}_${filename}`;
|
|
19
|
+
const targetPath = path.join(this.archiveDir, archivedName);
|
|
20
|
+
if (fs.existsSync(filePath)) {
|
|
21
|
+
fs.renameSync(filePath, targetPath);
|
|
22
|
+
}
|
|
23
|
+
return targetPath;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Saves a workflow object to the archive directory.
|
|
27
|
+
* @param workflow The workflow object to save
|
|
28
|
+
* @param filename Base filename
|
|
29
|
+
*/
|
|
30
|
+
async archiveWorkflow(workflow, filename) {
|
|
31
|
+
if (!fs.existsSync(this.archiveDir)) {
|
|
32
|
+
fs.mkdirSync(this.archiveDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
35
|
+
const archivedName = `${timestamp}_${filename}`;
|
|
36
|
+
const targetPath = path.join(this.archiveDir, archivedName);
|
|
37
|
+
fs.writeFileSync(targetPath, JSON.stringify(workflow, null, 2));
|
|
38
|
+
return targetPath;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=trash-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trash-service.js","sourceRoot":"","sources":["../../src/services/trash-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,OAAO,YAAY;IACb,UAAU,CAAS;IAE3B,YAAY,OAAe;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,QAAgB;QAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAE5D,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,QAAa,EAAE,QAAgB;QACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAE5D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEhE,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import { N8nApiClient } from './n8n-api-client.js';
|
|
3
|
+
import { WorkflowSyncStatus, IWorkflowStatus } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Watcher - State Observation Component
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* 1. File System Watch with debounce
|
|
9
|
+
* 2. Remote Polling with lightweight strategy
|
|
10
|
+
* 3. Canonical Hashing (SHA-256 of sorted JSON)
|
|
11
|
+
* 4. Status Matrix Calculation (3-way comparison)
|
|
12
|
+
* 5. State Persistence (only component that writes to .n8n-state.json)
|
|
13
|
+
*
|
|
14
|
+
* Never performs synchronization actions - only observes reality.
|
|
15
|
+
*/
|
|
16
|
+
export declare class Watcher extends EventEmitter {
|
|
17
|
+
private watcher;
|
|
18
|
+
private pollInterval;
|
|
19
|
+
private client;
|
|
20
|
+
private directory;
|
|
21
|
+
private pollIntervalMs;
|
|
22
|
+
private syncInactive;
|
|
23
|
+
private ignoredTags;
|
|
24
|
+
private stateFilePath;
|
|
25
|
+
private isConnected;
|
|
26
|
+
private isInitializing;
|
|
27
|
+
private localHashes;
|
|
28
|
+
private remoteHashes;
|
|
29
|
+
private fileToIdMap;
|
|
30
|
+
private idToFileMap;
|
|
31
|
+
private lastKnownStatuses;
|
|
32
|
+
private isPaused;
|
|
33
|
+
private syncInProgress;
|
|
34
|
+
private pausedFilenames;
|
|
35
|
+
private remoteTimestamps;
|
|
36
|
+
constructor(client: N8nApiClient, options: {
|
|
37
|
+
directory: string;
|
|
38
|
+
pollIntervalMs: number;
|
|
39
|
+
syncInactive: boolean;
|
|
40
|
+
ignoredTags: string[];
|
|
41
|
+
});
|
|
42
|
+
start(): Promise<void>;
|
|
43
|
+
stop(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Pause observation for a workflow during sync operations
|
|
46
|
+
*/
|
|
47
|
+
pauseObservation(workflowId: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Resume observation after sync operations
|
|
50
|
+
*/
|
|
51
|
+
resumeObservation(workflowId: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Pause observation for a filename (for workflows without ID yet)
|
|
54
|
+
*/
|
|
55
|
+
pauseObservationByFilename(filename: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Resume observation for a filename
|
|
58
|
+
*/
|
|
59
|
+
resumeObservationByFilename(filename: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Mark a workflow as being synced (prevents race conditions)
|
|
62
|
+
*/
|
|
63
|
+
markSyncInProgress(workflowId: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Mark a workflow as no longer being synced
|
|
66
|
+
*/
|
|
67
|
+
markSyncComplete(workflowId: string): void;
|
|
68
|
+
private onLocalChange;
|
|
69
|
+
private onLocalDelete;
|
|
70
|
+
refreshLocalState(): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Lightweight polling strategy:
|
|
73
|
+
* 1. Fetch only IDs and updatedAt timestamps
|
|
74
|
+
* 2. Compare with cached timestamps
|
|
75
|
+
* 3. Fetch full content only if timestamp changed
|
|
76
|
+
*/
|
|
77
|
+
refreshRemoteState(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Finalize sync - update base state after successful sync operation
|
|
80
|
+
* Called by SyncEngine after PULL/PUSH completes
|
|
81
|
+
*/
|
|
82
|
+
finalizeSync(workflowId: string): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Update workflow state in .n8n-state.json
|
|
85
|
+
* Only this component writes to the state file
|
|
86
|
+
*/
|
|
87
|
+
private updateWorkflowState;
|
|
88
|
+
/**
|
|
89
|
+
* Remove workflow from state file
|
|
90
|
+
* Called after deletion confirmation
|
|
91
|
+
*/
|
|
92
|
+
removeWorkflowState(id: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Load state from .n8n-state.json
|
|
95
|
+
*/
|
|
96
|
+
private loadState;
|
|
97
|
+
/**
|
|
98
|
+
* Save state to .n8n-state.json
|
|
99
|
+
*/
|
|
100
|
+
private saveState;
|
|
101
|
+
/**
|
|
102
|
+
* Compute canonical hash for content
|
|
103
|
+
*/
|
|
104
|
+
private computeHash;
|
|
105
|
+
private broadcastStatus;
|
|
106
|
+
calculateStatus(filename: string, workflowId?: string): WorkflowSyncStatus;
|
|
107
|
+
private shouldIgnore;
|
|
108
|
+
private safeName;
|
|
109
|
+
/**
|
|
110
|
+
* Find local file that contains a specific workflow ID
|
|
111
|
+
* Used when we have an ID but no filename mapping yet (e.g., after file rename)
|
|
112
|
+
*/
|
|
113
|
+
private findFilenameByWorkflowId;
|
|
114
|
+
private readJsonFile;
|
|
115
|
+
getFileToIdMap(): Map<string, string>;
|
|
116
|
+
getStatusMatrix(): IWorkflowStatus[];
|
|
117
|
+
/**
|
|
118
|
+
* Get last synced hash for a workflow
|
|
119
|
+
*/
|
|
120
|
+
getLastSyncedHash(workflowId: string): string | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* Update remote hash cache (for SyncEngine use)
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
setRemoteHash(workflowId: string, hash: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* Get all tracked workflow IDs
|
|
128
|
+
*/
|
|
129
|
+
getTrackedWorkflowIds(): string[];
|
|
130
|
+
/**
|
|
131
|
+
* Update workflow ID in state (when a workflow is re-created with a new ID)
|
|
132
|
+
*/
|
|
133
|
+
updateWorkflowId(oldId: string, newId: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/services/watcher.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAa,MAAM,aAAa,CAAC;AAG7E;;;;;;;;;;;GAWG;AACH,qBAAa,OAAQ,SAAQ,YAAY;IACrC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,cAAc,CAAkB;IAGxC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,iBAAiB,CAA8C;IAGvE,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,eAAe,CAAqB;IAG5C,OAAO,CAAC,gBAAgB,CAAkC;gBAGtD,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,MAAM,EAAE,CAAC;KACzB;IAWQ,KAAK;IAwDX,IAAI;IAWX;;OAEG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM;IAI1C;;OAEG;IACI,iBAAiB,CAAC,UAAU,EAAE,MAAM;IAO3C;;OAEG;IACI,0BAA0B,CAAC,QAAQ,EAAE,MAAM;IAIlD;;OAEG;IACI,2BAA2B,CAAC,QAAQ,EAAE,MAAM;IAInD;;OAEG;IACI,kBAAkB,CAAC,UAAU,EAAE,MAAM;IAI5C;;OAEG;IACI,gBAAgB,CAAC,UAAU,EAAE,MAAM;YAI5B,aAAa;YAgCb,aAAa;IAyDd,iBAAiB;IAuC9B;;;;;OAKG;IACU,kBAAkB;IAgG/B;;;OAGG;IACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD5D;;;OAGG;YACW,mBAAmB;IASjC;;;OAGG;IACU,mBAAmB,CAAC,EAAE,EAAE,MAAM;IAe3C;;OAEG;IACH,OAAO,CAAC,SAAS;IAejB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,eAAe;IAiBhB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB;IAuCjF,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,QAAQ;IAIhB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,YAAY;IAQb,cAAc;IAId,eAAe,IAAI,eAAe,EAAE;IAmD3C;;OAEG;IACI,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKhE;;;OAGG;IACI,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5D;;OAEG;IACI,qBAAqB,IAAI,MAAM,EAAE;IAKxC;;OAEG;IACU,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA+B7E"}
|