@nwire/storage-s3 0.9.2 → 0.10.1

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.
@@ -65,4 +65,3 @@ export interface S3StorageOptions {
65
65
  }
66
66
  /** Build an S3-backed Storage adapter. */
67
67
  export declare function s3Storage(options: S3StorageOptions): Storage;
68
- //# sourceMappingURL=storage-s3.d.ts.map
@@ -221,4 +221,3 @@ function translateError(err, key) {
221
221
  return new StorageObjectNotFoundError(key);
222
222
  return err;
223
223
  }
224
- //# sourceMappingURL=storage-s3.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nwire/storage-s3",
3
- "version": "0.9.2",
3
+ "version": "0.10.1",
4
4
  "description": "Nwire — S3 storage adapter. Works with AWS S3, MinIO, Cloudflare R2, Backblaze B2, and anything else speaking the S3 API. Wraps @aws-sdk/client-s3 + @aws-sdk/s3-request-presigner.",
5
5
  "keywords": [
6
6
  "adapter",
@@ -32,13 +32,13 @@
32
32
  "dependencies": {
33
33
  "@aws-sdk/client-s3": "^3.700.0",
34
34
  "@aws-sdk/s3-request-presigner": "^3.700.0",
35
- "@nwire/storage": "0.9.2"
35
+ "@nwire/storage": "0.10.1"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^22.19.9",
39
39
  "typescript": "^5.9.3",
40
40
  "vitest": "^4.1.6",
41
- "@nwire/test-kit": "0.9.2"
41
+ "@nwire/test-kit": "0.10.1"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",
@@ -1,23 +0,0 @@
1
- /**
2
- * Integration test — exercises `@nwire/storage-s3` against real MinIO.
3
- *
4
- * MinIO + the `nwire-dev` bucket come from the workspace docker-compose
5
- * (`nwire infra up` or `docker compose up -d minio minio-bootstrap`).
6
- * When MinIO isn't reachable on `127.0.0.1:9000`, the whole suite skips
7
- * cleanly — the default `pnpm vitest run` stays fast and self-contained,
8
- * and CI gets a deterministic skip rather than a flaky failure.
9
- *
10
- * Why exercise MinIO instead of trusting the unit tests:
11
- *
12
- * - Presigned URLs (`url()`) can only be verified against a server
13
- * that signs the URL the same way it later validates it. A stub
14
- * can't catch sig-version mismatches, path-style bugs, or auth
15
- * header drift across SDK upgrades.
16
- * - `forcePathStyle` + `endpoint` interactions are MinIO-specific and
17
- * break silently if the SDK changes how it composes URLs.
18
- * - Real round-trips through the S3 protocol catch encoding bugs
19
- * (binary bodies, metadata header casing, etag quoting) that pure
20
- * command-construction stubs miss.
21
- */
22
- export {};
23
- //# sourceMappingURL=storage-s3.integration.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/storage-s3.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
@@ -1,152 +0,0 @@
1
- /**
2
- * Integration test — exercises `@nwire/storage-s3` against real MinIO.
3
- *
4
- * MinIO + the `nwire-dev` bucket come from the workspace docker-compose
5
- * (`nwire infra up` or `docker compose up -d minio minio-bootstrap`).
6
- * When MinIO isn't reachable on `127.0.0.1:9000`, the whole suite skips
7
- * cleanly — the default `pnpm vitest run` stays fast and self-contained,
8
- * and CI gets a deterministic skip rather than a flaky failure.
9
- *
10
- * Why exercise MinIO instead of trusting the unit tests:
11
- *
12
- * - Presigned URLs (`url()`) can only be verified against a server
13
- * that signs the URL the same way it later validates it. A stub
14
- * can't catch sig-version mismatches, path-style bugs, or auth
15
- * header drift across SDK upgrades.
16
- * - `forcePathStyle` + `endpoint` interactions are MinIO-specific and
17
- * break silently if the SDK changes how it composes URLs.
18
- * - Real round-trips through the S3 protocol catch encoding bugs
19
- * (binary bodies, metadata header casing, etag quoting) that pure
20
- * command-construction stubs miss.
21
- */
22
- import { describe, it, expect, beforeAll, afterAll } from "vitest";
23
- import { randomUUID } from "node:crypto";
24
- import { isReachable } from "@nwire/test-kit";
25
- import { s3Storage } from "../storage-s3.js";
26
- import { StorageObjectNotFoundError } from "@nwire/storage";
27
- const MINIO_HOST = "127.0.0.1";
28
- const MINIO_PORT = 9000;
29
- const BUCKET = "nwire-dev";
30
- const reachable = await isReachable(MINIO_HOST, MINIO_PORT, 800);
31
- describe.skipIf(!reachable)("storage-s3 ↔ real MinIO", () => {
32
- let storage;
33
- // Namespace every run so concurrent CI workers and rerun-after-fail
34
- // don't trip over each other's keys.
35
- const ns = `tests/${randomUUID().slice(0, 8)}/`;
36
- beforeAll(() => {
37
- storage = s3Storage({
38
- bucket: BUCKET,
39
- region: "us-east-1",
40
- endpoint: `http://${MINIO_HOST}:${MINIO_PORT}`,
41
- forcePathStyle: true,
42
- credentials: { accessKeyId: "minioadmin", secretAccessKey: "minioadmin" },
43
- keyPrefix: ns,
44
- });
45
- });
46
- afterAll(async () => {
47
- // Best-effort cleanup — list and delete anything our prefix wrote.
48
- try {
49
- const page = await storage.list();
50
- for (const e of page.entries)
51
- await storage.delete(e.key);
52
- }
53
- catch {
54
- /* ignore — test isolation should keep these uncontended */
55
- }
56
- await storage.shutdown?.();
57
- });
58
- it("HeadBucket succeeds — healthCheck passes against MinIO", async () => {
59
- await expect(storage.healthCheck()).resolves.toBeUndefined();
60
- });
61
- it("put → get round-trips a UTF-8 string body with the right content type", async () => {
62
- const result = await storage.put("hello.txt", "Hello, MinIO!", {
63
- contentType: "text/plain",
64
- metadata: { sender: "phase-77" },
65
- });
66
- expect(result.size).toBe(13);
67
- expect(result.etag).toMatch(/^"?[a-f0-9]{32}/i);
68
- const back = await storage.get("hello.txt");
69
- expect(back.body.toString("utf-8")).toBe("Hello, MinIO!");
70
- expect(back.contentType).toBe("text/plain");
71
- expect(back.size).toBe(13);
72
- // MinIO + S3 normalize metadata to lowercase keys.
73
- expect(back.metadata?.sender).toBe("phase-77");
74
- });
75
- it("put accepts a binary Buffer and preserves bytes exactly", async () => {
76
- const bytes = Buffer.from([0xde, 0xad, 0xbe, 0xef, 0x00, 0xff, 0x7f]);
77
- await storage.put("binary.bin", bytes);
78
- const back = await storage.get("binary.bin");
79
- expect(Buffer.compare(back.body, bytes)).toBe(0);
80
- });
81
- it("get on a missing key throws StorageObjectNotFoundError", async () => {
82
- await expect(storage.get("missing/" + randomUUID())).rejects.toBeInstanceOf(StorageObjectNotFoundError);
83
- });
84
- it("exists() flips false → true → false across put + delete", async () => {
85
- const key = "lifecycle.txt";
86
- expect(await storage.exists(key)).toBe(false);
87
- await storage.put(key, "x");
88
- expect(await storage.exists(key)).toBe(true);
89
- await storage.delete(key);
90
- expect(await storage.exists(key)).toBe(false);
91
- });
92
- it("list() returns the entries we wrote, with our prefix stripped", async () => {
93
- // Fresh sub-namespace to keep the assertion simple.
94
- const inner = s3Storage({
95
- bucket: BUCKET,
96
- region: "us-east-1",
97
- endpoint: `http://${MINIO_HOST}:${MINIO_PORT}`,
98
- forcePathStyle: true,
99
- credentials: { accessKeyId: "minioadmin", secretAccessKey: "minioadmin" },
100
- keyPrefix: `${ns}list-test/`,
101
- });
102
- try {
103
- await inner.put("a.txt", "1");
104
- await inner.put("b.txt", "22");
105
- await inner.put("c/d.txt", "333");
106
- const page = await inner.list();
107
- const keys = page.entries.map((e) => e.key).sort();
108
- expect(keys).toEqual(["a.txt", "b.txt", "c/d.txt"]);
109
- const a = page.entries.find((e) => e.key === "a.txt");
110
- expect(a.size).toBe(1);
111
- }
112
- finally {
113
- await inner.shutdown?.();
114
- }
115
- });
116
- it("presigned GET url roundtrips via plain fetch", async () => {
117
- const key = "presigned.txt";
118
- await storage.put(key, "via signed url", { contentType: "text/plain" });
119
- const url = await storage.url(key, { expiresInSeconds: 60 });
120
- expect(url).toMatch(/X-Amz-Signature=/);
121
- const res = await fetch(url);
122
- expect(res.status).toBe(200);
123
- expect(await res.text()).toBe("via signed url");
124
- });
125
- it("presigned PUT url accepts a fetch-driven upload", async () => {
126
- const key = "uploaded-via-signed.txt";
127
- const url = await storage.url(key, {
128
- method: "put",
129
- contentType: "text/plain",
130
- expiresInSeconds: 60,
131
- });
132
- const res = await fetch(url, {
133
- method: "PUT",
134
- headers: { "content-type": "text/plain" },
135
- body: "uploaded through a presigned URL",
136
- });
137
- expect(res.ok).toBe(true);
138
- const back = await storage.get(key);
139
- expect(back.body.toString("utf-8")).toBe("uploaded through a presigned URL");
140
- });
141
- it("getStream() yields the same bytes as get()", async () => {
142
- const key = "stream.txt";
143
- await storage.put(key, "stream me");
144
- const stream = await storage.getStream(key);
145
- const chunks = [];
146
- for await (const c of stream) {
147
- chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c));
148
- }
149
- expect(Buffer.concat(chunks).toString("utf-8")).toBe("stream me");
150
- });
151
- });
152
- //# sourceMappingURL=storage-s3.integration.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.integration.test.js","sourceRoot":"","sources":["../../src/__tests__/storage-s3.integration.test.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- /**
2
- * `@nwire/storage-s3` — unit tests with a hand-rolled `S3Client.send`
3
- * stub. We're verifying:
4
- *
5
- * - the right command + parameters reach the SDK
6
- * - GetObject NotFound is translated to StorageObjectNotFoundError
7
- * - body assembly works for an async-iterable response (the Node case)
8
- *
9
- * Integration tests against real MinIO live elsewhere — the docker-
10
- * compose has the bucket ready when those run.
11
- */
12
- export {};
13
- //# sourceMappingURL=storage-s3.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/storage-s3.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -1,127 +0,0 @@
1
- /**
2
- * `@nwire/storage-s3` — unit tests with a hand-rolled `S3Client.send`
3
- * stub. We're verifying:
4
- *
5
- * - the right command + parameters reach the SDK
6
- * - GetObject NotFound is translated to StorageObjectNotFoundError
7
- * - body assembly works for an async-iterable response (the Node case)
8
- *
9
- * Integration tests against real MinIO live elsewhere — the docker-
10
- * compose has the bucket ready when those run.
11
- */
12
- import { describe, it, expect, vi } from "vitest";
13
- import { Readable } from "node:stream";
14
- import { s3Storage } from "../storage-s3.js";
15
- import { StorageObjectNotFoundError } from "@nwire/storage";
16
- function makeClientStub(responses) {
17
- const calls = [];
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- const send = vi.fn(async (cmd) => {
20
- const name = cmd.constructor.name;
21
- calls.push({ name, input: cmd.input });
22
- const reply = responses[name];
23
- if (reply instanceof Error)
24
- throw reply;
25
- return reply ?? {};
26
- });
27
- const stub = { send, destroy: vi.fn() };
28
- return { stub, send, calls };
29
- }
30
- describe("s3Storage — command translation", () => {
31
- it("put sends a PutObjectCommand with the right Bucket + Key + Body", async () => {
32
- const { stub, calls } = makeClientStub({
33
- PutObjectCommand: { ETag: '"abc"' },
34
- });
35
- const storage = s3Storage({ bucket: "uploads", client: stub });
36
- const result = await storage.put("a/b.txt", "hello", {
37
- contentType: "text/plain",
38
- metadata: { user: "alice" },
39
- });
40
- expect(result.etag).toBe('"abc"');
41
- expect(result.size).toBe(5);
42
- expect(calls).toEqual([
43
- {
44
- name: "PutObjectCommand",
45
- input: {
46
- Bucket: "uploads",
47
- Key: "a/b.txt",
48
- Body: "hello",
49
- ContentType: "text/plain",
50
- CacheControl: undefined,
51
- Metadata: { user: "alice" },
52
- },
53
- },
54
- ]);
55
- });
56
- it("get assembles the body from a Node Readable stream", async () => {
57
- const { stub } = makeClientStub({
58
- GetObjectCommand: {
59
- Body: Readable.from(["hel", "lo"]),
60
- ContentType: "text/plain",
61
- ContentLength: 5,
62
- ETag: '"abc"',
63
- },
64
- });
65
- const storage = s3Storage({ bucket: "uploads", client: stub });
66
- const obj = await storage.get("a/b.txt");
67
- expect(obj.body.toString("utf-8")).toBe("hello");
68
- expect(obj.contentType).toBe("text/plain");
69
- expect(obj.size).toBe(5);
70
- });
71
- it("get translates NoSuchKey into StorageObjectNotFoundError", async () => {
72
- const err = Object.assign(new Error("not found"), { name: "NoSuchKey" });
73
- const { stub } = makeClientStub({ GetObjectCommand: err });
74
- const storage = s3Storage({ bucket: "uploads", client: stub });
75
- await expect(storage.get("missing.txt")).rejects.toBeInstanceOf(StorageObjectNotFoundError);
76
- });
77
- it("exists returns false on 404, true on success", async () => {
78
- const { stub: ok } = makeClientStub({
79
- HeadObjectCommand: { ContentLength: 1 },
80
- });
81
- expect(await s3Storage({ bucket: "u", client: ok }).exists("a")).toBe(true);
82
- const err = Object.assign(new Error(""), {
83
- name: "NotFound",
84
- $metadata: { httpStatusCode: 404 },
85
- });
86
- const { stub: missing } = makeClientStub({ HeadObjectCommand: err });
87
- expect(await s3Storage({ bucket: "u", client: missing }).exists("a")).toBe(false);
88
- });
89
- it("list maps Contents into StorageEntry array", async () => {
90
- const { stub } = makeClientStub({
91
- ListObjectsV2Command: {
92
- Contents: [
93
- { Key: "a", Size: 1, LastModified: new Date(0), ETag: '"x"' },
94
- { Key: "b", Size: 2, LastModified: new Date(1), ETag: '"y"' },
95
- ],
96
- IsTruncated: false,
97
- },
98
- });
99
- const page = await s3Storage({ bucket: "u", client: stub }).list();
100
- expect(page.entries.map((e) => e.key)).toEqual(["a", "b"]);
101
- expect(page.nextCursor).toBeUndefined();
102
- });
103
- it("keyPrefix is applied to every operation and stripped on list", async () => {
104
- const { stub, calls } = makeClientStub({
105
- PutObjectCommand: {},
106
- ListObjectsV2Command: {
107
- Contents: [{ Key: "tenants/acme/a", Size: 1 }],
108
- },
109
- });
110
- const storage = s3Storage({ bucket: "u", client: stub, keyPrefix: "tenants/acme/" });
111
- await storage.put("a", "x");
112
- const page = await storage.list();
113
- expect(calls[0].input).toMatchObject({ Key: "tenants/acme/a" });
114
- expect(page.entries[0].key).toBe("a");
115
- });
116
- it("healthCheck calls HeadBucket", async () => {
117
- const { stub, calls } = makeClientStub({ HeadBucketCommand: {} });
118
- await s3Storage({ bucket: "u", client: stub }).healthCheck();
119
- expect(calls[0].name).toBe("HeadBucketCommand");
120
- });
121
- it("shutdown destroys the SDK client", async () => {
122
- const { stub } = makeClientStub({});
123
- await s3Storage({ bucket: "u", client: stub }).shutdown();
124
- expect(stub.destroy).toHaveBeenCalled();
125
- });
126
- });
127
- //# sourceMappingURL=storage-s3.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.test.js","sourceRoot":"","sources":["../../src/__tests__/storage-s3.test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.d.ts","sourceRoot":"","sources":["../src/storage-s3.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EACL,QAAQ,EAQT,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,OAAO,EASb,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;QACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;IACF;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAO5D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage-s3.js","sourceRoot":"","sources":["../src/storage-s3.ts"],"names":[],"mappings":"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"}