lean-s3 0.8.12 → 0.8.15

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
@@ -189,6 +189,19 @@ const client = new S3Client({
189
189
  });
190
190
  ```
191
191
 
192
+ ### Backblaze B2
193
+ ```js
194
+ // Docs: https://www.backblaze.com/apidocs/introduction-to-the-s3-compatible-api
195
+ const client = new S3Client({
196
+ // keep {region} placeholders (it is used internally).
197
+ endpoint: "https://s3.{region}.backblazeb2.com",
198
+ region: "<your-region>", // something like "eu-central-003"
199
+ bucket: "<your-bucket-name>",
200
+ accessKeyId: process.env.S3_ACCESS_KEY_ID, // <your-application-key-id>,
201
+ secretAccessKey: process.env.S3_SECRET_KEY, // <your-application-key>,
202
+ });
203
+ ```
204
+
192
205
  Popular S3 provider missing? Open an issue or file a PR!
193
206
 
194
207
  ## Tested On
@@ -197,6 +210,9 @@ To ensure compability across various providers and self-hosted services, all tes
197
210
  - Hetzner Object Storage
198
211
  - Cloudflare R2
199
212
  - Garage
213
+ - Backblaze B2
200
214
  - Minio
201
215
  - LocalStack
216
+ - RustFS
202
217
  - Ceph
218
+ - S3Mock
@@ -1,3 +1,4 @@
1
+ import * as nodeUtil from "node:util";
1
2
  import { Readable } from "node:stream";
2
3
  import { Dispatcher } from "undici";
3
4
 
@@ -557,6 +558,7 @@ declare class S3Client {
557
558
  * @internal
558
559
  */
559
560
  [kStream](path: ObjectKey, contentHash: Buffer | undefined, rageStart: number | undefined, rangeEndExclusive: number | undefined): ReadableStream<Uint8Array>;
561
+ [nodeUtil.inspect.custom](_depth?: number, options?: nodeUtil.InspectOptions): string;
560
562
  }
561
563
  //#endregion
562
564
  //#region src/S3Stat.d.ts
@@ -643,6 +645,7 @@ declare class S3File {
643
645
  * @param options Options for the copy operation.
644
646
  */
645
647
  copyTo(destination: string, options?: CopyObjectOptions): Promise<void>;
648
+ [nodeUtil.inspect.custom](_depth?: number, options?: nodeUtil.InspectOptions): string;
646
649
  }
647
650
  interface S3FileDeleteOptions extends OverridableS3ClientOptions {
648
651
  /** Signal to abort the request. */
@@ -666,22 +669,21 @@ type S3FileWriteOptions = {
666
669
  //#region src/S3Error.d.ts
667
670
  declare class S3Error extends Error {
668
671
  readonly code: string;
672
+ /** Path/key of the affected object. */
669
673
  readonly path: string;
670
674
  readonly message: string;
671
- readonly requestId: string | undefined;
672
- readonly hostId: string | undefined;
675
+ /** The HTTP status code. */
676
+ readonly status: number | undefined;
673
677
  constructor(code: string, path: string, {
674
678
  message,
675
- requestId,
676
- hostId,
677
- cause
679
+ cause,
680
+ status
678
681
  }?: S3ErrorOptions);
679
682
  }
680
683
  type S3ErrorOptions = {
681
684
  message?: string | undefined;
682
- requestId?: string | undefined;
683
- hostId?: string | undefined;
684
685
  cause?: unknown;
686
+ status?: number;
685
687
  };
686
688
  //#endregion
687
689
  //#region src/index.d.ts
@@ -1,3 +1,4 @@
1
+ import * as nodeUtil from "node:util";
1
2
  import { Readable } from "node:stream";
2
3
  import { Agent, request } from "undici";
3
4
  import { XMLBuilder, XMLParser } from "fast-xml-parser";
@@ -34,17 +35,17 @@ var S3Stat = class S3Stat {
34
35
  //#region src/S3Error.ts
35
36
  var S3Error = class extends Error {
36
37
  code;
38
+ /** Path/key of the affected object. */
37
39
  path;
38
40
  message;
39
- requestId;
40
- hostId;
41
- constructor(code, path, { message = void 0, requestId = void 0, hostId = void 0, cause = void 0 } = {}) {
41
+ /** The HTTP status code. */
42
+ status;
43
+ constructor(code, path, { message = void 0, cause = void 0, status = void 0 } = {}) {
42
44
  super(message, { cause });
43
45
  this.code = code;
44
46
  this.path = path;
45
47
  this.message = message ?? "Some unknown error occurred.";
46
- this.requestId = requestId;
47
- this.hostId = hostId;
48
+ this.status = status;
48
49
  }
49
50
  };
50
51
 
@@ -977,12 +978,17 @@ var S3Client = class {
977
978
  } catch (cause) {
978
979
  return controller.error(new S3Error("Unknown", path, {
979
980
  message: "Could not parse XML error response.",
981
+ status: response.statusCode,
980
982
  cause
981
983
  }));
982
984
  }
983
- return controller.error(new S3Error(error.Error.Code || "Unknown", path, { message: error.Error.Message || void 0 }));
985
+ return controller.error(new S3Error(error.Error.Code || "Unknown", path, {
986
+ message: error.Error.Message || void 0,
987
+ status: response.statusCode
988
+ }));
984
989
  }, onNetworkError);
985
990
  return controller.error(new S3Error("Unknown", path, {
991
+ status: response.statusCode,
986
992
  message: void 0,
987
993
  cause: responseText
988
994
  }));
@@ -995,6 +1001,17 @@ var S3Client = class {
995
1001
  }
996
1002
  });
997
1003
  }
1004
+ [nodeUtil.inspect.custom](_depth, options = {}) {
1005
+ if (options.depth === null) options.depth = 2;
1006
+ options.colors ??= true;
1007
+ const properties = {
1008
+ endpoint: this.#options.endpoint,
1009
+ bucket: this.#options.bucket,
1010
+ region: this.#options.region,
1011
+ accessKeyId: this.#options.accessKeyId
1012
+ };
1013
+ return `S3Client ${nodeUtil.formatWithOptions(options, properties)}`;
1014
+ }
998
1015
  };
999
1016
  function buildSearchParams(amzCredential, date, expiresIn, headerList, contentHashStr, storageClass, sessionToken, acl, responseContentDisposition) {
1000
1017
  let res = "";
@@ -1179,6 +1196,17 @@ var S3File = class S3File {
1179
1196
  async copyTo(destination, options = {}) {
1180
1197
  await this.#client.copyObject(this.#path, destination, options);
1181
1198
  }
1199
+ [nodeUtil.inspect.custom](_depth, options = {}) {
1200
+ if (options.depth === null) options.depth = 2;
1201
+ options.colors ??= true;
1202
+ const properties = {
1203
+ path: this.#path,
1204
+ start: this.#start,
1205
+ end: this.#end,
1206
+ contentType: this.#contentType
1207
+ };
1208
+ return `S3File ${nodeUtil.formatWithOptions(options, properties)}`;
1209
+ }
1182
1210
  };
1183
1211
 
1184
1212
  //#endregion
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.8.12",
5
+ "version": "0.8.15",
6
6
  "description": "A server-side S3 API for the regular user.",
7
7
  "keywords": [
8
8
  "s3",
@@ -26,12 +26,12 @@
26
26
  "type": "git",
27
27
  "url": "https://github.com/nikeee/lean-s3"
28
28
  },
29
- "exports": {
30
- "types": "./dist/index.d.ts",
31
- "default": "./dist/index.js"
32
- },
33
- "types": "./dist/index.d.ts",
29
+ "types": "./dist/index.d.mts",
30
+ "main": "./dist/index.mjs",
34
31
  "type": "module",
32
+ "files": [
33
+ "dist"
34
+ ],
35
35
  "scripts": {
36
36
  "build": "tsdown",
37
37
  "test": "tsgo && tsx --test src/*.test.ts src/test/*.test.ts",
@@ -39,27 +39,28 @@
39
39
  "ci": "biome ci ./src",
40
40
  "docs": "typedoc",
41
41
  "lint": "biome lint ./src",
42
- "format": "biome format --write ./src && biome lint --write ./src && biome check --write ./src",
42
+ "format": "biome check --write ./src",
43
43
  "prepublishOnly": "npm run build"
44
44
  },
45
45
  "dependencies": {
46
- "fast-xml-parser": "^5.3.0",
46
+ "fast-xml-parser": "^5.3.2",
47
47
  "undici": "^7.16.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@biomejs/biome": "2.3.2",
51
- "@testcontainers/localstack": "^11.7.2",
52
- "@testcontainers/minio": "^11.7.2",
53
- "@types/node": "^24.9.2",
54
- "@typescript/native-preview": "^7.0.0-dev.20251029.1",
50
+ "@biomejs/biome": "2.3.6",
51
+ "@testcontainers/localstack": "^11.8.1",
52
+ "@testcontainers/minio": "^11.8.1",
53
+ "@testcontainers/s3mock": "^11.8.1",
54
+ "@types/node": "^24.10.1",
55
+ "@typescript/native-preview": "^7.0.0-dev.20251117.1",
55
56
  "expect": "^30.2.0",
56
- "lefthook": "^2.0.2",
57
- "testcontainers": "^11.7.2",
58
- "tsdown": "^0.15.12",
57
+ "lefthook": "^2.0.4",
58
+ "testcontainers": "^11.8.1",
59
+ "tsdown": "^0.16.5",
59
60
  "tsx": "^4.20.6",
60
61
  "typedoc": "^0.28.14"
61
62
  },
62
63
  "engines": {
63
- "node": "^20.19.3 || ^22.17.0 || ^24.4.0 || ^25"
64
+ "node": "^20.19.5 || ^22.21.1 || ^24.11.0 || ^25.1.0"
64
65
  }
65
66
  }
package/tsdown.config.ts DELETED
@@ -1,6 +0,0 @@
1
- import { defineConfig } from "tsdown";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.ts"],
5
- target: "esnext",
6
- });