@voltro/cli 0.56.0 → 0.58.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/CHANGELOG.md +395 -0
- package/dist/apiBuild-CDE4NXNi.js +2 -0
- package/dist/{apiBuild-Bdaetr37.js → apiBuild-CkpsCqIu.js} +2 -2
- package/dist/bin.js +1 -1
- package/dist/build-51qBWfYY.js +981 -0
- package/dist/{checkCommand-D0QV_zM_.js → checkCommand-C1EbNmwl.js} +1 -1
- package/dist/{checkCommand-CAwFXrxA.js → checkCommand-C30J2F18.js} +4 -4
- package/dist/{codegenCommand-CidbQzbv.js → codegenCommand-kS3Twuc9.js} +12 -12
- package/dist/{codemodRunner-BlQPfjzA.js → codemodRunner-BKjCwGiN.js} +1127 -895
- package/dist/{commands-CWjfThXv.js → commands-DowWkYtd.js} +25 -25
- package/dist/{dashboardCommand-BekcY5Ls.js → dashboardCommand-gG1y4PFG.js} +3 -3
- package/dist/{dataCommand-2pccgbIy.js → dataCommand-hNOGKz4K.js} +7 -7
- package/dist/{dbCommand-DpK_vQET.js → dbCommand-CMAIz-Bf.js} +3 -3
- package/dist/dbCommand-DHi_RuDl.js +2 -0
- package/dist/{dev-Dw263KPu.js → dev-Ce2gEziv.js} +2411 -2391
- package/dist/dev-Dff_pdik.js +3 -0
- package/dist/{doctorCommand-aR_bFmIi.js → doctorCommand-5ULMpL10.js} +652 -289
- package/dist/doctorCommand-B8H2MYCE.js +2 -0
- package/dist/{dormancyCommand-eXTQMbHU.js → dormancyCommand-DYgI0Kf-.js} +3 -3
- package/dist/{embeddingsCommand-CTmiQvwa.js → embeddingsCommand-yJivQSrI.js} +2 -2
- package/dist/emptyResultHeadline-Csa5fZOF.js +18 -0
- package/dist/{envCommand-BDUgV7EM.js → envCommand-ORJUf8r_.js} +2 -2
- package/dist/{evolveCommand-YV8qW1LU.js → evolveCommand-DTawtTxf.js} +2 -2
- package/dist/frameworkTableAssembly-B96WCNJA.js +2 -0
- package/dist/{frameworkTableAssembly-DNOFXfEQ.js → frameworkTableAssembly-vfkzuzEo.js} +104 -85
- package/dist/index.js +1 -1
- package/dist/{infoCommand-BjVXpMlP.js → infoCommand-BFksHunl.js} +1 -1
- package/dist/inspect-CZvsmp8t.js +2 -0
- package/dist/{inspect-CNYvNXPU.js → inspect-PcC5J-Dl.js} +74 -59
- package/dist/{logsCmd-BU8uCdys.js → logsCmd-C5y9HyrG.js} +58 -53
- package/dist/manifestBuild-AUh31bFU.js +2 -0
- package/dist/{manifestBuild-CEkjfpwc.js → manifestBuild-BwiS4iYm.js} +1 -1
- package/dist/{migrate-SICulyz1.js → migrate-DtC3lu7H.js} +4 -4
- package/dist/{probeCommand-6HxEkNDG.js → probeCommand-BUYzc0CT.js} +1 -1
- package/dist/{runtimeTrace-DgYMc09E.js → runtimeTrace-BUk5zMXY.js} +1 -1
- package/dist/{sdkgen-PY-umd6O.js → sdkgen-CAhmmbjx.js} +1 -1
- package/dist/serveCommand-BUXUtSF5.js +2 -0
- package/dist/serveCommand-DhtC7WBq.js +2545 -0
- package/dist/serveEntry.js +1 -1
- package/dist/{start-BFQQkL1i.js → start-C75w6ftA.js} +1 -1
- package/dist/{start-B9NGB8gn.js → start-DNtIlBcn.js} +527 -502
- package/dist/startEntry.js +1 -1
- package/dist/{tracesCmd-BWYDqMy6.js → tracesCmd-C1qKa94g.js} +68 -63
- package/dist/{updateCommand-C9n_Z_oG.js → updateCommand-CtuD5r1t.js} +1 -1
- package/dist/updateCommand-eVKVHj3N.js +2 -0
- package/dist/webDev-Bzb8ZFus.js +2 -0
- package/dist/{webDev-C53hJdcL.js → webDev-CBN9KkyQ.js} +949 -834
- package/dist/{webhooksCommand-uuPu8qQX.js → webhooksCommand-BPJQOGTe.js} +2 -2
- package/package.json +61 -19
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/_manifest.json +2 -2
- package/templates/agent-docs/ai.md +175 -1
- package/templates/agent-docs/authentication.md +68 -19
- package/templates/agent-docs/cli.md +48 -0
- package/templates/agent-docs/configuration.md +29 -4
- package/templates/agent-docs/data.md +30 -0
- package/templates/agent-docs/database/scaling.md +10 -1
- package/templates/agent-docs/database/transactions.md +48 -0
- package/templates/agent-docs/deployment.md +22 -0
- package/templates/agent-docs/observability.md +13 -2
- package/templates/agent-docs/plugins/audit.md +21 -5
- package/templates/agent-docs/plugins/auth-supabase.md +21 -0
- package/templates/agent-docs/plugins/billing.md +2 -0
- package/templates/agent-docs/plugins/sentry.md +91 -8
- package/templates/agent-docs/reference.md +1 -0
- package/templates/agent-docs/scheduling.md +23 -0
- package/templates/agent-docs/schema-driven-ui.md +110 -0
- package/templates/agent-docs/whats-new.md +103 -399
- package/templates/apps/api-ai/package.json +6 -6
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -9
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-row-history/package.json +8 -8
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +7 -7
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +7 -7
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-auth/package.json +7 -7
- package/templates/apps/frontend-blank/package.json +6 -6
- package/templates/apps/frontend-cms/package.json +8 -8
- package/templates/apps/frontend-collab/package.json +9 -9
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +6 -6
- package/templates/apps/frontend-docs/package.json +8 -8
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +7 -7
- package/templates/apps/frontend-saas/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +6 -6
- package/templates/apps/frontend-ssr/package.json +6 -6
- package/templates/apps/frontend-ssr-api/package.json +7 -7
- package/templates/apps/frontend-static-blog/package.json +8 -8
- package/templates/apps/frontend-status/package.json +7 -7
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/apiBuild-Vw1figjO.js +0 -2
- package/dist/build-CI36wL4R.js +0 -868
- package/dist/dbCommand-DrycGWWt.js +0 -2
- package/dist/dev-B9Gz0k85.js +0 -3
- package/dist/doctorCommand-BMWs6aVm.js +0 -2
- package/dist/frameworkTableAssembly-CGNC0qr7.js +0 -2
- package/dist/inspect-S2rWy1Ys.js +0 -2
- package/dist/manifestBuild-DIa_s6u0.js +0 -2
- package/dist/serveCommand-BITS8Hpj.js +0 -2
- package/dist/serveCommand-DIJ3ma76.js +0 -2485
- package/dist/updateCommand-DsXEAHbd.js +0 -2
- package/dist/webDev-C2dRz9s5.js +0 -2
|
@@ -1,30 +1,51 @@
|
|
|
1
1
|
import { i as e, t } from "./nodeEnvironment-cGFAj1J8.js";
|
|
2
|
-
import {
|
|
3
|
-
import { A as
|
|
4
|
-
import { r as
|
|
5
|
-
import { o as
|
|
6
|
-
import { n as
|
|
7
|
-
import { a as
|
|
8
|
-
import { i as
|
|
9
|
-
import { n as
|
|
10
|
-
import { t as
|
|
11
|
-
import { a as
|
|
2
|
+
import { $ as n, $t as r, A as i, B as a, D as o, E as s, Et as c, F as l, Ft as u, G as d, H as ee, I as f, It as p, J as m, K as te, L as h, Lt as g, M as _, N as v, O as y, P as b, Pt as x, Q as ne, Qt as S, R as C, Rt as w, T as re, U as ie, W as ae, X as T, Y as E, Yt as oe, Z as se, a as ce, bt as le, c as D, en as ue, et as de, ft as fe, h as O, it as pe, j as me, jt as k, k as he, lt as A, m as j, mt as ge, n as _e, nt as ve, ot as ye, q as M, rt as be, s as xe, st as Se, tn as Ce, tt as N, u as we, xt as Te, z as P } from "./webDev-CBN9KkyQ.js";
|
|
3
|
+
import { A as F, I as Ee, M as De, O as Oe, g as ke, j as Ae, o as je } from "./inspect-PcC5J-Dl.js";
|
|
4
|
+
import { r as Me } from "./appPort-B_HpJ_ck.js";
|
|
5
|
+
import { o as Ne, t as Pe } from "./connectionConfig-Bk9IC7D0.js";
|
|
6
|
+
import { n as Fe, r as Ie, t as Le } from "./inspectMetrics-BY0Sjb2F.js";
|
|
7
|
+
import { a as Re, c as ze, d as Be, f as Ve, l as He, p as I, u as Ue } from "./renderModeScan-43yQ2opo.js";
|
|
8
|
+
import { i as We, n as Ge, r as Ke, t as qe } from "./runtimeRegistry-DMeKfTHP.js";
|
|
9
|
+
import { n as Je } from "./logFileSink-B4uP8pvf.js";
|
|
10
|
+
import { t as Ye } from "./bootTiming-BdyP9nYw.js";
|
|
11
|
+
import { a as Xe, n as Ze, r as Qe, t as $e } from "./staticCachePolicy-CIyj6DbS.js";
|
|
12
12
|
import { extname as L, join as R, resolve as z } from "node:path";
|
|
13
13
|
import { promises as B } from "node:fs";
|
|
14
14
|
import { pathToFileURL as V } from "node:url";
|
|
15
|
-
import { createLogger as H, printReadyBlock as
|
|
16
|
-
import { appMode as
|
|
17
|
-
import { applyKeepAlive as
|
|
18
|
-
import { Effect as
|
|
15
|
+
import { createLogger as H, printReadyBlock as et } from "@voltro/logger";
|
|
16
|
+
import { appMode as tt, frameworkVersion as nt, setProcessBootPath as rt } from "@voltro/protocol/identity";
|
|
17
|
+
import { applyKeepAlive as it, maybeCompress as U, negotiateEncoding as at, resolveKeepAlive as ot, snapshotMetricsSync as st } from "@voltro/runtime";
|
|
18
|
+
import { Effect as ct } from "effect";
|
|
19
19
|
import { createHash as W } from "node:crypto";
|
|
20
|
-
import { resolveBroadcastProvider as
|
|
21
|
-
import { createServer as
|
|
22
|
-
//#region src/
|
|
23
|
-
var
|
|
20
|
+
import { resolveBroadcastProvider as lt } from "@voltro/plugin-broadcast";
|
|
21
|
+
import { createServer as ut } from "node:http";
|
|
22
|
+
//#region src/inertPublicEnv.ts
|
|
23
|
+
var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
24
|
+
let n = [];
|
|
25
|
+
for (let [r, i] of Object.entries(e)) if (r.startsWith(dt) && i !== void 0 && i !== "") {
|
|
26
|
+
if (t === void 0 || !(r in t)) {
|
|
27
|
+
n.push({
|
|
28
|
+
key: r,
|
|
29
|
+
baked: "absent"
|
|
30
|
+
});
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
String(t[r]) !== i && n.push({
|
|
34
|
+
key: r,
|
|
35
|
+
baked: "different"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return n.sort((e, t) => e.key.localeCompare(t.key));
|
|
39
|
+
}, pt = (e) => {
|
|
40
|
+
let t = e.map((e) => e.baked === "absent" ? ` • ${e.key} — not in the bundle at all` : ` • ${e.key} — the bundle carries a DIFFERENT value; the built one wins`);
|
|
41
|
+
return `${e.length} VOLTRO_PUBLIC_* variable${e.length === 1 ? "" : "s"} set in this process's environment cannot reach the browser:\n${t.join("\n")}\n Public values are BAKED into the bundle by \`voltro build\` — that is what makes them
|
|
42
|
+
readable in a browser — so they must exist when the bundle is BUILT, not when it runs.
|
|
43
|
+
→ pass them to the build (a Docker build-arg / CI build step), not as deployment env.`;
|
|
44
|
+
}, mt = (e) => `W/"${W("md5").update(e).digest("hex")}"`, ht = (e) => {
|
|
24
45
|
let { response: t, status: n, headers: r, body: i, requestHeaders: a } = e, o = r["cache-control"], s = (typeof o == "string" ? o : "").toLowerCase();
|
|
25
46
|
if (i === void 0 || n !== 200 || s.includes("no-store")) return !1;
|
|
26
|
-
let c = r["content-type"], l = typeof c == "string" ? c : void 0, u = r.etag, d = typeof u == "string" ? u :
|
|
27
|
-
if (
|
|
47
|
+
let c = r["content-type"], l = typeof c == "string" ? c : void 0, u = r.etag, d = typeof u == "string" ? u : mt(i), ee = a["if-none-match"];
|
|
48
|
+
if (ee !== void 0 && ee.split(",").some((e) => e.trim() === d)) return t.writeHead(304, {
|
|
28
49
|
...r,
|
|
29
50
|
etag: d
|
|
30
51
|
}), t.end(), !0;
|
|
@@ -32,18 +53,18 @@ var ct = (e) => `W/"${W("md5").update(e).digest("hex")}"`, lt = (e) => {
|
|
|
32
53
|
...r,
|
|
33
54
|
etag: d
|
|
34
55
|
}), t.end(i), !0;
|
|
35
|
-
let
|
|
56
|
+
let f = U({
|
|
36
57
|
body: typeof i == "string" ? new TextEncoder().encode(i) : new Uint8Array(i),
|
|
37
58
|
contentType: l,
|
|
38
59
|
acceptEncoding: a["accept-encoding"],
|
|
39
60
|
options: e.compression
|
|
40
|
-
}),
|
|
61
|
+
}), p = {
|
|
41
62
|
...r,
|
|
42
|
-
...
|
|
63
|
+
...f.headers,
|
|
43
64
|
etag: d
|
|
44
65
|
};
|
|
45
|
-
return
|
|
46
|
-
}, G = H({ scope: "voltro:start:cdc" }),
|
|
66
|
+
return f.compressed && delete p["content-length"], t.writeHead(n, p), t.end(Buffer.from(f.bytes)), !0;
|
|
67
|
+
}, G = H({ scope: "voltro:start:cdc" }), gt = (e) => (t) => {
|
|
47
68
|
let n = 0;
|
|
48
69
|
for (let [r, i] of e.tableSubscriptionsByPattern) {
|
|
49
70
|
if (!i.includes(t)) continue;
|
|
@@ -54,13 +75,13 @@ var ct = (e) => `W/"${W("md5").update(e).digest("hex")}"`, lt = (e) => {
|
|
|
54
75
|
}));
|
|
55
76
|
}
|
|
56
77
|
return n;
|
|
57
|
-
},
|
|
58
|
-
let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r =
|
|
78
|
+
}, K = () => Pe() ? Ne() : null, _t = (e) => {
|
|
79
|
+
let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = gt(e), i = null, a = null;
|
|
59
80
|
return {
|
|
60
81
|
start: async () => {
|
|
61
82
|
let o = e.tableSubscriptionsByPattern.size > 0, s = e.onRevalidate !== void 0;
|
|
62
83
|
if (!o && !s) return G.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
|
|
63
|
-
let c =
|
|
84
|
+
let c = K();
|
|
64
85
|
if (!c && !o) return G.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
|
|
65
86
|
if (!c) return G.warn(`${e.tableSubscriptionsByPattern.size} route(s) declare \`cacheInvalidatesOn\` and will NOT be invalidated live — no database is configured for this web process. Set DB_URL (or DB_HOST / PG_HOST) so the CDC listener can connect; until then those routes go stale until their \`revalidate\` window expires.`, { routes: [...e.tableSubscriptionsByPattern.keys()] }), !1;
|
|
66
87
|
i = new (await (import("pg"))).default.Client(c), await i.connect(), a = (i) => {
|
|
@@ -102,7 +123,7 @@ var ct = (e) => `W/"${W("md5").update(e).digest("hex")}"`, lt = (e) => {
|
|
|
102
123
|
}
|
|
103
124
|
}
|
|
104
125
|
};
|
|
105
|
-
},
|
|
126
|
+
}, vt = H({ scope: "voltro:start:isr-cache" }), q = "voltro_isr_cache", yt = (e) => `
|
|
106
127
|
CREATE TABLE IF NOT EXISTS ${e} (
|
|
107
128
|
cache_key TEXT PRIMARY KEY,
|
|
108
129
|
html TEXT NOT NULL,
|
|
@@ -113,9 +134,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
|
|
|
113
134
|
stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
|
|
114
135
|
);
|
|
115
136
|
CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
116
|
-
`,
|
|
117
|
-
let t = e.tableName ??
|
|
118
|
-
i || (i = !0, await n.query(
|
|
137
|
+
`, bt = (e) => {
|
|
138
|
+
let t = e.tableName ?? q, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
|
|
139
|
+
i || (i = !0, await n.query(yt(t)));
|
|
119
140
|
})().then(async () => {
|
|
120
141
|
let e = await n.query(`SELECT * FROM ${t}`);
|
|
121
142
|
for (let t of e.rows) r.set(t.cache_key, {
|
|
@@ -127,10 +148,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
127
148
|
staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
|
|
128
149
|
});
|
|
129
150
|
}).catch((e) => {
|
|
130
|
-
|
|
151
|
+
vt.warn("postgres bootstrap failed", {}, e);
|
|
131
152
|
}), o = (e, t) => {
|
|
132
153
|
a.then(() => n.query(e, t)).catch((e) => {
|
|
133
|
-
|
|
154
|
+
vt.warn("postgres write failed", {}, e);
|
|
134
155
|
});
|
|
135
156
|
}, s = /* @__PURE__ */ new Map(), c = (e) => {
|
|
136
157
|
s.set(e, (s.get(e) ?? 0) + 1);
|
|
@@ -181,7 +202,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
181
202
|
return Array.from(r.entries());
|
|
182
203
|
}
|
|
183
204
|
};
|
|
184
|
-
}, J = H({ scope: "voltro:start:revalidate" }),
|
|
205
|
+
}, J = H({ scope: "voltro:start:revalidate" }), xt = (e) => {
|
|
185
206
|
try {
|
|
186
207
|
let t = JSON.parse(e);
|
|
187
208
|
return (t.kind === "path" || t.kind === "table" || t.kind === "tag") && typeof t.value == "string" && t.value.length > 0 && (t.tenant === void 0 || typeof t.tenant == "string") ? {
|
|
@@ -192,7 +213,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
192
213
|
} catch {
|
|
193
214
|
return J.warn("bad revalidation payload (not JSON)", { payload: e }), null;
|
|
194
215
|
}
|
|
195
|
-
},
|
|
216
|
+
}, St = (e, t) => {
|
|
196
217
|
if (t.kind === "table" || t.kind === "tag") {
|
|
197
218
|
let n = e.tableSink(t.value);
|
|
198
219
|
return J.info(`revalidate ${t.kind} '${t.value}' → dropped ${n} cache entries`, {
|
|
@@ -232,7 +253,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
232
253
|
dropped: s,
|
|
233
254
|
...t.tenant === void 0 ? {} : { tenant: t.tenant }
|
|
234
255
|
}), s;
|
|
235
|
-
}, Y = H({ scope: "voltro:start" }),
|
|
256
|
+
}, Y = H({ scope: "voltro:start" }), Ct = nt() ?? "unknown", X = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", wt = (e) => e instanceof Error && e._voltroControl === "not-found", Tt = {
|
|
236
257
|
".html": "text/html; charset=utf-8",
|
|
237
258
|
".js": "application/javascript",
|
|
238
259
|
".mjs": "application/javascript",
|
|
@@ -250,13 +271,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
250
271
|
".woff": "font/woff",
|
|
251
272
|
".woff2": "font/woff2",
|
|
252
273
|
".txt": "text/plain; charset=utf-8"
|
|
253
|
-
},
|
|
274
|
+
}, Et = (e) => Tt[L(e).toLowerCase()] ?? "application/octet-stream", Dt = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), Z = async (e) => {
|
|
254
275
|
try {
|
|
255
276
|
return await B.stat(e), !0;
|
|
256
277
|
} catch {
|
|
257
278
|
return !1;
|
|
258
279
|
}
|
|
259
|
-
},
|
|
280
|
+
}, Ot = (e) => {
|
|
260
281
|
let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
|
|
261
282
|
for (let e of r) e.startsWith("[[...") && e.endsWith("]]") ? (i.push("(.*)"), t.push(e.slice(5, -2)), n += 2) : e.startsWith("[...") && e.endsWith("]") ? (i.push("(.+)"), t.push(e.slice(4, -1)), n += 3) : e.startsWith("[") && e.endsWith("]") ? (i.push("([^/]+)"), t.push(e.slice(1, -1)), n += 1) : i.push(e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
262
283
|
let a = i.join("/");
|
|
@@ -265,8 +286,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
265
286
|
paramNames: t,
|
|
266
287
|
priority: n
|
|
267
288
|
};
|
|
268
|
-
},
|
|
269
|
-
let { regex: t, paramNames: n, priority: r } =
|
|
289
|
+
}, kt = (e) => e.map((e) => {
|
|
290
|
+
let { regex: t, paramNames: n, priority: r } = Ot(e.pattern);
|
|
270
291
|
return {
|
|
271
292
|
pattern: e.pattern,
|
|
272
293
|
file: e.file,
|
|
@@ -275,7 +296,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
275
296
|
paramNames: n,
|
|
276
297
|
priority: r
|
|
277
298
|
};
|
|
278
|
-
}).slice().sort((e, t) => e.priority - t.priority),
|
|
299
|
+
}).slice().sort((e, t) => e.priority - t.priority), At = (e, t) => {
|
|
279
300
|
for (let n of t) {
|
|
280
301
|
let t = n.regex.exec(e);
|
|
281
302
|
if (!t) continue;
|
|
@@ -287,7 +308,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
287
308
|
};
|
|
288
309
|
}
|
|
289
310
|
return null;
|
|
290
|
-
},
|
|
311
|
+
}, jt = null, Mt, Nt = (e, t) => t === void 0 ? Promise.resolve() : (Mt ??= (async () => {
|
|
291
312
|
try {
|
|
292
313
|
let n = await e.getHelpers(), r = n.apiDescriptors?.[t];
|
|
293
314
|
if (r === void 0) return;
|
|
@@ -295,21 +316,21 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
295
316
|
if (i === void 0) return;
|
|
296
317
|
i(t, await r());
|
|
297
318
|
} catch {}
|
|
298
|
-
})(),
|
|
299
|
-
let { provider: t, route: r, params:
|
|
300
|
-
await
|
|
301
|
-
let { search:
|
|
319
|
+
})(), Mt), Pt = async (e) => {
|
|
320
|
+
let { provider: t, route: r, params: i, pathname: a, dirs: o, shellTemplate: s, requestHeaders: c, requestUrl: l = "", apiOrigin: u, apiName: d } = e;
|
|
321
|
+
await Nt(t, d);
|
|
322
|
+
let { search: p } = be(l), g = await ie(ae(e.middlewares ?? [], {
|
|
302
323
|
route: r.pattern,
|
|
303
|
-
pathname:
|
|
324
|
+
pathname: a
|
|
304
325
|
}), {
|
|
305
|
-
pathname:
|
|
306
|
-
search:
|
|
307
|
-
headers:
|
|
308
|
-
cookies: ee(
|
|
326
|
+
pathname: a,
|
|
327
|
+
search: p,
|
|
328
|
+
headers: c,
|
|
329
|
+
cookies: ee(c.cookie),
|
|
309
330
|
route: r.pattern
|
|
310
|
-
}, e.onCookieWarning), y = await t.getPage(r.pattern, r.file),
|
|
311
|
-
apiName:
|
|
312
|
-
headers:
|
|
331
|
+
}, e.onCookieWarning), y = await t.getPage(r.pattern, r.file), x = e.forceSsrRender === !0 ? "ssr" : ze(y, r.file), ne = x === "isr" && y.ppr === !0, S = x === "isr" && e.holesOnly !== !0 ? h(g.headers) : g.headers, C = xe(u, S.cookie, {
|
|
332
|
+
apiName: d,
|
|
333
|
+
headers: S
|
|
313
334
|
});
|
|
314
335
|
if (e.holesOnly === !0) {
|
|
315
336
|
if (typeof y.loader != "function") return null;
|
|
@@ -318,239 +339,239 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
318
339
|
holes: {
|
|
319
340
|
loader: y.loader,
|
|
320
341
|
ctx: {
|
|
321
|
-
params:
|
|
322
|
-
pathname:
|
|
323
|
-
search:
|
|
342
|
+
params: i,
|
|
343
|
+
pathname: a,
|
|
344
|
+
search: p,
|
|
324
345
|
signal: e.signal,
|
|
325
|
-
headers:
|
|
326
|
-
query:
|
|
346
|
+
headers: S,
|
|
347
|
+
query: C,
|
|
327
348
|
isServer: !0
|
|
328
349
|
},
|
|
329
350
|
helpers: await t.getHelpers(),
|
|
330
351
|
page: r.pattern
|
|
331
352
|
},
|
|
332
|
-
setCookies:
|
|
353
|
+
setCookies: g.setCookies
|
|
333
354
|
};
|
|
334
355
|
}
|
|
335
|
-
let
|
|
336
|
-
if (
|
|
337
|
-
let
|
|
356
|
+
let w = x === "spa" && we(o, r.dirChain).some((e) => e.hasLayout);
|
|
357
|
+
if (x !== "ssr" && x !== "isr" && !w) return null;
|
|
358
|
+
let re = we(o, r.dirChain), oe = {}, ce = null, le, ue = new AbortController(), fe = ne ? b(S, r.pattern) : S;
|
|
338
359
|
try {
|
|
339
|
-
(await t.getHelpers()).beginStoreSeeds(), {chain:
|
|
340
|
-
entries:
|
|
360
|
+
(await t.getHelpers()).beginStoreSeeds(), {chain: le, segmentLoaderData: oe} = await D({
|
|
361
|
+
entries: re,
|
|
341
362
|
loadLayout: (e) => t.getLayout(e.dir),
|
|
342
363
|
loadError: (e) => t.getError(e.dir),
|
|
343
364
|
loadPending: (e) => t.getPending(e.dir),
|
|
344
365
|
ctx: {
|
|
345
|
-
params:
|
|
346
|
-
pathname:
|
|
347
|
-
search:
|
|
348
|
-
signal:
|
|
349
|
-
headers:
|
|
350
|
-
query:
|
|
366
|
+
params: i,
|
|
367
|
+
pathname: a,
|
|
368
|
+
search: p,
|
|
369
|
+
signal: ue.signal,
|
|
370
|
+
headers: fe,
|
|
371
|
+
query: C,
|
|
351
372
|
isServer: !0
|
|
352
373
|
}
|
|
353
|
-
}), typeof y.loader == "function" && !
|
|
354
|
-
params:
|
|
355
|
-
pathname:
|
|
356
|
-
search:
|
|
357
|
-
signal:
|
|
358
|
-
headers:
|
|
359
|
-
query:
|
|
374
|
+
}), typeof y.loader == "function" && !w && (ce = await y.loader({
|
|
375
|
+
params: i,
|
|
376
|
+
pathname: a,
|
|
377
|
+
search: p,
|
|
378
|
+
signal: ue.signal,
|
|
379
|
+
headers: fe,
|
|
380
|
+
query: C,
|
|
360
381
|
isServer: !0
|
|
361
382
|
}));
|
|
362
383
|
} catch (e) {
|
|
363
|
-
if (
|
|
384
|
+
if (X(e)) return {
|
|
364
385
|
control: "redirect",
|
|
365
386
|
status: e.status,
|
|
366
387
|
location: e.location,
|
|
367
|
-
setCookies:
|
|
368
|
-
responseHeaders:
|
|
388
|
+
setCookies: g.setCookies,
|
|
389
|
+
responseHeaders: g.responseHeaders
|
|
369
390
|
};
|
|
370
|
-
if (
|
|
391
|
+
if (wt(e)) return {
|
|
371
392
|
control: "not-found",
|
|
372
|
-
setCookies:
|
|
373
|
-
responseHeaders:
|
|
393
|
+
setCookies: g.setCookies,
|
|
394
|
+
responseHeaders: g.responseHeaders
|
|
374
395
|
};
|
|
375
396
|
throw e;
|
|
376
397
|
}
|
|
377
|
-
let
|
|
378
|
-
|
|
398
|
+
let O = await t.getHelpers();
|
|
399
|
+
w || await te({
|
|
379
400
|
pageMod: y,
|
|
380
|
-
params:
|
|
381
|
-
query:
|
|
382
|
-
apiName:
|
|
383
|
-
seed:
|
|
384
|
-
seedFailure:
|
|
401
|
+
params: i,
|
|
402
|
+
query: C,
|
|
403
|
+
apiName: d,
|
|
404
|
+
seed: O.seedPreloadedSubscription,
|
|
405
|
+
seedFailure: O.seedPreloadedSubscriptionFailure,
|
|
385
406
|
onError: ({ tag: e, apiName: t }, n) => Y.warn("preload seed failed", {
|
|
386
407
|
tag: e,
|
|
387
408
|
apiName: t,
|
|
388
|
-
pathname:
|
|
409
|
+
pathname: a
|
|
389
410
|
}, n)
|
|
390
411
|
});
|
|
391
|
-
let
|
|
412
|
+
let pe = {
|
|
392
413
|
pattern: r.pattern,
|
|
393
414
|
Component: y.default,
|
|
394
415
|
meta: y.meta,
|
|
395
416
|
loader: y.loader,
|
|
396
417
|
ErrorBoundary: y.ErrorBoundary,
|
|
397
418
|
Pending: y.Pending,
|
|
398
|
-
renderMode:
|
|
399
|
-
chain:
|
|
419
|
+
renderMode: x,
|
|
420
|
+
chain: le
|
|
400
421
|
};
|
|
401
|
-
if (
|
|
402
|
-
let
|
|
403
|
-
cookies:
|
|
404
|
-
headers:
|
|
405
|
-
url:
|
|
422
|
+
if (x === "isr" && g.cspNonce !== void 0) throw Error(`page '${r.pattern}' is renderMode 'isr' while middleware.ts mints a cspNonce — an isr render is CACHED and a cached nonce is a lie the browser enforces. Use renderMode 'ssr' for nonce'd pages, or a hash-based CSP for isr.`);
|
|
423
|
+
let me = {
|
|
424
|
+
cookies: ne ? v(f(g.cookies), r.pattern) : x === "isr" ? f(g.cookies) : g.cookies,
|
|
425
|
+
headers: fe,
|
|
426
|
+
url: l,
|
|
406
427
|
...e.formFlash === void 0 ? {} : { formFlash: e.formFlash }
|
|
407
|
-
},
|
|
408
|
-
lang:
|
|
409
|
-
...
|
|
428
|
+
}, k = O.i18n?.resolve(S.cookie, S["accept-language"]), he = {
|
|
429
|
+
lang: k?.locale ?? me.cookies["voltro:locale"] ?? "en",
|
|
430
|
+
...k?.timeZone === void 0 ? {} : { timeZone: k.timeZone },
|
|
410
431
|
renderedAt: Date.now()
|
|
411
|
-
},
|
|
412
|
-
if (
|
|
413
|
-
let e =
|
|
414
|
-
helpers:
|
|
432
|
+
}, A = y.interactive ?? "full";
|
|
433
|
+
if (w) {
|
|
434
|
+
let e = de({
|
|
435
|
+
helpers: O,
|
|
415
436
|
page: r.pattern,
|
|
416
|
-
interactive:
|
|
437
|
+
interactive: A,
|
|
417
438
|
delivery: "stream",
|
|
418
439
|
renderInput: {
|
|
419
|
-
descriptor:
|
|
420
|
-
params:
|
|
421
|
-
pathname:
|
|
422
|
-
search:
|
|
423
|
-
segmentLoaderData:
|
|
424
|
-
requestContext:
|
|
425
|
-
...
|
|
426
|
-
outerWrap:
|
|
427
|
-
locale:
|
|
440
|
+
descriptor: pe,
|
|
441
|
+
params: i,
|
|
442
|
+
pathname: a,
|
|
443
|
+
search: p,
|
|
444
|
+
segmentLoaderData: oe,
|
|
445
|
+
requestContext: me,
|
|
446
|
+
...k ? {
|
|
447
|
+
outerWrap: k.outerWrap,
|
|
448
|
+
locale: k.locale
|
|
428
449
|
} : {}
|
|
429
450
|
}
|
|
430
|
-
}), t = (t) =>
|
|
431
|
-
helpers:
|
|
451
|
+
}), t = (t) => ve({
|
|
452
|
+
helpers: O,
|
|
432
453
|
prepared: e,
|
|
433
454
|
meta: t,
|
|
434
|
-
interactive:
|
|
455
|
+
interactive: A
|
|
435
456
|
});
|
|
436
457
|
if (e.hasDeferred) {
|
|
437
|
-
let n =
|
|
458
|
+
let n = E({ shell: s });
|
|
438
459
|
return {
|
|
439
460
|
renderMode: "spa",
|
|
440
|
-
setCookies:
|
|
441
|
-
responseHeaders:
|
|
442
|
-
stream: (r) =>
|
|
461
|
+
setCookies: g.setCookies,
|
|
462
|
+
responseHeaders: g.responseHeaders,
|
|
463
|
+
stream: (r) => se({
|
|
443
464
|
res: r,
|
|
444
465
|
shell: n,
|
|
445
|
-
documentAttrs:
|
|
466
|
+
documentAttrs: he,
|
|
446
467
|
headers: {
|
|
447
|
-
...
|
|
468
|
+
...g.responseHeaders,
|
|
448
469
|
"content-type": "text/html; charset=utf-8",
|
|
449
470
|
"x-voltro-rendered-by": "spa",
|
|
450
|
-
...
|
|
471
|
+
...P(g.setCookies)
|
|
451
472
|
},
|
|
452
473
|
headInjection: t,
|
|
453
|
-
...
|
|
454
|
-
render: (t) =>
|
|
474
|
+
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce },
|
|
475
|
+
render: (t) => O.renderPageToStream({
|
|
455
476
|
...e.renderInput,
|
|
456
477
|
...t,
|
|
457
|
-
...
|
|
478
|
+
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce }
|
|
458
479
|
}),
|
|
459
480
|
onShellError: (e) => {
|
|
460
|
-
Y.error("spa layout shell render failed", { pathname:
|
|
481
|
+
Y.error("spa layout shell render failed", { pathname: a }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
|
|
461
482
|
}
|
|
462
483
|
})
|
|
463
484
|
};
|
|
464
485
|
}
|
|
465
|
-
let n =
|
|
466
|
-
helpers:
|
|
486
|
+
let n = N({
|
|
487
|
+
helpers: O,
|
|
467
488
|
prepared: e
|
|
468
|
-
}),
|
|
489
|
+
}), o = M(m(s.replace("<div id=\"root\"></div>", `<div id="root">${n.body}</div>`), t(n.meta)), he);
|
|
469
490
|
return {
|
|
470
|
-
html:
|
|
491
|
+
html: g.cspNonce === void 0 ? o : T(o, g.cspNonce),
|
|
471
492
|
renderMode: "spa",
|
|
472
493
|
revalidateMs: null,
|
|
473
|
-
setCookies:
|
|
474
|
-
responseHeaders:
|
|
494
|
+
setCookies: g.setCookies,
|
|
495
|
+
responseHeaders: g.responseHeaders
|
|
475
496
|
};
|
|
476
497
|
}
|
|
477
|
-
let
|
|
478
|
-
helpers:
|
|
498
|
+
let j = n({
|
|
499
|
+
helpers: O,
|
|
479
500
|
page: r.pattern,
|
|
480
|
-
pathname:
|
|
481
|
-
renderMode:
|
|
482
|
-
interactive:
|
|
483
|
-
loaderData:
|
|
484
|
-
segmentLoaderData:
|
|
501
|
+
pathname: a,
|
|
502
|
+
renderMode: x,
|
|
503
|
+
interactive: A,
|
|
504
|
+
loaderData: ce,
|
|
505
|
+
segmentLoaderData: oe,
|
|
485
506
|
pageLoaderRan: typeof y.loader == "function",
|
|
486
|
-
...
|
|
507
|
+
...ne ? { ppr: !0 } : {}
|
|
487
508
|
});
|
|
488
|
-
|
|
489
|
-
let
|
|
490
|
-
descriptor:
|
|
491
|
-
params:
|
|
492
|
-
pathname:
|
|
493
|
-
search:
|
|
494
|
-
loaderData:
|
|
495
|
-
segmentLoaderData:
|
|
496
|
-
requestContext:
|
|
497
|
-
...
|
|
498
|
-
outerWrap:
|
|
499
|
-
locale:
|
|
509
|
+
ne && _(j.stateInput, r.pattern);
|
|
510
|
+
let ge = {
|
|
511
|
+
descriptor: pe,
|
|
512
|
+
params: i,
|
|
513
|
+
pathname: a,
|
|
514
|
+
search: p,
|
|
515
|
+
loaderData: j.loaderData,
|
|
516
|
+
segmentLoaderData: j.segmentLoaderData,
|
|
517
|
+
requestContext: me,
|
|
518
|
+
...k ? {
|
|
519
|
+
outerWrap: k.outerWrap,
|
|
520
|
+
locale: k.locale
|
|
500
521
|
} : {}
|
|
501
|
-
},
|
|
502
|
-
if (
|
|
503
|
-
let n =
|
|
522
|
+
}, _e = (t) => {
|
|
523
|
+
if (jt === null || x !== "ssr" && x !== "isr" || typeof y.ogImage != "function" || t.includes("og:image")) return "";
|
|
524
|
+
let n = S["x-tenant"], i = jt.signOgUrl({
|
|
504
525
|
pattern: r.pattern,
|
|
505
526
|
params: e.params,
|
|
506
527
|
...n === void 0 ? {} : { tenant: n }
|
|
507
528
|
});
|
|
508
529
|
return `<meta property="og:image" content="${i}" /><meta name="twitter:image" content="${i}" /><meta name="twitter:card" content="summary_large_image" />`;
|
|
509
|
-
},
|
|
510
|
-
|
|
511
|
-
`<meta name="voltro-interactive" content="${
|
|
512
|
-
...
|
|
513
|
-
|
|
530
|
+
}, ye = (e) => [
|
|
531
|
+
O.renderMetaToHtml(e) + _e(O.renderMetaToHtml(e)),
|
|
532
|
+
`<meta name="voltro-interactive" content="${A}" />`,
|
|
533
|
+
...j.hasDeferred ? [O.renderDeferredRegistryScript()] : [],
|
|
534
|
+
O.renderRouterStateScript(j.stateInput)
|
|
514
535
|
].filter((e) => e.length > 0).join("\n ");
|
|
515
|
-
if (
|
|
516
|
-
let e =
|
|
536
|
+
if (x === "ssr" && A === "full" && e.buffered !== !0) {
|
|
537
|
+
let e = E({ shell: s });
|
|
517
538
|
return {
|
|
518
539
|
renderMode: "ssr",
|
|
519
|
-
setCookies:
|
|
520
|
-
stream: (t) =>
|
|
540
|
+
setCookies: g.setCookies,
|
|
541
|
+
stream: (t) => se({
|
|
521
542
|
res: t,
|
|
522
543
|
shell: e,
|
|
523
|
-
documentAttrs:
|
|
544
|
+
documentAttrs: he,
|
|
524
545
|
headers: {
|
|
525
|
-
...
|
|
546
|
+
...g.responseHeaders,
|
|
526
547
|
"content-type": "text/html; charset=utf-8",
|
|
527
548
|
"x-voltro-rendered-by": "ssr",
|
|
528
|
-
...
|
|
549
|
+
...P(g.setCookies)
|
|
529
550
|
},
|
|
530
|
-
headInjection:
|
|
531
|
-
...
|
|
532
|
-
render: (e) =>
|
|
533
|
-
...
|
|
551
|
+
headInjection: ye,
|
|
552
|
+
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce },
|
|
553
|
+
render: (e) => O.renderPageToStream({
|
|
554
|
+
...ge,
|
|
534
555
|
...e,
|
|
535
|
-
...
|
|
556
|
+
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce }
|
|
536
557
|
}),
|
|
537
558
|
onShellError: (e) => {
|
|
538
|
-
Y.error("ssr shell render failed", { pathname:
|
|
559
|
+
Y.error("ssr shell render failed", { pathname: a }, e), t.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), t.end("server error");
|
|
539
560
|
}
|
|
540
561
|
})
|
|
541
562
|
};
|
|
542
563
|
}
|
|
543
|
-
let { html:
|
|
544
|
-
|
|
545
|
-
let Ee =
|
|
564
|
+
let { html: Se, meta: Ce } = O.renderPageToHtml(ge), Te = ye(Ce), F = M(m(s.replace("<div id=\"root\"></div>", `<div id="root">${Se}</div>`), Te), he);
|
|
565
|
+
A === "none" && (F = Dt(F));
|
|
566
|
+
let Ee = x === "isr" ? I(y.revalidate) : null;
|
|
546
567
|
return {
|
|
547
|
-
html:
|
|
548
|
-
renderMode:
|
|
568
|
+
html: g.cspNonce === void 0 ? F : T(F, g.cspNonce),
|
|
569
|
+
renderMode: x,
|
|
549
570
|
revalidateMs: Ee,
|
|
550
|
-
setCookies:
|
|
551
|
-
responseHeaders:
|
|
571
|
+
setCookies: g.setCookies,
|
|
572
|
+
responseHeaders: g.responseHeaders
|
|
552
573
|
};
|
|
553
|
-
}, Q = (e) => e === "" ? "/" : e,
|
|
574
|
+
}, Q = (e) => e === "" ? "/" : e, Ft = async (e) => {
|
|
554
575
|
let t = await import(V(e).href);
|
|
555
576
|
return {
|
|
556
577
|
kind: "bundle",
|
|
@@ -580,11 +601,11 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
580
601
|
},
|
|
581
602
|
async close() {}
|
|
582
603
|
};
|
|
583
|
-
},
|
|
584
|
-
let n = await
|
|
604
|
+
}, It = async (e, t) => {
|
|
605
|
+
let n = await S("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
|
|
585
606
|
root: t,
|
|
586
607
|
envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
|
|
587
|
-
plugins: [
|
|
608
|
+
plugins: [r(), i()],
|
|
588
609
|
resolve: { dedupe: [
|
|
589
610
|
"react",
|
|
590
611
|
"react-dom",
|
|
@@ -598,131 +619,142 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
598
619
|
},
|
|
599
620
|
appType: "custom",
|
|
600
621
|
logLevel: "warn"
|
|
601
|
-
}),
|
|
602
|
-
limit:
|
|
622
|
+
}), o = R(e, "src", "pages"), s = (e) => e === "" ? o : R(o, e), c = g({
|
|
623
|
+
limit: w(),
|
|
603
624
|
onColdStart: (e) => Y.debug("ssr cold-compile start", { id: e }),
|
|
604
625
|
onColdEnd: (e, { durationMs: t, failed: n }) => Y.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
|
|
605
626
|
id: e,
|
|
606
627
|
ms: t,
|
|
607
628
|
...n ? { failed: !0 } : {}
|
|
608
629
|
})
|
|
609
|
-
}),
|
|
630
|
+
}), l = (e) => c.load(e, async () => await a.ssrLoadModule(e));
|
|
610
631
|
return {
|
|
611
632
|
kind: "middleware",
|
|
612
633
|
async getPage(e, t) {
|
|
613
|
-
return
|
|
634
|
+
return l(R(o, t));
|
|
614
635
|
},
|
|
615
636
|
async getLayout(e) {
|
|
616
|
-
return
|
|
637
|
+
return l(R(s(e), "layout.tsx"));
|
|
617
638
|
},
|
|
618
639
|
async getError(e) {
|
|
619
|
-
return
|
|
640
|
+
return l(R(s(e), "error.tsx"));
|
|
620
641
|
},
|
|
621
642
|
async getPending(e) {
|
|
622
|
-
return
|
|
643
|
+
return l(R(s(e), "loading.tsx"));
|
|
623
644
|
},
|
|
624
645
|
async getHelpers() {
|
|
625
|
-
return await
|
|
646
|
+
return await l("@voltro/web/ssr");
|
|
626
647
|
},
|
|
627
648
|
async close() {
|
|
628
|
-
await
|
|
649
|
+
await a.close();
|
|
629
650
|
}
|
|
630
651
|
};
|
|
631
|
-
},
|
|
632
|
-
let n =
|
|
633
|
-
if (!
|
|
652
|
+
}, Lt = async (t) => {
|
|
653
|
+
let n = Ye(), f = await j(t);
|
|
654
|
+
if (!f) return {
|
|
634
655
|
ran: !1,
|
|
635
656
|
exitCode: 0
|
|
636
657
|
};
|
|
637
|
-
if (
|
|
658
|
+
if (f.type !== "web") return Y.error("only web apps are supported by `voltro start`"), {
|
|
638
659
|
ran: !0,
|
|
639
660
|
exitCode: 1
|
|
640
661
|
};
|
|
641
662
|
{
|
|
642
|
-
let e =
|
|
663
|
+
let e = s(f);
|
|
643
664
|
if (e !== void 0) return Y.error(`voltro start: refusing to boot — ${e}`), {
|
|
644
665
|
ran: !0,
|
|
645
666
|
exitCode: 1
|
|
646
667
|
};
|
|
647
668
|
}
|
|
648
|
-
let { resolved:
|
|
649
|
-
rawEnv:
|
|
669
|
+
let { resolved: m } = await oe({
|
|
670
|
+
rawEnv: f.env,
|
|
650
671
|
appType: "web",
|
|
651
672
|
root: t,
|
|
652
673
|
log: Y,
|
|
653
674
|
generateTypes: !1
|
|
654
|
-
}),
|
|
675
|
+
}), te = m.publicValues;
|
|
655
676
|
n.mark("config");
|
|
656
|
-
let
|
|
657
|
-
|
|
658
|
-
let
|
|
677
|
+
let h = ue();
|
|
678
|
+
fe(h), Y.info("booting voltro start", { app: f.name ?? "(unnamed)" });
|
|
679
|
+
let g = Me({
|
|
659
680
|
kind: "web",
|
|
660
|
-
configPort:
|
|
681
|
+
configPort: f.port,
|
|
661
682
|
env: process.env,
|
|
662
|
-
dashboardPin: process.env[
|
|
683
|
+
dashboardPin: process.env[pe] === "1"
|
|
663
684
|
});
|
|
664
|
-
for (let e of
|
|
665
|
-
let
|
|
666
|
-
|
|
685
|
+
for (let e of g.warnings) Y.warn(e);
|
|
686
|
+
let _ = g.port, v = R(t, ".framework");
|
|
687
|
+
{
|
|
688
|
+
let e;
|
|
689
|
+
try {
|
|
690
|
+
e = JSON.parse(await B.readFile(R(v, "env.public.json"), "utf8"));
|
|
691
|
+
} catch {
|
|
692
|
+
e = void 0;
|
|
693
|
+
}
|
|
694
|
+
let t = ft(process.env, e);
|
|
695
|
+
t.length > 0 && Y.warn(pt(t));
|
|
696
|
+
}
|
|
697
|
+
let b = R(v, "dist"), S = R(b, "index.html");
|
|
698
|
+
if (!await Z(S)) return Y.error("no built dist found — run `voltro build` first", { distDir: b }), {
|
|
667
699
|
ran: !0,
|
|
668
700
|
exitCode: 1
|
|
669
701
|
};
|
|
670
|
-
let
|
|
671
|
-
await
|
|
672
|
-
id:
|
|
673
|
-
name:
|
|
702
|
+
let w = f.name ?? "unnamed", T = qe("web", w, _), E = Je(w);
|
|
703
|
+
await We({
|
|
704
|
+
id: T,
|
|
705
|
+
name: w,
|
|
674
706
|
kind: "web",
|
|
675
|
-
url: `http://localhost:${
|
|
707
|
+
url: `http://localhost:${_}`,
|
|
676
708
|
pid: process.pid,
|
|
677
709
|
status: "booting",
|
|
678
|
-
logFile:
|
|
710
|
+
logFile: E.path
|
|
679
711
|
}).catch(() => {});
|
|
680
|
-
let
|
|
681
|
-
|
|
712
|
+
let se = R(b, "_voltro", "shell.html"), D = await Z(se) ? await B.readFile(se, "utf8") : await B.readFile(S, "utf8"), de = await O(t, f), ve = Fe(f), M = Xe(f), N = _e(de[0]), P = de[0]?.name, ze = /* @__PURE__ */ new Set(), I = (e) => {
|
|
713
|
+
ze.has(e.name) || (ze.add(e.name), Y.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
|
|
682
714
|
cookie: e.name,
|
|
683
715
|
hint: "If your IdP client reads this from `document.cookie` (Supabase's `createBrowserClient` does), pass `httpOnly: false`. Otherwise the SSR render succeeds and the user is signed out at the first client-side call. Set `httpOnly: true` explicitly to silence this."
|
|
684
716
|
}));
|
|
685
|
-
}, L = await
|
|
717
|
+
}, L = await a(t);
|
|
686
718
|
L.length > 0 && Y.info(`middleware.ts loaded — ${L.length} middleware(s): ` + L.map((e) => e.exportName).join(", "));
|
|
687
719
|
let z, V = null, H = process.env.SSR_CACHE === "postgres";
|
|
688
|
-
if (H &&
|
|
720
|
+
if (H && Pe()) V = new (await (import("pg"))).default.Client(Ne()), await V.connect(), z = bt({ client: V }), Y.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
|
|
689
721
|
else if (H) {
|
|
690
722
|
let t = "SSR_CACHE=postgres, but nothing in the environment names a database (looked for DB_URL, DB_PRIMARY_URL, DB_DIRECT_URL, DB_MIGRATE_URL, DB_HOST, PG_HOST).";
|
|
691
723
|
if (e()) throw Y.fatal(`${t} Refusing to fall back to the per-process memory cache: it is not shared between instances and does not survive a restart, so the pages this process serves would differ from its replicas' with nothing to indicate it.`), Error("[voltro start] SSR_CACHE=postgres with no database configured");
|
|
692
|
-
z =
|
|
693
|
-
} else z =
|
|
694
|
-
await
|
|
695
|
-
let
|
|
696
|
-
|
|
697
|
-
let
|
|
698
|
-
if (!
|
|
699
|
-
let K =
|
|
724
|
+
z = Ve(), Y.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
|
|
725
|
+
} else z = Ve(), Y.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
|
|
726
|
+
await o(t, f, de, te);
|
|
727
|
+
let nt = R(t, "src", "pages"), { pages: rt, dirs: U } = await re(nt), W = kt(rt);
|
|
728
|
+
C(L, W.map((e) => e.pattern)), n.mark("scan");
|
|
729
|
+
let dt = R(b, "server", "ssrEntry.js"), G = await Z(dt);
|
|
730
|
+
if (!G && process.env.NODE_ENV === "production") throw Y.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${dt} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${dt}`);
|
|
731
|
+
let K = G ? await Ft(dt) : await It(t, v);
|
|
700
732
|
Y.info(`ssr loader: ${K.kind}`, {
|
|
701
733
|
kind: K.kind,
|
|
702
734
|
...K.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
|
|
703
735
|
}), n.mark("provider");
|
|
704
|
-
let
|
|
705
|
-
|
|
706
|
-
let q = /* @__PURE__ */ new Map(),
|
|
707
|
-
for (let e of
|
|
708
|
-
let t =
|
|
736
|
+
let vt = K.getPageMeta?.();
|
|
737
|
+
c(t);
|
|
738
|
+
let q = /* @__PURE__ */ new Map(), yt = 0;
|
|
739
|
+
for (let e of rt) {
|
|
740
|
+
let t = vt?.[e.pattern];
|
|
709
741
|
if (t) {
|
|
710
742
|
q.set(e.pattern, t);
|
|
711
743
|
continue;
|
|
712
744
|
}
|
|
713
745
|
try {
|
|
714
746
|
let t = await K.getPage(e.pattern, e.file);
|
|
715
|
-
q.set(e.pattern,
|
|
747
|
+
q.set(e.pattern, Re(t, e.file)), yt++;
|
|
716
748
|
} catch (t) {
|
|
717
749
|
Y.warn("failed to load page metadata", { pattern: e.pattern }, t);
|
|
718
750
|
}
|
|
719
751
|
}
|
|
720
|
-
let
|
|
752
|
+
let J = /* @__PURE__ */ new Map();
|
|
721
753
|
for (let [e, t] of q) {
|
|
722
754
|
if (t.interactive !== "islands") continue;
|
|
723
|
-
let n = R(
|
|
755
|
+
let n = R(b, "island-shells", `${k(e)}.html`);
|
|
724
756
|
try {
|
|
725
|
-
|
|
757
|
+
J.set(e, await B.readFile(n, "utf8"));
|
|
726
758
|
} catch {
|
|
727
759
|
Y.warn("islands page has no built per-page shell — serving the full app shell", {
|
|
728
760
|
pattern: e,
|
|
@@ -732,68 +764,68 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
732
764
|
}
|
|
733
765
|
Y.info(`registered ${q.size} route(s)`, {
|
|
734
766
|
count: q.size,
|
|
735
|
-
fromManifest: q.size -
|
|
736
|
-
fromModules:
|
|
767
|
+
fromManifest: q.size - yt,
|
|
768
|
+
fromModules: yt
|
|
737
769
|
}), n.mark("routes");
|
|
738
770
|
let X = /* @__PURE__ */ new Set();
|
|
739
|
-
for (let e of W) q.get(e.pattern)?.renderMode === "spa" &&
|
|
771
|
+
for (let e of W) q.get(e.pattern)?.renderMode === "spa" && we(U, e.dirChain).some((e) => e.hasLayout) && X.add(e.pattern);
|
|
740
772
|
X.size > 0 && Y.info(`${X.size} spa route(s) render an SSR layout shell`, { patterns: [...X] });
|
|
741
|
-
let
|
|
742
|
-
for (let [e, t] of q) t.cacheInvalidatesOn.length > 0 &&
|
|
743
|
-
let
|
|
744
|
-
for (let e of W)
|
|
773
|
+
let wt = /* @__PURE__ */ new Map();
|
|
774
|
+
for (let [e, t] of q) t.cacheInvalidatesOn.length > 0 && wt.set(e, t.cacheInvalidatesOn);
|
|
775
|
+
let Tt = /* @__PURE__ */ new Map();
|
|
776
|
+
for (let e of W) Tt.set(e.pattern, e.regex);
|
|
745
777
|
{
|
|
746
778
|
let n = new Set([...q].filter(([, e]) => (e.renderMode === "ssr" || e.renderMode === "isr") && e.hasOgImage).map(([e]) => e));
|
|
747
779
|
if (n.size > 0) {
|
|
748
|
-
let { secret:
|
|
749
|
-
if (!
|
|
750
|
-
let
|
|
751
|
-
|
|
780
|
+
let { secret: r, fromEnv: i } = Te();
|
|
781
|
+
if (!i && e()) throw Y.fatal(`${n.size} ssr route(s) export ogImage, but VOLTRO_OG_SECRET is unset. Behind a load balancer the signing replica and the fetching replica differ, so a per-boot secret would 403 every cross-replica image fetch. Set VOLTRO_OG_SECRET (any long random value, same on every replica).`), Error("[voltro start] ssr ogImage routes need VOLTRO_OG_SECRET in a deploy environment");
|
|
782
|
+
let a = new Map(rt.map((e) => [e.pattern, e.file]));
|
|
783
|
+
jt = le({
|
|
752
784
|
root: t,
|
|
753
|
-
fonts:
|
|
785
|
+
fonts: f.fonts,
|
|
754
786
|
cache: z,
|
|
755
|
-
secret:
|
|
787
|
+
secret: r,
|
|
756
788
|
isOgSsrRoute: (e) => n.has(e),
|
|
757
789
|
getPageModule: async (e) => {
|
|
758
|
-
let t =
|
|
790
|
+
let t = a.get(e);
|
|
759
791
|
return t === void 0 ? null : await K.getPage(e, t);
|
|
760
792
|
}
|
|
761
|
-
}), Y.info(`og route active for ${n.size} ssr route(s)`, { secret:
|
|
793
|
+
}), Y.info(`og route active for ${n.size} ssr route(s)`, { secret: i ? "env" : "per-boot" });
|
|
762
794
|
}
|
|
763
795
|
}
|
|
764
|
-
let
|
|
765
|
-
for (let [e, t] of q)
|
|
766
|
-
let
|
|
796
|
+
let Dt = /* @__PURE__ */ new Map();
|
|
797
|
+
for (let [e, t] of q) Dt.set(e, t.renderMode);
|
|
798
|
+
let Ot = [...q.values()].some((e) => e.renderMode === "isr"), Mt = {
|
|
767
799
|
cache: z,
|
|
768
|
-
tableSink:
|
|
800
|
+
tableSink: gt({
|
|
769
801
|
cache: z,
|
|
770
|
-
tableSubscriptionsByPattern:
|
|
771
|
-
regexByPattern:
|
|
802
|
+
tableSubscriptionsByPattern: wt,
|
|
803
|
+
regexByPattern: Tt
|
|
772
804
|
}),
|
|
773
|
-
regexByPattern:
|
|
774
|
-
renderModeByPattern:
|
|
775
|
-
},
|
|
776
|
-
let t =
|
|
777
|
-
t &&
|
|
778
|
-
},
|
|
805
|
+
regexByPattern: Tt,
|
|
806
|
+
renderModeByPattern: Dt
|
|
807
|
+
}, Nt = (e) => {
|
|
808
|
+
let t = xt(e);
|
|
809
|
+
t && St(Mt, t);
|
|
810
|
+
}, Q = _t({
|
|
779
811
|
cache: z,
|
|
780
|
-
tableSubscriptionsByPattern:
|
|
781
|
-
regexByPattern:
|
|
782
|
-
...
|
|
783
|
-
}),
|
|
784
|
-
if (
|
|
785
|
-
let e =
|
|
812
|
+
tableSubscriptionsByPattern: wt,
|
|
813
|
+
regexByPattern: Tt,
|
|
814
|
+
...Ot ? { onRevalidate: Nt } : {}
|
|
815
|
+
}), Lt = await Q.start(), $ = null, Rt = null;
|
|
816
|
+
if (Ot) {
|
|
817
|
+
let e = lt({}, process.env);
|
|
786
818
|
if (e.crossReplica) try {
|
|
787
|
-
|
|
788
|
-
let t =
|
|
789
|
-
$ = await
|
|
819
|
+
Rt = e.provider;
|
|
820
|
+
let t = Ie(process.env);
|
|
821
|
+
$ = await ct.runPromise(e.provider.subscribe(t, Nt)), Y.info(`revalidation subscriber: broker (${e.provider.name})`, { channel: t });
|
|
790
822
|
} catch (e) {
|
|
791
|
-
Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e),
|
|
823
|
+
Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), Rt = null;
|
|
792
824
|
}
|
|
793
|
-
|
|
825
|
+
Lt && $ === null && Y.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !Lt && $ === null && Y.warn("isr routes exist, but this web process has NO revalidation transport: no database is configured for the LISTEN line and no broker is configured. `revalidatePath` / `revalidateTable` / `revalidateTag` from the api will not reach this process — cached pages stay until their own `revalidate` window expires. Set DB_URL (postgres) or BROADCAST_URL (redis:// or nats://) on BOTH the api and this web deployment.");
|
|
794
826
|
}
|
|
795
827
|
n.mark("cdc");
|
|
796
|
-
let
|
|
828
|
+
let zt = Le(), Bt = rt.map((e) => {
|
|
797
829
|
let t = q.get(e.pattern);
|
|
798
830
|
return {
|
|
799
831
|
pattern: e.pattern,
|
|
@@ -809,20 +841,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
809
841
|
hasMeta: t?.hasMeta ?? !1,
|
|
810
842
|
hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
|
|
811
843
|
};
|
|
812
|
-
}),
|
|
844
|
+
}), Vt = U.map((e) => ({
|
|
813
845
|
dir: e.dir,
|
|
814
846
|
hasLayout: e.hasLayout,
|
|
815
847
|
hasError: e.hasError,
|
|
816
848
|
hasPending: e.hasPending,
|
|
817
849
|
hasNotFound: e.hasNotFound
|
|
818
|
-
})),
|
|
850
|
+
})), Ht = V ? "postgres" : "memory", Ut = {
|
|
819
851
|
kind: "web",
|
|
820
852
|
meta: {
|
|
821
|
-
name:
|
|
822
|
-
voltroVersion:
|
|
823
|
-
port:
|
|
824
|
-
mode:
|
|
825
|
-
apis: Object.entries(
|
|
853
|
+
name: f.name ?? "(unnamed)",
|
|
854
|
+
voltroVersion: Ct,
|
|
855
|
+
port: _,
|
|
856
|
+
mode: tt(),
|
|
857
|
+
apis: Object.entries(f.apis ?? {}).map(([e, t]) => {
|
|
826
858
|
let n = {
|
|
827
859
|
name: e,
|
|
828
860
|
package: t.package
|
|
@@ -830,8 +862,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
830
862
|
return t.url !== void 0 && (n.url = t.url), n;
|
|
831
863
|
})
|
|
832
864
|
},
|
|
833
|
-
routes:
|
|
834
|
-
dirs:
|
|
865
|
+
routes: Bt,
|
|
866
|
+
dirs: Vt,
|
|
835
867
|
cache: () => {
|
|
836
868
|
let e = Date.now(), t = z.snapshot().map(([t, n]) => ({
|
|
837
869
|
key: t,
|
|
@@ -844,16 +876,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
844
876
|
staleWhileRevalidateMs: n.staleWhileRevalidateMs
|
|
845
877
|
}));
|
|
846
878
|
return {
|
|
847
|
-
backend:
|
|
879
|
+
backend: Ht,
|
|
848
880
|
size: z.size(),
|
|
849
881
|
entries: t
|
|
850
882
|
};
|
|
851
883
|
},
|
|
852
|
-
metrics: () =>
|
|
853
|
-
},
|
|
854
|
-
let
|
|
855
|
-
if (
|
|
856
|
-
let e = await
|
|
884
|
+
metrics: () => st()
|
|
885
|
+
}, Wt = async (e, n) => {
|
|
886
|
+
let r = e.split("?")[0] ?? "/";
|
|
887
|
+
if (f.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
|
|
888
|
+
let e = await Ge();
|
|
857
889
|
return {
|
|
858
890
|
status: 200,
|
|
859
891
|
headers: { "content-type": "application/json; charset=utf-8" },
|
|
@@ -866,7 +898,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
866
898
|
body: `registry read error: ${e.message}`
|
|
867
899
|
};
|
|
868
900
|
}
|
|
869
|
-
if (
|
|
901
|
+
if (f.name === "voltroDashboard" && r === "/api/dashboard/config") {
|
|
870
902
|
let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
|
|
871
903
|
if (e && e.trim().length > 0) {
|
|
872
904
|
let n;
|
|
@@ -895,27 +927,27 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
895
927
|
body: JSON.stringify({ apps: t })
|
|
896
928
|
};
|
|
897
929
|
}
|
|
898
|
-
if (
|
|
899
|
-
let t = await
|
|
930
|
+
if (jt !== null && r === "/_voltro/og") {
|
|
931
|
+
let t = await jt.handle(new URL(e, "http://localhost"));
|
|
900
932
|
if (t !== null) return {
|
|
901
933
|
status: t.status,
|
|
902
934
|
headers: { ...t.headers },
|
|
903
935
|
body: Buffer.from(t.body)
|
|
904
936
|
};
|
|
905
937
|
}
|
|
906
|
-
if (
|
|
907
|
-
let t =
|
|
938
|
+
if (r === "/_voltro/inspect/logs") {
|
|
939
|
+
let t = A(e, ge(), n);
|
|
908
940
|
return {
|
|
909
941
|
status: t.status,
|
|
910
942
|
headers: {
|
|
911
943
|
"content-type": t.contentType,
|
|
912
|
-
...
|
|
944
|
+
...Oe(n.origin)
|
|
913
945
|
},
|
|
914
946
|
body: t.body
|
|
915
947
|
};
|
|
916
948
|
}
|
|
917
|
-
if (
|
|
918
|
-
let t =
|
|
949
|
+
if (r !== "/_voltro/inspect/stream") {
|
|
950
|
+
let t = ke(e, Ut, n);
|
|
919
951
|
if (t !== null) return {
|
|
920
952
|
status: t.status,
|
|
921
953
|
headers: {
|
|
@@ -925,57 +957,57 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
925
957
|
body: t.body
|
|
926
958
|
};
|
|
927
959
|
}
|
|
928
|
-
let
|
|
929
|
-
if (!
|
|
960
|
+
let i = At(r, W), a = i ? q.get(i.route.pattern)?.renderMode : void 0, o = a === "ssr" || a === "isr" || (i ? X.has(i.route.pattern) : !1), s = [];
|
|
961
|
+
if (!o && L.length > 0) {
|
|
930
962
|
let t = ae(L, {
|
|
931
963
|
route: void 0,
|
|
932
|
-
pathname:
|
|
964
|
+
pathname: r
|
|
933
965
|
});
|
|
934
966
|
if (t !== void 0) {
|
|
935
|
-
let
|
|
936
|
-
pathname:
|
|
937
|
-
search: e.slice(
|
|
967
|
+
let i = await ie(t, {
|
|
968
|
+
pathname: r,
|
|
969
|
+
search: e.slice(r.length),
|
|
938
970
|
headers: n,
|
|
939
971
|
cookies: ee(n.cookie),
|
|
940
972
|
route: void 0
|
|
941
973
|
});
|
|
942
|
-
|
|
974
|
+
s.push(...i.setCookies);
|
|
943
975
|
}
|
|
944
976
|
}
|
|
945
|
-
let
|
|
977
|
+
let c = (e) => s.length === 0 ? e : {
|
|
946
978
|
...e,
|
|
947
|
-
"set-cookie":
|
|
948
|
-
},
|
|
949
|
-
if (!
|
|
950
|
-
let e = await B.readFile(
|
|
979
|
+
"set-cookie": s.map(d)
|
|
980
|
+
}, u = r === "/" ? R(b, "index.html") : R(b, r.replace(/^\//, ""), "index.html");
|
|
981
|
+
if (!o && await Z(u)) {
|
|
982
|
+
let e = await B.readFile(u);
|
|
951
983
|
return {
|
|
952
984
|
status: 200,
|
|
953
|
-
headers:
|
|
985
|
+
headers: c({
|
|
954
986
|
"content-type": "text/html; charset=utf-8",
|
|
955
|
-
"cache-control":
|
|
987
|
+
"cache-control": Qe(M)
|
|
956
988
|
}),
|
|
957
989
|
body: e
|
|
958
990
|
};
|
|
959
991
|
}
|
|
960
|
-
if (
|
|
992
|
+
if (r.endsWith(".map")) return {
|
|
961
993
|
status: 404,
|
|
962
994
|
headers: { "content-type": "text/plain; charset=utf-8" },
|
|
963
995
|
body: "not found"
|
|
964
996
|
};
|
|
965
|
-
if (/\.[a-z0-9]+$/i.test(
|
|
966
|
-
let e = R(
|
|
997
|
+
if (/\.[a-z0-9]+$/i.test(r)) {
|
|
998
|
+
let e = R(b, r.replace(/^\//, ""));
|
|
967
999
|
if (await Z(e)) {
|
|
968
|
-
let t =
|
|
1000
|
+
let t = $e(r, M), i = at(n["accept-encoding"]), a = i === "br" ? `${e}.br` : i === "gzip" ? `${e}.gz` : void 0;
|
|
969
1001
|
if (a !== void 0 && await Z(a)) {
|
|
970
1002
|
let n = await B.readFile(e);
|
|
971
1003
|
return {
|
|
972
1004
|
status: 200,
|
|
973
|
-
headers:
|
|
974
|
-
"content-type":
|
|
1005
|
+
headers: c({
|
|
1006
|
+
"content-type": Et(e),
|
|
975
1007
|
"cache-control": t,
|
|
976
|
-
"content-encoding":
|
|
1008
|
+
"content-encoding": i === "br" ? "br" : "gzip",
|
|
977
1009
|
vary: "Accept-Encoding",
|
|
978
|
-
etag:
|
|
1010
|
+
etag: mt(n)
|
|
979
1011
|
}),
|
|
980
1012
|
body: await B.readFile(a)
|
|
981
1013
|
};
|
|
@@ -983,36 +1015,36 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
983
1015
|
let o = await B.readFile(e);
|
|
984
1016
|
return {
|
|
985
1017
|
status: 200,
|
|
986
|
-
headers:
|
|
987
|
-
"content-type":
|
|
1018
|
+
headers: c({
|
|
1019
|
+
"content-type": Et(e),
|
|
988
1020
|
"cache-control": t
|
|
989
1021
|
}),
|
|
990
1022
|
body: o
|
|
991
1023
|
};
|
|
992
1024
|
}
|
|
993
1025
|
}
|
|
994
|
-
let
|
|
995
|
-
if (!
|
|
996
|
-
let
|
|
997
|
-
if (
|
|
998
|
-
let a = await
|
|
1026
|
+
let p = At(r, W);
|
|
1027
|
+
if (!p) {
|
|
1028
|
+
let i = ce(U, r);
|
|
1029
|
+
if (i !== void 0) try {
|
|
1030
|
+
let a = await Pt({
|
|
999
1031
|
provider: K,
|
|
1000
1032
|
root: t,
|
|
1001
1033
|
route: {
|
|
1002
1034
|
pattern: "<not-found>",
|
|
1003
|
-
file:
|
|
1004
|
-
dirChain:
|
|
1035
|
+
file: i.dir === "" ? "not-found.tsx" : `${i.dir}/not-found.tsx`,
|
|
1036
|
+
dirChain: i.chain,
|
|
1005
1037
|
regex: /^$/,
|
|
1006
1038
|
paramNames: [],
|
|
1007
1039
|
priority: 2 ** 53 - 1
|
|
1008
1040
|
},
|
|
1009
1041
|
params: {},
|
|
1010
|
-
pathname:
|
|
1042
|
+
pathname: r,
|
|
1011
1043
|
dirs: U,
|
|
1012
1044
|
shellTemplate: D,
|
|
1013
1045
|
requestHeaders: n,
|
|
1014
|
-
apiOrigin:
|
|
1015
|
-
apiName:
|
|
1046
|
+
apiOrigin: N,
|
|
1047
|
+
apiName: P,
|
|
1016
1048
|
middlewares: L,
|
|
1017
1049
|
onCookieWarning: I,
|
|
1018
1050
|
requestUrl: e,
|
|
@@ -1021,159 +1053,159 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1021
1053
|
});
|
|
1022
1054
|
if (a && "html" in a && typeof a.html == "string") return {
|
|
1023
1055
|
status: 404,
|
|
1024
|
-
headers:
|
|
1056
|
+
headers: c({
|
|
1025
1057
|
"content-type": "text/html; charset=utf-8",
|
|
1026
1058
|
"x-voltro-rendered-by": "ssr-not-found"
|
|
1027
1059
|
}),
|
|
1028
1060
|
body: a.html
|
|
1029
1061
|
};
|
|
1030
1062
|
} catch (e) {
|
|
1031
|
-
Y.warn("not-found.tsx failed to render — serving the plain 404", { pathname:
|
|
1063
|
+
Y.warn("not-found.tsx failed to render — serving the plain 404", { pathname: r }, e instanceof Error ? e : Error(String(e)));
|
|
1032
1064
|
}
|
|
1033
1065
|
return {
|
|
1034
1066
|
status: 404,
|
|
1035
|
-
headers:
|
|
1067
|
+
headers: c({
|
|
1036
1068
|
"content-type": "text/plain",
|
|
1037
1069
|
"x-voltro-rendered-by": "plain-not-found"
|
|
1038
1070
|
}),
|
|
1039
1071
|
body: "not found"
|
|
1040
1072
|
};
|
|
1041
1073
|
}
|
|
1042
|
-
let
|
|
1043
|
-
...
|
|
1044
|
-
...
|
|
1045
|
-
}),
|
|
1074
|
+
let m = q.get(p.route.pattern), te = n["x-tenant"] ?? "anonymous", g = (await K.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, _ = He(r, {
|
|
1075
|
+
...m?.tenantAware ? { tenant: te } : {},
|
|
1076
|
+
...g ? { locale: g } : {}
|
|
1077
|
+
}), v = m?.ppr === !0 && m.renderMode === "isr", y = (i, a) => ({
|
|
1046
1078
|
status: 200,
|
|
1047
1079
|
headers: {},
|
|
1048
1080
|
body: "",
|
|
1049
1081
|
stream: (o) => {
|
|
1050
|
-
|
|
1082
|
+
l(p.route.pattern), o.writeHead(200, {
|
|
1051
1083
|
"content-type": "text/html; charset=utf-8",
|
|
1052
1084
|
"x-voltro-rendered-by": "isr",
|
|
1053
1085
|
"x-voltro-ppr": "shell+holes",
|
|
1054
1086
|
...a
|
|
1055
|
-
}), o.write(
|
|
1087
|
+
}), o.write(i), (async () => {
|
|
1056
1088
|
try {
|
|
1057
|
-
let
|
|
1089
|
+
let i = await Pt({
|
|
1058
1090
|
provider: K,
|
|
1059
1091
|
root: t,
|
|
1060
|
-
route:
|
|
1061
|
-
params:
|
|
1062
|
-
pathname:
|
|
1092
|
+
route: p.route,
|
|
1093
|
+
params: p.params,
|
|
1094
|
+
pathname: r,
|
|
1063
1095
|
dirs: U,
|
|
1064
|
-
shellTemplate:
|
|
1096
|
+
shellTemplate: J.get(p.route.pattern) ?? D,
|
|
1065
1097
|
requestHeaders: n,
|
|
1066
|
-
apiOrigin:
|
|
1067
|
-
apiName:
|
|
1098
|
+
apiOrigin: N,
|
|
1099
|
+
apiName: P,
|
|
1068
1100
|
middlewares: L,
|
|
1069
1101
|
onCookieWarning: I,
|
|
1070
1102
|
requestUrl: e,
|
|
1071
1103
|
holesOnly: !0
|
|
1072
1104
|
});
|
|
1073
|
-
|
|
1074
|
-
loader:
|
|
1075
|
-
ctx:
|
|
1105
|
+
i !== null && "holes" in i ? await me({
|
|
1106
|
+
loader: i.holes.loader,
|
|
1107
|
+
ctx: i.holes.ctx,
|
|
1076
1108
|
res: o,
|
|
1077
|
-
helpers:
|
|
1078
|
-
page:
|
|
1109
|
+
helpers: i.holes.helpers,
|
|
1110
|
+
page: i.holes.page,
|
|
1079
1111
|
log: Y
|
|
1080
1112
|
}) : o.writableEnded || o.end();
|
|
1081
1113
|
} catch (e) {
|
|
1082
|
-
Y.warn("ppr hole pass failed", { url:
|
|
1114
|
+
Y.warn("ppr hole pass failed", { url: r }, e), o.writableEnded || o.end();
|
|
1083
1115
|
}
|
|
1084
1116
|
})();
|
|
1085
1117
|
}
|
|
1086
|
-
}),
|
|
1087
|
-
if (
|
|
1118
|
+
}), x = z.get(_), S = Date.now();
|
|
1119
|
+
if (x && Ue(x, S)) return h.emit("cache", {
|
|
1088
1120
|
kind: "HIT",
|
|
1089
|
-
key:
|
|
1090
|
-
ageMs:
|
|
1091
|
-
}),
|
|
1092
|
-
"cache-control":
|
|
1121
|
+
key: _,
|
|
1122
|
+
ageMs: S - x.renderedAt
|
|
1123
|
+
}), v ? y(x.html, {
|
|
1124
|
+
"cache-control": Ze(M, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1093
1125
|
"x-voltro-cache": "HIT",
|
|
1094
|
-
"x-voltro-cache-key":
|
|
1095
|
-
"x-voltro-cache-age-ms": String(
|
|
1126
|
+
"x-voltro-cache-key": _,
|
|
1127
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
1096
1128
|
}) : {
|
|
1097
1129
|
status: 200,
|
|
1098
1130
|
headers: {
|
|
1099
1131
|
"content-type": "text/html; charset=utf-8",
|
|
1100
|
-
"cache-control":
|
|
1132
|
+
"cache-control": Ze(M, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1101
1133
|
"x-voltro-rendered-by": "isr",
|
|
1102
1134
|
"x-voltro-cache": "HIT",
|
|
1103
|
-
"x-voltro-cache-key":
|
|
1104
|
-
"x-voltro-cache-age-ms": String(
|
|
1135
|
+
"x-voltro-cache-key": _,
|
|
1136
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
1105
1137
|
},
|
|
1106
|
-
body:
|
|
1138
|
+
body: x.html
|
|
1107
1139
|
};
|
|
1108
|
-
if (
|
|
1109
|
-
|
|
1140
|
+
if (x && Be(x, S)) {
|
|
1141
|
+
h.emit("cache", {
|
|
1110
1142
|
kind: "STALE",
|
|
1111
|
-
key:
|
|
1112
|
-
ageMs:
|
|
1143
|
+
key: _,
|
|
1144
|
+
ageMs: S - x.renderedAt
|
|
1113
1145
|
});
|
|
1114
|
-
let
|
|
1146
|
+
let i = z.generation(_);
|
|
1115
1147
|
return (async () => {
|
|
1116
1148
|
try {
|
|
1117
|
-
let a = await
|
|
1149
|
+
let a = await Pt({
|
|
1118
1150
|
provider: K,
|
|
1119
1151
|
root: t,
|
|
1120
|
-
route:
|
|
1121
|
-
params:
|
|
1122
|
-
pathname:
|
|
1152
|
+
route: p.route,
|
|
1153
|
+
params: p.params,
|
|
1154
|
+
pathname: r,
|
|
1123
1155
|
dirs: U,
|
|
1124
|
-
shellTemplate:
|
|
1156
|
+
shellTemplate: J.get(p.route.pattern) ?? D,
|
|
1125
1157
|
requestHeaders: n,
|
|
1126
|
-
apiOrigin:
|
|
1127
|
-
apiName:
|
|
1158
|
+
apiOrigin: N,
|
|
1159
|
+
apiName: P,
|
|
1128
1160
|
middlewares: L,
|
|
1129
1161
|
onCookieWarning: I,
|
|
1130
1162
|
requestUrl: e,
|
|
1131
1163
|
buffered: !0
|
|
1132
1164
|
});
|
|
1133
1165
|
if (a && "html" in a && a.renderMode === "isr" && a.revalidateMs !== null) {
|
|
1134
|
-
let e = q.get(
|
|
1135
|
-
z.set(
|
|
1166
|
+
let e = q.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
|
|
1167
|
+
z.set(_, {
|
|
1136
1168
|
html: a.html,
|
|
1137
1169
|
renderedAt: t,
|
|
1138
1170
|
expiresAt: t + a.revalidateMs,
|
|
1139
1171
|
servableUntil: t + a.revalidateMs + e,
|
|
1140
1172
|
revalidateMs: a.revalidateMs,
|
|
1141
1173
|
staleWhileRevalidateMs: e
|
|
1142
|
-
}, { ifGeneration:
|
|
1174
|
+
}, { ifGeneration: i }) || Y.info("SWR refresh discarded — the entry was purged while it rendered", { key: _ });
|
|
1143
1175
|
}
|
|
1144
1176
|
} catch (e) {
|
|
1145
|
-
Y.warn("background SWR refresh failed", { url:
|
|
1177
|
+
Y.warn("background SWR refresh failed", { url: r }, e);
|
|
1146
1178
|
}
|
|
1147
|
-
})(),
|
|
1148
|
-
"cache-control":
|
|
1179
|
+
})(), v ? y(x.html, {
|
|
1180
|
+
"cache-control": Ze(M, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1149
1181
|
"x-voltro-cache": "STALE",
|
|
1150
|
-
"x-voltro-cache-key":
|
|
1151
|
-
"x-voltro-cache-age-ms": String(
|
|
1182
|
+
"x-voltro-cache-key": _,
|
|
1183
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
1152
1184
|
}) : {
|
|
1153
1185
|
status: 200,
|
|
1154
1186
|
headers: {
|
|
1155
1187
|
"content-type": "text/html; charset=utf-8",
|
|
1156
|
-
"cache-control":
|
|
1188
|
+
"cache-control": Ze(M, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1157
1189
|
"x-voltro-rendered-by": "isr",
|
|
1158
1190
|
"x-voltro-cache": "STALE",
|
|
1159
|
-
"x-voltro-cache-key":
|
|
1160
|
-
"x-voltro-cache-age-ms": String(
|
|
1191
|
+
"x-voltro-cache-key": _,
|
|
1192
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
1161
1193
|
},
|
|
1162
|
-
body:
|
|
1194
|
+
body: x.html
|
|
1163
1195
|
};
|
|
1164
1196
|
}
|
|
1165
1197
|
try {
|
|
1166
|
-
let
|
|
1198
|
+
let i = z.generation(_), a = await Pt({
|
|
1167
1199
|
provider: K,
|
|
1168
1200
|
root: t,
|
|
1169
|
-
route:
|
|
1170
|
-
params:
|
|
1171
|
-
pathname:
|
|
1201
|
+
route: p.route,
|
|
1202
|
+
params: p.params,
|
|
1203
|
+
pathname: r,
|
|
1172
1204
|
dirs: U,
|
|
1173
|
-
shellTemplate:
|
|
1205
|
+
shellTemplate: J.get(p.route.pattern) ?? D,
|
|
1174
1206
|
requestHeaders: n,
|
|
1175
|
-
apiOrigin:
|
|
1176
|
-
apiName:
|
|
1207
|
+
apiOrigin: N,
|
|
1208
|
+
apiName: P,
|
|
1177
1209
|
middlewares: L,
|
|
1178
1210
|
onCookieWarning: I,
|
|
1179
1211
|
requestUrl: e
|
|
@@ -1189,7 +1221,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1189
1221
|
let o = a.setCookies ?? [], s = a.responseHeaders ?? {}, c = (e) => ({
|
|
1190
1222
|
...s,
|
|
1191
1223
|
...e,
|
|
1192
|
-
...o.length === 0 ? {} : { "set-cookie": o.map(
|
|
1224
|
+
...o.length === 0 ? {} : { "set-cookie": o.map(d) }
|
|
1193
1225
|
});
|
|
1194
1226
|
if ("stream" in a) return {
|
|
1195
1227
|
status: 200,
|
|
@@ -1213,39 +1245,39 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1213
1245
|
body: "not found"
|
|
1214
1246
|
};
|
|
1215
1247
|
if ("holes" in a) throw Error("renderPageForRequest returned a holes arm without holesOnly");
|
|
1216
|
-
let
|
|
1248
|
+
let l = c({
|
|
1217
1249
|
"content-type": "text/html; charset=utf-8",
|
|
1218
1250
|
"x-voltro-rendered-by": a.renderMode
|
|
1219
1251
|
});
|
|
1220
1252
|
if (a.renderMode === "isr" && a.revalidateMs !== null) {
|
|
1221
|
-
let e = Date.now(), t = q.get(
|
|
1222
|
-
z.set(
|
|
1253
|
+
let e = Date.now(), t = q.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0;
|
|
1254
|
+
z.set(_, {
|
|
1223
1255
|
html: a.html,
|
|
1224
1256
|
renderedAt: e,
|
|
1225
1257
|
expiresAt: e + a.revalidateMs,
|
|
1226
1258
|
servableUntil: e + a.revalidateMs + t,
|
|
1227
1259
|
revalidateMs: a.revalidateMs,
|
|
1228
1260
|
staleWhileRevalidateMs: t
|
|
1229
|
-
}, { ifGeneration:
|
|
1261
|
+
}, { ifGeneration: i }) || Y.info("miss fill discarded — the entry was purged while it rendered", { key: _ }), l["x-voltro-cache"] = "MISS", l["x-voltro-cache-key"] = _, l["x-voltro-cache-revalidate-ms"] = String(a.revalidateMs), t > 0 && (l["x-voltro-cache-swr-ms"] = String(t)), h.emit("cache", {
|
|
1230
1262
|
kind: "MISS",
|
|
1231
|
-
key:
|
|
1263
|
+
key: _,
|
|
1232
1264
|
revalidateMs: a.revalidateMs,
|
|
1233
1265
|
swrMs: t
|
|
1234
1266
|
});
|
|
1235
|
-
} else a.renderMode === "isr" && (
|
|
1267
|
+
} else a.renderMode === "isr" && (l["x-voltro-cache"] = "BYPASS", h.emit("cache", {
|
|
1236
1268
|
kind: "BYPASS",
|
|
1237
|
-
key:
|
|
1269
|
+
key: _
|
|
1238
1270
|
}));
|
|
1239
|
-
return
|
|
1240
|
-
"x-voltro-cache":
|
|
1241
|
-
"x-voltro-cache-key":
|
|
1271
|
+
return v && a.renderMode === "isr" ? y(a.html, {
|
|
1272
|
+
"x-voltro-cache": l["x-voltro-cache"] ?? "MISS",
|
|
1273
|
+
"x-voltro-cache-key": _
|
|
1242
1274
|
}) : {
|
|
1243
1275
|
status: 200,
|
|
1244
|
-
headers:
|
|
1276
|
+
headers: l,
|
|
1245
1277
|
body: a.html
|
|
1246
1278
|
};
|
|
1247
1279
|
} catch (e) {
|
|
1248
|
-
return Y.error("render error", { url:
|
|
1280
|
+
return Y.error("render error", { url: r }, e), ne(e) ? {
|
|
1249
1281
|
status: 500,
|
|
1250
1282
|
headers: {
|
|
1251
1283
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -1265,26 +1297,26 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1265
1297
|
body: "server error"
|
|
1266
1298
|
};
|
|
1267
1299
|
}
|
|
1268
|
-
},
|
|
1269
|
-
apiName:
|
|
1270
|
-
apiOrigin:
|
|
1300
|
+
}, Gt = !1, Kt = i(f.health, () => Gt), qt = p({
|
|
1301
|
+
apiName: P,
|
|
1302
|
+
apiOrigin: N,
|
|
1271
1303
|
loadDescriptors: async () => {
|
|
1272
|
-
if (
|
|
1273
|
-
let e = (await K.getHelpers()).apiDescriptors?.[
|
|
1304
|
+
if (P === void 0) return;
|
|
1305
|
+
let e = (await K.getHelpers()).apiDescriptors?.[P];
|
|
1274
1306
|
return e === void 0 ? void 0 : await e();
|
|
1275
1307
|
},
|
|
1276
|
-
rpcQuery: (e, t) =>
|
|
1277
|
-
apiName:
|
|
1308
|
+
rpcQuery: (e, t) => xe(N, e, {
|
|
1309
|
+
apiName: P,
|
|
1278
1310
|
headers: t
|
|
1279
1311
|
}),
|
|
1280
1312
|
resolveLocale: async (e, t) => {
|
|
1281
|
-
let n = await K.getHelpers(), r =
|
|
1313
|
+
let n = await K.getHelpers(), r = u(t, n.i18n?.locales);
|
|
1282
1314
|
return r === void 0 ? n.i18n?.resolve(e.cookie, e["accept-language"])?.locale ?? "en" : r;
|
|
1283
1315
|
},
|
|
1284
1316
|
renderErrorPage: async ({ path: e, headers: n, flash: r }) => {
|
|
1285
|
-
let { pathname: i } =
|
|
1317
|
+
let { pathname: i } = be(e), a = At(i, W);
|
|
1286
1318
|
if (!a) return;
|
|
1287
|
-
let o = await
|
|
1319
|
+
let o = await Pt({
|
|
1288
1320
|
provider: K,
|
|
1289
1321
|
root: t,
|
|
1290
1322
|
route: a.route,
|
|
@@ -1293,8 +1325,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1293
1325
|
dirs: U,
|
|
1294
1326
|
shellTemplate: D,
|
|
1295
1327
|
requestHeaders: n,
|
|
1296
|
-
apiOrigin:
|
|
1297
|
-
apiName:
|
|
1328
|
+
apiOrigin: N,
|
|
1329
|
+
apiName: P,
|
|
1298
1330
|
middlewares: L,
|
|
1299
1331
|
onCookieWarning: I,
|
|
1300
1332
|
requestUrl: e,
|
|
@@ -1303,44 +1335,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1303
1335
|
});
|
|
1304
1336
|
return o !== null && "html" in o ? o.html : void 0;
|
|
1305
1337
|
}
|
|
1306
|
-
}),
|
|
1338
|
+
}), Jt = ot(f), Yt = ut(async (e, t) => {
|
|
1307
1339
|
let n = e.url ?? "/", i = Date.now(), a = {};
|
|
1308
1340
|
for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (a[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
|
|
1309
|
-
let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase();
|
|
1310
|
-
if (
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
"cache-control": "no-store"
|
|
1314
|
-
}), t.end("ok");
|
|
1315
|
-
return;
|
|
1316
|
-
}
|
|
1317
|
-
if (o === "/internal/readiness") {
|
|
1318
|
-
let e = Bt ? 200 : 503;
|
|
1319
|
-
t.writeHead(e, {
|
|
1341
|
+
let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase(), c = he(Kt, o);
|
|
1342
|
+
if (c !== void 0) {
|
|
1343
|
+
let e = await y(Kt, c);
|
|
1344
|
+
t.writeHead(e.status, {
|
|
1320
1345
|
"content-type": "text/plain",
|
|
1321
1346
|
"cache-control": "no-store"
|
|
1322
|
-
}), t.end(
|
|
1347
|
+
}), t.end(e.body);
|
|
1323
1348
|
return;
|
|
1324
1349
|
}
|
|
1325
|
-
if (!(o.startsWith(
|
|
1350
|
+
if (!(o.startsWith(x) && await qt(e, t))) {
|
|
1326
1351
|
if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
|
|
1327
|
-
let e =
|
|
1352
|
+
let e = Oe(a.origin);
|
|
1328
1353
|
t.writeHead(204, e), t.end();
|
|
1329
1354
|
return;
|
|
1330
1355
|
}
|
|
1331
|
-
if (
|
|
1356
|
+
if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy") {
|
|
1332
1357
|
let r = new URL(n, "http://x").searchParams.get("target");
|
|
1333
1358
|
if (!r) {
|
|
1334
1359
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
1335
1360
|
return;
|
|
1336
1361
|
}
|
|
1337
|
-
if (!
|
|
1362
|
+
if (!F(r)) {
|
|
1338
1363
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
1339
1364
|
return;
|
|
1340
1365
|
}
|
|
1341
1366
|
try {
|
|
1342
1367
|
let n = { accept: a.accept ?? "application/json" }, i = a.authorization;
|
|
1343
|
-
i ? n.authorization = Array.isArray(i) ? i[0] : i :
|
|
1368
|
+
i ? n.authorization = Array.isArray(i) ? i[0] : i : De(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
|
|
1344
1369
|
let o;
|
|
1345
1370
|
if (s && s !== "GET" && s !== "HEAD") {
|
|
1346
1371
|
let t = [];
|
|
@@ -1364,20 +1389,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1364
1389
|
}
|
|
1365
1390
|
return;
|
|
1366
1391
|
}
|
|
1367
|
-
if (
|
|
1392
|
+
if (f.name === "voltroDashboard" && o === "/api/dashboard/proxy/stream") {
|
|
1368
1393
|
let r = new URL(n, "http://x").searchParams.get("target");
|
|
1369
1394
|
if (!r) {
|
|
1370
1395
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
1371
1396
|
return;
|
|
1372
1397
|
}
|
|
1373
|
-
if (!
|
|
1398
|
+
if (!F(r)) {
|
|
1374
1399
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
1375
1400
|
return;
|
|
1376
1401
|
}
|
|
1377
1402
|
let i = new AbortController();
|
|
1378
1403
|
e.on("close", () => i.abort()), t.on("close", () => i.abort());
|
|
1379
1404
|
try {
|
|
1380
|
-
let e =
|
|
1405
|
+
let e = Ee(a, r), n = await fetch(r, {
|
|
1381
1406
|
redirect: "manual",
|
|
1382
1407
|
method: "GET",
|
|
1383
1408
|
headers: {
|
|
@@ -1412,22 +1437,22 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1412
1437
|
return;
|
|
1413
1438
|
}
|
|
1414
1439
|
if (o === "/_voltro/inspect/stream") {
|
|
1415
|
-
let n =
|
|
1416
|
-
if (
|
|
1440
|
+
let n = Oe(a.origin);
|
|
1441
|
+
if (Ae()) {
|
|
1417
1442
|
t.writeHead(503, {
|
|
1418
1443
|
"content-type": "application/json",
|
|
1419
1444
|
...n
|
|
1420
1445
|
}), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
|
|
1421
1446
|
return;
|
|
1422
1447
|
}
|
|
1423
|
-
let
|
|
1424
|
-
if (!
|
|
1448
|
+
let i = je(a, "GET");
|
|
1449
|
+
if (!i.ok) {
|
|
1425
1450
|
t.writeHead(401, {
|
|
1426
1451
|
"content-type": "application/json",
|
|
1427
1452
|
...n
|
|
1428
1453
|
}), t.end(JSON.stringify({
|
|
1429
1454
|
error: "unauthorized",
|
|
1430
|
-
reason:
|
|
1455
|
+
reason: i.reason
|
|
1431
1456
|
}));
|
|
1432
1457
|
return;
|
|
1433
1458
|
}
|
|
@@ -1438,37 +1463,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1438
1463
|
"x-accel-buffering": "no",
|
|
1439
1464
|
...n
|
|
1440
1465
|
}), t.flushHeaders(), t.write("retry: 5000\n\n");
|
|
1441
|
-
for (let e of
|
|
1442
|
-
let
|
|
1443
|
-
t.write(
|
|
1444
|
-
}),
|
|
1445
|
-
t.write(
|
|
1446
|
-
}, 15e3),
|
|
1447
|
-
clearInterval(
|
|
1466
|
+
for (let e of h.buffered()) t.write(r(e));
|
|
1467
|
+
let o = h.subscribe((e) => {
|
|
1468
|
+
t.write(r(e));
|
|
1469
|
+
}), s = setInterval(() => {
|
|
1470
|
+
t.write(Ce());
|
|
1471
|
+
}, 15e3), c = () => {
|
|
1472
|
+
clearInterval(s), o();
|
|
1448
1473
|
};
|
|
1449
|
-
e.on("close",
|
|
1474
|
+
e.on("close", c), t.on("close", c);
|
|
1450
1475
|
return;
|
|
1451
1476
|
}
|
|
1452
1477
|
try {
|
|
1453
|
-
let e = await
|
|
1454
|
-
if (e.stream ? e.stream(t) :
|
|
1478
|
+
let e = await Wt(n, a);
|
|
1479
|
+
if (e.stream ? e.stream(t) : ht({
|
|
1455
1480
|
response: t,
|
|
1456
1481
|
status: e.status,
|
|
1457
1482
|
headers: e.headers,
|
|
1458
1483
|
body: e.body,
|
|
1459
1484
|
requestHeaders: a,
|
|
1460
|
-
compression:
|
|
1485
|
+
compression: ve.compression
|
|
1461
1486
|
}) || (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
|
|
1462
1487
|
let t = Date.now() - i;
|
|
1463
|
-
|
|
1488
|
+
h.emit("request", {
|
|
1464
1489
|
url: o,
|
|
1465
1490
|
status: e.status,
|
|
1466
1491
|
durationMs: t,
|
|
1467
1492
|
renderedBy: e.headers["x-voltro-rendered-by"],
|
|
1468
1493
|
cache: e.headers["x-voltro-cache"]
|
|
1469
1494
|
});
|
|
1470
|
-
let n =
|
|
1471
|
-
|
|
1495
|
+
let n = At(o, W)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
|
|
1496
|
+
zt.record({
|
|
1472
1497
|
kind: "request",
|
|
1473
1498
|
tag: n,
|
|
1474
1499
|
durationMs: t,
|
|
@@ -1480,77 +1505,77 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1480
1505
|
}
|
|
1481
1506
|
}
|
|
1482
1507
|
});
|
|
1483
|
-
await new Promise((e) =>
|
|
1484
|
-
port:
|
|
1485
|
-
distDir:
|
|
1508
|
+
await new Promise((e) => Yt.listen(_, "::", e)), Gt = !0, n.mark("ready"), it(Yt, Jt), Y.info(`listening on http://localhost:${_}`, {
|
|
1509
|
+
port: _,
|
|
1510
|
+
distDir: b
|
|
1486
1511
|
}), Y.debug("dynamic + ssr/isr routes resolve via SSR loader");
|
|
1487
1512
|
try {
|
|
1488
|
-
await
|
|
1489
|
-
id:
|
|
1490
|
-
name:
|
|
1513
|
+
await We({
|
|
1514
|
+
id: T,
|
|
1515
|
+
name: w,
|
|
1491
1516
|
kind: "web",
|
|
1492
|
-
url: `http://localhost:${
|
|
1517
|
+
url: `http://localhost:${_}`,
|
|
1493
1518
|
pid: process.pid,
|
|
1494
1519
|
status: "live",
|
|
1495
|
-
logFile:
|
|
1520
|
+
logFile: E.path
|
|
1496
1521
|
});
|
|
1497
|
-
let e =
|
|
1522
|
+
let e = Se(t);
|
|
1498
1523
|
if (e) {
|
|
1499
|
-
let t = await
|
|
1524
|
+
let t = await ye({ dashboardAppPath: e });
|
|
1500
1525
|
t.status === "launched" ? Y.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && Y.debug(`dashboard already running on :${t.port}`, { port: t.port });
|
|
1501
1526
|
}
|
|
1502
1527
|
setInterval(() => {
|
|
1503
|
-
|
|
1504
|
-
id:
|
|
1505
|
-
name:
|
|
1528
|
+
We({
|
|
1529
|
+
id: T,
|
|
1530
|
+
name: w,
|
|
1506
1531
|
kind: "web",
|
|
1507
|
-
url: `http://localhost:${
|
|
1532
|
+
url: `http://localhost:${_}`,
|
|
1508
1533
|
pid: process.pid,
|
|
1509
1534
|
status: "live",
|
|
1510
|
-
logFile:
|
|
1535
|
+
logFile: E.path
|
|
1511
1536
|
}).catch(() => {});
|
|
1512
1537
|
}, 1e4).unref();
|
|
1513
1538
|
} catch (e) {
|
|
1514
1539
|
Y.warn("runtime-registry write failed", {}, e);
|
|
1515
1540
|
}
|
|
1516
|
-
|
|
1517
|
-
app:
|
|
1541
|
+
et({
|
|
1542
|
+
app: f.name ?? "unnamed",
|
|
1518
1543
|
kind: "web",
|
|
1519
|
-
url: `http://localhost:${
|
|
1544
|
+
url: `http://localhost:${_}`,
|
|
1520
1545
|
bootMs: n.total()
|
|
1521
1546
|
});
|
|
1522
|
-
let
|
|
1547
|
+
let Xt = n.phaseBreakdown();
|
|
1523
1548
|
Y.info(`start: ready in ${n.total()}ms`, {
|
|
1524
1549
|
bootMs: n.total(),
|
|
1525
|
-
...
|
|
1550
|
+
...Xt ? { phases: Xt } : {}
|
|
1526
1551
|
});
|
|
1527
|
-
let
|
|
1528
|
-
if (!
|
|
1529
|
-
if (
|
|
1552
|
+
let Zt = !1, Qt = (e) => async () => {
|
|
1553
|
+
if (!Zt) {
|
|
1554
|
+
if (Zt = !0, Y.info(`received ${e}, shutting down`, { signal: e }), Yt.close(), await Q.stop(), $) try {
|
|
1530
1555
|
$();
|
|
1531
1556
|
} catch {}
|
|
1532
|
-
if (
|
|
1533
|
-
await
|
|
1557
|
+
if (Rt) try {
|
|
1558
|
+
await ct.runPromise(Rt.close());
|
|
1534
1559
|
} catch {}
|
|
1535
1560
|
if (V) try {
|
|
1536
1561
|
await V.end();
|
|
1537
1562
|
} catch {}
|
|
1538
|
-
await K.close(), await
|
|
1563
|
+
await K.close(), await Ke(T), await E.dispose(), process.exit(0);
|
|
1539
1564
|
}
|
|
1540
1565
|
};
|
|
1541
|
-
process.on("SIGINT",
|
|
1542
|
-
let
|
|
1543
|
-
if (
|
|
1566
|
+
process.on("SIGINT", Qt("SIGINT")), process.on("SIGTERM", Qt("SIGTERM"));
|
|
1567
|
+
let $t = process.ppid;
|
|
1568
|
+
if ($t > 1) {
|
|
1544
1569
|
let e = setInterval(() => {
|
|
1545
|
-
(process.ppid !==
|
|
1570
|
+
(process.ppid !== $t || process.ppid === 1) && (clearInterval(e), Qt("SIGTERM")());
|
|
1546
1571
|
}, 2e3);
|
|
1547
1572
|
e.unref();
|
|
1548
1573
|
}
|
|
1549
1574
|
return new Promise(() => {});
|
|
1550
|
-
},
|
|
1551
|
-
|
|
1552
|
-
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await
|
|
1575
|
+
}, $ = async (e) => {
|
|
1576
|
+
rt("start"), t("start");
|
|
1577
|
+
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await Lt(z(n));
|
|
1553
1578
|
return r.ran ? r.exitCode : (Y.error("no web app found at this path"), 1);
|
|
1554
1579
|
};
|
|
1555
1580
|
//#endregion
|
|
1556
|
-
export {
|
|
1581
|
+
export { Lt as n, $ as t };
|