@critical-path/core 0.30.0 → 0.31.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.
@@ -1,3 +1,42 @@
1
+ /**
2
+ * Builds a storage key `<prefix>/<timestamp>_<random>_<filename>`. The prefix is validated (no
3
+ * `.`/`..` segments, no leading slash, safe characters only) so callers cannot write outside it.
4
+ */
5
+ export function buildStorageKey(pathPrefix, filename) {
6
+ let prefix = '';
7
+ if (pathPrefix) {
8
+ const trimmed = pathPrefix.replace(/\/+$/, '');
9
+ const segments = trimmed.split('/');
10
+ if (trimmed.startsWith('/') ||
11
+ segments.some((segment) => segment === '' || segment === '.' || segment === '..' || !/^[A-Za-z0-9._-]+$/.test(segment))) {
12
+ throw new Error(`Invalid storage path prefix "${pathPrefix}".`);
13
+ }
14
+ prefix = `${trimmed}/`;
15
+ }
16
+ const random = Array.from(crypto.getRandomValues(new Uint8Array(6)), (b) => b.toString(16).padStart(2, '0')).join('');
17
+ const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '_').replace(/^\.+/, '_') || 'file';
18
+ return `${prefix}${Date.now()}_${random}_${safeName}`;
19
+ }
20
+ /** Content types a browser would execute or render as a page if opened from the storage host. */
21
+ const ACTIVE_CONTENT_TYPES = new Set([
22
+ 'text/html',
23
+ 'application/xhtml+xml',
24
+ 'image/svg+xml',
25
+ 'text/javascript',
26
+ 'application/javascript',
27
+ 'text/xml',
28
+ 'application/xml'
29
+ ]);
30
+ /**
31
+ * `Content-Disposition` for stored files: active content (HTML, SVG, scripts) is forced to
32
+ * download so a stored file cannot run script on the storage origin.
33
+ */
34
+ export function contentDispositionFor(mimeType, filename) {
35
+ const base = mimeType.split(';')[0].trim().toLowerCase();
36
+ if (!ACTIVE_CONTENT_TYPES.has(base))
37
+ return undefined;
38
+ return `attachment; filename="${filename.replace(/["\\\r\n]/g, '_')}"`;
39
+ }
1
40
  export function normalizeUploadData(data, encoding, mimeType) {
2
41
  if (data instanceof Uint8Array) {
3
42
  return data;
@@ -65,10 +104,7 @@ export class InMemoryFileStore {
65
104
  this.publicBaseUrl = options.publicUrlBase || options.publicBaseUrl || 'memory://attachments';
66
105
  }
67
106
  async upload(input) {
68
- const prefix = input.pathPrefix ? `${input.pathPrefix.replace(/\/+$/, '')}/` : '';
69
- const randomId = Math.random().toString(36).substring(2, 9);
70
- const sanitizedFilename = input.filename.replace(/[^a-zA-Z0-9._-]/g, '_');
71
- const storageKey = `${prefix}${Date.now()}_${randomId}_${sanitizedFilename}`;
107
+ const storageKey = buildStorageKey(input.pathPrefix, input.filename);
72
108
  const buffer = normalizeUploadData(input.data, input.encoding, input.mimeType);
73
109
  const mimeType = input.mimeType || 'application/octet-stream';
74
110
  const sizeBytes = buffer.byteLength;
@@ -1 +1 @@
1
- {"version":3,"file":"file-storage.js","sourceRoot":"","sources":["../../src/storage/file-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-storage.js","sourceRoot":"","sources":["../../src/storage/file-storage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"firebase-storage.d.ts","sourceRoot":"","sources":["../../src/storage/firebase-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,8BAA8B;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG;QAClB,IAAI,CACF,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE;gBAAE,WAAW,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;aAAE,CAAC;YAAC,SAAS,CAAC,EAAE,OAAO,CAAA;SAAE,GACzF,OAAO,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,YAAY,CAAC,CAAC,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;YAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9H,SAAS,CAAC,IAAI,MAAM,CAAC;KACtB,CAAC;CACH;AAED,qBAAa,2BAA4B,YAAW,8BAA8B;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,KAAK,CAAgF;gBAEjF,IAAI,GAAE,MAA+B;IAIjD,IAAI,CAAC,IAAI,EAAE,MAAM;mBAII,UAAU,GAAG,MAAM,GAAG,MAAM,YAAY,GAAG;;oBAoB1C,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;uBAKlB,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;6BASR,GAAG,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;;;CAUvD;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,8BAA8B,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;IAC/D,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEnB,MAAM,GAAE,qBAA0B;IAS9C,OAAO,CAAC,YAAY;IAQd,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmCzD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;IAe1D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA6B1F"}
1
+ {"version":3,"file":"firebase-storage.d.ts","sourceRoot":"","sources":["../../src/storage/firebase-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,8BAA8B;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG;QAClB,IAAI,CACF,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,EAClC,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE;gBAAE,WAAW,CAAC,EAAE,MAAM,CAAC;gBAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;aAAE,CAAC;YAAC,SAAS,CAAC,EAAE,OAAO,CAAA;SAAE,GACzF,OAAO,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,YAAY,CAAC,CAAC,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;YAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9H,SAAS,CAAC,IAAI,MAAM,CAAC;KACtB,CAAC;CACH;AAED,qBAAa,2BAA4B,YAAW,8BAA8B;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,KAAK,CAAgF;gBAEjF,IAAI,GAAE,MAA+B;IAIjD,IAAI,CAAC,IAAI,EAAE,MAAM;mBAII,UAAU,GAAG,MAAM,GAAG,MAAM,YAAY,GAAG;;oBAoB1C,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;uBAKlB,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;6BASR,GAAG,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;;;CAUvD;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,8BAA8B,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;IAC/D,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEnB,MAAM,GAAE,qBAA0B;IAa9C,OAAO,CAAC,YAAY;IAQd,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiCzD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU5C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;IAe1D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAwB1F"}
@@ -1,4 +1,4 @@
1
- import { normalizeUploadData } from './file-storage.js';
1
+ import { buildStorageKey, contentDispositionFor, normalizeUploadData } from './file-storage.js';
2
2
  export class InMemoryFirebaseStorageMock {
3
3
  name;
4
4
  files = new Map();
@@ -63,7 +63,11 @@ export class FirebaseStorageAdapter {
63
63
  bucketName;
64
64
  publicUrlBase;
65
65
  constructor(config = {}) {
66
- this.bucket = config.bucket || new InMemoryFirebaseStorageMock(config.bucketName || 'default-bucket');
66
+ if (!config.bucket) {
67
+ // Never fall back to an in-memory mock silently: files would vanish on restart.
68
+ throw new Error('FirebaseStorageAdapter requires a "bucket" (e.g. getStorage().bucket()). Use InMemoryFirebaseStorageMock in tests.');
69
+ }
70
+ this.bucket = config.bucket;
67
71
  this.bucketName = config.bucketName || this.bucket.name || 'default-bucket';
68
72
  if (this.bucket && config.bucketName && this.bucket.name !== config.bucketName) {
69
73
  this.bucket.name = config.bucketName;
@@ -78,10 +82,7 @@ export class FirebaseStorageAdapter {
78
82
  return `https://firebasestorage.googleapis.com/v0/b/${encodeURIComponent(this.bucketName)}/o/${encodeURIComponent(storageKey)}?alt=media${tokenParam}`;
79
83
  }
80
84
  async upload(input) {
81
- const prefix = input.pathPrefix ? `${input.pathPrefix.replace(/\/+$/, '')}/` : '';
82
- const randomId = Math.random().toString(36).substring(2, 9);
83
- const sanitizedFilename = input.filename.replace(/[^a-zA-Z0-9._-]/g, '_');
84
- const storageKey = `${prefix}${Date.now()}_${randomId}_${sanitizedFilename}`;
85
+ const storageKey = buildStorageKey(input.pathPrefix, input.filename);
85
86
  const bodyData = normalizeUploadData(input.data, input.encoding, input.mimeType);
86
87
  const mimeType = input.mimeType || 'application/octet-stream';
87
88
  const sizeBytes = bodyData.byteLength;
@@ -92,6 +93,7 @@ export class FirebaseStorageAdapter {
92
93
  await fileRef.save(bodyData, {
93
94
  metadata: {
94
95
  contentType: mimeType,
96
+ ...(contentDispositionFor(mimeType, input.filename) ? { contentDisposition: contentDispositionFor(mimeType, input.filename) } : {}),
95
97
  metadata: {
96
98
  firebaseStorageDownloadTokens: downloadToken
97
99
  }
@@ -162,13 +164,8 @@ export class FirebaseStorageAdapter {
162
164
  headers: options.contentType ? { 'Content-Type': options.contentType } : {}
163
165
  };
164
166
  }
165
- // Fallback to direct public upload url
166
- return {
167
- uploadUrl: this.getPublicUrl(storageKey),
168
- storageKey,
169
- method: 'PUT',
170
- headers: options.contentType ? { 'Content-Type': options.contentType } : {}
171
- };
167
+ // A public URL is not an upload credential; refuse rather than hand out a URL that cannot work.
168
+ throw new Error('FirebaseStorageAdapter cannot presign uploads: the bucket does not support getSignedUrl.');
172
169
  }
173
170
  }
174
171
  //# sourceMappingURL=firebase-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"firebase-storage.js","sourceRoot":"","sources":["../../src/storage/firebase-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"firebase-storage.js","sourceRoot":"","sources":["../../src/storage/firebase-storage.ts"],"names":[],"mappings":"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"}
@@ -1,36 +1,64 @@
1
1
  import type { FileStorageAdapter, UploadFileInput, UploadFileResult, PresignedUrlOptions, PresignedUploadResult } from '../types/index.js';
2
- export interface S3ClientInterface {
3
- send?(command: any): Promise<any>;
4
- putObject?(params: any): Promise<any>;
5
- deleteObject?(params: any): Promise<any>;
6
- getSignedUrlPromise?(operation: string, params: any): Promise<string>;
2
+ /** The subset of the AWS SDK v3 `S3Client` the adapter uses. */
3
+ export interface S3ClientLike {
4
+ send(command: unknown): Promise<unknown>;
5
+ }
6
+ type CommandClass = new (input: Record<string, unknown>) => unknown;
7
+ /**
8
+ * Command classes from `@aws-sdk/client-s3`, passed in so `@critical-path/core` has no AWS
9
+ * dependency: `{ PutObjectCommand, DeleteObjectCommand, GetObjectCommand }`.
10
+ */
11
+ export interface S3Commands {
12
+ PutObjectCommand: CommandClass;
13
+ DeleteObjectCommand: CommandClass;
14
+ /** Needed for signed download URLs (private buckets). */
15
+ GetObjectCommand?: CommandClass;
7
16
  }
8
17
  export interface S3StorageConfig {
9
18
  bucket: string;
10
19
  region?: string;
20
+ /** Custom endpoint for S3-compatible services (MinIO, R2, LocalStack). */
11
21
  endpoint?: string;
12
- accessKeyId?: string;
13
- secretAccessKey?: string;
14
- sessionToken?: string;
22
+ /** Base URL for public object links (e.g. a CDN). */
15
23
  publicUrlBase?: string;
16
24
  forcePathStyle?: boolean;
17
- s3Client?: S3ClientInterface;
25
+ /** An AWS SDK v3 `S3Client` (or compatible). Required for uploads and deletes. */
26
+ client?: S3ClientLike;
27
+ commands?: S3Commands;
28
+ /**
29
+ * Signs a command into a URL, typically
30
+ * `(command, { expiresIn }) => getSignedUrl(client, command, { expiresIn })` from
31
+ * `@aws-sdk/s3-request-presigner`. Required for presigned uploads and signed downloads.
32
+ */
33
+ presign?: (command: unknown, options: {
34
+ expiresIn: number;
35
+ }) => Promise<string>;
36
+ /**
37
+ * Serve downloads through signed URLs instead of public object URLs (for private buckets).
38
+ * Requires `presign` and `commands.GetObjectCommand`. Default `false`.
39
+ */
40
+ signedDownloads?: boolean;
41
+ /** Lifetime of signed download URLs in seconds. Default 3600. */
42
+ downloadUrlExpiresIn?: number;
18
43
  }
44
+ /**
45
+ * Stores attachments in Amazon S3 (or an S3-compatible service) using the AWS SDK v3 client
46
+ * you provide. Errors from S3 propagate; nothing is reported as stored unless S3 accepted it.
47
+ */
19
48
  export declare class S3StorageAdapter implements FileStorageAdapter {
20
- private bucket;
21
- private region;
22
- private endpoint;
23
- private accessKeyId?;
24
- private secretAccessKey?;
25
- private sessionToken?;
26
- private publicUrlBase?;
27
- private forcePathStyle;
28
- private s3Client?;
49
+ private readonly bucket;
50
+ private readonly endpoint;
51
+ private readonly publicUrlBase?;
52
+ private readonly forcePathStyle;
53
+ private readonly config;
29
54
  constructor(config: S3StorageConfig);
55
+ private requireClient;
30
56
  private getObjectUrl;
31
57
  upload(input: UploadFileInput): Promise<UploadFileResult>;
58
+ /** Deletes an object. S3 deletes are idempotent, so a missing object still returns `true`. */
32
59
  delete(storageKey: string): Promise<boolean>;
33
60
  getDownloadUrl(storageKey: string): Promise<string>;
34
61
  getPresignedUploadUrl(options: PresignedUrlOptions): Promise<PresignedUploadResult>;
35
62
  }
63
+ export {};
36
64
  //# sourceMappingURL=s3.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,SAAS,CAAC,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,YAAY,CAAC,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACzC,mBAAmB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,qBAAa,gBAAiB,YAAW,kBAAkB;IACzD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAEzB,MAAM,EAAE,eAAe;IAenC,OAAO,CAAC,YAAY;IAWd,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2CzD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB5C,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAInD,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAgB1F"}
1
+ {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAG3B,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C;AAED,KAAK,YAAY,GAAG,KAAK,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,YAAY,CAAC;IAC/B,mBAAmB,EAAE,YAAY,CAAC;IAClC,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,YAAY,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChF;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,kBAAkB;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;gBAE7B,MAAM,EAAE,eAAe;IAmBnC,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IAOd,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB/D,8FAA8F;IACxF,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQnD,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAkB1F"}
@@ -1,120 +1,90 @@
1
- import { normalizeUploadData } from './file-storage.js';
1
+ import { buildStorageKey, contentDispositionFor, normalizeUploadData } from './file-storage.js';
2
+ /**
3
+ * Stores attachments in Amazon S3 (or an S3-compatible service) using the AWS SDK v3 client
4
+ * you provide. Errors from S3 propagate; nothing is reported as stored unless S3 accepted it.
5
+ */
2
6
  export class S3StorageAdapter {
3
7
  bucket;
4
- region;
5
8
  endpoint;
6
- accessKeyId;
7
- secretAccessKey;
8
- sessionToken;
9
9
  publicUrlBase;
10
10
  forcePathStyle;
11
- s3Client;
11
+ config;
12
12
  constructor(config) {
13
13
  if (!config.bucket) {
14
14
  throw new Error('S3StorageAdapter requires a "bucket" name in its config.');
15
15
  }
16
+ if (config.client && !config.commands) {
17
+ throw new Error('S3StorageAdapter needs "commands" ({ PutObjectCommand, DeleteObjectCommand }) from @aws-sdk/client-s3 when a client is given.');
18
+ }
19
+ if (config.signedDownloads && (!config.presign || !config.commands?.GetObjectCommand)) {
20
+ throw new Error('S3StorageAdapter signedDownloads requires "presign" and "commands.GetObjectCommand".');
21
+ }
22
+ this.config = config;
16
23
  this.bucket = config.bucket;
17
- this.region = config.region || 'us-east-1';
18
- this.endpoint = (config.endpoint || `https://s3.${this.region}.amazonaws.com`).replace(/\/+$/, '');
19
- this.accessKeyId = config.accessKeyId;
20
- this.secretAccessKey = config.secretAccessKey;
21
- this.sessionToken = config.sessionToken;
24
+ const region = config.region || 'us-east-1';
25
+ this.endpoint = (config.endpoint || `https://s3.${region}.amazonaws.com`).replace(/\/+$/, '');
22
26
  this.publicUrlBase = config.publicUrlBase?.replace(/\/+$/, '');
23
- this.forcePathStyle = config.forcePathStyle ?? (this.endpoint.includes('localhost') || this.endpoint.includes('127.0.0.1'));
24
- this.s3Client = config.s3Client;
27
+ this.forcePathStyle =
28
+ config.forcePathStyle ?? (this.endpoint.includes('localhost') || this.endpoint.includes('127.0.0.1'));
25
29
  }
26
- getObjectUrl(storageKey) {
27
- if (this.publicUrlBase) {
28
- return `${this.publicUrlBase}/${encodeURIComponent(storageKey).replace(/%2F/g, '/')}`;
30
+ requireClient(operation) {
31
+ if (!this.config.client || !this.config.commands) {
32
+ throw new Error(`S3StorageAdapter cannot ${operation}: configure "client" and "commands".`);
29
33
  }
30
- if (this.forcePathStyle) {
31
- return `${this.endpoint}/${this.bucket}/${encodeURIComponent(storageKey).replace(/%2F/g, '/')}`;
32
- }
33
- const hostWithBucket = this.endpoint.replace('://', `://${this.bucket}.`);
34
- return `${hostWithBucket}/${encodeURIComponent(storageKey).replace(/%2F/g, '/')}`;
34
+ return { client: this.config.client, commands: this.config.commands };
35
+ }
36
+ getObjectUrl(storageKey) {
37
+ const path = encodeURIComponent(storageKey).replace(/%2F/g, '/');
38
+ if (this.publicUrlBase)
39
+ return `${this.publicUrlBase}/${path}`;
40
+ if (this.forcePathStyle)
41
+ return `${this.endpoint}/${this.bucket}/${path}`;
42
+ return `${this.endpoint.replace('://', `://${this.bucket}.`)}/${path}`;
35
43
  }
36
44
  async upload(input) {
37
- const prefix = input.pathPrefix ? `${input.pathPrefix.replace(/\/+$/, '')}/` : '';
38
- const randomId = Math.random().toString(36).substring(2, 9);
39
- const sanitizedFilename = input.filename.replace(/[^a-zA-Z0-9._-]/g, '_');
40
- const storageKey = `${prefix}${Date.now()}_${randomId}_${sanitizedFilename}`;
41
- const bodyData = normalizeUploadData(input.data, input.encoding, input.mimeType);
45
+ const { client, commands } = this.requireClient('upload');
46
+ const storageKey = buildStorageKey(input.pathPrefix, input.filename);
47
+ const body = normalizeUploadData(input.data, input.encoding, input.mimeType);
42
48
  const mimeType = input.mimeType || 'application/octet-stream';
43
- const sizeBytes = bodyData.byteLength;
44
- const url = this.getObjectUrl(storageKey);
45
- if (this.s3Client) {
46
- try {
47
- if (typeof this.s3Client.send === 'function') {
48
- await this.s3Client.send({
49
- input: {
50
- Bucket: this.bucket,
51
- Key: storageKey,
52
- Body: bodyData,
53
- ContentType: mimeType
54
- }
55
- });
56
- }
57
- else if (typeof this.s3Client.putObject === 'function') {
58
- await this.s3Client.putObject({
59
- Bucket: this.bucket,
60
- Key: storageKey,
61
- Body: bodyData,
62
- ContentType: mimeType
63
- });
64
- }
65
- }
66
- catch {
67
- // Fallback
68
- }
69
- }
70
- return {
71
- storageKey,
72
- url,
73
- sizeBytes,
74
- mimeType
75
- };
49
+ const disposition = contentDispositionFor(mimeType, input.filename);
50
+ await client.send(new commands.PutObjectCommand({
51
+ Bucket: this.bucket,
52
+ Key: storageKey,
53
+ Body: body,
54
+ ContentType: mimeType,
55
+ ...(disposition ? { ContentDisposition: disposition } : {})
56
+ }));
57
+ return { storageKey, url: await this.getDownloadUrl(storageKey), sizeBytes: body.byteLength, mimeType };
76
58
  }
59
+ /** Deletes an object. S3 deletes are idempotent, so a missing object still returns `true`. */
77
60
  async delete(storageKey) {
78
- if (this.s3Client) {
79
- try {
80
- if (typeof this.s3Client.send === 'function') {
81
- await this.s3Client.send({
82
- input: {
83
- Bucket: this.bucket,
84
- Key: storageKey
85
- }
86
- });
87
- return true;
88
- }
89
- else if (typeof this.s3Client.deleteObject === 'function') {
90
- await this.s3Client.deleteObject({
91
- Bucket: this.bucket,
92
- Key: storageKey
93
- });
94
- return true;
95
- }
96
- }
97
- catch {
98
- return false;
99
- }
100
- }
61
+ const { client, commands } = this.requireClient('delete');
62
+ await client.send(new commands.DeleteObjectCommand({ Bucket: this.bucket, Key: storageKey }));
101
63
  return true;
102
64
  }
103
65
  async getDownloadUrl(storageKey) {
66
+ if (this.config.signedDownloads) {
67
+ const command = new this.config.commands.GetObjectCommand({ Bucket: this.bucket, Key: storageKey });
68
+ return this.config.presign(command, { expiresIn: this.config.downloadUrlExpiresIn ?? 3600 });
69
+ }
104
70
  return this.getObjectUrl(storageKey);
105
71
  }
106
72
  async getPresignedUploadUrl(options) {
107
- const storageKey = options.storageKey;
108
- const uploadUrl = this.getObjectUrl(storageKey);
109
- const headers = {};
110
- if (options.contentType) {
111
- headers['Content-Type'] = options.contentType;
73
+ if (!this.config.presign || !this.config.commands) {
74
+ throw new Error('S3StorageAdapter cannot presign uploads: configure "presign" and "commands".');
112
75
  }
76
+ const command = new this.config.commands.PutObjectCommand({
77
+ Bucket: this.bucket,
78
+ Key: options.storageKey,
79
+ ...(options.contentType ? { ContentType: options.contentType } : {})
80
+ });
81
+ const uploadUrl = await this.config.presign(command, { expiresIn: options.expiresInSeconds ?? 900 });
113
82
  return {
114
83
  uploadUrl,
115
- storageKey,
84
+ storageKey: options.storageKey,
116
85
  method: 'PUT',
117
- headers
86
+ // The signature covers Content-Type, so the uploader must send exactly this header.
87
+ headers: options.contentType ? { 'Content-Type': options.contentType } : {}
118
88
  };
119
89
  }
120
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"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"}