@pipedream/google_drive 1.6.3 → 1.7.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.
@@ -5,8 +5,8 @@ import googleDrive from "../../google_drive.app.mjs";
5
5
  export default {
6
6
  key: "google_drive-find-file",
7
7
  name: "Find File",
8
- description: "Search for a specific file by name. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
- version: "0.1.20",
8
+ description: "Search for a specific file by name. The `Search Name` field uses Google Drive's tokenized full-text matching — pass a distinctive word or short phrase rather than the full title when the name contains special characters like `&` or `'`. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
+ version: "0.1.21",
10
10
  annotations: {
11
11
  destructiveHint: false,
12
12
  openWorldHint: true,
@@ -6,8 +6,8 @@ import { GOOGLE_DRIVE_FOLDER_MIME_TYPE } from "../../common/constants.mjs";
6
6
  export default {
7
7
  key: "google_drive-find-folder",
8
8
  name: "Find Folder",
9
- description: "Search for a specific folder by name. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
10
- version: "0.1.20",
9
+ description: "Search for a specific folder by name. The `Search Name` field uses Google Drive's tokenized full-text matching — pass a distinctive word or short phrase rather than the full title when the name contains special characters like `&` or `'`. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
10
+ version: "0.1.21",
11
11
  annotations: {
12
12
  destructiveHint: false,
13
13
  openWorldHint: true,
@@ -39,7 +39,7 @@ export default {
39
39
  },
40
40
  },
41
41
  async run({ $ }) {
42
- const escapedSearchTerm = this.nameSearchTerm?.replace(/'/g, "\\'") || "";
42
+ const escapedSearchTerm = this.nameSearchTerm?.replace(/\\/g, "\\\\").replace(/'/g, "\\'") || "";
43
43
  let q = `mimeType = '${GOOGLE_DRIVE_FOLDER_MIME_TYPE}' and name contains '${escapedSearchTerm}'`.trim();
44
44
  if (!this.includeTrashed) {
45
45
  q += " and trashed=false";
@@ -5,8 +5,8 @@ import googleDrive from "../../google_drive.app.mjs";
5
5
  export default {
6
6
  key: "google_drive-find-forms",
7
7
  name: "Find Forms",
8
- description: "List Google Form documents or search for a Form by name. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
- version: "0.0.21",
8
+ description: "List Google Form documents or search for a Form by name. The `Search Name` field uses Google Drive's tokenized full-text matching — pass a distinctive word or short phrase rather than the full title when the name contains special characters like `&` or `'`. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
+ version: "0.0.22",
10
10
  annotations: {
11
11
  destructiveHint: false,
12
12
  openWorldHint: true,
@@ -5,8 +5,8 @@ import googleDrive from "../../google_drive.app.mjs";
5
5
  export default {
6
6
  key: "google_drive-find-spreadsheets",
7
7
  name: "Find Spreadsheets",
8
- description: "Search for a specific spreadsheet by name. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
- version: "0.1.20",
8
+ description: "Search for a specific spreadsheet by name. The `Search Name` field uses Google Drive's tokenized full-text matching — pass a distinctive word or short phrase rather than the full title when the name contains special characters like `&` or `'`. [See the documentation](https://developers.google.com/drive/api/v3/search-files) for more information",
9
+ version: "0.1.21",
10
10
  annotations: {
11
11
  destructiveHint: false,
12
12
  openWorldHint: true,
@@ -0,0 +1,121 @@
1
+ import googleDrive from "../../google_drive.app.mjs";
2
+
3
+ export default {
4
+ key: "google_drive-is-folder-ancestor",
5
+ name: "Is Folder Ancestor",
6
+ description: "Check if a specific folder is anywhere in the parent hierarchy of a file or folder. [See the documentation](https://developers.google.com/workspace/drive/api/reference/rest/v3/files/get)",
7
+ version: "0.0.1",
8
+ type: "action",
9
+ annotations: {
10
+ destructiveHint: false,
11
+ openWorldHint: true,
12
+ readOnlyHint: true,
13
+ },
14
+ props: {
15
+ googleDrive,
16
+ fileId: {
17
+ propDefinition: [
18
+ googleDrive,
19
+ "fileOrFolderId",
20
+ ],
21
+ description: "The ID of the file or folder to check",
22
+ },
23
+ ancestorFolderId: {
24
+ propDefinition: [
25
+ googleDrive,
26
+ "folderId",
27
+ ],
28
+ label: "Ancestor Folder ID",
29
+ description: "The folder ID to check for in the parent hierarchy",
30
+ },
31
+ },
32
+ async run({ $ }) {
33
+ const {
34
+ fileId, ancestorFolderId,
35
+ } = this;
36
+
37
+ // Get the initial file's parents to start traversal from parent (not the file itself)
38
+ let file;
39
+ try {
40
+ file = await this.googleDrive.getFile(fileId, {
41
+ fields: "id,name,parents",
42
+ });
43
+ } catch (err) {
44
+ throw new Error(`Failed to retrieve file "${fileId}": ${err.message}`);
45
+ }
46
+
47
+ const initialParents = file.parents || [];
48
+ if (initialParents.length === 0) {
49
+ $.export("$summary", `Folder "${ancestorFolderId}" is NOT an ancestor of file "${fileId}"`);
50
+ return {
51
+ isAncestor: false,
52
+ fileId,
53
+ ancestorFolderId,
54
+ reason: "not_in_hierarchy",
55
+ };
56
+ }
57
+
58
+ // BFS traversal to check all parent paths (files can have multiple parents in Drive)
59
+ const queue = [
60
+ ...initialParents,
61
+ ];
62
+ const visitedIds = new Set([
63
+ fileId,
64
+ ]);
65
+
66
+ while (queue.length > 0) {
67
+ const currentId = queue.shift();
68
+
69
+ // Skip if already visited (prevents cycles)
70
+ if (visitedIds.has(currentId)) {
71
+ continue;
72
+ }
73
+ visitedIds.add(currentId);
74
+
75
+ // Check if current parent matches the ancestor folder ID
76
+ if (currentId === ancestorFolderId) {
77
+ let ancestorFile;
78
+ try {
79
+ ancestorFile = await this.googleDrive.getFile(currentId, {
80
+ fields: "id,name",
81
+ });
82
+ } catch (err) {
83
+ throw new Error(`Failed to retrieve ancestor folder "${currentId}": ${err.message}`);
84
+ }
85
+ $.export("$summary", `Folder "${ancestorFolderId}" is an ancestor of file "${fileId}"`);
86
+ return {
87
+ isAncestor: true,
88
+ fileId,
89
+ ancestorFolderId,
90
+ ancestorName: ancestorFile.name,
91
+ };
92
+ }
93
+
94
+ // Get file metadata including parents to continue traversal
95
+ let parentFile;
96
+ try {
97
+ parentFile = await this.googleDrive.getFile(currentId, {
98
+ fields: "id,name,parents",
99
+ });
100
+ } catch (err) {
101
+ throw new Error(`Failed to retrieve file "${currentId}": ${err.message}`);
102
+ }
103
+
104
+ // Enqueue all parents for traversal
105
+ const parents = parentFile.parents || [];
106
+ for (const parentId of parents) {
107
+ if (!visitedIds.has(parentId)) {
108
+ queue.push(parentId);
109
+ }
110
+ }
111
+ }
112
+
113
+ $.export("$summary", `Folder "${ancestorFolderId}" is NOT an ancestor of file "${fileId}"`);
114
+ return {
115
+ isAncestor: false,
116
+ fileId,
117
+ ancestorFolderId,
118
+ reason: "not_in_hierarchy",
119
+ };
120
+ },
121
+ };
@@ -19,7 +19,8 @@ export default {
19
19
  : `${q} and ${searchQuery}`;
20
20
  } else {
21
21
  if (nameSearchTerm) {
22
- const nameQuery = `name contains '${nameSearchTerm}'`;
22
+ const escapedTerm = nameSearchTerm.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
23
+ const nameQuery = `name contains '${escapedTerm}'`;
23
24
  q = q
24
25
  ? `${q} and ${nameQuery}`
25
26
  : nameQuery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/google_drive",
3
- "version": "1.6.3",
3
+ "version": "1.7.1",
4
4
  "description": "Pipedream Google_drive Components",
5
5
  "main": "google_drive.app.mjs",
6
6
  "keywords": [