@voltro/cli 0.40.0 → 0.41.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 +74 -0
- package/dist/{apiBuild-C8xBEYbL.js → apiBuild-B_iH24qf.js} +2 -2
- package/dist/apiBuild-RM5W5YXk.js +2 -0
- package/dist/bin.js +1 -1
- package/dist/{build-CkhFGnKA.js → build-DUdi6F_Q.js} +150 -150
- package/dist/{checkCommand-QbHshOac.js → checkCommand-B2RWrpWi.js} +1 -1
- package/dist/{checkCommand-BcXJa2IS.js → checkCommand-DWL2_PPR.js} +2 -2
- package/dist/{codegenCommand-DF2OJh3O.js → codegenCommand-DkjoJ30Q.js} +2 -2
- package/dist/{codemodRunner-BcOvi4A2.js → codemodRunner-sFuWDETH.js} +520 -460
- package/dist/{commands-7Z7-HOE3.js → commands-D0VR1yBB.js} +22 -22
- package/dist/{dashboardCommand-CUycH6dR.js → dashboardCommand-Bro7Jwts.js} +5 -5
- package/dist/{dataCommand-By78lscK.js → dataCommand-OKC5FscP.js} +183 -172
- package/dist/{dbCommand-DSwGv9wS.js → dbCommand-BHRamDsy.js} +441 -414
- package/dist/dbCommand-C9iE1pd9.js +2 -0
- package/dist/{dev-Dh1NuYx1.js → dev-D4l_YOzI.js} +22 -22
- package/dist/{dev-D8JSKlBM.js → dev-DuqBJC7g.js} +1 -1
- package/dist/doctorCommand-Bw3V4L1j.js +2 -0
- package/dist/{doctorCommand-C-8-Z9D6.js → doctorCommand-TmZTAepc.js} +385 -279
- package/dist/{dormancyCommand-A79Odglm.js → dormancyCommand-CUKhRmGG.js} +1 -1
- package/dist/{embeddingsCommand-CoiyHfkY.js → embeddingsCommand-Db-iQM3l.js} +1 -1
- package/dist/{envCommand-B6d0s-jZ.js → envCommand-DQ_URZq9.js} +12 -12
- package/dist/{evolveCommand-BC5a9lxX.js → evolveCommand-CghRPrGO.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-ZqSVzJZ4.js → infoCommand-BCs_ZFnl.js} +1 -1
- package/dist/{migrate-BnPw2zC8.js → migrate-DLtPv2_D.js} +1 -1
- package/dist/{runtimeTrace-BslKJjDY.js → runtimeTrace-jFKvOPBz.js} +1 -1
- package/dist/{sdkgen-DQ8uEmmn.js → sdkgen-COQqHB9V.js} +1 -1
- package/dist/{serveCommand-Dqb9Ku1-.js → serveCommand-Cba_M2Su.js} +3 -3
- package/dist/serveCommand-DRbYK646.js +2 -0
- package/dist/serveEntry.js +1 -1
- package/dist/{start-dkNYKtgQ.js → start-BjcuFME_.js} +379 -343
- package/dist/{start-BA7txHhY.js → start-fifc0xpW.js} +1 -1
- package/dist/startEntry.js +1 -1
- package/dist/updateCommand-B2alql9k.js +2 -0
- package/dist/{updateCommand-eoGpZr3E.js → updateCommand-HZQVBU3T.js} +1 -1
- package/dist/webDev-D6QeXw3P.js +2 -0
- package/dist/{webDev-bybjZA0o.js → webDev-Dk8lFUzf.js} +642 -525
- package/dist/{webhooksCommand-DubZWNOx.js → webhooksCommand-D7ZpH7w0.js} +1 -1
- package/package.json +23 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/_manifest.json +1 -1
- package/templates/agent-docs/cli.md +6 -0
- package/templates/agent-docs/plugins/governance.md +8 -0
- package/templates/agent-docs/routing.md +141 -28
- package/templates/agent-docs/security.md +24 -0
- package/templates/agent-docs/whats-new.md +37 -121
- package/templates/apps/api-ai/package.json +7 -7
- 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 +10 -10
- 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-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-versioning/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +9 -9
- package/templates/apps/frontend-auth/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-cms/package.json +9 -9
- package/templates/apps/frontend-collab/package.json +10 -10
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +7 -7
- 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 +8 -8
- package/templates/apps/frontend-saas/package.json +8 -8
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/templates/apps/frontend-status/package.json +8 -8
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/apiBuild-BIyGkym8.js +0 -2
- package/dist/dbCommand-DcqEyxju.js +0 -2
- package/dist/doctorCommand-FhQ7EVYL.js +0 -2
- package/dist/serveCommand-BmvEQCMS.js +0 -2
- package/dist/updateCommand-BauSVxPp.js +0 -2
- package/dist/webDev-CBbKs4dZ.js +0 -2
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { i as e, t } from "./nodeEnvironment-cGFAj1J8.js";
|
|
2
2
|
import { r as n } from "./appPort-B_HpJ_ck.js";
|
|
3
|
-
import { A as r,
|
|
4
|
-
import { o as
|
|
5
|
-
import { A as
|
|
6
|
-
import { a as
|
|
7
|
-
import { i as
|
|
8
|
-
import { n as
|
|
9
|
-
import { t as
|
|
10
|
-
import { t as
|
|
11
|
-
import { dirname as
|
|
12
|
-
import { promises as
|
|
13
|
-
import { fileURLToPath as
|
|
14
|
-
import { createLogger as
|
|
15
|
-
import { snapshotMetricsSync as
|
|
16
|
-
import { createServer as
|
|
3
|
+
import { A as r, C as i, D as a, E as o, F as s, H as c, I as l, J as ee, L as u, M as d, N as f, O as te, P as p, R as m, S as h, T as ne, V as g, W as re, X as _, Y as v, Z as y, a as b, b as x, d as S, f as C, ht as w, i as ie, j as T, k as E, n as D, nt as O, q as k, s as ae, tt as A, vt as j, x as oe, y as M, z as se } from "./webDev-Dk8lFUzf.js";
|
|
4
|
+
import { o as N, t as P } from "./connectionConfig-Bk9IC7D0.js";
|
|
5
|
+
import { A as F, D as I, a as ce, h as le, j as ue, k as de } from "./inspect-B7U7Cl_Z.js";
|
|
6
|
+
import { a as fe, c as L, d as pe, f as R, l as me, p as he, u as ge } from "./renderModeScan-D7J1B7Kw.js";
|
|
7
|
+
import { i as _e, n as ve, r as ye, t as be } from "./runtimeRegistry-DMeKfTHP.js";
|
|
8
|
+
import { n as xe } from "./logFileSink-B4uP8pvf.js";
|
|
9
|
+
import { t as Se } from "./inspectMetrics-CfdKLh6t.js";
|
|
10
|
+
import { t as Ce } from "./bootTiming-BdyP9nYw.js";
|
|
11
|
+
import { dirname as we, extname as Te, join as z, resolve as Ee } from "node:path";
|
|
12
|
+
import { promises as B } from "node:fs";
|
|
13
|
+
import { fileURLToPath as V, pathToFileURL as H } from "node:url";
|
|
14
|
+
import { createLogger as U, printReadyBlock as De } from "@voltro/logger";
|
|
15
|
+
import { snapshotMetricsSync as Oe } from "@voltro/runtime";
|
|
16
|
+
import { createServer as ke } from "node:http";
|
|
17
17
|
//#region src/isrCdcInvalidator.ts
|
|
18
|
-
var
|
|
18
|
+
var W = U({ scope: "voltro:start:cdc" }), Ae = (e) => (t) => {
|
|
19
19
|
let n = 0;
|
|
20
20
|
for (let [r, i] of e.tableSubscriptionsByPattern) {
|
|
21
21
|
if (!i.includes(t)) continue;
|
|
@@ -26,17 +26,17 @@ var U = H({ scope: "voltro:start:cdc" }), W = (e) => (t) => {
|
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
28
28
|
return n;
|
|
29
|
-
}, G = () =>
|
|
30
|
-
let t = e.channel ?? "framework_changes", n =
|
|
29
|
+
}, G = () => P() ? N() : null, je = (e) => {
|
|
30
|
+
let t = e.channel ?? "framework_changes", n = Ae(e), r = null, i = null;
|
|
31
31
|
return {
|
|
32
32
|
start: async () => {
|
|
33
33
|
if (e.tableSubscriptionsByPattern.size === 0) {
|
|
34
|
-
|
|
34
|
+
W.debug("skipped — no pages declare cacheInvalidatesOn");
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
let a = G();
|
|
38
38
|
if (!a) {
|
|
39
|
-
|
|
39
|
+
W.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()] });
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
r = new (await (import("pg"))).default.Client(a), await r.connect(), i = (e) => {
|
|
@@ -45,16 +45,16 @@ var U = H({ scope: "voltro:start:cdc" }), W = (e) => (t) => {
|
|
|
45
45
|
try {
|
|
46
46
|
r = JSON.parse(e.payload);
|
|
47
47
|
} catch (e) {
|
|
48
|
-
|
|
48
|
+
W.warn("bad CDC payload", {}, e);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
let i = n(r.table);
|
|
52
|
-
i > 0 &&
|
|
52
|
+
i > 0 && W.info(`${r.op} on '${r.table}' → dropped ${i} cache entries`, {
|
|
53
53
|
op: r.op,
|
|
54
54
|
table: r.table,
|
|
55
55
|
dropped: i
|
|
56
56
|
});
|
|
57
|
-
}, r.on("notification", i), await r.query(`LISTEN ${t}`),
|
|
57
|
+
}, r.on("notification", i), await r.query(`LISTEN ${t}`), W.info(`LISTEN ${t}`, {
|
|
58
58
|
channel: t,
|
|
59
59
|
..."connectionString" in a ? { target: a.connectionString.replace(/\/\/[^@/]*@/, "//") } : {
|
|
60
60
|
host: a.host,
|
|
@@ -72,7 +72,7 @@ var U = H({ scope: "voltro:start:cdc" }), W = (e) => (t) => {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
-
}, K =
|
|
75
|
+
}, K = U({ scope: "voltro:start:isr-cache" }), q = "voltro_isr_cache", J = (e) => `
|
|
76
76
|
CREATE TABLE IF NOT EXISTS ${e} (
|
|
77
77
|
cache_key TEXT PRIMARY KEY,
|
|
78
78
|
html TEXT NOT NULL,
|
|
@@ -83,9 +83,9 @@ CREATE TABLE IF NOT EXISTS ${e} (
|
|
|
83
83
|
stale_while_revalidate_ms BIGINT NOT NULL DEFAULT 0
|
|
84
84
|
);
|
|
85
85
|
CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
86
|
-
`,
|
|
86
|
+
`, Me = (e) => {
|
|
87
87
|
let t = e.tableName ?? q, { client: n } = e, r = /* @__PURE__ */ new Map(), i = !1, a = (async () => {
|
|
88
|
-
i || (i = !0, await n.query(
|
|
88
|
+
i || (i = !0, await n.query(J(t)));
|
|
89
89
|
})().then(async () => {
|
|
90
90
|
let e = await n.query(`SELECT * FROM ${t}`);
|
|
91
91
|
for (let t of e.rows) r.set(t.cache_key, {
|
|
@@ -145,14 +145,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
145
145
|
return Array.from(r.entries());
|
|
146
146
|
}
|
|
147
147
|
};
|
|
148
|
-
},
|
|
148
|
+
}, Y = U({ scope: "voltro:start" }), Ne = await (async () => {
|
|
149
149
|
try {
|
|
150
|
-
let e = z(
|
|
150
|
+
let e = z(we(V(import.meta.url)), "..", "package.json"), t = await B.readFile(e, "utf8");
|
|
151
151
|
return JSON.parse(t).version ?? "0.0.0";
|
|
152
152
|
} catch {
|
|
153
153
|
return "0.0.0";
|
|
154
154
|
}
|
|
155
|
-
})(),
|
|
155
|
+
})(), Pe = (e) => e instanceof Error && e._voltroControl === "redirect" && typeof e.location == "string", X = (e) => e instanceof Error && e._voltroControl === "not-found", Fe = {
|
|
156
156
|
".html": "text/html; charset=utf-8",
|
|
157
157
|
".js": "application/javascript",
|
|
158
158
|
".mjs": "application/javascript",
|
|
@@ -170,13 +170,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
170
170
|
".woff": "font/woff",
|
|
171
171
|
".woff2": "font/woff2",
|
|
172
172
|
".txt": "text/plain; charset=utf-8"
|
|
173
|
-
},
|
|
173
|
+
}, Ie = (e) => Fe[Te(e).toLowerCase()] ?? "application/octet-stream", Z = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), Q = async (e) => {
|
|
174
174
|
try {
|
|
175
|
-
return await
|
|
175
|
+
return await B.stat(e), !0;
|
|
176
176
|
} catch {
|
|
177
177
|
return !1;
|
|
178
178
|
}
|
|
179
|
-
},
|
|
179
|
+
}, Le = (e) => {
|
|
180
180
|
let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
|
|
181
181
|
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, "\\$&"));
|
|
182
182
|
let a = i.join("/");
|
|
@@ -185,8 +185,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
185
185
|
paramNames: t,
|
|
186
186
|
priority: n
|
|
187
187
|
};
|
|
188
|
-
},
|
|
189
|
-
let { regex: t, paramNames: n, priority: r } =
|
|
188
|
+
}, Re = (e) => e.map((e) => {
|
|
189
|
+
let { regex: t, paramNames: n, priority: r } = Le(e.pattern);
|
|
190
190
|
return {
|
|
191
191
|
pattern: e.pattern,
|
|
192
192
|
file: e.file,
|
|
@@ -195,7 +195,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
195
195
|
paramNames: n,
|
|
196
196
|
priority: r
|
|
197
197
|
};
|
|
198
|
-
}).slice().sort((e, t) => e.priority - t.priority),
|
|
198
|
+
}).slice().sort((e, t) => e.priority - t.priority), ze = (e, t) => {
|
|
199
199
|
for (let n of t) {
|
|
200
200
|
let t = n.regex.exec(e);
|
|
201
201
|
if (!t) continue;
|
|
@@ -207,64 +207,68 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
return null;
|
|
210
|
-
},
|
|
211
|
-
let { provider: t, route: n, params: i, pathname: c, dirs:
|
|
210
|
+
}, Be = async (e) => {
|
|
211
|
+
let { provider: t, route: n, params: i, pathname: c, dirs: ee, shellTemplate: f, requestHeaders: te, requestUrl: g = "", apiOrigin: re, apiName: _ } = e, { search: v } = m(g), y = await o(a(e.middlewares ?? [], {
|
|
212
|
+
route: n.pattern,
|
|
213
|
+
pathname: c
|
|
214
|
+
}), {
|
|
212
215
|
pathname: c,
|
|
213
|
-
search:
|
|
214
|
-
headers:
|
|
215
|
-
cookies:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
search: v,
|
|
217
|
+
headers: te,
|
|
218
|
+
cookies: ne(te.cookie),
|
|
219
|
+
route: n.pattern
|
|
220
|
+
}, e.onCookieWarning), x = y.headers, S = ie(re, x.cookie, {
|
|
221
|
+
apiName: _,
|
|
222
|
+
headers: x
|
|
223
|
+
}), C = await t.getPage(n.pattern, n.file), w = L(C, n.file), D = w === "spa" && ae(ee, n.dirChain).some((e) => e.hasLayout);
|
|
224
|
+
if (w !== "ssr" && w !== "isr" && !D) return null;
|
|
225
|
+
let O = ae(ee, n.dirChain), k = {}, A = null, j, oe = new AbortController();
|
|
222
226
|
try {
|
|
223
|
-
(await t.getHelpers()).beginStoreSeeds(), {chain:
|
|
224
|
-
entries:
|
|
227
|
+
(await t.getHelpers()).beginStoreSeeds(), {chain: j, segmentLoaderData: k} = await b({
|
|
228
|
+
entries: O,
|
|
225
229
|
loadLayout: (e) => t.getLayout(e.dir),
|
|
226
230
|
loadError: (e) => t.getError(e.dir),
|
|
227
231
|
loadPending: (e) => t.getPending(e.dir),
|
|
228
232
|
ctx: {
|
|
229
233
|
params: i,
|
|
230
234
|
pathname: c,
|
|
231
|
-
search:
|
|
235
|
+
search: v,
|
|
232
236
|
signal: oe.signal,
|
|
233
|
-
headers:
|
|
234
|
-
query:
|
|
237
|
+
headers: x,
|
|
238
|
+
query: S,
|
|
235
239
|
isServer: !0
|
|
236
240
|
}
|
|
237
|
-
}), typeof
|
|
241
|
+
}), typeof C.loader == "function" && !D && (A = await C.loader({
|
|
238
242
|
params: i,
|
|
239
243
|
pathname: c,
|
|
240
|
-
search:
|
|
244
|
+
search: v,
|
|
241
245
|
signal: oe.signal,
|
|
242
|
-
headers:
|
|
243
|
-
query:
|
|
246
|
+
headers: x,
|
|
247
|
+
query: S,
|
|
244
248
|
isServer: !0
|
|
245
249
|
}));
|
|
246
250
|
} catch (e) {
|
|
247
|
-
if (
|
|
251
|
+
if (Pe(e)) return {
|
|
248
252
|
control: "redirect",
|
|
249
253
|
status: e.status,
|
|
250
254
|
location: e.location,
|
|
251
|
-
setCookies:
|
|
255
|
+
setCookies: y.setCookies
|
|
252
256
|
};
|
|
253
257
|
if (X(e)) return {
|
|
254
258
|
control: "not-found",
|
|
255
|
-
setCookies:
|
|
259
|
+
setCookies: y.setCookies
|
|
256
260
|
};
|
|
257
261
|
throw e;
|
|
258
262
|
}
|
|
259
|
-
let
|
|
260
|
-
|
|
261
|
-
pageMod:
|
|
263
|
+
let M = await t.getHelpers();
|
|
264
|
+
D || await E({
|
|
265
|
+
pageMod: C,
|
|
262
266
|
params: i,
|
|
263
|
-
query:
|
|
264
|
-
apiName:
|
|
265
|
-
seed:
|
|
266
|
-
seedFailure:
|
|
267
|
-
onError: ({ tag: e, apiName: t }, n) =>
|
|
267
|
+
query: S,
|
|
268
|
+
apiName: _,
|
|
269
|
+
seed: M.seedPreloadedSubscription,
|
|
270
|
+
seedFailure: M.seedPreloadedSubscriptionFailure,
|
|
271
|
+
onError: ({ tag: e, apiName: t }, n) => Y.warn("preload seed failed", {
|
|
268
272
|
tag: e,
|
|
269
273
|
apiName: t,
|
|
270
274
|
pathname: c
|
|
@@ -272,139 +276,141 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
272
276
|
});
|
|
273
277
|
let se = {
|
|
274
278
|
pattern: n.pattern,
|
|
275
|
-
Component:
|
|
276
|
-
meta:
|
|
277
|
-
loader:
|
|
278
|
-
ErrorBoundary:
|
|
279
|
-
Pending:
|
|
280
|
-
renderMode:
|
|
281
|
-
chain:
|
|
282
|
-
},
|
|
283
|
-
cookies:
|
|
284
|
-
headers:
|
|
279
|
+
Component: C.default,
|
|
280
|
+
meta: C.meta,
|
|
281
|
+
loader: C.loader,
|
|
282
|
+
ErrorBoundary: C.ErrorBoundary,
|
|
283
|
+
Pending: C.Pending,
|
|
284
|
+
renderMode: w,
|
|
285
|
+
chain: j
|
|
286
|
+
}, N = {
|
|
287
|
+
cookies: y.cookies,
|
|
288
|
+
headers: x,
|
|
285
289
|
url: g
|
|
286
|
-
},
|
|
287
|
-
if (
|
|
288
|
-
let e =
|
|
289
|
-
helpers:
|
|
290
|
+
}, P = M.i18n?.resolve(x.cookie, x["accept-language"]), F = C.interactive ?? "full";
|
|
291
|
+
if (D) {
|
|
292
|
+
let e = s({
|
|
293
|
+
helpers: M,
|
|
290
294
|
page: n.pattern,
|
|
291
|
-
interactive:
|
|
295
|
+
interactive: F,
|
|
292
296
|
delivery: "stream",
|
|
293
297
|
renderInput: {
|
|
294
298
|
descriptor: se,
|
|
295
299
|
params: i,
|
|
296
300
|
pathname: c,
|
|
297
|
-
search:
|
|
298
|
-
segmentLoaderData:
|
|
299
|
-
requestContext:
|
|
300
|
-
...
|
|
301
|
-
outerWrap:
|
|
302
|
-
locale:
|
|
301
|
+
search: v,
|
|
302
|
+
segmentLoaderData: k,
|
|
303
|
+
requestContext: N,
|
|
304
|
+
...P ? {
|
|
305
|
+
outerWrap: P.outerWrap,
|
|
306
|
+
locale: P.locale
|
|
303
307
|
} : {}
|
|
304
308
|
}
|
|
305
|
-
}), t =
|
|
306
|
-
helpers:
|
|
309
|
+
}), t = P?.locale ?? N.cookies["voltro:locale"] ?? "en", a = (t) => u({
|
|
310
|
+
helpers: M,
|
|
307
311
|
prepared: e,
|
|
308
312
|
meta: t,
|
|
309
|
-
interactive:
|
|
313
|
+
interactive: F
|
|
310
314
|
});
|
|
311
315
|
if (e.hasDeferred) {
|
|
312
|
-
let n =
|
|
316
|
+
let n = T({ shell: f });
|
|
313
317
|
return {
|
|
314
318
|
renderMode: "spa",
|
|
315
|
-
setCookies:
|
|
316
|
-
stream: (
|
|
317
|
-
res:
|
|
319
|
+
setCookies: y.setCookies,
|
|
320
|
+
stream: (r) => d({
|
|
321
|
+
res: r,
|
|
318
322
|
shell: n,
|
|
319
323
|
htmlLang: t,
|
|
320
324
|
headers: {
|
|
321
325
|
"content-type": "text/html; charset=utf-8",
|
|
322
|
-
"x-voltro-rendered-by": "spa"
|
|
326
|
+
"x-voltro-rendered-by": "spa",
|
|
327
|
+
...h(y.setCookies)
|
|
323
328
|
},
|
|
324
|
-
headInjection:
|
|
325
|
-
render: (t) =>
|
|
329
|
+
headInjection: a,
|
|
330
|
+
render: (t) => M.renderPageToStream({
|
|
326
331
|
...e.renderInput,
|
|
327
332
|
...t
|
|
328
333
|
}),
|
|
329
334
|
onShellError: (e) => {
|
|
330
|
-
|
|
335
|
+
Y.error("spa layout shell render failed", { pathname: c }, e), r.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), r.end("server error");
|
|
331
336
|
}
|
|
332
337
|
})
|
|
333
338
|
};
|
|
334
339
|
}
|
|
335
|
-
let
|
|
336
|
-
helpers:
|
|
340
|
+
let o = l({
|
|
341
|
+
helpers: M,
|
|
337
342
|
prepared: e
|
|
338
343
|
});
|
|
339
344
|
return {
|
|
340
|
-
html:
|
|
345
|
+
html: r(f.replace("<div id=\"root\"></div>", `<div id="root">${o.body}</div>`), a(o.meta)).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${t}"`),
|
|
341
346
|
renderMode: "spa",
|
|
342
347
|
revalidateMs: null,
|
|
343
|
-
setCookies:
|
|
348
|
+
setCookies: y.setCookies
|
|
344
349
|
};
|
|
345
350
|
}
|
|
346
|
-
let
|
|
347
|
-
helpers:
|
|
351
|
+
let I = p({
|
|
352
|
+
helpers: M,
|
|
348
353
|
page: n.pattern,
|
|
349
354
|
pathname: c,
|
|
350
|
-
renderMode:
|
|
351
|
-
interactive:
|
|
352
|
-
loaderData:
|
|
353
|
-
segmentLoaderData:
|
|
354
|
-
pageLoaderRan: typeof
|
|
355
|
+
renderMode: w,
|
|
356
|
+
interactive: F,
|
|
357
|
+
loaderData: A,
|
|
358
|
+
segmentLoaderData: k,
|
|
359
|
+
pageLoaderRan: typeof C.loader == "function"
|
|
355
360
|
}), ce = {
|
|
356
361
|
descriptor: se,
|
|
357
362
|
params: i,
|
|
358
363
|
pathname: c,
|
|
359
|
-
search:
|
|
360
|
-
loaderData:
|
|
361
|
-
segmentLoaderData:
|
|
362
|
-
requestContext:
|
|
363
|
-
...
|
|
364
|
-
outerWrap:
|
|
365
|
-
locale:
|
|
364
|
+
search: v,
|
|
365
|
+
loaderData: I.loaderData,
|
|
366
|
+
segmentLoaderData: I.segmentLoaderData,
|
|
367
|
+
requestContext: N,
|
|
368
|
+
...P ? {
|
|
369
|
+
outerWrap: P.outerWrap,
|
|
370
|
+
locale: P.locale
|
|
366
371
|
} : {}
|
|
367
372
|
}, le = (e) => [
|
|
368
|
-
|
|
369
|
-
`<meta name="voltro-interactive" content="${
|
|
370
|
-
...
|
|
371
|
-
|
|
373
|
+
M.renderMetaToHtml(e),
|
|
374
|
+
`<meta name="voltro-interactive" content="${F}" />`,
|
|
375
|
+
...I.hasDeferred ? [M.renderDeferredRegistryScript()] : [],
|
|
376
|
+
M.renderRouterStateScript(I.stateInput)
|
|
372
377
|
].filter((e) => e.length > 0).join("\n ");
|
|
373
|
-
if (
|
|
374
|
-
let e =
|
|
378
|
+
if (w === "ssr" && F === "full" && e.buffered !== !0) {
|
|
379
|
+
let e = P?.locale ?? N.cookies["voltro:locale"] ?? "en", t = T({ shell: f });
|
|
375
380
|
return {
|
|
376
381
|
renderMode: "ssr",
|
|
377
|
-
setCookies:
|
|
378
|
-
stream: (n) =>
|
|
382
|
+
setCookies: y.setCookies,
|
|
383
|
+
stream: (n) => d({
|
|
379
384
|
res: n,
|
|
380
385
|
shell: t,
|
|
381
386
|
htmlLang: e,
|
|
382
387
|
headers: {
|
|
383
388
|
"content-type": "text/html; charset=utf-8",
|
|
384
|
-
"x-voltro-rendered-by": "ssr"
|
|
389
|
+
"x-voltro-rendered-by": "ssr",
|
|
390
|
+
...h(y.setCookies)
|
|
385
391
|
},
|
|
386
392
|
headInjection: le,
|
|
387
|
-
render: (e) =>
|
|
393
|
+
render: (e) => M.renderPageToStream({
|
|
388
394
|
...ce,
|
|
389
395
|
...e
|
|
390
396
|
}),
|
|
391
397
|
onShellError: (e) => {
|
|
392
|
-
|
|
398
|
+
Y.error("ssr shell render failed", { pathname: c }, e), n.writeHead(500, { "content-type": "text/plain; charset=utf-8" }), n.end("server error");
|
|
393
399
|
}
|
|
394
400
|
})
|
|
395
401
|
};
|
|
396
402
|
}
|
|
397
|
-
let { html: ue, meta:
|
|
398
|
-
|
|
399
|
-
let
|
|
403
|
+
let { html: ue, meta: de } = M.renderPageToHtml(ce), fe = le(de), pe = P?.locale ?? N.cookies["voltro:locale"] ?? "en", R = r(f.replace("<div id=\"root\"></div>", `<div id="root">${ue}</div>`), fe).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${pe}"`);
|
|
404
|
+
F === "none" && (R = Z(R));
|
|
405
|
+
let me = w === "isr" ? he(C.revalidate) : null;
|
|
400
406
|
return {
|
|
401
|
-
html:
|
|
402
|
-
renderMode:
|
|
403
|
-
revalidateMs:
|
|
404
|
-
setCookies:
|
|
407
|
+
html: R,
|
|
408
|
+
renderMode: w,
|
|
409
|
+
revalidateMs: me,
|
|
410
|
+
setCookies: y.setCookies
|
|
405
411
|
};
|
|
406
|
-
}, $ = (e) => e === "" ? "/" : e,
|
|
407
|
-
let t = await import(
|
|
412
|
+
}, $ = (e) => e === "" ? "/" : e, Ve = async (e) => {
|
|
413
|
+
let t = await import(H(e).href);
|
|
408
414
|
return {
|
|
409
415
|
kind: "bundle",
|
|
410
416
|
getPageMeta: () => t.pageMeta,
|
|
@@ -433,8 +439,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
433
439
|
},
|
|
434
440
|
async close() {}
|
|
435
441
|
};
|
|
436
|
-
},
|
|
437
|
-
let n = await
|
|
442
|
+
}, He = async (e, t) => {
|
|
443
|
+
let n = await j("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
|
|
438
444
|
root: t,
|
|
439
445
|
envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
|
|
440
446
|
plugins: [r(), i()],
|
|
@@ -451,10 +457,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
451
457
|
},
|
|
452
458
|
appType: "custom",
|
|
453
459
|
logLevel: "warn"
|
|
454
|
-
}), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c =
|
|
455
|
-
limit:
|
|
456
|
-
onColdStart: (e) =>
|
|
457
|
-
onColdEnd: (e, { durationMs: t, failed: n }) =>
|
|
460
|
+
}), o = z(e, "src", "pages"), s = (e) => e === "" ? o : z(o, e), c = A({
|
|
461
|
+
limit: O(),
|
|
462
|
+
onColdStart: (e) => Y.debug("ssr cold-compile start", { id: e }),
|
|
463
|
+
onColdEnd: (e, { durationMs: t, failed: n }) => Y.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
|
|
458
464
|
id: e,
|
|
459
465
|
ms: t,
|
|
460
466
|
...n ? { failed: !0 } : {}
|
|
@@ -481,101 +487,106 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
481
487
|
await a.close();
|
|
482
488
|
}
|
|
483
489
|
};
|
|
484
|
-
},
|
|
485
|
-
let r =
|
|
486
|
-
if (!
|
|
490
|
+
}, Ue = async (t) => {
|
|
491
|
+
let r = Ce(), s = await S(t);
|
|
492
|
+
if (!s) return {
|
|
487
493
|
ran: !1,
|
|
488
494
|
exitCode: 0
|
|
489
495
|
};
|
|
490
|
-
if (
|
|
496
|
+
if (s.type !== "web") return Y.error("only web apps are supported by `voltro start`"), {
|
|
491
497
|
ran: !0,
|
|
492
498
|
exitCode: 1
|
|
493
499
|
};
|
|
494
|
-
let { resolved:
|
|
495
|
-
rawEnv:
|
|
500
|
+
let { resolved: l } = await w({
|
|
501
|
+
rawEnv: s.env,
|
|
496
502
|
appType: "web",
|
|
497
503
|
root: t,
|
|
498
|
-
log:
|
|
504
|
+
log: Y,
|
|
499
505
|
generateTypes: !1
|
|
500
|
-
}),
|
|
506
|
+
}), u = l.publicValues;
|
|
501
507
|
r.mark("config");
|
|
502
|
-
let
|
|
503
|
-
|
|
508
|
+
let d = _();
|
|
509
|
+
k(d), Y.info("booting voltro start", { app: s.name ?? "(unnamed)" });
|
|
504
510
|
let p = n({
|
|
505
511
|
kind: "web",
|
|
506
|
-
configPort:
|
|
512
|
+
configPort: s.port,
|
|
507
513
|
env: process.env,
|
|
508
|
-
dashboardPin: process.env[
|
|
514
|
+
dashboardPin: process.env[se] === "1"
|
|
509
515
|
});
|
|
510
|
-
for (let e of p.warnings)
|
|
511
|
-
let m = p.port, h = z(t, ".framework"),
|
|
512
|
-
if (!await Q(
|
|
516
|
+
for (let e of p.warnings) Y.warn(e);
|
|
517
|
+
let m = p.port, h = z(t, ".framework"), b = z(h, "dist"), ie = z(b, "index.html");
|
|
518
|
+
if (!await Q(ie)) return Y.error("no built dist found — run `voltro build` first", { distDir: b }), {
|
|
513
519
|
ran: !0,
|
|
514
520
|
exitCode: 1
|
|
515
521
|
};
|
|
516
|
-
let
|
|
517
|
-
await
|
|
518
|
-
id:
|
|
519
|
-
name:
|
|
522
|
+
let T = s.name ?? "unnamed", E = be("web", T, m), O = xe(T);
|
|
523
|
+
await _e({
|
|
524
|
+
id: E,
|
|
525
|
+
name: T,
|
|
520
526
|
kind: "web",
|
|
521
527
|
url: `http://localhost:${m}`,
|
|
522
528
|
pid: process.pid,
|
|
523
529
|
status: "booting",
|
|
524
|
-
logFile:
|
|
530
|
+
logFile: O.path
|
|
525
531
|
}).catch(() => {});
|
|
526
|
-
let
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
532
|
+
let A = z(b, "_voltro", "shell.html"), j = await Q(A) ? await B.readFile(A, "utf8") : await B.readFile(ie, "utf8"), L = await C(t, s), he = D(L[0]), we = L[0]?.name, Te = /* @__PURE__ */ new Set(), Ee = (e) => {
|
|
533
|
+
Te.has(e.name) || (Te.add(e.name), Y.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
|
|
534
|
+
cookie: e.name,
|
|
535
|
+
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."
|
|
536
|
+
}));
|
|
537
|
+
}, V = await i(t);
|
|
538
|
+
V.length > 0 && Y.info(`middleware.ts loaded — ${V.length} middleware(s): ` + V.map((e) => e.exportName).join(", "));
|
|
539
|
+
let H, U = null, W = process.env.SSR_CACHE === "postgres";
|
|
540
|
+
if (W && P()) U = new (await (import("pg"))).default.Client(N()), await U.connect(), H = Me({ client: U }), Y.info("isr cache backend: postgres", { table: "voltro_isr_cache" });
|
|
541
|
+
else if (W) {
|
|
531
542
|
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).";
|
|
532
|
-
if (e()) throw
|
|
533
|
-
|
|
534
|
-
} else
|
|
535
|
-
await
|
|
536
|
-
let
|
|
537
|
-
r.mark("scan");
|
|
538
|
-
let
|
|
539
|
-
if (!
|
|
540
|
-
let
|
|
541
|
-
|
|
542
|
-
kind:
|
|
543
|
-
...
|
|
543
|
+
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");
|
|
544
|
+
H = R(), Y.warn(`${t} Falling back to the per-process memory cache — this would be a hard failure in production.`);
|
|
545
|
+
} else H = R(), Y.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" });
|
|
546
|
+
await x(t, s, L, u);
|
|
547
|
+
let Ae = z(t, "src", "pages"), { pages: G, dirs: K } = await M(Ae), q = Re(G);
|
|
548
|
+
oe(V, q.map((e) => e.pattern)), r.mark("scan");
|
|
549
|
+
let J = z(b, "server", "ssrEntry.js"), Pe = await Q(J);
|
|
550
|
+
if (!Pe && process.env.NODE_ENV === "production") throw Y.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${J} 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 ${J}`);
|
|
551
|
+
let X = Pe ? await Ve(J) : await He(t, h);
|
|
552
|
+
Y.info(`ssr loader: ${X.kind}`, {
|
|
553
|
+
kind: X.kind,
|
|
554
|
+
...X.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
|
|
544
555
|
}), r.mark("provider");
|
|
545
|
-
let
|
|
546
|
-
for (let e of
|
|
547
|
-
let t =
|
|
556
|
+
let Fe = X.getPageMeta?.(), Z = /* @__PURE__ */ new Map(), Le = 0;
|
|
557
|
+
for (let e of G) {
|
|
558
|
+
let t = Fe?.[e.pattern];
|
|
548
559
|
if (t) {
|
|
549
|
-
|
|
560
|
+
Z.set(e.pattern, t);
|
|
550
561
|
continue;
|
|
551
562
|
}
|
|
552
563
|
try {
|
|
553
|
-
let t = await
|
|
554
|
-
|
|
564
|
+
let t = await X.getPage(e.pattern, e.file);
|
|
565
|
+
Z.set(e.pattern, fe(t, e.file)), Le++;
|
|
555
566
|
} catch (t) {
|
|
556
|
-
|
|
567
|
+
Y.warn("failed to load page metadata", { pattern: e.pattern }, t);
|
|
557
568
|
}
|
|
558
569
|
}
|
|
559
|
-
|
|
560
|
-
count:
|
|
561
|
-
fromManifest:
|
|
562
|
-
fromModules:
|
|
570
|
+
Y.info(`registered ${Z.size} route(s)`, {
|
|
571
|
+
count: Z.size,
|
|
572
|
+
fromManifest: Z.size - Le,
|
|
573
|
+
fromModules: Le
|
|
563
574
|
}), r.mark("routes");
|
|
564
|
-
let
|
|
565
|
-
for (let e of
|
|
566
|
-
|
|
567
|
-
let
|
|
568
|
-
for (let [e, t] of
|
|
569
|
-
let
|
|
570
|
-
for (let e of
|
|
571
|
-
let
|
|
572
|
-
cache:
|
|
573
|
-
tableSubscriptionsByPattern:
|
|
574
|
-
regexByPattern:
|
|
575
|
+
let $ = /* @__PURE__ */ new Set();
|
|
576
|
+
for (let e of q) Z.get(e.pattern)?.renderMode === "spa" && ae(K, e.dirChain).some((e) => e.hasLayout) && $.add(e.pattern);
|
|
577
|
+
$.size > 0 && Y.info(`${$.size} spa route(s) render an SSR layout shell`, { patterns: [...$] });
|
|
578
|
+
let Ue = /* @__PURE__ */ new Map();
|
|
579
|
+
for (let [e, t] of Z) t.cacheInvalidatesOn.length > 0 && Ue.set(e, t.cacheInvalidatesOn);
|
|
580
|
+
let We = /* @__PURE__ */ new Map();
|
|
581
|
+
for (let e of q) We.set(e.pattern, e.regex);
|
|
582
|
+
let Ge = je({
|
|
583
|
+
cache: H,
|
|
584
|
+
tableSubscriptionsByPattern: Ue,
|
|
585
|
+
regexByPattern: We
|
|
575
586
|
});
|
|
576
|
-
await
|
|
577
|
-
let
|
|
578
|
-
let t =
|
|
587
|
+
await Ge.start(), r.mark("cdc");
|
|
588
|
+
let Ke = Se(), qe = G.map((e) => {
|
|
589
|
+
let t = Z.get(e.pattern);
|
|
579
590
|
return {
|
|
580
591
|
pattern: e.pattern,
|
|
581
592
|
file: e.file,
|
|
@@ -590,20 +601,20 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
590
601
|
hasMeta: t?.hasMeta ?? !1,
|
|
591
602
|
hasGetStaticPaths: t?.hasGetStaticPaths ?? !1
|
|
592
603
|
};
|
|
593
|
-
}),
|
|
604
|
+
}), Je = K.map((e) => ({
|
|
594
605
|
dir: e.dir,
|
|
595
606
|
hasLayout: e.hasLayout,
|
|
596
607
|
hasError: e.hasError,
|
|
597
608
|
hasPending: e.hasPending,
|
|
598
609
|
hasNotFound: e.hasNotFound
|
|
599
|
-
})),
|
|
610
|
+
})), Ye = U ? "postgres" : "memory", Xe = {
|
|
600
611
|
kind: "web",
|
|
601
612
|
meta: {
|
|
602
|
-
name:
|
|
603
|
-
voltroVersion:
|
|
613
|
+
name: s.name ?? "(unnamed)",
|
|
614
|
+
voltroVersion: Ne,
|
|
604
615
|
port: m,
|
|
605
616
|
mode: "start",
|
|
606
|
-
apis: Object.entries(
|
|
617
|
+
apis: Object.entries(s.apis ?? {}).map(([e, t]) => {
|
|
607
618
|
let n = {
|
|
608
619
|
name: e,
|
|
609
620
|
package: t.package
|
|
@@ -611,10 +622,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
611
622
|
return t.url !== void 0 && (n.url = t.url), n;
|
|
612
623
|
})
|
|
613
624
|
},
|
|
614
|
-
routes:
|
|
615
|
-
dirs:
|
|
625
|
+
routes: qe,
|
|
626
|
+
dirs: Je,
|
|
616
627
|
cache: () => {
|
|
617
|
-
let e = Date.now(), t =
|
|
628
|
+
let e = Date.now(), t = H.snapshot().map(([t, n]) => ({
|
|
618
629
|
key: t,
|
|
619
630
|
renderedAt: n.renderedAt,
|
|
620
631
|
expiresAt: n.expiresAt,
|
|
@@ -625,16 +636,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
625
636
|
staleWhileRevalidateMs: n.staleWhileRevalidateMs
|
|
626
637
|
}));
|
|
627
638
|
return {
|
|
628
|
-
backend:
|
|
629
|
-
size:
|
|
639
|
+
backend: Ye,
|
|
640
|
+
size: H.size(),
|
|
630
641
|
entries: t
|
|
631
642
|
};
|
|
632
643
|
},
|
|
633
|
-
metrics: () =>
|
|
634
|
-
},
|
|
644
|
+
metrics: () => Oe()
|
|
645
|
+
}, Ze = async (e, n) => {
|
|
635
646
|
let r = e.split("?")[0] ?? "/";
|
|
636
|
-
if (
|
|
637
|
-
let e = await
|
|
647
|
+
if (s.name === "voltroDashboard" && r === "/api/dashboard/registry") try {
|
|
648
|
+
let e = await ve();
|
|
638
649
|
return {
|
|
639
650
|
status: 200,
|
|
640
651
|
headers: { "content-type": "application/json; charset=utf-8" },
|
|
@@ -647,7 +658,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
647
658
|
body: `registry read error: ${e.message}`
|
|
648
659
|
};
|
|
649
660
|
}
|
|
650
|
-
if (
|
|
661
|
+
if (s.name === "voltroDashboard" && r === "/api/dashboard/config") {
|
|
651
662
|
let e = process.env.VOLTRO_DASHBOARD_APPS, t = [];
|
|
652
663
|
if (e && e.trim().length > 0) {
|
|
653
664
|
let n;
|
|
@@ -677,18 +688,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
677
688
|
};
|
|
678
689
|
}
|
|
679
690
|
if (r === "/_voltro/inspect/logs") {
|
|
680
|
-
let t =
|
|
691
|
+
let t = re(e, ee(), n);
|
|
681
692
|
return {
|
|
682
693
|
status: t.status,
|
|
683
694
|
headers: {
|
|
684
695
|
"content-type": t.contentType,
|
|
685
|
-
...
|
|
696
|
+
...I(n.origin)
|
|
686
697
|
},
|
|
687
698
|
body: t.body
|
|
688
699
|
};
|
|
689
700
|
}
|
|
690
701
|
if (r !== "/_voltro/inspect/stream") {
|
|
691
|
-
let t = le(e,
|
|
702
|
+
let t = le(e, Xe, n);
|
|
692
703
|
if (t !== null) return {
|
|
693
704
|
status: t.status,
|
|
694
705
|
headers: {
|
|
@@ -698,72 +709,96 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
698
709
|
body: t.body
|
|
699
710
|
};
|
|
700
711
|
}
|
|
701
|
-
let
|
|
702
|
-
if (!
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
712
|
+
let i = ze(r, q), c = i ? Z.get(i.route.pattern)?.renderMode : void 0, l = c === "ssr" || c === "isr" || (i ? $.has(i.route.pattern) : !1), u = [];
|
|
713
|
+
if (!l && V.length > 0) {
|
|
714
|
+
let t = a(V, {
|
|
715
|
+
route: void 0,
|
|
716
|
+
pathname: r
|
|
717
|
+
});
|
|
718
|
+
if (t !== void 0) {
|
|
719
|
+
let i = await o(t, {
|
|
720
|
+
pathname: r,
|
|
721
|
+
search: e.slice(r.length),
|
|
722
|
+
headers: n,
|
|
723
|
+
cookies: ne(n.cookie),
|
|
724
|
+
route: void 0
|
|
725
|
+
});
|
|
726
|
+
u.push(...i.setCookies);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
let p = (e) => u.length === 0 ? e : {
|
|
730
|
+
...e,
|
|
731
|
+
"set-cookie": u.map(te)
|
|
732
|
+
}, m = r === "/" ? z(b, "index.html") : z(b, r.replace(/^\//, ""), "index.html");
|
|
733
|
+
if (!l && await Q(m)) {
|
|
734
|
+
let e = await B.readFile(m);
|
|
735
|
+
return {
|
|
736
|
+
status: 200,
|
|
737
|
+
headers: p({ "content-type": "text/html; charset=utf-8" }),
|
|
738
|
+
body: e
|
|
739
|
+
};
|
|
740
|
+
}
|
|
707
741
|
if (/\.[a-z0-9]+$/i.test(r)) {
|
|
708
|
-
let e = z(
|
|
742
|
+
let e = z(b, r.replace(/^\//, ""));
|
|
709
743
|
if (await Q(e)) {
|
|
710
|
-
let t = await
|
|
744
|
+
let t = await B.readFile(e);
|
|
711
745
|
return {
|
|
712
746
|
status: 200,
|
|
713
|
-
headers: { "content-type":
|
|
747
|
+
headers: p({ "content-type": Ie(e) }),
|
|
714
748
|
body: t
|
|
715
749
|
};
|
|
716
750
|
}
|
|
717
751
|
}
|
|
718
|
-
let
|
|
719
|
-
if (!
|
|
752
|
+
let h = ze(r, q);
|
|
753
|
+
if (!h) return {
|
|
720
754
|
status: 404,
|
|
721
|
-
headers: { "content-type": "text/plain" },
|
|
755
|
+
headers: p({ "content-type": "text/plain" }),
|
|
722
756
|
body: "not found"
|
|
723
757
|
};
|
|
724
|
-
let
|
|
725
|
-
...
|
|
726
|
-
...
|
|
727
|
-
}),
|
|
728
|
-
if (
|
|
758
|
+
let g = Z.get(h.route.pattern), _ = n["x-tenant"] ?? "anonymous", v = (await X.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, y = me(r, {
|
|
759
|
+
...g?.tenantAware ? { tenant: _ } : {},
|
|
760
|
+
...v ? { locale: v } : {}
|
|
761
|
+
}), x = H.get(y), S = Date.now();
|
|
762
|
+
if (x && ge(x, S)) return d.emit("cache", {
|
|
729
763
|
kind: "HIT",
|
|
730
|
-
key:
|
|
731
|
-
ageMs:
|
|
764
|
+
key: y,
|
|
765
|
+
ageMs: S - x.renderedAt
|
|
732
766
|
}), {
|
|
733
767
|
status: 200,
|
|
734
768
|
headers: {
|
|
735
769
|
"content-type": "text/html; charset=utf-8",
|
|
736
770
|
"x-voltro-rendered-by": "isr",
|
|
737
771
|
"x-voltro-cache": "HIT",
|
|
738
|
-
"x-voltro-cache-key":
|
|
739
|
-
"x-voltro-cache-age-ms": String(
|
|
772
|
+
"x-voltro-cache-key": y,
|
|
773
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
740
774
|
},
|
|
741
|
-
body:
|
|
775
|
+
body: x.html
|
|
742
776
|
};
|
|
743
|
-
if (
|
|
777
|
+
if (x && pe(x, S)) return d.emit("cache", {
|
|
744
778
|
kind: "STALE",
|
|
745
|
-
key:
|
|
746
|
-
ageMs:
|
|
779
|
+
key: y,
|
|
780
|
+
ageMs: S - x.renderedAt
|
|
747
781
|
}), (async () => {
|
|
748
782
|
try {
|
|
749
|
-
let i = await
|
|
750
|
-
provider:
|
|
783
|
+
let i = await Be({
|
|
784
|
+
provider: X,
|
|
751
785
|
root: t,
|
|
752
|
-
route:
|
|
753
|
-
params:
|
|
786
|
+
route: h.route,
|
|
787
|
+
params: h.params,
|
|
754
788
|
pathname: r,
|
|
755
|
-
dirs:
|
|
756
|
-
shellTemplate:
|
|
789
|
+
dirs: K,
|
|
790
|
+
shellTemplate: j,
|
|
757
791
|
requestHeaders: n,
|
|
758
|
-
apiOrigin:
|
|
759
|
-
apiName:
|
|
760
|
-
|
|
792
|
+
apiOrigin: he,
|
|
793
|
+
apiName: we,
|
|
794
|
+
middlewares: V,
|
|
795
|
+
onCookieWarning: Ee,
|
|
761
796
|
requestUrl: e,
|
|
762
797
|
buffered: !0
|
|
763
798
|
});
|
|
764
799
|
if (i && "html" in i && i.renderMode === "isr" && i.revalidateMs !== null) {
|
|
765
|
-
let e =
|
|
766
|
-
|
|
800
|
+
let e = Z.get(h.route.pattern)?.staleWhileRevalidateMs ?? 0, t = Date.now();
|
|
801
|
+
H.set(y, {
|
|
767
802
|
html: i.html,
|
|
768
803
|
renderedAt: t,
|
|
769
804
|
expiresAt: t + i.revalidateMs,
|
|
@@ -773,7 +808,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
773
808
|
});
|
|
774
809
|
}
|
|
775
810
|
} catch (e) {
|
|
776
|
-
|
|
811
|
+
Y.warn("background SWR refresh failed", { url: r }, e);
|
|
777
812
|
}
|
|
778
813
|
})(), {
|
|
779
814
|
status: 200,
|
|
@@ -781,24 +816,25 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
781
816
|
"content-type": "text/html; charset=utf-8",
|
|
782
817
|
"x-voltro-rendered-by": "isr",
|
|
783
818
|
"x-voltro-cache": "STALE",
|
|
784
|
-
"x-voltro-cache-key":
|
|
785
|
-
"x-voltro-cache-age-ms": String(
|
|
819
|
+
"x-voltro-cache-key": y,
|
|
820
|
+
"x-voltro-cache-age-ms": String(S - x.renderedAt)
|
|
786
821
|
},
|
|
787
|
-
body:
|
|
822
|
+
body: x.html
|
|
788
823
|
};
|
|
789
824
|
try {
|
|
790
|
-
let i = await
|
|
791
|
-
provider:
|
|
825
|
+
let i = await Be({
|
|
826
|
+
provider: X,
|
|
792
827
|
root: t,
|
|
793
|
-
route:
|
|
794
|
-
params:
|
|
828
|
+
route: h.route,
|
|
829
|
+
params: h.params,
|
|
795
830
|
pathname: r,
|
|
796
|
-
dirs:
|
|
797
|
-
shellTemplate:
|
|
831
|
+
dirs: K,
|
|
832
|
+
shellTemplate: j,
|
|
798
833
|
requestHeaders: n,
|
|
799
|
-
apiOrigin:
|
|
800
|
-
apiName:
|
|
801
|
-
|
|
834
|
+
apiOrigin: he,
|
|
835
|
+
apiName: we,
|
|
836
|
+
middlewares: V,
|
|
837
|
+
onCookieWarning: Ee,
|
|
802
838
|
requestUrl: e
|
|
803
839
|
});
|
|
804
840
|
if (!i) return {
|
|
@@ -807,15 +843,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
807
843
|
"content-type": "text/html; charset=utf-8",
|
|
808
844
|
"x-voltro-rendered-by": "spa-fallback"
|
|
809
845
|
},
|
|
810
|
-
body:
|
|
846
|
+
body: j
|
|
811
847
|
};
|
|
812
848
|
let a = i.setCookies ?? [], o = (e) => a.length === 0 ? e : {
|
|
813
849
|
...e,
|
|
814
|
-
"set-cookie": a.map(
|
|
850
|
+
"set-cookie": a.map(te)
|
|
815
851
|
};
|
|
816
852
|
if ("stream" in i) return {
|
|
817
853
|
status: 200,
|
|
818
|
-
headers:
|
|
854
|
+
headers: { "x-voltro-rendered-by": i.renderMode },
|
|
819
855
|
body: "",
|
|
820
856
|
stream: i.stream
|
|
821
857
|
};
|
|
@@ -839,23 +875,23 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
839
875
|
"x-voltro-rendered-by": i.renderMode
|
|
840
876
|
});
|
|
841
877
|
if (i.renderMode === "isr" && i.revalidateMs !== null) {
|
|
842
|
-
let e = Date.now(), t =
|
|
843
|
-
|
|
878
|
+
let e = Date.now(), t = Z.get(h.route.pattern)?.staleWhileRevalidateMs ?? 0;
|
|
879
|
+
H.set(y, {
|
|
844
880
|
html: i.html,
|
|
845
881
|
renderedAt: e,
|
|
846
882
|
expiresAt: e + i.revalidateMs,
|
|
847
883
|
servableUntil: e + i.revalidateMs + t,
|
|
848
884
|
revalidateMs: i.revalidateMs,
|
|
849
885
|
staleWhileRevalidateMs: t
|
|
850
|
-
}), s["x-voltro-cache"] = "MISS", s["x-voltro-cache-key"] =
|
|
886
|
+
}), s["x-voltro-cache"] = "MISS", s["x-voltro-cache-key"] = y, s["x-voltro-cache-revalidate-ms"] = String(i.revalidateMs), t > 0 && (s["x-voltro-cache-swr-ms"] = String(t)), d.emit("cache", {
|
|
851
887
|
kind: "MISS",
|
|
852
|
-
key:
|
|
888
|
+
key: y,
|
|
853
889
|
revalidateMs: i.revalidateMs,
|
|
854
890
|
swrMs: t
|
|
855
891
|
});
|
|
856
|
-
} else i.renderMode === "isr" && (s["x-voltro-cache"] = "BYPASS",
|
|
892
|
+
} else i.renderMode === "isr" && (s["x-voltro-cache"] = "BYPASS", d.emit("cache", {
|
|
857
893
|
kind: "BYPASS",
|
|
858
|
-
key:
|
|
894
|
+
key: y
|
|
859
895
|
}));
|
|
860
896
|
return {
|
|
861
897
|
status: 200,
|
|
@@ -863,7 +899,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
863
899
|
body: i.html
|
|
864
900
|
};
|
|
865
901
|
} catch (e) {
|
|
866
|
-
return
|
|
902
|
+
return Y.error("render error", { url: r }, e), f(e) ? {
|
|
867
903
|
status: 500,
|
|
868
904
|
headers: {
|
|
869
905
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -876,56 +912,56 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
876
912
|
body: "server error"
|
|
877
913
|
};
|
|
878
914
|
}
|
|
879
|
-
},
|
|
915
|
+
}, Qe = !1, $e = ke(async (e, t) => {
|
|
880
916
|
let n = e.url ?? "/", r = Date.now(), i = {};
|
|
881
917
|
for (let [t, n] of Object.entries(e.headers)) n !== void 0 && (i[t.toLowerCase()] = Array.isArray(n) ? n.join(", ") : n);
|
|
882
|
-
let
|
|
883
|
-
if (
|
|
918
|
+
let a = n.split("?")[0] ?? "/", o = (e.method ?? "GET").toUpperCase();
|
|
919
|
+
if (a === "/internal/liveness") {
|
|
884
920
|
t.writeHead(200, {
|
|
885
921
|
"content-type": "text/plain",
|
|
886
922
|
"cache-control": "no-store"
|
|
887
923
|
}), t.end("ok");
|
|
888
924
|
return;
|
|
889
925
|
}
|
|
890
|
-
if (
|
|
891
|
-
let e =
|
|
926
|
+
if (a === "/internal/readiness") {
|
|
927
|
+
let e = Qe ? 200 : 503;
|
|
892
928
|
t.writeHead(e, {
|
|
893
929
|
"content-type": "text/plain",
|
|
894
930
|
"cache-control": "no-store"
|
|
895
|
-
}), t.end(
|
|
931
|
+
}), t.end(Qe ? "ready" : "not-ready");
|
|
896
932
|
return;
|
|
897
933
|
}
|
|
898
|
-
if (
|
|
899
|
-
let e =
|
|
934
|
+
if (o === "OPTIONS" && a.startsWith("/_voltro/inspect")) {
|
|
935
|
+
let e = I(i.origin);
|
|
900
936
|
t.writeHead(204, e), t.end();
|
|
901
937
|
return;
|
|
902
938
|
}
|
|
903
|
-
if (
|
|
939
|
+
if (s.name === "voltroDashboard" && a === "/api/dashboard/proxy") {
|
|
904
940
|
let r = new URL(n, "http://x").searchParams.get("target");
|
|
905
941
|
if (!r) {
|
|
906
942
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
907
943
|
return;
|
|
908
944
|
}
|
|
909
|
-
if (!
|
|
945
|
+
if (!de(r)) {
|
|
910
946
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
911
947
|
return;
|
|
912
948
|
}
|
|
913
949
|
try {
|
|
914
950
|
let n = { accept: i.accept ?? "application/json" }, a = i.authorization;
|
|
915
951
|
a ? n.authorization = Array.isArray(a) ? a[0] : a : ue(r) && process.env.VOLTRO_INSPECT_TOKEN && (n.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
|
|
916
|
-
let
|
|
917
|
-
if (
|
|
952
|
+
let s;
|
|
953
|
+
if (o && o !== "GET" && o !== "HEAD") {
|
|
918
954
|
let t = [];
|
|
919
955
|
for await (let n of e) t.push(n);
|
|
920
|
-
|
|
956
|
+
s = Buffer.concat(t);
|
|
921
957
|
let r = i["content-type"];
|
|
922
958
|
r && (n["content-type"] = Array.isArray(r) ? r[0] : r);
|
|
923
959
|
}
|
|
924
960
|
let c = await fetch(r, {
|
|
925
961
|
redirect: "manual",
|
|
926
|
-
method:
|
|
962
|
+
method: o,
|
|
927
963
|
headers: n,
|
|
928
|
-
...
|
|
964
|
+
...s ? { body: new Uint8Array(s.buffer, s.byteOffset, s.byteLength) } : {}
|
|
929
965
|
}), l = Buffer.from(await c.arrayBuffer());
|
|
930
966
|
t.writeHead(c.status, {
|
|
931
967
|
"content-type": c.headers.get("content-type") ?? "application/octet-stream",
|
|
@@ -936,13 +972,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
936
972
|
}
|
|
937
973
|
return;
|
|
938
974
|
}
|
|
939
|
-
if (
|
|
975
|
+
if (s.name === "voltroDashboard" && a === "/api/dashboard/proxy/stream") {
|
|
940
976
|
let r = new URL(n, "http://x").searchParams.get("target");
|
|
941
977
|
if (!r) {
|
|
942
978
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
|
|
943
979
|
return;
|
|
944
980
|
}
|
|
945
|
-
if (!
|
|
981
|
+
if (!de(r)) {
|
|
946
982
|
t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
|
|
947
983
|
return;
|
|
948
984
|
}
|
|
@@ -983,9 +1019,9 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
983
1019
|
}
|
|
984
1020
|
return;
|
|
985
1021
|
}
|
|
986
|
-
if (
|
|
987
|
-
let n =
|
|
988
|
-
if (
|
|
1022
|
+
if (a === "/_voltro/inspect/stream") {
|
|
1023
|
+
let n = I(i.origin);
|
|
1024
|
+
if (F()) {
|
|
989
1025
|
t.writeHead(503, {
|
|
990
1026
|
"content-type": "application/json",
|
|
991
1027
|
...n
|
|
@@ -1010,11 +1046,11 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1010
1046
|
"x-accel-buffering": "no",
|
|
1011
1047
|
...n
|
|
1012
1048
|
}), t.flushHeaders(), t.write("retry: 5000\n\n");
|
|
1013
|
-
for (let e of
|
|
1014
|
-
let a =
|
|
1015
|
-
t.write(
|
|
1049
|
+
for (let e of d.buffered()) t.write(v(e));
|
|
1050
|
+
let a = d.subscribe((e) => {
|
|
1051
|
+
t.write(v(e));
|
|
1016
1052
|
}), o = setInterval(() => {
|
|
1017
|
-
t.write(
|
|
1053
|
+
t.write(y());
|
|
1018
1054
|
}, 15e3), s = () => {
|
|
1019
1055
|
clearInterval(o), a();
|
|
1020
1056
|
};
|
|
@@ -1022,18 +1058,18 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1022
1058
|
return;
|
|
1023
1059
|
}
|
|
1024
1060
|
try {
|
|
1025
|
-
let e = await
|
|
1026
|
-
if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !
|
|
1061
|
+
let e = await Ze(n, i);
|
|
1062
|
+
if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !a.startsWith("/_voltro/inspect")) {
|
|
1027
1063
|
let t = Date.now() - r;
|
|
1028
|
-
|
|
1029
|
-
url:
|
|
1064
|
+
d.emit("request", {
|
|
1065
|
+
url: a,
|
|
1030
1066
|
status: e.status,
|
|
1031
1067
|
durationMs: t,
|
|
1032
1068
|
renderedBy: e.headers["x-voltro-rendered-by"],
|
|
1033
1069
|
cache: e.headers["x-voltro-cache"]
|
|
1034
1070
|
});
|
|
1035
|
-
let n =
|
|
1036
|
-
|
|
1071
|
+
let n = ze(a, q)?.route.pattern ?? (e.status === 404 ? "<unmatched>" : "<asset>");
|
|
1072
|
+
Ke.record({
|
|
1037
1073
|
kind: "request",
|
|
1038
1074
|
tag: n,
|
|
1039
1075
|
durationMs: t,
|
|
@@ -1044,71 +1080,71 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
|
|
|
1044
1080
|
t.writeHead(500, { "content-type": "text/plain" }), t.end(`internal error: ${e.message}`);
|
|
1045
1081
|
}
|
|
1046
1082
|
});
|
|
1047
|
-
await new Promise((e) =>
|
|
1083
|
+
await new Promise((e) => $e.listen(m, "::", e)), Qe = !0, r.mark("ready"), Y.info(`listening on http://localhost:${m}`, {
|
|
1048
1084
|
port: m,
|
|
1049
|
-
distDir:
|
|
1050
|
-
}),
|
|
1085
|
+
distDir: b
|
|
1086
|
+
}), Y.debug("dynamic + ssr/isr routes resolve via SSR loader");
|
|
1051
1087
|
try {
|
|
1052
|
-
await
|
|
1053
|
-
id:
|
|
1054
|
-
name:
|
|
1088
|
+
await _e({
|
|
1089
|
+
id: E,
|
|
1090
|
+
name: T,
|
|
1055
1091
|
kind: "web",
|
|
1056
1092
|
url: `http://localhost:${m}`,
|
|
1057
1093
|
pid: process.pid,
|
|
1058
1094
|
status: "live",
|
|
1059
|
-
logFile:
|
|
1095
|
+
logFile: O.path
|
|
1060
1096
|
});
|
|
1061
|
-
let e =
|
|
1097
|
+
let e = c(t);
|
|
1062
1098
|
if (e) {
|
|
1063
|
-
let t = await
|
|
1064
|
-
t.status === "launched" ?
|
|
1099
|
+
let t = await g({ dashboardAppPath: e });
|
|
1100
|
+
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 });
|
|
1065
1101
|
}
|
|
1066
1102
|
setInterval(() => {
|
|
1067
|
-
|
|
1068
|
-
id:
|
|
1069
|
-
name:
|
|
1103
|
+
_e({
|
|
1104
|
+
id: E,
|
|
1105
|
+
name: T,
|
|
1070
1106
|
kind: "web",
|
|
1071
1107
|
url: `http://localhost:${m}`,
|
|
1072
1108
|
pid: process.pid,
|
|
1073
1109
|
status: "live",
|
|
1074
|
-
logFile:
|
|
1110
|
+
logFile: O.path
|
|
1075
1111
|
}).catch(() => {});
|
|
1076
1112
|
}, 1e4).unref();
|
|
1077
1113
|
} catch (e) {
|
|
1078
|
-
|
|
1114
|
+
Y.warn("runtime-registry write failed", {}, e);
|
|
1079
1115
|
}
|
|
1080
|
-
|
|
1081
|
-
app:
|
|
1116
|
+
De({
|
|
1117
|
+
app: s.name ?? "unnamed",
|
|
1082
1118
|
kind: "web",
|
|
1083
1119
|
url: `http://localhost:${m}`,
|
|
1084
1120
|
bootMs: r.total()
|
|
1085
1121
|
});
|
|
1086
|
-
let
|
|
1087
|
-
|
|
1122
|
+
let et = r.phaseBreakdown();
|
|
1123
|
+
Y.info(`start: ready in ${r.total()}ms`, {
|
|
1088
1124
|
bootMs: r.total(),
|
|
1089
|
-
...
|
|
1125
|
+
...et ? { phases: et } : {}
|
|
1090
1126
|
});
|
|
1091
|
-
let
|
|
1092
|
-
if (!
|
|
1093
|
-
if (
|
|
1094
|
-
await
|
|
1127
|
+
let tt = !1, nt = (e) => async () => {
|
|
1128
|
+
if (!tt) {
|
|
1129
|
+
if (tt = !0, Y.info(`received ${e}, shutting down`, { signal: e }), $e.close(), await Ge.stop(), U) try {
|
|
1130
|
+
await U.end();
|
|
1095
1131
|
} catch {}
|
|
1096
|
-
await
|
|
1132
|
+
await X.close(), await ye(E), await O.dispose(), process.exit(0);
|
|
1097
1133
|
}
|
|
1098
1134
|
};
|
|
1099
|
-
process.on("SIGINT",
|
|
1100
|
-
let
|
|
1101
|
-
if (
|
|
1135
|
+
process.on("SIGINT", nt("SIGINT")), process.on("SIGTERM", nt("SIGTERM"));
|
|
1136
|
+
let rt = process.ppid;
|
|
1137
|
+
if (rt > 1) {
|
|
1102
1138
|
let e = setInterval(() => {
|
|
1103
|
-
(process.ppid !==
|
|
1139
|
+
(process.ppid !== rt || process.ppid === 1) && (clearInterval(e), nt("SIGTERM")());
|
|
1104
1140
|
}, 2e3);
|
|
1105
1141
|
e.unref();
|
|
1106
1142
|
}
|
|
1107
1143
|
return new Promise(() => {});
|
|
1108
|
-
},
|
|
1144
|
+
}, We = async (e) => {
|
|
1109
1145
|
t("start");
|
|
1110
|
-
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await
|
|
1111
|
-
return r.ran ? r.exitCode : (
|
|
1146
|
+
let n = e.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await Ue(Ee(n));
|
|
1147
|
+
return r.ran ? r.exitCode : (Y.error("no web app found at this path"), 1);
|
|
1112
1148
|
};
|
|
1113
1149
|
//#endregion
|
|
1114
|
-
export {
|
|
1150
|
+
export { Ue as n, We as t };
|