@liquidmetal-ai/raindrop 0.13.0 → 0.15.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/README.md +327 -89
- package/bundle/build-CBEGQPJT.js +62 -0
- package/bundle/{chunk-IEF2XC25.js → chunk-2PH3PHH3.js} +5 -3
- package/bundle/{chunk-4HZ22KOV.js → chunk-3CMR7ES5.js} +4 -4
- package/bundle/{chunk-JSBM2JYW.js → chunk-3EYKCHIK.js} +1 -1
- package/bundle/chunk-5XHDP4VK.js +1697 -0
- package/bundle/{chunk-TSQK4HH6.js → chunk-674GMSXY.js} +1 -1
- package/bundle/{chunk-PS3WZBDF.js → chunk-6L4V66WZ.js} +1105 -2728
- package/bundle/{chunk-5245CEUM.js → chunk-AGG7JZVH.js} +2 -2
- package/bundle/{chunk-3GFKUF5D.js → chunk-B3IY2XS6.js} +4 -2
- package/bundle/{chunk-WIDI65NO.js → chunk-CBAXTRCS.js} +1 -1
- package/bundle/{chunk-JLVDTXO2.js → chunk-DPV5HIG7.js} +4 -4
- package/bundle/{chunk-36GNZK4A.js → chunk-EVXLXWP7.js} +1 -1
- package/bundle/{chunk-4YVU5KEQ.js → chunk-HN3AAKRY.js} +4 -2
- package/bundle/{chunk-NVNEQXHN.js → chunk-IGLE4Y3B.js} +7 -5
- package/bundle/{chunk-FGSYWVBA.js → chunk-IQ6HFRA6.js} +1 -1
- package/bundle/{chunk-O3QZDJ75.js → chunk-JQONDSHY.js} +2 -2
- package/bundle/{chunk-W4IPOFZC.js → chunk-KADMFJLN.js} +8 -6
- package/bundle/chunk-KG5BLUGU.js +246 -0
- package/bundle/{chunk-V5LHJTYS.js → chunk-KLOYSTZY.js} +13 -2
- package/bundle/{chunk-ETC5VU7H.js → chunk-KXHVSLAI.js} +1 -1
- package/bundle/{chunk-Y4WFGNPM.js → chunk-L6FRQULN.js} +1 -1
- package/bundle/{chunk-3QCVYSRU.js → chunk-LT3BFQ4O.js} +1 -1
- package/bundle/{chunk-KQZJHBNG.js → chunk-MBLKVNI5.js} +1 -1
- package/bundle/{chunk-6AIUQUUM.js → chunk-MFMVJZW6.js} +71 -15
- package/bundle/{chunk-25T7MEKO.js → chunk-MJBLNWG3.js} +1 -1
- package/bundle/{chunk-MSJ33O5Y.js → chunk-NRCQIE3Z.js} +95 -115
- package/bundle/{chunk-XKKPPSPC.js → chunk-OCYTN4IH.js} +2 -2
- package/bundle/{chunk-2GAMWFJE.js → chunk-QEF5D4VE.js} +1 -1
- package/bundle/{chunk-4B3QYXBA.js → chunk-T7MQCLXF.js} +5 -3
- package/bundle/{chunk-LDFYPOXJ.js → chunk-TFQY5TSY.js} +1 -1
- package/bundle/{chunk-BWK4MC7Y.js → chunk-USZXZZAR.js} +8 -6
- package/bundle/{chunk-ER2RCPCY.js → chunk-V54KHS5B.js} +2 -2
- package/bundle/{chunk-YSKASURB.js → chunk-V6J23FL2.js} +1 -1
- package/bundle/{chunk-UHSTDJ7X.js → chunk-VN2QYX4C.js} +1 -1
- package/bundle/{chunk-Z4OWKG7J.js → chunk-VOT5MMEY.js} +1 -1
- package/bundle/{chunk-W6GU26WO.js → chunk-WG6BDFPZ.js} +1 -1
- package/bundle/{chunk-AK77X5GL.js → chunk-XX74I5RK.js} +4 -2
- package/bundle/{chunk-6BT265R3.js → chunk-YQCRWPNI.js} +1 -1
- package/bundle/commands/annotation/get.js +3 -3
- package/bundle/commands/annotation/list.js +3 -3
- package/bundle/commands/annotation/put.js +3 -3
- package/bundle/commands/auth/apikey.js +2 -2
- package/bundle/commands/auth/list.js +2 -2
- package/bundle/commands/auth/login.js +2 -2
- package/bundle/commands/auth/logout.js +2 -2
- package/bundle/commands/auth/select.js +3 -3
- package/bundle/commands/bucket/create-credential.js +2 -2
- package/bundle/commands/bucket/delete-credential.js +2 -2
- package/bundle/commands/bucket/get-credential.js +2 -2
- package/bundle/commands/bucket/list-credentials.js +2 -2
- package/bundle/commands/build/actor/setup.js +124 -0
- package/bundle/commands/build/branch.js +10 -10
- package/bundle/commands/build/bucket-events/setup.js +146 -0
- package/bundle/commands/build/checkout.js +8 -8
- package/bundle/commands/build/clone.js +6 -6
- package/bundle/commands/build/delete.js +8 -8
- package/bundle/commands/build/deploy.js +10 -10
- package/bundle/commands/build/env/get.js +3 -3
- package/bundle/commands/build/env/list.js +2 -2
- package/bundle/commands/build/env/set.js +3 -3
- package/bundle/commands/build/env.js +2 -2
- package/bundle/commands/build/features.js +192 -0
- package/bundle/commands/build/find.js +4 -4
- package/bundle/commands/build/generate.js +52 -3
- package/bundle/commands/build/init-workspace.js +3 -3
- package/bundle/commands/build/init.js +15 -3
- package/bundle/commands/build/list.js +5 -5
- package/bundle/commands/build/queue/setup.js +133 -0
- package/bundle/commands/build/sandbox.js +6 -6
- package/bundle/commands/build/smartbucket/setup.js +165 -0
- package/bundle/commands/build/smartmemory/setup.js +171 -0
- package/bundle/commands/build/smartsql/setup.js +167 -0
- package/bundle/commands/build/start.js +2 -2
- package/bundle/commands/build/status.js +5 -5
- package/bundle/commands/build/stop.js +2 -2
- package/bundle/commands/build/stripe/dashboard.js +3 -3
- package/bundle/commands/build/stripe/onboard.js +3 -3
- package/bundle/commands/build/stripe/setup.js +3 -3
- package/bundle/commands/build/stripe/start.js +14 -14
- package/bundle/commands/build/stripe/status.js +3 -3
- package/bundle/commands/build/stripe/subscription/create.js +4 -4
- package/bundle/commands/build/stripe/subscription/get.js +4 -4
- package/bundle/commands/build/stripe/subscription/update.js +4 -4
- package/bundle/commands/build/tools/check.js +2 -2
- package/bundle/commands/build/tools/fmt.js +2 -2
- package/bundle/commands/build/unsandbox.js +6 -6
- package/bundle/commands/build/upload.js +5 -5
- package/bundle/commands/build/validate.js +85 -14
- package/bundle/commands/build/workos/delete.js +6 -6
- package/bundle/commands/build/workos/env/attach.js +3 -3
- package/bundle/commands/build/workos/env/attached.js +3 -3
- package/bundle/commands/build/workos/env/create.js +3 -3
- package/bundle/commands/build/workos/env/delete.js +3 -3
- package/bundle/commands/build/workos/env/detach.js +3 -3
- package/bundle/commands/build/workos/env/dev-login.js +3 -3
- package/bundle/commands/build/workos/env/get.js +3 -3
- package/bundle/commands/build/workos/env/list.js +3 -3
- package/bundle/commands/build/workos/env/set.js +3 -3
- package/bundle/commands/build/workos/invite.js +3 -3
- package/bundle/commands/build/workos/jwt.js +172 -0
- package/bundle/commands/build/workos/setup.js +3 -3
- package/bundle/commands/build/workos/status.js +3 -3
- package/bundle/commands/dns/create.js +2 -2
- package/bundle/commands/dns/delete.js +6 -6
- package/bundle/commands/dns/get.js +6 -6
- package/bundle/commands/dns/list.js +3 -3
- package/bundle/commands/dns/records/create.js +2 -2
- package/bundle/commands/dns/records/delete.js +3 -3
- package/bundle/commands/dns/records/get.js +2 -2
- package/bundle/commands/dns/records/list.js +2 -2
- package/bundle/commands/dns/records/update.js +2 -2
- package/bundle/commands/doctor.js +309 -0
- package/bundle/commands/logs/query.js +3 -3
- package/bundle/commands/logs/tail.js +3 -3
- package/bundle/commands/mcp/install-claude.js +2 -2
- package/bundle/commands/mcp/install-gemini.js +2 -2
- package/bundle/commands/mcp/install-goose.js +2 -2
- package/bundle/commands/mcp/status.js +2 -2
- package/bundle/commands/object/delete.js +5 -37
- package/bundle/commands/object/get.js +5 -37
- package/bundle/commands/object/list.js +7 -39
- package/bundle/commands/object/put.js +5 -37
- package/bundle/commands/query/chunk-search.js +14 -46
- package/bundle/commands/query/document.js +17 -55
- package/bundle/commands/query/events.js +2 -2
- package/bundle/commands/query/reindex.js +2 -2
- package/bundle/commands/query/search.js +14 -46
- package/bundle/commands/tail.js +2 -2
- package/bundle/index.js +1 -1
- package/dist/commands/build/actor/setup.d.ts +22 -0
- package/dist/commands/build/actor/setup.d.ts.map +1 -0
- package/dist/commands/build/actor/setup.js +116 -0
- package/dist/commands/build/bucket-events/setup.d.ts +22 -0
- package/dist/commands/build/bucket-events/setup.d.ts.map +1 -0
- package/dist/commands/build/bucket-events/setup.js +134 -0
- package/dist/commands/build/features.d.ts +19 -0
- package/dist/commands/build/features.d.ts.map +1 -0
- package/dist/commands/build/features.js +97 -0
- package/dist/commands/build/generate.d.ts +2 -0
- package/dist/commands/build/generate.d.ts.map +1 -1
- package/dist/commands/build/generate.js +52 -0
- package/dist/commands/build/init.d.ts.map +1 -1
- package/dist/commands/build/init.js +10 -0
- package/dist/commands/build/queue/setup.d.ts +21 -0
- package/dist/commands/build/queue/setup.d.ts.map +1 -0
- package/dist/commands/build/queue/setup.js +120 -0
- package/dist/commands/build/smartbucket/setup.d.ts +23 -0
- package/dist/commands/build/smartbucket/setup.d.ts.map +1 -0
- package/dist/commands/build/smartbucket/setup.js +167 -0
- package/dist/commands/build/smartmemory/setup.d.ts +23 -0
- package/dist/commands/build/smartmemory/setup.d.ts.map +1 -0
- package/dist/commands/build/smartmemory/setup.js +172 -0
- package/dist/commands/build/smartsql/setup.d.ts +23 -0
- package/dist/commands/build/smartsql/setup.d.ts.map +1 -0
- package/dist/commands/build/smartsql/setup.js +169 -0
- package/dist/commands/build/validate.d.ts +2 -0
- package/dist/commands/build/validate.d.ts.map +1 -1
- package/dist/commands/build/validate.js +80 -8
- package/dist/commands/build/workos/jwt.d.ts +23 -0
- package/dist/commands/build/workos/jwt.d.ts.map +1 -0
- package/dist/commands/build/workos/jwt.js +172 -0
- package/dist/commands/doctor.d.ts +27 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +328 -0
- package/dist/commands/object/delete.d.ts +0 -2
- package/dist/commands/object/delete.d.ts.map +1 -1
- package/dist/commands/object/delete.js +3 -38
- package/dist/commands/object/get.d.ts +0 -2
- package/dist/commands/object/get.d.ts.map +1 -1
- package/dist/commands/object/get.js +3 -38
- package/dist/commands/object/list.d.ts +0 -2
- package/dist/commands/object/list.d.ts.map +1 -1
- package/dist/commands/object/list.js +5 -40
- package/dist/commands/object/put.d.ts +0 -2
- package/dist/commands/object/put.d.ts.map +1 -1
- package/dist/commands/object/put.js +3 -38
- package/dist/commands/query/chunk-search.d.ts +0 -2
- package/dist/commands/query/chunk-search.d.ts.map +1 -1
- package/dist/commands/query/chunk-search.js +12 -46
- package/dist/commands/query/document.d.ts +1 -3
- package/dist/commands/query/document.d.ts.map +1 -1
- package/dist/commands/query/document.js +16 -60
- package/dist/commands/query/search.d.ts +0 -2
- package/dist/commands/query/search.d.ts.map +1 -1
- package/dist/commands/query/search.js +12 -46
- package/dist/feature-catalog.d.ts +28 -0
- package/dist/feature-catalog.d.ts.map +1 -0
- package/dist/feature-catalog.js +104 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/oclif.manifest.json +4811 -3433
- package/package.json +3 -3
- package/templates/examples/smartbucket-minimal.ts.hbs +87 -0
- package/templates/examples/smartmemory-minimal.ts.hbs +82 -0
- package/templates/examples/smartsql-minimal.ts.hbs +69 -0
- package/templates/handlers/actor/index.test.ts.hbs +48 -85
- package/templates/handlers/actor/index.ts.hbs +16 -316
- package/templates/handlers/bucket-event-notification/index.ts.hbs +32 -235
- package/templates/handlers/bucket-event-observer.ts.hbs +79 -0
- package/templates/handlers/http-service/index.test.ts.hbs +3 -0
- package/templates/handlers/http-service/index.ts.hbs +43 -15
- package/templates/handlers/queue-consumer-setup.ts.hbs +45 -0
- package/templates/handlers/task/index.test.ts.hbs +30 -112
- package/templates/handlers/task/index.ts.hbs +19 -58
- package/templates/init/RAINDROP.md.hbs +97 -1
- package/templates/init/eslint.config.js +43 -0
- package/templates/init/package.json.hbs +4 -1
- package/templates/init/tsconfig.json +3 -3
- package/bundle/chunk-23UBI7BN.js +0 -48
- package/bundle/chunk-2QWMBNE3.js +0 -384
- package/bundle/chunk-45IYWQDC.js +0 -384
- package/bundle/chunk-5YUO23QU.js +0 -4585
- package/bundle/chunk-6MIGCNUO.js +0 -75
- package/bundle/chunk-7ZJWA6HP.js +0 -805
- package/bundle/chunk-AIYVX2M7.js +0 -44
- package/bundle/chunk-BB5TNIEM.js +0 -48
- package/bundle/chunk-BUR3HFKH.js +0 -488
- package/bundle/chunk-BYSBS7KT.js +0 -488
- package/bundle/chunk-CX3RWI62.js +0 -28658
- package/bundle/chunk-DLH7MI57.js +0 -305
- package/bundle/chunk-E3WJIYJZ.js +0 -12148
- package/bundle/chunk-EX7NOPRF.js +0 -12148
- package/bundle/chunk-F76JQS2J.js +0 -231
- package/bundle/chunk-FBOXMVKD.js +0 -28679
- package/bundle/chunk-FTPZ6SQW.js +0 -238909
- package/bundle/chunk-H3CFZ7ZH.js +0 -74
- package/bundle/chunk-HXOILVWA.js +0 -384
- package/bundle/chunk-IMP7O5AC.js +0 -22452
- package/bundle/chunk-IPYOAKRE.js +0 -231
- package/bundle/chunk-J7HN6XF2.js +0 -4461
- package/bundle/chunk-JOLOAALA.js +0 -231
- package/bundle/chunk-JZ2G4Q35.js +0 -4585
- package/bundle/chunk-KVAWPWF7.js +0 -231
- package/bundle/chunk-MEUAAIXV.js +0 -28657
- package/bundle/chunk-QBWFE57Z.js +0 -384
- package/bundle/chunk-SP3LOXPC.js +0 -46
- package/bundle/chunk-T7C564PR.js +0 -28678
- package/bundle/chunk-UFH545WJ.js +0 -22452
- package/bundle/chunk-UHVMPWM5.js +0 -315
- package/bundle/chunk-VB7ZTSZV.js +0 -1089
- package/bundle/chunk-VBIJDFMJ.js +0 -384
- package/bundle/chunk-VR7RLTE3.js +0 -231
- package/bundle/chunk-WFZUJLEC.js +0 -231
- package/bundle/chunk-YDGJTLVZ.js +0 -133
- package/bundle/chunk-YPNQ7UFK.js +0 -502
- package/bundle/chunk-YXFDRMSN.js +0 -384
- package/dist/lib/dns-utils.d.ts +0 -7
- package/dist/lib/dns-utils.d.ts.map +0 -1
- package/dist/lib/dns-utils.js +0 -44
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { Actor, ActorState
|
|
1
|
+
import { Actor, ActorState } from '@liquidmetal-ai/raindrop-framework';
|
|
2
2
|
import { Env } from './raindrop.gen';
|
|
3
3
|
|
|
4
4
|
interface {{actorClassName}}State {
|
|
5
5
|
count: number;
|
|
6
6
|
lastUpdated: string;
|
|
7
|
-
|
|
8
|
-
messages: Array<{
|
|
9
|
-
id: string;
|
|
10
|
-
content: string;
|
|
11
|
-
timestamp: string;
|
|
12
|
-
}>;
|
|
7
|
+
data: Record<string, any>;
|
|
13
8
|
}
|
|
14
9
|
|
|
15
10
|
export class {{actorClassName}} extends Actor<Env> {
|
|
@@ -20,26 +15,24 @@ export class {{actorClassName}} extends Actor<Env> {
|
|
|
20
15
|
// === Initialization ===
|
|
21
16
|
|
|
22
17
|
async initialize(): Promise<void> {
|
|
23
|
-
// Initialize default state if not exists
|
|
24
18
|
const existing = await this.state.storage.get<{{actorClassName}}State>('state');
|
|
25
19
|
if (!existing) {
|
|
26
20
|
await this.state.storage.put('state', {
|
|
27
21
|
count: 0,
|
|
28
22
|
lastUpdated: new Date().toISOString(),
|
|
29
|
-
|
|
30
|
-
messages: [],
|
|
23
|
+
data: {},
|
|
31
24
|
});
|
|
32
25
|
}
|
|
33
26
|
}
|
|
34
27
|
|
|
35
|
-
// ===
|
|
28
|
+
// === Add Your Actor Methods Here ===
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
// Example: Simple counter
|
|
31
|
+
async increment(): Promise<number> {
|
|
38
32
|
const state = await this.state.storage.get<{{actorClassName}}State>('state') || {
|
|
39
33
|
count: 0,
|
|
40
34
|
lastUpdated: new Date().toISOString(),
|
|
41
|
-
|
|
42
|
-
messages: [],
|
|
35
|
+
data: {},
|
|
43
36
|
};
|
|
44
37
|
|
|
45
38
|
const newState = {
|
|
@@ -53,318 +46,25 @@ export class {{actorClassName}} extends Actor<Env> {
|
|
|
53
46
|
return newState.count;
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
async
|
|
49
|
+
async getCount(): Promise<number> {
|
|
57
50
|
const state = await this.state.storage.get<{{actorClassName}}State>('state');
|
|
58
51
|
return state?.count || 0;
|
|
59
52
|
}
|
|
60
53
|
|
|
61
|
-
async
|
|
54
|
+
async updateData(key: string, value: any): Promise<void> {
|
|
62
55
|
const state = await this.state.storage.get<{{actorClassName}}State>('state') || {
|
|
63
56
|
count: 0,
|
|
64
57
|
lastUpdated: new Date().toISOString(),
|
|
65
|
-
|
|
66
|
-
messages: [],
|
|
58
|
+
data: {},
|
|
67
59
|
};
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
timestamp: new Date().toISOString(),
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const newState = {
|
|
76
|
-
...state,
|
|
77
|
-
messages: [...state.messages, message],
|
|
78
|
-
lastUpdated: new Date().toISOString(),
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
await this.state.storage.put('state', newState);
|
|
82
|
-
this.env.logger.info('Message processed', { messageId: message.id });
|
|
83
|
-
return message;
|
|
61
|
+
state.data[key] = value;
|
|
62
|
+
state.lastUpdated = new Date().toISOString();
|
|
63
|
+
await this.state.storage.put('state', state);
|
|
84
64
|
}
|
|
85
65
|
|
|
86
|
-
async
|
|
66
|
+
async getData(key: string): Promise<any> {
|
|
87
67
|
const state = await this.state.storage.get<{{actorClassName}}State>('state');
|
|
88
|
-
return state?.
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async clearMessages(): Promise<void> {
|
|
92
|
-
const state = await this.state.storage.get<{{actorClassName}}State>('state') || {
|
|
93
|
-
count: 0,
|
|
94
|
-
lastUpdated: new Date().toISOString(),
|
|
95
|
-
userData: {},
|
|
96
|
-
messages: [],
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const newState = {
|
|
100
|
-
...state,
|
|
101
|
-
messages: [],
|
|
102
|
-
lastUpdated: new Date().toISOString(),
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
await this.state.storage.put('state', newState);
|
|
106
|
-
this.env.logger.info('Messages cleared');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async getState(): Promise<{{actorClassName}}State | null> {
|
|
110
|
-
return await this.state.storage.get<{{actorClassName}}State>('state') || null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// === Storage Integration ===
|
|
114
|
-
|
|
115
|
-
// Example: Save data to bucket
|
|
116
|
-
async saveToBucket(key: string, data: any): Promise<{ success: boolean; key?: string; error?: string }> {
|
|
117
|
-
try {
|
|
118
|
-
// Use bucket binding (add bucket to manifest to use this feature)
|
|
119
|
-
const bucket = (this.env as any).FILES;
|
|
120
|
-
if (!bucket) {
|
|
121
|
-
return { success: false, error: 'Bucket not configured - add bucket to manifest to use this feature' };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
await bucket.put(key, JSON.stringify(data));
|
|
125
|
-
this.env.logger.info('Data saved to bucket', { key });
|
|
126
|
-
return { success: true, key };
|
|
127
|
-
} catch (error) {
|
|
128
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
129
|
-
this.env.logger.error('Failed to save to bucket', { error: errorMessage, key });
|
|
130
|
-
return { success: false, error: errorMessage };
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Example: Load data from bucket
|
|
135
|
-
async loadFromBucket(key: string): Promise<{ success: boolean; data?: any; error?: string }> {
|
|
136
|
-
try {
|
|
137
|
-
// Use bucket binding (add bucket to manifest to use this feature)
|
|
138
|
-
const bucket = (this.env as any).FILES;
|
|
139
|
-
if (!bucket) {
|
|
140
|
-
return { success: false, error: 'Bucket not configured - add bucket to manifest to use this feature' };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const object = await bucket.get(key);
|
|
144
|
-
|
|
145
|
-
if (!object) {
|
|
146
|
-
return { success: false, error: 'Not found' };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const text = await object.text();
|
|
150
|
-
const data = JSON.parse(text);
|
|
151
|
-
return { success: true, data };
|
|
152
|
-
} catch (error) {
|
|
153
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
154
|
-
this.env.logger.error('Failed to load from bucket', { error: errorMessage, key });
|
|
155
|
-
return { success: false, error: errorMessage };
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Example: List bucket contents (no search API exists)
|
|
160
|
-
async listBucketContents(prefix?: string): Promise<{ success: boolean; items?: string[]; error?: string }> {
|
|
161
|
-
try {
|
|
162
|
-
// Use bucket binding (add bucket to manifest to use this feature)
|
|
163
|
-
const bucket = (this.env as any).FILES;
|
|
164
|
-
if (!bucket) {
|
|
165
|
-
return { success: false, error: 'Bucket not configured - add bucket to manifest to use this feature' };
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const options = prefix ? { prefix } : undefined;
|
|
169
|
-
const result = await bucket.list(options);
|
|
170
|
-
|
|
171
|
-
const items = result.objects.map((obj: any) => obj.key);
|
|
172
|
-
return { success: true, items };
|
|
173
|
-
} catch (error) {
|
|
174
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
175
|
-
this.env.logger.error('Failed to list bucket contents', { error: errorMessage, prefix });
|
|
176
|
-
return { success: false, error: errorMessage };
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// === Cache Integration ===
|
|
181
|
-
|
|
182
|
-
async cacheResult(key: string, result: any, ttlSeconds?: number): Promise<{ success: boolean; error?: string }> {
|
|
183
|
-
try {
|
|
184
|
-
// Use KV cache binding (add kv_cache to manifest to use this feature)
|
|
185
|
-
const cache = (this.env as any).CACHE || this.env.mem; // mem is always available
|
|
186
|
-
|
|
187
|
-
const options: KvCachePutOptions = {};
|
|
188
|
-
if (ttlSeconds) {
|
|
189
|
-
options.expirationTtl = ttlSeconds;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
await cache.put(key, JSON.stringify(result), options);
|
|
193
|
-
this.env.logger.info('Result cached', { key, ttl: ttlSeconds });
|
|
194
|
-
return { success: true };
|
|
195
|
-
} catch (error) {
|
|
196
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
197
|
-
this.env.logger.error('Failed to cache result', { error: errorMessage, key });
|
|
198
|
-
return { success: false, error: errorMessage };
|
|
199
|
-
}
|
|
68
|
+
return state?.data[key];
|
|
200
69
|
}
|
|
201
|
-
|
|
202
|
-
async getCachedResult(key: string): Promise<{ success: boolean; data?: any; error?: string }> {
|
|
203
|
-
try {
|
|
204
|
-
// Use KV cache binding (add kv_cache to manifest to use this feature)
|
|
205
|
-
const cache = (this.env as any).CACHE || this.env.mem; // mem is always available
|
|
206
|
-
const cached = await cache.get(key);
|
|
207
|
-
|
|
208
|
-
if (cached === null) {
|
|
209
|
-
return { success: false, error: 'Not found in cache' };
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const data = JSON.parse(cached);
|
|
213
|
-
return { success: true, data };
|
|
214
|
-
} catch (error) {
|
|
215
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
216
|
-
this.env.logger.error('Failed to get cached result', { error: errorMessage, key });
|
|
217
|
-
return { success: false, error: errorMessage };
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// === Queue Integration ===
|
|
222
|
-
|
|
223
|
-
// Note: Queue requires adding queue to manifest
|
|
224
|
-
async sendToQueue(message: any, delaySeconds?: number): Promise<{ success: boolean; error?: string }> {
|
|
225
|
-
return { success: false, error: 'Queue not configured - add queue to manifest to use this feature' };
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// === Alarm Scheduling ===
|
|
229
|
-
|
|
230
|
-
async schedulePeriodicTask(taskName: string, intervalSeconds: number, taskData?: any): Promise<void> {
|
|
231
|
-
const scheduledTime = new Date(Date.now() + intervalSeconds * 1000);
|
|
232
|
-
|
|
233
|
-
// Store alarm context
|
|
234
|
-
await this.state.storage.put('alarm:context', {
|
|
235
|
-
name: taskName,
|
|
236
|
-
data: { intervalSeconds, taskData }
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// Set alarm using storage API
|
|
240
|
-
await this.state.storage.setAlarm(scheduledTime);
|
|
241
|
-
|
|
242
|
-
this.env.logger.info('Periodic task scheduled', {
|
|
243
|
-
taskName,
|
|
244
|
-
scheduledFor: scheduledTime.toISOString()
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Alarm handler (called automatically when alarm triggers)
|
|
249
|
-
async alarm(): Promise<void> {
|
|
250
|
-
try {
|
|
251
|
-
const alarmContext = await this.state.storage.get<{
|
|
252
|
-
name: string;
|
|
253
|
-
data: any;
|
|
254
|
-
}>('alarm:context');
|
|
255
|
-
|
|
256
|
-
if (!alarmContext) {
|
|
257
|
-
this.env.logger.warn('No alarm context found');
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
this.env.logger.info('Alarm triggered', { name: alarmContext.name, data: alarmContext.data });
|
|
262
|
-
|
|
263
|
-
switch (alarmContext.name) {
|
|
264
|
-
case 'periodic-count':
|
|
265
|
-
const newCount = await this.incrementCounter();
|
|
266
|
-
this.env.logger.info('Incremented count via alarm', { newCount });
|
|
267
|
-
await this.schedulePeriodicTask('periodic-count', alarmContext.data.intervalSeconds);
|
|
268
|
-
break;
|
|
269
|
-
|
|
270
|
-
case 'cleanup':
|
|
271
|
-
await this.clearMessages();
|
|
272
|
-
this.env.logger.info('Completed cleanup task via alarm');
|
|
273
|
-
await this.schedulePeriodicTask('cleanup', alarmContext.data.intervalSeconds);
|
|
274
|
-
break;
|
|
275
|
-
|
|
276
|
-
default:
|
|
277
|
-
this.env.logger.warn('Unknown alarm type', { alarmType: alarmContext.name });
|
|
278
|
-
}
|
|
279
|
-
} catch (error) {
|
|
280
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
281
|
-
this.env.logger.error('Error in alarm handler', { error: errorMessage });
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// === Required Test Methods ===
|
|
286
|
-
|
|
287
|
-
async processUserData(userData: any): Promise<{ success: boolean; userId?: string; error?: string }> {
|
|
288
|
-
try {
|
|
289
|
-
if (!userData.userId || !userData.email) {
|
|
290
|
-
return { success: false, error: 'Missing required fields' };
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Increment counter
|
|
294
|
-
await this.incrementCounter();
|
|
295
|
-
|
|
296
|
-
// Save to bucket
|
|
297
|
-
await this.saveToBucket(`user:${userData.userId}`, userData);
|
|
298
|
-
|
|
299
|
-
// Cache the result
|
|
300
|
-
await this.cacheResult(`user:${userData.userId}`, userData);
|
|
301
|
-
|
|
302
|
-
// Send to queue (if configured)
|
|
303
|
-
await this.sendToQueue({ type: 'user_processed', userId: userData.userId });
|
|
304
|
-
|
|
305
|
-
return { success: true, userId: userData.userId };
|
|
306
|
-
} catch (error) {
|
|
307
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
308
|
-
return { success: false, error: errorMessage };
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
async getUserData(userId: string): Promise<{ success: boolean; data?: any; error?: string }> {
|
|
313
|
-
try {
|
|
314
|
-
// Try cache first
|
|
315
|
-
const cached = await this.getCachedResult(`user:${userId}`);
|
|
316
|
-
if (cached.success) {
|
|
317
|
-
return cached;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Try bucket
|
|
321
|
-
const bucketResult = await this.loadFromBucket(`user:${userId}`);
|
|
322
|
-
if (bucketResult.success) {
|
|
323
|
-
// Cache for future requests
|
|
324
|
-
await this.cacheResult(`user:${userId}`, bucketResult.data);
|
|
325
|
-
return bucketResult;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return { success: false, error: 'User not found' };
|
|
329
|
-
} catch (error) {
|
|
330
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
331
|
-
return { success: false, error: errorMessage };
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
async expensiveComputation(input: number): Promise<number> {
|
|
336
|
-
const cacheKey = `compute:${input}`;
|
|
337
|
-
|
|
338
|
-
// Try cache first
|
|
339
|
-
const cached = await this.getCachedResult(cacheKey);
|
|
340
|
-
if (cached.success) {
|
|
341
|
-
return cached.data;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Simulate expensive computation as expected by tests
|
|
345
|
-
const result = Math.pow(input, 2) + Math.sqrt(input);
|
|
346
|
-
|
|
347
|
-
// Cache the result
|
|
348
|
-
await this.cacheResult(cacheKey, result);
|
|
349
|
-
|
|
350
|
-
return result;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
async batchProcessMessages(messages: string[]): Promise<{ processed: number; errors: string[] }> {
|
|
354
|
-
let processed = 0;
|
|
355
|
-
const errors: string[] = [];
|
|
356
|
-
|
|
357
|
-
for (const message of messages) {
|
|
358
|
-
try {
|
|
359
|
-
await this.processMessage(message);
|
|
360
|
-
processed++;
|
|
361
|
-
} catch (error) {
|
|
362
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
363
|
-
errors.push(errorMessage);
|
|
364
|
-
this.env.logger.error('Failed to process message', { message, error: errorMessage });
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return { processed, errors };
|
|
369
|
-
}
|
|
370
|
-
}
|
|
70
|
+
}
|
|
@@ -8,264 +8,61 @@ import { Env } from './raindrop.gen';
|
|
|
8
8
|
export default class extends Each<BucketEventNotification, Env> {
|
|
9
9
|
async process(message: Message<BucketEventNotification>): Promise<void> {
|
|
10
10
|
const event = message.body;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
|
|
12
|
+
this.env.logger.info('Bucket event received', {
|
|
13
13
|
action: event.action,
|
|
14
14
|
bucket: event.bucket,
|
|
15
|
-
|
|
15
|
+
key: event.object.key,
|
|
16
16
|
size: event.object.size,
|
|
17
17
|
eTag: event.object.eTag,
|
|
18
|
-
eventTime: event.eventTime || new Date().toISOString(),
|
|
19
|
-
timestamp: new Date().toISOString()
|
|
20
18
|
});
|
|
21
19
|
|
|
20
|
+
// Handle different event types
|
|
22
21
|
switch (event.action) {
|
|
23
22
|
case 'ObjectCreated:Put':
|
|
24
|
-
await this.
|
|
23
|
+
await this.handleUpload(event);
|
|
25
24
|
break;
|
|
26
|
-
|
|
25
|
+
|
|
27
26
|
case 'ObjectRemoved:Delete':
|
|
28
|
-
await this.
|
|
27
|
+
await this.handleDeletion(event);
|
|
29
28
|
break;
|
|
30
|
-
|
|
29
|
+
|
|
31
30
|
case 'ObjectCreated:Post':
|
|
32
|
-
await this.
|
|
31
|
+
await this.handleMultipartUpload(event);
|
|
33
32
|
break;
|
|
34
|
-
|
|
35
|
-
default:
|
|
36
|
-
console.log('Unhandled event type:', event.action);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// === File Upload Handler ===
|
|
41
|
-
private async handleFileUpload(event: BucketEventNotification): Promise<void> {
|
|
42
|
-
try {
|
|
43
|
-
console.log(`Processing uploaded file: ${event.object.key}`);
|
|
44
|
-
|
|
45
|
-
// Example: Extract file information
|
|
46
|
-
const fileInfo = {
|
|
47
|
-
key: event.object.key,
|
|
48
|
-
size: event.object.size,
|
|
49
|
-
eTag: event.object.eTag,
|
|
50
|
-
uploadedAt: new Date().toISOString()
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
console.log('File info:', fileInfo);
|
|
54
|
-
|
|
55
|
-
// Example: Call an actor to process the file
|
|
56
|
-
// const processor = this.env.FILE_PROCESSOR_ACTOR;
|
|
57
|
-
// await processor.postMessage({
|
|
58
|
-
// type: 'processFile',
|
|
59
|
-
// data: fileInfo
|
|
60
|
-
// });
|
|
61
33
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// await metadataCache.put(
|
|
65
|
-
// `file:${event.object.key}`,
|
|
66
|
-
// JSON.stringify(fileInfo),
|
|
67
|
-
// { expirationTtl: 86400 } // 24 hours
|
|
68
|
-
// );
|
|
69
|
-
|
|
70
|
-
// Example: Send notification to queue
|
|
71
|
-
// const notificationQueue = this.env.NOTIFICATION_QUEUE;
|
|
72
|
-
// await notificationQueue.send({
|
|
73
|
-
// body: JSON.stringify({
|
|
74
|
-
// type: 'file_uploaded',
|
|
75
|
-
// fileInfo,
|
|
76
|
-
// timestamp: new Date().toISOString()
|
|
77
|
-
// })
|
|
78
|
-
// });
|
|
79
|
-
|
|
80
|
-
// Example: Content type detection (would need additional bucket.get() call)
|
|
81
|
-
// For now, we'll skip content-type based processing since it's not in the event
|
|
82
|
-
await this.triggerFileProcessing(event);
|
|
83
|
-
|
|
84
|
-
} catch (error) {
|
|
85
|
-
console.error('Error handling file upload:', error);
|
|
86
|
-
|
|
87
|
-
// Example: Send error notification
|
|
88
|
-
// const errorQueue = this.env.ERROR_QUEUE;
|
|
89
|
-
// await errorQueue.send({
|
|
90
|
-
// body: JSON.stringify({
|
|
91
|
-
// type: 'file_upload_error',
|
|
92
|
-
// error: error.message,
|
|
93
|
-
// fileInfo: {
|
|
94
|
-
// key: event.object.key,
|
|
95
|
-
// bucket: event.bucket
|
|
96
|
-
// },
|
|
97
|
-
// timestamp: new Date().toISOString()
|
|
98
|
-
// })
|
|
99
|
-
// });
|
|
34
|
+
default:
|
|
35
|
+
this.env.logger.warn('Unhandled event type', { action: event.action });
|
|
100
36
|
}
|
|
101
37
|
}
|
|
102
38
|
|
|
103
|
-
// ===
|
|
104
|
-
private async handleFileDeletion(event: BucketEventNotification): Promise<void> {
|
|
105
|
-
console.log(`Processing deleted file: ${event.object.key}`);
|
|
106
|
-
|
|
107
|
-
// Example: Clean up related data
|
|
108
|
-
// const metadataCache = this.env.FILE_METADATA_KV;
|
|
109
|
-
// await metadataCache.delete(`file:${event.object.key}`);
|
|
110
|
-
|
|
111
|
-
// Example: Notify other services
|
|
112
|
-
// const cleanupQueue = this.env.CLEANUP_QUEUE;
|
|
113
|
-
// await cleanupQueue.send({
|
|
114
|
-
// body: JSON.stringify({
|
|
115
|
-
// type: 'file_deleted',
|
|
116
|
-
// fileKey: event.object.key,
|
|
117
|
-
// timestamp: new Date().toISOString()
|
|
118
|
-
// })
|
|
119
|
-
// });
|
|
120
|
-
|
|
121
|
-
// Example: Update search index
|
|
122
|
-
// if (this.env.SMART_BUCKET) {
|
|
123
|
-
// try {
|
|
124
|
-
// // Remove from search index
|
|
125
|
-
// await this.env.SMART_BUCKET.delete({
|
|
126
|
-
// key: event.object.key
|
|
127
|
-
// });
|
|
128
|
-
// console.log(`Removed ${event.object.key} from search index`);
|
|
129
|
-
// } catch (error) {
|
|
130
|
-
// console.error('Failed to remove from search index:', error);
|
|
131
|
-
// }
|
|
132
|
-
// }
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// === Multi-part Upload Handler ===
|
|
136
|
-
private async handleMultiPartUpload(event: BucketEventNotification): Promise<void> {
|
|
137
|
-
console.log(`Processing multipart upload: ${event.object.key}`);
|
|
138
|
-
|
|
139
|
-
// Example: Trigger post-upload processing
|
|
140
|
-
// const postProcessor = this.env.POST_UPLOAD_ACTOR;
|
|
141
|
-
// await postProcessor.postMessage({
|
|
142
|
-
// type: 'processMultipartUpload',
|
|
143
|
-
// data: {
|
|
144
|
-
// key: event.object.key,
|
|
145
|
-
// size: event.object.size,
|
|
146
|
-
// eTag: event.object.eTag
|
|
147
|
-
// }
|
|
148
|
-
// });
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// === Image Processing Example ===
|
|
152
|
-
private async triggerImageProcessing(event: BucketEventNotification): Promise<void> {
|
|
153
|
-
console.log(`Triggering image processing for: ${event.object.key}`);
|
|
154
|
-
|
|
155
|
-
// Example: Call image processing actor
|
|
156
|
-
// const imageProcessor = this.env.IMAGE_PROCESSOR_ACTOR;
|
|
157
|
-
// await imageProcessor.postMessage({
|
|
158
|
-
// type: 'generateThumbnails',
|
|
159
|
-
// data: {
|
|
160
|
-
// sourceKey: event.object.key,
|
|
161
|
-
// bucket: event.bucket,
|
|
162
|
-
// eTag: event.object.eTag
|
|
163
|
-
// }
|
|
164
|
-
// });
|
|
165
|
-
|
|
166
|
-
// Example: Extract EXIF data
|
|
167
|
-
// const exifExtractor = this.env.EXIF_EXTRACTOR_ACTOR;
|
|
168
|
-
// await exifExtractor.postMessage({
|
|
169
|
-
// type: 'extractExif',
|
|
170
|
-
// data: { key: event.object.key }
|
|
171
|
-
// });
|
|
172
|
-
}
|
|
39
|
+
// === Add Your Event Handlers Here ===
|
|
173
40
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// const documentProcessor = this.env.DOCUMENT_PROCESSOR_ACTOR;
|
|
180
|
-
// await documentProcessor.postMessage({
|
|
181
|
-
// type: 'extractAndIndex',
|
|
182
|
-
// data: {
|
|
183
|
-
// key: event.object.key,
|
|
184
|
-
// bucket: event.bucket,
|
|
185
|
-
// eTag: event.object.eTag
|
|
186
|
-
// }
|
|
187
|
-
// });
|
|
188
|
-
|
|
189
|
-
// Example: Generate document summary
|
|
190
|
-
// const summarizer = this.env.DOCUMENT_SUMMARIZER_ACTOR;
|
|
191
|
-
// await summarizer.postMessage({
|
|
192
|
-
// type: 'summarize',
|
|
193
|
-
// data: { key: event.object.key }
|
|
194
|
-
// });
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// === Generic File Processing ===
|
|
198
|
-
private async triggerFileProcessing(event: BucketEventNotification): Promise<void> {
|
|
199
|
-
console.log(`Triggering generic file processing for: ${event.object.key}`);
|
|
200
|
-
|
|
201
|
-
// Content type detection would require fetching the object
|
|
202
|
-
// For now, we'll trigger generic processing
|
|
203
|
-
// const fileProcessor = this.env.FILE_PROCESSOR_ACTOR;
|
|
204
|
-
// await fileProcessor.postMessage({
|
|
205
|
-
// type: 'processFile',
|
|
206
|
-
// data: {
|
|
207
|
-
// key: event.object.key,
|
|
208
|
-
// bucket: event.bucket,
|
|
209
|
-
// eTag: event.object.eTag
|
|
210
|
-
// }
|
|
211
|
-
// });
|
|
212
|
-
}
|
|
41
|
+
private async handleUpload(event: BucketEventNotification): Promise<void> {
|
|
42
|
+
this.env.logger.info('Processing file upload', {
|
|
43
|
+
key: event.object.key,
|
|
44
|
+
size: event.object.size,
|
|
45
|
+
});
|
|
213
46
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (!contentType) return false;
|
|
217
|
-
|
|
218
|
-
const documentTypes = [
|
|
219
|
-
'application/pdf',
|
|
220
|
-
'application/msword',
|
|
221
|
-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
222
|
-
'text/plain',
|
|
223
|
-
'text/markdown',
|
|
224
|
-
'text/csv'
|
|
225
|
-
];
|
|
226
|
-
|
|
227
|
-
return documentTypes.includes(contentType);
|
|
47
|
+
// Add your upload processing logic here
|
|
48
|
+
// Example: trigger processing, update index, send notifications
|
|
228
49
|
}
|
|
229
50
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
console.log(`Batch processing ${events.length} files`);
|
|
235
|
-
|
|
236
|
-
// Group by file extension or other criteria
|
|
237
|
-
const grouped = events.reduce((acc, event) => {
|
|
238
|
-
const key = event.object.key;
|
|
239
|
-
const extension = key.split('.').pop() || 'unknown';
|
|
240
|
-
if (!acc[extension]) acc[extension] = [];
|
|
241
|
-
acc[extension].push(event);
|
|
242
|
-
return acc;
|
|
243
|
-
}, {} as Record<string, BucketEventNotification[]>);
|
|
51
|
+
private async handleDeletion(event: BucketEventNotification): Promise<void> {
|
|
52
|
+
this.env.logger.info('Processing file deletion', {
|
|
53
|
+
key: event.object.key,
|
|
54
|
+
});
|
|
244
55
|
|
|
245
|
-
//
|
|
246
|
-
|
|
247
|
-
console.log(`Processing ${files.length} files with extension: ${extension}`);
|
|
248
|
-
|
|
249
|
-
if (['jpg', 'jpeg', 'png', 'gif'].includes(extension)) {
|
|
250
|
-
// Process images in batch
|
|
251
|
-
// const batchProcessor = this.env.IMAGE_BATCH_PROCESSOR;
|
|
252
|
-
// await batchProcessor.postMessage({
|
|
253
|
-
// type: 'batchProcess',
|
|
254
|
-
// data: files.map(f => ({ key: f.object.key, bucket: f.bucket }))
|
|
255
|
-
// });
|
|
256
|
-
}
|
|
257
|
-
}
|
|
56
|
+
// Add your deletion logic here
|
|
57
|
+
// Example: clean up related data, update index, notify systems
|
|
258
58
|
}
|
|
259
59
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return { valid: false, reason: 'File too large' };
|
|
266
|
-
}
|
|
60
|
+
private async handleMultipartUpload(event: BucketEventNotification): Promise<void> {
|
|
61
|
+
this.env.logger.info('Processing multipart upload', {
|
|
62
|
+
key: event.object.key,
|
|
63
|
+
size: event.object.size,
|
|
64
|
+
});
|
|
267
65
|
|
|
268
|
-
//
|
|
269
|
-
return { valid: true };
|
|
66
|
+
// Add your multipart upload logic here
|
|
270
67
|
}
|
|
271
|
-
}
|
|
68
|
+
}
|