@voltro/cli 0.55.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/CHANGELOG.md +691 -0
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/apiBuild-B83Cb2Rv.js +2 -0
  4. package/dist/{apiBuild-CMvLJM_K.js → apiBuild-DDr2aNFd.js} +119 -88
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-S0QOzqPT.js → build-QKP6Bm0J.js} +308 -279
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-DNkY5kwF.js → checkCommand-BISqx1OJ.js} +1 -1
  9. package/dist/{checkCommand-fbj9GDjN.js → checkCommand-DUtMWjcR.js} +6 -6
  10. package/dist/{clusterCmd-DrVFCzSj.js → clusterCmd-CdLB1GkT.js} +1 -1
  11. package/dist/{codegen-SIepQtUl.js → codegen-Bth5lUTU.js} +2 -1
  12. package/dist/codegen-DbH7NbCR.js +2 -0
  13. package/dist/{codegenCommand-3TDJezom.js → codegenCommand-DnVuDxwT.js} +11 -11
  14. package/dist/{codemodRunner-C2zxZUIw.js → codemodRunner-BlQPfjzA.js} +222 -0
  15. package/dist/{commands-BBYJ7Q3B.js → commands-CRbxgxv0.js} +35 -35
  16. package/dist/{dashboardCommand-D2kmyCLL.js → dashboardCommand-Bf_-Ne3P.js} +5 -5
  17. package/dist/{dataCommand-BEPPQiTl.js → dataCommand-BoBJJ-Gb.js} +3 -3
  18. package/dist/{dbCommand-DZTmOFT4.js → dbCommand-CMAIz-Bf.js} +457 -441
  19. package/dist/dbCommand-DHi_RuDl.js +2 -0
  20. package/dist/dev-Bl9HqtV7.js +3 -0
  21. package/dist/{dev-Ca_A_S9v.js → dev-DOEJXicj.js} +2623 -2485
  22. package/dist/{doctorCommand-CGZJK_4o.js → doctorCommand-BrWu67JZ.js} +524 -280
  23. package/dist/doctorCommand-DrQv9SL3.js +2 -0
  24. package/dist/{dormancyCommand-DY2rYpTa.js → dormancyCommand-xn2y-pJm.js} +1 -1
  25. package/dist/{embeddingsCommand-BoCqZsgp.js → embeddingsCommand-Cn5MbRDM.js} +1 -1
  26. package/dist/emptyResultHeadline-Csa5fZOF.js +18 -0
  27. package/dist/{envCommand-Bxy2fOjc.js → envCommand-UJmJIbs9.js} +8 -8
  28. package/dist/{evolveCommand-BsbZ-XDg.js → evolveCommand-Db30twUy.js} +2 -2
  29. package/dist/frameworkTableAssembly-B96WCNJA.js +2 -0
  30. package/dist/{frameworkTableAssembly-Do-cf6RJ.js → frameworkTableAssembly-vfkzuzEo.js} +131 -104
  31. package/dist/index.js +1 -1
  32. package/dist/{infoCommand-EmM3jPKD.js → infoCommand-BjVXpMlP.js} +1 -1
  33. package/dist/inspect-B0hL41s0.js +2 -0
  34. package/dist/inspect-DZnan87F.js +1500 -0
  35. package/dist/{inspectCmd-niF97fAq.js → inspectCmd-CP-G0sVK.js} +1 -1
  36. package/dist/{inspectFetch-EMuhTG_9.js → inspectFetch-BU1NyzxV.js} +36 -24
  37. package/dist/{inspectMetrics-CGF94puw.js → inspectMetrics-BY0Sjb2F.js} +19 -19
  38. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-C5y9HyrG.js} +59 -54
  39. package/dist/{manifestBuild-DjX5MoXy.js → manifestBuild-DnbFKF6w.js} +1 -1
  40. package/dist/manifestBuild-UXrnUcXP.js +2 -0
  41. package/dist/{migrate-CGFZS-1a.js → migrate-DtC3lu7H.js} +4 -4
  42. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  43. package/dist/{probeCommand-Bs3iVBSL.js → probeCommand-C5fuN6Z2.js} +2 -2
  44. package/dist/{runtimeTrace-C1BTpHGQ.js → runtimeTrace-BQL_lfz6.js} +1 -1
  45. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  46. package/dist/{sdkgen-CXMwLg9n.js → sdkgen-CMUPrDjH.js} +1 -1
  47. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  48. package/dist/serveCommand-B_w-Mpb_.js +2544 -0
  49. package/dist/serveCommand-Dtb48ffg.js +2 -0
  50. package/dist/serveEntry.js +1 -1
  51. package/dist/{start-EOV7s1NZ.js → start-YaUehtDV.js} +580 -558
  52. package/dist/{start-DH7cat4-.js → start-s25GAIgn.js} +1 -1
  53. package/dist/startEntry.js +1 -1
  54. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  55. package/dist/{test-DO27-x2P.js → test-jipIQ5Mx.js} +1 -1
  56. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-C1qKa94g.js} +69 -64
  57. package/dist/{updateCommand-C_jN1w18.js → updateCommand-C9n_Z_oG.js} +8 -2
  58. package/dist/updateCommand-DsXEAHbd.js +2 -0
  59. package/dist/webDev-B6ZMX42w.js +2 -0
  60. package/dist/{webDev-B7vNj4Bq.js → webDev-BgdkyjP6.js} +1379 -1303
  61. package/dist/{webhooksCommand-B1LVcyO3.js → webhooksCommand-CYXTNvXq.js} +2 -2
  62. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  63. package/package.json +55 -19
  64. package/templates/AGENTS.core.md +20 -1
  65. package/templates/AGENTS.md +21 -2
  66. package/templates/agent-docs/_index.md +1 -1
  67. package/templates/agent-docs/_manifest.json +2 -2
  68. package/templates/agent-docs/ai.md +1 -1
  69. package/templates/agent-docs/authentication.md +34 -19
  70. package/templates/agent-docs/cli.md +170 -0
  71. package/templates/agent-docs/configuration.md +29 -4
  72. package/templates/agent-docs/data.md +145 -5
  73. package/templates/agent-docs/database/scaling.md +50 -2
  74. package/templates/agent-docs/deployment.md +75 -1
  75. package/templates/agent-docs/internationalization.md +32 -0
  76. package/templates/agent-docs/local-first-mobile.md +9 -2
  77. package/templates/agent-docs/observability.md +227 -0
  78. package/templates/agent-docs/plugins/audit.md +21 -5
  79. package/templates/agent-docs/plugins/billing.md +17 -0
  80. package/templates/agent-docs/plugins/broadcast.md +2 -1
  81. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  82. package/templates/agent-docs/plugins/row-history.md +11 -0
  83. package/templates/agent-docs/plugins.md +19 -0
  84. package/templates/agent-docs/reference.md +1 -0
  85. package/templates/agent-docs/scheduling.md +23 -0
  86. package/templates/agent-docs/schema-driven-ui.md +81 -0
  87. package/templates/agent-docs/templates/appshells.md +3 -3
  88. package/templates/agent-docs/whats-new.md +133 -77
  89. package/templates/apps/api-ai/package.json +6 -6
  90. package/templates/apps/api-auth/package.json +8 -8
  91. package/templates/apps/api-backend/package.json +7 -7
  92. package/templates/apps/api-backend-deactivation/package.json +7 -7
  93. package/templates/apps/api-backend-mail/package.json +8 -8
  94. package/templates/apps/api-backend-mariadb/package.json +9 -9
  95. package/templates/apps/api-backend-sqlite/package.json +8 -8
  96. package/templates/apps/api-backend-storage/package.json +8 -8
  97. package/templates/apps/api-cms/package.json +9 -9
  98. package/templates/apps/api-collab/package.json +8 -8
  99. package/templates/apps/api-data-advanced/package.json +8 -8
  100. package/templates/apps/api-durable/package.json +8 -8
  101. package/templates/apps/api-feature-flags/package.json +9 -9
  102. package/templates/apps/api-governance/package.json +8 -8
  103. package/templates/apps/api-kv/package.json +8 -8
  104. package/templates/apps/api-moderation/package.json +8 -8
  105. package/templates/apps/api-observability/package.json +8 -8
  106. package/templates/apps/api-ratelimit/package.json +8 -8
  107. package/templates/apps/api-rbac/package.json +8 -8
  108. package/templates/apps/api-rest/package.json +7 -7
  109. package/templates/apps/api-row-history/package.json +8 -8
  110. package/templates/apps/api-saas/package.json +11 -11
  111. package/templates/apps/api-saas-starter/package.json +10 -10
  112. package/templates/apps/api-search/package.json +8 -8
  113. package/templates/apps/api-status/package.json +8 -8
  114. package/templates/apps/api-webhooks/package.json +9 -9
  115. package/templates/apps/changelog/package.json +7 -7
  116. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  117. package/templates/apps/edge-functions/package.json +2 -2
  118. package/templates/apps/frontend-admin/package.json +7 -8
  119. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  120. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  121. package/templates/apps/frontend-app/package.json +8 -9
  122. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  123. package/templates/apps/frontend-auth/package.json +7 -8
  124. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  125. package/templates/apps/frontend-blank/package.json +6 -7
  126. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  127. package/templates/apps/frontend-cms/package.json +8 -9
  128. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  129. package/templates/apps/frontend-collab/README.md +7 -2
  130. package/templates/apps/frontend-collab/package.json +9 -10
  131. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  132. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  133. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  134. package/templates/apps/frontend-contact/package.json +7 -7
  135. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  136. package/templates/apps/frontend-dashboard/package.json +6 -7
  137. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  138. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  139. package/templates/apps/frontend-docs/package.json +8 -8
  140. package/templates/apps/frontend-i18n/package.json +6 -6
  141. package/templates/apps/frontend-landing/package.json +7 -7
  142. package/templates/apps/frontend-portal/package.json +7 -8
  143. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  144. package/templates/apps/frontend-saas/package.json +7 -8
  145. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  146. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  147. package/templates/apps/frontend-spa/package.json +6 -7
  148. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  149. package/templates/apps/frontend-ssr/package.json +6 -7
  150. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  151. package/templates/apps/frontend-ssr-api/package.json +7 -8
  152. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  153. package/templates/apps/frontend-static-blog/package.json +8 -8
  154. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  155. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  156. package/templates/apps/frontend-status/package.json +7 -8
  157. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  158. package/templates/apps/mobile-app/package.json +4 -4
  159. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  160. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  161. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  162. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  163. package/dist/apiBuild-Cl0IDx8c.js +0 -2
  164. package/dist/codegen-CN6vMM4J.js +0 -2
  165. package/dist/dbCommand-BTyBGhIA.js +0 -2
  166. package/dist/dev-DfVZaoys.js +0 -3
  167. package/dist/doctorCommand-djmqEcDC.js +0 -2
  168. package/dist/frameworkTableAssembly-Df2Ymp2f.js +0 -2
  169. package/dist/inspect-DCqILJ1G.js +0 -1197
  170. package/dist/inspect-DGJwpOAb.js +0 -2
  171. package/dist/manifestBuild-CJ2zvPvT.js +0 -2
  172. package/dist/serveCommand-C7IrCD58.js +0 -2445
  173. package/dist/serveCommand-Cjt5S9hD.js +0 -2
  174. package/dist/updateCommand-nnFjDbl4.js +0 -2
  175. package/dist/webDev-1XpVnYkW.js +0 -2
@@ -1,23 +1,24 @@
1
- import { bn as e } from "./dev-Ca_A_S9v.js";
2
- import { B as t, C as n, Ct as r, Dt as i, Et as a, J as o, Kt as s, Nt as c, St as l, Ut as u, V as d, Y as f, _t as p, a as m, b as h, bt as g, dt as _, ft as v, gt as y, l as b, m as x, p as S, q as C, s as w, ut as T, vt as E, wt as D, x as O, xt as k, yt as A, z as j } from "./webDev-B7vNj4Bq.js";
3
- import { t as M } from "./cliRuntime-Dh7UDinH.js";
4
- import { a as N } from "./renderModeScan-43yQ2opo.js";
5
- import { o as P } from "./imagePipeline-CBZmjT4i.js";
6
- import { a as F } from "./fontPipeline-Tsh8kZfA.js";
7
- import { i as I, o as L, s as R } from "./apiBuild-CMvLJM_K.js";
8
- import { n as z } from "./renderProfile-DvrhVJHa.js";
9
- import { dirname as B, join as V, resolve as H } from "node:path";
10
- import { existsSync as U, promises as W } from "node:fs";
1
+ import { kn as e } from "./dev-DOEJXicj.js";
2
+ import { $ as t, At as n, Ct as r, Dt as i, Et as a, G as o, It as s, Kt as c, Q as l, S as u, St as d, Tt as f, U as p, W as m, Yt as h, Z as g, bt as _, c as v, h as y, ht as b, kt as x, m as S, mt as C, o as w, pt as T, u as E, w as D, wt as ee, x as te, xt as O, yt as k } from "./webDev-BgdkyjP6.js";
3
+ import { d as A, i as j, o as M, s as N } from "./apiBuild-DDr2aNFd.js";
4
+ import { t as P } from "./cliRuntime-Dh7UDinH.js";
5
+ import { a as F } from "./renderModeScan-43yQ2opo.js";
6
+ import { o as I } from "./imagePipeline-CBZmjT4i.js";
7
+ import { a as L } from "./fontPipeline-Tsh8kZfA.js";
8
+ import { n as R } from "./renderProfile-DvrhVJHa.js";
9
+ import { dirname as z, join as B, resolve as V } from "node:path";
10
+ import { existsSync as H, promises as U } from "node:fs";
11
11
  import "node:url";
12
- import { createLogger as G } from "@voltro/logger";
12
+ import { createLogger as W } from "@voltro/logger";
13
+ import { setProcessBootPath as G } from "@voltro/protocol/identity";
13
14
  import { Effect as K } from "effect";
14
15
  import { createRequire as q } from "node:module";
15
16
  //#region src/webStartBundle.ts
16
- var J = G({ scope: "voltro:build" }), ee = async (e) => {
17
- let t = await s("esbuild", () => import("esbuild")), n = V(e, ".framework"), r = V(n, "dist-web", "startBundle");
18
- await W.mkdir(n, { recursive: !0 });
19
- let i = Date.now(), a = V(e, "tsconfig.json"), o = /* @__PURE__ */ new Set(), c = V(n, "startEntry.ts");
20
- await W.writeFile(c, [
17
+ var J = W({ scope: "voltro:build" }), ne = async (e) => {
18
+ let t = await h("esbuild", () => import("esbuild")), n = B(e, ".framework"), r = B(n, "dist-web", "startBundle");
19
+ await U.mkdir(n, { recursive: !0 });
20
+ let i = Date.now(), a = B(e, "tsconfig.json"), o = /* @__PURE__ */ new Set(), s = B(n, "startEntry.ts");
21
+ await U.writeFile(s, [
21
22
  "// GENERATED BY `voltro build` — do not edit; overwritten on next build.",
22
23
  "import { runStartCommand as __run, loadDotEnv } from '@voltro/cli/startEntry'",
23
24
  "import { pathToFileURL, fileURLToPath } from 'node:url'",
@@ -41,7 +42,7 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
41
42
  "}",
42
43
  ""
43
44
  ].join("\n"), "utf8"), await t.build({
44
- entryPoints: [c],
45
+ entryPoints: [s],
45
46
  bundle: !0,
46
47
  format: "esm",
47
48
  platform: "node",
@@ -49,32 +50,34 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
49
50
  outdir: r,
50
51
  splitting: !0,
51
52
  write: !0,
52
- plugins: [L([], e, o)],
53
- banner: { js: "import { createRequire as __voltroRequire } from 'node:module'; const require = __voltroRequire(import.meta.url);" },
53
+ minify: !0,
54
+ keepNames: !0,
55
+ plugins: [M([], e, o)],
56
+ banner: { js: A() },
54
57
  jsx: "automatic",
55
58
  jsxImportSource: "react",
56
59
  logLevel: "silent",
57
60
  absWorkingDir: e,
58
- alias: I("startEntry"),
59
- ...U(a) ? { tsconfig: a } : {}
61
+ alias: j("startEntry"),
62
+ ...H(a) ? { tsconfig: a } : {}
60
63
  });
61
- let l = await R(r, i);
64
+ let c = await N(r, i);
62
65
  return J.info("web build: start bundle written", {
63
- out: V(".framework", "dist-web", "startBundle", "startEntry.js"),
66
+ out: B(".framework", "dist-web", "startBundle", "startEntry.js"),
64
67
  ...o.size > 0 ? { externalizedOptionalPeers: [...o].join(", ") } : {},
65
- ...l > 0 ? { prunedStaleChunks: l } : {}
66
- }), V(r, "startEntry.js");
67
- }, Y = G({ scope: "voltro:build" }), X = () => ({
68
+ ...c > 0 ? { prunedStaleChunks: c } : {}
69
+ }), B(r, "startEntry.js");
70
+ }, Y = W({ scope: "voltro:build" }), X = () => ({
68
71
  name: "voltro:stub-engine-devtools",
69
72
  resolveId: (e) => e === "@tanstack/devtools-event-client" ? "\0voltro-engine-devtools-stub" : void 0,
70
73
  load: (e) => e === "\0voltro-engine-devtools-stub" ? "export class EventClient { constructor() {} on() { return () => {} } emit() {} }\n" : void 0
71
- }), te = (e, t) => ({
74
+ }), re = (e, t) => ({
72
75
  name: "voltro:ssr-optional-peer-external",
73
76
  enforce: "pre",
74
77
  resolveId(n, r) {
75
78
  if (n.startsWith(".") || n.startsWith("/") || n.startsWith("\0") || n.startsWith("node:") || n === "effect" || n.startsWith("@effect/") || n.startsWith("@voltro/")) return null;
76
- for (let t of [r ? B(r) : void 0, e]) if (t !== void 0) try {
77
- return q(V(t, "_.js")).resolve(n), null;
79
+ for (let t of [r ? z(r) : void 0, e]) if (t !== void 0) try {
80
+ return q(B(t, "_.js")).resolve(n), null;
78
81
  } catch {}
79
82
  return t.add(n), {
80
83
  id: n,
@@ -98,80 +101,80 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
98
101
  } else r.push(i);
99
102
  return r.length === 0 ? "/" : "/" + r.join("/");
100
103
  }, $ = (e, t) => {
101
- if (t === "/" || t === "") return V(e, "index.html");
104
+ if (t === "/" || t === "") return B(e, "index.html");
102
105
  let n = t.replace(/^\//, "").split("/");
103
- return V(e, ...n, "index.html");
104
- }, ne = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), re = (e, n) => {
105
- let r = e.replace("<div id=\"root\"></div>", `<div id="root">${n.body}</div>`), i = [
106
- n.metaHtml,
107
- `<meta name="voltro-interactive" content="${n.interactive}" />`,
108
- n.stateScript
106
+ return B(e, ...n, "index.html");
107
+ }, ie = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), ae = (e, t) => {
108
+ let n = e.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`), r = [
109
+ t.metaHtml,
110
+ `<meta name="voltro-interactive" content="${t.interactive}" />`,
111
+ t.stateScript
109
112
  ].filter((e) => e.length > 0).join("\n ");
110
- return r = t(d(r, i), n.documentAttrs), n.interactive === "none" && (r = ne(r)), r;
111
- }, ie = async (e) => {
112
- let { page: t, chainEntries: n, pageMod: r, helpers: i } = e, a = n.filter((e) => e.hasLayout);
113
- if (a.length === 0) return Y.debug("skip page", {
114
- pattern: t.pattern,
113
+ return n = m(o(n, r), t.documentAttrs), t.interactive === "none" && (n = ie(n)), n;
114
+ }, oe = async (e) => {
115
+ let { page: n, chainEntries: r, pageMod: i, helpers: a } = e, s = r.filter((e) => e.hasLayout);
116
+ if (s.length === 0) return Y.debug("skip page", {
117
+ pattern: n.pattern,
115
118
  reason: "renderMode=spa with no layout — nothing to shell"
116
119
  }), null;
117
- if (Z(t.pattern)) return Y.debug("skip page", {
118
- pattern: t.pattern,
120
+ if (Z(n.pattern)) return Y.debug("skip page", {
121
+ pattern: n.pattern,
119
122
  reason: "renderMode=spa with a dynamic pattern"
120
123
  }), null;
121
- let s = await Promise.all(a.map(e.loadLayout)), c = a.filter((e, t) => typeof s[t]?.loader == "function").map((e) => e.dir || "/");
122
- if (c.length > 0) return Y.info(`spa shell for ${t.pattern} left to on-demand rendering — its layout chain has a loader (${c.join(", ")}), whose output may be per-request`, {
123
- pattern: t.pattern,
124
- layouts: c
124
+ let c = await Promise.all(s.map(e.loadLayout)), u = s.filter((e, t) => typeof c[t]?.loader == "function").map((e) => e.dir || "/");
125
+ if (u.length > 0) return Y.info(`spa shell for ${n.pattern} left to on-demand rendering — its layout chain has a loader (${u.join(", ")}), whose output may be per-request`, {
126
+ pattern: n.pattern,
127
+ layouts: u
125
128
  }), null;
126
- let { chain: l, segmentLoaderData: u } = await w({
127
- entries: n,
129
+ let { chain: d, segmentLoaderData: f } = await v({
130
+ entries: r,
128
131
  loadLayout: e.loadLayout,
129
132
  loadError: e.loadError,
130
133
  loadPending: e.loadPending,
131
134
  ctx: e.ctx
132
135
  }), p = {
133
- pattern: t.pattern,
134
- Component: r.default,
135
- meta: r.meta,
136
- ErrorBoundary: r.ErrorBoundary,
137
- Pending: r.Pending,
136
+ pattern: n.pattern,
137
+ Component: i.default,
138
+ meta: i.meta,
139
+ ErrorBoundary: i.ErrorBoundary,
140
+ Pending: i.Pending,
138
141
  renderMode: "spa",
139
- chain: l
140
- }, m = r.interactive ?? "full", h = C({
141
- helpers: i,
142
- page: t.pattern,
142
+ chain: d
143
+ }, m = i.interactive ?? "full", h = g({
144
+ helpers: a,
145
+ page: n.pattern,
143
146
  interactive: m,
144
147
  delivery: "artefact",
145
148
  renderInput: {
146
149
  descriptor: p,
147
150
  params: {},
148
- pathname: t.pattern,
149
- segmentLoaderData: u,
151
+ pathname: n.pattern,
152
+ segmentLoaderData: f,
150
153
  ...e.outerWrap ? { outerWrap: e.outerWrap } : {},
151
154
  ...e.locale ? { locale: e.locale } : {}
152
155
  }
153
- }), g = o({
154
- helpers: i,
156
+ }), _ = l({
157
+ helpers: a,
155
158
  prepared: h
156
- }), _ = f({
157
- helpers: i,
159
+ }), y = t({
160
+ helpers: a,
158
161
  prepared: h,
159
- meta: g.meta,
162
+ meta: _.meta,
160
163
  interactive: m
161
- }), v = d(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${g.body}</div>`), _), y = $(e.distDir, t.pattern);
162
- return await W.mkdir(B(y), { recursive: !0 }), await W.writeFile(y, v, "utf8"), Y.debug("prerendered spa layout shell", { pattern: t.pattern }), {
163
- pattern: t.pattern,
164
- outPath: y
164
+ }), b = o(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${_.body}</div>`), y), x = $(e.distDir, n.pattern);
165
+ return await U.mkdir(z(x), { recursive: !0 }), await U.writeFile(x, b, "utf8"), Y.debug("prerendered spa layout shell", { pattern: n.pattern }), {
166
+ pattern: n.pattern,
167
+ outPath: x
165
168
  };
166
- }, ae = async (e) => {
167
- let { root: t, distDir: n, pages: r, dirs: a, vite: o } = e, s = V(n, "index.html"), u = await W.readFile(s, "utf8"), d = V(n, "_voltro", "shell.html");
168
- await W.mkdir(B(d), { recursive: !0 }), await W.writeFile(d, u, "utf8");
169
- let f = /* @__PURE__ */ new Map();
169
+ }, se = async (e) => {
170
+ let { root: t, distDir: r, pages: i, dirs: a, vite: o } = e, c = B(r, "index.html"), l = await U.readFile(c, "utf8"), u = B(r, "_voltro", "shell.html");
171
+ await U.mkdir(z(u), { recursive: !0 }), await U.writeFile(u, l, "utf8");
172
+ let d = /* @__PURE__ */ new Map();
170
173
  for (let t of e.islandsPlans ?? []) {
171
- let e = V(n, "island-shells", `${t.name}.html`);
174
+ let e = B(r, "island-shells", `${t.name}.html`);
172
175
  try {
173
- let n = i(await W.readFile(e, "utf8"), u);
174
- await W.writeFile(e, n, "utf8"), f.set(t.pattern, n);
176
+ let r = n(await U.readFile(e, "utf8"), l);
177
+ await U.writeFile(e, r, "utf8"), d.set(t.pattern, r);
175
178
  } catch {
176
179
  Y.warn("islands shell missing — page ships the full entry", {
177
180
  pattern: t.pattern,
@@ -179,32 +182,32 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
179
182
  });
180
183
  }
181
184
  }
182
- let m = V(t, "node_modules", "@voltro", "ui-shadcn"), h = U(V(m, "package.json")) ? m : null, g = [...h ? [
185
+ let m = B(t, "node_modules", "@voltro", "ui-shadcn"), h = H(B(m, "package.json")) ? m : null, g = [...h ? [
183
186
  {
184
187
  find: "@voltro/ui-shadcn/tokens.css",
185
- replacement: V(h, "src/tokens.css")
188
+ replacement: B(h, "src/tokens.css")
186
189
  },
187
190
  {
188
191
  find: "@voltro/ui-shadcn/cn",
189
- replacement: V(h, "src/cn.ts")
192
+ replacement: B(h, "src/cn.ts")
190
193
  },
191
194
  {
192
195
  find: "@voltro/ui-shadcn/brand",
193
- replacement: V(h, "src/brand/voltroLogo.tsx")
196
+ replacement: B(h, "src/brand/voltroLogo.tsx")
194
197
  },
195
198
  {
196
199
  find: "@voltro/ui-shadcn",
197
- replacement: V(h, "src/index.ts")
200
+ replacement: B(h, "src/index.ts")
198
201
  }
199
- ] : [], ...c(t)], _ = await o.createServer({
200
- root: V(t, ".framework"),
202
+ ] : [], ...s(t)], y = await o.createServer({
203
+ root: B(t, ".framework"),
201
204
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
202
205
  plugins: [
203
206
  (await import("@vitejs/plugin-react")).default(),
204
207
  (await import("@tailwindcss/vite")).default(),
205
- l({
208
+ f({
206
209
  root: t,
207
- config: P(e.images),
210
+ config: I(e.images),
208
211
  urlMode: "build-urls"
209
212
  }),
210
213
  X()
@@ -226,11 +229,11 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
226
229
  },
227
230
  appType: "custom",
228
231
  logLevel: "warn"
229
- }), v = await _.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: x, renderMetaToHtml: S, renderRouterStateScript: C, isDeferredLoaderResult: T, assertDeferralSupported: E, beginStoreSeeds: D, seedPreloadedSubscription: O, seedPreloadedSubscriptionFailure: k } = v, A, M = /* @__PURE__ */ new Map();
232
+ }), b = await y.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: x, renderMetaToHtml: S, renderRouterStateScript: C, isDeferredLoaderResult: w, assertDeferralSupported: T, beginStoreSeeds: D, seedPreloadedSubscription: ee, seedPreloadedSubscriptionFailure: te } = b, O, A = /* @__PURE__ */ new Map();
230
233
  if (e.locales && e.locales.length > 0 && e.defaultLocale) try {
231
- let n = await _.ssrLoadModule("@voltro/i18n");
234
+ let n = await y.ssrLoadModule("@voltro/i18n");
232
235
  try {
233
- A = (await _.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
236
+ O = (await y.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
234
237
  configured: e.timeZone ?? null,
235
238
  defaultTimeZone: e.defaultTimeZone ?? null
236
239
  });
@@ -238,15 +241,15 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
238
241
  let r = n.makeSsgWrap;
239
242
  if (typeof r != "function") throw Error("@voltro/i18n is installed but missing the `makeSsgWrap` export — upgrade @voltro/i18n to a version that ships SSG support.");
240
243
  for (let n of e.locales) try {
241
- let i = await _.ssrLoadModule(V(t, "src", "locales", `${n}.ts`)), a = i.default ?? i;
242
- M.set(n, r(n, a, e.defaultLocale));
244
+ let i = await y.ssrLoadModule(B(t, "src", "locales", `${n}.ts`)), a = i.default ?? i;
245
+ A.set(n, r(n, a, e.defaultLocale));
243
246
  } catch (e) {
244
247
  Y.warn(`i18n catalog missing for locale '${n}' — pages rendered at /${n}/* will crash. Add src/locales/${n}.ts.`, {}, e);
245
248
  }
246
249
  } catch (e) {
247
250
  Y.warn("i18n wrapper unavailable for SSG — pages that call useT() will fail. Check that @voltro/i18n is installed.", {}, e);
248
251
  }
249
- let I = [], L = {}, R = (e) => e.dir === "" ? V(t, "src", "pages") : V(t, "src", "pages", e.dir), z = async (e) => await _.ssrLoadModule(V(R(e), "layout.tsx")), H = async (e) => await _.ssrLoadModule(V(R(e), "error.tsx")), G = async (e) => await _.ssrLoadModule(V(R(e), "loading.tsx")), K = (e, t) => ({
252
+ let j = [], M = {}, N = (e) => e.dir === "" ? B(t, "src", "pages") : B(t, "src", "pages", e.dir), P = async (e) => await y.ssrLoadModule(B(N(e), "layout.tsx")), R = async (e) => await y.ssrLoadModule(B(N(e), "error.tsx")), V = async (e) => await y.ssrLoadModule(B(N(e), "loading.tsx")), W = (e, t) => ({
250
253
  params: e.params,
251
254
  pathname: e.pathname,
252
255
  search: "",
@@ -255,43 +258,43 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
255
258
  query: void 0,
256
259
  isServer: !0
257
260
  });
258
- for (let i of r) {
259
- let r = `${V(t, "src", "pages", i.file)}`, o = await _.ssrLoadModule(r), s = N(o, V("src", "pages", i.file));
260
- L[i.pattern] = s;
261
- let c = s.renderMode, l = b(a, i.dirChain);
261
+ for (let n of i) {
262
+ let i = `${B(t, "src", "pages", n.file)}`, o = await y.ssrLoadModule(i), s = F(o, B("src", "pages", n.file));
263
+ M[n.pattern] = s;
264
+ let c = s.renderMode, u = E(a, n.dirChain);
262
265
  if (c === "spa") {
263
- let t = await ie({
264
- page: i,
265
- chainEntries: l,
266
+ let t = await oe({
267
+ page: n,
268
+ chainEntries: u,
266
269
  pageMod: o,
267
- shellTemplate: u,
268
- distDir: n,
269
- helpers: v,
270
- loadLayout: z,
271
- loadError: H,
272
- loadPending: G,
273
- ctx: K({
270
+ shellTemplate: l,
271
+ distDir: r,
272
+ helpers: b,
273
+ loadLayout: P,
274
+ loadError: R,
275
+ loadPending: V,
276
+ ctx: W({
274
277
  params: {},
275
- pathname: i.pattern
278
+ pathname: n.pattern
276
279
  }, new AbortController().signal),
277
- outerWrap: M.get(e.defaultLocale ?? ""),
280
+ outerWrap: A.get(e.defaultLocale ?? ""),
278
281
  locale: e.defaultLocale
279
282
  });
280
- t && I.push(t);
283
+ t && j.push(t);
281
284
  continue;
282
285
  }
283
286
  if (c !== "static") {
284
287
  Y.debug("skip page", {
285
- pattern: i.pattern,
288
+ pattern: n.pattern,
286
289
  reason: `renderMode=${c}`
287
290
  });
288
291
  continue;
289
292
  }
290
- let d;
291
- if (Z(i.pattern)) {
293
+ let f;
294
+ if (Z(n.pattern)) {
292
295
  if (typeof o.getStaticPaths != "function") {
293
296
  Y.debug("skip page", {
294
- pattern: i.pattern,
297
+ pattern: n.pattern,
295
298
  reason: "no getStaticPaths export"
296
299
  });
297
300
  continue;
@@ -299,51 +302,51 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
299
302
  try {
300
303
  let e = await o.getStaticPaths();
301
304
  if (!Array.isArray(e)) {
302
- Y.warn("skip page — getStaticPaths did not return an array", { pattern: i.pattern });
305
+ Y.warn("skip page — getStaticPaths did not return an array", { pattern: n.pattern });
303
306
  continue;
304
307
  }
305
- d = e.map((e) => ({
308
+ f = e.map((e) => ({
306
309
  params: e.params,
307
- pathname: Q(i.pattern, e.params)
310
+ pathname: Q(n.pattern, e.params)
308
311
  }));
309
312
  } catch (e) {
310
- Y.warn("skip page — getStaticPaths threw", { pattern: i.pattern }, e);
313
+ Y.warn("skip page — getStaticPaths threw", { pattern: n.pattern }, e);
311
314
  continue;
312
315
  }
313
- if (d.length === 0) {
316
+ if (f.length === 0) {
314
317
  Y.debug("skip page", {
315
- pattern: i.pattern,
318
+ pattern: n.pattern,
316
319
  reason: "getStaticPaths returned []"
317
320
  });
318
321
  continue;
319
322
  }
320
- } else d = [{
323
+ } else f = [{
321
324
  params: {},
322
- pathname: i.pattern
325
+ pathname: n.pattern
323
326
  }];
324
327
  let m = o.interactive ?? "full";
325
- for (let r of d) {
328
+ for (let i of f) {
326
329
  D();
327
- let a, s, d = new AbortController();
330
+ let a, s, f = new AbortController();
328
331
  try {
329
- ({chain: a, segmentLoaderData: s} = await w({
330
- entries: l,
331
- loadLayout: z,
332
- loadError: H,
333
- loadPending: G,
334
- ctx: K(r, d.signal)
332
+ ({chain: a, segmentLoaderData: s} = await v({
333
+ entries: u,
334
+ loadLayout: P,
335
+ loadError: R,
336
+ loadPending: V,
337
+ ctx: W(i, f.signal)
335
338
  }));
336
339
  } catch (e) {
337
340
  let t = e?._voltroControl;
338
- if (e instanceof Error && t === "redirect") throw Error(`Static page "${r.pathname}" threw RedirectError from a LAYOUT loader at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
341
+ if (e instanceof Error && t === "redirect") throw Error(`Static page "${i.pathname}" threw RedirectError from a LAYOUT loader at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
339
342
  if (e instanceof Error && t === "not-found") {
340
- Y.warn("layout loader threw NotFoundError at build time — skipping artifact", { pathname: r.pathname });
343
+ Y.warn("layout loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
341
344
  continue;
342
345
  }
343
- throw Error(`Static page "${r.pathname}": a LAYOUT loader threw at build time — the page would prerender without its layout data. Fix the loader (cause below) or throw NotFoundError to skip this path.\ncause: ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
346
+ throw Error(`Static page "${i.pathname}": a LAYOUT loader threw at build time — the page would prerender without its layout data. Fix the loader (cause below) or throw NotFoundError to skip this path.\ncause: ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
344
347
  }
345
348
  let h = {
346
- pattern: i.pattern,
349
+ pattern: n.pattern,
347
350
  Component: o.default,
348
351
  meta: o.meta,
349
352
  loader: o.loader,
@@ -356,8 +359,8 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
356
359
  let e = new AbortController();
357
360
  try {
358
361
  g = await o.loader({
359
- params: r.params,
360
- pathname: r.pathname,
362
+ params: i.params,
363
+ pathname: i.pathname,
361
364
  search: "",
362
365
  headers: {},
363
366
  query: void 0,
@@ -365,88 +368,88 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
365
368
  isServer: !0
366
369
  });
367
370
  } catch (e) {
368
- if (e instanceof Error && e._voltroControl === "redirect") throw Error(`Static page "${r.pathname}" threw RedirectError at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
371
+ if (e instanceof Error && e._voltroControl === "redirect") throw Error(`Static page "${i.pathname}" threw RedirectError at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
369
372
  if (e instanceof Error && e._voltroControl === "not-found") {
370
- Y.warn("loader threw NotFoundError at build time — skipping artifact", { pathname: r.pathname });
373
+ Y.warn("loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
371
374
  continue;
372
375
  }
373
- throw Error(`Static page "${r.pathname}": its loader threw at build time — the page would prerender EMPTY. Fix the loader (cause below) or throw NotFoundError to skip this path.\ncause: ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
376
+ throw Error(`Static page "${i.pathname}": its loader threw at build time — the page would prerender EMPTY. Fix the loader (cause below) or throw NotFoundError to skip this path.\ncause: ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
374
377
  }
375
378
  }
376
- T(g) && E({
377
- page: r.pathname,
379
+ w(g) && T({
380
+ page: i.pathname,
378
381
  renderMode: c,
379
382
  interactive: m
380
383
  });
381
- for (let e of Object.values(s)) T(e) && E({
382
- page: r.pathname,
384
+ for (let e of Object.values(s)) w(e) && T({
385
+ page: i.pathname,
383
386
  renderMode: c,
384
387
  interactive: m
385
388
  });
386
- await j({
389
+ await p({
387
390
  pageMod: o,
388
- params: r.params,
391
+ params: i.params,
389
392
  query: void 0,
390
393
  apiName: void 0,
391
- seed: O,
392
- seedFailure: k
394
+ seed: ee,
395
+ seedFailure: te
393
396
  });
394
- let _ = r.params.locale ?? e.defaultLocale ?? "en", v = M.get(_) ?? M.get(e.defaultLocale ?? ""), b = Date.now(), N = v ? (e) => v(e, {
395
- timeZone: A,
396
- renderedAt: b
397
- }) : void 0, { html: P, meta: L } = x({
397
+ let y = i.params.locale ?? e.defaultLocale ?? "en", b = A.get(y) ?? A.get(e.defaultLocale ?? ""), E = Date.now(), M = b ? (e) => b(e, {
398
+ timeZone: O,
399
+ renderedAt: E
400
+ }) : void 0, { html: N, meta: F } = x({
398
401
  descriptor: h,
399
- params: r.params,
400
- pathname: r.pathname,
402
+ params: i.params,
403
+ pathname: i.pathname,
401
404
  loaderData: g,
402
405
  segmentLoaderData: s,
403
- ...N ? { outerWrap: N } : {},
404
- locale: _
405
- }), R = "";
406
+ ...M ? { outerWrap: M } : {},
407
+ locale: y
408
+ }), I = "";
406
409
  if (typeof o.ogImage == "function") {
407
- let i = await o.ogImage({
408
- params: r.params,
410
+ let n = await o.ogImage({
411
+ params: i.params,
409
412
  loaderData: g,
410
- locale: _
411
- }), a = await y(t, e.fonts), { png: s } = await p({
412
- element: i,
413
+ locale: y
414
+ }), a = await k(t, e.fonts), { png: s } = await _({
415
+ element: n,
413
416
  fonts: a
414
- }), c = `assets/og/${F(s)}.png`;
415
- await W.mkdir(V(n, "assets", "og"), { recursive: !0 }), await W.writeFile(V(n, c), Buffer.from(s));
417
+ }), c = `assets/og/${L(s)}.png`;
418
+ await U.mkdir(B(r, "assets", "og"), { recursive: !0 }), await U.writeFile(B(r, c), Buffer.from(s));
416
419
  let l = e.siteUrl === void 0 ? `/${c}` : `${e.siteUrl.replace(/\/$/, "")}/${c}`;
417
- R = S(L).includes("og:image") ? "" : `<meta property="og:image" content="${l}" /><meta name="twitter:image" content="${l}" /><meta name="twitter:card" content="summary_large_image" />`;
420
+ I = S(F).includes("og:image") ? "" : `<meta property="og:image" content="${l}" /><meta name="twitter:image" content="${l}" /><meta name="twitter:card" content="summary_large_image" />`;
418
421
  }
419
- let U = m === "islands" ? f.get(i.pattern) : void 0;
420
- m === "islands" && U === void 0 && Y.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: i.pattern });
421
- let q = re(U ?? u, {
422
- body: P,
423
- metaHtml: S(L) + R,
422
+ let H = m === "islands" ? d.get(n.pattern) : void 0;
423
+ m === "islands" && H === void 0 && Y.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: n.pattern });
424
+ let G = ae(H ?? l, {
425
+ body: N,
426
+ metaHtml: S(F) + I,
424
427
  stateScript: C({
425
- path: r.pathname,
428
+ path: i.pathname,
426
429
  loaderData: g,
427
430
  segmentLoaderData: s,
428
431
  pageLoaderRan: typeof o.loader == "function"
429
432
  }),
430
433
  interactive: m,
431
434
  documentAttrs: {
432
- lang: _,
433
- ...A === void 0 ? {} : { timeZone: A },
434
- renderedAt: b
435
+ lang: y,
436
+ ...O === void 0 ? {} : { timeZone: O },
437
+ renderedAt: E
435
438
  }
436
- }), J = $(n, r.pathname);
437
- await W.mkdir(B(J), { recursive: !0 }), await W.writeFile(J, q, "utf8"), I.push({
438
- pattern: r.pathname,
439
- outPath: J,
440
- ...L?.noIndex ? { noIndex: !0 } : {}
439
+ }), K = $(r, i.pathname);
440
+ await U.mkdir(z(K), { recursive: !0 }), await U.writeFile(K, G, "utf8"), j.push({
441
+ pattern: i.pathname,
442
+ outPath: K,
443
+ ...F?.noIndex ? { noIndex: !0 } : {}
441
444
  });
442
445
  }
443
446
  }
444
- return await _.close(), {
445
- rendered: I,
446
- pageMeta: L
447
+ return await y.close(), {
448
+ rendered: j,
449
+ pageMeta: M
447
450
  };
448
- }, oe = async (e, t, n, r, i, a, o, s) => {
449
- let c = V(e, ".framework"), l = [];
451
+ }, ce = async (e, t, n, r, i, a, o, s) => {
452
+ let c = B(e, ".framework"), l = [];
450
453
  for (let e of t) l.push(` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`);
451
454
  let u = [], d = [], f = [];
452
455
  for (let e of n) {
@@ -455,7 +458,7 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
455
458
  }
456
459
  let p = [], m = [];
457
460
  if (r && r.length > 0 && i) for (let t of r) {
458
- if (!U(V(e, "src", "locales", `${t}.ts`))) continue;
461
+ if (!H(B(e, "src", "locales", `${t}.ts`))) continue;
459
462
  let n = `__i18nCat_${t.replace(/[^a-zA-Z0-9]/g, "_")}`;
460
463
  p.push(`import ${n} from '../src/locales/${t}'`), m.push(` ${JSON.stringify(t)}: makeSsgWrap(${JSON.stringify(t)}, ${n} as unknown as Record<string, string>, ${JSON.stringify(i)}),`);
461
464
  }
@@ -532,16 +535,16 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
532
535
  "",
533
536
  S,
534
537
  ""
535
- ].join("\n"), w = V(c, "ssrEntry.ts");
536
- return await W.writeFile(w, C, "utf8"), w;
537
- }, se = async (e) => {
538
- let { checkRpcGroupFreshness: t } = await import("./codegen-CN6vMM4J.js"), n = await t(e);
538
+ ].join("\n"), w = B(c, "ssrEntry.ts");
539
+ return await U.writeFile(w, C, "utf8"), w;
540
+ }, le = async (e) => {
541
+ let { checkRpcGroupFreshness: t } = await import("./codegen-DbH7NbCR.js"), n = await t(e);
539
542
  if (n.kind === "fresh") return;
540
543
  n.kind === "stale" && Y.info("rpcGroup.generated.ts is stale — regenerating", {
541
544
  file: n.file,
542
545
  reason: n.reason
543
546
  });
544
- let { regenerateRpcGroup: r } = await import("./codegenCommand-3TDJezom.js"), i = await r(e);
547
+ let { regenerateRpcGroup: r } = await import("./codegenCommand-DnVuDxwT.js"), i = await r(e);
545
548
  if (i.kind === "refused") {
546
549
  Y.warn("could not regenerate the rpc group — building against what is on disk", { reason: i.reason });
547
550
  return;
@@ -550,16 +553,20 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
550
553
  plugins: i.plugins,
551
554
  routes: i.routes
552
555
  });
553
- }, ce = async (e) => {
556
+ }, ue = async (e) => {
554
557
  let t = await S(e, { preferSource: !0 });
555
558
  if (!t) {
556
- let { loadApiConfig: t } = await import("./dev-DfVZaoys.js"), n = await t(e);
557
- if (n) {
558
- Y.info("building api app", { app: n.name ?? "(unnamed)" }), await se(e);
559
- let { runApiBuild: t, runServeBundleBuild: r } = await import("./apiBuild-Cl0IDx8c.js");
559
+ let { loadApiConfigDiagnosed: t } = await import("./dev-Bl9HqtV7.js"), n = await t(e), r = n.config;
560
+ if (!r && n.present) return Y.error("app.config.ts is present but could not be loaded — this is NOT a statement about the app's type", { path: B(e, "app.config.ts") }, n.error), {
561
+ ran: !0,
562
+ exitCode: 1
563
+ };
564
+ if (r) {
565
+ Y.info("building api app", { app: r.name ?? "(unnamed)" }), await le(e);
566
+ let { runApiBuild: t, runServeBundleBuild: n } = await import("./apiBuild-B83Cb2Rv.js");
560
567
  await t(e);
561
568
  try {
562
- await r(e);
569
+ await n(e);
563
570
  } catch (e) {
564
571
  return Y.fatal("serve bundle build FAILED — refusing to ship a bundle-less image. Fix the error above (production serves from the bundle, never tsx).", {}, e), {
565
572
  ran: !0,
@@ -577,65 +584,70 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
577
584
  };
578
585
  }
579
586
  Y.info("building web app", { app: t.name ?? "(unnamed)" });
580
- let { resolved: i } = await u({
587
+ let { resolved: n } = await c({
581
588
  rawEnv: t.env,
582
589
  appType: "web",
583
590
  root: e,
584
591
  log: Y,
585
592
  generateTypes: !0
586
- }), o = await x(e, t);
587
- await n(e, t, o, i.publicValues);
588
- let { pages: d } = await O(V(e, "src", "pages")), f = [];
589
- for (let t of d) {
590
- let n = await W.readFile(V(e, "src", "pages", t.file), "utf8").catch(() => ""), r = a(n);
591
- n.includes("<Script") && (r === "none" || r === "islands") && Y.warn(r === "none" ? `page '${t.pattern}' uses <Script> but declares interactive: 'none' — zero-JS strips every script, so it will NEVER load. Remove the <Script>, or raise the page to islands/full.` : `page '${t.pattern}' uses <Script> in its STATIC part (the page file) while interactive: 'islands' — outside an island nothing mounts, so it will NEVER load. Move the <Script> into an *.island.tsx component (it fires when that island hydrates).`), r === "islands" && f.push({
593
+ }), o = await y(e, t);
594
+ await D(e, t, o, n.publicValues);
595
+ let { pages: l } = await u(B(e, "src", "pages")), p = [];
596
+ for (let t of l) {
597
+ let n = await U.readFile(B(e, "src", "pages", t.file), "utf8").catch(() => ""), r = x(n);
598
+ n.includes("<Script") && (r === "none" || r === "islands") && Y.warn(r === "none" ? `page '${t.pattern}' uses <Script> but declares interactive: 'none' — zero-JS strips every script, so it will NEVER load. Remove the <Script>, or raise the page to islands/full.` : `page '${t.pattern}' uses <Script> in its STATIC part (the page file) while interactive: 'islands' — outside an island nothing mounts, so it will NEVER load. Move the <Script> into an *.island.tsx component (it fires when that island hydrates).`), r === "islands" && p.push({
592
599
  pattern: t.pattern,
593
600
  file: t.file
594
601
  });
595
602
  }
596
- let p = m(o, "../../app.config"), y = await r({
603
+ let m = w(o, "../../app.config"), g = await a({
597
604
  webRoot: e,
598
- pages: f,
599
- headSnippets: D(await W.readFile(V(e, ".framework", "index.html"), "utf8").catch(() => "")),
600
- apiImports: p.imports,
601
- apiEntriesLiteral: `[\n${p.providerEntryLines.join("\n")}\n ]`
605
+ pages: p,
606
+ headSnippets: i(await U.readFile(B(e, ".framework", "index.html"), "utf8").catch(() => "")),
607
+ apiImports: m.imports,
608
+ apiEntriesLiteral: `[\n${m.providerEntryLines.join("\n")}\n ]`
602
609
  });
603
- y.length > 0 && Y.info("per-page islands entries", { pages: y.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
604
- let { pages: b } = await O(V(e, "src", "pages"));
605
- await v({
610
+ g.length > 0 && Y.info("per-page islands entries", { pages: g.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
611
+ let { pages: _ } = await u(B(e, "src", "pages"));
612
+ await b({
606
613
  appRoot: e,
607
- pages: b,
614
+ pages: _,
608
615
  mode: "prod"
609
616
  });
610
- let C = V(e, ".framework"), w = V(C, "dist"), j = V(e, "node_modules", "@voltro", "ui-shadcn"), M = U(V(j, "package.json")) ? j : null, N = [...M ? [
617
+ let v = B(e, ".framework"), E = B(v, "dist"), k = B(e, "node_modules", "@voltro", "ui-shadcn"), j = H(B(k, "package.json")) ? k : null, N = [...j ? [
611
618
  {
612
619
  find: "@voltro/ui-shadcn/tokens.css",
613
- replacement: V(M, "src/tokens.css")
620
+ replacement: B(j, "src/tokens.css")
614
621
  },
615
622
  {
616
623
  find: "@voltro/ui-shadcn/cn",
617
- replacement: V(M, "src/cn.ts")
624
+ replacement: B(j, "src/cn.ts")
618
625
  },
619
626
  {
620
627
  find: "@voltro/ui-shadcn/brand",
621
- replacement: V(M, "src/brand/voltroLogo.tsx")
628
+ replacement: B(j, "src/brand/voltroLogo.tsx")
622
629
  },
623
630
  {
624
631
  find: "@voltro/ui-shadcn",
625
- replacement: V(M, "src/index.ts")
632
+ replacement: B(j, "src/index.ts")
626
633
  }
627
- ] : [], ...c(e)];
634
+ ] : [], ...s(e)];
628
635
  Y.info("running vite build");
629
- let F = await s("vite", () => import("vite")), I = (await import("@vitejs/plugin-react")).default, R = (await import("@tailwindcss/vite")).default;
630
- await F.build({
631
- root: C,
636
+ let P = await h("vite", () => import("vite")), F = (await import("@vitejs/plugin-react")).default, L = (await import("@tailwindcss/vite")).default, V = t.web?.sourcemaps, W = t.web?.assetPrefix;
637
+ if (W !== void 0 && !/^https?:\/\/|^\//.test(W)) return Y.fatal(`web.assetPrefix must be an absolute URL or a root-relative path — got ${JSON.stringify(W)}. A bare host would be resolved against the page URL and 404 on every route but one.`), {
638
+ ran: !0,
639
+ exitCode: 1
640
+ };
641
+ await P.build({
642
+ root: v,
643
+ ...W === void 0 ? {} : { base: W.endsWith("/") ? W : `${W}/` },
632
644
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
633
645
  plugins: [
634
- I(),
635
- R(),
636
- l({
646
+ F(),
647
+ L(),
648
+ f({
637
649
  root: e,
638
- config: P(t.images)
650
+ config: I(t.images)
639
651
  }),
640
652
  X()
641
653
  ],
@@ -648,46 +660,47 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
648
660
  "@voltro/i18n"
649
661
  ]
650
662
  },
651
- publicDir: V(e, "public"),
663
+ publicDir: B(e, "public"),
652
664
  build: {
653
665
  outDir: "dist",
654
666
  emptyOutDir: !0,
667
+ ...V === "hidden" ? { sourcemap: "hidden" } : {},
655
668
  rollupOptions: {
656
669
  input: {
657
- index: V(C, "index.html"),
658
- ...Object.fromEntries(y.map((e) => [`island_${e.name}`, V(C, e.htmlFile)]))
670
+ index: B(v, "index.html"),
671
+ ...Object.fromEntries(g.map((e) => [`island_${e.name}`, B(v, e.htmlFile)]))
659
672
  },
660
- output: { manualChunks: h }
673
+ output: { manualChunks: te }
661
674
  }
662
675
  },
663
676
  logLevel: "warn"
664
677
  });
665
- let H = V(e, "src", "pages"), { pages: G, dirs: K } = await O(H);
666
- if (G.length === 0) return Y.info("no pages found — client-only bundle written", {
667
- pagesDir: H,
668
- distDir: w
678
+ let G = B(e, "src", "pages"), { pages: K, dirs: q } = await u(G);
679
+ if (K.length === 0) return Y.info("no pages found — client-only bundle written", {
680
+ pagesDir: G,
681
+ distDir: E
669
682
  }), {
670
683
  ran: !0,
671
684
  exitCode: 0
672
685
  };
673
686
  {
674
- let n = await k(e, t.fonts);
687
+ let n = await ee(e, t.fonts);
675
688
  if (n !== null) {
676
689
  for (let e of n.files) {
677
- let t = V(w, e.fileName);
678
- await W.mkdir(B(t), { recursive: !0 }), await W.writeFile(t, Buffer.from(e.bytes));
690
+ let t = B(E, e.fileName);
691
+ await U.mkdir(z(t), { recursive: !0 }), await U.writeFile(t, Buffer.from(e.bytes));
679
692
  }
680
693
  Y.info(`fonts: ${n.files.length} hashed file(s) into dist/assets/fonts`);
681
694
  }
682
695
  }
683
- g(e);
684
- let { rendered: q, pageMeta: J } = await ae({
696
+ r(e);
697
+ let { rendered: J, pageMeta: Z } = await se({
685
698
  root: e,
686
- distDir: w,
687
- pages: G,
688
- dirs: K,
689
- vite: F,
690
- islandsPlans: y,
699
+ distDir: E,
700
+ pages: K,
701
+ dirs: q,
702
+ vite: P,
703
+ islandsPlans: g,
691
704
  ...t.locales ? { locales: t.locales } : {},
692
705
  ...t.defaultLocale ? { defaultLocale: t.defaultLocale } : {},
693
706
  ...t.timeZone ? { timeZone: t.timeZone } : {},
@@ -696,26 +709,26 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
696
709
  ...t.fonts === void 0 ? {} : { fonts: t.fonts },
697
710
  ...t.seo?.siteUrl === void 0 ? {} : { siteUrl: t.seo.siteUrl }
698
711
  });
699
- await E(w), await A(w, t.feeds ?? [], t.seo?.siteUrl), Y.info("generating .framework/ssrEntry.ts"), await oe(e, G, K, t.locales, t.defaultLocale, J, {
712
+ await O(E), await d(E, t.feeds ?? [], t.seo?.siteUrl), Y.info("generating .framework/ssrEntry.ts"), await ce(e, K, q, t.locales, t.defaultLocale, Z, {
700
713
  ...t.timeZone ? { timeZone: t.timeZone } : {},
701
714
  ...t.defaultTimeZone ? { defaultTimeZone: t.defaultTimeZone } : {}
702
715
  }, o.map((e) => ({
703
716
  name: e.name,
704
717
  pkg: e.pkg
705
718
  }))), Y.info("vite build --ssr → dist/server/");
706
- let Z = /* @__PURE__ */ new Set();
719
+ let Q = /* @__PURE__ */ new Set();
707
720
  try {
708
- await F.build({
709
- root: C,
721
+ await P.build({
722
+ root: v,
710
723
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
711
724
  plugins: [
712
- I(),
713
- R(),
714
- l({
725
+ F(),
726
+ L(),
727
+ f({
715
728
  root: e,
716
- config: P(t.images)
729
+ config: I(t.images)
717
730
  }),
718
- te(e, Z),
731
+ re(e, Q),
719
732
  X()
720
733
  ],
721
734
  resolve: {
@@ -728,16 +741,18 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
728
741
  ]
729
742
  },
730
743
  ssr: { noExternal: !0 },
744
+ esbuild: { keepNames: !0 },
731
745
  build: {
732
746
  outDir: "dist/server",
733
747
  ssr: "ssrEntry.ts",
748
+ minify: "esbuild",
734
749
  emptyOutDir: !0,
735
750
  rollupOptions: { output: { format: "esm" } }
736
751
  },
737
752
  logLevel: "warn"
738
753
  }), Y.info("SSR bundle ready", {
739
754
  path: "dist/server/ssrEntry.js",
740
- ...Z.size > 0 ? { externalizedOptionalPeers: [...Z].join(", ") } : {}
755
+ ...Q.size > 0 ? { externalizedOptionalPeers: [...Q].join(", ") } : {}
741
756
  });
742
757
  } catch (e) {
743
758
  return Y.fatal("SSR bundle build FAILED — refusing to ship a bundle-less image. Fix the error above (production renders from the SSR bundle, never by compiling on demand).", {}, e), {
@@ -745,24 +760,24 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
745
760
  exitCode: 1
746
761
  };
747
762
  }
748
- let Q = V(e, "app.config.ts");
749
- if (U(Q)) {
763
+ let $ = B(e, "app.config.ts");
764
+ if (H($)) {
750
765
  Y.info("precompiling app.config.ts → dist/server/appConfig.js");
751
766
  try {
752
- await (await s("esbuild", () => import("esbuild"))).build({
753
- entryPoints: [Q],
754
- outfile: V(w, "server", "appConfig.js"),
767
+ await (await h("esbuild", () => import("esbuild"))).build({
768
+ entryPoints: [$],
769
+ outfile: B(E, "server", "appConfig.js"),
755
770
  bundle: !0,
756
771
  format: "esm",
757
772
  platform: "node",
758
773
  target: "node22",
759
- plugins: [L([], e, /* @__PURE__ */ new Set())],
760
- banner: { js: "import { createRequire as __voltroRequire } from 'node:module'; const require = __voltroRequire(import.meta.url);" },
774
+ plugins: [M([], e, /* @__PURE__ */ new Set())],
775
+ banner: { js: A() },
761
776
  jsx: "automatic",
762
777
  jsxImportSource: "react",
763
778
  absWorkingDir: e,
764
779
  logLevel: "silent",
765
- ...U(V(e, "tsconfig.json")) ? { tsconfig: V(e, "tsconfig.json") } : {}
780
+ ...H(B(e, "tsconfig.json")) ? { tsconfig: B(e, "tsconfig.json") } : {}
766
781
  });
767
782
  } catch (e) {
768
783
  return Y.fatal("app.config precompile FAILED — production `voltro start` would need the tsx loader to read it.", {}, e), {
@@ -772,45 +787,54 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
772
787
  }
773
788
  }
774
789
  try {
775
- await ee(e);
790
+ await ne(e);
776
791
  } catch (e) {
777
792
  Y.warn("start bundle build failed — `voltro start` will use the slower per-module boot", {}, e);
778
793
  }
779
- Y.info(`pre-rendered ${q.length} static route(s)`, {
780
- count: q.length,
781
- routes: q.map((e) => e.pattern)
794
+ Y.info(`pre-rendered ${J.length} static route(s)`, {
795
+ count: J.length,
796
+ routes: J.map((e) => e.pattern)
782
797
  });
783
798
  try {
784
799
  let e = process.env.VOLTRO_SEO_NOINDEX !== "1", n = t.seo?.siteUrl, r = t.locales ?? [], i = t.defaultLocale ?? r[0];
785
- if (n && !U(V(w, "sitemap.xml"))) {
786
- let t = new Set(r.filter((e) => e !== i)), a = q.filter((e) => !e.noIndex).map((e) => e.pattern).filter((e) => {
800
+ if (n && !H(B(E, "sitemap.xml"))) {
801
+ let t = new Set(r.filter((e) => e !== i)), a = J.filter((e) => !e.noIndex).map((e) => e.pattern).filter((e) => {
787
802
  let n = e.split("/").filter(Boolean)[0];
788
803
  return n === void 0 || !t.has(n);
789
- }).filter((e) => !e.includes("[")).map((e) => ({ path: e })), o = _({
804
+ }).filter((e) => !e.includes("[")).map((e) => ({ path: e })), o = C({
790
805
  siteUrl: n,
791
806
  entries: a,
792
807
  ...r.length > 1 ? { locales: r } : {},
793
808
  ...i ? { defaultLocale: i } : {}
794
809
  });
795
- await W.writeFile(V(w, "sitemap.xml"), o, "utf8"), Y.info("wrote dist/sitemap.xml", {
810
+ await U.writeFile(B(E, "sitemap.xml"), o, "utf8"), Y.info("wrote dist/sitemap.xml", {
796
811
  urls: a.length,
797
812
  indexable: e
798
813
  });
799
814
  }
800
- if (!U(V(w, "robots.txt"))) {
815
+ if (!H(B(E, "robots.txt"))) {
801
816
  let r = T({
802
817
  indexable: e,
803
818
  ...e && n ? { sitemapUrl: `${n.replace(/\/$/, "")}/sitemap.xml` } : {},
804
819
  ...t.seo?.disallow ? { disallow: t.seo.disallow } : {}
805
820
  });
806
- await W.writeFile(V(w, "robots.txt"), r, "utf8"), Y.info("wrote dist/robots.txt", { indexable: e });
821
+ await U.writeFile(B(E, "robots.txt"), r, "utf8"), Y.info("wrote dist/robots.txt", { indexable: e });
822
+ }
823
+ {
824
+ let { precompressAssets: e } = await import("./precompressAssets-YhTi1aWp.js"), t = await e(E);
825
+ t.files > 0 && Y.info("pre-compressed assets", {
826
+ files: t.files,
827
+ raw: t.originalBytes,
828
+ br: t.brotliBytes,
829
+ gz: t.gzipBytes
830
+ });
807
831
  }
808
832
  } catch (e) {
809
833
  Y.warn("SEO artefact generation failed (non-fatal)", {}, e);
810
834
  }
811
835
  try {
812
- let t = await z(e);
813
- await W.writeFile(V(w, ".voltro-build.json"), JSON.stringify({
836
+ let t = await R(e);
837
+ await U.writeFile(B(E, ".voltro-build.json"), JSON.stringify({
814
838
  version: 1,
815
839
  profile: t
816
840
  }, null, 2), "utf8"), Y.info("wrote deploy profile manifest", {
@@ -821,23 +845,28 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
821
845
  } catch (e) {
822
846
  Y.warn("could not write .voltro-build.json deploy manifest", {}, e);
823
847
  }
824
- return Y.info("build complete", { distDir: w }), {
848
+ return Y.info("build complete", { distDir: E }), {
825
849
  ran: !0,
826
850
  exitCode: 0
827
851
  };
828
- }, le = (e) => K.gen(function* () {
852
+ }, de = (e) => K.gen(function* () {
829
853
  let t = yield* K.tryPromise({
830
- try: () => ce(H(e)),
854
+ try: () => ue(V(e)),
831
855
  catch: (e) => e
832
856
  }).pipe(K.orDie);
833
- return t.ran ? t.exitCode : (yield* K.logError("no web app found at this path", { hint: "looked for app.config.ts with `type: 'web'`" }), 1);
834
- }), ue = async (t) => {
835
- if (t.includes("--target")) {
836
- let { runSdkBuildCommand: e } = await import("./sdkgen-CXMwLg9n.js");
857
+ return t.ran ? t.exitCode : (yield* K.logError("no voltro app found at this path", { hint: "looked for an app.config.ts with `type: 'web'` or `type: 'api'` — a web app gets the vite build + prerender + start bundle, an api gets the precompiled serve bundle" }), 1);
858
+ }), fe = async (t) => {
859
+ if (G("build"), t.includes("--target")) {
860
+ let { runSdkBuildCommand: e } = await import("./sdkgen-CMUPrDjH.js");
837
861
  return e(t);
838
862
  }
839
- let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await M(le(n), { scope: "voltro:build" }), i = e(n);
863
+ let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await P(de(n), { scope: "voltro:build" });
864
+ if (r === 0 && t.includes("--report")) {
865
+ let { collectBuildReport: e, formatBuildReport: t } = await import("./buildReport-52gHKgfO.js");
866
+ for (let r of t(e(n))) console.log(r);
867
+ }
868
+ let i = e(n);
840
869
  return i.warning !== void 0 && Y.warn(i.warning), r;
841
870
  };
842
871
  //#endregion
843
- export { ue as runBuildCommand };
872
+ export { fe as runBuildCommand };