@pipedream/google_drive 4.0.1 → 5.0.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 (71) hide show
  1. package/actions/add-comment/add-comment.mjs +1 -1
  2. package/actions/add-file-sharing-preference/add-file-sharing-preference.mjs +1 -1
  3. package/actions/copy-file/copy-file.mjs +1 -1
  4. package/actions/create-file-from-template/create-file-from-template.mjs +1 -1
  5. package/actions/create-file-from-text/create-file-from-text.mjs +1 -1
  6. package/actions/create-folder/create-folder.mjs +1 -1
  7. package/actions/create-shared-drive/create-shared-drive.mjs +1 -1
  8. package/actions/create-text-file/create-text-file.mjs +1 -1
  9. package/actions/delete-comment/delete-comment.mjs +1 -1
  10. package/actions/delete-file/delete-file.mjs +1 -1
  11. package/actions/delete-reply/delete-reply.mjs +1 -1
  12. package/actions/delete-shared-drive/delete-shared-drive.mjs +1 -1
  13. package/actions/download-file/download-file.mjs +1 -1
  14. package/actions/find-file/find-file.mjs +1 -1
  15. package/actions/find-folder/find-folder.mjs +1 -1
  16. package/actions/find-forms/find-forms.mjs +1 -1
  17. package/actions/find-spreadsheets/find-spreadsheets.mjs +1 -1
  18. package/actions/get-comment/get-comment.mjs +1 -1
  19. package/actions/get-current-user/get-current-user.mjs +1 -1
  20. package/actions/get-file/get-file.mjs +1 -1
  21. package/actions/get-file-by-id/get-file-by-id.mjs +1 -1
  22. package/actions/get-folder-id-for-path/get-folder-id-for-path.mjs +1 -1
  23. package/actions/get-reply/get-reply.mjs +1 -1
  24. package/actions/get-shared-drive/get-shared-drive.mjs +1 -1
  25. package/actions/get-user-details/get-user-details.mjs +1 -1
  26. package/actions/is-folder-ancestor/is-folder-ancestor.mjs +1 -1
  27. package/actions/list-access-proposals/list-access-proposals.mjs +1 -1
  28. package/actions/list-comments/list-comments.mjs +1 -1
  29. package/actions/list-files/list-files.mjs +1 -1
  30. package/actions/list-mime-type-options/list-mime-type-options.mjs +1 -1
  31. package/actions/list-permissions/list-permissions.mjs +1 -1
  32. package/actions/list-replies/list-replies.mjs +1 -1
  33. package/actions/list-shared-drives/list-shared-drives.mjs +1 -1
  34. package/actions/list-theme-id-options/list-theme-id-options.mjs +1 -1
  35. package/actions/move-file/move-file.mjs +1 -1
  36. package/actions/move-file-to-trash/move-file-to-trash.mjs +1 -1
  37. package/actions/remove-file-sharing-permission/remove-file-sharing-permission.mjs +1 -1
  38. package/actions/remove-sharing/remove-sharing.mjs +1 -1
  39. package/actions/reply-to-comment/reply-to-comment.mjs +1 -1
  40. package/actions/resolve-access-proposal/resolve-access-proposal.mjs +1 -1
  41. package/actions/resolve-comment/resolve-comment.mjs +1 -1
  42. package/actions/search-files/search-files.mjs +1 -1
  43. package/actions/search-shared-drives/search-shared-drives.mjs +1 -1
  44. package/actions/share-file/share-file.mjs +1 -1
  45. package/actions/trash-file/trash-file.mjs +1 -1
  46. package/actions/update-comment/update-comment.mjs +1 -1
  47. package/actions/update-file/update-file.mjs +1 -1
  48. package/actions/update-reply/update-reply.mjs +1 -1
  49. package/actions/update-shared-drive/update-shared-drive.mjs +1 -1
  50. package/actions/upload-file/upload-file.mjs +1 -1
  51. package/common/constants.mjs +22 -12
  52. package/google_drive.app.mjs +90 -11
  53. package/package.json +1 -1
  54. package/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs +9 -6
  55. package/sources/changes-to-specific-files/changes-to-specific-files.mjs +1 -1
  56. package/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs +9 -6
  57. package/sources/common-dedupe-changes.mjs +22 -11
  58. package/sources/common-webhook.mjs +104 -40
  59. package/sources/new-access-proposal/new-access-proposal.mjs +1 -1
  60. package/sources/new-files-instant/new-files-instant.mjs +4 -1
  61. package/sources/new-files-instant-polling/new-files-instant-polling.mjs +38 -47
  62. package/sources/new-files-shared-drive/new-files-shared-drive.mjs +2 -16
  63. package/sources/new-or-modified-comments/new-or-modified-comments.mjs +10 -7
  64. package/sources/new-or-modified-comments-polling/new-or-modified-comments-polling.mjs +1 -1
  65. package/sources/new-or-modified-files/new-or-modified-files.mjs +20 -1
  66. package/sources/new-or-modified-files-polling/new-or-modified-files-polling.mjs +37 -36
  67. package/sources/new-or-modified-folders/new-or-modified-folders.mjs +52 -50
  68. package/sources/new-or-modified-folders-polling/new-or-modified-folders-polling.mjs +55 -63
  69. package/sources/new-shared-drive/new-shared-drive.mjs +1 -1
  70. package/sources/new-spreadsheet/new-spreadsheet.mjs +1 -1
  71. package/sources/new-spreadsheet-polling/new-spreadsheet-polling.mjs +38 -47
@@ -4,7 +4,10 @@ import {
4
4
  getListFilesOpts,
5
5
  isMyDrive,
6
6
  } from "../../common/utils.mjs";
7
- import { GOOGLE_DRIVE_FOLDER_MIME_TYPE } from "../../common/constants.mjs";
7
+ import {
8
+ CHANGE_FILTER_FILE_FIELDS,
9
+ GOOGLE_DRIVE_FOLDER_MIME_TYPE,
10
+ } from "../../common/constants.mjs";
8
11
  import sampleEmit from "./test-event.mjs";
9
12
  import md5 from "md5";
10
13
 
@@ -12,7 +15,7 @@ export default {
12
15
  key: "google_drive-new-or-modified-folders-polling",
13
16
  name: "New or Modified Folders (Polling)",
14
17
  description: "Emit new event when a folder is created or modified in the selected Drive",
15
- version: "0.0.16",
18
+ version: "0.1.0",
16
19
  type: "source",
17
20
  dedupe: "unique",
18
21
  props: {
@@ -56,6 +59,12 @@ export default {
56
59
  "changesPageSize",
57
60
  ],
58
61
  },
62
+ maxEmitsPerRun: {
63
+ propDefinition: [
64
+ googleDrive,
65
+ "maxEmitsPerRun",
66
+ ],
67
+ },
59
68
  },
60
69
  hooks: {
61
70
  async deploy() {
@@ -115,20 +124,21 @@ export default {
115
124
  ...args,
116
125
  });
117
126
  },
118
- async getAllParents(folderId) {
127
+ async getAllParents(folderId, parentsCache = new Map()) {
119
128
  const allParents = [];
120
129
  let currentId = folderId;
121
130
 
122
131
  while (currentId) {
123
- const folder = await this.googleDrive.getFile(currentId, {
124
- fields: "parents",
125
- });
126
- const parents = folder.parents;
127
-
128
- if (parents && parents.length > 0) {
129
- allParents.push(parents[0]);
132
+ if (!parentsCache.has(currentId)) {
133
+ const { parents } = await this.googleDrive.getFile(currentId, {
134
+ fields: "parents",
135
+ });
136
+ parentsCache.set(currentId, parents?.[0]);
137
+ }
138
+ currentId = parentsCache.get(currentId);
139
+ if (currentId) {
140
+ allParents.push(currentId);
130
141
  }
131
- currentId = parents?.[0];
132
142
  }
133
143
 
134
144
  return allParents;
@@ -141,7 +151,7 @@ export default {
141
151
  );
142
152
  return root.id;
143
153
  },
144
- async shouldProcess(file, rootId) {
154
+ async shouldProcess(file, rootId, parentsCache) {
145
155
  // Skip if not a folder
146
156
  if (file.mimeType !== GOOGLE_DRIVE_FOLDER_MIME_TYPE) {
147
157
  return false;
@@ -154,7 +164,7 @@ export default {
154
164
 
155
165
  const allParents = [];
156
166
  if (this.includeSubfolders) {
157
- allParents.push(...(await this.getAllParents(file.id)));
167
+ allParents.push(...(await this.getAllParents(file.id, parentsCache)));
158
168
  } else if (file.parents) {
159
169
  allParents.push(file.parents[0]);
160
170
  }
@@ -182,60 +192,42 @@ export default {
182
192
  },
183
193
  async run() {
184
194
  const currentRunTimestamp = Date.now();
185
-
186
- const pageToken = this._getPageToken();
187
- const driveId = this.getDriveId();
188
195
  const rootId = await this.getRootId();
189
-
190
- const changedFilesStream =
191
- this.googleDrive.listChanges(pageToken, driveId, this.changesPageSize);
192
-
193
- for await (const changedFilesPage of changedFilesStream) {
194
- const {
195
- changedFiles,
196
- nextPageToken,
197
- } = changedFilesPage;
198
-
199
- console.log(changedFiles.length
200
- ? `Processing ${changedFiles.length} changed files`
201
- : "No changed files since last run");
202
-
203
- for (const file of changedFiles) {
204
- // Skip if not a folder
205
- if (file.mimeType !== GOOGLE_DRIVE_FOLDER_MIME_TYPE) {
206
- continue;
196
+ const parentsCache = new Map();
197
+
198
+ const caughtUp = await this.googleDrive.processChangesPages({
199
+ pageToken: this._getPageToken(),
200
+ driveId: this.getDriveId(),
201
+ pageSize: this.changesPageSize,
202
+ fileFields: CHANGE_FILTER_FILE_FIELDS,
203
+ maxEmits: this.maxEmitsPerRun,
204
+ changeFilter: async ({ file }) => file.mimeType === GOOGLE_DRIVE_FOLDER_MIME_TYPE
205
+ && this._getLastModifiedTimeForFile(file.id) !== Date.parse(file.modifiedTime)
206
+ && await this.shouldProcess(file, rootId, parentsCache),
207
+ processPage: async (changedFiles) => {
208
+ console.log(changedFiles.length
209
+ ? `Processing ${changedFiles.length} changed folders`
210
+ : "No changed folders since last run");
211
+
212
+ let emitted = 0;
213
+ for (const file of changedFiles) {
214
+ const modifiedTime = Date.parse(file.modifiedTime);
215
+ const fullFile = await this.googleDrive.getFile(file.id, {
216
+ fields: "*",
217
+ });
218
+ await this.emitFolder(fullFile);
219
+ emitted++;
220
+
221
+ this._setModifiedTimeForFile(fullFile.id, modifiedTime);
207
222
  }
223
+ return emitted;
224
+ },
225
+ savePageToken: (nextPageToken) => this._setPageToken(nextPageToken),
226
+ });
208
227
 
209
- // Get full file metadata
210
- const fullFile = await this.googleDrive.getFile(file.id, {
211
- fields: "*",
212
- });
213
-
214
- const modifiedTime = Date.parse(fullFile.modifiedTime);
215
- const lastModifiedTimeForFile = this._getLastModifiedTimeForFile(fullFile.id);
216
-
217
- // Skip if not modified since last check
218
- if (lastModifiedTimeForFile === modifiedTime) {
219
- console.log(`Skipping unmodified folder ${fullFile.name || fullFile.id}`);
220
- continue;
221
- }
222
-
223
- if (!await this.shouldProcess(fullFile, rootId)) {
224
- console.log(`Skipping folder ${fullFile.name || fullFile.id}`);
225
- continue;
226
- }
227
-
228
- await this.emitFolder(fullFile);
229
-
230
- this._setModifiedTimeForFile(fullFile.id, modifiedTime);
231
- }
232
-
233
- // Save the next page token after successfully processing
234
- this._setPageToken(nextPageToken);
228
+ if (caughtUp) {
229
+ this._setLastRunTimestamp(currentRunTimestamp);
235
230
  }
236
-
237
- // Update the last run timestamp after processing all changes
238
- this._setLastRunTimestamp(currentRunTimestamp);
239
231
  },
240
232
  sampleEmit,
241
233
  };
@@ -5,7 +5,7 @@ export default {
5
5
  key: "google_drive-new-shared-drive",
6
6
  name: "New Shared Drive",
7
7
  description: "Emits a new event any time a shared drive is created.",
8
- version: "0.1.27",
8
+ version: "0.1.28",
9
9
  type: "source",
10
10
  dedupe: "unique",
11
11
  props: {
@@ -6,7 +6,7 @@ export default {
6
6
  type: "source",
7
7
  name: "New Spreadsheet (Instant)",
8
8
  description: "Emit new event when a new spreadsheet is created in a drive.",
9
- version: "0.1.30",
9
+ version: "0.2.0",
10
10
  props: {
11
11
  googleDrive: newFilesInstant.props.googleDrive,
12
12
  db: newFilesInstant.props.db,
@@ -1,14 +1,17 @@
1
1
  import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2
2
  import googleDrive from "../../google_drive.app.mjs";
3
3
  import { getListFilesOpts } from "../../common/utils.mjs";
4
- import { GOOGLE_DRIVE_FOLDER_MIME_TYPE } from "../../common/constants.mjs";
4
+ import {
5
+ CHANGE_FILTER_FILE_FIELDS,
6
+ GOOGLE_DRIVE_FOLDER_MIME_TYPE,
7
+ } from "../../common/constants.mjs";
5
8
  import sampleEmit from "./test-event.mjs";
6
9
 
7
10
  export default {
8
11
  key: "google_drive-new-spreadsheet-polling",
9
12
  name: "New Spreadsheet (Polling)",
10
13
  description: "Emit new event when a new spreadsheet is created in a drive.",
11
- version: "0.0.15",
14
+ version: "0.1.0",
12
15
  type: "source",
13
16
  dedupe: "unique",
14
17
  props: {
@@ -50,6 +53,12 @@ export default {
50
53
  "changesPageSize",
51
54
  ],
52
55
  },
56
+ maxEmitsPerRun: {
57
+ propDefinition: [
58
+ googleDrive,
59
+ "maxEmitsPerRun",
60
+ ],
61
+ },
53
62
  },
54
63
  hooks: {
55
64
  async deploy() {
@@ -141,54 +150,36 @@ export default {
141
150
  const currentRunTimestamp = Date.now();
142
151
  const lastRunTimestamp = this._getLastRunTimestamp();
143
152
 
144
- const pageToken = this._getPageToken();
145
- const driveId = this.getDriveId();
146
-
147
- const changedFilesStream =
148
- this.googleDrive.listChanges(pageToken, driveId, this.changesPageSize);
149
-
150
- for await (const changedFilesPage of changedFilesStream) {
151
- const {
152
- changedFiles,
153
- nextPageToken,
154
- } = changedFilesPage;
155
-
156
- console.log(changedFiles.length
157
- ? `Processing ${changedFiles.length} changed files`
158
- : "No changed files since last run");
159
-
160
- for (const file of changedFiles) {
161
- // Skip if not a spreadsheet
162
- if (!file.mimeType || !file.mimeType.includes("spreadsheet")) {
163
- continue;
153
+ const caughtUp = await this.googleDrive.processChangesPages({
154
+ pageToken: this._getPageToken(),
155
+ driveId: this.getDriveId(),
156
+ pageSize: this.changesPageSize,
157
+ fileFields: CHANGE_FILTER_FILE_FIELDS,
158
+ maxEmits: this.maxEmitsPerRun,
159
+ changeFilter: ({ file }) => Date.parse(file.createdTime) > lastRunTimestamp
160
+ && this.shouldProcess(file),
161
+ processPage: async (changedFiles) => {
162
+ console.log(changedFiles.length
163
+ ? `Processing ${changedFiles.length} new spreadsheets`
164
+ : "No new spreadsheets since last run");
165
+
166
+ let emitted = 0;
167
+ for (const file of changedFiles) {
168
+ const fullFile = await this.googleDrive.getFile(file.id, {
169
+ fields: "*",
170
+ });
171
+ await this.emitSpreadsheet(fullFile);
172
+ emitted++;
164
173
  }
174
+ return emitted;
175
+ },
176
+ savePageToken: (nextPageToken) => this._setPageToken(nextPageToken),
177
+ });
165
178
 
166
- // Get full file metadata including parents
167
- const fullFile = await this.googleDrive.getFile(file.id, {
168
- fields: "*",
169
- });
170
-
171
- // Check if it's a new spreadsheet (created after last run)
172
- const fileCreatedTime = Date.parse(fullFile.createdTime);
173
- if (fileCreatedTime <= lastRunTimestamp) {
174
- console.log(`Skipping existing spreadsheet ${fullFile.name || fullFile.id}`);
175
- continue;
176
- }
177
-
178
- if (!this.shouldProcess(fullFile)) {
179
- console.log(`Skipping spreadsheet ${fullFile.name || fullFile.id}`);
180
- continue;
181
- }
182
-
183
- await this.emitSpreadsheet(fullFile);
184
- }
185
-
186
- // Save the next page token after successfully processing
187
- this._setPageToken(nextPageToken);
179
+ // Hold until caught up so backlog files aren't skipped
180
+ if (caughtUp) {
181
+ this._setLastRunTimestamp(currentRunTimestamp);
188
182
  }
189
-
190
- // Update the last run timestamp after processing all changes
191
- this._setLastRunTimestamp(currentRunTimestamp);
192
183
  },
193
184
  sampleEmit,
194
185
  };