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