@demiurgejs/core 0.2.0-beta.5 → 0.2.0-beta.6

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.
Files changed (92) hide show
  1. package/README.md +14 -0
  2. package/bin/demiurge.mjs +6 -0
  3. package/dist/chunks/{document-shell-9GPwtcTt.js → document-shell-C0aPrkhd.js} +2 -2
  4. package/dist/chunks/{document-shell-9GPwtcTt.js.map → document-shell-C0aPrkhd.js.map} +1 -1
  5. package/dist/chunks/image-CRerJ5BY.js +145 -0
  6. package/dist/chunks/image-CRerJ5BY.js.map +1 -0
  7. package/dist/chunks/{image-codec-Dh1POFhE.js → image-codec-CQ8Cwxwb.js} +2 -2
  8. package/dist/chunks/{image-codec-Dh1POFhE.js.map → image-codec-CQ8Cwxwb.js.map} +1 -1
  9. package/dist/chunks/{images-CG7ZzayG.js → images-QgdmLyQ3.js} +11 -11
  10. package/dist/chunks/{images-CG7ZzayG.js.map → images-QgdmLyQ3.js.map} +1 -1
  11. package/dist/chunks/{index-0MNiR_wo.js → index-LYve1rQp.js} +286 -351
  12. package/dist/chunks/index-LYve1rQp.js.map +1 -0
  13. package/dist/chunks/links-iU22QkCE.js +68 -0
  14. package/dist/chunks/links-iU22QkCE.js.map +1 -0
  15. package/dist/chunks/{plugin-BZauDxRY.js → plugin-bkP6WwrS.js} +13 -12
  16. package/dist/chunks/{plugin-BZauDxRY.js.map → plugin-bkP6WwrS.js.map} +1 -1
  17. package/dist/chunks/runtime-BH519j2t.js +294 -0
  18. package/dist/chunks/runtime-BH519j2t.js.map +1 -0
  19. package/dist/chunks/streaming-BlKlC3nw.js +427 -0
  20. package/dist/chunks/streaming-BlKlC3nw.js.map +1 -0
  21. package/dist/chunks/{testing-CUwGj2ie.js → testing-BEW1nchS.js} +645 -630
  22. package/dist/chunks/testing-BEW1nchS.js.map +1 -0
  23. package/dist/chunks/{vite-QoqrGl6f.js → vite-BADZA8Fl.js} +73 -70
  24. package/dist/chunks/vite-BADZA8Fl.js.map +1 -0
  25. package/dist/cli.d.ts +8 -2
  26. package/dist/cli.d.ts.map +1 -1
  27. package/dist/cli.js +186 -122
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config/index.js +2 -2
  30. package/dist/config/types.d.ts +3 -1
  31. package/dist/config/types.d.ts.map +1 -1
  32. package/dist/config/validate.d.ts.map +1 -1
  33. package/dist/data/cache.d.ts +5 -0
  34. package/dist/data/cache.d.ts.map +1 -1
  35. package/dist/data/index.d.ts +1 -1
  36. package/dist/data/index.d.ts.map +1 -1
  37. package/dist/data/testing.d.ts.map +1 -1
  38. package/dist/data/testing.js +101 -67
  39. package/dist/data/testing.js.map +1 -1
  40. package/dist/data/tiered.d.ts.map +1 -1
  41. package/dist/edge/index.js +27 -26
  42. package/dist/edge/index.js.map +1 -1
  43. package/dist/edge/stores.d.ts.map +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +126 -125
  47. package/dist/index.js.map +1 -1
  48. package/dist/internal/testing.js +2 -2
  49. package/dist/kv/index.js +7 -6
  50. package/dist/kv/index.js.map +1 -1
  51. package/dist/kv/store.d.ts.map +1 -1
  52. package/dist/node/http.d.ts +2 -0
  53. package/dist/node/http.d.ts.map +1 -1
  54. package/dist/node/index.d.ts +1 -1
  55. package/dist/node/index.d.ts.map +1 -1
  56. package/dist/node/index.js +12 -11
  57. package/dist/node/index.js.map +1 -1
  58. package/dist/node/serve.d.ts +4 -0
  59. package/dist/node/serve.d.ts.map +1 -1
  60. package/dist/redis/index.js +29 -28
  61. package/dist/redis/index.js.map +1 -1
  62. package/dist/redis/store.d.ts.map +1 -1
  63. package/dist/route/serialization.d.ts +4 -4
  64. package/dist/route/serialization.d.ts.map +1 -1
  65. package/dist/static/index.d.ts.map +1 -1
  66. package/dist/static/index.js +255 -255
  67. package/dist/static/index.js.map +1 -1
  68. package/dist/static/testing.d.ts +26 -0
  69. package/dist/static/testing.d.ts.map +1 -0
  70. package/dist/static/testing.js +76 -0
  71. package/dist/static/testing.js.map +1 -0
  72. package/dist/testing/index.d.ts +47 -0
  73. package/dist/testing/index.d.ts.map +1 -0
  74. package/dist/testing/index.js +99 -0
  75. package/dist/testing/index.js.map +1 -0
  76. package/dist/vercel/build.d.ts +31 -0
  77. package/dist/vercel/build.d.ts.map +1 -0
  78. package/dist/vercel/config.d.ts +15 -0
  79. package/dist/vercel/config.d.ts.map +1 -0
  80. package/dist/vercel/index.d.ts +7 -0
  81. package/dist/vercel/index.d.ts.map +1 -0
  82. package/dist/vercel/index.js +11 -0
  83. package/dist/vercel/index.js.map +1 -0
  84. package/dist/vercel/runtime.d.ts +29 -0
  85. package/dist/vercel/runtime.d.ts.map +1 -0
  86. package/dist/vite/index.js +1 -1
  87. package/package.json +13 -1
  88. package/dist/chunks/index-0MNiR_wo.js.map +0 -1
  89. package/dist/chunks/streaming-GYIsVTQH.js +0 -560
  90. package/dist/chunks/streaming-GYIsVTQH.js.map +0 -1
  91. package/dist/chunks/testing-CUwGj2ie.js.map +0 -1
  92. package/dist/chunks/vite-QoqrGl6f.js.map +0 -1
@@ -1,560 +0,0 @@
1
- import { Readable as x, Transform as N } from "node:stream";
2
- import { pipeline as I } from "node:stream/promises";
3
- import { isIP as k } from "node:net";
4
- import { s as B, a as U, c as $, b as M } from "./index-0MNiR_wo.js";
5
- import { createHash as O } from "node:crypto";
6
- import { r as z, n as F, t as j } from "./image-codec-Dh1POFhE.js";
7
- import { d as V, e as _, h as G, j as W, u as K } from "./images-CG7ZzayG.js";
8
- import { R as L } from "./static-files-ehaD1kE7.js";
9
- import { readFile as J } from "node:fs/promises";
10
- import { resolve as C, relative as Y, sep as Q } from "node:path";
11
- import { renderToPipeableStream as X } from "react-dom/server";
12
- import { c as Z } from "./document-shell-9GPwtcTt.js";
13
- const y = {
14
- for: "x-forwarded-for",
15
- host: "x-forwarded-host",
16
- protocol: "x-forwarded-proto"
17
- }, H = !1, q = /* @__PURE__ */ new Set(["CONNECT", "TRACE", "TRACK"]);
18
- class ee extends Error {
19
- method;
20
- constructor(t) {
21
- super(`HTTP method "${t}" is not supported.`), this.method = t, this.name = "UnsupportedMethodError";
22
- }
23
- }
24
- class b extends Error {
25
- host;
26
- constructor(t) {
27
- super(`HTTP host "${t}" is not allowed.`), this.host = t, this.name = "UntrustedHostError";
28
- }
29
- }
30
- class E extends Error {
31
- method;
32
- constructor(t) {
33
- super(
34
- `The request body for the ${t} request was already read. A host such as Vercel Functions or Express body-parser reads the body before the adapter runs. Supply the recovered bytes with the toWebRequest body option.`
35
- ), this.method = t, this.name = "ConsumedRequestBodyError";
36
- }
37
- }
38
- function te(e) {
39
- if (e.allowedHosts.length === 0)
40
- throw new Error("Demiurge Node allowedHosts must contain at least one host.");
41
- for (const n of e.allowedHosts)
42
- if (!S(n))
43
- throw new Error(`Demiurge Node allowed host "${n}" is invalid.`);
44
- const t = e.trustProxy ?? H;
45
- if (t !== !1) {
46
- if ("hops" in t) {
47
- if (!Number.isSafeInteger(t.hops) || t.hops < 0)
48
- throw new Error(
49
- "Demiurge Node trustProxy hop count must be a non-negative integer."
50
- );
51
- return;
52
- }
53
- for (const n of t.ranges) {
54
- const r = n.split("/")[0];
55
- P(r, n);
56
- }
57
- }
58
- }
59
- function Me(e, t) {
60
- te(t);
61
- const n = e.method ?? "GET";
62
- if (q.has(n.toUpperCase()))
63
- throw new ee(n);
64
- const r = A(e.socket?.remoteAddress), o = de(
65
- r,
66
- e.headers[y.for],
67
- t.trustProxy ?? H
68
- ), s = T(
69
- e.headers[y.protocol],
70
- o.forwardedDepth
71
- ), l = ue(e, s), f = T(
72
- e.headers[y.host],
73
- o.forwardedDepth
74
- ) ?? e.headers.host, a = fe(f, t.allowedHosts), i = `${l}://${a}`, d = new URL(e.url ?? "/", i), u = me(e.headers), h = {
75
- headers: u,
76
- method: n,
77
- signal: t.signal
78
- };
79
- if (n !== "GET" && n !== "HEAD") {
80
- const c = ne(e, t.body);
81
- c === null ? (h.body = x.toWeb(e), h.duplex = "half") : (h.body = c.body, h.duplex = "half", c.length !== null ? (u.set("content-length", String(c.length)), u.delete("transfer-encoding")) : (u.delete("content-length"), u.delete("transfer-encoding")), c.contentType !== void 0 && (c.contentType === null ? u.delete("content-type") : u.set("content-type", c.contentType)));
82
- }
83
- const p = new Request(d, h);
84
- return B(p, { clientIp: o.clientIp }), p;
85
- }
86
- function ne(e, t) {
87
- if (t !== void 0)
88
- return {
89
- body: t,
90
- contentType: ce(t),
91
- length: ie(t)
92
- };
93
- const n = e.body;
94
- if (n != null)
95
- return oe(
96
- n,
97
- e.headers["content-type"],
98
- e.method ?? ""
99
- );
100
- if (Number(e.headers["content-length"]) === 0)
101
- return { body: null, length: 0 };
102
- if (e.readableDidRead || re(e))
103
- throw new E(e.method ?? "");
104
- return e.readableEnded ? { body: null, length: 0 } : null;
105
- }
106
- function re(e) {
107
- return !e.complete || e.readableLength > 0 || e.readableEnded ? !1 : Number(e.headers["content-length"]) > 0 || !!e.headers["transfer-encoding"];
108
- }
109
- function oe(e, t, n) {
110
- if (typeof e == "string")
111
- return { body: e, length: Buffer.byteLength(e) };
112
- if (ArrayBuffer.isView(e)) {
113
- const o = Uint8Array.from(
114
- new Uint8Array(e.buffer, e.byteOffset, e.byteLength)
115
- );
116
- return { body: o, length: o.byteLength };
117
- }
118
- if (e instanceof ArrayBuffer)
119
- return { body: e, length: e.byteLength };
120
- const r = le(t);
121
- if (r === "application/json") {
122
- const o = JSON.stringify(e);
123
- if (o === void 0)
124
- throw new E(n);
125
- return { body: o, contentType: void 0, length: Buffer.byteLength(o) };
126
- }
127
- if (r === "application/x-www-form-urlencoded" && se(e)) {
128
- const o = ae(e).toString();
129
- return { body: o, contentType: void 0, length: Buffer.byteLength(o) };
130
- }
131
- throw new E(n);
132
- }
133
- function se(e) {
134
- if (typeof e != "object" || e === null)
135
- return !1;
136
- const t = Object.getPrototypeOf(e);
137
- return t === Object.prototype || t === null;
138
- }
139
- function ae(e) {
140
- const t = new URLSearchParams();
141
- for (const [n, r] of Object.entries(e)) {
142
- if (Array.isArray(r)) {
143
- for (const o of r)
144
- t.append(n, String(o));
145
- continue;
146
- }
147
- t.append(n, String(r));
148
- }
149
- return t;
150
- }
151
- function ie(e) {
152
- return e === null ? 0 : typeof e == "string" ? Buffer.byteLength(e) : ArrayBuffer.isView(e) || e instanceof ArrayBuffer ? e.byteLength : e instanceof Blob ? e.size : e instanceof URLSearchParams ? Buffer.byteLength(e.toString()) : null;
153
- }
154
- function ce(e) {
155
- if (e === null || e instanceof FormData)
156
- return null;
157
- if (e instanceof URLSearchParams)
158
- return "application/x-www-form-urlencoded;charset=UTF-8";
159
- if (e instanceof Blob)
160
- return e.type || null;
161
- }
162
- function le(e) {
163
- return e?.split(";")[0].trim().toLowerCase();
164
- }
165
- function ue(e, t) {
166
- if (t) {
167
- const n = t.toLowerCase();
168
- if (n !== "http" && n !== "https")
169
- throw new Error(`Unsupported forwarded protocol "${t}".`);
170
- return n;
171
- }
172
- return e.socket?.encrypted ? "https" : "http";
173
- }
174
- function fe(e, t) {
175
- if (t.length === 0)
176
- throw new Error("Demiurge Node allowedHosts must contain at least one host.");
177
- if (!e)
178
- throw new b("");
179
- const n = S(e);
180
- if (!n)
181
- throw new b(e);
182
- if (!t.some((o) => {
183
- const s = S(o);
184
- if (!s)
185
- throw new Error(`Demiurge Node allowed host "${o}" is invalid.`);
186
- return s.port ? s.host === n.host : s.hostname === n.hostname;
187
- }))
188
- throw new b(e);
189
- return n.host;
190
- }
191
- function S(e) {
192
- if (e.trim() !== e || e.includes("@"))
193
- return null;
194
- try {
195
- const t = new URL(`http://${e}`);
196
- return !t.hostname || t.pathname !== "/" || t.search || t.hash || t.host.toLowerCase() !== e.toLowerCase() ? null : t;
197
- } catch {
198
- return null;
199
- }
200
- }
201
- function de(e, t, n) {
202
- const r = D(t), o = [...r, e];
203
- if (n === !1)
204
- return { clientIp: e, forwardedDepth: 0 };
205
- if ("hops" in n) {
206
- if (!Number.isSafeInteger(n.hops) || n.hops < 0)
207
- throw new Error(
208
- "Demiurge Node trustProxy hop count must be a non-negative integer."
209
- );
210
- const f = Math.min(n.hops, r.length);
211
- return {
212
- clientIp: o[o.length - 1 - f],
213
- forwardedDepth: n.hops
214
- };
215
- }
216
- let s = o.length - 1, l = 0;
217
- for (; s > 0 && R(o[s], n.ranges); )
218
- s -= 1, l += 1;
219
- return {
220
- clientIp: o[s],
221
- forwardedDepth: l || (R(e, n.ranges) ? 1 : 0)
222
- };
223
- }
224
- function T(e, t) {
225
- if (t === 0)
226
- return;
227
- const n = D(e);
228
- if (n.length !== 0)
229
- return n[Math.max(0, n.length - t)];
230
- }
231
- function D(e) {
232
- return (Array.isArray(e) ? e : [e]).flatMap((t) => t?.split(",") ?? []).map((t) => t.trim()).filter(Boolean);
233
- }
234
- function R(e, t) {
235
- return t.some((n) => P(e, n));
236
- }
237
- function P(e, t) {
238
- const [n, r] = t.split("/"), o = v(A(e)), s = v(A(n));
239
- if (!o || !s || o.length !== s.length) {
240
- if (!s)
241
- throw new Error(`Demiurge Node trustProxy range "${t}" is invalid.`);
242
- return !1;
243
- }
244
- const l = o.length * 8, f = r === void 0 ? l : Number(r);
245
- if (!Number.isInteger(f) || f < 0 || f > l)
246
- throw new Error(`Demiurge Node trustProxy range "${t}" is invalid.`);
247
- for (let a = 0; a < f; a += 1) {
248
- const i = 1 << 7 - a % 8;
249
- if ((o[Math.floor(a / 8)] & i) !== (s[Math.floor(a / 8)] & i))
250
- return !1;
251
- }
252
- return !0;
253
- }
254
- function A(e) {
255
- return e ? e.startsWith("::ffff:") ? e.slice(7) : e : "unknown";
256
- }
257
- function v(e) {
258
- const t = k(e);
259
- if (t === 4)
260
- return e.split(".").map(Number);
261
- if (t !== 6)
262
- return null;
263
- const [n = "", r = ""] = e.split("::"), o = n ? n.split(":") : [], s = r ? r.split(":") : [], l = 8 - o.length - s.length;
264
- return [
265
- ...o,
266
- ...Array.from({ length: l }, () => "0"),
267
- ...s
268
- ].flatMap((a) => {
269
- const i = Number.parseInt(a, 16);
270
- return [i >> 8, i & 255];
271
- });
272
- }
273
- function Oe(e) {
274
- e.statusCode = 501, e.setHeader("content-type", "text/plain; charset=utf-8"), e.end("Not Implemented");
275
- }
276
- async function ze(e, t) {
277
- const n = ge(t.headers);
278
- if (t.headers.forEach((r, o) => {
279
- o !== "set-cookie" && e.setHeader(o, r);
280
- }), n.length > 0 && e.setHeader("set-cookie", n), e.statusCode = t.status, t.statusText && (e.statusMessage = t.statusText), !t.body) {
281
- e.end();
282
- return;
283
- }
284
- try {
285
- await I(
286
- x.fromWeb(
287
- t.body
288
- ),
289
- e
290
- );
291
- } catch (r) {
292
- if (!pe(r))
293
- throw r;
294
- }
295
- }
296
- const he = /* @__PURE__ */ new Set([
297
- "ECONNRESET",
298
- "EPIPE",
299
- "ERR_STREAM_DESTROYED",
300
- "ERR_STREAM_PREMATURE_CLOSE"
301
- ]);
302
- function pe(e) {
303
- return e instanceof Error && "code" in e && typeof e.code == "string" && he.has(e.code);
304
- }
305
- function me(e) {
306
- const t = new Headers();
307
- for (const [n, r] of Object.entries(e)) {
308
- if (Array.isArray(r)) {
309
- for (const o of r)
310
- t.append(n, o);
311
- continue;
312
- }
313
- r && t.set(n, r);
314
- }
315
- return t;
316
- }
317
- function ge(e) {
318
- const t = e.getSetCookie;
319
- if (t)
320
- return t.call(e);
321
- const n = e.get("set-cookie");
322
- return n ? we(n) : [];
323
- }
324
- function we(e) {
325
- return e.split(/,\s*(?=[^;,=\s]+\s*=)/);
326
- }
327
- function Fe(e) {
328
- const t = e.basePath ?? V;
329
- let n;
330
- return async function(s) {
331
- const l = new URL(s.url);
332
- if (!l.pathname.startsWith(`${t}/`))
333
- return null;
334
- if (s.method !== "GET" && s.method !== "HEAD")
335
- return new Response("Method Not Allowed", {
336
- headers: {
337
- allow: "GET, HEAD",
338
- "content-type": "text/plain; charset=utf-8"
339
- },
340
- status: 405
341
- });
342
- n ??= r();
343
- let f;
344
- try {
345
- f = await n;
346
- } catch (i) {
347
- throw n = void 0, i;
348
- }
349
- const a = f.get(l.pathname);
350
- return a ? ye(s, a) : null;
351
- };
352
- async function r() {
353
- const o = await z({ ...e, basePath: t });
354
- return new Map(o.map((s) => [s.url, s]));
355
- }
356
- }
357
- function ye(e, t) {
358
- const n = `"${O("sha256").update(t.body).digest("base64url").slice(0, 27)}"`, r = new Headers({
359
- "cache-control": L,
360
- "content-type": t.contentType,
361
- etag: n
362
- });
363
- return e.headers.get("if-none-match") === n ? new Response(null, { headers: r, status: 304 }) : (r.set("content-length", String(t.body.byteLength)), new Response(
364
- e.method === "HEAD" ? null : t.body,
365
- { headers: r, status: 200 }
366
- ));
367
- }
368
- const be = 64, Ee = 20 * 1024 * 1024;
369
- function je(e) {
370
- const t = C(e.root), n = e.policy ?? {}, r = n.optimizerPath ?? _, o = e.cacheSize ?? be, s = e.fetch ?? ((a, i) => fetch(a, i)), l = /* @__PURE__ */ new Map();
371
- return async function(i) {
372
- const d = new URL(i.url), u = d.pathname === r ? void 0 : e.resolveVariant?.(d.pathname);
373
- if (d.pathname !== r && !u)
374
- return null;
375
- if (i.method !== "GET" && i.method !== "HEAD")
376
- return w(405, "Method Not Allowed", {
377
- allow: "GET, HEAD"
378
- });
379
- if (u && !G(u.src, n))
380
- return w(403, "The image policy does not allow this image source.");
381
- const h = u ? { descriptor: u, ok: !0 } : W(d, n);
382
- if (!h.ok)
383
- return w(h.rejection.status, h.rejection.reason);
384
- const p = F(
385
- h.descriptor,
386
- u ? null : i.headers.get("accept")
387
- ), c = `${p}|${d.pathname}${d.search}`;
388
- let m = l.get(c);
389
- if (m)
390
- l.delete(c);
391
- else {
392
- const g = await f(h.descriptor);
393
- if (!g)
394
- return w(404, "The image source does not exist.");
395
- m = await j(g, {
396
- format: p,
397
- quality: h.descriptor.quality,
398
- width: h.descriptor.width
399
- });
400
- }
401
- for (l.set(c, m); l.size > o; )
402
- l.delete(l.keys().next().value);
403
- return Se(
404
- i,
405
- m,
406
- !u && h.descriptor.format === "auto"
407
- );
408
- };
409
- async function f(a) {
410
- if (a.sourceKind === "remote") {
411
- const d = await s(a.src);
412
- if (!d.ok)
413
- return;
414
- const u = new Uint8Array(await d.arrayBuffer());
415
- return u.byteLength > Ee ? void 0 : u;
416
- }
417
- const i = Ae(t, a.src);
418
- if (i)
419
- try {
420
- return new Uint8Array(await J(i));
421
- } catch {
422
- return;
423
- }
424
- }
425
- }
426
- function Se(e, t, n) {
427
- const r = `"${Te(t.body)}"`, o = new Headers({
428
- "cache-control": L,
429
- "content-type": t.contentType,
430
- etag: r
431
- });
432
- return n && o.set("vary", "accept"), e.headers.get("if-none-match") === r ? new Response(null, { headers: o, status: 304 }) : (o.set("content-length", String(t.body.byteLength)), new Response(
433
- e.method === "HEAD" ? null : t.body,
434
- { headers: o, status: 200 }
435
- ));
436
- }
437
- function w(e, t, n = {}) {
438
- return new Response(t, {
439
- headers: { "content-type": "text/plain; charset=utf-8", ...n },
440
- status: e
441
- });
442
- }
443
- function Ae(e, t) {
444
- let n;
445
- try {
446
- n = decodeURIComponent(K(t));
447
- } catch {
448
- return;
449
- }
450
- if (n.split(/[\\/]/).includes(".."))
451
- return;
452
- const r = C(e, `.${n}`);
453
- return Y(e, r).split(Q).includes("..") ? void 0 : r;
454
- }
455
- function Te(e) {
456
- let t = 2166136261, n = 16777619;
457
- for (const r of e)
458
- t = Math.imul(t ^ r, 16777619) >>> 0, n = Math.imul(n ^ r, 2246822507) >>> 0;
459
- return `${t.toString(36)}${n.toString(36)}${e.byteLength.toString(36)}`;
460
- }
461
- function Ve(e, t = {}) {
462
- return e.render.mode === "streaming" ? Re(e, t) : U(e, t);
463
- }
464
- async function Re(e, t = {}) {
465
- if (t.signal?.aborted)
466
- throw t.signal.reason;
467
- const n = $(e, t), r = M(e, n);
468
- return await new Promise((o, s) => {
469
- let l = !1, f = !1, a = !1, i = "", d;
470
- const u = new N({
471
- destroy(c, m) {
472
- l || (f = !0), m(c);
473
- },
474
- flush(c) {
475
- c(null, i);
476
- },
477
- transform(c, m, g) {
478
- g(null, c);
479
- }
480
- }), h = () => {
481
- f = !0, d?.abort(t.signal?.reason), u.destroy();
482
- }, p = () => t.signal?.removeEventListener("abort", h);
483
- u.once("finish", () => {
484
- l = !0;
485
- }), u.once("close", () => {
486
- p(), l || (f = !0, d?.abort(new Error("Demiurge streaming response was cancelled.")));
487
- }), t.signal?.addEventListener("abort", h, { once: !0 }), d = X(r, {
488
- nonce: t.nonce,
489
- onError(c) {
490
- a && !f && t.onStreamError?.(c);
491
- },
492
- onShellError(c) {
493
- p(), s(c);
494
- },
495
- onShellReady() {
496
- (async () => {
497
- try {
498
- const c = await Z(e, {
499
- ...t,
500
- scripts: n.scripts()
501
- });
502
- i = c.suffix, n.flushHead(), u.push(c.prefix), a = !0, d?.pipe(u), o(
503
- new Response(ve(u), {
504
- headers: { "content-type": "text/html; charset=utf-8" }
505
- })
506
- );
507
- } catch (c) {
508
- p(), d?.abort(c), u.destroy(), s(c);
509
- }
510
- })();
511
- }
512
- });
513
- });
514
- }
515
- function ve(e) {
516
- let t = !1, n = () => {
517
- };
518
- return new ReadableStream({
519
- cancel() {
520
- t = !0, n(), e.pause(), e.destroy();
521
- },
522
- pull() {
523
- e.resume();
524
- },
525
- start(r) {
526
- e.on("data", o), e.once("end", s), e.once("error", l), e.once("close", f);
527
- function o(i) {
528
- t || (r.enqueue(Uint8Array.from(i)), (r.desiredSize ?? 1) <= 0 && e.pause());
529
- }
530
- function s() {
531
- t || (t = !0, a(), r.close());
532
- }
533
- function l(i) {
534
- t || (t = !0, a(), r.error(i));
535
- }
536
- function f() {
537
- t || (t = !0, a(), r.close());
538
- }
539
- function a() {
540
- e.off("data", o), e.off("end", s), e.off("error", l), e.off("close", f);
541
- }
542
- n = a;
543
- }
544
- });
545
- }
546
- export {
547
- E as C,
548
- ee as U,
549
- b as a,
550
- ze as b,
551
- Fe as c,
552
- je as d,
553
- Re as e,
554
- me as f,
555
- Ve as r,
556
- Me as t,
557
- te as v,
558
- Oe as w
559
- };
560
- //# sourceMappingURL=streaming-GYIsVTQH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"streaming-GYIsVTQH.js","sources":["../../src/node/http.ts","../../src/node/font.ts","../../src/node/image.ts","../../src/node/streaming.ts"],"sourcesContent":["import { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { isIP } from \"node:net\";\nimport type {\n IncomingHttpHeaders,\n IncomingMessage,\n ServerResponse,\n} from \"node:http\";\nimport { setRequestConnectionMetadata } from \"../server/request-metadata\";\n\nexport type HttpScheme = \"http\" | \"https\";\n\nexport type NodeOriginPolicy = {\n allowedHosts: readonly string[];\n trustProxy?: TrustProxy;\n};\n\nexport type ToWebRequestOptions = NodeOriginPolicy & {\n // A host that reads the request body before the adapter runs can supply the\n // bytes it recovered. The adapter then uses them instead of the stream.\n body?: BodyInit | null;\n signal?: AbortSignal;\n};\n\nexport type TrustProxy =\n | false\n | { hops: number }\n | { ranges: readonly string[] };\n\nconst forwardedHeaders = {\n for: \"x-forwarded-for\",\n host: \"x-forwarded-host\",\n protocol: \"x-forwarded-proto\",\n} as const satisfies Record<\"for\" | \"host\" | \"protocol\", string>;\nconst defaultTrustProxy = false satisfies TrustProxy;\n\n// The Fetch specification prohibits these methods in the `Request` constructor.\n// `new Request(...)` throws for them. Without this guard, an unauthenticated\n// client can make a generic 500 response and add stack traces to the server log.\nconst forbiddenMethods = new Set([\"CONNECT\", \"TRACE\", \"TRACK\"]);\n\nexport class UnsupportedMethodError extends Error {\n method: string;\n\n constructor(method: string) {\n super(`HTTP method \"${method}\" is not supported.`);\n this.method = method;\n this.name = \"UnsupportedMethodError\";\n }\n}\n\nexport class UntrustedHostError extends Error {\n host: string;\n\n constructor(host: string) {\n super(`HTTP host \"${host}\" is not allowed.`);\n this.host = host;\n this.name = \"UntrustedHostError\";\n }\n}\n\nexport class ConsumedRequestBodyError extends Error {\n method: string;\n\n constructor(method: string) {\n super(\n `The request body for the ${method} request was already read. ` +\n \"A host such as Vercel Functions or Express body-parser reads the \" +\n \"body before the adapter runs. Supply the recovered bytes with the \" +\n \"toWebRequest body option.\",\n );\n this.method = method;\n this.name = \"ConsumedRequestBodyError\";\n }\n}\n\nexport function validateNodeOriginPolicy(policy: NodeOriginPolicy) {\n if (policy.allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n for (const host of policy.allowedHosts) {\n if (!parseAuthority(host)) {\n throw new Error(`Demiurge Node allowed host \"${host}\" is invalid.`);\n }\n }\n\n const trustProxy = policy.trustProxy ?? defaultTrustProxy;\n\n if (trustProxy === false) {\n return;\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n return;\n }\n\n for (const range of trustProxy.ranges) {\n const network = range.split(\"/\")[0];\n ipMatchesRange(network, range);\n }\n}\n\nexport function toWebRequest(\n request: IncomingMessage,\n options: ToWebRequestOptions,\n) {\n validateNodeOriginPolicy(options);\n const method = request.method ?? \"GET\";\n\n if (forbiddenMethods.has(method.toUpperCase())) {\n throw new UnsupportedMethodError(method);\n }\n\n const peerAddress = normalizeIpAddress(request.socket?.remoteAddress);\n const proxy = resolveProxyChain(\n peerAddress,\n request.headers[forwardedHeaders.for],\n options.trustProxy ?? defaultTrustProxy,\n );\n const forwardedProtocol = selectForwardedValue(\n request.headers[forwardedHeaders.protocol],\n proxy.forwardedDepth,\n );\n const protocol = resolveProtocol(request, forwardedProtocol);\n const host = selectForwardedValue(\n request.headers[forwardedHeaders.host],\n proxy.forwardedDepth,\n ) ?? request.headers.host;\n const authority = validateAllowedHost(host, options.allowedHosts);\n const origin = `${protocol}://${authority}`;\n const url = new URL(request.url ?? \"/\", origin);\n const headers = toHeaders(request.headers);\n const init: RequestInit & { duplex?: \"half\" } = {\n headers,\n method,\n signal: options.signal,\n };\n\n if (method !== \"GET\" && method !== \"HEAD\") {\n const recovered = resolveRecoveredBody(request, options.body);\n\n if (recovered === null) {\n // TYPE-EVIDENCE: Readable.toWeb returns a web stream that matches the DOM ReadableStream body type.\n init.body = Readable.toWeb(request) as ReadableStream;\n init.duplex = \"half\";\n } else {\n init.body = recovered.body;\n init.duplex = \"half\";\n\n if (recovered.length !== null) {\n // The host reports the length of the original bytes. Recovered bytes\n // can have a different length, so the header must describe what this\n // request carries.\n headers.set(\"content-length\", String(recovered.length));\n headers.delete(\"transfer-encoding\");\n } else {\n // The supplied body can have a different size from the incoming body.\n // Remove framing headers when the adapter cannot determine its size.\n headers.delete(\"content-length\");\n headers.delete(\"transfer-encoding\");\n }\n\n if (recovered.contentType !== undefined) {\n if (recovered.contentType === null) {\n headers.delete(\"content-type\");\n } else {\n headers.set(\"content-type\", recovered.contentType);\n }\n }\n }\n }\n\n const webRequest = new Request(url, init);\n setRequestConnectionMetadata(webRequest, { clientIp: proxy.clientIp });\n\n return webRequest;\n}\n\n// A host that reads the request body before the adapter runs leaves an\n// IncomingMessage that gives no data and never ends. `Readable.toWeb` on that\n// stream makes a request body that waits forever, and every unsafe request\n// stops with no error. The adapter must use the bytes the host kept instead.\n// A `null` result means the adapter still owns the stream.\nfunction resolveRecoveredBody(\n request: IncomingMessage,\n suppliedBody: BodyInit | null | undefined,\n) {\n if (suppliedBody !== undefined) {\n return {\n body: suppliedBody,\n contentType: suppliedBodyContentType(suppliedBody),\n length: knownBodyLength(suppliedBody),\n };\n }\n\n // TYPE-EVIDENCE: a host such as Vercel Functions or Express body-parser adds the parsed body to the request. The cast reads that optional property.\n const parsed = (request as IncomingMessage & { body?: unknown }).body;\n\n if (parsed !== undefined && parsed !== null) {\n return encodeParsedBody(\n parsed,\n request.headers[\"content-type\"],\n request.method ?? \"\",\n );\n }\n\n if (Number(request.headers[\"content-length\"]) === 0) {\n return { body: null, length: 0 };\n }\n\n if (request.readableDidRead || isDrainedByHost(request)) {\n throw new ConsumedRequestBodyError(request.method ?? \"\");\n }\n\n if (request.readableEnded) {\n return { body: null, length: 0 };\n }\n\n return null;\n}\n\n// A complete message with no buffered data and no read is a message that\n// another reader took. A message the adapter owns still holds its bytes.\nfunction isDrainedByHost(request: IncomingMessage) {\n if (!request.complete || request.readableLength > 0 || request.readableEnded) {\n return false;\n }\n\n const declaredLength = Number(request.headers[\"content-length\"]);\n\n return declaredLength > 0 || Boolean(request.headers[\"transfer-encoding\"]);\n}\n\nfunction encodeParsedBody(\n parsed: unknown,\n contentType: string | undefined,\n method: string,\n) {\n if (typeof parsed === \"string\") {\n return { body: parsed, length: Buffer.byteLength(parsed) };\n }\n\n if (ArrayBuffer.isView(parsed)) {\n const bytes = Uint8Array.from(\n new Uint8Array(parsed.buffer, parsed.byteOffset, parsed.byteLength),\n );\n\n return { body: bytes, length: bytes.byteLength };\n }\n\n if (parsed instanceof ArrayBuffer) {\n return { body: parsed, length: parsed.byteLength };\n }\n\n const type = mediaType(contentType);\n\n if (type === \"application/json\") {\n const json = JSON.stringify(parsed);\n\n if (json === undefined) {\n throw new ConsumedRequestBodyError(method);\n }\n\n return { body: json, contentType: undefined, length: Buffer.byteLength(json) };\n }\n\n if (type === \"application/x-www-form-urlencoded\" && isRecord(parsed)) {\n const encoded = toSearchParams(parsed).toString();\n\n return { body: encoded, contentType: undefined, length: Buffer.byteLength(encoded) };\n }\n\n // A parsed multipart or unknown body does not contain the original bytes.\n // Require the host to pass those bytes through the body option.\n throw new ConsumedRequestBodyError(method);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction toSearchParams(parsed: object) {\n const params = new URLSearchParams();\n\n for (const [name, value] of Object.entries(parsed)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n params.append(name, String(item));\n }\n\n continue;\n }\n\n params.append(name, String(value));\n }\n\n return params;\n}\n\nfunction knownBodyLength(body: BodyInit | null) {\n if (body === null) {\n return 0;\n }\n\n if (typeof body === \"string\") {\n return Buffer.byteLength(body);\n }\n\n if (ArrayBuffer.isView(body) || body instanceof ArrayBuffer) {\n return body.byteLength;\n }\n\n if (body instanceof Blob) {\n return body.size;\n }\n\n if (body instanceof URLSearchParams) {\n return Buffer.byteLength(body.toString());\n }\n\n return null;\n}\n\nfunction suppliedBodyContentType(body: BodyInit | null) {\n if (body === null || body instanceof FormData) {\n return null;\n }\n\n if (body instanceof URLSearchParams) {\n return \"application/x-www-form-urlencoded;charset=UTF-8\";\n }\n\n if (body instanceof Blob) {\n return body.type || null;\n }\n\n return undefined;\n}\n\nfunction mediaType(contentType: string | undefined) {\n return contentType?.split(\";\")[0].trim().toLowerCase();\n}\n\nfunction resolveProtocol(\n request: IncomingMessage,\n forwardedProtocol: string | undefined,\n) {\n if (forwardedProtocol) {\n const protocol = forwardedProtocol.toLowerCase();\n\n if (protocol !== \"http\" && protocol !== \"https\") {\n throw new Error(`Unsupported forwarded protocol \"${forwardedProtocol}\".`);\n }\n\n return protocol;\n }\n\n // TYPE-EVIDENCE: the socket may expose the encrypted flag that Node sets for TLS connections. The cast reads that optional flag.\n return (request.socket as { encrypted?: boolean } | undefined)?.encrypted\n ? \"https\"\n : \"http\";\n}\n\nfunction validateAllowedHost(\n host: string | undefined,\n allowedHosts: readonly string[],\n) {\n if (allowedHosts.length === 0) {\n throw new Error(\"Demiurge Node allowedHosts must contain at least one host.\");\n }\n\n if (!host) {\n throw new UntrustedHostError(\"\");\n }\n\n const authority = parseAuthority(host);\n\n if (!authority) {\n throw new UntrustedHostError(host);\n }\n\n const allowed = allowedHosts.some((candidate) => {\n const expected = parseAuthority(candidate);\n\n if (!expected) {\n throw new Error(`Demiurge Node allowed host \"${candidate}\" is invalid.`);\n }\n\n return expected.port\n ? expected.host === authority.host\n : expected.hostname === authority.hostname;\n });\n\n if (!allowed) {\n throw new UntrustedHostError(host);\n }\n\n return authority.host;\n}\n\nfunction parseAuthority(value: string) {\n if (value.trim() !== value || value.includes(\"@\")) {\n return null;\n }\n\n try {\n const parsed = new URL(`http://${value}`);\n\n if (\n !parsed.hostname ||\n parsed.pathname !== \"/\" ||\n parsed.search ||\n parsed.hash ||\n parsed.host.toLowerCase() !== value.toLowerCase()\n ) {\n return null;\n }\n\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction resolveProxyChain(\n peerAddress: string,\n forwardedFor: string | readonly string[] | undefined,\n trustProxy: TrustProxy,\n) {\n const forwarded = headerValues(forwardedFor);\n const chain = [...forwarded, peerAddress];\n\n if (trustProxy === false) {\n return { clientIp: peerAddress, forwardedDepth: 0 };\n }\n\n if (\"hops\" in trustProxy) {\n if (!Number.isSafeInteger(trustProxy.hops) || trustProxy.hops < 0) {\n throw new Error(\n \"Demiurge Node trustProxy hop count must be a non-negative integer.\",\n );\n }\n\n const clientHops = Math.min(trustProxy.hops, forwarded.length);\n\n return {\n clientIp: chain[chain.length - 1 - clientHops],\n forwardedDepth: trustProxy.hops,\n };\n }\n\n let index = chain.length - 1;\n let trustedHops = 0;\n\n while (\n index > 0 &&\n isAddressTrusted(chain[index], trustProxy.ranges)\n ) {\n index -= 1;\n trustedHops += 1;\n }\n\n return {\n clientIp: chain[index],\n forwardedDepth:\n trustedHops || (isAddressTrusted(peerAddress, trustProxy.ranges) ? 1 : 0),\n };\n}\n\nfunction selectForwardedValue(\n header: string | readonly string[] | undefined,\n trustedDepth: number,\n) {\n if (trustedDepth === 0) {\n return undefined;\n }\n\n const values = headerValues(header);\n\n if (values.length === 0) {\n return undefined;\n }\n\n return values[Math.max(0, values.length - trustedDepth)];\n}\n\nfunction headerValues(value: string | readonly string[] | undefined) {\n return (Array.isArray(value) ? value : [value])\n .flatMap((item) => item?.split(\",\") ?? [])\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction isAddressTrusted(address: string, ranges: readonly string[]) {\n return ranges.some((range) => ipMatchesRange(address, range));\n}\n\nfunction ipMatchesRange(address: string, range: string) {\n const [networkValue, prefixValue] = range.split(\"/\");\n const addressBytes = ipBytes(normalizeIpAddress(address));\n const networkBytes = ipBytes(normalizeIpAddress(networkValue));\n\n if (!addressBytes || !networkBytes || addressBytes.length !== networkBytes.length) {\n if (!networkBytes) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n return false;\n }\n\n const maximumPrefix = addressBytes.length * 8;\n const prefix = prefixValue === undefined ? maximumPrefix : Number(prefixValue);\n\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > maximumPrefix) {\n throw new Error(`Demiurge Node trustProxy range \"${range}\" is invalid.`);\n }\n\n for (let bit = 0; bit < prefix; bit += 1) {\n const mask = 1 << (7 - (bit % 8));\n\n if ((addressBytes[Math.floor(bit / 8)] & mask) !==\n (networkBytes[Math.floor(bit / 8)] & mask)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction normalizeIpAddress(address: string | undefined) {\n if (!address) {\n return \"unknown\";\n }\n\n return address.startsWith(\"::ffff:\") ? address.slice(7) : address;\n}\n\nfunction ipBytes(address: string) {\n const version = isIP(address);\n\n if (version === 4) {\n return address.split(\".\").map(Number);\n }\n\n if (version !== 6) {\n return null;\n }\n\n const [left = \"\", right = \"\"] = address.split(\"::\");\n const leftGroups = left ? left.split(\":\") : [];\n const rightGroups = right ? right.split(\":\") : [];\n const missing = 8 - leftGroups.length - rightGroups.length;\n const groups = [\n ...leftGroups,\n ...Array.from({ length: missing }, () => \"0\"),\n ...rightGroups,\n ];\n\n return groups.flatMap((group) => {\n const value = Number.parseInt(group, 16);\n return [value >> 8, value & 255];\n });\n}\n\n// Shared by the Node adapter and the Vite dev middleware so a request the\n// Fetch layer cannot represent gets the same answer in both.\nexport function writeNotImplemented(serverResponse: ServerResponse) {\n serverResponse.statusCode = 501;\n serverResponse.setHeader(\"content-type\", \"text/plain; charset=utf-8\");\n serverResponse.end(\"Not Implemented\");\n}\n\nexport async function writeWebResponse(\n serverResponse: ServerResponse,\n webResponse: Response,\n) {\n // `Headers.forEach` joins repeated headers with a comma, which is wrong for\n // `set-cookie`: two cookies would arrive as one malformed header. Node's\n // `setHeader` takes an array for exactly this case.\n const cookies = getSetCookies(webResponse.headers);\n\n webResponse.headers.forEach((value, name) => {\n if (name === \"set-cookie\") {\n return;\n }\n\n serverResponse.setHeader(name, value);\n });\n\n if (cookies.length > 0) {\n serverResponse.setHeader(\"set-cookie\", cookies);\n }\n\n serverResponse.statusCode = webResponse.status;\n\n // An empty status text would otherwise overwrite Node's default reason\n // phrase with nothing at all.\n if (webResponse.statusText) {\n serverResponse.statusMessage = webResponse.statusText;\n }\n\n if (!webResponse.body) {\n serverResponse.end();\n return;\n }\n\n // `Readable.pipe()` does not destroy its source when the destination closes\n // or has an error. An aborted client can leave the source stream open. It can\n // also leave an associated file descriptor open. `pipeline` destroys the\n // source when either side closes.\n try {\n // TYPE-EVIDENCE: the DOM body stream matches the Node web stream shape that fromWeb reads.\n await pipeline(\n Readable.fromWeb(\n webResponse.body as import(\"node:stream/web\").ReadableStream,\n ),\n serverResponse,\n );\n } catch (error) {\n if (!isClientDisconnect(error)) {\n throw error;\n }\n }\n}\n\n// A client disconnect during a response is ordinary traffic, not a server\n// fault. A new throw would run the caller error path for each canceled download.\n// This path records a stack trace and creates an unused 500 response. An\n// unauthenticated client can cause this condition.\nconst clientDisconnectCodes = new Set([\n \"ECONNRESET\",\n \"EPIPE\",\n \"ERR_STREAM_DESTROYED\",\n \"ERR_STREAM_PREMATURE_CLOSE\",\n]);\n\nfunction isClientDisconnect(error: unknown) {\n return (\n error instanceof Error &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n clientDisconnectCodes.has(error.code)\n );\n}\n\nexport function toHeaders(headers: IncomingHttpHeaders) {\n const nextHeaders = new Headers();\n\n for (const [name, value] of Object.entries(headers)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n nextHeaders.append(name, item);\n }\n continue;\n }\n\n if (value) {\n nextHeaders.set(name, value);\n }\n }\n\n return nextHeaders;\n}\n\nfunction getSetCookies(headers: Headers) {\n // TYPE-EVIDENCE: the getSetCookie method is a vendor extension present in some server runtimes. The cast reads that optional method for the runtime check.\n const getSetCookie = (headers as Headers & {\n getSetCookie?: () => string[];\n }).getSetCookie;\n\n if (getSetCookie) {\n return getSetCookie.call(headers);\n }\n\n const combined = headers.get(\"set-cookie\");\n\n return combined ? splitSetCookies(combined) : [];\n}\n\nfunction splitSetCookies(value: string) {\n return value.split(/,\\s*(?=[^;,=\\s]+\\s*=)/);\n}\n","import { createHash } from \"node:crypto\";\nimport {\n resolveFontAssets,\n type FontAsset,\n type FontAssetOptions,\n} from \"../platform/font-assets\";\nimport { defaultFontPath } from \"../platform/fonts\";\nimport { REVALIDATED_FILE_CACHE_CONTROL } from \"../static-files\";\nimport type { StaticFileHandler } from \"./static\";\n\nexport type FontAssetHandlerOptions = FontAssetOptions;\n\n// The handler answers the self-hosted font URLs that the document declares.\n// It returns null for every other path, so it composes with the static file\n// handler and the route pipeline. The image optimizer composes the same way.\nexport function createFontAssetHandler(\n options: FontAssetHandlerOptions,\n): StaticFileHandler {\n const basePath = options.basePath ?? defaultFontPath;\n let pending: Promise<Map<string, FontAsset>> | undefined;\n\n return async function handleFontRequest(request) {\n const url = new URL(request.url);\n\n if (!url.pathname.startsWith(`${basePath}/`)) {\n return null;\n }\n\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n return new Response(\"Method Not Allowed\", {\n headers: {\n allow: \"GET, HEAD\",\n \"content-type\": \"text/plain; charset=utf-8\",\n },\n status: 405,\n });\n }\n\n pending ??= loadAssets();\n\n let assets: Map<string, FontAsset>;\n\n try {\n assets = await pending;\n } catch (error) {\n pending = undefined;\n throw error;\n }\n\n const asset = assets.get(url.pathname);\n\n return asset ? respond(request, asset) : null;\n };\n\n async function loadAssets() {\n const assets = await resolveFontAssets({ ...options, basePath });\n\n return new Map(assets.map((asset) => [asset.url, asset]));\n }\n}\n\n// A font URL names the family, the weight, and the style rather than the\n// content of the file. A strong entity tag keeps a replaced file cheap to\n// revalidate, the same trade the image optimizer makes.\nfunction respond(request: Request, asset: FontAsset) {\n const etag = `\"${createHash(\"sha256\").update(asset.body).digest(\"base64url\").slice(0, 27)}\"`;\n const headers = new Headers({\n \"cache-control\": REVALIDATED_FILE_CACHE_CONTROL,\n \"content-type\": asset.contentType,\n etag,\n });\n\n if (request.headers.get(\"if-none-match\") === etag) {\n return new Response(null, { headers, status: 304 });\n }\n\n headers.set(\"content-length\", String(asset.body.byteLength));\n\n // TYPE-EVIDENCE: the font body is an ArrayBuffer-backed view that the DOM body type accepts.\n return new Response(\n request.method === \"HEAD\" ? null : (asset.body as Uint8Array<ArrayBuffer>),\n { headers, status: 200 },\n );\n}\n","import { readFile } from \"node:fs/promises\";\nimport { relative, resolve, sep } from \"node:path\";\nimport {\n negotiateImageFormat,\n transformImage,\n type EncodedImage,\n} from \"../platform/image-codec\";\nimport { defaultImageOptimizerPath } from \"../platform/image-url\";\nimport type { ImageVariantDescriptor } from \"../platform/image-url\";\nimport {\n isAllowedImageSource,\n parseImageOptimizerRequest,\n} from \"../platform/images\";\nimport type { ImagePolicy } from \"../platform/images\";\nimport { urlPath } from \"../platform/url\";\nimport type { StaticFileHandler } from \"./static\";\nimport { REVALIDATED_FILE_CACHE_CONTROL } from \"../static-files\";\n\nexport type ImageOptimizerFetch = (\n input: string,\n init?: { signal?: AbortSignal },\n) => Promise<Response>;\n\nexport type ImageOptimizerOptions = {\n // The number of encoded variants that stay in memory. The optimizer keeps\n // the most recent request at the front.\n cacheSize?: number;\n fetch?: ImageOptimizerFetch;\n policy?: ImagePolicy;\n // Maps a static loader variant path back to the transform behind it. The\n // development server passes the recorded plans, so a page renders the same\n // URL in development and in the static build.\n resolveVariant?: (pathname: string) => ImageVariantDescriptor | undefined;\n // The directory that holds every local source image, normally the client\n // build output.\n root: string;\n};\n\nconst defaultCacheSize = 64;\nconst maximumRemoteImageBytes = 20 * 1024 * 1024;\n\n// The optimizer answers the same URL that `planImageTransform` writes. It\n// returns null for every other path, so it composes with the static file\n// handler and the route pipeline.\nexport function createImageOptimizer(\n options: ImageOptimizerOptions,\n): StaticFileHandler {\n const root = resolve(options.root);\n const policy = options.policy ?? {};\n const optimizerPath = policy.optimizerPath ?? defaultImageOptimizerPath;\n const cacheSize = options.cacheSize ?? defaultCacheSize;\n const load = options.fetch ?? ((input, init) => fetch(input, init));\n const cache = new Map<string, EncodedImage>();\n\n return async function handleImageRequest(request) {\n const url = new URL(request.url);\n const variant = url.pathname === optimizerPath\n ? undefined\n : options.resolveVariant?.(url.pathname);\n\n if (url.pathname !== optimizerPath && !variant) {\n return null;\n }\n\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n return plainText(405, \"Method Not Allowed\", {\n allow: \"GET, HEAD\",\n });\n }\n\n if (variant && !isAllowedImageSource(variant.src, policy)) {\n return plainText(403, \"The image policy does not allow this image source.\");\n }\n\n const parsed = variant\n ? ({ descriptor: variant, ok: true } as const)\n : parseImageOptimizerRequest(url, policy);\n\n if (!parsed.ok) {\n return plainText(parsed.rejection.status, parsed.rejection.reason);\n }\n\n const format = negotiateImageFormat(\n parsed.descriptor,\n variant ? null : request.headers.get(\"accept\"),\n );\n const key = `${format}|${url.pathname}${url.search}`;\n let encoded = cache.get(key);\n\n if (encoded) {\n cache.delete(key);\n } else {\n const source = await readSource(parsed.descriptor);\n\n if (!source) {\n return plainText(404, \"The image source does not exist.\");\n }\n\n encoded = await transformImage(source, {\n format,\n quality: parsed.descriptor.quality,\n width: parsed.descriptor.width,\n });\n }\n\n cache.set(key, encoded);\n\n while (cache.size > cacheSize) {\n // TYPE-EVIDENCE: the loop runs only while the cache holds an entry. The next key therefore exists as a string.\n cache.delete(cache.keys().next().value as string);\n }\n\n return respond(\n request,\n encoded,\n !variant && parsed.descriptor.format === \"auto\",\n );\n };\n\n async function readSource(descriptor: ImageVariantDescriptor) {\n if (descriptor.sourceKind === \"remote\") {\n const response = await load(descriptor.src);\n\n if (!response.ok) {\n return undefined;\n }\n\n const body = new Uint8Array(await response.arrayBuffer());\n\n return body.byteLength > maximumRemoteImageBytes ? undefined : body;\n }\n\n const file = resolveLocalFile(root, descriptor.src);\n\n if (!file) {\n return undefined;\n }\n\n try {\n return new Uint8Array(await readFile(file));\n } catch {\n return undefined;\n }\n }\n}\n\n// The URL carries the source path rather than a content hash, so a long\n// immutable lifetime would outlive a replaced source file. A strong entity\n// tag keeps the revalidation cheap instead.\nfunction respond(request: Request, encoded: EncodedImage, varyOnAccept: boolean) {\n const etag = `\"${weakHash(encoded.body)}\"`;\n const headers = new Headers({\n \"cache-control\": REVALIDATED_FILE_CACHE_CONTROL,\n \"content-type\": encoded.contentType,\n etag,\n });\n\n if (varyOnAccept) {\n headers.set(\"vary\", \"accept\");\n }\n\n if (request.headers.get(\"if-none-match\") === etag) {\n return new Response(null, { headers, status: 304 });\n }\n\n headers.set(\"content-length\", String(encoded.body.byteLength));\n\n // TYPE-EVIDENCE: the encoded body is an ArrayBuffer-backed view that the DOM body type accepts.\n return new Response(\n request.method === \"HEAD\" ? null : (encoded.body as Uint8Array<ArrayBuffer>),\n { headers, status: 200 },\n );\n}\n\nfunction plainText(\n status: number,\n body: string,\n extraHeaders: Record<string, string> = {},\n) {\n return new Response(body, {\n headers: { \"content-type\": \"text/plain; charset=utf-8\", ...extraHeaders },\n status,\n });\n}\n\nfunction resolveLocalFile(root: string, src: string) {\n let decoded: string;\n\n try {\n decoded = decodeURIComponent(urlPath(src));\n } catch {\n return undefined;\n }\n\n if (decoded.split(/[\\\\/]/).includes(\"..\")) {\n return undefined;\n }\n\n const file = resolve(root, `.${decoded}`);\n\n return relative(root, file).split(sep).includes(\"..\") ? undefined : file;\n}\n\nfunction weakHash(body: Uint8Array) {\n let low = 0x811c9dc5;\n let high = 0x01000193;\n\n for (const byte of body) {\n low = Math.imul(low ^ byte, 0x01000193) >>> 0;\n high = Math.imul(high ^ byte, 0x85ebca6b) >>> 0;\n }\n\n return `${low.toString(36)}${high.toString(36)}${body.byteLength.toString(36)}`;\n}\n","import { Transform } from \"node:stream\";\nimport { renderToPipeableStream } from \"react-dom/server\";\nimport type { LoadedRouteMatch } from \"../router\";\nimport { createDocumentShell } from \"../server/document-shell\";\nimport { createPageRenderTree } from \"../server/render-tree\";\nimport { createPageScriptContext } from \"../server/render-tree\";\nimport {\n renderPageResponse,\n type SsrRenderOptions,\n} from \"../server/ssr\";\n\nexport function renderNodePageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n return match.render.mode === \"streaming\"\n ? renderStreamingPageResponse(match, options)\n : renderPageResponse(match, options);\n}\n\nexport async function renderStreamingPageResponse(\n match: LoadedRouteMatch,\n options: SsrRenderOptions = {},\n) {\n if (options.signal?.aborted) {\n throw options.signal.reason;\n }\n\n const scripts = createPageScriptContext(match, options);\n const content = createPageRenderTree(match, scripts);\n\n return await new Promise<Response>((resolveResponse, rejectResponse) => {\n let completed = false;\n let cancelled = false;\n let responseCommitted = false;\n let documentSuffix = \"\";\n // TYPE-EVIDENCE: undefined is a member of the declared union type. The cast only makes the variable type explicit.\n let stream = undefined as ReturnType<typeof renderToPipeableStream> | undefined;\n const documentStream = new Transform({\n destroy(error, callback) {\n if (!completed) {\n cancelled = true;\n }\n\n callback(error);\n },\n flush(callback) {\n callback(null, documentSuffix);\n },\n transform(chunk, _encoding, callback) {\n callback(null, chunk);\n },\n });\n const abort = () => {\n cancelled = true;\n stream?.abort(options.signal?.reason);\n documentStream.destroy();\n };\n const cleanup = () => options.signal?.removeEventListener(\"abort\", abort);\n\n documentStream.once(\"finish\", () => {\n completed = true;\n });\n documentStream.once(\"close\", () => {\n cleanup();\n\n if (!completed) {\n cancelled = true;\n stream?.abort(new Error(\"Demiurge streaming response was cancelled.\"));\n }\n });\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n\n stream = renderToPipeableStream(content, {\n nonce: options.nonce,\n onError(error) {\n if (responseCommitted && !cancelled) {\n options.onStreamError?.(error);\n }\n },\n onShellError(error) {\n cleanup();\n rejectResponse(error);\n },\n onShellReady() {\n void (async () => {\n try {\n const shell = await createDocumentShell(match, {\n ...options,\n scripts: scripts.scripts(),\n });\n documentSuffix = shell.suffix;\n scripts.flushHead();\n documentStream.push(shell.prefix);\n responseCommitted = true;\n stream?.pipe(documentStream);\n resolveResponse(\n new Response(toWebReadableStream(documentStream), {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n }),\n );\n } catch (error) {\n cleanup();\n stream?.abort(error);\n documentStream.destroy();\n rejectResponse(error);\n }\n })();\n },\n });\n });\n}\n\nexport function toWebReadableStream(stream: Transform) {\n let closed = false;\n let removeListeners = () => {};\n\n return new ReadableStream<Uint8Array>({\n cancel() {\n closed = true;\n removeListeners();\n stream.pause();\n stream.destroy();\n },\n pull() {\n stream.resume();\n },\n start(controller) {\n stream.on(\"data\", onData);\n stream.once(\"end\", onEnd);\n stream.once(\"error\", onError);\n stream.once(\"close\", onClose);\n\n function onData(chunk: Buffer) {\n if (closed) {\n return;\n }\n\n controller.enqueue(Uint8Array.from(chunk));\n\n if ((controller.desiredSize ?? 1) <= 0) {\n stream.pause();\n }\n }\n\n function onEnd() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function onError(error: Error) {\n if (!closed) {\n closed = true;\n cleanup();\n controller.error(error);\n }\n }\n\n function onClose() {\n if (!closed) {\n closed = true;\n cleanup();\n controller.close();\n }\n }\n\n function cleanup() {\n stream.off(\"data\", onData);\n stream.off(\"end\", onEnd);\n stream.off(\"error\", onError);\n stream.off(\"close\", onClose);\n }\n\n removeListeners = cleanup;\n },\n });\n}\n"],"names":["forwardedHeaders","defaultTrustProxy","forbiddenMethods","UnsupportedMethodError","method","UntrustedHostError","host","ConsumedRequestBodyError","validateNodeOriginPolicy","policy","parseAuthority","trustProxy","range","network","ipMatchesRange","toWebRequest","request","options","peerAddress","normalizeIpAddress","proxy","resolveProxyChain","forwardedProtocol","selectForwardedValue","protocol","resolveProtocol","authority","validateAllowedHost","origin","url","headers","toHeaders","init","recovered","resolveRecoveredBody","Readable","webRequest","setRequestConnectionMetadata","suppliedBody","suppliedBodyContentType","knownBodyLength","parsed","encodeParsedBody","isDrainedByHost","contentType","bytes","type","mediaType","json","isRecord","encoded","toSearchParams","value","prototype","params","name","item","body","allowedHosts","candidate","expected","forwardedFor","forwarded","headerValues","chain","clientHops","index","trustedHops","isAddressTrusted","header","trustedDepth","values","address","ranges","networkValue","prefixValue","addressBytes","ipBytes","networkBytes","maximumPrefix","prefix","bit","mask","version","isIP","left","right","leftGroups","rightGroups","missing","group","writeNotImplemented","serverResponse","writeWebResponse","webResponse","cookies","getSetCookies","pipeline","error","isClientDisconnect","clientDisconnectCodes","nextHeaders","getSetCookie","combined","splitSetCookies","createFontAssetHandler","basePath","defaultFontPath","pending","loadAssets","assets","asset","respond","resolveFontAssets","etag","createHash","REVALIDATED_FILE_CACHE_CONTROL","defaultCacheSize","maximumRemoteImageBytes","createImageOptimizer","root","resolve","optimizerPath","defaultImageOptimizerPath","cacheSize","load","input","cache","variant","plainText","isAllowedImageSource","parseImageOptimizerRequest","format","negotiateImageFormat","key","source","readSource","transformImage","descriptor","response","file","resolveLocalFile","readFile","varyOnAccept","weakHash","status","extraHeaders","src","decoded","urlPath","relative","sep","low","high","byte","renderNodePageResponse","match","renderStreamingPageResponse","renderPageResponse","scripts","createPageScriptContext","content","createPageRenderTree","resolveResponse","rejectResponse","completed","cancelled","responseCommitted","documentSuffix","stream","documentStream","Transform","callback","chunk","_encoding","abort","cleanup","renderToPipeableStream","shell","createDocumentShell","toWebReadableStream","closed","removeListeners","controller","onData","onEnd","onError","onClose"],"mappings":"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"}