@voyant-travel/storage 0.105.0 → 0.106.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/routes.d.ts CHANGED
@@ -6,16 +6,12 @@
6
6
  * shares the same content-type safety + key-parsing helpers; splitting it would
7
7
  * scatter a single storage-backed contract.
8
8
  *
9
- * POST /v1/uploads — multipart file upload → storage ticket
10
- * POST /v1/admin/uploads — (admin alias)
11
- * POST /v1/uploads/videovideo upload ticket (deployment signer)
12
- * POST /v1/admin/uploads/video — (admin alias)
13
- * GET /v1/media/* — serve stored bytes (hardened)
14
- * GET /v1/admin/media/* — (admin alias)
9
+ * POST /v1/admin/uploads — multipart file upload → storage ticket
10
+ * POST /v1/admin/uploads/video video upload ticket (deployment signer)
11
+ * GET /v1/admin/media/*serve stored bytes (hardened)
15
12
  *
16
- * These routes register ABSOLUTE paths (both the public `/v1/*` and the
17
- * `/v1/admin/*` aliases), so a deployment mounts the returned `Hono` at the
18
- * app root rather than under a module prefix.
13
+ * These routes register ABSOLUTE admin paths, so a deployment mounts the
14
+ * returned `Hono` at the app root rather than under a module prefix.
19
15
  *
20
16
  * The deployment supplies the storage-backed specifics via `options`:
21
17
  * - `resolveStorage(c)` — the R2-backed `StorageProvider` for this request
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyBjD,8DAA8D;AAC9D,eAAO,MAAM,2BAA2B;;;;;;;;iBAQtC,CAAA;AAEF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAMlF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAAA;IAClD;;;OAGG;IACH,qBAAqB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpF;;;OAGG;IACH,mBAAmB,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1C;AA4BD,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGjD;AAiGD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAqGnE"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyBjD,8DAA8D;AAC9D,eAAO,MAAM,2BAA2B;;;;;;;;iBAQtC,CAAA;AAEF,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAMlF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAAA;IAClD;;;OAGG;IACH,qBAAqB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpF;;;OAGG;IACH,mBAAmB,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1C;AA4BD,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGjD;AAiGD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAkGnE"}
package/dist/routes.js CHANGED
@@ -6,16 +6,12 @@
6
6
  * shares the same content-type safety + key-parsing helpers; splitting it would
7
7
  * scatter a single storage-backed contract.
8
8
  *
9
- * POST /v1/uploads — multipart file upload → storage ticket
10
- * POST /v1/admin/uploads — (admin alias)
11
- * POST /v1/uploads/videovideo upload ticket (deployment signer)
12
- * POST /v1/admin/uploads/video — (admin alias)
13
- * GET /v1/media/* — serve stored bytes (hardened)
14
- * GET /v1/admin/media/* — (admin alias)
9
+ * POST /v1/admin/uploads — multipart file upload → storage ticket
10
+ * POST /v1/admin/uploads/video video upload ticket (deployment signer)
11
+ * GET /v1/admin/media/*serve stored bytes (hardened)
15
12
  *
16
- * These routes register ABSOLUTE paths (both the public `/v1/*` and the
17
- * `/v1/admin/*` aliases), so a deployment mounts the returned `Hono` at the
18
- * app root rather than under a module prefix.
13
+ * These routes register ABSOLUTE admin paths, so a deployment mounts the
14
+ * returned `Hono` at the app root rather than under a module prefix.
19
15
  *
20
16
  * The deployment supplies the storage-backed specifics via `options`:
21
17
  * - `resolveStorage(c)` — the R2-backed `StorageProvider` for this request
@@ -217,7 +213,6 @@ export function createMediaRoutes(options) {
217
213
  size: file.size,
218
214
  });
219
215
  };
220
- hono.post("/v1/uploads", handleUpload);
221
216
  hono.post("/v1/admin/uploads", handleUpload);
222
217
  const handleVideoUploadTicket = async (c) => {
223
218
  let raw;
@@ -234,7 +229,6 @@ export function createMediaRoutes(options) {
234
229
  const ticket = await options.signVideoUploadTicket(c, parsed.data);
235
230
  return c.json(ticket);
236
231
  };
237
- hono.post("/v1/uploads/video", handleVideoUploadTicket);
238
232
  hono.post("/v1/admin/uploads/video", handleVideoUploadTicket);
239
233
  const handleMediaServe = async (c) => {
240
234
  const storage = options.resolveStorage(c);
@@ -257,7 +251,6 @@ export function createMediaRoutes(options) {
257
251
  headers.set("Content-Length", String(buffer.byteLength));
258
252
  return new Response(buffer, { headers });
259
253
  };
260
- hono.get("/v1/media/*", handleMediaServe);
261
254
  hono.get("/v1/admin/media/*", handleMediaServe);
262
255
  return hono;
263
256
  }
@@ -37,7 +37,7 @@ describe("media routes", () => {
37
37
  it("streams stored media by allowed key as an attachment", async () => {
38
38
  const storage = makeStorage({ get: vi.fn(async () => new TextEncoder().encode("pdf").buffer) });
39
39
  const app = mountApp({ resolveStorage: () => storage });
40
- const response = await app.request("/v1/media/brochures/products/example.pdf");
40
+ const response = await app.request("/v1/admin/media/brochures/products/example.pdf");
41
41
  expect(response.status).toBe(200);
42
42
  expect(response.headers.get("content-type")).toBe("application/pdf");
43
43
  expect(response.headers.get("x-content-type-options")).toBe("nosniff");
@@ -47,7 +47,7 @@ describe("media routes", () => {
47
47
  it("rejects media keys outside allowed upload prefixes", async () => {
48
48
  const get = vi.fn(async () => new TextEncoder().encode("private").buffer);
49
49
  const app = mountApp({ resolveStorage: () => makeStorage({ get }) });
50
- const response = await app.request("/v1/media/private/example.pdf");
50
+ const response = await app.request("/v1/admin/media/private/example.pdf");
51
51
  expect(response.status).toBe(400);
52
52
  expect(get).not.toHaveBeenCalled();
53
53
  });
@@ -56,7 +56,7 @@ describe("media routes", () => {
56
56
  get: vi.fn(async () => new TextEncoder().encode("<svg />").buffer),
57
57
  });
58
58
  const app = mountApp({ resolveStorage: () => storage });
59
- const response = await app.request("/v1/media/uploads/evil.svg");
59
+ const response = await app.request("/v1/admin/media/uploads/evil.svg");
60
60
  expect(response.status).toBe(200);
61
61
  expect(response.headers.get("content-type")).toBe("application/octet-stream");
62
62
  expect(response.headers.get("content-disposition")).toBe('attachment; filename="evil.svg"');
@@ -72,14 +72,14 @@ describe("media routes", () => {
72
72
  });
73
73
  it("responds 503 when storage is unconfigured", async () => {
74
74
  const app = mountApp({ resolveStorage: () => null });
75
- const response = await app.request("/v1/media/uploads/example.pdf");
75
+ const response = await app.request("/v1/admin/media/uploads/example.pdf");
76
76
  expect(response.status).toBe(503);
77
77
  });
78
78
  it("rejects unsafe upload types", async () => {
79
79
  const upload = vi.fn();
80
80
  const app = mountApp({ resolveStorage: () => makeStorage({ upload }) });
81
81
  const boundary = "----voyant-test-boundary";
82
- const response = await app.request("/v1/uploads", {
82
+ const response = await app.request("/v1/admin/uploads", {
83
83
  method: "POST",
84
84
  headers: { "content-type": `multipart/form-data; boundary=${boundary}` },
85
85
  body: multipartFileBody({
@@ -95,7 +95,7 @@ describe("media routes", () => {
95
95
  it("accepts bounded uploads on the admin surface", async () => {
96
96
  const upload = vi.fn(async (_body, options) => ({
97
97
  key: options.key,
98
- url: `/api/v1/media/${options.key}`,
98
+ url: `/api/v1/admin/media/${options.key}`,
99
99
  }));
100
100
  const app = mountApp({ resolveStorage: () => makeStorage({ upload }) });
101
101
  const boundary = "----voyant-test-boundary";
@@ -133,7 +133,7 @@ describe("media routes", () => {
133
133
  it("rejects an invalid video upload ticket body", async () => {
134
134
  const signVideoUploadTicket = vi.fn();
135
135
  const app = mountApp({ signVideoUploadTicket });
136
- const response = await app.request("/v1/uploads/video", {
136
+ const response = await app.request("/v1/admin/uploads/video", {
137
137
  method: "POST",
138
138
  headers: { "content-type": "application/json" },
139
139
  body: JSON.stringify({ fileSize: -1, maxDurationSeconds: 60 }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/storage",
3
- "version": "0.105.0",
3
+ "version": "0.106.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -69,10 +69,10 @@
69
69
  "directory": "packages/storage"
70
70
  },
71
71
  "scripts": {
72
- "typecheck": "tsc --noEmit",
72
+ "typecheck": "tsc -p tsconfig.typecheck.json",
73
73
  "lint": "biome check src/",
74
74
  "test": "vitest run",
75
- "build": "tsc -p tsconfig.json",
75
+ "build": "tsc -p tsconfig.build.json",
76
76
  "clean": "rm -rf dist tsconfig.tsbuildinfo"
77
77
  },
78
78
  "main": "./dist/index.js",