@divyacon/piece-google-cloud-storage 0.0.0-stage → 0.1.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.
Files changed (93) hide show
  1. package/LICENSE.MIT-AP +24 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +50 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/actions/clone-object.d.ts +9 -0
  7. package/dist/lib/actions/clone-object.d.ts.map +1 -0
  8. package/dist/lib/actions/clone-object.js +77 -0
  9. package/dist/lib/actions/clone-object.js.map +1 -0
  10. package/dist/lib/actions/create-bucket-acl.d.ts +7 -0
  11. package/dist/lib/actions/create-bucket-acl.d.ts.map +1 -0
  12. package/dist/lib/actions/create-bucket-acl.js +60 -0
  13. package/dist/lib/actions/create-bucket-acl.js.map +1 -0
  14. package/dist/lib/actions/create-bucket-default-object-acl.d.ts +7 -0
  15. package/dist/lib/actions/create-bucket-default-object-acl.d.ts.map +1 -0
  16. package/dist/lib/actions/create-bucket-default-object-acl.js +60 -0
  17. package/dist/lib/actions/create-bucket-default-object-acl.js.map +1 -0
  18. package/dist/lib/actions/create-bucket.d.ts +10 -0
  19. package/dist/lib/actions/create-bucket.d.ts.map +1 -0
  20. package/dist/lib/actions/create-bucket.js +80 -0
  21. package/dist/lib/actions/create-bucket.js.map +1 -0
  22. package/dist/lib/actions/create-object-acl.d.ts +9 -0
  23. package/dist/lib/actions/create-object-acl.d.ts.map +1 -0
  24. package/dist/lib/actions/create-object-acl.js +72 -0
  25. package/dist/lib/actions/create-object-acl.js.map +1 -0
  26. package/dist/lib/actions/delete-bucket-acl.d.ts +6 -0
  27. package/dist/lib/actions/delete-bucket-acl.d.ts.map +1 -0
  28. package/dist/lib/actions/delete-bucket-acl.js +56 -0
  29. package/dist/lib/actions/delete-bucket-acl.js.map +1 -0
  30. package/dist/lib/actions/delete-bucket-default-object-acl.d.ts +6 -0
  31. package/dist/lib/actions/delete-bucket-default-object-acl.d.ts.map +1 -0
  32. package/dist/lib/actions/delete-bucket-default-object-acl.js +56 -0
  33. package/dist/lib/actions/delete-bucket-default-object-acl.js.map +1 -0
  34. package/dist/lib/actions/delete-empty-bucket.d.ts +5 -0
  35. package/dist/lib/actions/delete-empty-bucket.d.ts.map +1 -0
  36. package/dist/lib/actions/delete-empty-bucket.js +50 -0
  37. package/dist/lib/actions/delete-empty-bucket.js.map +1 -0
  38. package/dist/lib/actions/delete-object-acl.d.ts +8 -0
  39. package/dist/lib/actions/delete-object-acl.d.ts.map +1 -0
  40. package/dist/lib/actions/delete-object-acl.js +71 -0
  41. package/dist/lib/actions/delete-object-acl.js.map +1 -0
  42. package/dist/lib/actions/delete-object.d.ts +7 -0
  43. package/dist/lib/actions/delete-object.d.ts.map +1 -0
  44. package/dist/lib/actions/delete-object.js +66 -0
  45. package/dist/lib/actions/delete-object.js.map +1 -0
  46. package/dist/lib/actions/search-buckets.d.ts +9 -0
  47. package/dist/lib/actions/search-buckets.d.ts.map +1 -0
  48. package/dist/lib/actions/search-buckets.js +96 -0
  49. package/dist/lib/actions/search-buckets.js.map +1 -0
  50. package/dist/lib/actions/search-objects.d.ts +12 -0
  51. package/dist/lib/actions/search-objects.d.ts.map +1 -0
  52. package/dist/lib/actions/search-objects.js +105 -0
  53. package/dist/lib/actions/search-objects.js.map +1 -0
  54. package/dist/lib/common/auth.d.ts +2 -0
  55. package/dist/lib/common/auth.d.ts.map +1 -0
  56. package/dist/lib/common/auth.js +20 -0
  57. package/dist/lib/common/auth.js.map +1 -0
  58. package/dist/lib/common/client.d.ts +9 -0
  59. package/dist/lib/common/client.d.ts.map +1 -0
  60. package/dist/lib/common/client.js +48 -0
  61. package/dist/lib/common/client.js.map +1 -0
  62. package/dist/lib/common/props.d.ts +12 -0
  63. package/dist/lib/common/props.d.ts.map +1 -0
  64. package/dist/lib/common/props.js +231 -0
  65. package/dist/lib/common/props.js.map +1 -0
  66. package/dist/lib/triggers/new-object-created.d.ts +19 -0
  67. package/dist/lib/triggers/new-object-created.d.ts.map +1 -0
  68. package/dist/lib/triggers/new-object-created.js +127 -0
  69. package/dist/lib/triggers/new-object-created.js.map +1 -0
  70. package/dist/lib/triggers/object-updated.d.ts +19 -0
  71. package/dist/lib/triggers/object-updated.d.ts.map +1 -0
  72. package/dist/lib/triggers/object-updated.js +127 -0
  73. package/dist/lib/triggers/object-updated.js.map +1 -0
  74. package/package.json +44 -4
  75. package/src/index.ts +46 -0
  76. package/src/lib/actions/clone-object.ts +75 -0
  77. package/src/lib/actions/create-bucket-acl.ts +58 -0
  78. package/src/lib/actions/create-bucket-default-object-acl.ts +58 -0
  79. package/src/lib/actions/create-bucket.ts +75 -0
  80. package/src/lib/actions/create-object-acl.ts +81 -0
  81. package/src/lib/actions/delete-bucket-acl.ts +52 -0
  82. package/src/lib/actions/delete-bucket-default-object-acl.ts +52 -0
  83. package/src/lib/actions/delete-empty-bucket.ts +42 -0
  84. package/src/lib/actions/delete-object-acl.ts +64 -0
  85. package/src/lib/actions/delete-object.ts +59 -0
  86. package/src/lib/actions/search-buckets.ts +92 -0
  87. package/src/lib/actions/search-objects.ts +101 -0
  88. package/src/lib/common/auth.ts +15 -0
  89. package/src/lib/common/client.ts +63 -0
  90. package/src/lib/common/props.ts +249 -0
  91. package/src/lib/triggers/new-object-created.ts +174 -0
  92. package/src/lib/triggers/object-updated.ts +174 -0
  93. package/README.md +0 -3
@@ -0,0 +1,52 @@
1
+ import { createAction, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { bucketDropdown, aclEntityProperty, projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const deleteBucketDefaultObjectAcl = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'delete_bucket_default_object_acl',
10
+ displayName: 'Delete Bucket Default Object ACL',
11
+ description: 'Remove default ACL settings from a bucket. Perfect for reverting to default behavior.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Removes an entity\'s entry from a bucket\'s default object ACL, so it no longer applies to future uploads. Use to revert a default-permission rule for new objects. Not idempotent: the first call removes the entry and a repeat fails because it no longer exists, and it does not affect already-uploaded objects. Only works on buckets using fine-grained ACLs, not uniform bucket-level access; requires bucket and entity.', idempotent: false },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ bucket: bucketDropdown,
17
+ entity: aclEntityProperty,
18
+ },
19
+ async run(context) {
20
+ const { bucket, entity } = context.propsValue;
21
+ const auth = context.auth as OAuth2PropertyValue;
22
+
23
+ try {
24
+ await gcsCommon.makeRequest(
25
+ HttpMethod.DELETE,
26
+ `/b/${bucket}/defaultObjectAcl/${encodeURIComponent(entity)}`,
27
+ auth.access_token
28
+ );
29
+
30
+ return {
31
+ success: true,
32
+ bucket,
33
+ entity,
34
+ message: `Default object ACL entry for entity "${entity}" removed successfully from bucket "${bucket}"`,
35
+ };
36
+ } catch (error: any) {
37
+ if (error.response?.status === 400) {
38
+ throw new Error('Bad request. This bucket may have uniform bucket-level access enabled, which doesn\'t support default object ACLs. Use IAM policies instead.');
39
+ }
40
+ if (error.response?.status === 403) {
41
+ throw new Error('Access denied. You need storage.buckets.update permission to modify bucket default object ACLs.');
42
+ }
43
+ if (error.response?.status === 404) {
44
+ if (error.response?.data?.error?.message?.includes('ACL')) {
45
+ throw new Error(`Default object ACL entry for entity "${entity}" not found on bucket "${bucket}".`);
46
+ }
47
+ throw new Error(`Bucket "${bucket}" not found.`);
48
+ }
49
+ throw new Error(`Failed to delete bucket default object ACL: ${error.message || 'Unknown error'}`);
50
+ }
51
+ },
52
+ });
@@ -0,0 +1,42 @@
1
+ import { createAction, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { bucketDropdown, projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const deleteEmptyBucket = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'delete_empty_bucket',
10
+ displayName: 'Delete Empty Bucket',
11
+ description: 'Clean up unused buckets by deleting them if they contain no live objects.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Permanently deletes a Cloud Storage bucket. Use to clean up an unused bucket. The bucket must be empty (no live or noncurrent objects) or the call fails, so delete its objects first. Not idempotent: the first call removes the bucket and a repeat fails because it no longer exists.', idempotent: false },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ bucket: bucketDropdown,
17
+ },
18
+ async run(context) {
19
+ const { bucket } = context.propsValue;
20
+ const auth = context.auth as OAuth2PropertyValue;
21
+
22
+ try {
23
+ await gcsCommon.makeRequest(HttpMethod.DELETE, `/b/${bucket}`, auth.access_token);
24
+
25
+ return {
26
+ success: true,
27
+ message: `Bucket "${bucket}" deleted successfully`,
28
+ };
29
+ } catch (error: any) {
30
+ if (error.response?.status === 409) {
31
+ throw new Error(`Bucket "${bucket}" contains live or noncurrent objects and cannot be deleted. Remove all objects first.`);
32
+ }
33
+ if (error.response?.status === 403) {
34
+ throw new Error('Access denied. You need storage.buckets.delete permission to delete this bucket.');
35
+ }
36
+ if (error.response?.status === 404) {
37
+ throw new Error(`Bucket "${bucket}" not found. It may have already been deleted.`);
38
+ }
39
+ throw new Error(`Failed to delete bucket: ${error.message || 'Unknown error'}`);
40
+ }
41
+ },
42
+ });
@@ -0,0 +1,64 @@
1
+ import { createAction, Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { bucketDropdown, objectDropdown, aclEntityProperty, projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const deleteObjectAcl = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'delete_object_acl',
10
+ displayName: 'Delete Object ACL',
11
+ description: 'Remove an ACL entry from an object. Perfect for revoking access for a user.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Removes an entity\'s entry from a single object\'s access-control list, optionally targeting a specific generation. Use to revoke a user or group\'s access to one file. Not idempotent: the first call removes the entry and a repeat fails because it no longer exists. Only works on buckets using fine-grained ACLs, not uniform bucket-level access; requires bucket, object, and entity.', idempotent: false },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ bucket: bucketDropdown,
17
+ object: objectDropdown('bucket'),
18
+ entity: aclEntityProperty,
19
+ generation: Property.Number({
20
+ displayName: 'Generation',
21
+ description: 'Optional generation number for versioned objects',
22
+ required: false,
23
+ }),
24
+ },
25
+ async run(context) {
26
+ const { bucket, object, entity, generation } = context.propsValue;
27
+ const auth = context.auth as OAuth2PropertyValue;
28
+
29
+ let path = `/b/${bucket}/o/${encodeURIComponent(object as string)}/acl/${encodeURIComponent(entity as string)}`;
30
+ if (generation) {
31
+ path += `?generation=${generation}`;
32
+ }
33
+
34
+ try {
35
+ await gcsCommon.makeRequest(HttpMethod.DELETE, path, auth.access_token);
36
+
37
+ return {
38
+ success: true,
39
+ bucket,
40
+ object,
41
+ entity,
42
+ generation: generation || 'latest',
43
+ message: `ACL entry for entity "${entity}" removed successfully from object "${object}"`,
44
+ };
45
+ } catch (error: any) {
46
+ if (error.response?.status === 400) {
47
+ if (entity.includes('user-') && entity.includes('@')) {
48
+ throw new Error('Cannot remove OWNER access from the object owner. The only way to remove owner access is to delete or replace the object.');
49
+ }
50
+ throw new Error('Bad request. This bucket may have uniform bucket-level access enabled, which doesn\'t support object ACLs. Use IAM policies instead.');
51
+ }
52
+ if (error.response?.status === 403) {
53
+ throw new Error('Access denied. You need storage.objects.setIamPolicy permission or OWNER ACL permission on the object.');
54
+ }
55
+ if (error.response?.status === 404) {
56
+ if (error.response?.data?.error?.message?.includes('ACL')) {
57
+ throw new Error(`ACL entry for entity "${entity}" not found on object "${object}".`);
58
+ }
59
+ throw new Error(`Object "${object}" not found in bucket "${bucket}".`);
60
+ }
61
+ throw new Error(`Failed to delete object ACL: ${error.message || 'Unknown error'}`);
62
+ }
63
+ },
64
+ });
@@ -0,0 +1,59 @@
1
+ import { createAction, Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { bucketDropdown, objectDropdown, projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const deleteObject = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'delete_object',
10
+ displayName: 'Delete Object',
11
+ description: 'Permanently delete a specific object. Perfect for removing obsolete files.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Permanently deletes an object from a bucket, optionally a specific generation/revision for versioned objects. Use to remove an obsolete or unwanted file. Not idempotent: the first call removes the object and a repeat fails because it no longer exists. Requires the bucket and object name.', idempotent: false },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ bucket: bucketDropdown,
17
+ object: objectDropdown('bucket'),
18
+ generation: Property.Number({
19
+ displayName: 'Generation',
20
+ description: 'Optional generation number for versioned objects (permanently deletes a specific revision)',
21
+ required: false,
22
+ }),
23
+ },
24
+ async run(context) {
25
+ const { bucket, object, generation } = context.propsValue;
26
+ const auth = context.auth as OAuth2PropertyValue;
27
+
28
+ let path = `/b/${bucket}/o/${encodeURIComponent(object as string)}`;
29
+ if (generation) {
30
+ path += `?generation=${generation}`;
31
+ }
32
+
33
+ try {
34
+ await gcsCommon.makeRequest(HttpMethod.DELETE, path, auth.access_token);
35
+
36
+ return {
37
+ success: true,
38
+ bucket,
39
+ object,
40
+ generation: generation || 'latest',
41
+ message: `Object "${object}" deleted successfully from bucket "${bucket}"`,
42
+ };
43
+ } catch (error: any) {
44
+ if (error.response?.status === 404) {
45
+ throw new Error(`Object "${object}" not found in bucket "${bucket}". It may have already been deleted.`);
46
+ }
47
+ if (error.response?.status === 403) {
48
+ throw new Error('Access denied. You need storage.objects.delete permission to delete this object.');
49
+ }
50
+ if (error.response?.status === 412) {
51
+ throw new Error('Precondition failed. Object may have been modified or deleted by another process.');
52
+ }
53
+ if (error.response?.status === 400) {
54
+ throw new Error('Invalid request. Check object name and generation parameters.');
55
+ }
56
+ throw new Error(`Failed to delete object: ${error.message || 'Unknown error'}`);
57
+ }
58
+ },
59
+ });
@@ -0,0 +1,92 @@
1
+ import { createAction, Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const searchBuckets = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'search_buckets',
10
+ displayName: 'Search Buckets',
11
+ description: 'Search buckets by name. Perfect for finding buckets in your project.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Lists buckets in a project, optionally filtered by name prefix, including soft-deleted versions, and choosing whether ACLs are returned; with no prefix it returns all buckets. Use to find a bucket or enumerate a project\'s buckets, and pass the returned page token to paginate. Idempotent read that does not modify storage. Requires the project ID.', idempotent: true },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ prefix: Property.ShortText({
17
+ displayName: 'Name Prefix',
18
+ description: 'Filter buckets whose names begin with this prefix',
19
+ required: false,
20
+ }),
21
+ includeSoftDeleted: Property.Checkbox({
22
+ displayName: 'Include Soft-Deleted',
23
+ description: 'Include soft-deleted bucket versions in results',
24
+ required: false,
25
+ }),
26
+ projection: Property.StaticDropdown({
27
+ displayName: 'Projection',
28
+ description: 'Set of properties to return',
29
+ required: false,
30
+ options: {
31
+ options: [
32
+ { label: 'No ACLs (faster)', value: 'noAcl' },
33
+ { label: 'Full (includes ACLs)', value: 'full' },
34
+ ],
35
+ },
36
+ }),
37
+ pageToken: Property.ShortText({
38
+ displayName: 'Page Token',
39
+ description: 'Token for pagination (from previous response)',
40
+ required: false,
41
+ }),
42
+ maxResults: Property.Number({
43
+ displayName: 'Max Results',
44
+ description: 'Maximum number of buckets to return',
45
+ required: false,
46
+ }),
47
+ },
48
+ async run(context) {
49
+ const {
50
+ projectId,
51
+ prefix,
52
+ includeSoftDeleted,
53
+ projection,
54
+ pageToken,
55
+ maxResults
56
+ } = context.propsValue;
57
+ const auth = context.auth as OAuth2PropertyValue;
58
+
59
+ const params = new URLSearchParams();
60
+ params.append('project', projectId!);
61
+ if (prefix) params.append('prefix', prefix);
62
+ if (includeSoftDeleted) params.append('softDeleted', 'true');
63
+ if (projection) params.append('projection', projection);
64
+ if (pageToken) params.append('pageToken', pageToken);
65
+ if (maxResults) params.append('maxResults', maxResults.toString());
66
+
67
+ const path = `/b?${params.toString()}`;
68
+
69
+ try {
70
+ const response = await gcsCommon.makeRequest(HttpMethod.GET, path, auth.access_token);
71
+
72
+ return {
73
+ success: true,
74
+ projectId,
75
+ items: response.items || [],
76
+ nextPageToken: response.nextPageToken,
77
+ totalBuckets: response.items?.length || 0,
78
+ };
79
+ } catch (error: any) {
80
+ if (error.response?.status === 403) {
81
+ throw new Error('Access denied. You need storage.buckets.list permission to search buckets in this project.');
82
+ }
83
+ if (error.response?.status === 404) {
84
+ throw new Error(`Project "${projectId}" not found or you don't have access to it.`);
85
+ }
86
+ if (error.response?.status === 400) {
87
+ throw new Error('Invalid search parameters. Check your project ID and other filters.');
88
+ }
89
+ throw new Error(`Failed to search buckets: ${error.message || 'Unknown error'}`);
90
+ }
91
+ },
92
+ });
@@ -0,0 +1,101 @@
1
+ import { createAction, Property, OAuth2PropertyValue } from '@agnocon/pieces-framework';
2
+ import { googleCloudStorageAuth } from '../common/auth';
3
+ import { gcsCommon } from '../common/client';
4
+ import { bucketDropdown, projectIdProperty } from '../common/props';
5
+ import { HttpMethod } from '@agnocon/pieces-common';
6
+
7
+ export const searchObjects = createAction({
8
+ auth: googleCloudStorageAuth,
9
+ name: 'search_objects',
10
+ displayName: 'Search Objects',
11
+ description: 'Search objects by criteria. Perfect for finding files in your bucket.',
12
+ audience: 'both',
13
+ aiMetadata: { description: 'Lists objects in a bucket, optionally narrowed by name prefix, glob pattern, delimiter (for hierarchical/folder listing), or object versions; with no filters it returns all objects. Use to find files or enumerate bucket contents, and pass the returned page token to paginate. Idempotent read that does not modify storage. Requires the bucket name.', idempotent: true },
14
+ props: {
15
+ projectId: projectIdProperty,
16
+ bucket: bucketDropdown,
17
+ prefix: Property.ShortText({
18
+ displayName: 'Prefix',
19
+ description: 'Filter objects whose names begin with this prefix',
20
+ required: false,
21
+ }),
22
+ matchGlob: Property.ShortText({
23
+ displayName: 'Glob Pattern',
24
+ description: 'Glob pattern to filter results (e.g., "folder/*", "backup-*.txt")',
25
+ required: false,
26
+ }),
27
+ delimiter: Property.ShortText({
28
+ displayName: 'Delimiter',
29
+ description: 'Delimiter for hierarchical listing (commonly "/")',
30
+ required: false,
31
+ }),
32
+ includeFoldersAsPrefixes: Property.Checkbox({
33
+ displayName: 'Include Folders',
34
+ description: 'Include empty folders and managed folders in results',
35
+ required: false,
36
+ }),
37
+ versions: Property.Checkbox({
38
+ displayName: 'Include Versions',
39
+ description: 'List all versions of objects as distinct results',
40
+ required: false,
41
+ }),
42
+ pageToken: Property.ShortText({
43
+ displayName: 'Page Token',
44
+ description: 'Token for pagination (from previous response)',
45
+ required: false,
46
+ }),
47
+ maxResults: Property.Number({
48
+ displayName: 'Max Results',
49
+ description: 'Maximum number of objects to return (recommended: ≤1000)',
50
+ required: false,
51
+ }),
52
+ },
53
+ async run(context) {
54
+ const {
55
+ bucket,
56
+ prefix,
57
+ matchGlob,
58
+ delimiter,
59
+ includeFoldersAsPrefixes,
60
+ versions,
61
+ pageToken,
62
+ maxResults
63
+ } = context.propsValue;
64
+ const auth = context.auth as OAuth2PropertyValue;
65
+
66
+ const params = new URLSearchParams();
67
+ if (prefix) params.append('prefix', prefix);
68
+ if (matchGlob) params.append('matchGlob', matchGlob);
69
+ if (delimiter) params.append('delimiter', delimiter);
70
+ if (includeFoldersAsPrefixes) params.append('includeFoldersAsPrefixes', 'true');
71
+ if (versions) params.append('versions', 'true');
72
+ if (pageToken) params.append('pageToken', pageToken);
73
+ if (maxResults) params.append('maxResults', maxResults.toString());
74
+
75
+ const path = `/b/${bucket}/o?${params.toString()}`;
76
+
77
+ try {
78
+ const response = await gcsCommon.makeRequest(HttpMethod.GET, path, auth.access_token);
79
+
80
+ return {
81
+ success: true,
82
+ bucket,
83
+ items: response.items || [],
84
+ nextPageToken: response.nextPageToken,
85
+ prefixes: response.prefixes || [],
86
+ totalItems: response.items?.length || 0,
87
+ };
88
+ } catch (error: any) {
89
+ if (error.response?.status === 403) {
90
+ throw new Error('Access denied. You need storage.objects.list permission to search objects in this bucket.');
91
+ }
92
+ if (error.response?.status === 404) {
93
+ throw new Error(`Bucket "${bucket}" not found.`);
94
+ }
95
+ if (error.response?.status === 400) {
96
+ throw new Error('Invalid search parameters. Check your prefix, glob pattern, or other filters.');
97
+ }
98
+ throw new Error(`Failed to search objects: ${error.message || 'Unknown error'}`);
99
+ }
100
+ },
101
+ });
@@ -0,0 +1,15 @@
1
+ import { PieceAuth } from '@agnocon/pieces-framework';
2
+
3
+ export const googleCloudStorageAuth = PieceAuth.OAuth2({
4
+ description: '',
5
+ authUrl: 'https://accounts.google.com/o/oauth2/auth',
6
+ tokenUrl: 'https://oauth2.googleapis.com/token',
7
+ required: true,
8
+ scope: [
9
+ 'https://www.googleapis.com/auth/devstorage.read_write',
10
+ 'https://www.googleapis.com/auth/devstorage.full_control',
11
+ 'https://www.googleapis.com/auth/cloud-platform.read-only',
12
+ 'https://www.googleapis.com/auth/pubsub',
13
+ 'email'
14
+ ],
15
+ });
@@ -0,0 +1,63 @@
1
+ import {
2
+ httpClient,
3
+ HttpMethod,
4
+ AuthenticationType,
5
+ } from '@agnocon/pieces-common';
6
+ import { OAuth2PropertyValue } from '@agnocon/pieces-framework';
7
+
8
+ export const gcsCommon = {
9
+ gcsBaseUrl: 'https://www.googleapis.com/storage/v1',
10
+ pubsubBaseUrl: 'https://pubsub.googleapis.com/v1',
11
+
12
+ async makeGCSRequest(
13
+ method: HttpMethod,
14
+ path: string,
15
+ accessToken: string,
16
+ body?: any
17
+ ): Promise<any> {
18
+ const url = path.startsWith('http') ? path : `${this.gcsBaseUrl}${path}`;
19
+
20
+ const response = await httpClient.sendRequest({
21
+ method,
22
+ url,
23
+ authentication: {
24
+ type: AuthenticationType.BEARER_TOKEN,
25
+ token: accessToken,
26
+ },
27
+ body,
28
+ });
29
+
30
+ return response.body;
31
+ },
32
+
33
+ async makePubSubRequest(
34
+ method: HttpMethod,
35
+ path: string,
36
+ accessToken: string,
37
+ body?: any
38
+ ): Promise<any> {
39
+ const url = path.startsWith('http') ? path : `${this.pubsubBaseUrl}${path}`;
40
+
41
+ const response = await httpClient.sendRequest({
42
+ method,
43
+ url,
44
+ authentication: {
45
+ type: AuthenticationType.BEARER_TOKEN,
46
+ token: accessToken,
47
+ },
48
+ body,
49
+ });
50
+
51
+ return response.body;
52
+ },
53
+
54
+ // For backward compatibility
55
+ async makeRequest(
56
+ method: HttpMethod,
57
+ path: string,
58
+ accessToken: string,
59
+ body?: any
60
+ ): Promise<any> {
61
+ return this.makeGCSRequest(method, path, accessToken, body);
62
+ },
63
+ };