@voltro/cli 0.30.0 → 0.30.1

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/apiBuild-Ca6Sq5jy.js +2 -0
  3. package/dist/{apiBuild-BceikpQf.js → apiBuild-DmkzRyv7.js} +2 -2
  4. package/dist/bin.js +3 -3
  5. package/dist/{checkCommand-BMr-X48w.js → checkCommand-C4konUy9.js} +422 -298
  6. package/dist/checkCommand-DHD0aBeR.js +2 -0
  7. package/dist/{commands-D4Y1-Nlu.js → commands-BkJft9K2.js} +1609 -1607
  8. package/dist/{dbCommand-C7hbl5pk.js → dbCommand-qn__kLEt.js} +1 -1
  9. package/dist/dbCommand-wfGi3FgG.js +2 -0
  10. package/dist/{dev-DmnkH-wr.js → dev-C_NPcLDp.js} +1266 -1250
  11. package/dist/{dev-Cr-teYsz.js → dev-DXhhZ7-f.js} +1 -1
  12. package/dist/frameworkTableAssembly-Bn_c4Mnl.js +2 -0
  13. package/dist/{frameworkTableAssembly-BzAajuUv.js → frameworkTableAssembly-Cpgn2e88.js} +128 -130
  14. package/dist/index.js +1 -1
  15. package/dist/{inspectMetrics-BeJdP_3b.js → inspectMetrics-CkB2J0Zn.js} +2 -0
  16. package/dist/{sdkgen-CqpOq_fy.js → sdkgen-wsWLrq4l.js} +1 -1
  17. package/dist/{serveCommand-Ciq_wIY8.js → serveCommand-HtI4X5kj.js} +14 -14
  18. package/dist/serveEntry.js +2 -2
  19. package/dist/{start-ocqB1seX.js → start-egkbpugc.js} +177 -175
  20. package/dist/startEntry.js +2 -2
  21. package/package.json +17 -17
  22. package/templates/AGENTS.md +1 -1
  23. package/templates/agent-docs/_index.md +1 -1
  24. package/templates/agent-docs/cli.md +27 -0
  25. package/templates/agent-docs/routing.md +14 -0
  26. package/templates/agent-docs/whats-new.md +36 -342
  27. package/templates/agent-docs/workflows.md +2 -0
  28. package/templates/apps/api-ai/package.json +7 -7
  29. package/templates/apps/api-auth/package.json +8 -8
  30. package/templates/apps/api-backend/package.json +7 -7
  31. package/templates/apps/api-backend-deactivation/package.json +7 -7
  32. package/templates/apps/api-backend-mail/package.json +8 -8
  33. package/templates/apps/api-backend-mariadb/package.json +9 -9
  34. package/templates/apps/api-backend-sqlite/package.json +8 -8
  35. package/templates/apps/api-backend-storage/package.json +8 -8
  36. package/templates/apps/api-cms/package.json +10 -10
  37. package/templates/apps/api-collab/package.json +8 -8
  38. package/templates/apps/api-data-advanced/package.json +8 -8
  39. package/templates/apps/api-durable/package.json +8 -8
  40. package/templates/apps/api-feature-flags/package.json +9 -9
  41. package/templates/apps/api-governance/package.json +8 -8
  42. package/templates/apps/api-kv/package.json +8 -8
  43. package/templates/apps/api-moderation/package.json +8 -8
  44. package/templates/apps/api-observability/package.json +8 -8
  45. package/templates/apps/api-ratelimit/package.json +8 -8
  46. package/templates/apps/api-rbac/package.json +8 -8
  47. package/templates/apps/api-rest/package.json +7 -7
  48. package/templates/apps/api-saas/package.json +11 -11
  49. package/templates/apps/api-saas-starter/package.json +10 -10
  50. package/templates/apps/api-search/package.json +8 -8
  51. package/templates/apps/api-status/package.json +8 -8
  52. package/templates/apps/api-versioning/package.json +8 -8
  53. package/templates/apps/api-webhooks/package.json +9 -9
  54. package/templates/apps/changelog/package.json +6 -6
  55. package/templates/apps/edge-functions/package.json +2 -2
  56. package/templates/apps/frontend-admin/package.json +8 -8
  57. package/templates/apps/frontend-app/package.json +8 -8
  58. package/templates/apps/frontend-auth/package.json +8 -8
  59. package/templates/apps/frontend-blank/package.json +7 -7
  60. package/templates/apps/frontend-cms/package.json +9 -9
  61. package/templates/apps/frontend-collab/package.json +9 -9
  62. package/templates/apps/frontend-contact/package.json +7 -7
  63. package/templates/apps/frontend-dashboard/package.json +7 -7
  64. package/templates/apps/frontend-docs/package.json +7 -7
  65. package/templates/apps/frontend-i18n/package.json +6 -6
  66. package/templates/apps/frontend-landing/package.json +7 -7
  67. package/templates/apps/frontend-portal/package.json +8 -8
  68. package/templates/apps/frontend-saas/package.json +8 -8
  69. package/templates/apps/frontend-spa/package.json +7 -7
  70. package/templates/apps/frontend-ssr/package.json +7 -7
  71. package/templates/apps/frontend-ssr-api/package.json +8 -8
  72. package/templates/apps/frontend-static-blog/package.json +6 -6
  73. package/templates/apps/frontend-status/package.json +8 -8
  74. package/templates/apps/mobile-app/package.json +2 -2
  75. package/dist/apiBuild-CxvR1Dwt.js +0 -2
  76. package/dist/checkCommand-BOk9y264.js +0 -2
  77. package/dist/dbCommand-D8nhyppR.js +0 -2
  78. package/dist/frameworkTableAssembly-DU0aOxjL.js +0 -2
@@ -1,7 +1,7 @@
1
- import { B as e, E as t, G as n, I as r, K as i, N as a, O as o, Q as s, S as c, T as l, U as u, W as ee, Z as d, _ as te, _t as f, a as p, at as m, b as h, c as g, f as _, ft as v, g as y, gt as b, h as x, ht as ne, i as re, it as ie, lt as ae, m as S, mt as C, nt as oe, o as se, ot as w, p as T, q as E, r as D, rt as O, s as k, t as A, v as j, x as ce, y as M } from "./inspectMetrics-BeJdP_3b.js";
2
- import { A as le, E as N, O as P, a as ue, k as F, m as de } from "./inspect-BUUjt773.js";
3
- import { t as fe } from "./bootTiming-BdyP9nYw.js";
4
- import { dirname as I, extname as pe, join as L, resolve as R } from "node:path";
1
+ import { B as e, E as t, G as n, I as r, K as i, N as a, O as o, Q as s, S as c, T as l, U as u, W as ee, Z as d, _ as f, _t as p, a as m, at as h, b as g, c as _, f as v, ft as y, g as b, gt as x, h as S, ht as te, i as ne, it as re, lt as ie, m as C, mt as w, nt as ae, o as oe, ot as T, p as E, q as D, r as O, rt as k, s as A, t as j, v as M, x as se, y as N } from "./inspectMetrics-CkB2J0Zn.js";
2
+ import { A as ce, E as P, O as F, a as le, k as I, m as ue } from "./inspect-BUUjt773.js";
3
+ import { t as de } from "./bootTiming-BdyP9nYw.js";
4
+ import { dirname as L, extname as fe, join as R, resolve as pe } from "node:path";
5
5
  import { fileURLToPath as z, pathToFileURL as B } from "node:url";
6
6
  import { createLogger as V, printReadyBlock as me } from "@voltro/logger";
7
7
  import { promises as H } from "node:fs";
@@ -144,7 +144,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
144
144
  };
145
145
  }, J = V({ scope: "voltro:start" }), be = await (async () => {
146
146
  try {
147
- let e = L(I(z(import.meta.url)), "..", "package.json"), t = await H.readFile(e, "utf8");
147
+ let e = R(L(z(import.meta.url)), "..", "package.json"), t = await H.readFile(e, "utf8");
148
148
  return JSON.parse(t).version ?? "0.0.0";
149
149
  } catch {
150
150
  return "0.0.0";
@@ -167,7 +167,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
167
167
  ".woff": "font/woff",
168
168
  ".woff2": "font/woff2",
169
169
  ".txt": "text/plain; charset=utf-8"
170
- }, xe = (e) => Z[pe(e).toLowerCase()] ?? "application/octet-stream", Se = (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) => {
170
+ }, xe = (e) => Z[fe(e).toLowerCase()] ?? "application/octet-stream", Se = (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) => {
171
171
  try {
172
172
  return await H.stat(e), !0;
173
173
  } catch {
@@ -205,30 +205,30 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
205
205
  }
206
206
  return null;
207
207
  }, Ee = async (e) => {
208
- let { provider: t, route: n, params: i, pathname: a, dirs: o, shellTemplate: s, requestHeaders: l, requestUrl: u = "", apiOrigin: ee, apiName: d } = e, { search: te } = c(u), f = re(ee, l.cookie, { apiName: d }), m = await t.getPage(n.pattern, n.file), g = r(m, n.file), _ = g === "spa" && se(o, n.dirChain).some((e) => e.hasLayout);
209
- if (g !== "ssr" && g !== "isr" && !_) return null;
210
- let v = se(o, n.dirChain), b = {}, ne = null, ie, ae = new AbortController();
208
+ let { provider: t, route: n, params: i, pathname: a, dirs: o, shellTemplate: s, requestHeaders: l, requestUrl: u = "", apiOrigin: ee, apiName: d } = e, { search: f } = c(u), p = ne(ee, l.cookie, { apiName: d }), h = await t.getPage(n.pattern, n.file), _ = r(h, n.file), v = _ === "spa" && oe(o, n.dirChain).some((e) => e.hasLayout);
209
+ if (_ !== "ssr" && _ !== "isr" && !v) return null;
210
+ let y = oe(o, n.dirChain), x = {}, te = null, re, ie = new AbortController();
211
211
  try {
212
- (await t.getHelpers()).beginStoreSeeds(), {chain: ie, segmentLoaderData: b} = await p({
213
- entries: v,
212
+ (await t.getHelpers()).beginStoreSeeds(), {chain: re, segmentLoaderData: x} = await m({
213
+ entries: y,
214
214
  loadLayout: (e) => t.getLayout(e.dir),
215
215
  loadError: (e) => t.getError(e.dir),
216
216
  loadPending: (e) => t.getPending(e.dir),
217
217
  ctx: {
218
218
  params: i,
219
219
  pathname: a,
220
- search: te,
221
- signal: ae.signal,
220
+ search: f,
221
+ signal: ie.signal,
222
222
  headers: l,
223
- query: f
223
+ query: p
224
224
  }
225
- }), typeof m.loader == "function" && !_ && (ne = await m.loader({
225
+ }), typeof h.loader == "function" && !v && (te = await h.loader({
226
226
  params: i,
227
227
  pathname: a,
228
- search: te,
229
- signal: ae.signal,
228
+ search: f,
229
+ signal: ie.signal,
230
230
  headers: l,
231
- query: f
231
+ query: p
232
232
  }));
233
233
  } catch (e) {
234
234
  if (Y(e)) return {
@@ -239,61 +239,62 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
239
239
  if (X(e)) return { control: "not-found" };
240
240
  throw e;
241
241
  }
242
- let C = await t.getHelpers();
243
- _ || await S({
244
- pageMod: m,
242
+ let w = await t.getHelpers();
243
+ v || await C({
244
+ pageMod: h,
245
245
  params: i,
246
- query: f,
246
+ query: p,
247
247
  apiName: d,
248
- seed: C.seedPreloadedSubscription,
248
+ seed: w.seedPreloadedSubscription,
249
249
  onError: ({ tag: e, apiName: t }, n) => J.warn("preload seed failed", {
250
250
  tag: e,
251
251
  apiName: t,
252
252
  pathname: a
253
253
  }, n)
254
254
  });
255
- let oe = {
255
+ let ae = {
256
256
  pattern: n.pattern,
257
- Component: m.default,
258
- meta: m.meta,
259
- loader: m.loader,
260
- ErrorBoundary: m.ErrorBoundary,
261
- Pending: m.Pending,
262
- renderMode: g,
263
- chain: ie
264
- }, T = {
265
- cookies: C.parseCookieHeader(l.cookie),
257
+ Component: h.default,
258
+ meta: h.meta,
259
+ loader: h.loader,
260
+ ErrorBoundary: h.ErrorBoundary,
261
+ Pending: h.Pending,
262
+ renderMode: _,
263
+ chain: re
264
+ }, E = {
265
+ cookies: w.parseCookieHeader(l.cookie),
266
266
  headers: l,
267
267
  url: u
268
- }, E = C.i18n?.resolve(l.cookie, l["accept-language"]), D = m.interactive ?? "full";
269
- if (_) {
270
- let e = M({
271
- helpers: C,
268
+ }, D = w.i18n?.resolve(l.cookie, l["accept-language"]), O = h.interactive ?? "full";
269
+ if (v) {
270
+ let e = N({
271
+ helpers: w,
272
272
  page: n.pattern,
273
- interactive: D,
273
+ interactive: O,
274
274
  delivery: "stream",
275
275
  renderInput: {
276
- descriptor: oe,
276
+ descriptor: ae,
277
277
  params: i,
278
278
  pathname: a,
279
- segmentLoaderData: b,
280
- requestContext: T,
281
- ...E ? {
282
- outerWrap: E.outerWrap,
283
- locale: E.locale
279
+ search: f,
280
+ segmentLoaderData: x,
281
+ requestContext: E,
282
+ ...D ? {
283
+ outerWrap: D.outerWrap,
284
+ locale: D.locale
284
285
  } : {}
285
286
  }
286
- }), t = E?.locale ?? T.cookies["voltro:locale"] ?? "en", r = (t) => ce({
287
- helpers: C,
287
+ }), t = D?.locale ?? E.cookies["voltro:locale"] ?? "en", r = (t) => se({
288
+ helpers: w,
288
289
  prepared: e,
289
290
  meta: t,
290
- interactive: D
291
+ interactive: O
291
292
  });
292
293
  if (e.hasDeferred) {
293
- let n = x({ shell: s });
294
+ let n = S({ shell: s });
294
295
  return {
295
296
  renderMode: "spa",
296
- stream: (i) => y({
297
+ stream: (i) => b({
297
298
  res: i,
298
299
  shell: n,
299
300
  htmlLang: t,
@@ -302,7 +303,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
302
303
  "x-voltro-rendered-by": "spa"
303
304
  },
304
305
  headInjection: r,
305
- render: (t) => C.renderPageToStream({
306
+ render: (t) => w.renderPageToStream({
306
307
  ...e.renderInput,
307
308
  ...t
308
309
  }),
@@ -312,8 +313,8 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
312
313
  })
313
314
  };
314
315
  }
315
- let o = h({
316
- helpers: C,
316
+ let o = g({
317
+ helpers: w,
317
318
  prepared: e
318
319
  });
319
320
  return {
@@ -322,37 +323,38 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
322
323
  revalidateMs: null
323
324
  };
324
325
  }
325
- let O = j({
326
- helpers: C,
326
+ let k = M({
327
+ helpers: w,
327
328
  page: n.pattern,
328
329
  pathname: a,
329
- renderMode: g,
330
- interactive: D,
331
- loaderData: ne,
332
- segmentLoaderData: b,
333
- pageLoaderRan: typeof m.loader == "function"
334
- }), k = {
335
- descriptor: oe,
330
+ renderMode: _,
331
+ interactive: O,
332
+ loaderData: te,
333
+ segmentLoaderData: x,
334
+ pageLoaderRan: typeof h.loader == "function"
335
+ }), A = {
336
+ descriptor: ae,
336
337
  params: i,
337
338
  pathname: a,
338
- loaderData: O.loaderData,
339
- segmentLoaderData: O.segmentLoaderData,
340
- requestContext: T,
341
- ...E ? {
342
- outerWrap: E.outerWrap,
343
- locale: E.locale
339
+ search: f,
340
+ loaderData: k.loaderData,
341
+ segmentLoaderData: k.segmentLoaderData,
342
+ requestContext: E,
343
+ ...D ? {
344
+ outerWrap: D.outerWrap,
345
+ locale: D.locale
344
346
  } : {}
345
- }, A = (e) => [
346
- C.renderMetaToHtml(e),
347
- `<meta name="voltro-interactive" content="${D}" />`,
348
- ...O.hasDeferred ? [C.renderDeferredRegistryScript()] : [],
349
- C.renderRouterStateScript(O.stateInput)
347
+ }, j = (e) => [
348
+ w.renderMetaToHtml(e),
349
+ `<meta name="voltro-interactive" content="${O}" />`,
350
+ ...k.hasDeferred ? [w.renderDeferredRegistryScript()] : [],
351
+ w.renderRouterStateScript(k.stateInput)
350
352
  ].filter((e) => e.length > 0).join("\n ");
351
- if (g === "ssr" && D === "full" && e.buffered !== !0) {
352
- let e = E?.locale ?? T.cookies["voltro:locale"] ?? "en", t = x({ shell: s });
353
+ if (_ === "ssr" && O === "full" && e.buffered !== !0) {
354
+ let e = D?.locale ?? E.cookies["voltro:locale"] ?? "en", t = S({ shell: s });
353
355
  return {
354
356
  renderMode: "ssr",
355
- stream: (n) => y({
357
+ stream: (n) => b({
356
358
  res: n,
357
359
  shell: t,
358
360
  htmlLang: e,
@@ -360,9 +362,9 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
360
362
  "content-type": "text/html; charset=utf-8",
361
363
  "x-voltro-rendered-by": "ssr"
362
364
  },
363
- headInjection: A,
364
- render: (e) => C.renderPageToStream({
365
- ...k,
365
+ headInjection: j,
366
+ render: (e) => w.renderPageToStream({
367
+ ...A,
366
368
  ...e
367
369
  }),
368
370
  onShellError: (e) => {
@@ -371,13 +373,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
371
373
  })
372
374
  };
373
375
  }
374
- let { html: le, meta: N } = C.renderPageToHtml(k), P = A(N), ue = E?.locale ?? T.cookies["voltro:locale"] ?? "en", F = s.replace("<div id=\"root\"></div>", `<div id="root">${le}</div>`).replace("</head>", ` ${P}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${ue}"`);
375
- D === "none" && (F = Se(F));
376
- let de = g === "isr" ? w(m.revalidate) : null;
376
+ let { html: ce, meta: P } = w.renderPageToHtml(A), F = j(P), le = D?.locale ?? E.cookies["voltro:locale"] ?? "en", I = s.replace("<div id=\"root\"></div>", `<div id="root">${ce}</div>`).replace("</head>", ` ${F}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${le}"`);
377
+ O === "none" && (I = Se(I));
378
+ let ue = _ === "isr" ? T(h.revalidate) : null;
377
379
  return {
378
- html: F,
379
- renderMode: g,
380
- revalidateMs: de
380
+ html: I,
381
+ renderMode: _,
382
+ revalidateMs: ue
381
383
  };
382
384
  }, $ = (e) => e === "" ? "/" : e, De = async (e) => {
383
385
  let t = await import(B(e).href);
@@ -410,7 +412,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
410
412
  async close() {}
411
413
  };
412
414
  }, Oe = async (e, t) => {
413
- let n = await v("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
415
+ let n = await y("vite", () => import("vite")), r = (await import("@vitejs/plugin-react")).default, i = (await import("@tailwindcss/vite")).default, a = await n.createServer({
414
416
  root: t,
415
417
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
416
418
  plugins: [r(), i()],
@@ -422,7 +424,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
422
424
  },
423
425
  appType: "custom",
424
426
  logLevel: "warn"
425
- }), o = L(e, "src", "pages"), c = (e) => e === "" ? o : L(o, e), l = d({
427
+ }), o = R(e, "src", "pages"), c = (e) => e === "" ? o : R(o, e), l = d({
426
428
  limit: s(),
427
429
  onColdStart: (e) => J.debug("ssr cold-compile start", { id: e }),
428
430
  onColdEnd: (e, { durationMs: t, failed: n }) => J.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
@@ -434,16 +436,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
434
436
  return {
435
437
  kind: "middleware",
436
438
  async getPage(e, t) {
437
- return u(L(o, t));
439
+ return u(R(o, t));
438
440
  },
439
441
  async getLayout(e) {
440
- return u(L(c(e), "layout.tsx"));
442
+ return u(R(c(e), "layout.tsx"));
441
443
  },
442
444
  async getError(e) {
443
- return u(L(c(e), "error.tsx"));
445
+ return u(R(c(e), "error.tsx"));
444
446
  },
445
447
  async getPending(e) {
446
- return u(L(c(e), "loading.tsx"));
448
+ return u(R(c(e), "loading.tsx"));
447
449
  },
448
450
  async getHelpers() {
449
451
  return await u("@voltro/web/ssr");
@@ -453,7 +455,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
453
455
  }
454
456
  };
455
457
  }, ke = async (r) => {
456
- let s = fe(), c = await k(r);
458
+ let s = de(), c = await A(r);
457
459
  if (!c) return {
458
460
  ran: !1,
459
461
  exitCode: 0
@@ -462,51 +464,51 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
462
464
  ran: !0,
463
465
  exitCode: 1
464
466
  };
465
- let { resolved: d } = await ae({
467
+ let { resolved: d } = await ie({
466
468
  rawEnv: c.env,
467
469
  appType: "web",
468
470
  root: r,
469
471
  log: J,
470
472
  generateTypes: !1
471
- }), p = d.publicValues;
473
+ }), m = d.publicValues;
472
474
  s.mark("config");
473
- let h = i();
474
- u(h), J.info("booting voltro start", { app: c.name ?? "(unnamed)" });
475
- let v = (() => {
475
+ let g = i();
476
+ u(g), J.info("booting voltro start", { app: c.name ?? "(unnamed)" });
477
+ let y = (() => {
476
478
  if (process.env.VOLTRO_IS_DASHBOARD === "1" && process.env.VOLTRO_DASHBOARD_PORT) return Number(process.env.VOLTRO_DASHBOARD_PORT);
477
479
  if (process.env.PORT) {
478
480
  let e = Number(process.env.PORT);
479
481
  if (Number.isFinite(e) && e > 0) return e;
480
482
  }
481
483
  return c.port ?? 5173;
482
- })(), y = L(r, ".framework"), x = L(y, "dist"), re = L(x, "index.html");
483
- if (!await Q(re)) return J.error("no built dist found — run `voltro build` first", { distDir: x }), {
484
+ })(), b = R(r, ".framework"), S = R(b, "dist"), ne = R(S, "index.html");
485
+ if (!await Q(ne)) return J.error("no built dist found — run `voltro build` first", { distDir: S }), {
484
486
  ran: !0,
485
487
  exitCode: 1
486
488
  };
487
- let S = c.name ?? "unnamed", w = C("web", S, v), j = o(S);
488
- await f({
489
- id: w,
490
- name: S,
489
+ let C = c.name ?? "unnamed", T = w("web", C, y), M = o(C);
490
+ await p({
491
+ id: T,
492
+ name: C,
491
493
  kind: "web",
492
- url: `http://localhost:${v}`,
494
+ url: `http://localhost:${y}`,
493
495
  pid: process.pid,
494
496
  status: "booting",
495
- logFile: j.path
497
+ logFile: M.path
496
498
  }).catch(() => {});
497
- let ce = L(x, "_voltro", "shell.html"), M = await Q(ce) ? await H.readFile(ce, "utf8") : await H.readFile(re, "utf8"), I = await g(r, c), pe = D(I[0]), R = I[0]?.name, z, B = null;
499
+ let se = R(S, "_voltro", "shell.html"), N = await Q(se) ? await H.readFile(se, "utf8") : await H.readFile(ne, "utf8"), L = await _(r, c), fe = O(L[0]), pe = L[0]?.name, z, B = null;
498
500
  process.env.SSR_CACHE === "postgres" && process.env.PG_HOST ? (B = new (await (import("pg"))).default.Client({
499
501
  host: process.env.PG_HOST,
500
502
  port: Number(process.env.PG_PORT ?? 5432),
501
503
  user: process.env.PG_USER ?? "app",
502
504
  password: process.env.PG_PASSWORD ?? "app",
503
505
  database: process.env.PG_DATABASE ?? "app"
504
- }), await B.connect(), z = ye({ client: B }), J.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (z = m(), J.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await T(r, c, I, p);
505
- let { pages: V, dirs: U } = await _(L(r, "src", "pages")), W = we(V);
506
+ }), await B.connect(), z = ye({ client: B }), J.info("isr cache backend: postgres", { table: "voltro_isr_cache" })) : (z = h(), J.info("isr cache backend: memory (per-process)", { hint: "set SSR_CACHE=postgres for persistent storage" })), await E(r, c, L, m);
507
+ let { pages: V, dirs: U } = await v(R(r, "src", "pages")), W = we(V);
506
508
  s.mark("scan");
507
- let G = L(x, "server", "ssrEntry.js"), K = await Q(G);
509
+ let G = R(S, "server", "ssrEntry.js"), K = await Q(G);
508
510
  if (!K && process.env.NODE_ENV === "production") throw J.fatal(`production \`voltro start\` requires a precompiled SSR bundle at ${G} but it is missing. Run \`voltro build\` before serving — production renders from the bundle and never compiles on demand.`), Error(`[voltro start] missing SSR bundle at ${G}`);
509
- let q = K ? await De(G) : await Oe(r, y);
511
+ let q = K ? await De(G) : await Oe(r, b);
510
512
  J.info(`ssr loader: ${q.kind}`, {
511
513
  kind: q.kind,
512
514
  ...q.kind === "middleware" ? { hint: "no pre-built SSR bundle found; run `voltro build` to enable bundle mode" } : {}
@@ -531,7 +533,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
531
533
  fromModules: X
532
534
  }), s.mark("routes");
533
535
  let Z = /* @__PURE__ */ new Set();
534
- for (let e of W) Y.get(e.pattern)?.renderMode === "spa" && se(U, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
536
+ for (let e of W) Y.get(e.pattern)?.renderMode === "spa" && oe(U, e.dirChain).some((e) => e.hasLayout) && Z.add(e.pattern);
535
537
  Z.size > 0 && J.info(`${Z.size} spa route(s) render an SSR layout shell`, { patterns: [...Z] });
536
538
  let Se = /* @__PURE__ */ new Map();
537
539
  for (let [e, t] of Y) t.cacheInvalidatesOn.length > 0 && Se.set(e, t.cacheInvalidatesOn);
@@ -543,7 +545,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
543
545
  regexByPattern: Ce
544
546
  });
545
547
  await $.start(), s.mark("cdc");
546
- let ke = A(), Ae = V.map((e) => {
548
+ let ke = j(), Ae = V.map((e) => {
547
549
  let t = Y.get(e.pattern);
548
550
  return {
549
551
  pattern: e.pattern,
@@ -570,7 +572,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
570
572
  meta: {
571
573
  name: c.name ?? "(unnamed)",
572
574
  voltroVersion: be,
573
- port: v,
575
+ port: y,
574
576
  mode: "start",
575
577
  apis: Object.entries(c.apis ?? {}).map(([e, t]) => {
576
578
  let n = {
@@ -603,7 +605,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
603
605
  }, Pe = async (t, n) => {
604
606
  let i = t.split("?")[0] ?? "/";
605
607
  if (c.name === "voltroDashboard" && i === "/api/dashboard/registry") try {
606
- let e = await ne();
608
+ let e = await te();
607
609
  return {
608
610
  status: 200,
609
611
  headers: { "content-type": "application/json; charset=utf-8" },
@@ -651,13 +653,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
651
653
  status: r.status,
652
654
  headers: {
653
655
  "content-type": r.contentType,
654
- ...N(n.origin)
656
+ ...P(n.origin)
655
657
  },
656
658
  body: r.body
657
659
  };
658
660
  }
659
661
  if (i !== "/_voltro/inspect/stream") {
660
- let e = de(t, Ne, n);
662
+ let e = ue(t, Ne, n);
661
663
  if (e !== null) return {
662
664
  status: e.status,
663
665
  headers: {
@@ -667,14 +669,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
667
669
  body: e.body
668
670
  };
669
671
  }
670
- let a = Te(i, W), o = a ? Y.get(a.route.pattern)?.renderMode : void 0, s = o === "ssr" || o === "isr" || (a ? Z.has(a.route.pattern) : !1), l = i === "/" ? L(x, "index.html") : L(x, i.replace(/^\//, ""), "index.html");
672
+ let a = Te(i, W), o = a ? Y.get(a.route.pattern)?.renderMode : void 0, s = o === "ssr" || o === "isr" || (a ? Z.has(a.route.pattern) : !1), l = i === "/" ? R(S, "index.html") : R(S, i.replace(/^\//, ""), "index.html");
671
673
  if (!s && await Q(l)) return {
672
674
  status: 200,
673
675
  headers: { "content-type": "text/html; charset=utf-8" },
674
676
  body: await H.readFile(l)
675
677
  };
676
678
  if (/\.[a-z0-9]+$/i.test(i)) {
677
- let e = L(x, i.replace(/^\//, ""));
679
+ let e = R(S, i.replace(/^\//, ""));
678
680
  if (await Q(e)) {
679
681
  let t = await H.readFile(e);
680
682
  return {
@@ -690,29 +692,29 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
690
692
  headers: { "content-type": "text/plain" },
691
693
  body: "not found"
692
694
  };
693
- let d = Y.get(u.route.pattern), f = n["x-tenant"] ?? "anonymous", p = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, m = oe(i, {
694
- ...d?.tenantAware ? { tenant: f } : {},
695
- ...p ? { locale: p } : {}
696
- }), g = z.get(m), _ = Date.now();
697
- if (g && O(g, _)) return h.emit("cache", {
695
+ let d = Y.get(u.route.pattern), p = n["x-tenant"] ?? "anonymous", m = (await q.getHelpers()).i18n?.resolve(n.cookie, n["accept-language"])?.locale, h = ae(i, {
696
+ ...d?.tenantAware ? { tenant: p } : {},
697
+ ...m ? { locale: m } : {}
698
+ }), _ = z.get(h), v = Date.now();
699
+ if (_ && k(_, v)) return g.emit("cache", {
698
700
  kind: "HIT",
699
- key: m,
700
- ageMs: _ - g.renderedAt
701
+ key: h,
702
+ ageMs: v - _.renderedAt
701
703
  }), {
702
704
  status: 200,
703
705
  headers: {
704
706
  "content-type": "text/html; charset=utf-8",
705
707
  "x-voltro-rendered-by": "isr",
706
708
  "x-voltro-cache": "HIT",
707
- "x-voltro-cache-key": m,
708
- "x-voltro-cache-age-ms": String(_ - g.renderedAt)
709
+ "x-voltro-cache-key": h,
710
+ "x-voltro-cache-age-ms": String(v - _.renderedAt)
709
711
  },
710
- body: g.html
712
+ body: _.html
711
713
  };
712
- if (g && ie(g, _)) return h.emit("cache", {
714
+ if (_ && re(_, v)) return g.emit("cache", {
713
715
  kind: "STALE",
714
- key: m,
715
- ageMs: _ - g.renderedAt
716
+ key: h,
717
+ ageMs: v - _.renderedAt
716
718
  }), (async () => {
717
719
  try {
718
720
  let e = await Ee({
@@ -722,16 +724,16 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
722
724
  params: u.params,
723
725
  pathname: i,
724
726
  dirs: U,
725
- shellTemplate: M,
727
+ shellTemplate: N,
726
728
  requestHeaders: n,
727
- apiOrigin: pe,
728
- apiName: R,
729
+ apiOrigin: fe,
730
+ apiName: pe,
729
731
  requestUrl: t,
730
732
  buffered: !0
731
733
  });
732
734
  if (e && "html" in e && e.renderMode === "isr" && e.revalidateMs !== null) {
733
735
  let t = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0, n = Date.now();
734
- z.set(m, {
736
+ z.set(h, {
735
737
  html: e.html,
736
738
  renderedAt: n,
737
739
  expiresAt: n + e.revalidateMs,
@@ -749,10 +751,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
749
751
  "content-type": "text/html; charset=utf-8",
750
752
  "x-voltro-rendered-by": "isr",
751
753
  "x-voltro-cache": "STALE",
752
- "x-voltro-cache-key": m,
753
- "x-voltro-cache-age-ms": String(_ - g.renderedAt)
754
+ "x-voltro-cache-key": h,
755
+ "x-voltro-cache-age-ms": String(v - _.renderedAt)
754
756
  },
755
- body: g.html
757
+ body: _.html
756
758
  };
757
759
  try {
758
760
  let e = await Ee({
@@ -762,10 +764,10 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
762
764
  params: u.params,
763
765
  pathname: i,
764
766
  dirs: U,
765
- shellTemplate: M,
767
+ shellTemplate: N,
766
768
  requestHeaders: n,
767
- apiOrigin: pe,
768
- apiName: R,
769
+ apiOrigin: fe,
770
+ apiName: pe,
769
771
  requestUrl: t
770
772
  });
771
773
  if (!e) return {
@@ -774,7 +776,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
774
776
  "content-type": "text/html; charset=utf-8",
775
777
  "x-voltro-rendered-by": "spa-fallback"
776
778
  },
777
- body: M
779
+ body: N
778
780
  };
779
781
  if ("stream" in e) return {
780
782
  status: 200,
@@ -803,22 +805,22 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
803
805
  };
804
806
  if (e.renderMode === "isr" && e.revalidateMs !== null) {
805
807
  let t = Date.now(), n = Y.get(u.route.pattern)?.staleWhileRevalidateMs ?? 0;
806
- z.set(m, {
808
+ z.set(h, {
807
809
  html: e.html,
808
810
  renderedAt: t,
809
811
  expiresAt: t + e.revalidateMs,
810
812
  servableUntil: t + e.revalidateMs + n,
811
813
  revalidateMs: e.revalidateMs,
812
814
  staleWhileRevalidateMs: n
813
- }), a["x-voltro-cache"] = "MISS", a["x-voltro-cache-key"] = m, a["x-voltro-cache-revalidate-ms"] = String(e.revalidateMs), n > 0 && (a["x-voltro-cache-swr-ms"] = String(n)), h.emit("cache", {
815
+ }), a["x-voltro-cache"] = "MISS", a["x-voltro-cache-key"] = h, a["x-voltro-cache-revalidate-ms"] = String(e.revalidateMs), n > 0 && (a["x-voltro-cache-swr-ms"] = String(n)), g.emit("cache", {
814
816
  kind: "MISS",
815
- key: m,
817
+ key: h,
816
818
  revalidateMs: e.revalidateMs,
817
819
  swrMs: n
818
820
  });
819
- } else e.renderMode === "isr" && (a["x-voltro-cache"] = "BYPASS", h.emit("cache", {
821
+ } else e.renderMode === "isr" && (a["x-voltro-cache"] = "BYPASS", g.emit("cache", {
820
822
  kind: "BYPASS",
821
- key: m
823
+ key: h
822
824
  }));
823
825
  return {
824
826
  status: 200,
@@ -826,7 +828,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
826
828
  body: e.html
827
829
  };
828
830
  } catch (e) {
829
- return J.error("render error", { url: i }, e), te(e) ? {
831
+ return J.error("render error", { url: i }, e), f(e) ? {
830
832
  status: 500,
831
833
  headers: {
832
834
  "content-type": "text/plain; charset=utf-8",
@@ -859,7 +861,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
859
861
  return;
860
862
  }
861
863
  if (s === "OPTIONS" && o.startsWith("/_voltro/inspect")) {
862
- let e = N(a.origin);
864
+ let e = P(a.origin);
863
865
  t.writeHead(204, e), t.end();
864
866
  return;
865
867
  }
@@ -869,13 +871,13 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
869
871
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
870
872
  return;
871
873
  }
872
- if (!P(n)) {
874
+ if (!F(n)) {
873
875
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
874
876
  return;
875
877
  }
876
878
  try {
877
879
  let r = { accept: a.accept ?? "application/json" }, i = a.authorization;
878
- i ? r.authorization = Array.isArray(i) ? i[0] : i : le(n) && process.env.VOLTRO_INSPECT_TOKEN && (r.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
880
+ i ? r.authorization = Array.isArray(i) ? i[0] : i : ce(n) && process.env.VOLTRO_INSPECT_TOKEN && (r.authorization = `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}`);
879
881
  let o;
880
882
  if (s && s !== "GET" && s !== "HEAD") {
881
883
  let t = [];
@@ -905,14 +907,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
905
907
  t.writeHead(400, { "content-type": "text/plain" }), t.end("missing ?target=");
906
908
  return;
907
909
  }
908
- if (!P(n)) {
910
+ if (!F(n)) {
909
911
  t.writeHead(400, { "content-type": "text/plain" }), t.end("target not allowed: must be loopback or an origin configured in VOLTRO_DASHBOARD_APPS");
910
912
  return;
911
913
  }
912
914
  let i = new AbortController();
913
915
  e.on("close", () => i.abort()), t.on("close", () => i.abort());
914
916
  try {
915
- let e = a.authorization ?? (le(n) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), r = await fetch(n, {
917
+ let e = a.authorization ?? (ce(n) && process.env.VOLTRO_INSPECT_TOKEN ? `Bearer ${process.env.VOLTRO_INSPECT_TOKEN}` : void 0), r = await fetch(n, {
916
918
  redirect: "manual",
917
919
  method: "GET",
918
920
  headers: {
@@ -947,15 +949,15 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
947
949
  return;
948
950
  }
949
951
  if (o === "/_voltro/inspect/stream") {
950
- let r = N(a.origin);
951
- if (F()) {
952
+ let r = P(a.origin);
953
+ if (I()) {
952
954
  t.writeHead(503, {
953
955
  "content-type": "application/json",
954
956
  ...r
955
957
  }), t.end(JSON.stringify({ error: "inspect disabled (VOLTRO_INSPECT=off)" }));
956
958
  return;
957
959
  }
958
- let i = ue(a, "GET");
960
+ let i = le(a, "GET");
959
961
  if (!i.ok) {
960
962
  t.writeHead(401, {
961
963
  "content-type": "application/json",
@@ -973,11 +975,11 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
973
975
  "x-accel-buffering": "no",
974
976
  ...r
975
977
  }), t.flushHeaders(), t.write("retry: 5000\n\n");
976
- for (let e of h.buffered()) t.write(n(e));
977
- let o = h.subscribe((e) => {
978
+ for (let e of g.buffered()) t.write(n(e));
979
+ let o = g.subscribe((e) => {
978
980
  t.write(n(e));
979
981
  }), s = setInterval(() => {
980
- t.write(E());
982
+ t.write(D());
981
983
  }, 15e3), c = () => {
982
984
  clearInterval(s), o();
983
985
  };
@@ -988,7 +990,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
988
990
  let e = await Pe(r, a);
989
991
  if (e.stream ? e.stream(t) : (t.writeHead(e.status, e.headers), t.end(e.body)), !o.startsWith("/_voltro/inspect")) {
990
992
  let t = Date.now() - i;
991
- h.emit("request", {
993
+ g.emit("request", {
992
994
  url: o,
993
995
  status: e.status,
994
996
  durationMs: t,
@@ -1007,19 +1009,19 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1007
1009
  t.writeHead(500, { "content-type": "text/plain" }), t.end(`internal error: ${e.message}`);
1008
1010
  }
1009
1011
  });
1010
- await new Promise((e) => Ie.listen(v, "::", e)), Fe = !0, s.mark("ready"), J.info(`listening on http://localhost:${v}`, {
1011
- port: v,
1012
- distDir: x
1012
+ await new Promise((e) => Ie.listen(y, "::", e)), Fe = !0, s.mark("ready"), J.info(`listening on http://localhost:${y}`, {
1013
+ port: y,
1014
+ distDir: S
1013
1015
  }), J.debug("dynamic + ssr/isr routes resolve via SSR loader");
1014
1016
  try {
1015
- await f({
1016
- id: w,
1017
- name: S,
1017
+ await p({
1018
+ id: T,
1019
+ name: C,
1018
1020
  kind: "web",
1019
- url: `http://localhost:${v}`,
1021
+ url: `http://localhost:${y}`,
1020
1022
  pid: process.pid,
1021
1023
  status: "live",
1022
- logFile: j.path
1024
+ logFile: M.path
1023
1025
  });
1024
1026
  let e = t(r);
1025
1027
  if (e) {
@@ -1027,14 +1029,14 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1027
1029
  t.status === "launched" ? J.info(`dashboard launched at http://localhost:${t.port}`, { port: t.port }) : t.status === "already-running" && J.debug(`dashboard already running on :${t.port}`, { port: t.port });
1028
1030
  }
1029
1031
  setInterval(() => {
1030
- f({
1031
- id: w,
1032
- name: S,
1032
+ p({
1033
+ id: T,
1034
+ name: C,
1033
1035
  kind: "web",
1034
- url: `http://localhost:${v}`,
1036
+ url: `http://localhost:${y}`,
1035
1037
  pid: process.pid,
1036
1038
  status: "live",
1037
- logFile: j.path
1039
+ logFile: M.path
1038
1040
  }).catch(() => {});
1039
1041
  }, 1e4).unref();
1040
1042
  } catch (e) {
@@ -1043,7 +1045,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1043
1045
  me({
1044
1046
  app: c.name ?? "unnamed",
1045
1047
  kind: "web",
1046
- url: `http://localhost:${v}`,
1048
+ url: `http://localhost:${y}`,
1047
1049
  bootMs: s.total()
1048
1050
  });
1049
1051
  let Le = s.phaseBreakdown();
@@ -1056,7 +1058,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1056
1058
  if (Re = !0, J.info(`received ${e}, shutting down`, { signal: e }), Ie.close(), await $.stop(), B) try {
1057
1059
  await B.end();
1058
1060
  } catch {}
1059
- await q.close(), await b(w), await j.dispose(), process.exit(0);
1061
+ await q.close(), await x(T), await M.dispose(), process.exit(0);
1060
1062
  }
1061
1063
  };
1062
1064
  process.on("SIGINT", ze("SIGINT")), process.on("SIGTERM", ze("SIGTERM"));
@@ -1070,7 +1072,7 @@ CREATE INDEX IF NOT EXISTS ${e}_servable_until_idx ON ${e} (servable_until);
1070
1072
  return new Promise(() => {});
1071
1073
  }, Ae = async (e) => {
1072
1074
  process.env.NODE_ENV || (process.env.NODE_ENV = "production");
1073
- let t = await ke(R(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1075
+ let t = await ke(pe(e.find((e) => !e.startsWith("-")) ?? process.cwd()));
1074
1076
  return t.ran ? t.exitCode : (J.error("no web app found at this path"), 1);
1075
1077
  };
1076
1078
  //#endregion