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