@guayaba/workflow-piece-google-cloud-storage 0.1.3
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/.eslintrc.json +33 -0
- package/README.md +5 -0
- package/assets/logo.png +0 -0
- package/package.json +21 -0
- package/src/i18n/de.json +123 -0
- package/src/i18n/es.json +123 -0
- package/src/i18n/fr.json +123 -0
- package/src/i18n/ja.json +123 -0
- package/src/i18n/nl.json +123 -0
- package/src/i18n/pt.json +123 -0
- package/src/i18n/translation.json +123 -0
- package/src/i18n/zh.json +123 -0
- package/src/index.ts +46 -0
- package/src/lib/actions/clone-object.ts +73 -0
- package/src/lib/actions/create-bucket-acl.ts +56 -0
- package/src/lib/actions/create-bucket-default-object-acl.ts +56 -0
- package/src/lib/actions/create-bucket.ts +73 -0
- package/src/lib/actions/create-object-acl.ts +79 -0
- package/src/lib/actions/delete-bucket-acl.ts +50 -0
- package/src/lib/actions/delete-bucket-default-object-acl.ts +50 -0
- package/src/lib/actions/delete-empty-bucket.ts +40 -0
- package/src/lib/actions/delete-object-acl.ts +62 -0
- package/src/lib/actions/delete-object.ts +57 -0
- package/src/lib/actions/search-buckets.ts +90 -0
- package/src/lib/actions/search-objects.ts +99 -0
- package/src/lib/common/auth.ts +14 -0
- package/src/lib/common/client.ts +63 -0
- package/src/lib/common/props.ts +249 -0
- package/src/lib/triggers/new-object-created.ts +171 -0
- package/src/lib/triggers/object-updated.ts +171 -0
- package/tsconfig.json +20 -0
- package/tsconfig.lib.json +13 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createTrigger, TriggerStrategy, Property } from '@guayaba/workflows-framework';
|
|
2
|
+
import { googleCloudStorageAuth } from '../common/auth';
|
|
3
|
+
import { gcsCommon } from '../common/client';
|
|
4
|
+
import { bucketDropdown, projectIdProperty } from '../common/props';
|
|
5
|
+
import { HttpMethod } from '@guayaba/workflows-common';
|
|
6
|
+
|
|
7
|
+
interface TriggerData {
|
|
8
|
+
topicName: string;
|
|
9
|
+
subscriptionName: string;
|
|
10
|
+
notificationId: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const objectUpdated = createTrigger({
|
|
14
|
+
auth: googleCloudStorageAuth,
|
|
15
|
+
name: 'object_updated',
|
|
16
|
+
displayName: 'Object Updated',
|
|
17
|
+
description: 'Triggers when an existing object is updated in a bucket',
|
|
18
|
+
props: {
|
|
19
|
+
projectId: projectIdProperty,
|
|
20
|
+
bucket: bucketDropdown,
|
|
21
|
+
prefix: Property.ShortText({
|
|
22
|
+
displayName: 'Prefix Filter',
|
|
23
|
+
description: 'Only trigger for objects with this prefix',
|
|
24
|
+
required: false,
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
27
|
+
type: TriggerStrategy.WEBHOOK,
|
|
28
|
+
sampleData: {
|
|
29
|
+
kind: 'storage#object',
|
|
30
|
+
id: 'example-bucket/example-object/1234567890',
|
|
31
|
+
name: 'example-object.txt',
|
|
32
|
+
bucket: 'example-bucket',
|
|
33
|
+
generation: '1234567890',
|
|
34
|
+
contentType: 'text/plain',
|
|
35
|
+
timeCreated: '2023-01-01T00:00:00.000Z',
|
|
36
|
+
updated: '2023-01-01T01:00:00.000Z',
|
|
37
|
+
size: '2048',
|
|
38
|
+
},
|
|
39
|
+
onEnable: async (context) => {
|
|
40
|
+
const { projectId, bucket, prefix } = context.propsValue;
|
|
41
|
+
const auth = context.auth;
|
|
42
|
+
|
|
43
|
+
// Generate unique names for this trigger instance
|
|
44
|
+
const triggerId = `ap-gcs-update-${bucket}-${Date.now()}`;
|
|
45
|
+
const topicName = `projects/${projectId}/topics/${triggerId}`;
|
|
46
|
+
const subscriptionName = `projects/${projectId}/subscriptions/${triggerId}`;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
// 1. Create Pub/Sub topic
|
|
50
|
+
await gcsCommon.makePubSubRequest(
|
|
51
|
+
HttpMethod.PUT,
|
|
52
|
+
`/projects/${projectId}/topics/${triggerId}`,
|
|
53
|
+
auth.access_token
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// 2. Create GCS notification configuration for metadata updates
|
|
57
|
+
const notificationConfig: any = {
|
|
58
|
+
topic: topicName,
|
|
59
|
+
payload_format: 'JSON_API_V1',
|
|
60
|
+
event_types: ['OBJECT_METADATA_UPDATE'],
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (prefix) {
|
|
64
|
+
notificationConfig.object_name_prefix = prefix;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const notificationResponse = await gcsCommon.makeGCSRequest(
|
|
68
|
+
HttpMethod.POST,
|
|
69
|
+
`/b/${bucket}/notificationConfigs`,
|
|
70
|
+
auth.access_token,
|
|
71
|
+
notificationConfig
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// 3. Create Pub/Sub subscription with webhook push
|
|
75
|
+
const subscriptionConfig = {
|
|
76
|
+
topic: topicName,
|
|
77
|
+
pushConfig: {
|
|
78
|
+
pushEndpoint: context.webhookUrl,
|
|
79
|
+
},
|
|
80
|
+
ackDeadlineSeconds: 60,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
await gcsCommon.makePubSubRequest(
|
|
84
|
+
HttpMethod.PUT,
|
|
85
|
+
`/projects/${projectId}/subscriptions/${triggerId}`,
|
|
86
|
+
auth.access_token,
|
|
87
|
+
subscriptionConfig
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Store trigger data for cleanup
|
|
91
|
+
await context.store.put<TriggerData>('_trigger', {
|
|
92
|
+
topicName: triggerId,
|
|
93
|
+
subscriptionName: triggerId,
|
|
94
|
+
notificationId: notificationResponse.id,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
} catch (error) {
|
|
98
|
+
// Cleanup on failure
|
|
99
|
+
try {
|
|
100
|
+
await gcsCommon.makePubSubRequest(
|
|
101
|
+
HttpMethod.DELETE,
|
|
102
|
+
`/projects/${projectId}/subscriptions/${triggerId}`,
|
|
103
|
+
auth.access_token
|
|
104
|
+
);
|
|
105
|
+
} catch (e) { /* ignore */ }
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
await gcsCommon.makePubSubRequest(
|
|
109
|
+
HttpMethod.DELETE,
|
|
110
|
+
`/projects/${projectId}/topics/${triggerId}`,
|
|
111
|
+
auth.access_token
|
|
112
|
+
);
|
|
113
|
+
} catch (e) { /* ignore */ }
|
|
114
|
+
|
|
115
|
+
throw new Error(`Failed to setup Pub/Sub notifications: ${(error as any)?.message || 'Unknown error'}`);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
onDisable: async (context) => {
|
|
119
|
+
const triggerData = await context.store.get<TriggerData>('_trigger');
|
|
120
|
+
if (!triggerData) return;
|
|
121
|
+
|
|
122
|
+
const { projectId } = context.propsValue;
|
|
123
|
+
const { bucket } = context.propsValue;
|
|
124
|
+
const auth = context.auth;
|
|
125
|
+
|
|
126
|
+
// Clean up in reverse order
|
|
127
|
+
try {
|
|
128
|
+
// Delete subscription
|
|
129
|
+
await gcsCommon.makePubSubRequest(
|
|
130
|
+
HttpMethod.DELETE,
|
|
131
|
+
`/projects/${projectId}/subscriptions/${triggerData.subscriptionName}`,
|
|
132
|
+
auth.access_token
|
|
133
|
+
);
|
|
134
|
+
} catch (e) { /* ignore */ }
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
// Delete notification config
|
|
138
|
+
await gcsCommon.makeGCSRequest(
|
|
139
|
+
HttpMethod.DELETE,
|
|
140
|
+
`/b/${bucket}/notificationConfigs/${triggerData.notificationId}`,
|
|
141
|
+
auth.access_token
|
|
142
|
+
);
|
|
143
|
+
} catch (e) { /* ignore */ }
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
// Delete topic
|
|
147
|
+
await gcsCommon.makePubSubRequest(
|
|
148
|
+
HttpMethod.DELETE,
|
|
149
|
+
`/projects/${projectId}/topics/${triggerData.topicName}`,
|
|
150
|
+
auth.access_token
|
|
151
|
+
);
|
|
152
|
+
} catch (e) { /* ignore */ }
|
|
153
|
+
},
|
|
154
|
+
run: async (context) => {
|
|
155
|
+
const payload = context.payload.body as any;
|
|
156
|
+
|
|
157
|
+
if (!payload?.message?.data) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Decode Pub/Sub message
|
|
162
|
+
const messageData = JSON.parse(
|
|
163
|
+
Buffer.from(payload.message.data, 'base64').toString()
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Extract GCS object from notification payload
|
|
167
|
+
const gcsObject = messageData;
|
|
168
|
+
|
|
169
|
+
return [gcsObject];
|
|
170
|
+
},
|
|
171
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"importHelpers": true,
|
|
8
|
+
"noImplicitOverride": true,
|
|
9
|
+
"noImplicitReturns": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true,
|
|
11
|
+
"noPropertyAccessFromIndexSignature": true
|
|
12
|
+
},
|
|
13
|
+
"files": [],
|
|
14
|
+
"include": [],
|
|
15
|
+
"references": [
|
|
16
|
+
{
|
|
17
|
+
"path": "./tsconfig.lib.json"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|