@voltro/cli 0.55.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CHANGELOG.md +497 -0
  2. package/bin/voltro.mjs +24 -0
  3. package/dist/{apiBuild-CMvLJM_K.js → apiBuild-Bdaetr37.js} +119 -88
  4. package/dist/apiBuild-Vw1figjO.js +2 -0
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-S0QOzqPT.js → build-CI36wL4R.js} +337 -312
  7. package/dist/buildReport-52gHKgfO.js +64 -0
  8. package/dist/{checkCommand-fbj9GDjN.js → checkCommand-CAwFXrxA.js} +6 -6
  9. package/dist/{checkCommand-DNkY5kwF.js → checkCommand-D0QV_zM_.js} +1 -1
  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-CidbQzbv.js} +10 -10
  14. package/dist/{codemodRunner-C2zxZUIw.js → codemodRunner-BlQPfjzA.js} +222 -0
  15. package/dist/{commands-BBYJ7Q3B.js → commands-CWjfThXv.js} +35 -35
  16. package/dist/{dashboardCommand-D2kmyCLL.js → dashboardCommand-BekcY5Ls.js} +3 -3
  17. package/dist/{dataCommand-BEPPQiTl.js → dataCommand-2pccgbIy.js} +3 -3
  18. package/dist/{dbCommand-DZTmOFT4.js → dbCommand-DpK_vQET.js} +457 -441
  19. package/dist/dbCommand-DrycGWWt.js +2 -0
  20. package/dist/{dev-DfVZaoys.js → dev-B9Gz0k85.js} +1 -1
  21. package/dist/{dev-Ca_A_S9v.js → dev-Dw263KPu.js} +2603 -2482
  22. package/dist/doctorCommand-BMWs6aVm.js +2 -0
  23. package/dist/{doctorCommand-CGZJK_4o.js → doctorCommand-aR_bFmIi.js} +353 -251
  24. package/dist/{dormancyCommand-DY2rYpTa.js → dormancyCommand-eXTQMbHU.js} +1 -1
  25. package/dist/{embeddingsCommand-BoCqZsgp.js → embeddingsCommand-CTmiQvwa.js} +1 -1
  26. package/dist/{envCommand-Bxy2fOjc.js → envCommand-BDUgV7EM.js} +12 -12
  27. package/dist/{evolveCommand-BsbZ-XDg.js → evolveCommand-YV8qW1LU.js} +2 -2
  28. package/dist/frameworkTableAssembly-CGNC0qr7.js +2 -0
  29. package/dist/{frameworkTableAssembly-Do-cf6RJ.js → frameworkTableAssembly-DNOFXfEQ.js} +92 -84
  30. package/dist/index.js +1 -1
  31. package/dist/{infoCommand-EmM3jPKD.js → infoCommand-BjVXpMlP.js} +1 -1
  32. package/dist/inspect-CNYvNXPU.js +1484 -0
  33. package/dist/inspect-S2rWy1Ys.js +2 -0
  34. package/dist/{inspectCmd-niF97fAq.js → inspectCmd-CP-G0sVK.js} +1 -1
  35. package/dist/{inspectFetch-EMuhTG_9.js → inspectFetch-BU1NyzxV.js} +36 -24
  36. package/dist/{inspectMetrics-CGF94puw.js → inspectMetrics-BY0Sjb2F.js} +19 -19
  37. package/dist/{logsCmd-B6oNsfaZ.js → logsCmd-BU8uCdys.js} +1 -1
  38. package/dist/{manifestBuild-DjX5MoXy.js → manifestBuild-CEkjfpwc.js} +1 -1
  39. package/dist/manifestBuild-DIa_s6u0.js +2 -0
  40. package/dist/{migrate-CGFZS-1a.js → migrate-SICulyz1.js} +2 -2
  41. package/dist/precompressAssets-YhTi1aWp.js +40 -0
  42. package/dist/{probeCommand-Bs3iVBSL.js → probeCommand-6HxEkNDG.js} +2 -2
  43. package/dist/{runtimeTrace-C1BTpHGQ.js → runtimeTrace-DgYMc09E.js} +1 -1
  44. package/dist/{scheduleCmd-DQRu6BZC.js → scheduleCmd-DYBUfo_T.js} +1 -1
  45. package/dist/{sdkgen-CXMwLg9n.js → sdkgen-PY-umd6O.js} +1 -1
  46. package/dist/{seedRunner-Dgsiwk_e.js → seedRunner-DISBKow-.js} +16 -16
  47. package/dist/serveCommand-BITS8Hpj.js +2 -0
  48. package/dist/{serveCommand-C7IrCD58.js → serveCommand-DIJ3ma76.js} +910 -870
  49. package/dist/serveEntry.js +1 -1
  50. package/dist/{start-EOV7s1NZ.js → start-B9NGB8gn.js} +575 -546
  51. package/dist/{start-DH7cat4-.js → start-BFQQkL1i.js} +1 -1
  52. package/dist/startEntry.js +1 -1
  53. package/dist/staticCachePolicy-CIyj6DbS.js +15 -0
  54. package/dist/{test-DO27-x2P.js → test-jipIQ5Mx.js} +1 -1
  55. package/dist/{tracesCmd-DgtgOUdi.js → tracesCmd-BWYDqMy6.js} +1 -1
  56. package/dist/{updateCommand-C_jN1w18.js → updateCommand-C9n_Z_oG.js} +8 -2
  57. package/dist/updateCommand-DsXEAHbd.js +2 -0
  58. package/dist/webDev-C2dRz9s5.js +2 -0
  59. package/dist/{webDev-B7vNj4Bq.js → webDev-C53hJdcL.js} +1240 -1271
  60. package/dist/{webhooksCommand-B1LVcyO3.js → webhooksCommand-uuPu8qQX.js} +1 -1
  61. package/dist/{workflowsCmd-BGF-mRZ5.js → workflowsCmd-g-DNpaUc.js} +1 -1
  62. package/package.json +55 -19
  63. package/templates/AGENTS.core.md +20 -1
  64. package/templates/AGENTS.md +21 -2
  65. package/templates/agent-docs/_index.md +1 -1
  66. package/templates/agent-docs/_manifest.json +1 -1
  67. package/templates/agent-docs/cli.md +122 -0
  68. package/templates/agent-docs/data.md +145 -5
  69. package/templates/agent-docs/database/scaling.md +40 -1
  70. package/templates/agent-docs/deployment.md +53 -1
  71. package/templates/agent-docs/internationalization.md +32 -0
  72. package/templates/agent-docs/local-first-mobile.md +9 -2
  73. package/templates/agent-docs/observability.md +227 -0
  74. package/templates/agent-docs/plugins/billing.md +15 -0
  75. package/templates/agent-docs/plugins/broadcast.md +2 -1
  76. package/templates/agent-docs/plugins/ratelimit.md +6 -1
  77. package/templates/agent-docs/plugins/row-history.md +11 -0
  78. package/templates/agent-docs/plugins.md +19 -0
  79. package/templates/agent-docs/templates/appshells.md +3 -3
  80. package/templates/agent-docs/whats-new.md +432 -73
  81. package/templates/apps/api-ai/package.json +6 -6
  82. package/templates/apps/api-auth/package.json +8 -8
  83. package/templates/apps/api-backend/package.json +7 -7
  84. package/templates/apps/api-backend-deactivation/package.json +7 -7
  85. package/templates/apps/api-backend-mail/package.json +8 -8
  86. package/templates/apps/api-backend-mariadb/package.json +9 -9
  87. package/templates/apps/api-backend-sqlite/package.json +8 -8
  88. package/templates/apps/api-backend-storage/package.json +8 -8
  89. package/templates/apps/api-cms/package.json +9 -9
  90. package/templates/apps/api-collab/package.json +8 -8
  91. package/templates/apps/api-data-advanced/package.json +8 -8
  92. package/templates/apps/api-durable/package.json +8 -8
  93. package/templates/apps/api-feature-flags/package.json +9 -9
  94. package/templates/apps/api-governance/package.json +8 -8
  95. package/templates/apps/api-kv/package.json +8 -8
  96. package/templates/apps/api-moderation/package.json +8 -8
  97. package/templates/apps/api-observability/package.json +8 -8
  98. package/templates/apps/api-ratelimit/package.json +8 -8
  99. package/templates/apps/api-rbac/package.json +8 -8
  100. package/templates/apps/api-rest/package.json +7 -7
  101. package/templates/apps/api-row-history/package.json +8 -8
  102. package/templates/apps/api-saas/package.json +11 -11
  103. package/templates/apps/api-saas-starter/package.json +10 -10
  104. package/templates/apps/api-search/package.json +8 -8
  105. package/templates/apps/api-status/package.json +8 -8
  106. package/templates/apps/api-webhooks/package.json +9 -9
  107. package/templates/apps/changelog/package.json +7 -7
  108. package/templates/apps/changelog/src/pages/[locale]/page.tsx +7 -1
  109. package/templates/apps/edge-functions/package.json +2 -2
  110. package/templates/apps/frontend-admin/package.json +7 -8
  111. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +1 -2
  112. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +1 -2
  113. package/templates/apps/frontend-app/package.json +8 -9
  114. package/templates/apps/frontend-app/src/pages/layout.tsx +1 -2
  115. package/templates/apps/frontend-auth/package.json +7 -8
  116. package/templates/apps/frontend-auth/src/components/AuthShell.tsx +1 -2
  117. package/templates/apps/frontend-blank/package.json +6 -7
  118. package/templates/apps/frontend-blank/src/pages/layout.tsx +1 -2
  119. package/templates/apps/frontend-cms/package.json +8 -9
  120. package/templates/apps/frontend-cms/src/pages/(app)/layout.tsx +1 -2
  121. package/templates/apps/frontend-collab/README.md +7 -2
  122. package/templates/apps/frontend-collab/package.json +9 -10
  123. package/templates/apps/frontend-collab/src/pages/layout.tsx +1 -2
  124. package/templates/apps/frontend-collab/src/pages/page.test.tsx +8 -4
  125. package/templates/apps/frontend-collab/src/pages/page.tsx +10 -5
  126. package/templates/apps/frontend-contact/package.json +7 -7
  127. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +1 -1
  128. package/templates/apps/frontend-dashboard/package.json +6 -7
  129. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +1 -2
  130. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +1 -2
  131. package/templates/apps/frontend-docs/package.json +8 -8
  132. package/templates/apps/frontend-i18n/package.json +6 -6
  133. package/templates/apps/frontend-landing/package.json +7 -7
  134. package/templates/apps/frontend-portal/package.json +7 -8
  135. package/templates/apps/frontend-portal/src/pages/(portal)/layout.tsx +1 -2
  136. package/templates/apps/frontend-saas/package.json +7 -8
  137. package/templates/apps/frontend-saas/src/pages/(marketing)/layout.tsx +1 -2
  138. package/templates/apps/frontend-saas/src/pages/dashboard/layout.tsx +1 -2
  139. package/templates/apps/frontend-spa/package.json +6 -7
  140. package/templates/apps/frontend-spa/src/pages/layout.tsx +1 -2
  141. package/templates/apps/frontend-ssr/package.json +6 -7
  142. package/templates/apps/frontend-ssr/src/pages/layout.tsx +1 -2
  143. package/templates/apps/frontend-ssr-api/package.json +7 -8
  144. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +1 -2
  145. package/templates/apps/frontend-static-blog/package.json +8 -8
  146. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +1 -1
  147. package/templates/apps/frontend-static-blog/src/pages/[locale]/page.tsx +7 -1
  148. package/templates/apps/frontend-status/package.json +7 -8
  149. package/templates/apps/frontend-status/src/pages/layout.tsx +1 -2
  150. package/templates/apps/mobile-app/package.json +4 -4
  151. package/templates/baselines/compose/docker/api.Dockerfile +61 -5
  152. package/templates/baselines/compose/docker/web.Dockerfile +55 -10
  153. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +61 -5
  154. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +55 -10
  155. package/dist/apiBuild-Cl0IDx8c.js +0 -2
  156. package/dist/codegen-CN6vMM4J.js +0 -2
  157. package/dist/dbCommand-BTyBGhIA.js +0 -2
  158. package/dist/doctorCommand-djmqEcDC.js +0 -2
  159. package/dist/frameworkTableAssembly-Df2Ymp2f.js +0 -2
  160. package/dist/inspect-DCqILJ1G.js +0 -1197
  161. package/dist/inspect-DGJwpOAb.js +0 -2
  162. package/dist/manifestBuild-CJ2zvPvT.js +0 -2
  163. package/dist/serveCommand-Cjt5S9hD.js +0 -2
  164. package/dist/updateCommand-nnFjDbl4.js +0 -2
  165. 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 { Cn as e } from "./dev-Dw263KPu.js";
2
+ import { B as t, H as n, J as r, S as i, St as a, Tt as o, V as s, Vt as c, Wt as l, X as u, Y as d, _t as f, bt as p, c as m, ct as h, gt as g, h as _, ht as v, jt as y, lt as b, m as x, mt as S, o as C, u as w, ut as ee, vt as T, w as E, wt as te, x as D, xt as O, yt as k } from "./webDev-C53hJdcL.js";
3
+ import { d as A, i as j, o as M, s as N } from "./apiBuild-Bdaetr37.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 l("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,19 +101,19 @@ 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 r = e.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`), i = [
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", {
113
+ return r = s(n(r, i), t.documentAttrs), t.interactive === "none" && (r = ie(r)), r;
114
+ }, oe = async (e) => {
115
+ let { page: t, chainEntries: i, pageMod: a, helpers: o } = e, s = i.filter((e) => e.hasLayout);
116
+ if (s.length === 0) return Y.debug("skip page", {
114
117
  pattern: t.pattern,
115
118
  reason: "renderMode=spa with no layout — nothing to shell"
116
119
  }), null;
@@ -118,60 +121,60 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
118
121
  pattern: t.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`, {
124
+ let c = await Promise.all(s.map(e.loadLayout)), l = s.filter((e, t) => typeof c[t]?.loader == "function").map((e) => e.dir || "/");
125
+ if (l.length > 0) return Y.info(`spa shell for ${t.pattern} left to on-demand rendering — its layout chain has a loader (${l.join(", ")}), whose output may be per-request`, {
123
126
  pattern: t.pattern,
124
- layouts: c
127
+ layouts: l
125
128
  }), null;
126
- let { chain: l, segmentLoaderData: u } = await w({
127
- entries: n,
129
+ let { chain: f, segmentLoaderData: p } = await m({
130
+ entries: i,
128
131
  loadLayout: e.loadLayout,
129
132
  loadError: e.loadError,
130
133
  loadPending: e.loadPending,
131
134
  ctx: e.ctx
132
- }), p = {
135
+ }), h = {
133
136
  pattern: t.pattern,
134
- Component: r.default,
135
- meta: r.meta,
136
- ErrorBoundary: r.ErrorBoundary,
137
- Pending: r.Pending,
137
+ Component: a.default,
138
+ meta: a.meta,
139
+ ErrorBoundary: a.ErrorBoundary,
140
+ Pending: a.Pending,
138
141
  renderMode: "spa",
139
- chain: l
140
- }, m = r.interactive ?? "full", h = C({
141
- helpers: i,
142
+ chain: f
143
+ }, g = a.interactive ?? "full", _ = r({
144
+ helpers: o,
142
145
  page: t.pattern,
143
- interactive: m,
146
+ interactive: g,
144
147
  delivery: "artefact",
145
148
  renderInput: {
146
- descriptor: p,
149
+ descriptor: h,
147
150
  params: {},
148
151
  pathname: t.pattern,
149
- segmentLoaderData: u,
152
+ segmentLoaderData: p,
150
153
  ...e.outerWrap ? { outerWrap: e.outerWrap } : {},
151
154
  ...e.locale ? { locale: e.locale } : {}
152
155
  }
153
- }), g = o({
154
- helpers: i,
155
- prepared: h
156
- }), _ = f({
157
- helpers: i,
158
- prepared: h,
159
- meta: g.meta,
160
- 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 }), {
156
+ }), v = d({
157
+ helpers: o,
158
+ prepared: _
159
+ }), y = u({
160
+ helpers: o,
161
+ prepared: _,
162
+ meta: v.meta,
163
+ interactive: g
164
+ }), b = n(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${v.body}</div>`), y), x = $(e.distDir, t.pattern);
165
+ return await U.mkdir(z(x), { recursive: !0 }), await U.writeFile(x, b, "utf8"), Y.debug("prerendered spa layout shell", { pattern: t.pattern }), {
163
166
  pattern: t.pattern,
164
- outPath: y
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: n, distDir: r, pages: i, dirs: a, vite: s } = 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 n = o(await U.readFile(e, "utf8"), l);
177
+ await U.writeFile(e, n, "utf8"), d.set(t.pattern, n);
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 f = B(n, "node_modules", "@voltro", "ui-shadcn"), h = H(B(f, "package.json")) ? f : 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
+ ] : [], ...y(n)], _ = await s.createServer({
203
+ root: B(n, ".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({
206
- root: t,
207
- config: P(e.images),
208
+ p({
209
+ root: n,
210
+ config: I(e.images),
208
211
  urlMode: "build-urls"
209
212
  }),
210
213
  X()
@@ -226,27 +229,27 @@ 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 _.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: x, renderMetaToHtml: C, renderRouterStateScript: ee, isDeferredLoaderResult: T, assertDeferralSupported: E, beginStoreSeeds: te, seedPreloadedSubscription: D, seedPreloadedSubscriptionFailure: O } = b, k, 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 t = await _.ssrLoadModule("@voltro/i18n");
232
235
  try {
233
- A = (await _.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
236
+ k = (await _.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
234
237
  configured: e.timeZone ?? null,
235
238
  defaultTimeZone: e.defaultTimeZone ?? null
236
239
  });
237
240
  } catch {}
238
- let r = n.makeSsgWrap;
241
+ let r = t.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
- 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));
243
+ for (let t of e.locales) try {
244
+ let i = await _.ssrLoadModule(B(n, "src", "locales", `${t}.ts`)), a = i.default ?? i;
245
+ A.set(t, r(t, a, e.defaultLocale));
243
246
  } catch (e) {
244
- Y.warn(`i18n catalog missing for locale '${n}' — pages rendered at /${n}/* will crash. Add src/locales/${n}.ts.`, {}, e);
247
+ Y.warn(`i18n catalog missing for locale '${t}' — pages rendered at /${t}/* will crash. Add src/locales/${t}.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(n, "src", "pages") : B(n, "src", "pages", e.dir), P = async (e) => await _.ssrLoadModule(B(N(e), "layout.tsx")), R = async (e) => await _.ssrLoadModule(B(N(e), "error.tsx")), V = async (e) => await _.ssrLoadModule(B(N(e), "loading.tsx")), W = (e, t) => ({
250
253
  params: e.params,
251
254
  pathname: e.pathname,
252
255
  search: "",
@@ -255,109 +258,109 @@ 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);
262
- if (c === "spa") {
263
- let t = await ie({
264
- page: i,
265
- chainEntries: l,
266
- pageMod: o,
267
- shellTemplate: u,
268
- distDir: n,
269
- helpers: v,
270
- loadLayout: z,
271
- loadError: H,
272
- loadPending: G,
273
- ctx: K({
261
+ for (let o of i) {
262
+ let i = `${B(n, "src", "pages", o.file)}`, s = await _.ssrLoadModule(i), c = F(s, B("src", "pages", o.file));
263
+ M[o.pattern] = c;
264
+ let u = c.renderMode, f = w(a, o.dirChain);
265
+ if (u === "spa") {
266
+ let t = await oe({
267
+ page: o,
268
+ chainEntries: f,
269
+ pageMod: s,
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: o.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
- if (c !== "static") {
286
+ if (u !== "static") {
284
287
  Y.debug("skip page", {
285
- pattern: i.pattern,
286
- reason: `renderMode=${c}`
288
+ pattern: o.pattern,
289
+ reason: `renderMode=${u}`
287
290
  });
288
291
  continue;
289
292
  }
290
- let d;
291
- if (Z(i.pattern)) {
292
- if (typeof o.getStaticPaths != "function") {
293
+ let p;
294
+ if (Z(o.pattern)) {
295
+ if (typeof s.getStaticPaths != "function") {
293
296
  Y.debug("skip page", {
294
- pattern: i.pattern,
297
+ pattern: o.pattern,
295
298
  reason: "no getStaticPaths export"
296
299
  });
297
300
  continue;
298
301
  }
299
302
  try {
300
- let e = await o.getStaticPaths();
303
+ let e = await s.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: o.pattern });
303
306
  continue;
304
307
  }
305
- d = e.map((e) => ({
308
+ p = e.map((e) => ({
306
309
  params: e.params,
307
- pathname: Q(i.pattern, e.params)
310
+ pathname: Q(o.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: o.pattern }, e);
311
314
  continue;
312
315
  }
313
- if (d.length === 0) {
316
+ if (p.length === 0) {
314
317
  Y.debug("skip page", {
315
- pattern: i.pattern,
318
+ pattern: o.pattern,
316
319
  reason: "getStaticPaths returned []"
317
320
  });
318
321
  continue;
319
322
  }
320
- } else d = [{
323
+ } else p = [{
321
324
  params: {},
322
- pathname: i.pattern
325
+ pathname: o.pattern
323
326
  }];
324
- let m = o.interactive ?? "full";
325
- for (let r of d) {
326
- D();
327
- let a, s, d = new AbortController();
327
+ let h = s.interactive ?? "full";
328
+ for (let i of p) {
329
+ te();
330
+ let a, c, p = 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: c} = await m({
333
+ entries: f,
334
+ loadLayout: P,
335
+ loadError: R,
336
+ loadPending: V,
337
+ ctx: W(i, p.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
- let h = {
346
- pattern: i.pattern,
347
- Component: o.default,
348
- meta: o.meta,
349
- loader: o.loader,
350
- ErrorBoundary: o.ErrorBoundary,
351
- Pending: o.Pending,
352
- renderMode: c,
348
+ let g = {
349
+ pattern: o.pattern,
350
+ Component: s.default,
351
+ meta: s.meta,
352
+ loader: s.loader,
353
+ ErrorBoundary: s.ErrorBoundary,
354
+ Pending: s.Pending,
355
+ renderMode: u,
353
356
  chain: a
354
- }, g = null;
355
- if (typeof o.loader == "function") {
357
+ }, _ = null;
358
+ if (typeof s.loader == "function") {
356
359
  let e = new AbortController();
357
360
  try {
358
- g = await o.loader({
359
- params: r.params,
360
- pathname: r.pathname,
361
+ _ = await s.loader({
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,
378
- renderMode: c,
379
- interactive: m
379
+ T(_) && E({
380
+ page: i.pathname,
381
+ renderMode: u,
382
+ interactive: h
380
383
  });
381
- for (let e of Object.values(s)) T(e) && E({
382
- page: r.pathname,
383
- renderMode: c,
384
- interactive: m
384
+ for (let e of Object.values(c)) T(e) && E({
385
+ page: i.pathname,
386
+ renderMode: u,
387
+ interactive: h
385
388
  });
386
- await j({
387
- pageMod: o,
388
- params: r.params,
389
+ await t({
390
+ pageMod: s,
391
+ params: i.params,
389
392
  query: void 0,
390
393
  apiName: void 0,
391
- seed: O,
392
- seedFailure: k
394
+ seed: D,
395
+ seedFailure: O
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({
398
- descriptor: h,
399
- params: r.params,
400
- pathname: r.pathname,
401
- loaderData: g,
402
- segmentLoaderData: s,
403
- ...N ? { outerWrap: N } : {},
404
- locale: _
405
- }), R = "";
406
- if (typeof o.ogImage == "function") {
407
- let i = await o.ogImage({
408
- params: r.params,
409
- loaderData: g,
410
- locale: _
411
- }), a = await y(t, e.fonts), { png: s } = await p({
412
- element: i,
397
+ let y = i.params.locale ?? e.defaultLocale ?? "en", b = A.get(y) ?? A.get(e.defaultLocale ?? ""), w = Date.now(), M = b ? (e) => b(e, {
398
+ timeZone: k,
399
+ renderedAt: w
400
+ }) : void 0, { html: N, meta: F } = x({
401
+ descriptor: g,
402
+ params: i.params,
403
+ pathname: i.pathname,
404
+ loaderData: _,
405
+ segmentLoaderData: c,
406
+ ...M ? { outerWrap: M } : {},
407
+ locale: y
408
+ }), I = "";
409
+ if (typeof s.ogImage == "function") {
410
+ let t = await s.ogImage({
411
+ params: i.params,
412
+ loaderData: _,
413
+ locale: y
414
+ }), a = await S(n, e.fonts), { png: o } = await v({
415
+ element: t,
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(o)}.png`;
418
+ await U.mkdir(B(r, "assets", "og"), { recursive: !0 }), await U.writeFile(B(r, c), Buffer.from(o));
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 = C(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,
424
- stateScript: C({
425
- path: r.pathname,
426
- loaderData: g,
427
- segmentLoaderData: s,
428
- pageLoaderRan: typeof o.loader == "function"
422
+ let H = h === "islands" ? d.get(o.pattern) : void 0;
423
+ h === "islands" && H === void 0 && Y.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: o.pattern });
424
+ let G = ae(H ?? l, {
425
+ body: N,
426
+ metaHtml: C(F) + I,
427
+ stateScript: ee({
428
+ path: i.pathname,
429
+ loaderData: _,
430
+ segmentLoaderData: c,
431
+ pageLoaderRan: typeof s.loader == "function"
429
432
  }),
430
- interactive: m,
433
+ interactive: h,
431
434
  documentAttrs: {
432
- lang: _,
433
- ...A === void 0 ? {} : { timeZone: A },
434
- renderedAt: b
435
+ lang: y,
436
+ ...k === void 0 ? {} : { timeZone: k },
437
+ renderedAt: w
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
447
  return await _.close(), {
445
- rendered: I,
446
- pageMeta: L
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-CidbQzbv.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,13 +553,13 @@ 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) => {
554
- let t = await S(e, { preferSource: !0 });
556
+ }, ue = async (e) => {
557
+ let t = await x(e, { preferSource: !0 });
555
558
  if (!t) {
556
- let { loadApiConfig: t } = await import("./dev-DfVZaoys.js"), n = await t(e);
559
+ let { loadApiConfig: t } = await import("./dev-B9Gz0k85.js"), n = await t(e);
557
560
  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");
561
+ Y.info("building api app", { app: n.name ?? "(unnamed)" }), await le(e);
562
+ let { runApiBuild: t, runServeBundleBuild: r } = await import("./apiBuild-Vw1figjO.js");
560
563
  await t(e);
561
564
  try {
562
565
  await r(e);
@@ -577,65 +580,70 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
577
580
  };
578
581
  }
579
582
  Y.info("building web app", { app: t.name ?? "(unnamed)" });
580
- let { resolved: i } = await u({
583
+ let { resolved: n } = await c({
581
584
  rawEnv: t.env,
582
585
  appType: "web",
583
586
  root: e,
584
587
  log: Y,
585
588
  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({
589
+ }), r = await _(e, t);
590
+ await E(e, t, r, n.publicValues);
591
+ let { pages: o } = await i(B(e, "src", "pages")), s = [];
592
+ for (let t of o) {
593
+ let n = await U.readFile(B(e, "src", "pages", t.file), "utf8").catch(() => ""), r = te(n);
594
+ 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" && s.push({
592
595
  pattern: t.pattern,
593
596
  file: t.file
594
597
  });
595
598
  }
596
- let p = m(o, "../../app.config"), y = await r({
599
+ let u = C(r, "../../app.config"), d = await O({
597
600
  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 ]`
601
+ pages: s,
602
+ headSnippets: a(await U.readFile(B(e, ".framework", "index.html"), "utf8").catch(() => "")),
603
+ apiImports: u.imports,
604
+ apiEntriesLiteral: `[\n${u.providerEntryLines.join("\n")}\n ]`
602
605
  });
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({
606
+ d.length > 0 && Y.info("per-page islands entries", { pages: d.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
607
+ let { pages: m } = await i(B(e, "src", "pages"));
608
+ await ee({
606
609
  appRoot: e,
607
- pages: b,
610
+ pages: m,
608
611
  mode: "prod"
609
612
  });
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 ? [
613
+ let v = B(e, ".framework"), S = B(v, "dist"), w = B(e, "node_modules", "@voltro", "ui-shadcn"), j = H(B(w, "package.json")) ? w : null, N = [...j ? [
611
614
  {
612
615
  find: "@voltro/ui-shadcn/tokens.css",
613
- replacement: V(M, "src/tokens.css")
616
+ replacement: B(j, "src/tokens.css")
614
617
  },
615
618
  {
616
619
  find: "@voltro/ui-shadcn/cn",
617
- replacement: V(M, "src/cn.ts")
620
+ replacement: B(j, "src/cn.ts")
618
621
  },
619
622
  {
620
623
  find: "@voltro/ui-shadcn/brand",
621
- replacement: V(M, "src/brand/voltroLogo.tsx")
624
+ replacement: B(j, "src/brand/voltroLogo.tsx")
622
625
  },
623
626
  {
624
627
  find: "@voltro/ui-shadcn",
625
- replacement: V(M, "src/index.ts")
628
+ replacement: B(j, "src/index.ts")
626
629
  }
627
- ] : [], ...c(e)];
630
+ ] : [], ...y(e)];
628
631
  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,
632
+ let P = await l("vite", () => import("vite")), F = (await import("@vitejs/plugin-react")).default, L = (await import("@tailwindcss/vite")).default, V = t.web?.sourcemaps, W = t.web?.assetPrefix;
633
+ 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.`), {
634
+ ran: !0,
635
+ exitCode: 1
636
+ };
637
+ await P.build({
638
+ root: v,
639
+ ...W === void 0 ? {} : { base: W.endsWith("/") ? W : `${W}/` },
632
640
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
633
641
  plugins: [
634
- I(),
635
- R(),
636
- l({
642
+ F(),
643
+ L(),
644
+ p({
637
645
  root: e,
638
- config: P(t.images)
646
+ config: I(t.images)
639
647
  }),
640
648
  X()
641
649
  ],
@@ -648,24 +656,25 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
648
656
  "@voltro/i18n"
649
657
  ]
650
658
  },
651
- publicDir: V(e, "public"),
659
+ publicDir: B(e, "public"),
652
660
  build: {
653
661
  outDir: "dist",
654
662
  emptyOutDir: !0,
663
+ ...V === "hidden" ? { sourcemap: "hidden" } : {},
655
664
  rollupOptions: {
656
665
  input: {
657
- index: V(C, "index.html"),
658
- ...Object.fromEntries(y.map((e) => [`island_${e.name}`, V(C, e.htmlFile)]))
666
+ index: B(v, "index.html"),
667
+ ...Object.fromEntries(d.map((e) => [`island_${e.name}`, B(v, e.htmlFile)]))
659
668
  },
660
- output: { manualChunks: h }
669
+ output: { manualChunks: D }
661
670
  }
662
671
  },
663
672
  logLevel: "warn"
664
673
  });
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
674
+ let G = B(e, "src", "pages"), { pages: K, dirs: q } = await i(G);
675
+ if (K.length === 0) return Y.info("no pages found — client-only bundle written", {
676
+ pagesDir: G,
677
+ distDir: S
669
678
  }), {
670
679
  ran: !0,
671
680
  exitCode: 0
@@ -674,20 +683,20 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
674
683
  let n = await k(e, t.fonts);
675
684
  if (n !== null) {
676
685
  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));
686
+ let t = B(S, e.fileName);
687
+ await U.mkdir(z(t), { recursive: !0 }), await U.writeFile(t, Buffer.from(e.bytes));
679
688
  }
680
689
  Y.info(`fonts: ${n.files.length} hashed file(s) into dist/assets/fonts`);
681
690
  }
682
691
  }
683
- g(e);
684
- let { rendered: q, pageMeta: J } = await ae({
692
+ T(e);
693
+ let { rendered: J, pageMeta: Z } = await se({
685
694
  root: e,
686
- distDir: w,
687
- pages: G,
688
- dirs: K,
689
- vite: F,
690
- islandsPlans: y,
695
+ distDir: S,
696
+ pages: K,
697
+ dirs: q,
698
+ vite: P,
699
+ islandsPlans: d,
691
700
  ...t.locales ? { locales: t.locales } : {},
692
701
  ...t.defaultLocale ? { defaultLocale: t.defaultLocale } : {},
693
702
  ...t.timeZone ? { timeZone: t.timeZone } : {},
@@ -696,26 +705,26 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
696
705
  ...t.fonts === void 0 ? {} : { fonts: t.fonts },
697
706
  ...t.seo?.siteUrl === void 0 ? {} : { siteUrl: t.seo.siteUrl }
698
707
  });
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, {
708
+ await g(S), await f(S, t.feeds ?? [], t.seo?.siteUrl), Y.info("generating .framework/ssrEntry.ts"), await ce(e, K, q, t.locales, t.defaultLocale, Z, {
700
709
  ...t.timeZone ? { timeZone: t.timeZone } : {},
701
710
  ...t.defaultTimeZone ? { defaultTimeZone: t.defaultTimeZone } : {}
702
- }, o.map((e) => ({
711
+ }, r.map((e) => ({
703
712
  name: e.name,
704
713
  pkg: e.pkg
705
714
  }))), Y.info("vite build --ssr → dist/server/");
706
- let Z = /* @__PURE__ */ new Set();
715
+ let Q = /* @__PURE__ */ new Set();
707
716
  try {
708
- await F.build({
709
- root: C,
717
+ await P.build({
718
+ root: v,
710
719
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
711
720
  plugins: [
712
- I(),
713
- R(),
714
- l({
721
+ F(),
722
+ L(),
723
+ p({
715
724
  root: e,
716
- config: P(t.images)
725
+ config: I(t.images)
717
726
  }),
718
- te(e, Z),
727
+ re(e, Q),
719
728
  X()
720
729
  ],
721
730
  resolve: {
@@ -728,16 +737,18 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
728
737
  ]
729
738
  },
730
739
  ssr: { noExternal: !0 },
740
+ esbuild: { keepNames: !0 },
731
741
  build: {
732
742
  outDir: "dist/server",
733
743
  ssr: "ssrEntry.ts",
744
+ minify: "esbuild",
734
745
  emptyOutDir: !0,
735
746
  rollupOptions: { output: { format: "esm" } }
736
747
  },
737
748
  logLevel: "warn"
738
749
  }), Y.info("SSR bundle ready", {
739
750
  path: "dist/server/ssrEntry.js",
740
- ...Z.size > 0 ? { externalizedOptionalPeers: [...Z].join(", ") } : {}
751
+ ...Q.size > 0 ? { externalizedOptionalPeers: [...Q].join(", ") } : {}
741
752
  });
742
753
  } catch (e) {
743
754
  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 +756,24 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
745
756
  exitCode: 1
746
757
  };
747
758
  }
748
- let Q = V(e, "app.config.ts");
749
- if (U(Q)) {
759
+ let $ = B(e, "app.config.ts");
760
+ if (H($)) {
750
761
  Y.info("precompiling app.config.ts → dist/server/appConfig.js");
751
762
  try {
752
- await (await s("esbuild", () => import("esbuild"))).build({
753
- entryPoints: [Q],
754
- outfile: V(w, "server", "appConfig.js"),
763
+ await (await l("esbuild", () => import("esbuild"))).build({
764
+ entryPoints: [$],
765
+ outfile: B(S, "server", "appConfig.js"),
755
766
  bundle: !0,
756
767
  format: "esm",
757
768
  platform: "node",
758
769
  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);" },
770
+ plugins: [M([], e, /* @__PURE__ */ new Set())],
771
+ banner: { js: A() },
761
772
  jsx: "automatic",
762
773
  jsxImportSource: "react",
763
774
  absWorkingDir: e,
764
775
  logLevel: "silent",
765
- ...U(V(e, "tsconfig.json")) ? { tsconfig: V(e, "tsconfig.json") } : {}
776
+ ...H(B(e, "tsconfig.json")) ? { tsconfig: B(e, "tsconfig.json") } : {}
766
777
  });
767
778
  } catch (e) {
768
779
  return Y.fatal("app.config precompile FAILED — production `voltro start` would need the tsx loader to read it.", {}, e), {
@@ -772,45 +783,54 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
772
783
  }
773
784
  }
774
785
  try {
775
- await ee(e);
786
+ await ne(e);
776
787
  } catch (e) {
777
788
  Y.warn("start bundle build failed — `voltro start` will use the slower per-module boot", {}, e);
778
789
  }
779
- Y.info(`pre-rendered ${q.length} static route(s)`, {
780
- count: q.length,
781
- routes: q.map((e) => e.pattern)
790
+ Y.info(`pre-rendered ${J.length} static route(s)`, {
791
+ count: J.length,
792
+ routes: J.map((e) => e.pattern)
782
793
  });
783
794
  try {
784
795
  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) => {
796
+ if (n && !H(B(S, "sitemap.xml"))) {
797
+ let t = new Set(r.filter((e) => e !== i)), a = J.filter((e) => !e.noIndex).map((e) => e.pattern).filter((e) => {
787
798
  let n = e.split("/").filter(Boolean)[0];
788
799
  return n === void 0 || !t.has(n);
789
- }).filter((e) => !e.includes("[")).map((e) => ({ path: e })), o = _({
800
+ }).filter((e) => !e.includes("[")).map((e) => ({ path: e })), o = b({
790
801
  siteUrl: n,
791
802
  entries: a,
792
803
  ...r.length > 1 ? { locales: r } : {},
793
804
  ...i ? { defaultLocale: i } : {}
794
805
  });
795
- await W.writeFile(V(w, "sitemap.xml"), o, "utf8"), Y.info("wrote dist/sitemap.xml", {
806
+ await U.writeFile(B(S, "sitemap.xml"), o, "utf8"), Y.info("wrote dist/sitemap.xml", {
796
807
  urls: a.length,
797
808
  indexable: e
798
809
  });
799
810
  }
800
- if (!U(V(w, "robots.txt"))) {
801
- let r = T({
811
+ if (!H(B(S, "robots.txt"))) {
812
+ let r = h({
802
813
  indexable: e,
803
814
  ...e && n ? { sitemapUrl: `${n.replace(/\/$/, "")}/sitemap.xml` } : {},
804
815
  ...t.seo?.disallow ? { disallow: t.seo.disallow } : {}
805
816
  });
806
- await W.writeFile(V(w, "robots.txt"), r, "utf8"), Y.info("wrote dist/robots.txt", { indexable: e });
817
+ await U.writeFile(B(S, "robots.txt"), r, "utf8"), Y.info("wrote dist/robots.txt", { indexable: e });
818
+ }
819
+ {
820
+ let { precompressAssets: e } = await import("./precompressAssets-YhTi1aWp.js"), t = await e(S);
821
+ t.files > 0 && Y.info("pre-compressed assets", {
822
+ files: t.files,
823
+ raw: t.originalBytes,
824
+ br: t.brotliBytes,
825
+ gz: t.gzipBytes
826
+ });
807
827
  }
808
828
  } catch (e) {
809
829
  Y.warn("SEO artefact generation failed (non-fatal)", {}, e);
810
830
  }
811
831
  try {
812
- let t = await z(e);
813
- await W.writeFile(V(w, ".voltro-build.json"), JSON.stringify({
832
+ let t = await R(e);
833
+ await U.writeFile(B(S, ".voltro-build.json"), JSON.stringify({
814
834
  version: 1,
815
835
  profile: t
816
836
  }, null, 2), "utf8"), Y.info("wrote deploy profile manifest", {
@@ -821,23 +841,28 @@ var J = G({ scope: "voltro:build" }), ee = async (e) => {
821
841
  } catch (e) {
822
842
  Y.warn("could not write .voltro-build.json deploy manifest", {}, e);
823
843
  }
824
- return Y.info("build complete", { distDir: w }), {
844
+ return Y.info("build complete", { distDir: S }), {
825
845
  ran: !0,
826
846
  exitCode: 0
827
847
  };
828
- }, le = (e) => K.gen(function* () {
848
+ }, de = (e) => K.gen(function* () {
829
849
  let t = yield* K.tryPromise({
830
- try: () => ce(H(e)),
850
+ try: () => ue(V(e)),
831
851
  catch: (e) => e
832
852
  }).pipe(K.orDie);
833
853
  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");
854
+ }), fe = async (t) => {
855
+ if (G("build"), t.includes("--target")) {
856
+ let { runSdkBuildCommand: e } = await import("./sdkgen-PY-umd6O.js");
837
857
  return e(t);
838
858
  }
839
- let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await M(le(n), { scope: "voltro:build" }), i = e(n);
859
+ let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await P(de(n), { scope: "voltro:build" });
860
+ if (r === 0 && t.includes("--report")) {
861
+ let { collectBuildReport: e, formatBuildReport: t } = await import("./buildReport-52gHKgfO.js");
862
+ for (let r of t(e(n))) console.log(r);
863
+ }
864
+ let i = e(n);
840
865
  return i.warning !== void 0 && Y.warn(i.warning), r;
841
866
  };
842
867
  //#endregion
843
- export { ue as runBuildCommand };
868
+ export { fe as runBuildCommand };