lean-s3 0.6.2 → 0.6.3

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/README.md CHANGED
@@ -141,6 +141,9 @@ See [DESIGN_DECISIONS.md](./DESIGN_DECISIONS.md) to read about why this library
141
141
  - ✅ [`UploadPart`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html) via `.uploadPart`
142
142
  - ✅ [`CompleteMultipartUpload`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html) via `.completeMultipartUpload`
143
143
  - ✅ [`AbortMultipartUpload`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html) via `.abortMultipartUpload`
144
+ - ✅ [`PutBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html) via `.putBucketCors`
145
+ - ✅ [`GetBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html) via `.getBucketCors`
146
+ - ✅ [`DeleteBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html) via `.deleteBucketCors`
144
147
 
145
148
  ## Example Configurations
146
149
  ### Hetzner Object Storage
package/dist/index.d.ts CHANGED
@@ -208,6 +208,35 @@ type BucketDeletionOptions = {
208
208
  type BucketExistsOptions = {
209
209
  signal?: AbortSignal;
210
210
  };
211
+ type BucketCorsRules = readonly BucketCorsRule[];
212
+ type BucketCorsRule = {
213
+ allowedMethods: readonly HttpMethod[];
214
+ /** One or more origins you want customers to be able to access the bucket from. */
215
+ allowedOrigins: readonly string[];
216
+ /** Headers that are specified in the `Access-Control-Request-Headers` header. These headers are allowed in a preflight `OPTIONS` request. */
217
+ allowedHeaders?: readonly string[];
218
+ /** One or more headers in the response that you want customers to be able to access from their applications. */
219
+ exposeHeaders?: readonly string[];
220
+ /** Unique identifier for the rule. The value cannot be longer than 255 characters. */
221
+ id?: string;
222
+ /** The time in seconds that your browser is to cache the preflight response for the specified resource. */
223
+ maxAgeSeconds?: number;
224
+ };
225
+ type PutBucketCorsOptions = {
226
+ bucket?: string;
227
+ signal?: AbortSignal;
228
+ };
229
+ type DeleteBucketCorsOptions = {
230
+ bucket?: string;
231
+ signal?: AbortSignal;
232
+ };
233
+ type GetBucketCorsOptions = {
234
+ bucket?: string;
235
+ signal?: AbortSignal;
236
+ };
237
+ type GetBucketCorsResult = {
238
+ rules: BucketCorsRule[];
239
+ };
211
240
  /**
212
241
  * A configured S3 bucket instance for managing files.
213
242
  *
@@ -232,6 +261,11 @@ declare class S3Client {
232
261
  * @param options The default options to use for the S3 client.
233
262
  */
234
263
  constructor(options: S3ClientOptions);
264
+ cors: {
265
+ get: () => void;
266
+ set: () => void;
267
+ delete: () => void;
268
+ };
235
269
  /**
236
270
  * Creates an S3File instance for the given path.
237
271
  *
@@ -345,6 +379,18 @@ declare class S3Client {
345
379
  * @remarks Uses [`HeadBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html).
346
380
  */
347
381
  bucketExists(name: string, options?: BucketExistsOptions): Promise<boolean>;
382
+ /**
383
+ * @remarks Uses [`PutBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html).
384
+ */
385
+ putBucketCors(rules: BucketCorsRules, options?: PutBucketCorsOptions): Promise<void>;
386
+ /**
387
+ * @remarks Uses [`GetBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html).
388
+ */
389
+ getBucketCors(options?: GetBucketCorsOptions): Promise<GetBucketCorsResult>;
390
+ /**
391
+ * @remarks Uses [`DeleteBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html).
392
+ */
393
+ deleteBucketCors(options?: DeleteBucketCorsOptions): Promise<void>;
348
394
  /**
349
395
  * Uses [`ListObjectsV2`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) to iterate over all keys. Pagination and continuation is handled internally.
350
396
  */
@@ -490,4 +536,4 @@ type BucketInfo = {
490
536
  type?: string;
491
537
  };
492
538
 
493
- export { type AbortMultipartUploadOptions, type Acl, 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 HttpMethod, type ListMultipartUploadsOptions, type ListMultipartUploadsResult, type ListObjectsIteratingOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListPartsResult, type MultipartUpload, type MultipartUploadPart, type OverridableS3ClientOptions, type PresignableHttpMethod, 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 };
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 };
package/dist/index.js CHANGED
@@ -404,6 +404,14 @@ var S3Client = class {
404
404
  sessionToken
405
405
  };
406
406
  }
407
+ cors = {
408
+ get: () => {
409
+ },
410
+ set: () => {
411
+ },
412
+ delete: () => {
413
+ }
414
+ };
407
415
  /**
408
416
  * Creates an S3File instance for the given path.
409
417
  *
@@ -912,6 +920,90 @@ var S3Client = class {
912
920
  }
913
921
  throw new Error(`Response code not supported: ${response.statusCode}`);
914
922
  }
923
+ //#region bucket cors
924
+ /**
925
+ * @remarks Uses [`PutBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html).
926
+ */
927
+ async putBucketCors(rules, options = {}) {
928
+ const body = xmlBuilder.build({
929
+ CORSConfiguration: {
930
+ CORSRule: rules.map((r) => ({
931
+ AllowedOrigin: r.allowedOrigins,
932
+ AllowedMethod: r.allowedMethods,
933
+ ExposeHeader: r.exposeHeaders,
934
+ ID: r.id ?? void 0,
935
+ MaxAgeSeconds: r.maxAgeSeconds ?? void 0
936
+ }))
937
+ }
938
+ });
939
+ const response = await this[signedRequest](
940
+ "PUT",
941
+ "",
942
+ "cors=",
943
+ // "=" is needed by minio for some reason
944
+ body,
945
+ {
946
+ "content-md5": md5Base64(body)
947
+ },
948
+ void 0,
949
+ void 0,
950
+ ensureValidBucketName(options.bucket ?? this.#options.bucket),
951
+ options.signal
952
+ );
953
+ if (response.statusCode === 200) {
954
+ response.body.dump();
955
+ return;
956
+ }
957
+ if (400 <= response.statusCode && response.statusCode < 500) {
958
+ throw await getResponseError(response, "");
959
+ }
960
+ throw new Error(
961
+ `Response code not implemented yet: ${response.statusCode}`
962
+ );
963
+ }
964
+ /**
965
+ * @remarks Uses [`GetBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html).
966
+ */
967
+ async getBucketCors(options = {}) {
968
+ const response = await this[signedRequest](
969
+ "GET",
970
+ "",
971
+ "cors=",
972
+ // "=" is needed by minio for some reason
973
+ void 0,
974
+ void 0,
975
+ void 0,
976
+ void 0,
977
+ ensureValidBucketName(options.bucket ?? this.#options.bucket),
978
+ options.signal
979
+ );
980
+ if (response.statusCode !== 200) {
981
+ response.body.dump();
982
+ throw fromStatusCode(response.statusCode, "");
983
+ }
984
+ throw new Error("Not implemented");
985
+ }
986
+ /**
987
+ * @remarks Uses [`DeleteBucketCors`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html).
988
+ */
989
+ async deleteBucketCors(options = {}) {
990
+ const response = await this[signedRequest](
991
+ "DELETE",
992
+ "",
993
+ "cors=",
994
+ // "=" is needed by minio for some reason
995
+ void 0,
996
+ void 0,
997
+ void 0,
998
+ void 0,
999
+ ensureValidBucketName(options.bucket ?? this.#options.bucket),
1000
+ options.signal
1001
+ );
1002
+ if (response.statusCode !== 204) {
1003
+ response.body.dump();
1004
+ throw fromStatusCode(response.statusCode, "");
1005
+ }
1006
+ }
915
1007
  //#endregion
916
1008
  //#region list objects
917
1009
  /**
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.2",
5
+ "version": "0.6.3",
6
6
  "description": "A server-side S3 API for the regular user.",
7
7
  "keywords": [
8
8
  "s3",
@@ -44,19 +44,19 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "fast-xml-parser": "^5.2.5",
47
- "undici": "^7.10.0"
47
+ "undici": "^7.11.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@biomejs/biome": "2.0.5",
50
+ "@biomejs/biome": "2.0.6",
51
51
  "@testcontainers/localstack": "^11.0.3",
52
52
  "@testcontainers/minio": "^11.0.3",
53
- "@types/node": "^24.0.4",
54
- "@typescript/native-preview": "^7.0.0-dev.20250626.1",
53
+ "@types/node": "^24.0.7",
54
+ "@typescript/native-preview": "^7.0.0-dev.20250629.1",
55
55
  "expect": "^30.0.3",
56
56
  "lefthook": "^1.11.14",
57
57
  "tsup": "^8.5.0",
58
58
  "tsx": "^4.20.3",
59
- "typedoc": "^0.28.5"
59
+ "typedoc": "^0.28.6"
60
60
  },
61
61
  "engines": {
62
62
  "node": "^20.19.2 || ^22.16.0 || ^24.2.0"