@pipedream/google_drive 1.12.2 → 2.1.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/actions/add-comment/add-comment.mjs +1 -1
- package/actions/add-file-sharing-preference/add-file-sharing-preference.mjs +1 -1
- package/actions/copy-file/copy-file.mjs +1 -1
- package/actions/create-file-from-template/create-file-from-template.mjs +1 -1
- package/actions/create-file-from-text/create-file-from-text.mjs +1 -1
- package/actions/create-folder/create-folder.mjs +1 -1
- package/actions/create-shared-drive/create-shared-drive.mjs +1 -1
- package/actions/create-text-file/create-text-file.mjs +1 -1
- package/actions/delete-comment/delete-comment.mjs +1 -1
- package/actions/delete-file/delete-file.mjs +1 -1
- package/actions/delete-reply/delete-reply.mjs +1 -1
- package/actions/delete-shared-drive/delete-shared-drive.mjs +1 -1
- package/actions/download-file/download-file.mjs +142 -80
- package/actions/find-file/find-file.mjs +1 -1
- package/actions/find-folder/find-folder.mjs +1 -1
- package/actions/find-forms/find-forms.mjs +1 -1
- package/actions/find-spreadsheets/find-spreadsheets.mjs +1 -1
- package/actions/get-comment/get-comment.mjs +1 -1
- package/actions/get-current-user/get-current-user.mjs +1 -1
- package/actions/get-file/get-file.mjs +1 -1
- package/actions/get-file-by-id/get-file-by-id.mjs +1 -1
- package/actions/get-folder-id-for-path/get-folder-id-for-path.mjs +1 -1
- package/actions/get-reply/get-reply.mjs +1 -1
- package/actions/get-shared-drive/get-shared-drive.mjs +1 -1
- package/actions/get-user-details/get-user-details.mjs +1 -1
- package/actions/is-folder-ancestor/is-folder-ancestor.mjs +1 -1
- package/actions/list-access-proposals/list-access-proposals.mjs +1 -1
- package/actions/list-comments/list-comments.mjs +59 -10
- package/actions/list-files/list-files.mjs +69 -25
- package/actions/list-mime-type-options/list-mime-type-options.mjs +1 -1
- package/actions/list-permissions/list-permissions.mjs +1 -1
- package/actions/list-replies/list-replies.mjs +1 -1
- package/actions/list-shared-drives/list-shared-drives.mjs +1 -1
- package/actions/list-theme-id-options/list-theme-id-options.mjs +1 -1
- package/actions/move-file/move-file.mjs +1 -1
- package/actions/move-file-to-trash/move-file-to-trash.mjs +1 -1
- package/actions/remove-file-sharing-permission/remove-file-sharing-permission.mjs +1 -1
- package/actions/remove-sharing/remove-sharing.mjs +1 -1
- package/actions/reply-to-comment/reply-to-comment.mjs +1 -1
- package/actions/resolve-access-proposal/resolve-access-proposal.mjs +1 -1
- package/actions/resolve-comment/resolve-comment.mjs +1 -1
- package/actions/search-files/search-files.mjs +1 -1
- package/actions/search-shared-drives/search-shared-drives.mjs +1 -1
- package/actions/share-file/share-file.mjs +1 -1
- package/actions/trash-file/trash-file.mjs +1 -1
- package/actions/update-comment/update-comment.mjs +1 -1
- package/actions/update-file/update-file.mjs +1 -1
- package/actions/update-reply/update-reply.mjs +1 -1
- package/actions/update-shared-drive/update-shared-drive.mjs +1 -1
- package/actions/upload-file/upload-file.mjs +1 -1
- package/common/constants.mjs +15 -0
- package/common/utils.mjs +48 -0
- package/package.json +1 -1
- package/sources/changes-to-files-in-drive/changes-to-files-in-drive.mjs +1 -1
- package/sources/changes-to-specific-files/changes-to-specific-files.mjs +1 -1
- package/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs +1 -1
- package/sources/new-access-proposal/new-access-proposal.mjs +1 -1
- package/sources/new-files-instant/new-files-instant.mjs +1 -1
- package/sources/new-files-instant-polling/new-files-instant-polling.mjs +1 -1
- package/sources/new-files-shared-drive/new-files-shared-drive.mjs +1 -1
- package/sources/new-or-modified-comments/new-or-modified-comments.mjs +1 -1
- package/sources/new-or-modified-comments-polling/new-or-modified-comments-polling.mjs +1 -1
- package/sources/new-or-modified-files/new-or-modified-files.mjs +1 -1
- package/sources/new-or-modified-files-polling/new-or-modified-files-polling.mjs +1 -1
- package/sources/new-or-modified-folders/new-or-modified-folders.mjs +1 -1
- package/sources/new-or-modified-folders-polling/new-or-modified-folders-polling.mjs +1 -1
- package/sources/new-shared-drive/new-shared-drive.mjs +1 -1
- package/sources/new-spreadsheet/new-spreadsheet.mjs +1 -1
- package/sources/new-spreadsheet-polling/new-spreadsheet-polling.mjs +1 -1
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import googleDrive from "../../google_drive.app.mjs";
|
|
2
|
+
import { parseRfc3339 } from "../../common/utils.mjs";
|
|
3
|
+
import {
|
|
4
|
+
COMMENTS_MAX_PAGE_SIZE, DEFAULT_COMMENT_LIMIT, MAX_COMMENT_LIMIT,
|
|
5
|
+
} from "../../common/constants.mjs";
|
|
2
6
|
|
|
3
7
|
export default {
|
|
4
8
|
key: "google_drive-list-comments",
|
|
5
9
|
name: "List Comments",
|
|
6
|
-
description: "List
|
|
7
|
-
version: "0.0
|
|
10
|
+
description: "List the comments on a file, including each comment's author, plain text and HTML content, the file text it is anchored to, whether it is resolved, and its full reply thread. Use **Find File** first to resolve a file's name to its ID. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/comments/list)",
|
|
11
|
+
version: "0.1.0",
|
|
8
12
|
annotations: {
|
|
9
13
|
destructiveHint: false,
|
|
10
14
|
openWorldHint: true,
|
|
@@ -18,7 +22,6 @@ export default {
|
|
|
18
22
|
googleDrive,
|
|
19
23
|
"watchedDrive",
|
|
20
24
|
],
|
|
21
|
-
optional: false,
|
|
22
25
|
},
|
|
23
26
|
fileId: {
|
|
24
27
|
propDefinition: [
|
|
@@ -28,16 +31,62 @@ export default {
|
|
|
28
31
|
drive: c.drive,
|
|
29
32
|
}),
|
|
30
33
|
],
|
|
31
|
-
description: "The file to list comments for.",
|
|
34
|
+
description: "The Google Drive file ID to list comments for, for example `1AbCDefGhIJkLmNoPqRsTuVwXyZ`. Use **List Files** to resolve a document's name to its ID or use **Find File** to look up a file ID by name.",
|
|
35
|
+
},
|
|
36
|
+
includeDeleted: {
|
|
37
|
+
type: "boolean",
|
|
38
|
+
label: "Include Deleted",
|
|
39
|
+
description: "Whether to include deleted comments. Deleted comments are returned without their original content. Defaults to `false`.",
|
|
40
|
+
optional: true,
|
|
41
|
+
default: false,
|
|
42
|
+
},
|
|
43
|
+
startModifiedTime: {
|
|
44
|
+
type: "string",
|
|
45
|
+
label: "Start Modified Time",
|
|
46
|
+
description: "Only return comments modified at or after this time, as an RFC 3339 timestamp (e.g. `2026-01-31T00:00:00Z`). A comment's modified time also changes when any of its replies changes, so this returns recently-active threads. Leave blank to return all comments.",
|
|
47
|
+
optional: true,
|
|
48
|
+
},
|
|
49
|
+
limit: {
|
|
50
|
+
type: "integer",
|
|
51
|
+
label: "Limit",
|
|
52
|
+
description: `Maximum number of comments to return (min 1, max ${MAX_COMMENT_LIMIT}). Defaults to ${DEFAULT_COMMENT_LIMIT}.`,
|
|
53
|
+
optional: true,
|
|
54
|
+
default: DEFAULT_COMMENT_LIMIT,
|
|
55
|
+
min: 1,
|
|
56
|
+
max: MAX_COMMENT_LIMIT,
|
|
32
57
|
},
|
|
33
58
|
},
|
|
34
59
|
async run({ $ }) {
|
|
35
|
-
const
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
const args = {
|
|
61
|
+
includeDeleted: this.includeDeleted,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (this.startModifiedTime) {
|
|
65
|
+
args.startModifiedTime = parseRfc3339(this.startModifiedTime, "Start Modified Time");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const limit = this.limit || DEFAULT_COMMENT_LIMIT;
|
|
69
|
+
const comments = [];
|
|
70
|
+
let pageToken;
|
|
71
|
+
|
|
72
|
+
do {
|
|
73
|
+
const { data } = await this.googleDrive.listSyncComments(
|
|
74
|
+
// `comments.list` takes no `driveId` - a comment is addressed by file ID
|
|
75
|
+
// alone - so the app method's first argument is intentionally unset. The
|
|
76
|
+
// `drive` prop only scopes the **File** dropdown.
|
|
77
|
+
undefined,
|
|
78
|
+
this.fileId,
|
|
79
|
+
{
|
|
80
|
+
...args,
|
|
81
|
+
pageSize: Math.min(COMMENTS_MAX_PAGE_SIZE, limit - comments.length),
|
|
82
|
+
pageToken,
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
comments.push(...(data.comments || []));
|
|
86
|
+
pageToken = data.nextPageToken;
|
|
87
|
+
} while (pageToken && comments.length < limit);
|
|
39
88
|
|
|
40
|
-
$.export("$summary", `Successfully found ${
|
|
41
|
-
return
|
|
89
|
+
$.export("$summary", `Successfully found ${comments.length} comment(s) for file ${this.fileId}`);
|
|
90
|
+
return comments;
|
|
42
91
|
},
|
|
43
92
|
};
|
|
@@ -8,8 +8,8 @@ import { PAGINATION_TOKEN_FIELD } from "../../common/constants.mjs";
|
|
|
8
8
|
export default {
|
|
9
9
|
key: "google_drive-list-files",
|
|
10
10
|
name: "List Files",
|
|
11
|
-
description: "List files from a specific folder. [See the documentation](https://developers.google.com/drive/api/v3/reference/files/list) for more information",
|
|
12
|
-
version: "0.
|
|
11
|
+
description: "List files from a specific folder. Set `Max Results` to cap how many files are returned per run, then pass the returned `nextPageToken` back in as `Page Token` on the next run to page through a large folder in fixed-size batches. [See the documentation](https://developers.google.com/drive/api/v3/reference/files/list) for more information",
|
|
12
|
+
version: "1.0.1",
|
|
13
13
|
annotations: {
|
|
14
14
|
destructiveHint: false,
|
|
15
15
|
openWorldHint: true,
|
|
@@ -55,7 +55,17 @@ export default {
|
|
|
55
55
|
description: "Filter by file name that contains a specific text",
|
|
56
56
|
type: "string",
|
|
57
57
|
optional: true,
|
|
58
|
-
|
|
58
|
+
},
|
|
59
|
+
filterType: {
|
|
60
|
+
type: "string",
|
|
61
|
+
label: "Filter Type",
|
|
62
|
+
description: "Whether to return files with names containing the Filter Text or files with names that match the Filter Text exactly. Defaults to \"CONTAINS\". Not relevant unless `Filter Text` is entered.",
|
|
63
|
+
options: [
|
|
64
|
+
"CONTAINS",
|
|
65
|
+
"EXACT MATCH",
|
|
66
|
+
],
|
|
67
|
+
default: "CONTAINS",
|
|
68
|
+
optional: true,
|
|
59
69
|
},
|
|
60
70
|
trashed: {
|
|
61
71
|
label: "Trashed",
|
|
@@ -63,22 +73,19 @@ export default {
|
|
|
63
73
|
description: "If `true`, list **only** trashed files. If `false`, list **only** non-trashed files. Keep it empty to include both.",
|
|
64
74
|
optional: true,
|
|
65
75
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return props;
|
|
76
|
+
maxResults: {
|
|
77
|
+
label: "Max Results",
|
|
78
|
+
type: "integer",
|
|
79
|
+
description: "The maximum number of files to return per run. Leave empty to return every file in the folder. Combine with `Page Token` to page through a large folder in fixed-size batches across multiple runs.",
|
|
80
|
+
optional: true,
|
|
81
|
+
min: 1,
|
|
82
|
+
},
|
|
83
|
+
pageToken: {
|
|
84
|
+
label: "Page Token",
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "A cursor for resuming a previous run. Pass the `nextPageToken` returned by an earlier run to continue listing from where it stopped instead of starting over. Leave empty to start from the beginning of the folder.",
|
|
87
|
+
optional: true,
|
|
88
|
+
},
|
|
82
89
|
},
|
|
83
90
|
async run({ $ }) {
|
|
84
91
|
if (this.limitToMyDrive && this.drive && !isMyDrive(this.drive)) {
|
|
@@ -112,16 +119,53 @@ export default {
|
|
|
112
119
|
}
|
|
113
120
|
opts.fields = fieldsValue;
|
|
114
121
|
}
|
|
122
|
+
|
|
123
|
+
const maxResults = this.maxResults === undefined
|
|
124
|
+
? undefined
|
|
125
|
+
: Number(this.maxResults);
|
|
126
|
+
if (maxResults !== undefined && (!Number.isInteger(maxResults) || maxResults < 1)) {
|
|
127
|
+
throw new ConfigurationError("`Max Results` must be a positive integer.");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const startToken = this.pageToken;
|
|
115
131
|
const allFiles = [];
|
|
116
|
-
let pageToken;
|
|
132
|
+
let pageToken = startToken;
|
|
117
133
|
do {
|
|
134
|
+
const pageOpts = {
|
|
135
|
+
...opts,
|
|
136
|
+
};
|
|
137
|
+
if (maxResults) {
|
|
138
|
+
// Request exactly as many as we still need (Drive caps pageSize at 1000).
|
|
139
|
+
// Aligning pageSize to the remaining count means the returned
|
|
140
|
+
// nextPageToken points right after the last file we keep, so no files
|
|
141
|
+
// are skipped when resuming — we never over-fetch and discard.
|
|
142
|
+
pageOpts.pageSize = Math.min(maxResults - allFiles.length, 1000);
|
|
143
|
+
}
|
|
118
144
|
const {
|
|
119
|
-
files, nextPageToken,
|
|
120
|
-
}
|
|
145
|
+
files = [], nextPageToken,
|
|
146
|
+
} = await this.googleDrive.listFilesInPage(pageToken, pageOpts);
|
|
121
147
|
allFiles.push(...files);
|
|
122
148
|
pageToken = nextPageToken;
|
|
123
|
-
} while (pageToken);
|
|
124
|
-
|
|
125
|
-
|
|
149
|
+
} while (pageToken && (!maxResults || allFiles.length < maxResults));
|
|
150
|
+
|
|
151
|
+
const isComplete = !pageToken;
|
|
152
|
+
const resumed = Boolean(startToken);
|
|
153
|
+
let summary = `${resumed
|
|
154
|
+
? "Resumed and returned"
|
|
155
|
+
: "Successfully found"} ${allFiles.length} file(s).`;
|
|
156
|
+
// Only surface batch state when the caller is actually paging.
|
|
157
|
+
if (maxResults || startToken || !isComplete) {
|
|
158
|
+
summary += isComplete
|
|
159
|
+
? " Reached the end of the folder."
|
|
160
|
+
: " More results remain — pass `nextPageToken` as `Page Token` on the next run to continue.";
|
|
161
|
+
}
|
|
162
|
+
$.export("$summary", summary);
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
files: allFiles,
|
|
166
|
+
count: allFiles.length,
|
|
167
|
+
nextPageToken: pageToken ?? null,
|
|
168
|
+
isComplete,
|
|
169
|
+
};
|
|
126
170
|
},
|
|
127
171
|
};
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-list-mime-type-options",
|
|
5
5
|
name: "List Mime Type Options",
|
|
6
6
|
description: "Retrieves available options for the Mime Type field.",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.4",
|
|
8
8
|
type: "action",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: false,
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " Use this tool when the user asks 'who has access to this file?' or needs to audit sharing."
|
|
11
11
|
+ " Pass permission IDs from this response to **Remove Sharing** to revoke access."
|
|
12
12
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/reference/permissions/list)",
|
|
13
|
-
version: "0.0.
|
|
13
|
+
version: "0.0.3",
|
|
14
14
|
type: "action",
|
|
15
15
|
annotations: {
|
|
16
16
|
destructiveHint: false,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-list-replies",
|
|
5
5
|
name: "List Replies",
|
|
6
6
|
description: "List replies to a specific comment. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/replies/list) for more information",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " Pass a drive ID to **Search Files** `driveId` parameter to search within a specific shared drive."
|
|
11
11
|
+ " Optionally filter by name using the `query` parameter (e.g., `name contains 'Engineering'`)."
|
|
12
12
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/reference/drives/list)",
|
|
13
|
-
version: "0.0.
|
|
13
|
+
version: "0.0.3",
|
|
14
14
|
type: "action",
|
|
15
15
|
annotations: {
|
|
16
16
|
destructiveHint: false,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-move-file",
|
|
5
5
|
name: "Move File",
|
|
6
6
|
description: "Move a file from one folder to another. [See the documentation](https://developers.google.com/drive/api/v3/reference/files/update) for more information",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.24",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: true,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "google_drive-move-file-to-trash",
|
|
6
6
|
name: "Move File to Trash",
|
|
7
7
|
description: "Move a file or folder to trash. [See the documentation](https://developers.google.com/drive/api/v3/reference/files/update) for more information",
|
|
8
|
-
version: "0.1.
|
|
8
|
+
version: "0.1.24",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: true,
|
|
11
11
|
openWorldHint: true,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
name: "Remove File Sharing Permission",
|
|
7
7
|
description:
|
|
8
8
|
"Remove a [sharing permission](https://support.google.com/drive/answer/7166529) from the sharing preferences of a file or folder. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/permissions/delete)",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.9",
|
|
10
10
|
annotations: {
|
|
11
11
|
destructiveHint: true,
|
|
12
12
|
openWorldHint: true,
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " The owner permission cannot be removed."
|
|
11
11
|
+ " Use **Search Files** to find the file ID by name if needed."
|
|
12
12
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/reference/permissions/delete)",
|
|
13
|
-
version: "0.0.
|
|
13
|
+
version: "0.0.3",
|
|
14
14
|
type: "action",
|
|
15
15
|
annotations: {
|
|
16
16
|
destructiveHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-reply-to-comment",
|
|
5
5
|
name: "Reply to Comment",
|
|
6
6
|
description: "Add a reply to an existing comment. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/replies/create)",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.13",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "google_drive-resolve-access-proposal",
|
|
6
6
|
name: "Resolve Access Proposals",
|
|
7
7
|
description: "Accept or deny a request for access to a file or folder in Google Drive. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/accessproposals/resolve)",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.17",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: false,
|
|
11
11
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-resolve-comment",
|
|
5
5
|
name: "Resolve Comment",
|
|
6
6
|
description: "Mark a comment as resolved. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/comments/update)",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.13",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: true,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -22,7 +22,7 @@ export default {
|
|
|
22
22
|
+ "\n\nWhen the user says 'my files', use **Get User Details** first to get the owner email."
|
|
23
23
|
+ " To scope to a shared drive, pass the `driveId` from **List Shared Drives**."
|
|
24
24
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/search-files)",
|
|
25
|
-
version: "0.0.
|
|
25
|
+
version: "0.0.3",
|
|
26
26
|
type: "action",
|
|
27
27
|
annotations: {
|
|
28
28
|
destructiveHint: false,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-search-shared-drives",
|
|
5
5
|
name: "Search for Shared Drives",
|
|
6
6
|
description: "Search for shared drives with query options. [See the documentation](https://developers.google.com/drive/api/v3/search-shareddrives) for more information",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.25",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
+ "\n\n**Roles:** `reader` (view only), `commenter` (can comment), `writer` (can edit)."
|
|
16
16
|
+ " Use **List Permissions** to see existing sharing on a file."
|
|
17
17
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/reference/permissions/create)",
|
|
18
|
-
version: "0.0.
|
|
18
|
+
version: "0.0.3",
|
|
19
19
|
type: "action",
|
|
20
20
|
annotations: {
|
|
21
21
|
destructiveHint: false,
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " Use this instead of permanent deletion as the safer default."
|
|
11
11
|
+ " To find trashed files, use **Search Files** with `trashed = true`."
|
|
12
12
|
+ " [See the documentation](https://developers.google.com/drive/api/v3/reference/files/update)",
|
|
13
|
-
version: "0.0.
|
|
13
|
+
version: "0.0.3",
|
|
14
14
|
type: "action",
|
|
15
15
|
annotations: {
|
|
16
16
|
destructiveHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-update-comment",
|
|
5
5
|
name: "Update Comment",
|
|
6
6
|
description: "Update the content of a specific comment. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/comments/update) for more information",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_drive-update-file",
|
|
7
7
|
name: "Update File",
|
|
8
8
|
description: "Update a file's metadata and/or content. [See the documentation](https://developers.google.com/drive/api/v3/reference/files/update) for more information",
|
|
9
|
-
version: "2.0.
|
|
9
|
+
version: "2.0.16",
|
|
10
10
|
annotations: {
|
|
11
11
|
destructiveHint: true,
|
|
12
12
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-update-reply",
|
|
5
5
|
name: "Update Reply",
|
|
6
6
|
description: "Update a reply on a specific comment. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/replies/update) for more information",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_drive-update-shared-drive",
|
|
5
5
|
name: "Update Shared Drive",
|
|
6
6
|
description: "Update an existing shared drive. [See the documentation](https://developers.google.com/drive/api/v3/reference/drives/update) for more information",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.24",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: true,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
key: "google_drive-upload-file",
|
|
14
14
|
name: "Upload File",
|
|
15
15
|
description: "Upload a file to Google Drive. [See the documentation](https://developers.google.com/drive/api/v3/manage-uploads) for more information",
|
|
16
|
-
version: "2.0.
|
|
16
|
+
version: "2.0.17",
|
|
17
17
|
annotations: {
|
|
18
18
|
destructiveHint: false,
|
|
19
19
|
openWorldHint: true,
|
package/common/constants.mjs
CHANGED
|
@@ -234,6 +234,17 @@ const GOOGLE_DRIVE_UPLOAD_TYPE_OPTIONS = [
|
|
|
234
234
|
},
|
|
235
235
|
];
|
|
236
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Maximum `pageSize` accepted by `comments.list`; larger values are coerced down
|
|
239
|
+
* to this by the API.
|
|
240
|
+
* https://developers.google.com/workspace/drive/api/reference/rest/v3/comments/list
|
|
241
|
+
*/
|
|
242
|
+
const COMMENTS_MAX_PAGE_SIZE = 100;
|
|
243
|
+
|
|
244
|
+
const DEFAULT_COMMENT_LIMIT = 100;
|
|
245
|
+
|
|
246
|
+
const MAX_COMMENT_LIMIT = 500;
|
|
247
|
+
|
|
237
248
|
export {
|
|
238
249
|
GOOGLE_DRIVE_NOTIFICATION_SYNC,
|
|
239
250
|
GOOGLE_DRIVE_NOTIFICATION_ADD,
|
|
@@ -270,4 +281,8 @@ export {
|
|
|
270
281
|
GOOGLE_DRIVE_GRANTEE_DOMAIN,
|
|
271
282
|
GOOGLE_DRIVE_GRANTEE_ANYONE,
|
|
272
283
|
GOOGLE_DRIVE_GRANTEE_TYPES,
|
|
284
|
+
// Comments
|
|
285
|
+
COMMENTS_MAX_PAGE_SIZE,
|
|
286
|
+
DEFAULT_COMMENT_LIMIT,
|
|
287
|
+
MAX_COMMENT_LIMIT,
|
|
273
288
|
};
|
package/common/utils.mjs
CHANGED
|
@@ -338,6 +338,53 @@ async function stashFile(item, googleDrive, dir) {
|
|
|
338
338
|
};
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
/**
|
|
342
|
+
* RFC 3339 date (`2026-01-31`) or date-time (`2026-01-31T00:00:00Z`). A
|
|
343
|
+
* date-time must carry a `Z` or numeric offset, as RFC 3339 requires: without
|
|
344
|
+
* one, `Date.parse` silently reads it in the runner's local timezone.
|
|
345
|
+
*
|
|
346
|
+
* The time fields spell out their RFC 3339 ranges rather than using `\d{2}`,
|
|
347
|
+
* because `Date.parse` accepts the ISO 8601 end-of-day hour `24` and rolls it
|
|
348
|
+
* into the next day (`...T24:00:00Z` becomes the 1st of the next month).
|
|
349
|
+
*/
|
|
350
|
+
const RFC_3339_REGEX =
|
|
351
|
+
/^(\d{4})-(\d{2})-(\d{2})(?:[Tt]([01]\d|2[0-3]):([0-5]\d):([0-5]\d)(?:\.\d+)?(?:[Zz]|[+-]([01]\d|2[0-3]):[0-5]\d))?$/;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Validate an RFC 3339 timestamp and normalize it to a UTC ISO string.
|
|
355
|
+
*
|
|
356
|
+
* `Date.parse` alone is too permissive to use as the gate: it accepts
|
|
357
|
+
* locale-ambiguous input like `01/02/2026` and bare years like `2026`, and it
|
|
358
|
+
* rolls impossible dates over (`2026-02-31` becomes March 3) rather than
|
|
359
|
+
* rejecting them. Either would silently filter from the wrong instant.
|
|
360
|
+
*
|
|
361
|
+
* @param {String} value the user-supplied timestamp
|
|
362
|
+
* @param {String} label the prop label, used in the error message
|
|
363
|
+
* @returns {String} the timestamp normalized to a UTC ISO string
|
|
364
|
+
*/
|
|
365
|
+
function parseRfc3339(value, label) {
|
|
366
|
+
const match = RFC_3339_REGEX.exec(String(value).trim());
|
|
367
|
+
if (!match) {
|
|
368
|
+
throw new ConfigurationError(`Invalid ${label} "${value}". Use an RFC 3339 timestamp, e.g. "2026-01-31T00:00:00Z" or "2026-01-31".`);
|
|
369
|
+
}
|
|
370
|
+
const [
|
|
371
|
+
, year,
|
|
372
|
+
month,
|
|
373
|
+
day,
|
|
374
|
+
] = match.map(Number);
|
|
375
|
+
// The shape is right, but `2026-02-31` still parses, so confirm the calendar
|
|
376
|
+
// date round-trips unchanged before trusting it.
|
|
377
|
+
const utc = new Date(Date.UTC(year, month - 1, day));
|
|
378
|
+
const parsed = Date.parse(match[0]);
|
|
379
|
+
if (utc.getUTCFullYear() !== year
|
|
380
|
+
|| utc.getUTCMonth() !== month - 1
|
|
381
|
+
|| utc.getUTCDate() !== day
|
|
382
|
+
|| Number.isNaN(parsed)) {
|
|
383
|
+
throw new ConfigurationError(`Invalid ${label} "${value}". That is not a real date or time.`);
|
|
384
|
+
}
|
|
385
|
+
return new Date(parsed).toISOString();
|
|
386
|
+
}
|
|
387
|
+
|
|
341
388
|
export {
|
|
342
389
|
buildFilePaths,
|
|
343
390
|
byteToMB,
|
|
@@ -348,6 +395,7 @@ export {
|
|
|
348
395
|
MY_DRIVE_VALUE,
|
|
349
396
|
omitEmptyStringValues,
|
|
350
397
|
parseObjectEntries,
|
|
398
|
+
parseRfc3339,
|
|
351
399
|
stashFile,
|
|
352
400
|
streamToBuffer,
|
|
353
401
|
toSingleLineString,
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@ export default {
|
|
|
14
14
|
key: "google_drive-changes-to-files-in-drive",
|
|
15
15
|
name: "Changes to Files in Drive",
|
|
16
16
|
description: "Emit new event when a change is made to one of the specified files. [See the documentation](https://developers.google.com/drive/api/v3/reference/changes/watch)",
|
|
17
|
-
version: "0.0.
|
|
17
|
+
version: "0.0.13",
|
|
18
18
|
type: "source",
|
|
19
19
|
dedupe: "unique",
|
|
20
20
|
props: {
|
|
@@ -16,7 +16,7 @@ export default {
|
|
|
16
16
|
key: "google_drive-changes-to-specific-files",
|
|
17
17
|
name: "Changes to Specific Files",
|
|
18
18
|
description: "Watches for changes to specific files, emitting an event when a change is made to one of those files. To watch for changes to [shared drive](https://support.google.com/a/users/answer/9310351) files, use the **Changes to Specific Files (Shared Drive)** source instead.",
|
|
19
|
-
version: "0.3.
|
|
19
|
+
version: "0.3.11",
|
|
20
20
|
type: "source",
|
|
21
21
|
// Dedupe events based on the "x-goog-message-number" header for the target channel:
|
|
22
22
|
// https://developers.google.com/drive/api/v3/push#making-watch-requests
|
package/sources/changes-to-specific-files-shared-drive/changes-to-specific-files-shared-drive.mjs
CHANGED
|
@@ -29,7 +29,7 @@ export default {
|
|
|
29
29
|
key: "google_drive-changes-to-specific-files-shared-drive",
|
|
30
30
|
name: "Changes to Specific Files (Shared Drive)",
|
|
31
31
|
description: "Watches for changes to specific files in a shared drive, emitting an event when a change is made to one of those files",
|
|
32
|
-
version: "0.3.
|
|
32
|
+
version: "0.3.13",
|
|
33
33
|
type: "source",
|
|
34
34
|
// Dedupe events based on the "x-goog-message-number" header for the target channel:
|
|
35
35
|
// https://developers.google.com/drive/api/v3/push#making-watch-requests
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_drive-new-access-proposal",
|
|
7
7
|
name: "New Access Proposal",
|
|
8
8
|
description: "Emit new event when a new access proposal is requested in Google Drive",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.16",
|
|
10
10
|
type: "source",
|
|
11
11
|
dedupe: "unique",
|
|
12
12
|
props: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
key: "google_drive-new-files-instant",
|
|
12
12
|
name: "New Files (Instant)",
|
|
13
13
|
description: "Emit new event when a new file is added in your linked Google Drive",
|
|
14
|
-
version: "0.2.
|
|
14
|
+
version: "0.2.13",
|
|
15
15
|
type: "source",
|
|
16
16
|
dedupe: "unique",
|
|
17
17
|
props: {
|
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
key: "google_drive-new-files-instant-polling",
|
|
9
9
|
name: "New Files (Polling)",
|
|
10
10
|
description: "Emit new event when a new file is added in your linked Google Drive",
|
|
11
|
-
version: "0.0.
|
|
11
|
+
version: "0.0.11",
|
|
12
12
|
type: "source",
|
|
13
13
|
dedupe: "unique",
|
|
14
14
|
props: {
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
key: "google_drive-new-files-shared-drive",
|
|
8
8
|
name: "New Files (Shared Drive)",
|
|
9
9
|
description: "Emit new event when a new file is added in your shared Google Drive",
|
|
10
|
-
version: "0.1.
|
|
10
|
+
version: "0.1.13",
|
|
11
11
|
type: "source",
|
|
12
12
|
dedupe: "unique",
|
|
13
13
|
props: {
|
|
@@ -18,7 +18,7 @@ export default {
|
|
|
18
18
|
name: "New or Modified Comments (Instant)",
|
|
19
19
|
description:
|
|
20
20
|
"Emit new event when a comment is created or modified in the selected file",
|
|
21
|
-
version: "1.0.
|
|
21
|
+
version: "1.0.22",
|
|
22
22
|
type: "source",
|
|
23
23
|
// Dedupe events based on the "x-goog-message-number" header for the target channel:
|
|
24
24
|
// https://developers.google.com/drive/api/v3/push#making-watch-requests
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
key: "google_drive-new-or-modified-comments-polling",
|
|
8
8
|
name: "New or Modified Comments (Polling)",
|
|
9
9
|
description: "Emit new event when a comment is created or modified in the selected file",
|
|
10
|
-
version: "0.0.
|
|
10
|
+
version: "0.0.11",
|
|
11
11
|
type: "source",
|
|
12
12
|
dedupe: "unique",
|
|
13
13
|
props: {
|
|
@@ -26,7 +26,7 @@ export default {
|
|
|
26
26
|
key: "google_drive-new-or-modified-files",
|
|
27
27
|
name: "New or Modified Files (Instant)",
|
|
28
28
|
description: "Emit new event when a file in the selected Drive is created, modified or trashed.",
|
|
29
|
-
version: "0.4.
|
|
29
|
+
version: "0.4.13",
|
|
30
30
|
type: "source",
|
|
31
31
|
// Dedupe events based on the "x-goog-message-number" header for the target channel:
|
|
32
32
|
// https://developers.google.com/drive/api/v3/push#making-watch-requests
|