@voltro/cli 0.59.0 → 0.60.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 +58 -0
- package/dist/bin.js +1 -1
- package/dist/{build-uRMZrT8z.js → build-BxAsLzyU.js} +14 -10
- package/dist/{codemodRunner-kNnh1I7_.js → codemodRunner-ClUqkhvR.js} +86 -37
- package/dist/{commands-cu34ENUT.js → commands-Ro4hYBHD.js} +7 -7
- package/dist/{dashboardCommand-gG1y4PFG.js → dashboardCommand-t8Qsebjr.js} +1 -1
- package/dist/{evolveCommand-8CuFBlbQ.js → evolveCommand-CThb0EZZ.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/{infoCommand-D02A4WI2.js → infoCommand-a0WkKcUY.js} +1 -1
- package/dist/{start-C75w6ftA.js → start-BhoDQ25C.js} +1 -1
- package/dist/{start-DNtIlBcn.js → start-CcdPRG8L.js} +418 -367
- package/dist/startEntry.js +1 -1
- package/dist/{updateCommand-Bw3mCUDT.js → updateCommand-D9avpQFT.js} +1 -1
- package/dist/updateCommand-QMOirvXC.js +2 -0
- package/package.json +25 -19
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/plugins/sentry.md +93 -6
- package/templates/agent-docs/whats-new.md +29 -26
- package/templates/apps/api-ai/package.json +6 -6
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -9
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-row-history/package.json +8 -8
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +7 -7
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +7 -7
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-auth/package.json +7 -7
- package/templates/apps/frontend-blank/package.json +6 -6
- package/templates/apps/frontend-cms/package.json +8 -8
- package/templates/apps/frontend-collab/package.json +9 -9
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +6 -6
- package/templates/apps/frontend-docs/package.json +8 -8
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +7 -7
- package/templates/apps/frontend-saas/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +6 -6
- package/templates/apps/frontend-ssr/package.json +6 -6
- package/templates/apps/frontend-ssr-api/package.json +7 -7
- package/templates/apps/frontend-static-blog/package.json +8 -8
- package/templates/apps/frontend-status/package.json +7 -7
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/updateCommand-inInBIAh.js +0 -2
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { i as e, t } from "./nodeEnvironment-cGFAj1J8.js";
|
|
2
|
-
import { $ as n, $t as r, A as i, B as a, D as o, E as s, Et as c, F as l, Ft as u, G as d, H as ee, I as f, It as p, J as m, K as te, L as h, Lt as g, M as _, N as v, O as y, P as b, Pt as x, Q as
|
|
3
|
-
import { A as
|
|
4
|
-
import { r as
|
|
5
|
-
import { o as
|
|
6
|
-
import { n as
|
|
7
|
-
import { a as
|
|
8
|
-
import { i as
|
|
9
|
-
import { n as
|
|
10
|
-
import { t as
|
|
11
|
-
import { a as
|
|
12
|
-
import { extname as
|
|
13
|
-
import { promises as
|
|
14
|
-
import { pathToFileURL as
|
|
15
|
-
import { createLogger as
|
|
16
|
-
import { appMode as
|
|
17
|
-
import { applyKeepAlive as
|
|
18
|
-
import { Effect as
|
|
19
|
-
import {
|
|
2
|
+
import { $ as n, $t as r, A as i, B as a, D as o, E as s, Et as c, F as l, Ft as u, G as d, H as ee, I as f, It as p, J as m, K as te, L as h, Lt as g, M as _, N as v, O as y, P as b, Pt as x, Q as S, Qt as C, R as w, Rt as T, T as ne, U as re, W as ie, X as E, Y as D, Yt as ae, Z as oe, a as se, bt as ce, c as O, en as le, et as ue, ft as de, h as k, it as fe, j as pe, jt as A, k as me, lt as j, m as M, mt as he, n as ge, nt as _e, ot as ve, q as N, rt as ye, s as be, st as xe, tn as Se, tt as P, u as Ce, xt as we, z as F } from "./webDev-CBN9KkyQ.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-PcC5J-Dl.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 { createRequire as G } from "node:module";
|
|
20
|
+
import { createHash as ct } from "node:crypto";
|
|
20
21
|
import { resolveBroadcastProvider as lt } from "@voltro/plugin-broadcast";
|
|
21
22
|
import { createServer as ut } from "node:http";
|
|
22
23
|
//#region src/inertPublicEnv.ts
|
|
@@ -41,7 +42,7 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
41
42
|
return `${e.length} VOLTRO_PUBLIC_* variable${e.length === 1 ? "" : "s"} set in this process's environment cannot reach the browser:\n${t.join("\n")}\n Public values are BAKED into the bundle by \`voltro build\` — that is what makes them
|
|
42
43
|
readable in a browser — so they must exist when the bundle is BUILT, not when it runs.
|
|
43
44
|
→ pass them to the build (a Docker build-arg / CI build step), not as deployment env.`;
|
|
44
|
-
}, mt = (e) => `W/"${
|
|
45
|
+
}, mt = (e) => `W/"${ct("md5").update(e).digest("hex")}"`, ht = (e) => {
|
|
45
46
|
let { response: t, status: n, headers: r, body: i, requestHeaders: a } = e, o = r["cache-control"], s = (typeof o == "string" ? o : "").toLowerCase();
|
|
46
47
|
if (i === void 0 || n !== 200 || s.includes("no-store")) return !1;
|
|
47
48
|
let c = r["content-type"], l = typeof c == "string" ? c : void 0, u = r.etag, d = typeof u == "string" ? u : mt(i), ee = a["if-none-match"];
|
|
@@ -53,7 +54,7 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
53
54
|
...r,
|
|
54
55
|
etag: d
|
|
55
56
|
}), t.end(i), !0;
|
|
56
|
-
let f =
|
|
57
|
+
let f = W({
|
|
57
58
|
body: typeof i == "string" ? new TextEncoder().encode(i) : new Uint8Array(i),
|
|
58
59
|
contentType: l,
|
|
59
60
|
acceptEncoding: a["accept-encoding"],
|
|
@@ -64,7 +65,7 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
64
65
|
etag: d
|
|
65
66
|
};
|
|
66
67
|
return f.compressed && delete p["content-length"], t.writeHead(n, p), t.end(Buffer.from(f.bytes)), !0;
|
|
67
|
-
},
|
|
68
|
+
}, K = U({ scope: "voltro:start:cdc" }), gt = (e) => (t) => {
|
|
68
69
|
let n = 0;
|
|
69
70
|
for (let [r, i] of e.tableSubscriptionsByPattern) {
|
|
70
71
|
if (!i.includes(t)) continue;
|
|
@@ -75,15 +76,15 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
75
76
|
}));
|
|
76
77
|
}
|
|
77
78
|
return n;
|
|
78
|
-
},
|
|
79
|
+
}, _t = () => Ne() ? Me() : null, vt = (e) => {
|
|
79
80
|
let t = e.channel ?? "framework_changes", n = e.revalidateChannel ?? "voltro_revalidate", r = gt(e), i = null, a = null;
|
|
80
81
|
return {
|
|
81
82
|
start: async () => {
|
|
82
83
|
let o = e.tableSubscriptionsByPattern.size > 0, s = e.onRevalidate !== void 0;
|
|
83
|
-
if (!o && !s) return
|
|
84
|
-
let c =
|
|
85
|
-
if (!c && !o) return
|
|
86
|
-
if (!c) return
|
|
84
|
+
if (!o && !s) return K.debug("skipped — no pages declare cacheInvalidatesOn and no revalidation handler is wired"), !1;
|
|
85
|
+
let c = _t();
|
|
86
|
+
if (!c && !o) return K.debug("no database configured — the revalidation LISTEN line is unavailable"), !1;
|
|
87
|
+
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;
|
|
87
88
|
i = new (await (import("pg"))).default.Client(c), await i.connect(), a = (i) => {
|
|
88
89
|
if (i.channel === n && i.payload && e.onRevalidate) {
|
|
89
90
|
e.onRevalidate(i.payload);
|
|
@@ -94,18 +95,18 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
94
95
|
try {
|
|
95
96
|
a = JSON.parse(i.payload);
|
|
96
97
|
} catch (e) {
|
|
97
|
-
|
|
98
|
+
K.warn("bad CDC payload", {}, e);
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
let o = r(a.table);
|
|
101
|
-
o > 0 &&
|
|
102
|
+
o > 0 && K.info(`${a.op} on '${a.table}' → dropped ${o} cache entries`, {
|
|
102
103
|
op: a.op,
|
|
103
104
|
table: a.table,
|
|
104
105
|
dropped: o
|
|
105
106
|
});
|
|
106
107
|
}, i.on("notification", a), o && await i.query(`LISTEN ${t}`), s && await i.query(`LISTEN ${n}`);
|
|
107
108
|
let l = [...o ? [t] : [], ...s ? [n] : []];
|
|
108
|
-
return
|
|
109
|
+
return K.info(`LISTEN ${l.join(", ")}`, {
|
|
109
110
|
channels: l,
|
|
110
111
|
..."connectionString" in c ? { target: c.connectionString.replace(/\/\/[^@/]*@/, "//") } : {
|
|
111
112
|
host: c.host,
|
|
@@ -123,7 +124,7 @@ var dt = "VOLTRO_PUBLIC_", ft = (e, t) => {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
};
|
|
126
|
-
},
|
|
127
|
+
}, q = U({ scope: "voltro:start:isr-cache" }), yt = "voltro_isr_cache", bt = (e) => `
|
|
127
128
|
CREATE TABLE IF NOT EXISTS ${e} (
|
|
128
129
|
cache_key TEXT PRIMARY KEY,
|
|
129
130
|
html TEXT NOT NULL,
|
|
@@ -134,9 +135,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
|
|
|
134
135
|
stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
|
|
135
136
|
);
|
|
136
137
|
CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
137
|
-
`,
|
|
138
|
-
let t = e.tableName ??
|
|
139
|
-
i || (i = !0, await n.query(
|
|
138
|
+
`, xt = (e) => {
|
|
139
|
+
let t = e.tableName ?? yt, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
|
|
140
|
+
i || (i = !0, await n.query(bt(t)));
|
|
140
141
|
})().then(async () => {
|
|
141
142
|
let e = await n.query(`SELECT * FROM ${t}`);
|
|
142
143
|
for (let t of e.rows) r.set(t.cache_key, {
|
|
@@ -148,10 +149,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
148
149
|
staleWhileRevalidateMs: Number(t.stale_while_revalidate_ms)
|
|
149
150
|
});
|
|
150
151
|
}).catch((e) => {
|
|
151
|
-
|
|
152
|
+
q.warn("postgres bootstrap failed", {}, e);
|
|
152
153
|
}), o = (e, t) => {
|
|
153
154
|
a.then(() => n.query(e, t)).catch((e) => {
|
|
154
|
-
|
|
155
|
+
q.warn("postgres write failed", {}, e);
|
|
155
156
|
});
|
|
156
157
|
}, s = /* @__PURE__ */ new Map(), c = (e) => {
|
|
157
158
|
s.set(e, (s.get(e) ?? 0) + 1);
|
|
@@ -202,7 +203,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
202
203
|
return Array.from(r.entries());
|
|
203
204
|
}
|
|
204
205
|
};
|
|
205
|
-
}, J =
|
|
206
|
+
}, J = U({ scope: "voltro:start:revalidate" }), St = (e) => {
|
|
206
207
|
try {
|
|
207
208
|
let t = JSON.parse(e);
|
|
208
209
|
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") ? {
|
|
@@ -213,7 +214,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
213
214
|
} catch {
|
|
214
215
|
return J.warn("bad revalidation payload (not JSON)", { payload: e }), null;
|
|
215
216
|
}
|
|
216
|
-
},
|
|
217
|
+
}, Ct = (e, t) => {
|
|
217
218
|
if (t.kind === "table" || t.kind === "tag") {
|
|
218
219
|
let n = e.tableSink(t.value);
|
|
219
220
|
return J.info(`revalidate ${t.kind} '${t.value}' → dropped ${n} cache entries`, {
|
|
@@ -253,7 +254,47 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
253
254
|
dropped: s,
|
|
254
255
|
...t.tenant === void 0 ? {} : { tenant: t.tenant }
|
|
255
256
|
}), s;
|
|
256
|
-
},
|
|
257
|
+
}, wt = async (e) => {
|
|
258
|
+
let t = G(z(e, "package.json")), n;
|
|
259
|
+
try {
|
|
260
|
+
n = t.resolve("@voltro/plugin-sentry/server");
|
|
261
|
+
} catch {
|
|
262
|
+
return { reason: "SENTRY_DSN is set but `@voltro/plugin-sentry` is not installed in this app — the web server cannot report SSR errors. → `pnpm add @voltro/plugin-sentry` in the web app." };
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
return await import(H(n).href);
|
|
266
|
+
} catch (e) {
|
|
267
|
+
return { reason: `@voltro/plugin-sentry/server resolved but could not be loaded: ${e instanceof Error ? e.message : String(e)}` };
|
|
268
|
+
}
|
|
269
|
+
}, Tt = async (e, t, n, r = {}) => {
|
|
270
|
+
let i = t.SENTRY_DSN;
|
|
271
|
+
if (i === void 0 || i === "") return;
|
|
272
|
+
let a = await (r.load ?? wt)(e);
|
|
273
|
+
if ("reason" in a) {
|
|
274
|
+
n.warn(a.reason);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
let o = {
|
|
278
|
+
dsn: i,
|
|
279
|
+
environment: t.SENTRY_ENVIRONMENT,
|
|
280
|
+
release: t.SENTRY_RELEASE,
|
|
281
|
+
traces: !1
|
|
282
|
+
}, s = await a.initSentryServer(o, n);
|
|
283
|
+
if (s !== void 0) return n.info("sentry active", {
|
|
284
|
+
...a.sentryActiveFields(s, o),
|
|
285
|
+
process: "web"
|
|
286
|
+
}), (e, t) => {
|
|
287
|
+
try {
|
|
288
|
+
s.sdk.captureException(e, {
|
|
289
|
+
tags: {
|
|
290
|
+
"voltro.process": "web",
|
|
291
|
+
"voltro.stage": t.stage
|
|
292
|
+
},
|
|
293
|
+
...t.pathname === void 0 ? {} : { extra: { pathname: t.pathname } }
|
|
294
|
+
});
|
|
295
|
+
} catch {}
|
|
296
|
+
};
|
|
297
|
+
}, Y = U({ scope: "voltro:start" }), Et = tt() ?? "unknown", Dt = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", Ot = (e) => e instanceof Error && e._voltroControl === "not-found", kt = {
|
|
257
298
|
".html": "text/html; charset=utf-8",
|
|
258
299
|
".js": "application/javascript",
|
|
259
300
|
".mjs": "application/javascript",
|
|
@@ -271,13 +312,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
271
312
|
".woff": "font/woff",
|
|
272
313
|
".woff2": "font/woff2",
|
|
273
314
|
".txt": "text/plain; charset=utf-8"
|
|
274
|
-
},
|
|
315
|
+
}, At = (e) => kt[R(e).toLowerCase()] ?? "application/octet-stream", jt = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), X = async (e) => {
|
|
275
316
|
try {
|
|
276
|
-
return await
|
|
317
|
+
return await V.stat(e), !0;
|
|
277
318
|
} catch {
|
|
278
319
|
return !1;
|
|
279
320
|
}
|
|
280
|
-
},
|
|
321
|
+
}, Mt = (e) => {
|
|
281
322
|
let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
|
|
282
323
|
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, "\\$&"));
|
|
283
324
|
let a = i.join("/");
|
|
@@ -286,8 +327,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
286
327
|
paramNames: t,
|
|
287
328
|
priority: n
|
|
288
329
|
};
|
|
289
|
-
},
|
|
290
|
-
let { regex: t, paramNames: n, priority: r } =
|
|
330
|
+
}, Nt = (e) => e.map((e) => {
|
|
331
|
+
let { regex: t, paramNames: n, priority: r } = Mt(e.pattern);
|
|
291
332
|
return {
|
|
292
333
|
pattern: e.pattern,
|
|
293
334
|
file: e.file,
|
|
@@ -296,7 +337,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
296
337
|
paramNames: n,
|
|
297
338
|
priority: r
|
|
298
339
|
};
|
|
299
|
-
}).slice().sort((e, t) => e.priority - t.priority),
|
|
340
|
+
}).slice().sort((e, t) => e.priority - t.priority), Pt = (e, t) => {
|
|
300
341
|
for (let n of t) {
|
|
301
342
|
let t = n.regex.exec(e);
|
|
302
343
|
if (!t) continue;
|
|
@@ -308,7 +349,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
308
349
|
};
|
|
309
350
|
}
|
|
310
351
|
return null;
|
|
311
|
-
},
|
|
352
|
+
}, Z = null, Ft, It = (e, t) => t === void 0 ? Promise.resolve() : (Ft ??= (async () => {
|
|
312
353
|
try {
|
|
313
354
|
let n = await e.getHelpers(), r = n.apiDescriptors?.[t];
|
|
314
355
|
if (r === void 0) return;
|
|
@@ -316,10 +357,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
316
357
|
if (i === void 0) return;
|
|
317
358
|
i(t, await r());
|
|
318
359
|
} catch {}
|
|
319
|
-
})(),
|
|
360
|
+
})(), Ft), Lt = async (e) => {
|
|
320
361
|
let { provider: t, route: r, params: i, pathname: a, dirs: o, shellTemplate: s, requestHeaders: c, requestUrl: l = "", apiOrigin: u, apiName: d } = e;
|
|
321
|
-
await
|
|
322
|
-
let { search: p } =
|
|
362
|
+
await It(t, d);
|
|
363
|
+
let { search: p } = ye(l), g = await re(ie(e.middlewares ?? [], {
|
|
323
364
|
route: r.pattern,
|
|
324
365
|
pathname: a
|
|
325
366
|
}), {
|
|
@@ -328,9 +369,9 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
328
369
|
headers: c,
|
|
329
370
|
cookies: ee(c.cookie),
|
|
330
371
|
route: r.pattern
|
|
331
|
-
}, e.onCookieWarning), y = await t.getPage(r.pattern, r.file), x = e.forceSsrRender === !0 ? "ssr" :
|
|
372
|
+
}, e.onCookieWarning), y = await t.getPage(r.pattern, r.file), x = e.forceSsrRender === !0 ? "ssr" : Re(y, r.file), S = x === "isr" && y.ppr === !0, C = x === "isr" && e.holesOnly !== !0 ? h(g.headers) : g.headers, w = be(u, C.cookie, {
|
|
332
373
|
apiName: d,
|
|
333
|
-
headers:
|
|
374
|
+
headers: C
|
|
334
375
|
});
|
|
335
376
|
if (e.holesOnly === !0) {
|
|
336
377
|
if (typeof y.loader != "function") return null;
|
|
@@ -343,8 +384,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
343
384
|
pathname: a,
|
|
344
385
|
search: p,
|
|
345
386
|
signal: e.signal,
|
|
346
|
-
headers:
|
|
347
|
-
query:
|
|
387
|
+
headers: C,
|
|
388
|
+
query: w,
|
|
348
389
|
isServer: !0
|
|
349
390
|
},
|
|
350
391
|
helpers: await t.getHelpers(),
|
|
@@ -353,12 +394,12 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
353
394
|
setCookies: g.setCookies
|
|
354
395
|
};
|
|
355
396
|
}
|
|
356
|
-
let
|
|
357
|
-
if (x !== "ssr" && x !== "isr" && !
|
|
358
|
-
let
|
|
397
|
+
let T = x === "spa" && Ce(o, r.dirChain).some((e) => e.hasLayout);
|
|
398
|
+
if (x !== "ssr" && x !== "isr" && !T) return null;
|
|
399
|
+
let ne = Ce(o, r.dirChain), ae = {}, se = null, ce, le = new AbortController(), de = S ? b(C, r.pattern) : C;
|
|
359
400
|
try {
|
|
360
|
-
(await t.getHelpers()).beginStoreSeeds(), {chain:
|
|
361
|
-
entries:
|
|
401
|
+
(await t.getHelpers()).beginStoreSeeds(), {chain: ce, segmentLoaderData: ae} = await O({
|
|
402
|
+
entries: ne,
|
|
362
403
|
loadLayout: (e) => t.getLayout(e.dir),
|
|
363
404
|
loadError: (e) => t.getError(e.dir),
|
|
364
405
|
loadPending: (e) => t.getPending(e.dir),
|
|
@@ -366,50 +407,50 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
366
407
|
params: i,
|
|
367
408
|
pathname: a,
|
|
368
409
|
search: p,
|
|
369
|
-
signal:
|
|
370
|
-
headers:
|
|
371
|
-
query:
|
|
410
|
+
signal: le.signal,
|
|
411
|
+
headers: de,
|
|
412
|
+
query: w,
|
|
372
413
|
isServer: !0
|
|
373
414
|
}
|
|
374
|
-
}), typeof y.loader == "function" && !
|
|
415
|
+
}), typeof y.loader == "function" && !T && (se = await y.loader({
|
|
375
416
|
params: i,
|
|
376
417
|
pathname: a,
|
|
377
418
|
search: p,
|
|
378
|
-
signal:
|
|
379
|
-
headers:
|
|
380
|
-
query:
|
|
419
|
+
signal: le.signal,
|
|
420
|
+
headers: de,
|
|
421
|
+
query: w,
|
|
381
422
|
isServer: !0
|
|
382
423
|
}));
|
|
383
424
|
} catch (e) {
|
|
384
|
-
if (
|
|
425
|
+
if (Dt(e)) return {
|
|
385
426
|
control: "redirect",
|
|
386
427
|
status: e.status,
|
|
387
428
|
location: e.location,
|
|
388
429
|
setCookies: g.setCookies,
|
|
389
430
|
responseHeaders: g.responseHeaders
|
|
390
431
|
};
|
|
391
|
-
if (
|
|
432
|
+
if (Ot(e)) return {
|
|
392
433
|
control: "not-found",
|
|
393
434
|
setCookies: g.setCookies,
|
|
394
435
|
responseHeaders: g.responseHeaders
|
|
395
436
|
};
|
|
396
437
|
throw e;
|
|
397
438
|
}
|
|
398
|
-
let
|
|
399
|
-
|
|
439
|
+
let k = await t.getHelpers();
|
|
440
|
+
T || await te({
|
|
400
441
|
pageMod: y,
|
|
401
442
|
params: i,
|
|
402
|
-
query:
|
|
443
|
+
query: w,
|
|
403
444
|
apiName: d,
|
|
404
|
-
seed:
|
|
405
|
-
seedFailure:
|
|
445
|
+
seed: k.seedPreloadedSubscription,
|
|
446
|
+
seedFailure: k.seedPreloadedSubscriptionFailure,
|
|
406
447
|
onError: ({ tag: e, apiName: t }, n) => Y.warn("preload seed failed", {
|
|
407
448
|
tag: e,
|
|
408
449
|
apiName: t,
|
|
409
450
|
pathname: a
|
|
410
451
|
}, n)
|
|
411
452
|
});
|
|
412
|
-
let
|
|
453
|
+
let fe = {
|
|
413
454
|
pattern: r.pattern,
|
|
414
455
|
Component: y.default,
|
|
415
456
|
meta: y.meta,
|
|
@@ -417,162 +458,168 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
417
458
|
ErrorBoundary: y.ErrorBoundary,
|
|
418
459
|
Pending: y.Pending,
|
|
419
460
|
renderMode: x,
|
|
420
|
-
chain:
|
|
461
|
+
chain: ce
|
|
421
462
|
};
|
|
422
463
|
if (x === "isr" && g.cspNonce !== void 0) throw Error(`page '${r.pattern}' is renderMode 'isr' while middleware.ts mints a cspNonce — an isr render is CACHED and a cached nonce is a lie the browser enforces. Use renderMode 'ssr' for nonce'd pages, or a hash-based CSP for isr.`);
|
|
423
|
-
let
|
|
424
|
-
cookies:
|
|
425
|
-
headers:
|
|
464
|
+
let pe = {
|
|
465
|
+
cookies: S ? v(f(g.cookies), r.pattern) : x === "isr" ? f(g.cookies) : g.cookies,
|
|
466
|
+
headers: de,
|
|
426
467
|
url: l,
|
|
427
468
|
...e.formFlash === void 0 ? {} : { formFlash: e.formFlash }
|
|
428
|
-
},
|
|
429
|
-
lang:
|
|
430
|
-
...
|
|
469
|
+
}, A = k.i18n?.resolve(C.cookie, C["accept-language"]), me = {
|
|
470
|
+
lang: A?.locale ?? pe.cookies["voltro:locale"] ?? "en",
|
|
471
|
+
...A?.timeZone === void 0 ? {} : { timeZone: A.timeZone },
|
|
431
472
|
renderedAt: Date.now()
|
|
432
|
-
},
|
|
433
|
-
if (
|
|
434
|
-
let e =
|
|
435
|
-
helpers:
|
|
473
|
+
}, j = y.interactive ?? "full";
|
|
474
|
+
if (T) {
|
|
475
|
+
let e = ue({
|
|
476
|
+
helpers: k,
|
|
436
477
|
page: r.pattern,
|
|
437
|
-
interactive:
|
|
478
|
+
interactive: j,
|
|
438
479
|
delivery: "stream",
|
|
439
480
|
renderInput: {
|
|
440
|
-
descriptor:
|
|
481
|
+
descriptor: fe,
|
|
441
482
|
params: i,
|
|
442
483
|
pathname: a,
|
|
443
484
|
search: p,
|
|
444
|
-
segmentLoaderData:
|
|
445
|
-
requestContext:
|
|
446
|
-
...
|
|
447
|
-
outerWrap:
|
|
448
|
-
locale:
|
|
485
|
+
segmentLoaderData: ae,
|
|
486
|
+
requestContext: pe,
|
|
487
|
+
...A ? {
|
|
488
|
+
outerWrap: A.outerWrap,
|
|
489
|
+
locale: A.locale
|
|
449
490
|
} : {}
|
|
450
491
|
}
|
|
451
|
-
}), t = (t) =>
|
|
452
|
-
helpers:
|
|
492
|
+
}), t = (t) => _e({
|
|
493
|
+
helpers: k,
|
|
453
494
|
prepared: e,
|
|
454
495
|
meta: t,
|
|
455
|
-
interactive:
|
|
496
|
+
interactive: j
|
|
456
497
|
});
|
|
457
498
|
if (e.hasDeferred) {
|
|
458
|
-
let n =
|
|
499
|
+
let n = D({ shell: s });
|
|
459
500
|
return {
|
|
460
501
|
renderMode: "spa",
|
|
461
502
|
setCookies: g.setCookies,
|
|
462
503
|
responseHeaders: g.responseHeaders,
|
|
463
|
-
stream: (r) =>
|
|
504
|
+
stream: (r) => oe({
|
|
464
505
|
res: r,
|
|
465
506
|
shell: n,
|
|
466
|
-
documentAttrs:
|
|
507
|
+
documentAttrs: me,
|
|
467
508
|
headers: {
|
|
468
509
|
...g.responseHeaders,
|
|
469
510
|
"content-type": "text/html; charset=utf-8",
|
|
470
511
|
"x-voltro-rendered-by": "spa",
|
|
471
|
-
...
|
|
512
|
+
...F(g.setCookies)
|
|
472
513
|
},
|
|
473
514
|
headInjection: t,
|
|
474
515
|
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce },
|
|
475
|
-
render: (t) =>
|
|
516
|
+
render: (t) => k.renderPageToStream({
|
|
476
517
|
...e.renderInput,
|
|
477
518
|
...t,
|
|
478
519
|
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce }
|
|
479
520
|
}),
|
|
480
521
|
onShellError: (e) => {
|
|
481
|
-
Y.error("spa layout shell render failed", { pathname: a }, e),
|
|
522
|
+
Y.error("spa layout shell render failed", { pathname: a }, e), Bt?.(e, {
|
|
523
|
+
stage: "spa-layout-shell",
|
|
524
|
+
pathname: a
|
|
525
|
+
}), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
|
|
482
526
|
}
|
|
483
527
|
})
|
|
484
528
|
};
|
|
485
529
|
}
|
|
486
|
-
let n =
|
|
487
|
-
helpers:
|
|
530
|
+
let n = P({
|
|
531
|
+
helpers: k,
|
|
488
532
|
prepared: e
|
|
489
|
-
}), o =
|
|
533
|
+
}), o = N(m(s.replace("<div id=\"root\"></div>", `<div id="root">${n.body}</div>`), t(n.meta)), me);
|
|
490
534
|
return {
|
|
491
|
-
html: g.cspNonce === void 0 ? o :
|
|
535
|
+
html: g.cspNonce === void 0 ? o : E(o, g.cspNonce),
|
|
492
536
|
renderMode: "spa",
|
|
493
537
|
revalidateMs: null,
|
|
494
538
|
setCookies: g.setCookies,
|
|
495
539
|
responseHeaders: g.responseHeaders
|
|
496
540
|
};
|
|
497
541
|
}
|
|
498
|
-
let
|
|
499
|
-
helpers:
|
|
542
|
+
let M = n({
|
|
543
|
+
helpers: k,
|
|
500
544
|
page: r.pattern,
|
|
501
545
|
pathname: a,
|
|
502
546
|
renderMode: x,
|
|
503
|
-
interactive:
|
|
504
|
-
loaderData:
|
|
505
|
-
segmentLoaderData:
|
|
547
|
+
interactive: j,
|
|
548
|
+
loaderData: se,
|
|
549
|
+
segmentLoaderData: ae,
|
|
506
550
|
pageLoaderRan: typeof y.loader == "function",
|
|
507
|
-
...
|
|
551
|
+
...S ? { ppr: !0 } : {}
|
|
508
552
|
});
|
|
509
|
-
|
|
510
|
-
let
|
|
511
|
-
descriptor:
|
|
553
|
+
S && _(M.stateInput, r.pattern);
|
|
554
|
+
let he = {
|
|
555
|
+
descriptor: fe,
|
|
512
556
|
params: i,
|
|
513
557
|
pathname: a,
|
|
514
558
|
search: p,
|
|
515
|
-
loaderData:
|
|
516
|
-
segmentLoaderData:
|
|
517
|
-
requestContext:
|
|
518
|
-
...
|
|
519
|
-
outerWrap:
|
|
520
|
-
locale:
|
|
559
|
+
loaderData: M.loaderData,
|
|
560
|
+
segmentLoaderData: M.segmentLoaderData,
|
|
561
|
+
requestContext: pe,
|
|
562
|
+
...A ? {
|
|
563
|
+
outerWrap: A.outerWrap,
|
|
564
|
+
locale: A.locale
|
|
521
565
|
} : {}
|
|
522
|
-
},
|
|
523
|
-
if (
|
|
524
|
-
let n =
|
|
566
|
+
}, ge = (t) => {
|
|
567
|
+
if (Z === null || x !== "ssr" && x !== "isr" || typeof y.ogImage != "function" || t.includes("og:image")) return "";
|
|
568
|
+
let n = C["x-tenant"], i = Z.signOgUrl({
|
|
525
569
|
pattern: r.pattern,
|
|
526
570
|
params: e.params,
|
|
527
571
|
...n === void 0 ? {} : { tenant: n }
|
|
528
572
|
});
|
|
529
573
|
return `<meta property="og:image" content="${i}" /><meta name="twitter:image" content="${i}" /><meta name="twitter:card" content="summary_large_image" />`;
|
|
530
|
-
},
|
|
531
|
-
|
|
532
|
-
`<meta name="voltro-interactive" content="${
|
|
533
|
-
...
|
|
534
|
-
|
|
574
|
+
}, ve = (e) => [
|
|
575
|
+
k.renderMetaToHtml(e) + ge(k.renderMetaToHtml(e)),
|
|
576
|
+
`<meta name="voltro-interactive" content="${j}" />`,
|
|
577
|
+
...M.hasDeferred ? [k.renderDeferredRegistryScript()] : [],
|
|
578
|
+
k.renderRouterStateScript(M.stateInput)
|
|
535
579
|
].filter((e) => e.length > 0).join("\n ");
|
|
536
|
-
if (x === "ssr" &&
|
|
537
|
-
let e =
|
|
580
|
+
if (x === "ssr" && j === "full" && e.buffered !== !0) {
|
|
581
|
+
let e = D({ shell: s });
|
|
538
582
|
return {
|
|
539
583
|
renderMode: "ssr",
|
|
540
584
|
setCookies: g.setCookies,
|
|
541
|
-
stream: (t) =>
|
|
585
|
+
stream: (t) => oe({
|
|
542
586
|
res: t,
|
|
543
587
|
shell: e,
|
|
544
|
-
documentAttrs:
|
|
588
|
+
documentAttrs: me,
|
|
545
589
|
headers: {
|
|
546
590
|
...g.responseHeaders,
|
|
547
591
|
"content-type": "text/html; charset=utf-8",
|
|
548
592
|
"x-voltro-rendered-by": "ssr",
|
|
549
|
-
...
|
|
593
|
+
...F(g.setCookies)
|
|
550
594
|
},
|
|
551
|
-
headInjection:
|
|
595
|
+
headInjection: ve,
|
|
552
596
|
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce },
|
|
553
|
-
render: (e) =>
|
|
554
|
-
...
|
|
597
|
+
render: (e) => k.renderPageToStream({
|
|
598
|
+
...he,
|
|
555
599
|
...e,
|
|
556
600
|
...g.cspNonce === void 0 ? {} : { nonce: g.cspNonce }
|
|
557
601
|
}),
|
|
558
602
|
onShellError: (e) => {
|
|
559
|
-
Y.error("ssr shell render failed", { pathname: a }, e),
|
|
603
|
+
Y.error("ssr shell render failed", { pathname: a }, e), Bt?.(e, {
|
|
604
|
+
stage: "ssr-shell",
|
|
605
|
+
pathname: a
|
|
606
|
+
}), t.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), t.end("server error");
|
|
560
607
|
}
|
|
561
608
|
})
|
|
562
609
|
};
|
|
563
610
|
}
|
|
564
|
-
let { html:
|
|
565
|
-
|
|
566
|
-
let
|
|
611
|
+
let { html: xe, meta: Se } = k.renderPageToHtml(he), we = ve(Se), I = N(m(s.replace("<div id=\"root\"></div>", `<div id="root">${xe}</div>`), we), me);
|
|
612
|
+
j === "none" && (I = jt(I));
|
|
613
|
+
let Te = x === "isr" ? L(y.revalidate) : null;
|
|
567
614
|
return {
|
|
568
|
-
html: g.cspNonce === void 0 ?
|
|
615
|
+
html: g.cspNonce === void 0 ? I : E(I, g.cspNonce),
|
|
569
616
|
renderMode: x,
|
|
570
|
-
revalidateMs:
|
|
617
|
+
revalidateMs: Te,
|
|
571
618
|
setCookies: g.setCookies,
|
|
572
619
|
responseHeaders: g.responseHeaders
|
|
573
620
|
};
|
|
574
|
-
}, Q = (e) => e === "" ? "/" : e,
|
|
575
|
-
let t = await import(
|
|
621
|
+
}, Q = (e) => e === "" ? "/" : e, Rt = async (e) => {
|
|
622
|
+
let t = await import(H(e).href);
|
|
576
623
|
return {
|
|
577
624
|
kind: "bundle",
|
|
578
625
|
getPageMeta: () => t.pageMeta,
|
|
@@ -601,8 +648,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
601
648
|
},
|
|
602
649
|
async close() {}
|
|
603
650
|
};
|
|
604
|
-
},
|
|
605
|
-
let n = await
|
|
651
|
+
}, zt = async (e, t) => {
|
|
652
|
+
let n = await C("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
|
|
606
653
|
root: t,
|
|
607
654
|
envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
|
|
608
655
|
plugins: [r(), i()],
|
|
@@ -619,8 +666,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
619
666
|
},
|
|
620
667
|
appType: "custom",
|
|
621
668
|
logLevel: "warn"
|
|
622
|
-
}), o =
|
|
623
|
-
limit:
|
|
669
|
+
}), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c = g({
|
|
670
|
+
limit: T(),
|
|
624
671
|
onColdStart: (e) => Y.debug("ssr cold-compile start", { id: e }),
|
|
625
672
|
onColdEnd: (e, { durationMs: t, failed: n }) => Y.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
|
|
626
673
|
id: e,
|
|
@@ -631,16 +678,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
631
678
|
return {
|
|
632
679
|
kind: "middleware",
|
|
633
680
|
async getPage(e, t) {
|
|
634
|
-
return l(
|
|
681
|
+
return l(z(o, t));
|
|
635
682
|
},
|
|
636
683
|
async getLayout(e) {
|
|
637
|
-
return l(
|
|
684
|
+
return l(z(s(e), "layout.tsx"));
|
|
638
685
|
},
|
|
639
686
|
async getError(e) {
|
|
640
|
-
return l(
|
|
687
|
+
return l(z(s(e), "error.tsx"));
|
|
641
688
|
},
|
|
642
689
|
async getPending(e) {
|
|
643
|
-
return l(
|
|
690
|
+
return l(z(s(e), "loading.tsx"));
|
|
644
691
|
},
|
|
645
692
|
async getHelpers() {
|
|
646
693
|
return await l("@voltro/web/ssr");
|
|
@@ -649,8 +696,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
649
696
|
await a.close();
|
|
650
697
|
}
|
|
651
698
|
};
|
|
652
|
-
},
|
|
653
|
-
let n =
|
|
699
|
+
}, Bt, $ = async (t) => {
|
|
700
|
+
let n = Je(), f = await M(t);
|
|
654
701
|
if (!f) return {
|
|
655
702
|
ran: !1,
|
|
656
703
|
exitCode: 0
|
|
@@ -659,6 +706,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
659
706
|
ran: !0,
|
|
660
707
|
exitCode: 1
|
|
661
708
|
};
|
|
709
|
+
Bt = await Tt(t, process.env, Y);
|
|
662
710
|
{
|
|
663
711
|
let e = s(f);
|
|
664
712
|
if (e !== void 0) return Y.error(`voltro start: refusing to boot — ${e}`), {
|
|
@@ -666,7 +714,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
666
714
|
exitCode: 1
|
|
667
715
|
};
|
|
668
716
|
}
|
|
669
|
-
let { resolved: m } = await
|
|
717
|
+
let { resolved: m } = await ae({
|
|
670
718
|
rawEnv: f.env,
|
|
671
719
|
appType: "web",
|
|
672
720
|
root: t,
|
|
@@ -674,87 +722,87 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
674
722
|
generateTypes: !1
|
|
675
723
|
}), te = m.publicValues;
|
|
676
724
|
n.mark("config");
|
|
677
|
-
let h =
|
|
678
|
-
|
|
679
|
-
let g =
|
|
725
|
+
let h = le();
|
|
726
|
+
de(h), Y.info("booting voltro start", { app: f.name ?? "(unnamed)" });
|
|
727
|
+
let g = je({
|
|
680
728
|
kind: "web",
|
|
681
729
|
configPort: f.port,
|
|
682
730
|
env: process.env,
|
|
683
|
-
dashboardPin: process.env[
|
|
731
|
+
dashboardPin: process.env[fe] === "1"
|
|
684
732
|
});
|
|
685
733
|
for (let e of g.warnings) Y.warn(e);
|
|
686
|
-
let _ = g.port, v =
|
|
734
|
+
let _ = g.port, v = z(t, ".framework");
|
|
687
735
|
{
|
|
688
736
|
let e;
|
|
689
737
|
try {
|
|
690
|
-
e = JSON.parse(await
|
|
738
|
+
e = JSON.parse(await V.readFile(z(v, "env.public.json"), "utf8"));
|
|
691
739
|
} catch {
|
|
692
740
|
e = void 0;
|
|
693
741
|
}
|
|
694
742
|
let t = ft(process.env, e);
|
|
695
743
|
t.length > 0 && Y.warn(pt(t));
|
|
696
744
|
}
|
|
697
|
-
let b =
|
|
698
|
-
if (!await
|
|
745
|
+
let b = z(v, "dist"), C = z(b, "index.html");
|
|
746
|
+
if (!await X(C)) return Y.error("no built dist found — run `voltro build` first", { distDir: b }), {
|
|
699
747
|
ran: !0,
|
|
700
748
|
exitCode: 1
|
|
701
749
|
};
|
|
702
|
-
let
|
|
703
|
-
await
|
|
704
|
-
id:
|
|
705
|
-
name:
|
|
750
|
+
let T = f.name ?? "unnamed", E = Ke("web", T, _), D = qe(T);
|
|
751
|
+
await Ue({
|
|
752
|
+
id: E,
|
|
753
|
+
name: T,
|
|
706
754
|
kind: "web",
|
|
707
755
|
url: `http://localhost:${_}`,
|
|
708
756
|
pid: process.pid,
|
|
709
757
|
status: "booting",
|
|
710
|
-
logFile:
|
|
758
|
+
logFile: D.path
|
|
711
759
|
}).catch(() => {});
|
|
712
|
-
let
|
|
713
|
-
|
|
760
|
+
let oe = z(b, "_voltro", "shell.html"), O = await X(oe) ? await V.readFile(oe, "utf8") : await V.readFile(C, "utf8"), ue = await k(t, f), _e = Pe(f), N = Ye(f), P = ge(ue[0]), F = ue[0]?.name, Re = /* @__PURE__ */ new Set(), L = (e) => {
|
|
761
|
+
Re.has(e.name) || (Re.add(e.name), Y.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
|
|
714
762
|
cookie: e.name,
|
|
715
763
|
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."
|
|
716
764
|
}));
|
|
717
|
-
},
|
|
718
|
-
|
|
719
|
-
let
|
|
720
|
-
if (
|
|
721
|
-
else if (
|
|
765
|
+
}, R = await a(t);
|
|
766
|
+
R.length > 0 && Y.info(`middleware.ts loaded — ${R.length} middleware(s): ` + R.map((e) => e.exportName).join(", "));
|
|
767
|
+
let B, H = null, U = process.env.SSR_CACHE === "postgres";
|
|
768
|
+
if (U && Ne()) H = new (await (import("pg"))).default.Client(Me()), await H.connect(), B = xt({ client: H }), Y.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
|
|
769
|
+
else if (U) {
|
|
722
770
|
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).";
|
|
723
771
|
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");
|
|
724
|
-
|
|
725
|
-
} else
|
|
726
|
-
await o(t, f,
|
|
727
|
-
let
|
|
728
|
-
|
|
729
|
-
let
|
|
730
|
-
if (!
|
|
731
|
-
let K =
|
|
772
|
+
B = Be(), Y.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
|
|
773
|
+
} else B = Be(), Y.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
|
|
774
|
+
await o(t, f, ue, te);
|
|
775
|
+
let tt = z(t, "src", "pages"), { pages: nt, dirs: W } = await ne(tt), G = Nt(nt);
|
|
776
|
+
w(R, G.map((e) => e.pattern)), n.mark("scan");
|
|
777
|
+
let ct = z(b, "server", "ssrEntry.js"), dt = await X(ct);
|
|
778
|
+
if (!dt && process.env.NODE_ENV === "production") throw Y.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${ct} 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 ${ct}`);
|
|
779
|
+
let K = dt ? await Rt(ct) : await zt(t, v);
|
|
732
780
|
Y.info(`ssr loader: ${K.kind}`, {
|
|
733
781
|
kind: K.kind,
|
|
734
782
|
...K.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
|
|
735
783
|
}), n.mark("provider");
|
|
736
|
-
let
|
|
784
|
+
let _t = K.getPageMeta?.();
|
|
737
785
|
c(t);
|
|
738
786
|
let q = /* @__PURE__ */ new Map(), yt = 0;
|
|
739
|
-
for (let e of
|
|
740
|
-
let t =
|
|
787
|
+
for (let e of nt) {
|
|
788
|
+
let t = _t?.[e.pattern];
|
|
741
789
|
if (t) {
|
|
742
790
|
q.set(e.pattern, t);
|
|
743
791
|
continue;
|
|
744
792
|
}
|
|
745
793
|
try {
|
|
746
794
|
let t = await K.getPage(e.pattern, e.file);
|
|
747
|
-
q.set(e.pattern,
|
|
795
|
+
q.set(e.pattern, Le(t, e.file)), yt++;
|
|
748
796
|
} catch (t) {
|
|
749
797
|
Y.warn("failed to load page metadata", { pattern: e.pattern }, t);
|
|
750
798
|
}
|
|
751
799
|
}
|
|
752
|
-
let
|
|
800
|
+
let bt = /* @__PURE__ */ new Map();
|
|
753
801
|
for (let [e, t] of q) {
|
|
754
802
|
if (t.interactive !== "islands") continue;
|
|
755
|
-
let n =
|
|
803
|
+
let n = z(b, "island-shells", `${A(e)}.html`);
|
|
756
804
|
try {
|
|
757
|
-
|
|
805
|
+
bt.set(e, await V.readFile(n, "utf8"));
|
|
758
806
|
} catch {
|
|
759
807
|
Y.warn("islands page has no built per-page shell — serving the full app shell", {
|
|
760
808
|
pattern: e,
|
|
@@ -767,23 +815,23 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
767
815
|
fromManifest: q.size - yt,
|
|
768
816
|
fromModules: yt
|
|
769
817
|
}), n.mark("routes");
|
|
770
|
-
let
|
|
771
|
-
for (let e of
|
|
772
|
-
|
|
818
|
+
let J = /* @__PURE__ */ new Set();
|
|
819
|
+
for (let e of G) q.get(e.pattern)?.renderMode === "spa" && Ce(W, e.dirChain).some((e) => e.hasLayout) && J.add(e.pattern);
|
|
820
|
+
J.size > 0 && Y.info(`${J.size} spa route(s) render an SSR layout shell`, { patterns: [...J] });
|
|
773
821
|
let wt = /* @__PURE__ */ new Map();
|
|
774
822
|
for (let [e, t] of q) t.cacheInvalidatesOn.length > 0 && wt.set(e, t.cacheInvalidatesOn);
|
|
775
|
-
let
|
|
776
|
-
for (let e of
|
|
823
|
+
let Dt = /* @__PURE__ */ new Map();
|
|
824
|
+
for (let e of G) Dt.set(e.pattern, e.regex);
|
|
777
825
|
{
|
|
778
826
|
let n = new Set([...q].filter(([, e]) => (e.renderMode === "ssr" || e.renderMode === "isr") && e.hasOgImage).map(([e]) => e));
|
|
779
827
|
if (n.size > 0) {
|
|
780
|
-
let { secret: r, fromEnv: i } =
|
|
828
|
+
let { secret: r, fromEnv: i } = we();
|
|
781
829
|
if (!i && e()) throw Y.fatal(`${n.size} ssr route(s) export ogImage, but VOLTRO_OG_SECRET is unset. Behind a load balancer the signing replica and the fetching replica differ, so a per-boot secret would 403 every cross-replica image fetch. Set VOLTRO_OG_SECRET (any long random value, same on every replica).`), Error("[voltro start] ssr ogImage routes need VOLTRO_OG_SECRET in a deploy environment");
|
|
782
|
-
let a = new Map(
|
|
783
|
-
|
|
830
|
+
let a = new Map(nt.map((e) => [e.pattern, e.file]));
|
|
831
|
+
Z = ce({
|
|
784
832
|
root: t,
|
|
785
833
|
fonts: f.fonts,
|
|
786
|
-
cache:
|
|
834
|
+
cache: B,
|
|
787
835
|
secret: r,
|
|
788
836
|
isOgSsrRoute: (e) => n.has(e),
|
|
789
837
|
getPageModule: async (e) => {
|
|
@@ -793,39 +841,39 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
793
841
|
}), Y.info(`og route active for ${n.size} ssr route(s)`, { secret: i ? "env" : "per-boot" });
|
|
794
842
|
}
|
|
795
843
|
}
|
|
796
|
-
let
|
|
797
|
-
for (let [e, t] of q)
|
|
798
|
-
let
|
|
799
|
-
cache:
|
|
844
|
+
let Ot = /* @__PURE__ */ new Map();
|
|
845
|
+
for (let [e, t] of q) Ot.set(e, t.renderMode);
|
|
846
|
+
let kt = [...q.values()].some((e) => e.renderMode === "isr"), jt = {
|
|
847
|
+
cache: B,
|
|
800
848
|
tableSink: gt({
|
|
801
|
-
cache:
|
|
849
|
+
cache: B,
|
|
802
850
|
tableSubscriptionsByPattern: wt,
|
|
803
|
-
regexByPattern:
|
|
851
|
+
regexByPattern: Dt
|
|
804
852
|
}),
|
|
805
|
-
regexByPattern:
|
|
806
|
-
renderModeByPattern:
|
|
807
|
-
},
|
|
808
|
-
let t =
|
|
809
|
-
t &&
|
|
810
|
-
},
|
|
811
|
-
cache:
|
|
853
|
+
regexByPattern: Dt,
|
|
854
|
+
renderModeByPattern: Ot
|
|
855
|
+
}, Mt = (e) => {
|
|
856
|
+
let t = St(e);
|
|
857
|
+
t && Ct(jt, t);
|
|
858
|
+
}, Ft = vt({
|
|
859
|
+
cache: B,
|
|
812
860
|
tableSubscriptionsByPattern: wt,
|
|
813
|
-
regexByPattern:
|
|
814
|
-
...
|
|
815
|
-
}),
|
|
816
|
-
if (
|
|
861
|
+
regexByPattern: Dt,
|
|
862
|
+
...kt ? { onRevalidate: Mt } : {}
|
|
863
|
+
}), It = await Ft.start(), Q = null, $ = null;
|
|
864
|
+
if (kt) {
|
|
817
865
|
let e = lt({}, process.env);
|
|
818
866
|
if (e.crossReplica) try {
|
|
819
|
-
|
|
820
|
-
let t =
|
|
821
|
-
|
|
867
|
+
$ = e.provider;
|
|
868
|
+
let t = Fe(process.env);
|
|
869
|
+
Q = await st.runPromise(e.provider.subscribe(t, Mt)), Y.info(`revalidation subscriber: broker (${e.provider.name})`, { channel: t });
|
|
822
870
|
} catch (e) {
|
|
823
|
-
Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e),
|
|
871
|
+
Y.warn("revalidation broker subscribe failed — broker leg disabled", {}, e), $ = null;
|
|
824
872
|
}
|
|
825
|
-
|
|
873
|
+
It && Q === null && Y.info("revalidation subscriber: postgres LISTEN (voltro_revalidate)"), !It && Q === 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.");
|
|
826
874
|
}
|
|
827
875
|
n.mark("cdc");
|
|
828
|
-
let
|
|
876
|
+
let Vt = Ie(), Ht = nt.map((e) => {
|
|
829
877
|
let t = q.get(e.pattern);
|
|
830
878
|
return {
|
|
831
879
|
pattern: e.pattern,
|
|
@@ -841,19 +889,19 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
841
889
|
hasMeta: t?.hasMeta ?? !1,
|
|
842
890
|
hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
|
|
843
891
|
};
|
|
844
|
-
}),
|
|
892
|
+
}), Ut = W.map((e) => ({
|
|
845
893
|
dir: e.dir,
|
|
846
894
|
hasLayout: e.hasLayout,
|
|
847
895
|
hasError: e.hasError,
|
|
848
896
|
hasPending: e.hasPending,
|
|
849
897
|
hasNotFound: e.hasNotFound
|
|
850
|
-
})),
|
|
898
|
+
})), Wt = H ? "postgres" : "memory", Gt = {
|
|
851
899
|
kind: "web",
|
|
852
900
|
meta: {
|
|
853
901
|
name: f.name ?? "(unnamed)",
|
|
854
|
-
voltroVersion:
|
|
902
|
+
voltroVersion: Et,
|
|
855
903
|
port: _,
|
|
856
|
-
mode:
|
|
904
|
+
mode: et(),
|
|
857
905
|
apis: Object.entries(f.apis ?? {}).map(([e, t]) => {
|
|
858
906
|
let n = {
|
|
859
907
|
name: e,
|
|
@@ -862,10 +910,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
862
910
|
return t.url !== void 0 && (n.url = t.url), n;
|
|
863
911
|
})
|
|
864
912
|
},
|
|
865
|
-
routes:
|
|
866
|
-
dirs:
|
|
913
|
+
routes: Ht,
|
|
914
|
+
dirs: Ut,
|
|
867
915
|
cache: () => {
|
|
868
|
-
let e = Date.now(), t =
|
|
916
|
+
let e = Date.now(), t = B.snapshot().map(([t, n]) => ({
|
|
869
917
|
key: t,
|
|
870
918
|
renderedAt: n.renderedAt,
|
|
871
919
|
expiresAt: n.expiresAt,
|
|
@@ -876,16 +924,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
876
924
|
staleWhileRevalidateMs: n.staleWhileRevalidateMs
|
|
877
925
|
}));
|
|
878
926
|
return {
|
|
879
|
-
backend:
|
|
880
|
-
size:
|
|
927
|
+
backend: Wt,
|
|
928
|
+
size: B.size(),
|
|
881
929
|
entries: t
|
|
882
930
|
};
|
|
883
931
|
},
|
|
884
|
-
metrics: () =>
|
|
885
|
-
},
|
|
932
|
+
metrics: () => ot()
|
|
933
|
+
}, Kt = async (e, n) => {
|
|
886
934
|
let r = e.split("?")[0] ?? "/";
|
|
887
935
|
if (f.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
|
|
888
|
-
let e = await
|
|
936
|
+
let e = await We();
|
|
889
937
|
return {
|
|
890
938
|
status: 200,
|
|
891
939
|
headers: { "content-type": "application/json; charset=utf-8" },
|
|
@@ -927,8 +975,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
927
975
|
body: JSON.stringify({ apps: t })
|
|
928
976
|
};
|
|
929
977
|
}
|
|
930
|
-
if (
|
|
931
|
-
let t = await
|
|
978
|
+
if (Z !== null && r === "/_voltro/og") {
|
|
979
|
+
let t = await Z.handle(new URL(e, "http://localhost"));
|
|
932
980
|
if (t !== null) return {
|
|
933
981
|
status: t.status,
|
|
934
982
|
headers: { ...t.headers },
|
|
@@ -936,18 +984,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
936
984
|
};
|
|
937
985
|
}
|
|
938
986
|
if (r === "/_voltro/inspect/logs") {
|
|
939
|
-
let t =
|
|
987
|
+
let t = j(e, he(), n);
|
|
940
988
|
return {
|
|
941
989
|
status: t.status,
|
|
942
990
|
headers: {
|
|
943
991
|
"content-type": t.contentType,
|
|
944
|
-
...
|
|
992
|
+
...De(n.origin)
|
|
945
993
|
},
|
|
946
994
|
body: t.body
|
|
947
995
|
};
|
|
948
996
|
}
|
|
949
997
|
if (r !== "/_voltro/inspect/stream") {
|
|
950
|
-
let t =
|
|
998
|
+
let t = Oe(e, Gt, n);
|
|
951
999
|
if (t !== null) return {
|
|
952
1000
|
status: t.status,
|
|
953
1001
|
headers: {
|
|
@@ -957,14 +1005,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
957
1005
|
body: t.body
|
|
958
1006
|
};
|
|
959
1007
|
}
|
|
960
|
-
let i =
|
|
961
|
-
if (!o &&
|
|
962
|
-
let t =
|
|
1008
|
+
let i = Pt(r, G), a = i ? q.get(i.route.pattern)?.renderMode : void 0, o = a === "ssr" || a === "isr" || (i ? J.has(i.route.pattern) : !1), s = [];
|
|
1009
|
+
if (!o && R.length > 0) {
|
|
1010
|
+
let t = ie(R, {
|
|
963
1011
|
route: void 0,
|
|
964
1012
|
pathname: r
|
|
965
1013
|
});
|
|
966
1014
|
if (t !== void 0) {
|
|
967
|
-
let i = await
|
|
1015
|
+
let i = await re(t, {
|
|
968
1016
|
pathname: r,
|
|
969
1017
|
search: e.slice(r.length),
|
|
970
1018
|
headers: n,
|
|
@@ -977,14 +1025,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
977
1025
|
let c = (e) => s.length === 0 ? e : {
|
|
978
1026
|
...e,
|
|
979
1027
|
"set-cookie": s.map(d)
|
|
980
|
-
}, u = r === "/" ?
|
|
981
|
-
if (!o && await
|
|
982
|
-
let e = await
|
|
1028
|
+
}, u = r === "/" ? z(b, "index.html") : z(b, r.replace(/^\//, ""), "index.html");
|
|
1029
|
+
if (!o && await X(u)) {
|
|
1030
|
+
let e = await V.readFile(u);
|
|
983
1031
|
return {
|
|
984
1032
|
status: 200,
|
|
985
1033
|
headers: c({
|
|
986
1034
|
"content-type": "text/html; charset=utf-8",
|
|
987
|
-
"cache-control":
|
|
1035
|
+
"cache-control": Ze(N)
|
|
988
1036
|
}),
|
|
989
1037
|
body: e
|
|
990
1038
|
};
|
|
@@ -995,39 +1043,39 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
995
1043
|
body: "not found"
|
|
996
1044
|
};
|
|
997
1045
|
if (/\.[a-z0-9]+$/i.test(r)) {
|
|
998
|
-
let e =
|
|
999
|
-
if (await
|
|
1000
|
-
let t =
|
|
1001
|
-
if (a !== void 0 && await
|
|
1002
|
-
let n = await
|
|
1046
|
+
let e = z(b, r.replace(/^\//, ""));
|
|
1047
|
+
if (await X(e)) {
|
|
1048
|
+
let t = Qe(r, N), i = it(n["accept-encoding"]), a = i === "br" ? `${e}.br` : i === "gzip" ? `${e}.gz` : void 0;
|
|
1049
|
+
if (a !== void 0 && await X(a)) {
|
|
1050
|
+
let n = await V.readFile(e);
|
|
1003
1051
|
return {
|
|
1004
1052
|
status: 200,
|
|
1005
1053
|
headers: c({
|
|
1006
|
-
"content-type":
|
|
1054
|
+
"content-type": At(e),
|
|
1007
1055
|
"cache-control": t,
|
|
1008
1056
|
"content-encoding": i === "br" ? "br" : "gzip",
|
|
1009
1057
|
vary: "Accept-Encoding",
|
|
1010
1058
|
etag: mt(n)
|
|
1011
1059
|
}),
|
|
1012
|
-
body: await
|
|
1060
|
+
body: await V.readFile(a)
|
|
1013
1061
|
};
|
|
1014
1062
|
}
|
|
1015
|
-
let o = await
|
|
1063
|
+
let o = await V.readFile(e);
|
|
1016
1064
|
return {
|
|
1017
1065
|
status: 200,
|
|
1018
1066
|
headers: c({
|
|
1019
|
-
"content-type":
|
|
1067
|
+
"content-type": At(e),
|
|
1020
1068
|
"cache-control": t
|
|
1021
1069
|
}),
|
|
1022
1070
|
body: o
|
|
1023
1071
|
};
|
|
1024
1072
|
}
|
|
1025
1073
|
}
|
|
1026
|
-
let p =
|
|
1074
|
+
let p = Pt(r, G);
|
|
1027
1075
|
if (!p) {
|
|
1028
|
-
let i =
|
|
1076
|
+
let i = se(W, r);
|
|
1029
1077
|
if (i !== void 0) try {
|
|
1030
|
-
let a = await
|
|
1078
|
+
let a = await Lt({
|
|
1031
1079
|
provider: K,
|
|
1032
1080
|
root: t,
|
|
1033
1081
|
route: {
|
|
@@ -1040,13 +1088,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1040
1088
|
},
|
|
1041
1089
|
params: {},
|
|
1042
1090
|
pathname: r,
|
|
1043
|
-
dirs:
|
|
1044
|
-
shellTemplate:
|
|
1091
|
+
dirs: W,
|
|
1092
|
+
shellTemplate: O,
|
|
1045
1093
|
requestHeaders: n,
|
|
1046
|
-
apiOrigin:
|
|
1047
|
-
apiName:
|
|
1048
|
-
middlewares:
|
|
1049
|
-
onCookieWarning:
|
|
1094
|
+
apiOrigin: P,
|
|
1095
|
+
apiName: F,
|
|
1096
|
+
middlewares: R,
|
|
1097
|
+
onCookieWarning: L,
|
|
1050
1098
|
requestUrl: e,
|
|
1051
1099
|
buffered: !0,
|
|
1052
1100
|
forceSsrRender: !0
|
|
@@ -1071,7 +1119,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1071
1119
|
body: "not found"
|
|
1072
1120
|
};
|
|
1073
1121
|
}
|
|
1074
|
-
let m = q.get(p.route.pattern), te = n["x-tenant"] ?? "anonymous", g = (await K.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, _ =
|
|
1122
|
+
let m = q.get(p.route.pattern), te = n["x-tenant"] ?? "anonymous", g = (await K.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, _ = Ve(r, {
|
|
1075
1123
|
...m?.tenantAware ? { tenant: te } : {},
|
|
1076
1124
|
...g ? { locale: g } : {}
|
|
1077
1125
|
}), v = m?.ppr === !0 && m.renderMode === "isr", y = (i, a) => ({
|
|
@@ -1086,23 +1134,23 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1086
1134
|
...a
|
|
1087
1135
|
}), o.write(i), (async () => {
|
|
1088
1136
|
try {
|
|
1089
|
-
let i = await
|
|
1137
|
+
let i = await Lt({
|
|
1090
1138
|
provider: K,
|
|
1091
1139
|
root: t,
|
|
1092
1140
|
route: p.route,
|
|
1093
1141
|
params: p.params,
|
|
1094
1142
|
pathname: r,
|
|
1095
|
-
dirs:
|
|
1096
|
-
shellTemplate:
|
|
1143
|
+
dirs: W,
|
|
1144
|
+
shellTemplate: bt.get(p.route.pattern) ?? O,
|
|
1097
1145
|
requestHeaders: n,
|
|
1098
|
-
apiOrigin:
|
|
1099
|
-
apiName:
|
|
1100
|
-
middlewares:
|
|
1101
|
-
onCookieWarning:
|
|
1146
|
+
apiOrigin: P,
|
|
1147
|
+
apiName: F,
|
|
1148
|
+
middlewares: R,
|
|
1149
|
+
onCookieWarning: L,
|
|
1102
1150
|
requestUrl: e,
|
|
1103
1151
|
holesOnly: !0
|
|
1104
1152
|
});
|
|
1105
|
-
i !== null && "holes" in i ? await
|
|
1153
|
+
i !== null && "holes" in i ? await pe({
|
|
1106
1154
|
loader: i.holes.loader,
|
|
1107
1155
|
ctx: i.holes.ctx,
|
|
1108
1156
|
res: o,
|
|
@@ -1115,56 +1163,56 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1115
1163
|
}
|
|
1116
1164
|
})();
|
|
1117
1165
|
}
|
|
1118
|
-
}), x =
|
|
1119
|
-
if (x &&
|
|
1166
|
+
}), x = B.get(_), C = Date.now();
|
|
1167
|
+
if (x && He(x, C)) return h.emit("cache", {
|
|
1120
1168
|
kind: "HIT",
|
|
1121
1169
|
key: _,
|
|
1122
|
-
ageMs:
|
|
1170
|
+
ageMs: C - x.renderedAt
|
|
1123
1171
|
}), v ? y(x.html, {
|
|
1124
|
-
"cache-control":
|
|
1172
|
+
"cache-control": Xe(N, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1125
1173
|
"x-voltro-cache": "HIT",
|
|
1126
1174
|
"x-voltro-cache-key": _,
|
|
1127
|
-
"x-voltro-cache-age-ms": String(
|
|
1175
|
+
"x-voltro-cache-age-ms": String(C - x.renderedAt)
|
|
1128
1176
|
}) : {
|
|
1129
1177
|
status: 200,
|
|
1130
1178
|
headers: {
|
|
1131
1179
|
"content-type": "text/html; charset=utf-8",
|
|
1132
|
-
"cache-control":
|
|
1180
|
+
"cache-control": Xe(N, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1133
1181
|
"x-voltro-rendered-by": "isr",
|
|
1134
1182
|
"x-voltro-cache": "HIT",
|
|
1135
1183
|
"x-voltro-cache-key": _,
|
|
1136
|
-
"x-voltro-cache-age-ms": String(
|
|
1184
|
+
"x-voltro-cache-age-ms": String(C - x.renderedAt)
|
|
1137
1185
|
},
|
|
1138
1186
|
body: x.html
|
|
1139
1187
|
};
|
|
1140
|
-
if (x &&
|
|
1188
|
+
if (x && ze(x, C)) {
|
|
1141
1189
|
h.emit("cache", {
|
|
1142
1190
|
kind: "STALE",
|
|
1143
1191
|
key: _,
|
|
1144
|
-
ageMs:
|
|
1192
|
+
ageMs: C - x.renderedAt
|
|
1145
1193
|
});
|
|
1146
|
-
let i =
|
|
1194
|
+
let i = B.generation(_);
|
|
1147
1195
|
return (async () => {
|
|
1148
1196
|
try {
|
|
1149
|
-
let a = await
|
|
1197
|
+
let a = await Lt({
|
|
1150
1198
|
provider: K,
|
|
1151
1199
|
root: t,
|
|
1152
1200
|
route: p.route,
|
|
1153
1201
|
params: p.params,
|
|
1154
1202
|
pathname: r,
|
|
1155
|
-
dirs:
|
|
1156
|
-
shellTemplate:
|
|
1203
|
+
dirs: W,
|
|
1204
|
+
shellTemplate: bt.get(p.route.pattern) ?? O,
|
|
1157
1205
|
requestHeaders: n,
|
|
1158
|
-
apiOrigin:
|
|
1159
|
-
apiName:
|
|
1160
|
-
middlewares:
|
|
1161
|
-
onCookieWarning:
|
|
1206
|
+
apiOrigin: P,
|
|
1207
|
+
apiName: F,
|
|
1208
|
+
middlewares: R,
|
|
1209
|
+
onCookieWarning: L,
|
|
1162
1210
|
requestUrl: e,
|
|
1163
1211
|
buffered: !0
|
|
1164
1212
|
});
|
|
1165
1213
|
if (a && "html" in a && a.renderMode === "isr" && a.revalidateMs !== null) {
|
|
1166
1214
|
let e = q.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
|
|
1167
|
-
|
|
1215
|
+
B.set(_, {
|
|
1168
1216
|
html: a.html,
|
|
1169
1217
|
renderedAt: t,
|
|
1170
1218
|
expiresAt: t + a.revalidateMs,
|
|
@@ -1177,37 +1225,37 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1177
1225
|
Y.warn("background SWR refresh failed", { url: r }, e);
|
|
1178
1226
|
}
|
|
1179
1227
|
})(), v ? y(x.html, {
|
|
1180
|
-
"cache-control":
|
|
1228
|
+
"cache-control": Xe(N, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1181
1229
|
"x-voltro-cache": "STALE",
|
|
1182
1230
|
"x-voltro-cache-key": _,
|
|
1183
|
-
"x-voltro-cache-age-ms": String(
|
|
1231
|
+
"x-voltro-cache-age-ms": String(C - x.renderedAt)
|
|
1184
1232
|
}) : {
|
|
1185
1233
|
status: 200,
|
|
1186
1234
|
headers: {
|
|
1187
1235
|
"content-type": "text/html; charset=utf-8",
|
|
1188
|
-
"cache-control":
|
|
1236
|
+
"cache-control": Xe(N, x.revalidateMs, x.staleWhileRevalidateMs),
|
|
1189
1237
|
"x-voltro-rendered-by": "isr",
|
|
1190
1238
|
"x-voltro-cache": "STALE",
|
|
1191
1239
|
"x-voltro-cache-key": _,
|
|
1192
|
-
"x-voltro-cache-age-ms": String(
|
|
1240
|
+
"x-voltro-cache-age-ms": String(C - x.renderedAt)
|
|
1193
1241
|
},
|
|
1194
1242
|
body: x.html
|
|
1195
1243
|
};
|
|
1196
1244
|
}
|
|
1197
1245
|
try {
|
|
1198
|
-
let i =
|
|
1246
|
+
let i = B.generation(_), a = await Lt({
|
|
1199
1247
|
provider: K,
|
|
1200
1248
|
root: t,
|
|
1201
1249
|
route: p.route,
|
|
1202
1250
|
params: p.params,
|
|
1203
1251
|
pathname: r,
|
|
1204
|
-
dirs:
|
|
1205
|
-
shellTemplate:
|
|
1252
|
+
dirs: W,
|
|
1253
|
+
shellTemplate: bt.get(p.route.pattern) ?? O,
|
|
1206
1254
|
requestHeaders: n,
|
|
1207
|
-
apiOrigin:
|
|
1208
|
-
apiName:
|
|
1209
|
-
middlewares:
|
|
1210
|
-
onCookieWarning:
|
|
1255
|
+
apiOrigin: P,
|
|
1256
|
+
apiName: F,
|
|
1257
|
+
middlewares: R,
|
|
1258
|
+
onCookieWarning: L,
|
|
1211
1259
|
requestUrl: e
|
|
1212
1260
|
});
|
|
1213
1261
|
if (!a) return {
|
|
@@ -1216,7 +1264,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1216
1264
|
"content-type": "text/html; charset=utf-8",
|
|
1217
1265
|
"x-voltro-rendered-by": "spa-fallback"
|
|
1218
1266
|
},
|
|
1219
|
-
body:
|
|
1267
|
+
body: O
|
|
1220
1268
|
};
|
|
1221
1269
|
let o = a.setCookies ?? [], s = a.responseHeaders ?? {}, c = (e) => ({
|
|
1222
1270
|
...s,
|
|
@@ -1251,7 +1299,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1251
1299
|
});
|
|
1252
1300
|
if (a.renderMode === "isr" && a.revalidateMs !== null) {
|
|
1253
1301
|
let e = Date.now(), t = q.get(p.route.pattern)?.staleWhileRevalidateMs ?? 0;
|
|
1254
|
-
|
|
1302
|
+
B.set(_, {
|
|
1255
1303
|
html: a.html,
|
|
1256
1304
|
renderedAt: e,
|
|
1257
1305
|
expiresAt: e + a.revalidateMs,
|
|
@@ -1277,7 +1325,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1277
1325
|
body: a.html
|
|
1278
1326
|
};
|
|
1279
1327
|
} catch (e) {
|
|
1280
|
-
return Y.error("render error", { url: r }, e),
|
|
1328
|
+
return Y.error("render error", { url: r }, e), Bt?.(e, {
|
|
1329
|
+
stage: "render",
|
|
1330
|
+
pathname: r
|
|
1331
|
+
}), S(e) ? {
|
|
1281
1332
|
status: 500,
|
|
1282
1333
|
headers: {
|
|
1283
1334
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -1297,16 +1348,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1297
1348
|
body: "server error"
|
|
1298
1349
|
};
|
|
1299
1350
|
}
|
|
1300
|
-
},
|
|
1301
|
-
apiName:
|
|
1302
|
-
apiOrigin:
|
|
1351
|
+
}, qt = !1, Jt = i(f.health, () => qt), Yt = p({
|
|
1352
|
+
apiName: F,
|
|
1353
|
+
apiOrigin: P,
|
|
1303
1354
|
loadDescriptors: async () => {
|
|
1304
|
-
if (
|
|
1305
|
-
let e = (await K.getHelpers()).apiDescriptors?.[
|
|
1355
|
+
if (F === void 0) return;
|
|
1356
|
+
let e = (await K.getHelpers()).apiDescriptors?.[F];
|
|
1306
1357
|
return e === void 0 ? void 0 : await e();
|
|
1307
1358
|
},
|
|
1308
|
-
rpcQuery: (e, t) =>
|
|
1309
|
-
apiName:
|
|
1359
|
+
rpcQuery: (e, t) => be(P, e, {
|
|
1360
|
+
apiName: F,
|
|
1310
1361
|
headers: t
|
|
1311
1362
|
}),
|
|
1312
1363
|
resolveLocale: async (e, t) => {
|
|
@@ -1314,42 +1365,42 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1314
1365
|
return r === void 0 ? n.i18n?.resolve(e.cookie, e["accept-language"])?.locale ?? "en" : r;
|
|
1315
1366
|
},
|
|
1316
1367
|
renderErrorPage: async ({ path: e, headers: n, flash: r }) => {
|
|
1317
|
-
let { pathname: i } =
|
|
1368
|
+
let { pathname: i } = ye(e), a = Pt(i, G);
|
|
1318
1369
|
if (!a) return;
|
|
1319
|
-
let o = await
|
|
1370
|
+
let o = await Lt({
|
|
1320
1371
|
provider: K,
|
|
1321
1372
|
root: t,
|
|
1322
1373
|
route: a.route,
|
|
1323
1374
|
params: a.params,
|
|
1324
1375
|
pathname: i,
|
|
1325
|
-
dirs:
|
|
1326
|
-
shellTemplate:
|
|
1376
|
+
dirs: W,
|
|
1377
|
+
shellTemplate: O,
|
|
1327
1378
|
requestHeaders: n,
|
|
1328
|
-
apiOrigin:
|
|
1329
|
-
apiName:
|
|
1330
|
-
middlewares:
|
|
1331
|
-
onCookieWarning:
|
|
1379
|
+
apiOrigin: P,
|
|
1380
|
+
apiName: F,
|
|
1381
|
+
middlewares: R,
|
|
1382
|
+
onCookieWarning: L,
|
|
1332
1383
|
requestUrl: e,
|
|
1333
1384
|
formFlash: r,
|
|
1334
1385
|
buffered: !0
|
|
1335
1386
|
});
|
|
1336
1387
|
return o !== null && "html" in o ? o.html : void 0;
|
|
1337
1388
|
}
|
|
1338
|
-
}),
|
|
1389
|
+
}), Xt = at(f), Zt = ut(async (e, t) => {
|
|
1339
1390
|
let n = e.url ?? "/", i = Date.now(), a = {};
|
|
1340
1391
|
for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (a[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
|
|
1341
|
-
let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase(), c =
|
|
1392
|
+
let o = n.split("?")[0] ?? "/", s = (e.method ?? "GET").toUpperCase(), c = me(Jt, o);
|
|
1342
1393
|
if (c !== void 0) {
|
|
1343
|
-
let e = await y(
|
|
1394
|
+
let e = await y(Jt, c);
|
|
1344
1395
|
t.writeHead(e.status, {
|
|
1345
1396
|
"content-type": "text/plain",
|
|
1346
1397
|
"cache-control": "no-store"
|
|
1347
1398
|
}), t.end(e.body);
|
|
1348
1399
|
return;
|
|
1349
1400
|
}
|
|
1350
|
-
if (!(o.startsWith(x) && await
|
|
1401
|
+
if (!(o.startsWith(x) && await Yt(e, t))) {
|
|
1351
1402
|
if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
|
|
1352
|
-
let e =
|
|
1403
|
+
let e = De(a.origin);
|
|
1353
1404
|
t.writeHead(204, e), t.end();
|
|
1354
1405
|
return;
|
|
1355
1406
|
}
|
|
@@ -1359,13 +1410,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1359
1410
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
1360
1411
|
return;
|
|
1361
1412
|
}
|
|
1362
|
-
if (!
|
|
1413
|
+
if (!I(r)) {
|
|
1363
1414
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
1364
1415
|
return;
|
|
1365
1416
|
}
|
|
1366
1417
|
try {
|
|
1367
1418
|
let n = { accept: a.accept ?? "application/json" }, i = a.authorization;
|
|
1368
|
-
i ? n.authorization = Array.isArray(i) ? i[0] : i :
|
|
1419
|
+
i ? n.authorization = Array.isArray(i) ? i[0] : i : Ee(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
|
|
1369
1420
|
let o;
|
|
1370
1421
|
if (s && s !== "GET" && s !== "HEAD") {
|
|
1371
1422
|
let t = [];
|
|
@@ -1395,14 +1446,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1395
1446
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
1396
1447
|
return;
|
|
1397
1448
|
}
|
|
1398
|
-
if (!
|
|
1449
|
+
if (!I(r)) {
|
|
1399
1450
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
1400
1451
|
return;
|
|
1401
1452
|
}
|
|
1402
1453
|
let i = new AbortController();
|
|
1403
1454
|
e.on("close", () => i.abort()), t.on("close", () => i.abort());
|
|
1404
1455
|
try {
|
|
1405
|
-
let e =
|
|
1456
|
+
let e = Te(a, r), n = await fetch(r, {
|
|
1406
1457
|
redirect: "manual",
|
|
1407
1458
|
method: "GET",
|
|
1408
1459
|
headers: {
|
|
@@ -1437,15 +1488,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1437
1488
|
return;
|
|
1438
1489
|
}
|
|
1439
1490
|
if (o === "/_voltro/inspect/stream") {
|
|
1440
|
-
let n =
|
|
1441
|
-
if (
|
|
1491
|
+
let n = De(a.origin);
|
|
1492
|
+
if (ke()) {
|
|
1442
1493
|
t.writeHead(503, {
|
|
1443
1494
|
"content-type": "application/json",
|
|
1444
1495
|
...n
|
|
1445
1496
|
}), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
|
|
1446
1497
|
return;
|
|
1447
1498
|
}
|
|
1448
|
-
let i =
|
|
1499
|
+
let i = Ae(a, "GET");
|
|
1449
1500
|
if (!i.ok) {
|
|
1450
1501
|
t.writeHead(401, {
|
|
1451
1502
|
"content-type": "application/json",
|
|
@@ -1467,7 +1518,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1467
1518
|
let o = h.subscribe((e) => {
|
|
1468
1519
|
t.write(r(e));
|
|
1469
1520
|
}), s = setInterval(() => {
|
|
1470
|
-
t.write(
|
|
1521
|
+
t.write(Se());
|
|
1471
1522
|
}, 15e3), c = () => {
|
|
1472
1523
|
clearInterval(s), o();
|
|
1473
1524
|
};
|
|
@@ -1475,14 +1526,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1475
1526
|
return;
|
|
1476
1527
|
}
|
|
1477
1528
|
try {
|
|
1478
|
-
let e = await
|
|
1529
|
+
let e = await Kt(n, a);
|
|
1479
1530
|
if (e.stream ? e.stream(t) : ht({
|
|
1480
1531
|
response: t,
|
|
1481
1532
|
status: e.status,
|
|
1482
1533
|
headers: e.headers,
|
|
1483
1534
|
body: e.body,
|
|
1484
1535
|
requestHeaders: a,
|
|
1485
|
-
compression:
|
|
1536
|
+
compression: _e.compression
|
|
1486
1537
|
}) || (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
|
|
1487
1538
|
let t = Date.now() - i;
|
|
1488
1539
|
h.emit("request", {
|
|
@@ -1492,8 +1543,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1492
1543
|
renderedBy: e.headers["x-voltro-rendered-by"],
|
|
1493
1544
|
cache: e.headers["x-voltro-cache"]
|
|
1494
1545
|
});
|
|
1495
|
-
let n =
|
|
1496
|
-
|
|
1546
|
+
let n = Pt(o, G)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
|
|
1547
|
+
Vt.record({
|
|
1497
1548
|
kind: "request",
|
|
1498
1549
|
tag: n,
|
|
1499
1550
|
durationMs: t,
|
|
@@ -1505,77 +1556,77 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1505
1556
|
}
|
|
1506
1557
|
}
|
|
1507
1558
|
});
|
|
1508
|
-
await new Promise((e) =>
|
|
1559
|
+
await new Promise((e) => Zt.listen(_, "::", e)), qt = !0, n.mark("ready"), rt(Zt, Xt), Y.info(`listening on http://localhost:${_}`, {
|
|
1509
1560
|
port: _,
|
|
1510
1561
|
distDir: b
|
|
1511
1562
|
}), Y.debug("dynamic + ssr/isr routes resolve via SSR loader");
|
|
1512
1563
|
try {
|
|
1513
|
-
await
|
|
1514
|
-
id:
|
|
1515
|
-
name:
|
|
1564
|
+
await Ue({
|
|
1565
|
+
id: E,
|
|
1566
|
+
name: T,
|
|
1516
1567
|
kind: "web",
|
|
1517
1568
|
url: `http://localhost:${_}`,
|
|
1518
1569
|
pid: process.pid,
|
|
1519
1570
|
status: "live",
|
|
1520
|
-
logFile:
|
|
1571
|
+
logFile: D.path
|
|
1521
1572
|
});
|
|
1522
|
-
let e =
|
|
1573
|
+
let e = xe(t);
|
|
1523
1574
|
if (e) {
|
|
1524
|
-
let t = await
|
|
1575
|
+
let t = await ve({ dashboardAppPath: e });
|
|
1525
1576
|
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 });
|
|
1526
1577
|
}
|
|
1527
1578
|
setInterval(() => {
|
|
1528
|
-
|
|
1529
|
-
id:
|
|
1530
|
-
name:
|
|
1579
|
+
Ue({
|
|
1580
|
+
id: E,
|
|
1581
|
+
name: T,
|
|
1531
1582
|
kind: "web",
|
|
1532
1583
|
url: `http://localhost:${_}`,
|
|
1533
1584
|
pid: process.pid,
|
|
1534
1585
|
status: "live",
|
|
1535
|
-
logFile:
|
|
1586
|
+
logFile: D.path
|
|
1536
1587
|
}).catch(() => {});
|
|
1537
1588
|
}, 1e4).unref();
|
|
1538
1589
|
} catch (e) {
|
|
1539
1590
|
Y.warn("runtime-registry write failed", {}, e);
|
|
1540
1591
|
}
|
|
1541
|
-
|
|
1592
|
+
$e({
|
|
1542
1593
|
app: f.name ?? "unnamed",
|
|
1543
1594
|
kind: "web",
|
|
1544
1595
|
url: `http://localhost:${_}`,
|
|
1545
1596
|
bootMs: n.total()
|
|
1546
1597
|
});
|
|
1547
|
-
let
|
|
1598
|
+
let Qt = n.phaseBreakdown();
|
|
1548
1599
|
Y.info(`start: ready in ${n.total()}ms`, {
|
|
1549
1600
|
bootMs: n.total(),
|
|
1550
|
-
...
|
|
1601
|
+
...Qt ? { phases: Qt } : {}
|
|
1551
1602
|
});
|
|
1552
|
-
let
|
|
1553
|
-
if (
|
|
1554
|
-
if (
|
|
1555
|
-
|
|
1603
|
+
let $t = !1, en = (e) => async () => {
|
|
1604
|
+
if (!$t) {
|
|
1605
|
+
if ($t = !0, Y.info(`received ${e}, shutting down`, { signal: e }), Zt.close(), await Ft.stop(), Q) try {
|
|
1606
|
+
Q();
|
|
1556
1607
|
} catch {}
|
|
1557
|
-
if (
|
|
1558
|
-
await
|
|
1608
|
+
if ($) try {
|
|
1609
|
+
await st.runPromise($.close());
|
|
1559
1610
|
} catch {}
|
|
1560
|
-
if (
|
|
1561
|
-
await
|
|
1611
|
+
if (H) try {
|
|
1612
|
+
await H.end();
|
|
1562
1613
|
} catch {}
|
|
1563
|
-
await K.close(), await
|
|
1614
|
+
await K.close(), await Ge(E), await D.dispose(), process.exit(0);
|
|
1564
1615
|
}
|
|
1565
1616
|
};
|
|
1566
|
-
process.on("SIGINT",
|
|
1567
|
-
let
|
|
1568
|
-
if (
|
|
1617
|
+
process.on("SIGINT", en("SIGINT")), process.on("SIGTERM", en("SIGTERM"));
|
|
1618
|
+
let tn = process.ppid;
|
|
1619
|
+
if (tn > 1) {
|
|
1569
1620
|
let e = setInterval(() => {
|
|
1570
|
-
(process.ppid !==
|
|
1621
|
+
(process.ppid !== tn || process.ppid === 1) && (clearInterval(e), en("SIGTERM")());
|
|
1571
1622
|
}, 2e3);
|
|
1572
1623
|
e.unref();
|
|
1573
1624
|
}
|
|
1574
1625
|
return new Promise(() => {});
|
|
1575
|
-
},
|
|
1576
|
-
|
|
1577
|
-
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await
|
|
1626
|
+
}, Vt = async (e) => {
|
|
1627
|
+
nt("start"), t("start");
|
|
1628
|
+
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await $(B(n));
|
|
1578
1629
|
return r.ran ? r.exitCode : (Y.error("no web app found at this path"), 1);
|
|
1579
1630
|
};
|
|
1580
1631
|
//#endregion
|
|
1581
|
-
export {
|
|
1632
|
+
export { $ as n, Vt as t };
|