n8n-nodes-onedrive-business 1.1.2 → 1.1.5

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.
@@ -358,9 +358,9 @@ class OneDriveBusinessTrigger {
358
358
  OneDriveBusinessTrigger.instances.set(nodeId, instance);
359
359
  }
360
360
  // Create delta processor
361
- const deltaProcessor = new DeltaProcessor_1.DeltaProcessor(graphClient, instance.stateStore, drivePath);
361
+ const deltaProcessor = new DeltaProcessor_1.DeltaProcessor(graphClient, instance.stateStore, drivePath, watchPath);
362
362
  // Process delta query
363
- const triggerEvents = await deltaProcessor.processDeltaQuery(eventFilter, watchPath);
363
+ const triggerEvents = await deltaProcessor.processDeltaQuery(eventFilter);
364
364
  // Clean up old versions periodically
365
365
  const state = instance.stateStore.getState();
366
366
  const processedCount = Object.keys(state.processedVersions).length;
@@ -378,7 +378,7 @@ class OneDriveBusinessTrigger {
378
378
  },
379
379
  })));
380
380
  }
381
- return workflowData;
381
+ return workflowData.length > 0 ? workflowData : null;
382
382
  }
383
383
  }
384
384
  exports.OneDriveBusinessTrigger = OneDriveBusinessTrigger;
@@ -36,21 +36,16 @@ export declare class DeltaProcessor {
36
36
  private graphClient;
37
37
  private stateStore;
38
38
  private drivePath;
39
+ private watchPath?;
39
40
  private stabilityTracker;
40
41
  private readonly STABILITY_WINDOW_MS;
41
- constructor(graphClient: GraphClient, stateStore: StateStore, drivePath: string);
42
+ constructor(graphClient: GraphClient, stateStore: StateStore, drivePath: string, watchPath?: string);
42
43
  /**
43
44
  * Process delta query and return triggerable events
44
45
  *
45
46
  * This is the main entry point called by the trigger node
46
47
  */
47
- /**
48
- * Process delta query and return triggerable events
49
- *
50
- * This is the main entry point called by the trigger node
51
- */
52
- processDeltaQuery(eventFilter: Set<string>, // e.g., ['file.created', 'file.updated']
53
- watchPath?: string): Promise<TriggerEvent[]>;
48
+ processDeltaQuery(eventFilter: Set<string>): Promise<TriggerEvent[]>;
54
49
  /**
55
50
  * Fetch all pages from delta query
56
51
  * Handles @odata.nextLink pagination and stores @odata.deltaLink
@@ -61,10 +56,6 @@ export declare class DeltaProcessor {
61
56
  * Returns a TriggerEvent if the item should trigger a workflow
62
57
  */
63
58
  private processItem;
64
- /**
65
- * Check if item is within the watched path
66
- */
67
- private isItemInScope;
68
59
  /**
69
60
  * Classify event as created vs updated
70
61
  *
@@ -34,7 +34,7 @@ const helpers_1 = require("./helpers");
34
34
  * Without this processor, ONE file upload would trigger FOUR workflow executions.
35
35
  */
36
36
  class DeltaProcessor {
37
- constructor(graphClient, stateStore, drivePath) {
37
+ constructor(graphClient, stateStore, drivePath, watchPath) {
38
38
  // Stability tracking for files currently being uploaded
39
39
  this.stabilityTracker = new Map();
40
40
  // Stability window: wait 15 seconds after last modification
@@ -42,19 +42,15 @@ class DeltaProcessor {
42
42
  this.graphClient = graphClient;
43
43
  this.stateStore = stateStore;
44
44
  this.drivePath = drivePath;
45
+ this.watchPath = watchPath;
45
46
  }
46
47
  /**
47
48
  * Process delta query and return triggerable events
48
49
  *
49
50
  * This is the main entry point called by the trigger node
50
51
  */
51
- /**
52
- * Process delta query and return triggerable events
53
- *
54
- * This is the main entry point called by the trigger node
55
- */
56
- async processDeltaQuery(eventFilter, // e.g., ['file.created', 'file.updated']
57
- watchPath) {
52
+ async processDeltaQuery(eventFilter // e.g., ['file.created', 'file.updated']
53
+ ) {
58
54
  const events = [];
59
55
  try {
60
56
  // Get current state
@@ -69,13 +65,28 @@ class DeltaProcessor {
69
65
  }
70
66
  else {
71
67
  // Initial delta query
72
- deltaEndpoint = `${this.drivePath}/root/delta`;
68
+ if (this.watchPath && this.watchPath !== '' && this.watchPath !== '/') {
69
+ // Scope to specific folder
70
+ let path = this.watchPath;
71
+ if (!path.startsWith('/')) {
72
+ path = '/' + path;
73
+ }
74
+ // Syntax: /drive/root:/path/to/folder:/delta
75
+ // Note the colons wrapping the path
76
+ deltaEndpoint = `${this.drivePath}/root:${encodeURIComponent(path)}:/delta`;
77
+ console.log(`[DeltaProcessor] Initializing Scoped Delta Query: ${deltaEndpoint}`);
78
+ }
79
+ else {
80
+ // Browse entire drive
81
+ deltaEndpoint = `${this.drivePath}/root/delta`;
82
+ console.log(`[DeltaProcessor] Initializing Root Delta Query`);
83
+ }
73
84
  }
74
85
  // Fetch delta changes (handle pagination)
75
86
  const items = await this.fetchAllDeltaPages(deltaEndpoint);
76
87
  // Process each item
77
88
  for (const item of items) {
78
- const event = await this.processItem(item, eventFilter, watchPath);
89
+ const event = await this.processItem(item, eventFilter);
79
90
  if (event) {
80
91
  events.push(event);
81
92
  }
@@ -95,6 +106,8 @@ class DeltaProcessor {
95
106
  const allItems = [];
96
107
  let currentEndpoint = initialEndpoint;
97
108
  while (currentEndpoint) {
109
+ // Log for debugging
110
+ console.log(`[DeltaProcessor] Fetching: ${currentEndpoint}`);
98
111
  const response = await this.graphClient.get(currentEndpoint);
99
112
  allItems.push(...response.value);
100
113
  // Check for next page
@@ -119,19 +132,18 @@ class DeltaProcessor {
119
132
  * Process a single delta item
120
133
  * Returns a TriggerEvent if the item should trigger a workflow
121
134
  */
122
- async processItem(item, eventFilter, watchPath) {
135
+ async processItem(item, eventFilter) {
123
136
  // Skip deleted items (unless specifically requested)
124
137
  if (item.deleted) {
125
138
  return null;
126
139
  }
127
- // Skip root folder
140
+ // Skip root folder (the folder itself, not its children)
128
141
  if (!item.parentReference) {
129
142
  return null;
130
143
  }
131
- // Check scope (folder filtering)
132
- if (watchPath && !this.isItemInScope(item, watchPath)) {
133
- return null;
134
- }
144
+ // Note: We don't need manual scope checking (isItemInScope) anymore
145
+ // because the Delta Query itself is scoped to the target folder.
146
+ // Any item returned here IS in the scope.
135
147
  // Determine event type
136
148
  const eventType = this.classifyEvent(item);
137
149
  // Check if this event type is enabled
@@ -163,42 +175,6 @@ class DeltaProcessor {
163
175
  timestamp: new Date().toISOString(),
164
176
  };
165
177
  }
166
- /**
167
- * Check if item is within the watched path
168
- */
169
- isItemInScope(item, watchPath) {
170
- if (!item.parentReference || !item.parentReference.path) {
171
- return false;
172
- }
173
- // Extract relative path from parentReference.path
174
- // Format: /drives/{drive-id}/root:/path/to/folder
175
- const parts = item.parentReference.path.split('root:');
176
- if (parts.length < 2) {
177
- // Item is in root
178
- // If watchPath is /, then it's a match. Otherwise no.
179
- return watchPath === '/' || watchPath === '';
180
- }
181
- let relativePath = parts[1]; // /path/to/folder
182
- // Ensure paths start with / for consistent comparison
183
- if (!relativePath.startsWith('/')) {
184
- relativePath = '/' + relativePath;
185
- }
186
- // Ensure watchPath starts with /
187
- let normalizedWatchPath = watchPath;
188
- if (!normalizedWatchPath.startsWith('/')) {
189
- normalizedWatchPath = '/' + normalizedWatchPath;
190
- }
191
- // Check if relative path matches or is a subfolder
192
- // 1. Exact match: relativePath === normalizedWatchPath
193
- // 2. Subfolder: relativePath startsWith normalizedWatchPath + '/'
194
- if (relativePath === normalizedWatchPath) {
195
- return true;
196
- }
197
- if (relativePath.startsWith(normalizedWatchPath + '/')) {
198
- return true;
199
- }
200
- return false;
201
- }
202
178
  /**
203
179
  * Classify event as created vs updated
204
180
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-onedrive-business",
3
- "version": "1.1.2",
3
+ "version": "1.1.5",
4
4
  "description": "n8n custom node for OneDrive Business with robust deduplication and webhook triggers",
5
5
  "keywords": [
6
6
  "n8n",