@bubblelab/bubble-core 0.1.201 → 0.1.202
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/dist/bubble-bundle.d.ts +203 -182
- package/dist/bubble-factory.d.ts.map +1 -1
- package/dist/bubble-factory.js +4 -0
- package/dist/bubble-factory.js.map +1 -1
- package/dist/bubbles/service-bubble/agi-inc.d.ts +134 -134
- package/dist/bubbles/service-bubble/agi-inc.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/agi-inc.js +4 -6
- package/dist/bubbles/service-bubble/agi-inc.js.map +1 -1
- package/dist/bubbles/service-bubble/ai-agent.d.ts +74 -74
- package/dist/bubbles/service-bubble/airtable.d.ts +154 -154
- package/dist/bubbles/service-bubble/airtable.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/airtable.js +8 -13
- package/dist/bubbles/service-bubble/airtable.js.map +1 -1
- package/dist/bubbles/service-bubble/apify/actors/google-maps-scraper.d.ts +10 -10
- package/dist/bubbles/service-bubble/apify/actors/instagram-hashtag-scraper.d.ts +8 -8
- package/dist/bubbles/service-bubble/apify/actors/instagram-scraper.d.ts +24 -24
- package/dist/bubbles/service-bubble/apify/actors/linkedin-posts-search.d.ts +26 -26
- package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.d.ts +56 -56
- package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-posts.d.ts +76 -76
- package/dist/bubbles/service-bubble/apify/actors/tiktok-scraper.d.ts +20 -20
- package/dist/bubbles/service-bubble/apify/actors/twitter-scraper.d.ts +26 -26
- package/dist/bubbles/service-bubble/apify/actors/youtube-scraper.d.ts +8 -8
- package/dist/bubbles/service-bubble/apify/apify-scraper.schema.d.ts +208 -208
- package/dist/bubbles/service-bubble/apify/apify.d.ts +34 -34
- package/dist/bubbles/service-bubble/ashby/ashby.d.ts +120 -120
- package/dist/bubbles/service-bubble/ashby/ashby.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/ashby/ashby.js +8 -10
- package/dist/bubbles/service-bubble/ashby/ashby.js.map +1 -1
- package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +86 -86
- package/dist/bubbles/service-bubble/attio/attio.d.ts +76 -76
- package/dist/bubbles/service-bubble/attio/attio.schema.d.ts +54 -54
- package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +64 -64
- package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +38 -38
- package/dist/bubbles/service-bubble/confluence/confluence.d.ts +54 -54
- package/dist/bubbles/service-bubble/confluence/confluence.schema.d.ts +26 -26
- package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +118 -118
- package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/crustdata/crustdata.js +16 -17
- package/dist/bubbles/service-bubble/crustdata/crustdata.js.map +1 -1
- package/dist/bubbles/service-bubble/crustdata/crustdata.schema.d.ts +102 -102
- package/dist/bubbles/service-bubble/eleven-labs.d.ts +56 -56
- package/dist/bubbles/service-bubble/eleven-labs.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/eleven-labs.js +12 -14
- package/dist/bubbles/service-bubble/eleven-labs.js.map +1 -1
- package/dist/bubbles/service-bubble/firecrawl.d.ts +468 -468
- package/dist/bubbles/service-bubble/firecrawl.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/firecrawl.js +3 -12
- package/dist/bubbles/service-bubble/firecrawl.js.map +1 -1
- package/dist/bubbles/service-bubble/followupboss.d.ts +534 -534
- package/dist/bubbles/service-bubble/followupboss.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/followupboss.js +12 -13
- package/dist/bubbles/service-bubble/followupboss.js.map +1 -1
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +295 -295
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.js +11 -12
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.js.map +1 -1
- package/dist/bubbles/service-bubble/fullenrich/fullenrich.schema.d.ts +160 -160
- package/dist/bubbles/service-bubble/github.d.ts +144 -144
- package/dist/bubbles/service-bubble/gmail.d.ts +248 -248
- package/dist/bubbles/service-bubble/google-calendar.d.ts +64 -64
- package/dist/bubbles/service-bubble/google-calendar.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/google-calendar.js +10 -11
- package/dist/bubbles/service-bubble/google-calendar.js.map +1 -1
- package/dist/bubbles/service-bubble/google-drive.d.ts +154 -148
- package/dist/bubbles/service-bubble/google-drive.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/google-drive.js +8 -1
- package/dist/bubbles/service-bubble/google-drive.js.map +1 -1
- package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +52 -52
- package/dist/bubbles/service-bubble/google-sheets/google-sheets.schema.d.ts +30 -30
- package/dist/bubbles/service-bubble/hello-world.d.ts +4 -4
- package/dist/bubbles/service-bubble/http.d.ts +14 -14
- package/dist/bubbles/service-bubble/hubspot/hubspot.d.ts +47 -47
- package/dist/bubbles/service-bubble/hubspot/hubspot.schema.d.ts +12 -12
- package/dist/bubbles/service-bubble/insforge-db.d.ts +16 -16
- package/dist/bubbles/service-bubble/insforge-db.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/insforge-db.js +24 -26
- package/dist/bubbles/service-bubble/insforge-db.js.map +1 -1
- package/dist/bubbles/service-bubble/jira/jira.d.ts +91 -91
- package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +69 -69
- package/dist/bubbles/service-bubble/linear/linear.d.ts +49 -49
- package/dist/bubbles/service-bubble/linear/linear.schema.d.ts +33 -33
- package/dist/bubbles/service-bubble/notion/notion.d.ts +444 -444
- package/dist/bubbles/service-bubble/notion/property-schemas.d.ts +8 -8
- package/dist/bubbles/service-bubble/postgresql.d.ts +16 -16
- package/dist/bubbles/service-bubble/posthog/posthog.d.ts +43 -43
- package/dist/bubbles/service-bubble/posthog/posthog.schema.d.ts +51 -51
- package/dist/bubbles/service-bubble/resend.d.ts +20 -20
- package/dist/bubbles/service-bubble/resend.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/resend.js +8 -13
- package/dist/bubbles/service-bubble/resend.js.map +1 -1
- package/dist/bubbles/service-bubble/s3/index.d.ts +4 -0
- package/dist/bubbles/service-bubble/s3/index.d.ts.map +1 -0
- package/dist/bubbles/service-bubble/s3/index.js +4 -0
- package/dist/bubbles/service-bubble/s3/index.js.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.d.ts +301 -0
- package/dist/bubbles/service-bubble/s3/s3.d.ts.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.js +320 -0
- package/dist/bubbles/service-bubble/s3/s3.js.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.schema.d.ts +262 -0
- package/dist/bubbles/service-bubble/s3/s3.schema.d.ts.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.schema.js +212 -0
- package/dist/bubbles/service-bubble/s3/s3.schema.js.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.utils.d.ts +17 -0
- package/dist/bubbles/service-bubble/s3/s3.utils.d.ts.map +1 -0
- package/dist/bubbles/service-bubble/s3/s3.utils.js +46 -0
- package/dist/bubbles/service-bubble/s3/s3.utils.js.map +1 -0
- package/dist/bubbles/service-bubble/sendsafely/sendsafely.d.ts +22 -22
- package/dist/bubbles/service-bubble/sendsafely/sendsafely.schema.d.ts +14 -14
- package/dist/bubbles/service-bubble/slack/slack.d.ts +554 -554
- package/dist/bubbles/service-bubble/storage.d.ts +60 -60
- package/dist/bubbles/service-bubble/stripe/stripe.d.ts +224 -224
- package/dist/bubbles/service-bubble/stripe/stripe.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/stripe/stripe.js +5 -7
- package/dist/bubbles/service-bubble/stripe/stripe.js.map +1 -1
- package/dist/bubbles/service-bubble/stripe/stripe.schema.d.ts +131 -131
- package/dist/bubbles/service-bubble/telegram.d.ts +414 -414
- package/dist/bubbles/service-bubble/telegram.d.ts.map +1 -1
- package/dist/bubbles/service-bubble/telegram.js +3 -3
- package/dist/bubbles/service-bubble/telegram.js.map +1 -1
- package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +40 -40
- package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.schema.d.ts +34 -34
- package/dist/bubbles/tool-bubble/browser-tools/_shared/schema.d.ts +2 -2
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/schema.d.ts +3 -3
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/schema.d.ts +2 -2
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/schema.d.ts +2 -2
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/schema.d.ts +2 -2
- package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/code-edit-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +104 -104
- package/dist/bubbles/tool-bubble/get-bubble-details-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/get-trigger-detail-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +20 -20
- package/dist/bubbles/tool-bubble/instagram-tool.d.ts +16 -16
- package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +919 -919
- package/dist/bubbles/tool-bubble/list-airtable-bases-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-airtable-tables-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-bubbles-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/list-capabilities-tool.d.ts +12 -12
- package/dist/bubbles/tool-bubble/people-search-tool.d.ts +84 -84
- package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +30 -30
- package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +4 -4
- package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +12 -12
- package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +76 -76
- package/dist/bubbles/tool-bubble/tool-template.d.ts +4 -4
- package/dist/bubbles/tool-bubble/twitter-tool.d.ts +170 -170
- package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +8 -8
- package/dist/bubbles/tool-bubble/web-search-tool.d.ts +12 -12
- package/dist/bubbles/tool-bubble/yc-scraper-tool.d.ts +42 -42
- package/dist/bubbles/tool-bubble/youtube-tool.d.ts +28 -28
- package/dist/bubbles/workflow-bubble/database-analyzer.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +16 -16
- package/dist/bubbles/workflow-bubble/parse-document.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +66 -66
- package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +24 -24
- package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +4 -4
- package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +76 -76
- package/dist/bubbles/workflow-bubble/slack-notifier.workflow.d.ts +4 -4
- package/dist/bubbles.json +489 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { ServiceBubble } from '../../../types/service-bubble-class.js';
|
|
2
|
+
import type { BubbleContext } from '../../../types/bubble.js';
|
|
3
|
+
import { CredentialType } from '@bubblelab/shared-schemas';
|
|
4
|
+
import { type S3ParamsInput, type S3Result } from './s3.schema.js';
|
|
5
|
+
/**
|
|
6
|
+
* S3 Storage Service Bubble
|
|
7
|
+
*
|
|
8
|
+
* S3-compatible storage operations for file management.
|
|
9
|
+
* Works with AWS S3, MinIO, DigitalOcean Spaces, Backblaze B2, and other
|
|
10
|
+
* S3-compatible providers via a configurable endpoint.
|
|
11
|
+
*
|
|
12
|
+
* Uses a single bundled credential (S3_CRED) containing:
|
|
13
|
+
* - accessKeyId, secretAccessKey (required)
|
|
14
|
+
* - endpoint (optional, for non-AWS providers)
|
|
15
|
+
* - region (optional, defaults to us-east-1)
|
|
16
|
+
*/
|
|
17
|
+
export declare class S3Bubble<T extends S3ParamsInput = S3ParamsInput> extends ServiceBubble<T, Extract<S3Result, {
|
|
18
|
+
operation: T['operation'];
|
|
19
|
+
}>> {
|
|
20
|
+
static readonly service = "s3";
|
|
21
|
+
static readonly authType: "apikey";
|
|
22
|
+
static readonly bubbleName = "s3-storage";
|
|
23
|
+
static readonly type: "service";
|
|
24
|
+
static readonly schema: import("zod").ZodDiscriminatedUnion<"operation", [import("zod").ZodObject<{
|
|
25
|
+
operation: import("zod").ZodLiteral<"getUploadUrl">;
|
|
26
|
+
bucketName: import("zod").ZodString;
|
|
27
|
+
fileName: import("zod").ZodString;
|
|
28
|
+
region: import("zod").ZodOptional<import("zod").ZodString>;
|
|
29
|
+
expirationMinutes: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
30
|
+
contentType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
31
|
+
userId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
32
|
+
credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
|
|
33
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
34
|
+
operation: "getUploadUrl";
|
|
35
|
+
bucketName: string;
|
|
36
|
+
fileName: string;
|
|
37
|
+
expirationMinutes: number;
|
|
38
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
39
|
+
region?: string | undefined;
|
|
40
|
+
contentType?: string | undefined;
|
|
41
|
+
userId?: string | undefined;
|
|
42
|
+
}, {
|
|
43
|
+
operation: "getUploadUrl";
|
|
44
|
+
bucketName: string;
|
|
45
|
+
fileName: string;
|
|
46
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
47
|
+
region?: string | undefined;
|
|
48
|
+
contentType?: string | undefined;
|
|
49
|
+
expirationMinutes?: number | undefined;
|
|
50
|
+
userId?: string | undefined;
|
|
51
|
+
}>, import("zod").ZodObject<{
|
|
52
|
+
operation: import("zod").ZodLiteral<"getFile">;
|
|
53
|
+
bucketName: import("zod").ZodString;
|
|
54
|
+
fileName: import("zod").ZodString;
|
|
55
|
+
region: import("zod").ZodOptional<import("zod").ZodString>;
|
|
56
|
+
expirationMinutes: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
57
|
+
userId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
58
|
+
credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
|
|
59
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
60
|
+
operation: "getFile";
|
|
61
|
+
bucketName: string;
|
|
62
|
+
fileName: string;
|
|
63
|
+
expirationMinutes: number;
|
|
64
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
65
|
+
region?: string | undefined;
|
|
66
|
+
userId?: string | undefined;
|
|
67
|
+
}, {
|
|
68
|
+
operation: "getFile";
|
|
69
|
+
bucketName: string;
|
|
70
|
+
fileName: string;
|
|
71
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
72
|
+
region?: string | undefined;
|
|
73
|
+
expirationMinutes?: number | undefined;
|
|
74
|
+
userId?: string | undefined;
|
|
75
|
+
}>, import("zod").ZodObject<{
|
|
76
|
+
operation: import("zod").ZodLiteral<"deleteFile">;
|
|
77
|
+
bucketName: import("zod").ZodString;
|
|
78
|
+
fileName: import("zod").ZodString;
|
|
79
|
+
region: import("zod").ZodOptional<import("zod").ZodString>;
|
|
80
|
+
credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
|
|
81
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
82
|
+
operation: "deleteFile";
|
|
83
|
+
bucketName: string;
|
|
84
|
+
fileName: string;
|
|
85
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
86
|
+
region?: string | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
operation: "deleteFile";
|
|
89
|
+
bucketName: string;
|
|
90
|
+
fileName: string;
|
|
91
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
92
|
+
region?: string | undefined;
|
|
93
|
+
}>, import("zod").ZodObject<{
|
|
94
|
+
operation: import("zod").ZodLiteral<"updateFile">;
|
|
95
|
+
bucketName: import("zod").ZodDefault<import("zod").ZodString>;
|
|
96
|
+
fileName: import("zod").ZodString;
|
|
97
|
+
region: import("zod").ZodOptional<import("zod").ZodString>;
|
|
98
|
+
contentType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
99
|
+
fileContent: import("zod").ZodString;
|
|
100
|
+
credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
|
|
101
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
102
|
+
operation: "updateFile";
|
|
103
|
+
bucketName: string;
|
|
104
|
+
fileName: string;
|
|
105
|
+
fileContent: string;
|
|
106
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
107
|
+
region?: string | undefined;
|
|
108
|
+
contentType?: string | undefined;
|
|
109
|
+
}, {
|
|
110
|
+
operation: "updateFile";
|
|
111
|
+
fileName: string;
|
|
112
|
+
fileContent: string;
|
|
113
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
114
|
+
region?: string | undefined;
|
|
115
|
+
contentType?: string | undefined;
|
|
116
|
+
bucketName?: string | undefined;
|
|
117
|
+
}>, import("zod").ZodObject<{
|
|
118
|
+
operation: import("zod").ZodLiteral<"getMultipleUploadUrls">;
|
|
119
|
+
bucketName: import("zod").ZodString;
|
|
120
|
+
pdfFileName: import("zod").ZodString;
|
|
121
|
+
pageCount: import("zod").ZodNumber;
|
|
122
|
+
region: import("zod").ZodOptional<import("zod").ZodString>;
|
|
123
|
+
expirationMinutes: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
124
|
+
userId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
125
|
+
credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
|
|
126
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
127
|
+
operation: "getMultipleUploadUrls";
|
|
128
|
+
bucketName: string;
|
|
129
|
+
expirationMinutes: number;
|
|
130
|
+
pdfFileName: string;
|
|
131
|
+
pageCount: number;
|
|
132
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
133
|
+
region?: string | undefined;
|
|
134
|
+
userId?: string | undefined;
|
|
135
|
+
}, {
|
|
136
|
+
operation: "getMultipleUploadUrls";
|
|
137
|
+
bucketName: string;
|
|
138
|
+
pdfFileName: string;
|
|
139
|
+
pageCount: number;
|
|
140
|
+
credentials?: Partial<Record<CredentialType, string>> | undefined;
|
|
141
|
+
region?: string | undefined;
|
|
142
|
+
expirationMinutes?: number | undefined;
|
|
143
|
+
userId?: string | undefined;
|
|
144
|
+
}>]>;
|
|
145
|
+
static readonly resultSchema: import("zod").ZodDiscriminatedUnion<"operation", [import("zod").ZodObject<{
|
|
146
|
+
operation: import("zod").ZodLiteral<"getUploadUrl">;
|
|
147
|
+
success: import("zod").ZodBoolean;
|
|
148
|
+
uploadUrl: import("zod").ZodOptional<import("zod").ZodString>;
|
|
149
|
+
fileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
150
|
+
contentType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
151
|
+
error: import("zod").ZodString;
|
|
152
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
153
|
+
operation: "getUploadUrl";
|
|
154
|
+
success: boolean;
|
|
155
|
+
error: string;
|
|
156
|
+
contentType?: string | undefined;
|
|
157
|
+
fileName?: string | undefined;
|
|
158
|
+
uploadUrl?: string | undefined;
|
|
159
|
+
}, {
|
|
160
|
+
operation: "getUploadUrl";
|
|
161
|
+
success: boolean;
|
|
162
|
+
error: string;
|
|
163
|
+
contentType?: string | undefined;
|
|
164
|
+
fileName?: string | undefined;
|
|
165
|
+
uploadUrl?: string | undefined;
|
|
166
|
+
}>, import("zod").ZodObject<{
|
|
167
|
+
operation: import("zod").ZodLiteral<"getFile">;
|
|
168
|
+
success: import("zod").ZodBoolean;
|
|
169
|
+
downloadUrl: import("zod").ZodOptional<import("zod").ZodString>;
|
|
170
|
+
fileUrl: import("zod").ZodOptional<import("zod").ZodString>;
|
|
171
|
+
fileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
172
|
+
fileSize: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
173
|
+
contentType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
174
|
+
lastModified: import("zod").ZodOptional<import("zod").ZodString>;
|
|
175
|
+
error: import("zod").ZodString;
|
|
176
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
177
|
+
operation: "getFile";
|
|
178
|
+
success: boolean;
|
|
179
|
+
error: string;
|
|
180
|
+
contentType?: string | undefined;
|
|
181
|
+
fileName?: string | undefined;
|
|
182
|
+
downloadUrl?: string | undefined;
|
|
183
|
+
fileUrl?: string | undefined;
|
|
184
|
+
fileSize?: number | undefined;
|
|
185
|
+
lastModified?: string | undefined;
|
|
186
|
+
}, {
|
|
187
|
+
operation: "getFile";
|
|
188
|
+
success: boolean;
|
|
189
|
+
error: string;
|
|
190
|
+
contentType?: string | undefined;
|
|
191
|
+
fileName?: string | undefined;
|
|
192
|
+
downloadUrl?: string | undefined;
|
|
193
|
+
fileUrl?: string | undefined;
|
|
194
|
+
fileSize?: number | undefined;
|
|
195
|
+
lastModified?: string | undefined;
|
|
196
|
+
}>, import("zod").ZodObject<{
|
|
197
|
+
operation: import("zod").ZodLiteral<"deleteFile">;
|
|
198
|
+
success: import("zod").ZodBoolean;
|
|
199
|
+
fileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
200
|
+
deleted: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
201
|
+
error: import("zod").ZodString;
|
|
202
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
203
|
+
operation: "deleteFile";
|
|
204
|
+
success: boolean;
|
|
205
|
+
error: string;
|
|
206
|
+
deleted?: boolean | undefined;
|
|
207
|
+
fileName?: string | undefined;
|
|
208
|
+
}, {
|
|
209
|
+
operation: "deleteFile";
|
|
210
|
+
success: boolean;
|
|
211
|
+
error: string;
|
|
212
|
+
deleted?: boolean | undefined;
|
|
213
|
+
fileName?: string | undefined;
|
|
214
|
+
}>, import("zod").ZodObject<{
|
|
215
|
+
operation: import("zod").ZodLiteral<"updateFile">;
|
|
216
|
+
success: import("zod").ZodBoolean;
|
|
217
|
+
fileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
218
|
+
updated: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
219
|
+
contentType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
220
|
+
error: import("zod").ZodString;
|
|
221
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
222
|
+
operation: "updateFile";
|
|
223
|
+
success: boolean;
|
|
224
|
+
error: string;
|
|
225
|
+
updated?: boolean | undefined;
|
|
226
|
+
contentType?: string | undefined;
|
|
227
|
+
fileName?: string | undefined;
|
|
228
|
+
}, {
|
|
229
|
+
operation: "updateFile";
|
|
230
|
+
success: boolean;
|
|
231
|
+
error: string;
|
|
232
|
+
updated?: boolean | undefined;
|
|
233
|
+
contentType?: string | undefined;
|
|
234
|
+
fileName?: string | undefined;
|
|
235
|
+
}>, import("zod").ZodObject<{
|
|
236
|
+
operation: import("zod").ZodLiteral<"getMultipleUploadUrls">;
|
|
237
|
+
success: import("zod").ZodBoolean;
|
|
238
|
+
pdfUploadUrl: import("zod").ZodOptional<import("zod").ZodString>;
|
|
239
|
+
pdfFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
240
|
+
pageUploadUrls: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
|
|
241
|
+
pageNumber: import("zod").ZodNumber;
|
|
242
|
+
uploadUrl: import("zod").ZodString;
|
|
243
|
+
fileName: import("zod").ZodString;
|
|
244
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
245
|
+
fileName: string;
|
|
246
|
+
uploadUrl: string;
|
|
247
|
+
pageNumber: number;
|
|
248
|
+
}, {
|
|
249
|
+
fileName: string;
|
|
250
|
+
uploadUrl: string;
|
|
251
|
+
pageNumber: number;
|
|
252
|
+
}>, "many">>;
|
|
253
|
+
error: import("zod").ZodString;
|
|
254
|
+
}, "strip", import("zod").ZodTypeAny, {
|
|
255
|
+
operation: "getMultipleUploadUrls";
|
|
256
|
+
success: boolean;
|
|
257
|
+
error: string;
|
|
258
|
+
pdfFileName?: string | undefined;
|
|
259
|
+
pdfUploadUrl?: string | undefined;
|
|
260
|
+
pageUploadUrls?: {
|
|
261
|
+
fileName: string;
|
|
262
|
+
uploadUrl: string;
|
|
263
|
+
pageNumber: number;
|
|
264
|
+
}[] | undefined;
|
|
265
|
+
}, {
|
|
266
|
+
operation: "getMultipleUploadUrls";
|
|
267
|
+
success: boolean;
|
|
268
|
+
error: string;
|
|
269
|
+
pdfFileName?: string | undefined;
|
|
270
|
+
pdfUploadUrl?: string | undefined;
|
|
271
|
+
pageUploadUrls?: {
|
|
272
|
+
fileName: string;
|
|
273
|
+
uploadUrl: string;
|
|
274
|
+
pageNumber: number;
|
|
275
|
+
}[] | undefined;
|
|
276
|
+
}>]>;
|
|
277
|
+
static readonly shortDescription = "S3-compatible storage operations for file management";
|
|
278
|
+
static readonly longDescription = "\n A comprehensive storage bubble for S3-compatible storage providers.\n Works with AWS S3, MinIO, DigitalOcean Spaces, Backblaze B2, and more.\n Use cases:\n - Generate presigned upload URLs for client-side file uploads\n - Get secure download URLs for file retrieval with authentication\n - Delete files from S3 buckets\n - Update/replace files in S3 buckets (supports base64 encoded content for binary files like images)\n - Manage file access with time-limited URLs\n ";
|
|
279
|
+
static readonly alias = "s3";
|
|
280
|
+
private s3Client;
|
|
281
|
+
constructor(params?: T, context?: BubbleContext, instanceId?: string);
|
|
282
|
+
protected chooseCredential(): string | undefined;
|
|
283
|
+
private initializeS3Client;
|
|
284
|
+
/**
|
|
285
|
+
* Extract the correct region from an S3 PermanentRedirect error.
|
|
286
|
+
* AWS returns the correct endpoint in the error message, e.g.
|
|
287
|
+
* "...endpoint: gymii-test.s3.us-east-2.amazonaws.com"
|
|
288
|
+
*/
|
|
289
|
+
private extractRegionFromRedirectError;
|
|
290
|
+
testCredential(): Promise<boolean>;
|
|
291
|
+
private executeOperation;
|
|
292
|
+
protected performAction(context?: BubbleContext): Promise<Extract<S3Result, {
|
|
293
|
+
operation: T['operation'];
|
|
294
|
+
}>>;
|
|
295
|
+
private getUploadUrl;
|
|
296
|
+
private getFile;
|
|
297
|
+
private deleteFile;
|
|
298
|
+
private updateFile;
|
|
299
|
+
private getMultipleUploadUrls;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=s3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../../../src/bubbles/service-bubble/s3/s3.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;AAGxB;;;;;;;;;;;GAWG;AACH,qBAAa,QAAQ,CACnB,CAAC,SAAS,aAAa,GAAG,aAAa,CACvC,SAAQ,aAAa,CACrB,CAAC,EACD,OAAO,CAAC,QAAQ,EAAE;IAAE,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC,CACjD;IACC,MAAM,CAAC,QAAQ,CAAC,OAAO,QAAQ;IAC/B,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAG,QAAQ,CAAU;IAC7C,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAU;IAC1C,MAAM,CAAC,QAAQ,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAAkB;IACxC,MAAM,CAAC,QAAQ,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAAkB;IAC9C,MAAM,CAAC,QAAQ,CAAC,gBAAgB,0DACyB;IACzD,MAAM,CAAC,QAAQ,CAAC,eAAe,ufAS7B;IACF,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ;IAE7B,OAAO,CAAC,QAAQ,CAAyB;gBAGvC,MAAM,GAAE,CAIF,EACN,OAAO,CAAC,EAAE,aAAa,EACvB,UAAU,CAAC,EAAE,MAAM;IAKrB,SAAS,CAAC,gBAAgB,IAAI,MAAM,GAAG,SAAS;IAYhD,OAAO,CAAC,kBAAkB;IAgC1B;;;;OAIG;IACH,OAAO,CAAC,8BAA8B;IAOzB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;YAsBjC,gBAAgB;cAkBd,aAAa,CAC3B,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,CAAA;KAAE,CAAC,CAAC;YAmC9C,YAAY;YAkCZ,OAAO;YA+CP,UAAU;YAqBV,UAAU;YAyCV,qBAAqB;CA6DpC"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, HeadObjectCommand, ListBucketsCommand, } from '@aws-sdk/client-s3';
|
|
2
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
3
|
+
import { ServiceBubble } from '../../../types/service-bubble-class.js';
|
|
4
|
+
import { CredentialType } from '@bubblelab/shared-schemas';
|
|
5
|
+
import { S3ParamsSchema, S3ResultSchema, } from './s3.schema.js';
|
|
6
|
+
import { parseS3Credential, isBase64 } from './s3.utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* S3 Storage Service Bubble
|
|
9
|
+
*
|
|
10
|
+
* S3-compatible storage operations for file management.
|
|
11
|
+
* Works with AWS S3, MinIO, DigitalOcean Spaces, Backblaze B2, and other
|
|
12
|
+
* S3-compatible providers via a configurable endpoint.
|
|
13
|
+
*
|
|
14
|
+
* Uses a single bundled credential (S3_CRED) containing:
|
|
15
|
+
* - accessKeyId, secretAccessKey (required)
|
|
16
|
+
* - endpoint (optional, for non-AWS providers)
|
|
17
|
+
* - region (optional, defaults to us-east-1)
|
|
18
|
+
*/
|
|
19
|
+
export class S3Bubble extends ServiceBubble {
|
|
20
|
+
static service = 's3';
|
|
21
|
+
static authType = 'apikey';
|
|
22
|
+
static bubbleName = 's3-storage';
|
|
23
|
+
static type = 'service';
|
|
24
|
+
static schema = S3ParamsSchema;
|
|
25
|
+
static resultSchema = S3ResultSchema;
|
|
26
|
+
static shortDescription = 'S3-compatible storage operations for file management';
|
|
27
|
+
static longDescription = `
|
|
28
|
+
A comprehensive storage bubble for S3-compatible storage providers.
|
|
29
|
+
Works with AWS S3, MinIO, DigitalOcean Spaces, Backblaze B2, and more.
|
|
30
|
+
Use cases:
|
|
31
|
+
- Generate presigned upload URLs for client-side file uploads
|
|
32
|
+
- Get secure download URLs for file retrieval with authentication
|
|
33
|
+
- Delete files from S3 buckets
|
|
34
|
+
- Update/replace files in S3 buckets (supports base64 encoded content for binary files like images)
|
|
35
|
+
- Manage file access with time-limited URLs
|
|
36
|
+
`;
|
|
37
|
+
static alias = 's3';
|
|
38
|
+
s3Client = null;
|
|
39
|
+
constructor(params = {
|
|
40
|
+
operation: 'getUploadUrl',
|
|
41
|
+
bucketName: 'my-bucket',
|
|
42
|
+
fileName: 'example.txt',
|
|
43
|
+
}, context, instanceId) {
|
|
44
|
+
super(params, context, instanceId);
|
|
45
|
+
}
|
|
46
|
+
chooseCredential() {
|
|
47
|
+
const { credentials } = this.params;
|
|
48
|
+
if (!credentials || typeof credentials !== 'object') {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return credentials[CredentialType.S3_CRED];
|
|
52
|
+
}
|
|
53
|
+
initializeS3Client(regionOverride) {
|
|
54
|
+
const credentialValue = this.chooseCredential();
|
|
55
|
+
if (!credentialValue) {
|
|
56
|
+
throw new Error('S3 credentials not found. Provide an S3_CRED credential.');
|
|
57
|
+
}
|
|
58
|
+
const creds = parseS3Credential(credentialValue);
|
|
59
|
+
// Region: explicit override > per-operation > credential > default
|
|
60
|
+
const region = regionOverride || this.params.region || creds.region || 'us-east-1';
|
|
61
|
+
const clientConfig = {
|
|
62
|
+
region,
|
|
63
|
+
credentials: {
|
|
64
|
+
accessKeyId: creds.accessKeyId,
|
|
65
|
+
secretAccessKey: creds.secretAccessKey,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
// Only set endpoint for non-AWS providers
|
|
69
|
+
if (creds.endpoint) {
|
|
70
|
+
clientConfig.endpoint = creds.endpoint;
|
|
71
|
+
clientConfig.forcePathStyle = true;
|
|
72
|
+
}
|
|
73
|
+
this.s3Client = new S3Client(clientConfig);
|
|
74
|
+
return creds;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extract the correct region from an S3 PermanentRedirect error.
|
|
78
|
+
* AWS returns the correct endpoint in the error message, e.g.
|
|
79
|
+
* "...endpoint: gymii-test.s3.us-east-2.amazonaws.com"
|
|
80
|
+
*/
|
|
81
|
+
extractRegionFromRedirectError(error) {
|
|
82
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
83
|
+
// Match patterns like "bucketname.s3.us-east-2.amazonaws.com" or just "s3.us-west-1.amazonaws.com"
|
|
84
|
+
const match = message.match(/s3[.-]([a-z0-9-]+)\.amazonaws\.com/);
|
|
85
|
+
return match?.[1];
|
|
86
|
+
}
|
|
87
|
+
async testCredential() {
|
|
88
|
+
const credential = this.chooseCredential();
|
|
89
|
+
if (!credential) {
|
|
90
|
+
throw new Error('S3 credentials not provided');
|
|
91
|
+
}
|
|
92
|
+
const creds = parseS3Credential(credential);
|
|
93
|
+
if (!creds.accessKeyId || !creds.secretAccessKey) {
|
|
94
|
+
throw new Error('S3 credential is missing accessKeyId or secretAccessKey');
|
|
95
|
+
}
|
|
96
|
+
this.initializeS3Client();
|
|
97
|
+
if (!this.s3Client) {
|
|
98
|
+
throw new Error('Failed to initialize S3 client');
|
|
99
|
+
}
|
|
100
|
+
// Actually call S3 to verify the credentials work — let errors propagate
|
|
101
|
+
// so the validator can surface vendor-specific messages
|
|
102
|
+
await this.s3Client.send(new ListBucketsCommand({}));
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
async executeOperation() {
|
|
106
|
+
const { operation } = this.params;
|
|
107
|
+
switch (operation) {
|
|
108
|
+
case 'getUploadUrl':
|
|
109
|
+
return await this.getUploadUrl(this.params);
|
|
110
|
+
case 'getFile':
|
|
111
|
+
return await this.getFile(this.params);
|
|
112
|
+
case 'deleteFile':
|
|
113
|
+
return await this.deleteFile(this.params);
|
|
114
|
+
case 'updateFile':
|
|
115
|
+
return await this.updateFile(this.params);
|
|
116
|
+
case 'getMultipleUploadUrls':
|
|
117
|
+
return await this.getMultipleUploadUrls(this.params);
|
|
118
|
+
default:
|
|
119
|
+
throw new Error(`Unsupported operation: ${operation}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async performAction(context) {
|
|
123
|
+
void context;
|
|
124
|
+
const { operation } = this.params;
|
|
125
|
+
try {
|
|
126
|
+
this.initializeS3Client();
|
|
127
|
+
if (!this.s3Client) {
|
|
128
|
+
throw new Error('Failed to initialize S3 client');
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const result = await this.executeOperation();
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
// Auto-retry on region mismatch (PermanentRedirect)
|
|
136
|
+
const redirectRegion = this.extractRegionFromRedirectError(error);
|
|
137
|
+
if (redirectRegion) {
|
|
138
|
+
console.log(`[S3Bubble] Region redirect detected, retrying with region: ${redirectRegion}`);
|
|
139
|
+
this.initializeS3Client(redirectRegion);
|
|
140
|
+
const result = await this.executeOperation();
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
return {
|
|
148
|
+
operation,
|
|
149
|
+
success: false,
|
|
150
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async getUploadUrl(params) {
|
|
155
|
+
if (!this.s3Client)
|
|
156
|
+
throw new Error('S3 client not initialized');
|
|
157
|
+
// Generate secure filename with timestamp and optional userId for isolation
|
|
158
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
159
|
+
const fileExtension = params.fileName.split('.').pop() || 'bin';
|
|
160
|
+
const baseName = params.fileName.replace(/\.[^/.]+$/, '');
|
|
161
|
+
const sanitizedBaseName = baseName.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
162
|
+
const userPrefix = params.userId ? `${params.userId}/` : '';
|
|
163
|
+
const secureFileName = `${userPrefix}${timestamp}-${sanitizedBaseName}.${fileExtension}`;
|
|
164
|
+
const command = new PutObjectCommand({
|
|
165
|
+
Bucket: params.bucketName,
|
|
166
|
+
Key: secureFileName,
|
|
167
|
+
ContentType: params.contentType,
|
|
168
|
+
});
|
|
169
|
+
const uploadUrl = await getSignedUrl(this.s3Client, command, {
|
|
170
|
+
expiresIn: params.expirationMinutes * 60,
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
operation: 'getUploadUrl',
|
|
174
|
+
success: true,
|
|
175
|
+
uploadUrl,
|
|
176
|
+
fileName: secureFileName,
|
|
177
|
+
contentType: params.contentType,
|
|
178
|
+
error: '',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async getFile(params) {
|
|
182
|
+
if (!this.s3Client)
|
|
183
|
+
throw new Error('S3 client not initialized');
|
|
184
|
+
const command = new GetObjectCommand({
|
|
185
|
+
Bucket: params.bucketName,
|
|
186
|
+
Key: params.fileName,
|
|
187
|
+
});
|
|
188
|
+
const downloadUrl = await getSignedUrl(this.s3Client, command, {
|
|
189
|
+
expiresIn: params.expirationMinutes * 60,
|
|
190
|
+
});
|
|
191
|
+
// Also get file metadata
|
|
192
|
+
try {
|
|
193
|
+
const headCommand = new HeadObjectCommand({
|
|
194
|
+
Bucket: params.bucketName,
|
|
195
|
+
Key: params.fileName,
|
|
196
|
+
});
|
|
197
|
+
const metadata = await this.s3Client.send(headCommand);
|
|
198
|
+
return {
|
|
199
|
+
operation: 'getFile',
|
|
200
|
+
success: true,
|
|
201
|
+
downloadUrl,
|
|
202
|
+
fileUrl: downloadUrl,
|
|
203
|
+
fileName: params.fileName,
|
|
204
|
+
fileSize: metadata.ContentLength,
|
|
205
|
+
contentType: metadata.ContentType,
|
|
206
|
+
lastModified: metadata.LastModified?.toISOString(),
|
|
207
|
+
error: '',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// If metadata fetch fails, still return the download URL
|
|
212
|
+
return {
|
|
213
|
+
operation: 'getFile',
|
|
214
|
+
success: true,
|
|
215
|
+
downloadUrl,
|
|
216
|
+
fileUrl: downloadUrl,
|
|
217
|
+
fileName: params.fileName,
|
|
218
|
+
error: '',
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async deleteFile(params) {
|
|
223
|
+
if (!this.s3Client)
|
|
224
|
+
throw new Error('S3 client not initialized');
|
|
225
|
+
const command = new DeleteObjectCommand({
|
|
226
|
+
Bucket: params.bucketName,
|
|
227
|
+
Key: params.fileName,
|
|
228
|
+
});
|
|
229
|
+
await this.s3Client.send(command);
|
|
230
|
+
return {
|
|
231
|
+
operation: 'deleteFile',
|
|
232
|
+
success: true,
|
|
233
|
+
fileName: params.fileName,
|
|
234
|
+
deleted: true,
|
|
235
|
+
error: '',
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
async updateFile(params) {
|
|
239
|
+
if (!this.s3Client)
|
|
240
|
+
throw new Error('S3 client not initialized');
|
|
241
|
+
// Generate secure filename with timestamp
|
|
242
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
243
|
+
const fileExtension = params.fileName.split('.').pop() || 'bin';
|
|
244
|
+
const baseName = params.fileName.replace(/\.[^/.]+$/, '');
|
|
245
|
+
const sanitizedBaseName = baseName.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
246
|
+
const secureFileName = `${timestamp}-${crypto.randomUUID()}-${sanitizedBaseName}.${fileExtension}`;
|
|
247
|
+
// Handle base64 encoded content
|
|
248
|
+
let bodyContent;
|
|
249
|
+
if (isBase64(params.fileContent)) {
|
|
250
|
+
const base64Data = params.fileContent.replace(/^data:[^;]+;base64,/, '');
|
|
251
|
+
bodyContent = Buffer.from(base64Data, 'base64');
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
bodyContent = params.fileContent;
|
|
255
|
+
}
|
|
256
|
+
const command = new PutObjectCommand({
|
|
257
|
+
Bucket: params.bucketName,
|
|
258
|
+
Key: secureFileName,
|
|
259
|
+
ContentType: params.contentType,
|
|
260
|
+
Body: bodyContent,
|
|
261
|
+
});
|
|
262
|
+
await this.s3Client.send(command);
|
|
263
|
+
return {
|
|
264
|
+
operation: 'updateFile',
|
|
265
|
+
success: true,
|
|
266
|
+
fileName: secureFileName,
|
|
267
|
+
updated: true,
|
|
268
|
+
contentType: params.contentType,
|
|
269
|
+
error: '',
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
async getMultipleUploadUrls(params) {
|
|
273
|
+
if (!this.s3Client)
|
|
274
|
+
throw new Error('S3 client not initialized');
|
|
275
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
276
|
+
const userPrefix = params.userId ? `${params.userId}/` : '';
|
|
277
|
+
// Generate secure PDF filename
|
|
278
|
+
const pdfExtension = params.pdfFileName.split('.').pop() || 'pdf';
|
|
279
|
+
const pdfBaseName = params.pdfFileName
|
|
280
|
+
.replace(/\.[^/.]+$/, '')
|
|
281
|
+
.replace(/[^a-zA-Z0-9-_]/g, '_');
|
|
282
|
+
const securePdfFileName = `${userPrefix}${timestamp}-${pdfBaseName}.${pdfExtension}`;
|
|
283
|
+
// Generate PDF upload URL
|
|
284
|
+
const pdfCommand = new PutObjectCommand({
|
|
285
|
+
Bucket: params.bucketName,
|
|
286
|
+
Key: securePdfFileName,
|
|
287
|
+
ContentType: 'application/pdf',
|
|
288
|
+
});
|
|
289
|
+
const pdfUploadUrl = await getSignedUrl(this.s3Client, pdfCommand, {
|
|
290
|
+
expiresIn: params.expirationMinutes * 60,
|
|
291
|
+
});
|
|
292
|
+
// Generate page image upload URLs
|
|
293
|
+
const pageUploadUrls = [];
|
|
294
|
+
for (let pageNum = 1; pageNum <= params.pageCount; pageNum++) {
|
|
295
|
+
const pageFileName = `${userPrefix}${timestamp}-${pdfBaseName}_page${pageNum}.jpeg`;
|
|
296
|
+
const pageCommand = new PutObjectCommand({
|
|
297
|
+
Bucket: params.bucketName,
|
|
298
|
+
Key: pageFileName,
|
|
299
|
+
ContentType: 'image/jpeg',
|
|
300
|
+
});
|
|
301
|
+
const pageUploadUrl = await getSignedUrl(this.s3Client, pageCommand, {
|
|
302
|
+
expiresIn: params.expirationMinutes * 60,
|
|
303
|
+
});
|
|
304
|
+
pageUploadUrls.push({
|
|
305
|
+
pageNumber: pageNum,
|
|
306
|
+
uploadUrl: pageUploadUrl,
|
|
307
|
+
fileName: pageFileName,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
operation: 'getMultipleUploadUrls',
|
|
312
|
+
success: true,
|
|
313
|
+
pdfUploadUrl,
|
|
314
|
+
pdfFileName: securePdfFileName,
|
|
315
|
+
pageUploadUrls,
|
|
316
|
+
error: '',
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=s3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.js","sourceRoot":"","sources":["../../../../src/bubbles/service-bubble/s3/s3.ts"],"names":[],"mappings":"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"}
|