lean-s3 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -39,8 +39,11 @@ interface S3ClientOptions {
39
39
  secretAccessKey: string;
40
40
  sessionToken?: string;
41
41
  }
42
- type OverridableS3ClientOptions = Pick<S3ClientOptions, "region" | "bucket" | "endpoint">;
43
- type CreateFileInstanceOptions = {};
42
+ type OverridableS3ClientOptions = Partial<Pick<S3ClientOptions, "region" | "bucket" | "endpoint">>;
43
+ type CreateFileInstanceOptions = {
44
+ /** Content-Type of the file. */
45
+ type?: string;
46
+ };
44
47
  type DeleteObjectsOptions = {
45
48
  bucket?: string;
46
49
  signal?: AbortSignal;
@@ -55,13 +58,15 @@ type DeleteObjectsError = {
55
58
  versionId: string;
56
59
  };
57
60
  interface S3FilePresignOptions {
58
- contentHash: Buffer;
61
+ contentHash?: Buffer;
59
62
  /** Seconds. */
60
- expiresIn: number;
61
- method: PresignableHttpMethod;
62
- contentLength: number;
63
- storageClass: StorageClass;
64
- acl: Acl;
63
+ expiresIn?: number;
64
+ method?: PresignableHttpMethod;
65
+ contentLength?: number;
66
+ storageClass?: StorageClass;
67
+ acl?: Acl;
68
+ /** `Content-Type` of the file. */
69
+ type?: string;
65
70
  }
66
71
  type ListObjectsOptions = {
67
72
  bucket?: string;
@@ -261,11 +266,6 @@ declare class S3Client {
261
266
  * @param options The default options to use for the S3 client.
262
267
  */
263
268
  constructor(options: S3ClientOptions);
264
- cors: {
265
- get: () => void;
266
- set: () => void;
267
- delete: () => void;
268
- };
269
269
  /**
270
270
  * Creates an S3File instance for the given path.
271
271
  *
@@ -289,7 +289,6 @@ declare class S3Client {
289
289
  *
290
290
  * lean-s3 does not enforce these restrictions.
291
291
  *
292
- * @param {Partial<CreateFileInstanceOptions>} [_options] TODO
293
292
  * @example
294
293
  * ```js
295
294
  * const file = client.file("image.jpg");
@@ -297,11 +296,10 @@ declare class S3Client {
297
296
  *
298
297
  * const configFile = client.file("config.json", {
299
298
  * type: "application/json",
300
- * acl: "private"
301
299
  * });
302
300
  * ```
303
301
  */
304
- file(path: string, _options?: Partial<CreateFileInstanceOptions>): S3File;
302
+ file(path: string, options?: CreateFileInstanceOptions): S3File;
305
303
  /**
306
304
  * Generate a presigned URL for temporary access to a file.
307
305
  * Useful for generating upload/download URLs without exposing credentials.
@@ -315,7 +313,7 @@ declare class S3Client {
315
313
  * ```
316
314
  */
317
315
  presign(path: string, { method, expiresIn, // TODO: Maybe rename this to expiresInSeconds
318
- storageClass, contentLength, acl, region: regionOverride, bucket: bucketOverride, endpoint: endpointOverride, }?: Partial<S3FilePresignOptions & OverridableS3ClientOptions>): string;
316
+ storageClass, contentLength, type, acl, region: regionOverride, bucket: bucketOverride, endpoint: endpointOverride, }?: S3FilePresignOptions & OverridableS3ClientOptions): string;
319
317
  createMultipartUpload(key: string, options?: CreateMultipartUploadOptions): Promise<CreateMultipartUploadResult>;
320
318
  /**
321
319
  * @remarks Uses [`ListMultipartUploads`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html).
@@ -431,6 +429,10 @@ declare class S3Stat {
431
429
  static tryParseFromHeaders(headers: Record<string, string | string[] | undefined>): S3Stat | undefined;
432
430
  }
433
431
 
432
+ type S3FileWriteOptions = {
433
+ /** Content-Type of the file. */
434
+ type?: string;
435
+ };
434
436
  declare class S3File {
435
437
  #private;
436
438
  /** @internal */
@@ -443,20 +445,20 @@ declare class S3File {
443
445
  * @throws {S3Error} If the file does not exist or the server has some other issues.
444
446
  * @throws {Error} If the server returns an invalid response.
445
447
  */
446
- stat(options?: Partial<S3StatOptions>): Promise<S3Stat>;
448
+ stat(options?: S3StatOptions): Promise<S3Stat>;
447
449
  /**
448
450
  * Check if a file exists in the bucket. Uses `HEAD` request to check existence.
449
451
  *
450
452
  * @remarks Uses [`HeadObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html).
451
453
  */
452
- exists(options?: Partial<S3FileExistsOptions>): Promise<boolean>;
454
+ exists(options?: S3FileExistsOptions): Promise<boolean>;
453
455
  /**
454
456
  * Delete a file from the bucket.
455
457
  *
456
458
  * @remarks - Uses [`DeleteObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html).
457
459
  * - `versionId` not supported.
458
460
  *
459
- * @param {Partial<S3FileDeleteOptions>} [options]
461
+ * @param {S3FileDeleteOptions} [options]
460
462
  *
461
463
  * @example
462
464
  * ```js
@@ -472,7 +474,7 @@ declare class S3File {
472
474
  * }
473
475
  * ```
474
476
  */
475
- delete(options?: Partial<S3FileDeleteOptions>): Promise<void>;
477
+ delete(options?: S3FileDeleteOptions): Promise<void>;
476
478
  toString(): string;
477
479
  json(): Promise<unknown>;
478
480
  bytes(): Promise<Uint8Array>;
@@ -483,18 +485,19 @@ declare class S3File {
483
485
  stream(): ReadableStream<Uint8Array>;
484
486
  /**
485
487
  * @param {ByteSource} data
488
+ * @param {S3FileWriteOptions} [options.type] Defaults to the Content-Type that was used to create the {@link S3File} instance.
486
489
  * @returns {Promise<void>}
487
490
  */
488
- write(data: ByteSource): Promise<void>;
491
+ write(data: ByteSource, options?: S3FileWriteOptions): Promise<void>;
489
492
  }
490
493
  interface S3FileDeleteOptions extends OverridableS3ClientOptions {
491
- signal: AbortSignal;
494
+ signal?: AbortSignal;
492
495
  }
493
496
  interface S3StatOptions extends OverridableS3ClientOptions {
494
- signal: AbortSignal;
497
+ signal?: AbortSignal;
495
498
  }
496
499
  interface S3FileExistsOptions extends OverridableS3ClientOptions {
497
- signal: AbortSignal;
500
+ signal?: AbortSignal;
498
501
  }
499
502
 
500
503
  declare class S3Error extends Error {
@@ -536,4 +539,4 @@ type BucketInfo = {
536
539
  type?: string;
537
540
  };
538
541
 
539
- export { type AbortMultipartUploadOptions, type Acl, type BucketCorsRule, type BucketCorsRules, type BucketCreationOptions, type BucketDeletionOptions, type BucketExistsOptions, type BucketInfo, type BucketLocationInfo, type ByteSource, type ChecksumAlgorithm, type ChecksumType, type CompleteMultipartUploadOptions, type CompleteMultipartUploadResult, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, type GetBucketCorsOptions, type GetBucketCorsResult, type HttpMethod, type ListMultipartUploadsOptions, type ListMultipartUploadsResult, type ListObjectsIteratingOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListPartsResult, type MultipartUpload, type MultipartUploadPart, type OverridableS3ClientOptions, type PresignableHttpMethod, type PutBucketCorsOptions, S3BucketEntry, S3Client, type S3ClientOptions, S3Error, type S3ErrorOptions, S3File, type S3FileDeleteOptions, type S3FileExistsOptions, type S3FilePresignOptions, S3Stat, type S3StatOptions, type StorageClass, type UndiciBodyInit, type UploadPartOptions, type UploadPartResult };
542
+ export { type AbortMultipartUploadOptions, type Acl, type BucketCorsRule, type BucketCorsRules, type BucketCreationOptions, type BucketDeletionOptions, type BucketExistsOptions, type BucketInfo, type BucketLocationInfo, type ByteSource, type ChecksumAlgorithm, type ChecksumType, type CompleteMultipartUploadOptions, type CompleteMultipartUploadResult, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteBucketCorsOptions, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, type GetBucketCorsOptions, type GetBucketCorsResult, type HttpMethod, type ListMultipartUploadsOptions, type ListMultipartUploadsResult, type ListObjectsIteratingOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListPartsResult, type MultipartUpload, type MultipartUploadPart, type OverridableS3ClientOptions, type PresignableHttpMethod, type PutBucketCorsOptions, S3BucketEntry, S3Client, type S3ClientOptions, S3Error, type S3ErrorOptions, S3File, type S3FileDeleteOptions, type S3FileExistsOptions, type S3FilePresignOptions, type S3FileWriteOptions, S3Stat, type S3StatOptions, type StorageClass, type UndiciBodyInit, type UploadPartOptions, type UploadPartResult };
package/dist/index.js CHANGED
@@ -404,14 +404,20 @@ var S3Client = class {
404
404
  sessionToken
405
405
  };
406
406
  }
407
+ // Maybe future API
408
+ /*
407
409
  cors = {
408
- get: () => {
409
- },
410
- set: () => {
411
- },
412
- delete: () => {
413
- }
410
+ get: () => {
411
+ // TODO: GetBucketCors
412
+ },
413
+ set: () => {
414
+ // TODO: PutBucketCors
415
+ },
416
+ delete: () => {
417
+ // TODO: DeleteBucketCors
418
+ },
414
419
  };
420
+ */
415
421
  /**
416
422
  * Creates an S3File instance for the given path.
417
423
  *
@@ -435,7 +441,6 @@ var S3Client = class {
435
441
  *
436
442
  * lean-s3 does not enforce these restrictions.
437
443
  *
438
- * @param {Partial<CreateFileInstanceOptions>} [_options] TODO
439
444
  * @example
440
445
  * ```js
441
446
  * const file = client.file("image.jpg");
@@ -443,17 +448,16 @@ var S3Client = class {
443
448
  *
444
449
  * const configFile = client.file("config.json", {
445
450
  * type: "application/json",
446
- * acl: "private"
447
451
  * });
448
452
  * ```
449
453
  */
450
- file(path, _options) {
454
+ file(path, options = {}) {
451
455
  return new S3File(
452
456
  this,
453
457
  ensureValidPath(path),
454
458
  void 0,
455
459
  void 0,
456
- void 0
460
+ options.type ?? void 0
457
461
  );
458
462
  }
459
463
  /**
@@ -474,6 +478,7 @@ var S3Client = class {
474
478
  // TODO: Maybe rename this to expiresInSeconds
475
479
  storageClass,
476
480
  contentLength,
481
+ type,
477
482
  acl,
478
483
  region: regionOverride,
479
484
  bucket: bucketOverride,
@@ -495,17 +500,21 @@ var S3Client = class {
495
500
  `${options.accessKeyId}/${date.date}/${region}/s3/aws4_request`,
496
501
  date,
497
502
  expiresIn,
498
- typeof contentLength === "number" ? "content-length;host" : "host",
503
+ typeof contentLength === "number" || typeof type === "string" ? typeof contentLength === "number" && typeof type === "string" ? "content-length;content-type;host" : typeof contentLength === "number" ? "content-length;host" : typeof type === "string" ? "content-type;host" : "" : "host",
499
504
  unsignedPayload,
500
505
  storageClass,
501
506
  options.sessionToken,
502
507
  acl
503
508
  );
504
- const dataDigest = typeof contentLength === "number" ? createCanonicalDataDigest(
509
+ const dataDigest = typeof contentLength === "number" || typeof type === "string" ? createCanonicalDataDigest(
505
510
  method,
506
511
  res.pathname,
507
512
  query,
508
- { "content-length": String(contentLength), host: res.host },
513
+ typeof contentLength === "number" && typeof type === "string" ? {
514
+ "content-length": String(contentLength),
515
+ "content-type": type,
516
+ host: res.host
517
+ } : typeof contentLength === "number" ? { "content-length": String(contentLength), host: res.host } : typeof type === "string" ? { "content-type": type, host: res.host } : {},
509
518
  unsignedPayload
510
519
  ) : createCanonicalDataDigestHostOnly(
511
520
  method,
@@ -1541,7 +1550,7 @@ var S3File = class _S3File {
1541
1550
  * @remarks - Uses [`DeleteObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html).
1542
1551
  * - `versionId` not supported.
1543
1552
  *
1544
- * @param {Partial<S3FileDeleteOptions>} [options]
1553
+ * @param {S3FileDeleteOptions} [options]
1545
1554
  *
1546
1555
  * @example
1547
1556
  * ```js
@@ -1632,15 +1641,16 @@ var S3File = class _S3File {
1632
1641
  }
1633
1642
  /**
1634
1643
  * @param {ByteSource} data
1644
+ * @param {S3FileWriteOptions} [options.type] Defaults to the Content-Type that was used to create the {@link S3File} instance.
1635
1645
  * @returns {Promise<void>}
1636
1646
  */
1637
- async write(data) {
1647
+ async write(data, options = {}) {
1638
1648
  const signal = void 0;
1639
1649
  const [bytes, length, hash] = await this.#transformData(data);
1640
1650
  return await this.#client[write](
1641
1651
  this.#path,
1642
1652
  bytes,
1643
- this.#contentType,
1653
+ options.type ?? this.#contentType,
1644
1654
  length,
1645
1655
  hash,
1646
1656
  this.#start,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "lean-s3",
3
3
  "author": "Niklas Mollenhauer",
4
4
  "license": "MIT",
5
- "version": "0.6.3",
5
+ "version": "0.7.0",
6
6
  "description": "A server-side S3 API for the regular user.",
7
7
  "keywords": [
8
8
  "s3",
@@ -48,15 +48,15 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@biomejs/biome": "2.0.6",
51
- "@testcontainers/localstack": "^11.0.3",
52
- "@testcontainers/minio": "^11.0.3",
53
- "@types/node": "^24.0.7",
54
- "@typescript/native-preview": "^7.0.0-dev.20250629.1",
55
- "expect": "^30.0.3",
56
- "lefthook": "^1.11.14",
51
+ "@testcontainers/localstack": "^11.2.0",
52
+ "@testcontainers/minio": "^11.2.0",
53
+ "@types/node": "^24.0.10",
54
+ "@typescript/native-preview": "^7.0.0-dev.20250705.1",
55
+ "expect": "^30.0.4",
56
+ "lefthook": "^1.11.16",
57
57
  "tsup": "^8.5.0",
58
58
  "tsx": "^4.20.3",
59
- "typedoc": "^0.28.6"
59
+ "typedoc": "^0.28.7"
60
60
  },
61
61
  "engines": {
62
62
  "node": "^20.19.2 || ^22.16.0 || ^24.2.0"