lean-s3 0.7.6 → 0.7.8

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
@@ -1,5 +1,4 @@
1
1
  import { Readable } from 'node:stream';
2
- import * as stream_web from 'stream/web';
3
2
  import { Dispatcher } from 'undici';
4
3
 
5
4
  /**
@@ -35,10 +34,41 @@ declare const kStream: unique symbol;
35
34
  declare const kSignedRequest: unique symbol;
36
35
  declare const kGetEffectiveParams: unique symbol;
37
36
  interface S3ClientOptions {
37
+ /**
38
+ * The name of the bucket to operate on.
39
+ * Different S3 providers have different limitations here. All of them require:
40
+ * - Must be at least 3 characters long
41
+ * - Must be at most 63 characters long
42
+ * - Must not start or end with a period (.)
43
+ * - Must not contain two adjacent periods (..)
44
+ * - Must only contain lowercase letters, numbers, periods (.), and hyphens (-).
45
+ */
38
46
  bucket: string;
47
+ /**
48
+ * The region of the S3 bucket.
49
+ * This value is required for all S3 proviers. However, some providers don't care about its actual value.
50
+ */
39
51
  region: string;
52
+ /**
53
+ * The endpoint of the S3 service.
54
+ * This is required for all S3 providers.
55
+ *
56
+ * The endpoint may contain placeholders for region and bucket, which will be replaced internally with the actual values on use.
57
+ *
58
+ * For example, `https://{bucket}.s3.{region}.example.com` will be replaced with `https://my-bucket.s3.us-west-2.example.com` if the bucket is `my-bucket` and the region is `us-west-2`.
59
+ *
60
+ * If the endpoint does not contain a placeholder for the bucket, it will be appended to the path of the endpoint.
61
+ */
40
62
  endpoint: string;
63
+ /**
64
+ * The access key ID to use for authentication.
65
+ * This is required for all S3 providers.
66
+ */
41
67
  accessKeyId: string;
68
+ /**
69
+ * The secret access key to use for authentication.
70
+ * This is required for all S3 providers.
71
+ */
42
72
  secretAccessKey: string;
43
73
  sessionToken?: string;
44
74
  }
@@ -48,7 +78,9 @@ type CreateFileInstanceOptions = {
48
78
  type?: string;
49
79
  };
50
80
  type DeleteObjectsOptions = {
81
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
51
82
  bucket?: string;
83
+ /** Signal to abort the request. */
52
84
  signal?: AbortSignal;
53
85
  };
54
86
  type DeleteObjectsResult = {
@@ -93,31 +125,38 @@ interface S3FilePresignOptions extends OverridableS3ClientOptions {
93
125
  };
94
126
  }
95
127
  type ListObjectsOptions = {
128
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
96
129
  bucket?: string;
97
130
  prefix?: string;
98
131
  maxKeys?: number;
99
132
  delimiter?: string;
100
133
  startAfter?: string;
101
134
  continuationToken?: string;
135
+ /** Signal to abort the request. */
102
136
  signal?: AbortSignal;
103
137
  };
104
138
  type ListObjectsIteratingOptions = {
139
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
105
140
  bucket?: string;
106
141
  prefix?: string;
107
142
  startAfter?: string;
143
+ /** Signal to abort the request. */
108
144
  signal?: AbortSignal;
109
145
  internalPageSize?: number;
110
146
  };
111
147
  type ListMultipartUploadsOptions = {
148
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
112
149
  bucket?: string;
113
150
  delimiter?: string;
114
151
  keyMarker?: string;
115
152
  maxUploads?: number;
116
153
  prefix?: string;
117
154
  uploadIdMarker?: string;
155
+ /** Signal to abort the request. */
118
156
  signal?: AbortSignal;
119
157
  };
120
158
  type ListMultipartUploadsResult = {
159
+ /** Name of the bucket the operation was used upon. */
121
160
  bucket?: string;
122
161
  keyMarker?: string;
123
162
  uploadIdMarker?: string;
@@ -145,32 +184,50 @@ type MultipartUpload = {
145
184
  uploadId?: string;
146
185
  };
147
186
  type CreateMultipartUploadOptions = {
187
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
148
188
  bucket?: string;
189
+ /** Signal to abort the request. */
149
190
  signal?: AbortSignal;
150
191
  };
151
192
  type CreateMultipartUploadResult = {
193
+ /** Name of the bucket the multipart upload was created in. */
152
194
  bucket: string;
153
195
  key: string;
154
196
  uploadId: string;
155
197
  };
156
198
  type AbortMultipartUploadOptions = {
199
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
157
200
  bucket?: string;
201
+ /** Signal to abort the request. */
158
202
  signal?: AbortSignal;
159
203
  };
160
204
  type CompleteMultipartUploadOptions = {
205
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
161
206
  bucket?: string;
207
+ /** Signal to abort the request. */
162
208
  signal?: AbortSignal;
163
209
  };
164
210
  type CompleteMultipartUploadResult = {
211
+ /** The URI that identifies the newly created object. */
165
212
  location?: string;
213
+ /** Name of the bucket the multipart upload was created in. */
166
214
  bucket?: string;
167
215
  key?: string;
168
216
  etag?: string;
217
+ /** The Base64 encoded, 32-bit `CRC32` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC32` checksum algorithm. */
169
218
  checksumCRC32?: string;
219
+ /** The Base64 encoded, 32-bit `CRC32C` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC32C` checksum algorithm. */
170
220
  checksumCRC32C?: string;
221
+ /** The Base64 encoded, 64-bit `CRC64NVME` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC64NVME` checksum algorithm. */
171
222
  checksumCRC64NVME?: string;
223
+ /** The Base64 encoded, 160-bit `SHA1` checksum of the part. This checksum is present if the multipart upload request was created with the `SHA1` checksum algorithm. */
172
224
  checksumSHA1?: string;
225
+ /** The Base64 encoded, 256-bit `SHA256` checksum of the part. This checksum is present if the multipart upload request was created with the `SHA256` checksum algorithm. */
173
226
  checksumSHA256?: string;
227
+ /**
228
+ * The checksum type, which determines how part-level checksums are combined to create an object-level checksum for multipart objects.
229
+ * You can use this header as a data integrity check to verify that the checksum type that is received is the same checksum type that was specified during the `CreateMultipartUpload` request.
230
+ */
174
231
  checksumType?: ChecksumType;
175
232
  };
176
233
  type MultipartUploadPart = {
@@ -178,7 +235,9 @@ type MultipartUploadPart = {
178
235
  etag: string;
179
236
  };
180
237
  type UploadPartOptions = {
238
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
181
239
  bucket?: string;
240
+ /** Signal to abort the request. */
182
241
  signal?: AbortSignal;
183
242
  };
184
243
  type UploadPartResult = {
@@ -188,10 +247,13 @@ type UploadPartResult = {
188
247
  type ListPartsOptions = {
189
248
  maxParts?: number;
190
249
  partNumberMarker?: string;
250
+ /** Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
191
251
  bucket?: string;
252
+ /** Signal to abort the request. */
192
253
  signal?: AbortSignal;
193
254
  };
194
255
  type ListPartsResult = {
256
+ /** Name of the bucket. */
195
257
  bucket: string;
196
258
  key: string;
197
259
  uploadId: string;
@@ -200,10 +262,15 @@ type ListPartsResult = {
200
262
  maxParts?: number;
201
263
  isTruncated: boolean;
202
264
  parts: Array<{
265
+ /** The Base64 encoded, 32-bit `CRC32` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC32` checksum algorithm. */
203
266
  checksumCRC32?: string;
267
+ /** The Base64 encoded, 32-bit `CRC32C` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC32C` checksum algorithm. */
204
268
  checksumCRC32C?: string;
269
+ /** The Base64 encoded, 64-bit `CRC64NVME` checksum of the part. This checksum is present if the multipart upload request was created with the `CRC64NVME` checksum algorithm. */
205
270
  checksumCRC64NVME?: string;
271
+ /** The Base64 encoded, 160-bit `SHA1` checksum of the part. This checksum is present if the multipart upload request was created with the `SHA1` checksum algorithm. */
206
272
  checksumSHA1?: string;
273
+ /** The Base64 encoded, 256-bit `SHA256` checksum of the part. This checksum is present if the multipart upload request was created with the `SHA256` checksum algorithm. */
207
274
  checksumSHA256?: string;
208
275
  etag: string;
209
276
  lastModified: Date;
@@ -226,17 +293,22 @@ type ListObjectsResult = {
226
293
  contents: readonly S3BucketEntry[];
227
294
  };
228
295
  type BucketCreationOptions = {
296
+ /** Set this to override the {@link S3ClientOptions#endpoint} that was passed on creation of the {@link S3Client}. */
229
297
  endpoint?: string;
298
+ /** Set this to override the {@link S3ClientOptions#region} that was passed on creation of the {@link S3Client}. */
230
299
  region?: string;
231
300
  locationConstraint?: string;
232
301
  location?: BucketLocationInfo;
233
302
  info?: BucketInfo;
303
+ /** Signal to abort the request. */
234
304
  signal?: AbortSignal;
235
305
  };
236
306
  type BucketDeletionOptions = {
307
+ /** Signal to abort the request. */
237
308
  signal?: AbortSignal;
238
309
  };
239
310
  type BucketExistsOptions = {
311
+ /** Signal to abort the request. */
240
312
  signal?: AbortSignal;
241
313
  };
242
314
  type BucketCorsRules = readonly BucketCorsRule[];
@@ -254,15 +326,21 @@ type BucketCorsRule = {
254
326
  maxAgeSeconds?: number;
255
327
  };
256
328
  type PutBucketCorsOptions = {
329
+ /** The CORS rules to set on the bucket. Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
257
330
  bucket?: string;
331
+ /** Signal to abort the request. */
258
332
  signal?: AbortSignal;
259
333
  };
260
334
  type DeleteBucketCorsOptions = {
335
+ /** The name of the bucket to delete the CORS configuration for. Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
261
336
  bucket?: string;
337
+ /** Signal to abort the request. */
262
338
  signal?: AbortSignal;
263
339
  };
264
340
  type GetBucketCorsOptions = {
341
+ /** The name of the bucket to get the CORS configuration for. Set this to override the {@link S3ClientOptions#bucket} that was passed on creation of the {@link S3Client}. */
265
342
  bucket?: string;
343
+ /** Signal to abort the request. */
266
344
  signal?: AbortSignal;
267
345
  };
268
346
  type GetBucketCorsResult = {
@@ -377,7 +455,7 @@ declare class S3Client {
377
455
  * @throws {RangeError} If `key` is not at least 1 character long.
378
456
  * @throws {Error} If `uploadId` is not provided.
379
457
  */
380
- uploadPart(path: string, uploadId: string, data: UndiciBodyInit, partNumber: number, options?: UploadPartOptions): Promise<UploadPartResult>;
458
+ uploadPart(path: string, uploadId: string, data: string | Buffer | Uint8Array | Readable, partNumber: number, options?: UploadPartOptions): Promise<UploadPartResult>;
381
459
  /**
382
460
  * @remarks Uses [`ListParts`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html).
383
461
  * @throws {RangeError} If `key` is not at least 1 character long.
@@ -448,16 +526,13 @@ declare class S3Client {
448
526
  * TODO: Maybe move this into a separate free function?
449
527
  * @internal
450
528
  */
451
- [kSignedRequest](region: Region, endpoint: Endpoint, bucket: BucketName, method: HttpMethod, pathWithoutBucket: ObjectKey, query: string | undefined, body: UndiciBodyInit | undefined, additionalSignedHeaders: Record<string, string> | undefined, additionalUnsignedHeaders: Record<string, string> | undefined, contentHash: Buffer | undefined, signal: AbortSignal | undefined): Promise<Dispatcher.ResponseData<null>>;
452
- /**
453
- * @internal
454
- * @param {import("./index.d.ts").UndiciBodyInit} data TODO
455
- */
456
- [kWrite](path: ObjectKey, data: UndiciBodyInit, contentType: string, contentLength: number | undefined, contentHash: Buffer | undefined, rageStart: number | undefined, rangeEndExclusive: number | undefined, signal?: AbortSignal | undefined): Promise<void>;
529
+ [kSignedRequest](region: Region, endpoint: Endpoint, bucket: BucketName, method: HttpMethod, pathWithoutBucket: ObjectKey, query: string | undefined, body: string | Buffer | Uint8Array | Readable | undefined, additionalSignedHeaders: Record<string, string> | undefined, additionalUnsignedHeaders: Record<string, string> | undefined, contentHash: Buffer | undefined, signal: AbortSignal | undefined): Promise<Dispatcher.ResponseData<null>>;
530
+ /** @internal */
531
+ [kWrite](path: ObjectKey, data: string | Buffer | Uint8Array | Readable, contentType: string, contentLength: number | undefined, contentHash: Buffer | undefined, rageStart: number | undefined, rangeEndExclusive: number | undefined, signal?: AbortSignal | undefined): Promise<void>;
457
532
  /**
458
533
  * @internal
459
534
  */
460
- [kStream](path: ObjectKey, contentHash: Buffer | undefined, rageStart: number | undefined, rangeEndExclusive: number | undefined): stream_web.ReadableStream<Uint8Array<ArrayBufferLike>>;
535
+ [kStream](path: ObjectKey, contentHash: Buffer | undefined, rageStart: number | undefined, rangeEndExclusive: number | undefined): ReadableStream<Uint8Array>;
461
536
  }
462
537
 
463
538
  declare class S3Stat {
@@ -469,10 +544,6 @@ declare class S3Stat {
469
544
  static tryParseFromHeaders(headers: Record<string, string | string[] | undefined>): S3Stat | undefined;
470
545
  }
471
546
 
472
- type S3FileWriteOptions = {
473
- /** Content-Type of the file. */
474
- type?: string;
475
- };
476
547
  declare class S3File {
477
548
  #private;
478
549
  /** @internal */
@@ -533,7 +604,6 @@ declare class S3File {
533
604
  arrayBuffer(): Promise<ArrayBuffer>;
534
605
  text(): Promise<string>;
535
606
  blob(): Promise<Blob>;
536
- /** @returns {ReadableStream<Uint8Array>} */
537
607
  stream(): ReadableStream<Uint8Array>;
538
608
  /**
539
609
  * @param {ByteSource} data
@@ -543,14 +613,23 @@ declare class S3File {
543
613
  write(data: ByteSource, options?: S3FileWriteOptions): Promise<void>;
544
614
  }
545
615
  interface S3FileDeleteOptions extends OverridableS3ClientOptions {
616
+ /** Signal to abort the request. */
546
617
  signal?: AbortSignal;
547
618
  }
548
619
  interface S3StatOptions extends OverridableS3ClientOptions {
620
+ /** Signal to abort the request. */
549
621
  signal?: AbortSignal;
550
622
  }
551
623
  interface S3FileExistsOptions extends OverridableS3ClientOptions {
624
+ /** Signal to abort the request. */
552
625
  signal?: AbortSignal;
553
626
  }
627
+ type S3FileWriteOptions = {
628
+ /** Content-Type of the file. */
629
+ type?: string;
630
+ /** Signal to abort the request. */
631
+ signal?: AbortSignal;
632
+ };
554
633
 
555
634
  declare class S3Error extends Error {
556
635
  readonly code: string;
@@ -573,9 +652,7 @@ type ChecksumAlgorithm = "CRC32" | "CRC32C" | "CRC64NVME" | "SHA1" | "SHA256";
573
652
  type ChecksumType = "COMPOSITE" | "FULL_OBJECT";
574
653
  type PresignableHttpMethod = "GET" | "DELETE" | "PUT" | "HEAD";
575
654
  type HttpMethod = PresignableHttpMethod | "POST";
576
- /** Body values supported by undici. */
577
- type UndiciBodyInit = string | Buffer | Uint8Array | Readable;
578
- type ByteSource = UndiciBodyInit | Blob;
655
+ type ByteSource = string | Buffer | Uint8Array | Readable | Blob;
579
656
  /**
580
657
  * Implements [LocationInfo](https://docs.aws.amazon.com/AmazonS3/latest/API/API_LocationInfo.html)
581
658
  */
@@ -602,4 +679,4 @@ type AttachmentContentDisposition = {
602
679
  filename?: string;
603
680
  };
604
681
 
605
- export { type AbortMultipartUploadOptions, type Acl, type AttachmentContentDisposition, 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 ContentDisposition, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteBucketCorsOptions, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, type GetBucketCorsOptions, type GetBucketCorsResult, type HttpMethod, type InlineContentDisposition, 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 };
682
+ export { type AbortMultipartUploadOptions, type Acl, type AttachmentContentDisposition, 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 ContentDisposition, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteBucketCorsOptions, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, type GetBucketCorsOptions, type GetBucketCorsResult, type HttpMethod, type InlineContentDisposition, 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 UploadPartOptions, type UploadPartResult };
package/dist/index.js CHANGED
@@ -1293,10 +1293,7 @@ var S3Client = class {
1293
1293
  });
1294
1294
  }
1295
1295
  }
1296
- /**
1297
- * @internal
1298
- * @param {import("./index.d.ts").UndiciBodyInit} data TODO
1299
- */
1296
+ /** @internal */
1300
1297
  async [kWrite](path, data, contentType, contentLength, contentHash, rageStart, rangeEndExclusive, signal = void 0) {
1301
1298
  const bucket = this.#options.bucket;
1302
1299
  const endpoint = this.#options.endpoint;
@@ -1363,7 +1360,6 @@ var S3Client = class {
1363
1360
  const contentHashStr = contentHash?.toString("hex") ?? unsignedPayload;
1364
1361
  const headersToBeSigned = prepareHeadersForSigning({
1365
1362
  "amz-sdk-invocation-id": crypto.randomUUID(),
1366
- // TODO: Maybe support retries and do "amz-sdk-request": attempt=1; max=3
1367
1363
  host: url.host,
1368
1364
  range,
1369
1365
  // Hetzner doesnt care if the x-amz-content-sha256 header is missing, R2 requires it to be present
@@ -1683,7 +1679,6 @@ var S3File = class _S3File {
1683
1679
  headers: { "Content-Type": this.#contentType }
1684
1680
  }).blob();
1685
1681
  }
1686
- /** @returns {ReadableStream<Uint8Array>} */
1687
1682
  stream() {
1688
1683
  return this.#client[kStream](this.#path, void 0, this.#start, this.#end);
1689
1684
  }
@@ -1726,7 +1721,6 @@ var S3File = class _S3File {
1726
1721
  * @returns {Promise<void>}
1727
1722
  */
1728
1723
  async write(data, options = {}) {
1729
- const signal = void 0;
1730
1724
  const [bytes, length, hash] = await this.#transformData(data);
1731
1725
  return await this.#client[kWrite](
1732
1726
  this.#path,
@@ -1736,7 +1730,7 @@ var S3File = class _S3File {
1736
1730
  hash,
1737
1731
  this.#start,
1738
1732
  this.#end,
1739
- signal
1733
+ options.signal
1740
1734
  );
1741
1735
  }
1742
1736
  };
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.7.6",
5
+ "version": "0.7.8",
6
6
  "description": "A server-side S3 API for the regular user.",
7
7
  "keywords": [
8
8
  "s3",
@@ -44,17 +44,17 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "fast-xml-parser": "^5.2.5",
47
- "undici": "^7.11.0"
47
+ "undici": "^7.12.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@biomejs/biome": "2.1.1",
51
- "@testcontainers/localstack": "^11.2.1",
52
- "@testcontainers/minio": "^11.2.1",
53
- "@types/node": "^24.0.13",
54
- "@typescript/native-preview": "^7.0.0-dev.20250711.1",
55
- "expect": "^30.0.4",
50
+ "@biomejs/biome": "2.1.2",
51
+ "@testcontainers/localstack": "^11.3.2",
52
+ "@testcontainers/minio": "^11.3.2",
53
+ "@types/node": "^24.1.0",
54
+ "@typescript/native-preview": "^7.0.0-dev.20250723.1",
55
+ "expect": "^30.0.5",
56
56
  "lefthook": "^1.12.2",
57
- "testcontainers": "^11.2.1",
57
+ "testcontainers": "^11.3.2",
58
58
  "tsup": "^8.5.0",
59
59
  "tsx": "^4.20.3",
60
60
  "typedoc": "^0.28.7"