@bubblelab/bubble-core 0.1.201 → 0.1.203

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 (199) hide show
  1. package/dist/bubble-bundle.d.ts +171 -150
  2. package/dist/bubble-factory.d.ts.map +1 -1
  3. package/dist/bubble-factory.js +4 -0
  4. package/dist/bubble-factory.js.map +1 -1
  5. package/dist/bubbles/service-bubble/agi-inc.d.ts +112 -112
  6. package/dist/bubbles/service-bubble/agi-inc.d.ts.map +1 -1
  7. package/dist/bubbles/service-bubble/agi-inc.js +4 -6
  8. package/dist/bubbles/service-bubble/agi-inc.js.map +1 -1
  9. package/dist/bubbles/service-bubble/ai-agent.d.ts +74 -74
  10. package/dist/bubbles/service-bubble/ai-agent.js +3 -3
  11. package/dist/bubbles/service-bubble/ai-agent.js.map +1 -1
  12. package/dist/bubbles/service-bubble/airtable.d.ts +158 -158
  13. package/dist/bubbles/service-bubble/airtable.d.ts.map +1 -1
  14. package/dist/bubbles/service-bubble/airtable.js +8 -13
  15. package/dist/bubbles/service-bubble/airtable.js.map +1 -1
  16. package/dist/bubbles/service-bubble/apify/actors/instagram-hashtag-scraper.d.ts +2 -2
  17. package/dist/bubbles/service-bubble/apify/actors/instagram-scraper.d.ts +8 -8
  18. package/dist/bubbles/service-bubble/apify/actors/linkedin-jobs-scraper.d.ts +2 -2
  19. package/dist/bubbles/service-bubble/apify/actors/linkedin-posts-search.d.ts +22 -22
  20. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.d.ts +38 -38
  21. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-posts.d.ts +52 -52
  22. package/dist/bubbles/service-bubble/apify/actors/tiktok-scraper.d.ts +6 -6
  23. package/dist/bubbles/service-bubble/apify/actors/twitter-scraper.d.ts +12 -12
  24. package/dist/bubbles/service-bubble/apify/actors/youtube-scraper.d.ts +12 -12
  25. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.d.ts +126 -126
  26. package/dist/bubbles/service-bubble/apify/apify.d.ts +30 -30
  27. package/dist/bubbles/service-bubble/apify/apify.d.ts.map +1 -1
  28. package/dist/bubbles/service-bubble/apify/apify.js +10 -11
  29. package/dist/bubbles/service-bubble/apify/apify.js.map +1 -1
  30. package/dist/bubbles/service-bubble/ashby/ashby.d.ts +90 -90
  31. package/dist/bubbles/service-bubble/ashby/ashby.d.ts.map +1 -1
  32. package/dist/bubbles/service-bubble/ashby/ashby.js +8 -10
  33. package/dist/bubbles/service-bubble/ashby/ashby.js.map +1 -1
  34. package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +2 -2
  35. package/dist/bubbles/service-bubble/attio/attio.d.ts +70 -70
  36. package/dist/bubbles/service-bubble/attio/attio.js +11 -12
  37. package/dist/bubbles/service-bubble/attio/attio.js.map +1 -1
  38. package/dist/bubbles/service-bubble/attio/attio.schema.d.ts +6 -6
  39. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +58 -58
  40. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts.map +1 -1
  41. package/dist/bubbles/service-bubble/browserbase/browserbase.js +3 -8
  42. package/dist/bubbles/service-bubble/browserbase/browserbase.js.map +1 -1
  43. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +1 -1
  44. package/dist/bubbles/service-bubble/confluence/confluence.d.ts +43 -43
  45. package/dist/bubbles/service-bubble/confluence/confluence.d.ts.map +1 -1
  46. package/dist/bubbles/service-bubble/confluence/confluence.js +4 -6
  47. package/dist/bubbles/service-bubble/confluence/confluence.js.map +1 -1
  48. package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +94 -94
  49. package/dist/bubbles/service-bubble/crustdata/crustdata.js +16 -17
  50. package/dist/bubbles/service-bubble/crustdata/crustdata.js.map +1 -1
  51. package/dist/bubbles/service-bubble/eleven-labs.d.ts +48 -48
  52. package/dist/bubbles/service-bubble/eleven-labs.d.ts.map +1 -1
  53. package/dist/bubbles/service-bubble/eleven-labs.js +12 -14
  54. package/dist/bubbles/service-bubble/eleven-labs.js.map +1 -1
  55. package/dist/bubbles/service-bubble/firecrawl.d.ts +304 -304
  56. package/dist/bubbles/service-bubble/firecrawl.d.ts.map +1 -1
  57. package/dist/bubbles/service-bubble/firecrawl.js +3 -12
  58. package/dist/bubbles/service-bubble/firecrawl.js.map +1 -1
  59. package/dist/bubbles/service-bubble/followupboss.d.ts +260 -260
  60. package/dist/bubbles/service-bubble/followupboss.d.ts.map +1 -1
  61. package/dist/bubbles/service-bubble/followupboss.js +12 -13
  62. package/dist/bubbles/service-bubble/followupboss.js.map +1 -1
  63. package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +44 -44
  64. package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts.map +1 -1
  65. package/dist/bubbles/service-bubble/fullenrich/fullenrich.js +11 -12
  66. package/dist/bubbles/service-bubble/fullenrich/fullenrich.js.map +1 -1
  67. package/dist/bubbles/service-bubble/github.d.ts +102 -102
  68. package/dist/bubbles/service-bubble/github.d.ts.map +1 -1
  69. package/dist/bubbles/service-bubble/github.js +14 -17
  70. package/dist/bubbles/service-bubble/github.js.map +1 -1
  71. package/dist/bubbles/service-bubble/gmail.d.ts +332 -332
  72. package/dist/bubbles/service-bubble/gmail.d.ts.map +1 -1
  73. package/dist/bubbles/service-bubble/gmail.js +10 -12
  74. package/dist/bubbles/service-bubble/gmail.js.map +1 -1
  75. package/dist/bubbles/service-bubble/google-calendar.d.ts +136 -136
  76. package/dist/bubbles/service-bubble/google-calendar.d.ts.map +1 -1
  77. package/dist/bubbles/service-bubble/google-calendar.js +10 -11
  78. package/dist/bubbles/service-bubble/google-calendar.js.map +1 -1
  79. package/dist/bubbles/service-bubble/google-drive.d.ts +116 -110
  80. package/dist/bubbles/service-bubble/google-drive.d.ts.map +1 -1
  81. package/dist/bubbles/service-bubble/google-drive.js +19 -13
  82. package/dist/bubbles/service-bubble/google-drive.js.map +1 -1
  83. package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +52 -52
  84. package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts.map +1 -1
  85. package/dist/bubbles/service-bubble/google-sheets/google-sheets.js +6 -8
  86. package/dist/bubbles/service-bubble/google-sheets/google-sheets.js.map +1 -1
  87. package/dist/bubbles/service-bubble/hello-world.d.ts +4 -4
  88. package/dist/bubbles/service-bubble/http.d.ts +12 -12
  89. package/dist/bubbles/service-bubble/hubspot/hubspot.d.ts +20 -20
  90. package/dist/bubbles/service-bubble/hubspot/hubspot.js +9 -10
  91. package/dist/bubbles/service-bubble/hubspot/hubspot.js.map +1 -1
  92. package/dist/bubbles/service-bubble/insforge-db.d.ts +12 -12
  93. package/dist/bubbles/service-bubble/insforge-db.d.ts.map +1 -1
  94. package/dist/bubbles/service-bubble/insforge-db.js +24 -26
  95. package/dist/bubbles/service-bubble/insforge-db.js.map +1 -1
  96. package/dist/bubbles/service-bubble/jira/jira.d.ts +74 -74
  97. package/dist/bubbles/service-bubble/jira/jira.d.ts.map +1 -1
  98. package/dist/bubbles/service-bubble/jira/jira.js +5 -7
  99. package/dist/bubbles/service-bubble/jira/jira.js.map +1 -1
  100. package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +36 -36
  101. package/dist/bubbles/service-bubble/linear/linear.d.ts +44 -44
  102. package/dist/bubbles/service-bubble/linear/linear.d.ts.map +1 -1
  103. package/dist/bubbles/service-bubble/linear/linear.js +5 -7
  104. package/dist/bubbles/service-bubble/linear/linear.js.map +1 -1
  105. package/dist/bubbles/service-bubble/notion/notion.d.ts +408 -408
  106. package/dist/bubbles/service-bubble/notion/notion.d.ts.map +1 -1
  107. package/dist/bubbles/service-bubble/notion/notion.js +5 -11
  108. package/dist/bubbles/service-bubble/notion/notion.js.map +1 -1
  109. package/dist/bubbles/service-bubble/notion/property-schemas.d.ts +8 -8
  110. package/dist/bubbles/service-bubble/postgresql.d.ts +12 -12
  111. package/dist/bubbles/service-bubble/posthog/posthog.d.ts +33 -33
  112. package/dist/bubbles/service-bubble/posthog/posthog.d.ts.map +1 -1
  113. package/dist/bubbles/service-bubble/posthog/posthog.js +17 -18
  114. package/dist/bubbles/service-bubble/posthog/posthog.js.map +1 -1
  115. package/dist/bubbles/service-bubble/posthog/posthog.schema.d.ts +14 -14
  116. package/dist/bubbles/service-bubble/resend.d.ts +32 -32
  117. package/dist/bubbles/service-bubble/resend.d.ts.map +1 -1
  118. package/dist/bubbles/service-bubble/resend.js +8 -13
  119. package/dist/bubbles/service-bubble/resend.js.map +1 -1
  120. package/dist/bubbles/service-bubble/s3/index.d.ts +4 -0
  121. package/dist/bubbles/service-bubble/s3/index.d.ts.map +1 -0
  122. package/dist/bubbles/service-bubble/s3/index.js +4 -0
  123. package/dist/bubbles/service-bubble/s3/index.js.map +1 -0
  124. package/dist/bubbles/service-bubble/s3/s3.d.ts +306 -0
  125. package/dist/bubbles/service-bubble/s3/s3.d.ts.map +1 -0
  126. package/dist/bubbles/service-bubble/s3/s3.js +369 -0
  127. package/dist/bubbles/service-bubble/s3/s3.js.map +1 -0
  128. package/dist/bubbles/service-bubble/s3/s3.schema.d.ts +265 -0
  129. package/dist/bubbles/service-bubble/s3/s3.schema.d.ts.map +1 -0
  130. package/dist/bubbles/service-bubble/s3/s3.schema.js +213 -0
  131. package/dist/bubbles/service-bubble/s3/s3.schema.js.map +1 -0
  132. package/dist/bubbles/service-bubble/s3/s3.utils.d.ts +17 -0
  133. package/dist/bubbles/service-bubble/s3/s3.utils.d.ts.map +1 -0
  134. package/dist/bubbles/service-bubble/s3/s3.utils.js +46 -0
  135. package/dist/bubbles/service-bubble/s3/s3.utils.js.map +1 -0
  136. package/dist/bubbles/service-bubble/sendsafely/sendsafely.d.ts +18 -18
  137. package/dist/bubbles/service-bubble/sendsafely/sendsafely.d.ts.map +1 -1
  138. package/dist/bubbles/service-bubble/sendsafely/sendsafely.js +4 -9
  139. package/dist/bubbles/service-bubble/sendsafely/sendsafely.js.map +1 -1
  140. package/dist/bubbles/service-bubble/slack/slack.d.ts +378 -378
  141. package/dist/bubbles/service-bubble/slack/slack.d.ts.map +1 -1
  142. package/dist/bubbles/service-bubble/slack/slack.js +4 -3
  143. package/dist/bubbles/service-bubble/slack/slack.js.map +1 -1
  144. package/dist/bubbles/service-bubble/storage.d.ts +92 -92
  145. package/dist/bubbles/service-bubble/stripe/stripe.d.ts +123 -123
  146. package/dist/bubbles/service-bubble/stripe/stripe.d.ts.map +1 -1
  147. package/dist/bubbles/service-bubble/stripe/stripe.js +5 -7
  148. package/dist/bubbles/service-bubble/stripe/stripe.js.map +1 -1
  149. package/dist/bubbles/service-bubble/stripe/stripe.schema.d.ts +28 -28
  150. package/dist/bubbles/service-bubble/telegram.d.ts +116 -116
  151. package/dist/bubbles/service-bubble/telegram.d.ts.map +1 -1
  152. package/dist/bubbles/service-bubble/telegram.js +3 -3
  153. package/dist/bubbles/service-bubble/telegram.js.map +1 -1
  154. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +32 -32
  155. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.schema.d.ts +8 -8
  156. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.d.ts +4 -4
  157. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.d.ts +4 -4
  158. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.d.ts +4 -4
  159. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.d.ts +4 -4
  160. package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
  161. package/dist/bubbles/tool-bubble/chart-js-tool.d.ts +8 -8
  162. package/dist/bubbles/tool-bubble/code-edit-tool.d.ts +4 -4
  163. package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +14 -14
  164. package/dist/bubbles/tool-bubble/get-bubble-details-tool.d.ts +4 -4
  165. package/dist/bubbles/tool-bubble/get-trigger-detail-tool.d.ts +4 -4
  166. package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +8 -8
  167. package/dist/bubbles/tool-bubble/instagram-tool.d.ts +8 -8
  168. package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +405 -405
  169. package/dist/bubbles/tool-bubble/list-airtable-bases-tool.d.ts +4 -4
  170. package/dist/bubbles/tool-bubble/list-airtable-tables-tool.d.ts +4 -4
  171. package/dist/bubbles/tool-bubble/list-bubbles-tool.d.ts +4 -4
  172. package/dist/bubbles/tool-bubble/list-capabilities-tool.d.ts +4 -4
  173. package/dist/bubbles/tool-bubble/people-search-tool.d.ts +14 -14
  174. package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +4 -4
  175. package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +4 -4
  176. package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +8 -8
  177. package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +68 -68
  178. package/dist/bubbles/tool-bubble/tool-template.d.ts +4 -4
  179. package/dist/bubbles/tool-bubble/twitter-tool.d.ts +142 -142
  180. package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +8 -8
  181. package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +8 -8
  182. package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +8 -8
  183. package/dist/bubbles/tool-bubble/web-search-tool.d.ts +8 -8
  184. package/dist/bubbles/tool-bubble/yc-scraper-tool.d.ts +12 -12
  185. package/dist/bubbles/tool-bubble/youtube-tool.d.ts +28 -28
  186. package/dist/bubbles/workflow-bubble/database-analyzer.workflow.d.ts +4 -4
  187. package/dist/bubbles/workflow-bubble/generate-document.workflow.d.ts +16 -16
  188. package/dist/bubbles/workflow-bubble/parse-document.workflow.d.ts +8 -8
  189. package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +66 -66
  190. package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +24 -24
  191. package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +4 -4
  192. package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +28 -28
  193. package/dist/bubbles/workflow-bubble/slack-notifier.workflow.d.ts +4 -4
  194. package/dist/bubbles.json +493 -3
  195. package/dist/index.d.ts +1 -0
  196. package/dist/index.d.ts.map +1 -1
  197. package/dist/index.js +1 -0
  198. package/dist/index.js.map +1 -1
  199. package/package.json +2 -2
@@ -0,0 +1,369 @@
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 ||
61
+ this.params.region ||
62
+ creds.region ||
63
+ 'us-east-1';
64
+ const clientConfig = {
65
+ region,
66
+ credentials: {
67
+ accessKeyId: creds.accessKeyId,
68
+ secretAccessKey: creds.secretAccessKey,
69
+ },
70
+ };
71
+ // Only set endpoint for non-AWS providers
72
+ if (creds.endpoint) {
73
+ clientConfig.endpoint = creds.endpoint;
74
+ clientConfig.forcePathStyle = true;
75
+ }
76
+ this.s3Client = new S3Client(clientConfig);
77
+ return creds;
78
+ }
79
+ /**
80
+ * Extract the correct region from an S3 PermanentRedirect error.
81
+ * AWS returns the correct endpoint in the error message, e.g.
82
+ * "...endpoint: gymii-test.s3.us-east-2.amazonaws.com"
83
+ */
84
+ extractRegionFromRedirectError(error) {
85
+ // AWS SDK v3 PermanentRedirect errors include region in multiple places
86
+ const err = error;
87
+ // Check if this is a PermanentRedirect error
88
+ if (err?.name !== 'PermanentRedirect' && err?.Code !== 'PermanentRedirect') {
89
+ return undefined;
90
+ }
91
+ // 1. Check $response headers for x-amz-bucket-region
92
+ const response = err?.$response;
93
+ const headers = response?.headers;
94
+ if (headers?.['x-amz-bucket-region']) {
95
+ return headers['x-amz-bucket-region'];
96
+ }
97
+ // 2. Extract region from Endpoint in error message or body
98
+ const message = error instanceof Error ? error.message : String(error);
99
+ const regionFromEndpoint = message.match(/s3[.-]([a-z0-9-]+)\.amazonaws\.com/);
100
+ if (regionFromEndpoint?.[1]) {
101
+ return regionFromEndpoint[1];
102
+ }
103
+ // 3. Check Endpoint field on the error object itself
104
+ const endpoint = err?.Endpoint;
105
+ if (endpoint) {
106
+ const match = endpoint.match(/s3[.-]([a-z0-9-]+)\.amazonaws\.com/);
107
+ if (match?.[1])
108
+ return match[1];
109
+ }
110
+ return undefined;
111
+ }
112
+ async testCredential() {
113
+ const credential = this.chooseCredential();
114
+ if (!credential) {
115
+ throw new Error('S3 credentials not provided');
116
+ }
117
+ const creds = parseS3Credential(credential);
118
+ if (!creds.accessKeyId || !creds.secretAccessKey) {
119
+ throw new Error('S3 credential is missing accessKeyId or secretAccessKey');
120
+ }
121
+ this.initializeS3Client();
122
+ if (!this.s3Client) {
123
+ throw new Error('Failed to initialize S3 client');
124
+ }
125
+ // Actually call S3 to verify the credentials work — let errors propagate
126
+ // so the validator can surface vendor-specific messages
127
+ await this.s3Client.send(new ListBucketsCommand({}));
128
+ return true;
129
+ }
130
+ async executeOperation() {
131
+ const { operation } = this.params;
132
+ switch (operation) {
133
+ case 'getUploadUrl':
134
+ return await this.getUploadUrl(this.params);
135
+ case 'getFile':
136
+ return await this.getFile(this.params);
137
+ case 'deleteFile':
138
+ return await this.deleteFile(this.params);
139
+ case 'updateFile':
140
+ return await this.updateFile(this.params);
141
+ case 'getMultipleUploadUrls':
142
+ return await this.getMultipleUploadUrls(this.params);
143
+ default:
144
+ throw new Error(`Unsupported operation: ${operation}`);
145
+ }
146
+ }
147
+ async performAction(context) {
148
+ void context;
149
+ const { operation } = this.params;
150
+ try {
151
+ this.initializeS3Client();
152
+ if (!this.s3Client) {
153
+ throw new Error('Failed to initialize S3 client');
154
+ }
155
+ try {
156
+ const result = await this.executeOperation();
157
+ return result;
158
+ }
159
+ catch (error) {
160
+ // Auto-retry on region mismatch (PermanentRedirect)
161
+ const redirectRegion = this.extractRegionFromRedirectError(error);
162
+ if (redirectRegion) {
163
+ console.log(`[S3Bubble] Region redirect detected, retrying with region: ${redirectRegion}`);
164
+ this.initializeS3Client(redirectRegion);
165
+ const result = await this.executeOperation();
166
+ return result;
167
+ }
168
+ throw error;
169
+ }
170
+ }
171
+ catch (error) {
172
+ // Surface S3-specific error names (e.g., NotFound, NoSuchKey, AccessDenied)
173
+ const err = error;
174
+ const errorName = err?.name || err?.Code || '';
175
+ const errorMessage = error instanceof Error ? error.message : '';
176
+ // Map common S3 error names to human-readable messages
177
+ const s3ErrorMessages = {
178
+ NotFound: 'The specified file does not exist',
179
+ NoSuchKey: 'The specified file does not exist',
180
+ NoSuchBucket: 'The specified bucket does not exist',
181
+ AccessDenied: 'Access denied — check your S3 credentials and bucket permissions',
182
+ PermanentRedirect: 'Bucket is in a different region — set the correct region',
183
+ InvalidAccessKeyId: 'The AWS access key ID is invalid',
184
+ SignatureDoesNotMatch: 'The secret access key is invalid',
185
+ };
186
+ const friendlyMessage = s3ErrorMessages[errorName];
187
+ const displayError = friendlyMessage
188
+ || (errorMessage && errorMessage !== errorName ? `${errorName}: ${errorMessage}` : '')
189
+ || errorName
190
+ || 'Unknown error occurred';
191
+ return {
192
+ operation,
193
+ success: false,
194
+ error: displayError,
195
+ };
196
+ }
197
+ }
198
+ async getUploadUrl(params) {
199
+ if (!this.s3Client)
200
+ throw new Error('S3 client not initialized');
201
+ // Generate secure filename with timestamp and optional userId for isolation
202
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
203
+ const fileExtension = params.fileName.split('.').pop() || 'bin';
204
+ const baseName = params.fileName.replace(/\.[^/.]+$/, '');
205
+ const sanitizedBaseName = baseName.replace(/[^a-zA-Z0-9-_]/g, '_');
206
+ const userPrefix = params.userId ? `${params.userId}/` : '';
207
+ const secureFileName = `${userPrefix}${timestamp}-${sanitizedBaseName}.${fileExtension}`;
208
+ const command = new PutObjectCommand({
209
+ Bucket: params.bucketName,
210
+ Key: secureFileName,
211
+ ContentType: params.contentType,
212
+ });
213
+ const uploadUrl = await getSignedUrl(this.s3Client, command, {
214
+ expiresIn: params.expirationMinutes * 60,
215
+ });
216
+ return {
217
+ operation: 'getUploadUrl',
218
+ success: true,
219
+ uploadUrl,
220
+ fileName: secureFileName,
221
+ contentType: params.contentType,
222
+ error: '',
223
+ };
224
+ }
225
+ async getFile(params) {
226
+ if (!this.s3Client)
227
+ throw new Error('S3 client not initialized');
228
+ // Check if file exists and get metadata
229
+ const headCommand = new HeadObjectCommand({
230
+ Bucket: params.bucketName,
231
+ Key: params.fileName,
232
+ });
233
+ const metadata = await this.s3Client.send(headCommand);
234
+ // Generate presigned download URL
235
+ const command = new GetObjectCommand({
236
+ Bucket: params.bucketName,
237
+ Key: params.fileName,
238
+ });
239
+ const downloadUrl = await getSignedUrl(this.s3Client, command, {
240
+ expiresIn: params.expirationMinutes * 60,
241
+ });
242
+ return {
243
+ operation: 'getFile',
244
+ success: true,
245
+ downloadUrl,
246
+ fileUrl: downloadUrl,
247
+ fileName: params.fileName,
248
+ fileSize: metadata.ContentLength,
249
+ contentType: metadata.ContentType,
250
+ lastModified: metadata.LastModified?.toISOString(),
251
+ error: '',
252
+ };
253
+ }
254
+ async deleteFile(params) {
255
+ if (!this.s3Client)
256
+ throw new Error('S3 client not initialized');
257
+ const command = new DeleteObjectCommand({
258
+ Bucket: params.bucketName,
259
+ Key: params.fileName,
260
+ });
261
+ await this.s3Client.send(command);
262
+ return {
263
+ operation: 'deleteFile',
264
+ success: true,
265
+ fileName: params.fileName,
266
+ deleted: true,
267
+ error: '',
268
+ };
269
+ }
270
+ /** Check if a fileName already has a secure prefix (timestamp-UUID pattern) */
271
+ isSecureFileName(fileName) {
272
+ // Matches patterns like "2026-02-28T00-42-37-653Z-b2f0c3bd-7d29-492c-bea1-394042d33ee2-..."
273
+ // or with userId prefix like "alice/2026-02-28T00-42-37-653Z-..."
274
+ const nameWithoutUserPrefix = fileName.includes('/')
275
+ ? fileName.split('/').slice(1).join('/')
276
+ : fileName;
277
+ return /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-[0-9a-f]{8}-/.test(nameWithoutUserPrefix);
278
+ }
279
+ async updateFile(params) {
280
+ if (!this.s3Client)
281
+ throw new Error('S3 client not initialized');
282
+ let key;
283
+ if (this.isSecureFileName(params.fileName)) {
284
+ // Already a secure filename (from a previous operation) — use as-is
285
+ key = params.fileName;
286
+ }
287
+ else {
288
+ // Generate new secure filename
289
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
290
+ const fileExtension = params.fileName.split('.').pop() || 'bin';
291
+ const baseName = params.fileName.replace(/\.[^/.]+$/, '');
292
+ const sanitizedBaseName = baseName.replace(/[^a-zA-Z0-9-_]/g, '_');
293
+ const userPrefix = params.userId ? `${params.userId}/` : '';
294
+ key = `${userPrefix}${timestamp}-${crypto.randomUUID()}-${sanitizedBaseName}.${fileExtension}`;
295
+ }
296
+ // Handle base64 encoded content
297
+ let bodyContent;
298
+ if (isBase64(params.fileContent)) {
299
+ const base64Data = params.fileContent.replace(/^data:[^;]+;base64,/, '');
300
+ bodyContent = Buffer.from(base64Data, 'base64');
301
+ }
302
+ else {
303
+ bodyContent = params.fileContent;
304
+ }
305
+ const command = new PutObjectCommand({
306
+ Bucket: params.bucketName,
307
+ Key: key,
308
+ ContentType: params.contentType,
309
+ Body: bodyContent,
310
+ });
311
+ await this.s3Client.send(command);
312
+ return {
313
+ operation: 'updateFile',
314
+ success: true,
315
+ fileName: key,
316
+ updated: true,
317
+ contentType: params.contentType,
318
+ error: '',
319
+ };
320
+ }
321
+ async getMultipleUploadUrls(params) {
322
+ if (!this.s3Client)
323
+ throw new Error('S3 client not initialized');
324
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
325
+ const userPrefix = params.userId ? `${params.userId}/` : '';
326
+ // Generate secure PDF filename
327
+ const pdfExtension = params.pdfFileName.split('.').pop() || 'pdf';
328
+ const pdfBaseName = params.pdfFileName
329
+ .replace(/\.[^/.]+$/, '')
330
+ .replace(/[^a-zA-Z0-9-_]/g, '_');
331
+ const securePdfFileName = `${userPrefix}${timestamp}-${pdfBaseName}.${pdfExtension}`;
332
+ // Generate PDF upload URL
333
+ const pdfCommand = new PutObjectCommand({
334
+ Bucket: params.bucketName,
335
+ Key: securePdfFileName,
336
+ ContentType: 'application/pdf',
337
+ });
338
+ const pdfUploadUrl = await getSignedUrl(this.s3Client, pdfCommand, {
339
+ expiresIn: params.expirationMinutes * 60,
340
+ });
341
+ // Generate page image upload URLs
342
+ const pageUploadUrls = [];
343
+ for (let pageNum = 1; pageNum <= params.pageCount; pageNum++) {
344
+ const pageFileName = `${userPrefix}${timestamp}-${pdfBaseName}_page${pageNum}.jpeg`;
345
+ const pageCommand = new PutObjectCommand({
346
+ Bucket: params.bucketName,
347
+ Key: pageFileName,
348
+ ContentType: 'image/jpeg',
349
+ });
350
+ const pageUploadUrl = await getSignedUrl(this.s3Client, pageCommand, {
351
+ expiresIn: params.expirationMinutes * 60,
352
+ });
353
+ pageUploadUrls.push({
354
+ pageNumber: pageNum,
355
+ uploadUrl: pageUploadUrl,
356
+ fileName: pageFileName,
357
+ });
358
+ }
359
+ return {
360
+ operation: 'getMultipleUploadUrls',
361
+ success: true,
362
+ pdfUploadUrl,
363
+ pdfFileName: securePdfFileName,
364
+ pageUploadUrls,
365
+ error: '',
366
+ };
367
+ }
368
+ }
369
+ //# 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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"}
@@ -0,0 +1,265 @@
1
+ import { z } from 'zod';
2
+ import { CredentialType } from '@bubblelab/shared-schemas';
3
+ export declare const S3ParamsSchema: z.ZodDiscriminatedUnion<"operation", [z.ZodObject<{
4
+ operation: z.ZodLiteral<"getUploadUrl">;
5
+ bucketName: z.ZodString;
6
+ fileName: z.ZodString;
7
+ region: z.ZodOptional<z.ZodString>;
8
+ expirationMinutes: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
9
+ contentType: z.ZodOptional<z.ZodString>;
10
+ userId: z.ZodOptional<z.ZodString>;
11
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodNativeEnum<typeof CredentialType>, z.ZodString>>;
12
+ }, "strip", z.ZodTypeAny, {
13
+ operation: "getUploadUrl";
14
+ bucketName: string;
15
+ fileName: string;
16
+ expirationMinutes: number;
17
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
18
+ contentType?: string | undefined;
19
+ region?: string | undefined;
20
+ userId?: string | undefined;
21
+ }, {
22
+ operation: "getUploadUrl";
23
+ bucketName: string;
24
+ fileName: string;
25
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
26
+ contentType?: string | undefined;
27
+ region?: string | undefined;
28
+ expirationMinutes?: number | undefined;
29
+ userId?: string | undefined;
30
+ }>, z.ZodObject<{
31
+ operation: z.ZodLiteral<"getFile">;
32
+ bucketName: z.ZodString;
33
+ fileName: z.ZodString;
34
+ region: z.ZodOptional<z.ZodString>;
35
+ expirationMinutes: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
36
+ userId: z.ZodOptional<z.ZodString>;
37
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodNativeEnum<typeof CredentialType>, z.ZodString>>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ operation: "getFile";
40
+ bucketName: string;
41
+ fileName: string;
42
+ expirationMinutes: number;
43
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
44
+ region?: string | undefined;
45
+ userId?: string | undefined;
46
+ }, {
47
+ operation: "getFile";
48
+ bucketName: string;
49
+ fileName: string;
50
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
51
+ region?: string | undefined;
52
+ expirationMinutes?: number | undefined;
53
+ userId?: string | undefined;
54
+ }>, z.ZodObject<{
55
+ operation: z.ZodLiteral<"deleteFile">;
56
+ bucketName: z.ZodString;
57
+ fileName: z.ZodString;
58
+ region: z.ZodOptional<z.ZodString>;
59
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodNativeEnum<typeof CredentialType>, z.ZodString>>;
60
+ }, "strip", z.ZodTypeAny, {
61
+ operation: "deleteFile";
62
+ bucketName: string;
63
+ fileName: string;
64
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
65
+ region?: string | undefined;
66
+ }, {
67
+ operation: "deleteFile";
68
+ bucketName: string;
69
+ fileName: string;
70
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
71
+ region?: string | undefined;
72
+ }>, z.ZodObject<{
73
+ operation: z.ZodLiteral<"updateFile">;
74
+ bucketName: z.ZodDefault<z.ZodString>;
75
+ fileName: z.ZodString;
76
+ region: z.ZodOptional<z.ZodString>;
77
+ contentType: z.ZodOptional<z.ZodString>;
78
+ fileContent: z.ZodString;
79
+ userId: z.ZodOptional<z.ZodString>;
80
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodNativeEnum<typeof CredentialType>, z.ZodString>>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ operation: "updateFile";
83
+ bucketName: string;
84
+ fileName: string;
85
+ fileContent: string;
86
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
87
+ contentType?: string | undefined;
88
+ region?: string | undefined;
89
+ userId?: string | undefined;
90
+ }, {
91
+ operation: "updateFile";
92
+ fileName: string;
93
+ fileContent: string;
94
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
95
+ contentType?: string | undefined;
96
+ bucketName?: string | undefined;
97
+ region?: string | undefined;
98
+ userId?: string | undefined;
99
+ }>, z.ZodObject<{
100
+ operation: z.ZodLiteral<"getMultipleUploadUrls">;
101
+ bucketName: z.ZodString;
102
+ pdfFileName: z.ZodString;
103
+ pageCount: z.ZodNumber;
104
+ region: z.ZodOptional<z.ZodString>;
105
+ expirationMinutes: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
106
+ userId: z.ZodOptional<z.ZodString>;
107
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodNativeEnum<typeof CredentialType>, z.ZodString>>;
108
+ }, "strip", z.ZodTypeAny, {
109
+ operation: "getMultipleUploadUrls";
110
+ bucketName: string;
111
+ expirationMinutes: number;
112
+ pdfFileName: string;
113
+ pageCount: number;
114
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
115
+ region?: string | undefined;
116
+ userId?: string | undefined;
117
+ }, {
118
+ operation: "getMultipleUploadUrls";
119
+ bucketName: string;
120
+ pdfFileName: string;
121
+ pageCount: number;
122
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
123
+ region?: string | undefined;
124
+ expirationMinutes?: number | undefined;
125
+ userId?: string | undefined;
126
+ }>]>;
127
+ export declare const S3ResultSchema: z.ZodDiscriminatedUnion<"operation", [z.ZodObject<{
128
+ operation: z.ZodLiteral<"getUploadUrl">;
129
+ success: z.ZodBoolean;
130
+ uploadUrl: z.ZodOptional<z.ZodString>;
131
+ fileName: z.ZodOptional<z.ZodString>;
132
+ contentType: z.ZodOptional<z.ZodString>;
133
+ error: z.ZodString;
134
+ }, "strip", z.ZodTypeAny, {
135
+ error: string;
136
+ success: boolean;
137
+ operation: "getUploadUrl";
138
+ contentType?: string | undefined;
139
+ fileName?: string | undefined;
140
+ uploadUrl?: string | undefined;
141
+ }, {
142
+ error: string;
143
+ success: boolean;
144
+ operation: "getUploadUrl";
145
+ contentType?: string | undefined;
146
+ fileName?: string | undefined;
147
+ uploadUrl?: string | undefined;
148
+ }>, z.ZodObject<{
149
+ operation: z.ZodLiteral<"getFile">;
150
+ success: z.ZodBoolean;
151
+ downloadUrl: z.ZodOptional<z.ZodString>;
152
+ fileUrl: z.ZodOptional<z.ZodString>;
153
+ fileName: z.ZodOptional<z.ZodString>;
154
+ fileSize: z.ZodOptional<z.ZodNumber>;
155
+ contentType: z.ZodOptional<z.ZodString>;
156
+ lastModified: z.ZodOptional<z.ZodString>;
157
+ error: z.ZodString;
158
+ }, "strip", z.ZodTypeAny, {
159
+ error: string;
160
+ success: boolean;
161
+ operation: "getFile";
162
+ contentType?: string | undefined;
163
+ fileName?: string | undefined;
164
+ downloadUrl?: string | undefined;
165
+ fileUrl?: string | undefined;
166
+ fileSize?: number | undefined;
167
+ lastModified?: string | undefined;
168
+ }, {
169
+ error: string;
170
+ success: boolean;
171
+ operation: "getFile";
172
+ contentType?: string | undefined;
173
+ fileName?: string | undefined;
174
+ downloadUrl?: string | undefined;
175
+ fileUrl?: string | undefined;
176
+ fileSize?: number | undefined;
177
+ lastModified?: string | undefined;
178
+ }>, z.ZodObject<{
179
+ operation: z.ZodLiteral<"deleteFile">;
180
+ success: z.ZodBoolean;
181
+ fileName: z.ZodOptional<z.ZodString>;
182
+ deleted: z.ZodOptional<z.ZodBoolean>;
183
+ error: z.ZodString;
184
+ }, "strip", z.ZodTypeAny, {
185
+ error: string;
186
+ success: boolean;
187
+ operation: "deleteFile";
188
+ deleted?: boolean | undefined;
189
+ fileName?: string | undefined;
190
+ }, {
191
+ error: string;
192
+ success: boolean;
193
+ operation: "deleteFile";
194
+ deleted?: boolean | undefined;
195
+ fileName?: string | undefined;
196
+ }>, z.ZodObject<{
197
+ operation: z.ZodLiteral<"updateFile">;
198
+ success: z.ZodBoolean;
199
+ fileName: z.ZodOptional<z.ZodString>;
200
+ updated: z.ZodOptional<z.ZodBoolean>;
201
+ contentType: z.ZodOptional<z.ZodString>;
202
+ error: z.ZodString;
203
+ }, "strip", z.ZodTypeAny, {
204
+ error: string;
205
+ success: boolean;
206
+ operation: "updateFile";
207
+ updated?: boolean | undefined;
208
+ contentType?: string | undefined;
209
+ fileName?: string | undefined;
210
+ }, {
211
+ error: string;
212
+ success: boolean;
213
+ operation: "updateFile";
214
+ updated?: boolean | undefined;
215
+ contentType?: string | undefined;
216
+ fileName?: string | undefined;
217
+ }>, z.ZodObject<{
218
+ operation: z.ZodLiteral<"getMultipleUploadUrls">;
219
+ success: z.ZodBoolean;
220
+ pdfUploadUrl: z.ZodOptional<z.ZodString>;
221
+ pdfFileName: z.ZodOptional<z.ZodString>;
222
+ pageUploadUrls: z.ZodOptional<z.ZodArray<z.ZodObject<{
223
+ pageNumber: z.ZodNumber;
224
+ uploadUrl: z.ZodString;
225
+ fileName: z.ZodString;
226
+ }, "strip", z.ZodTypeAny, {
227
+ fileName: string;
228
+ uploadUrl: string;
229
+ pageNumber: number;
230
+ }, {
231
+ fileName: string;
232
+ uploadUrl: string;
233
+ pageNumber: number;
234
+ }>, "many">>;
235
+ error: z.ZodString;
236
+ }, "strip", z.ZodTypeAny, {
237
+ error: string;
238
+ success: boolean;
239
+ operation: "getMultipleUploadUrls";
240
+ pdfFileName?: string | undefined;
241
+ pdfUploadUrl?: string | undefined;
242
+ pageUploadUrls?: {
243
+ fileName: string;
244
+ uploadUrl: string;
245
+ pageNumber: number;
246
+ }[] | undefined;
247
+ }, {
248
+ error: string;
249
+ success: boolean;
250
+ operation: "getMultipleUploadUrls";
251
+ pdfFileName?: string | undefined;
252
+ pdfUploadUrl?: string | undefined;
253
+ pageUploadUrls?: {
254
+ fileName: string;
255
+ uploadUrl: string;
256
+ pageNumber: number;
257
+ }[] | undefined;
258
+ }>]>;
259
+ export type S3Result = z.output<typeof S3ResultSchema>;
260
+ export type S3Params = z.output<typeof S3ParamsSchema>;
261
+ export type S3ParamsInput = z.input<typeof S3ParamsSchema>;
262
+ export type S3OperationResult<T extends S3Params['operation']> = Extract<S3Result, {
263
+ operation: T;
264
+ }>;
265
+ //# sourceMappingURL=s3.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.schema.d.ts","sourceRoot":"","sources":["../../../../src/bubbles/service-bubble/s3/s3.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+HzB,CAAC;AAGH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8FzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AACvD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AACvD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAG3D,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CACtE,QAAQ,EACR;IAAE,SAAS,EAAE,CAAC,CAAA;CAAE,CACjB,CAAC"}