@voltro/cli 0.51.0 → 0.52.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 (164) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/dist/{agentsMd-D6yD7IQv.js → agentsMd-0l980yhL.js} +4 -1
  3. package/dist/agentsMd-SDDSkyl4.js +2 -0
  4. package/dist/apiBuild-BYBpL7Pz.js +2 -0
  5. package/dist/{apiBuild-CPDHXF72.js → apiBuild-CSFI8QGq.js} +3 -3
  6. package/dist/bin.js +1 -1
  7. package/dist/build-CPgcMQug.js +793 -0
  8. package/dist/checkCommand-2SbqzukH.js +2 -0
  9. package/dist/{checkCommand-DNuPiWMc.js → checkCommand-COmqc2cB.js} +92 -46
  10. package/dist/{cloudCmd-F4YJeqM3.js → cloudCmd-QUXh-b5w.js} +1 -1
  11. package/dist/codegen-CctkDO-1.js +2 -0
  12. package/dist/{codegen-CrMXs4hb.js → codegen-VF479Cnb.js} +1 -1
  13. package/dist/{codegenCommand-BNBHcNNj.js → codegenCommand-DCdG2JN-.js} +12 -12
  14. package/dist/{codemodRunner-BDVixlSw.js → codemodRunner-r7J9lIa7.js} +588 -540
  15. package/dist/{commands-B1OiS9bX.js → commands-Cc_nV8WI.js} +35 -35
  16. package/dist/{dashboardCommand-C-vvPY1B.js → dashboardCommand-C-gKvwqh.js} +5 -5
  17. package/dist/{dataCommand-C1GxXW5q.js → dataCommand-BgpBHnlB.js} +27 -27
  18. package/dist/dbCommand-DNb6yeOG.js +2 -0
  19. package/dist/{dbCommand-If4Y1xQ-.js → dbCommand-sHedr-NJ.js} +2 -2
  20. package/dist/dev--A3nsxA3.js +3 -0
  21. package/dist/{dev-kdAg9Q7l.js → dev-CRHoCEiy.js} +2142 -2103
  22. package/dist/doctorCommand-CqoWA2p5.js +2 -0
  23. package/dist/{doctorCommand-nKmeW78u.js → doctorCommand-DtfJ3FA6.js} +314 -234
  24. package/dist/{dormancyCommand-CY3wa_SW.js → dormancyCommand-Drn7o0No.js} +1 -1
  25. package/dist/{embeddingsCommand-BDLIgje_.js → embeddingsCommand-Z-jO1fWN.js} +1 -1
  26. package/dist/{envCommand-C6V_xVlT.js → envCommand-D4gCrrTZ.js} +8 -8
  27. package/dist/{evolveCommand-D3c4DSfN.js → evolveCommand-CMROeKeA.js} +2 -2
  28. package/dist/fileConventions-DOqD3lPS.js +34 -0
  29. package/dist/{fileTaxonomy-CJfgOllU.js → fileTaxonomy-DvDUV9wq.js} +1 -1
  30. package/dist/frameworkTableAssembly-C6ETawPR.js +2 -0
  31. package/dist/{frameworkTableAssembly-BwJVEKLr.js → frameworkTableAssembly-w-XnLa3q.js} +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/{infoCommand-BnRFEF1o.js → infoCommand-DXM868o_.js} +1 -1
  34. package/dist/inspectMetrics-CGF94puw.js +143 -0
  35. package/dist/{metaCommands-CfRLra0s.js → metaCommands-C6RFmF1r.js} +2 -2
  36. package/dist/{migrate-DehuBakM.js → migrate-D0F-eTlK.js} +2 -2
  37. package/dist/{pageConvention-cEiRxdab.js → pageConvention-CzUiSbtU.js} +1 -1
  38. package/dist/{privacyCommand-XejDMvmu.js → privacyCommand-DGdopOI6.js} +1 -1
  39. package/dist/{projectScaffold-mIX_DpSe.js → projectScaffold-B4dmTlwT.js} +1 -1
  40. package/dist/{projectScaffold-BIl97_E6.js → projectScaffold-EzlErR4E.js} +1 -1
  41. package/dist/{renderModeScan-D7J1B7Kw.js → renderModeScan-CcH2X1_D.js} +25 -10
  42. package/dist/{renderProfile-1OWWAAtx.js → renderProfile-Ck32Fzxr.js} +2 -2
  43. package/dist/{runtimeTrace-ZsBU7Tkx.js → runtimeTrace-BPQyCmC5.js} +1 -1
  44. package/dist/{sdkgen-O4XqWOjM.js → sdkgen-Se88ifTd.js} +1 -1
  45. package/dist/serveCommand-DLc-BznW.js +2 -0
  46. package/dist/{serveCommand-DdiYNBBu.js → serveCommand-DkP3OT0W.js} +885 -868
  47. package/dist/serveEntry.js +1 -1
  48. package/dist/start-DfL3fOiN.js +3 -0
  49. package/dist/start-jw89Xbqy.js +1339 -0
  50. package/dist/startEntry.js +1 -1
  51. package/dist/{staticCommand-Dr2M6tpU.js → staticCommand-BwNEDlSU.js} +1 -1
  52. package/dist/{test-rXFq4S76.js → test-f3amja6a.js} +1 -1
  53. package/dist/updateCommand-5gFVfK5q.js +2 -0
  54. package/dist/{updateCommand-Bs322Q78.js → updateCommand-BMk2e4ky.js} +1 -1
  55. package/dist/{webDev-B-ubQEMX.js → webDev-BgWL9gKV.js} +1156 -835
  56. package/dist/webDev-CZbTsDcH.js +2 -0
  57. package/dist/{webhooksCommand-FLYY9IXh.js → webhooksCommand-CoIO3jbj.js} +1 -1
  58. package/package.json +30 -17
  59. package/templates/AGENTS.core.md +11 -0
  60. package/templates/AGENTS.md +15 -4
  61. package/templates/agent-docs/_index.md +4 -4
  62. package/templates/agent-docs/_manifest.json +11 -11
  63. package/templates/agent-docs/cli.md +96 -14
  64. package/templates/agent-docs/data.md +210 -7
  65. package/templates/agent-docs/database/schema.md +1 -1
  66. package/templates/agent-docs/database/seedsdialects.md +1 -1
  67. package/templates/agent-docs/deployment.md +22 -3
  68. package/templates/agent-docs/introduction.md +46 -0
  69. package/templates/agent-docs/local-first-mobile.md +34 -7
  70. package/templates/agent-docs/plugins/ai-flows.md +1 -1
  71. package/templates/agent-docs/plugins/audit.md +5 -5
  72. package/templates/agent-docs/plugins/cdc-out.md +2 -2
  73. package/templates/agent-docs/plugins/{versioning.md → row-history.md} +22 -22
  74. package/templates/agent-docs/plugins/storage.md +2 -2
  75. package/templates/agent-docs/plugins.md +29 -7
  76. package/templates/agent-docs/reference.md +39 -2
  77. package/templates/agent-docs/routing.md +341 -47
  78. package/templates/agent-docs/schema-driven-ui.md +78 -2
  79. package/templates/agent-docs/security.md +125 -8
  80. package/templates/agent-docs/templates/apibackends.md +14 -14
  81. package/templates/agent-docs/templates/overview.md +1 -1
  82. package/templates/agent-docs/whats-new.md +76 -53
  83. package/templates/apps/api-ai/package.json +6 -7
  84. package/templates/apps/api-ai/tests/summarize.test.ts +1 -1
  85. package/templates/apps/api-auth/package.json +8 -8
  86. package/templates/apps/api-backend/package.json +7 -7
  87. package/templates/apps/api-backend-deactivation/package.json +7 -7
  88. package/templates/apps/api-backend-mail/package.json +8 -8
  89. package/templates/apps/api-backend-mariadb/package.json +9 -9
  90. package/templates/apps/api-backend-sqlite/package.json +8 -8
  91. package/templates/apps/api-backend-storage/package.json +8 -8
  92. package/templates/apps/api-cms/package.json +9 -10
  93. package/templates/apps/api-collab/package.json +8 -8
  94. package/templates/apps/api-data-advanced/package.json +8 -8
  95. package/templates/apps/api-durable/package.json +8 -8
  96. package/templates/apps/api-feature-flags/package.json +9 -9
  97. package/templates/apps/api-governance/package.json +8 -8
  98. package/templates/apps/api-kv/package.json +8 -8
  99. package/templates/apps/api-moderation/package.json +8 -8
  100. package/templates/apps/api-observability/package.json +8 -8
  101. package/templates/apps/api-ratelimit/package.json +8 -8
  102. package/templates/apps/api-rbac/package.json +8 -8
  103. package/templates/apps/api-rest/package.json +7 -7
  104. package/templates/apps/{api-versioning → api-row-history}/README.md +3 -3
  105. package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.server.ts +1 -1
  106. package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.server.ts +1 -1
  107. package/templates/apps/{api-versioning → api-row-history}/app.config.ts +3 -3
  108. package/templates/apps/{api-versioning → api-row-history}/database/schema.ts +1 -1
  109. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.server.ts +1 -1
  110. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.ts +1 -1
  111. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.ts +1 -1
  112. package/templates/apps/{api-versioning → api-row-history}/package.json +8 -8
  113. package/templates/apps/api-row-history/template.json +6 -0
  114. package/templates/apps/{api-versioning → api-row-history}/tests/documents.create.test.ts +1 -1
  115. package/templates/apps/api-saas/app.config.ts +1 -0
  116. package/templates/apps/api-saas/package.json +10 -11
  117. package/templates/apps/api-saas-starter/package.json +10 -10
  118. package/templates/apps/api-search/package.json +8 -8
  119. package/templates/apps/api-status/package.json +8 -8
  120. package/templates/apps/api-webhooks/package.json +9 -9
  121. package/templates/apps/changelog/package.json +6 -6
  122. package/templates/apps/edge-functions/package.json +2 -2
  123. package/templates/apps/frontend-admin/package.json +8 -8
  124. package/templates/apps/frontend-app/package.json +9 -9
  125. package/templates/apps/frontend-auth/package.json +8 -8
  126. package/templates/apps/frontend-blank/package.json +7 -7
  127. package/templates/apps/frontend-cms/package.json +9 -9
  128. package/templates/apps/frontend-collab/package.json +10 -10
  129. package/templates/apps/frontend-collab/src/pages/page.test.tsx +10 -9
  130. package/templates/apps/frontend-collab/src/pages/page.tsx +42 -65
  131. package/templates/apps/frontend-contact/package.json +7 -7
  132. package/templates/apps/frontend-dashboard/package.json +7 -7
  133. package/templates/apps/frontend-docs/package.json +6 -7
  134. package/templates/apps/frontend-i18n/package.json +6 -6
  135. package/templates/apps/frontend-landing/package.json +6 -7
  136. package/templates/apps/frontend-portal/package.json +8 -8
  137. package/templates/apps/frontend-saas/package.json +8 -8
  138. package/templates/apps/frontend-spa/package.json +7 -7
  139. package/templates/apps/frontend-ssr/package.json +7 -7
  140. package/templates/apps/frontend-ssr-api/package.json +8 -8
  141. package/templates/apps/frontend-static-blog/package.json +6 -6
  142. package/templates/apps/frontend-status/package.json +8 -8
  143. package/templates/apps/mobile-app/package.json +4 -4
  144. package/dist/agentsMd-Bu_XQgVf.js +0 -2
  145. package/dist/apiBuild-GDKuGOMV.js +0 -2
  146. package/dist/build-DETLZAFt.js +0 -752
  147. package/dist/checkCommand-CWcnDArJ.js +0 -2
  148. package/dist/codegen-DiMn2KkZ.js +0 -2
  149. package/dist/dbCommand-C27HIsGE.js +0 -2
  150. package/dist/dev-CK522MV5.js +0 -3
  151. package/dist/doctorCommand-BK4l18eG.js +0 -2
  152. package/dist/fileConventions-Cof68_BL.js +0 -33
  153. package/dist/frameworkTableAssembly-CVDB2hCq.js +0 -2
  154. package/dist/inspectMetrics-CfdKLh6t.js +0 -72
  155. package/dist/serveCommand-BRnPCxVd.js +0 -2
  156. package/dist/start-BLNmWkLa.js +0 -1154
  157. package/dist/start-Dzicuyw8.js +0 -3
  158. package/dist/updateCommand-eXB35SEv.js +0 -2
  159. package/dist/webDev-DposiF3j.js +0 -2
  160. package/templates/apps/api-versioning/template.json +0 -6
  161. /package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.ts +0 -0
  162. /package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.ts +0 -0
  163. /package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.server.ts +0 -0
  164. /package/templates/apps/{api-versioning → api-row-history}/tsconfig.json +0 -0
@@ -0,0 +1,793 @@
1
+ import { _n as e } from "./dev-CRHoCEiy.js";
2
+ import { At as t, Dt as n, M as r, N as i, P as a, Q as o, X as s, Z as c, b as l, c as u, f as d, ht as f, i as p, lt as m, nt as h, o as g, ot as _, p as v, rt as y, st as b, tt as x, ut as S, x as C, y as w } from "./webDev-BgWL9gKV.js";
3
+ import { t as T } from "./cliRuntime-Dh7UDinH.js";
4
+ import { a as E } from "./renderModeScan-CcH2X1_D.js";
5
+ import { i as D, o as O, s as k } from "./apiBuild-CSFI8QGq.js";
6
+ import { n as A } from "./renderProfile-Ck32Fzxr.js";
7
+ import { dirname as j, join as M, resolve as N } from "node:path";
8
+ import { existsSync as P, promises as F } from "node:fs";
9
+ import "node:url";
10
+ import { createLogger as I } from "@voltro/logger";
11
+ import { Effect as L } from "effect";
12
+ import { createRequire as R } from "node:module";
13
+ //#region src/webStartBundle.ts
14
+ var z = I({ scope: "voltro:build" }), B = async (e) => {
15
+ let n = await t("esbuild", () => import("esbuild")), r = M(e, ".framework"), i = M(r, "dist-web", "startBundle");
16
+ await F.mkdir(r, { recursive: !0 });
17
+ let a = Date.now(), o = M(e, "tsconfig.json"), s = /* @__PURE__ */ new Set(), c = M(r, "startEntry.ts");
18
+ await F.writeFile(c, [
19
+ "// GENERATED BY `voltro build` — do not edit; overwritten on next build.",
20
+ "import { runStartCommand as __run, loadDotEnv } from '@voltro/cli/startEntry'",
21
+ "import { pathToFileURL, fileURLToPath } from 'node:url'",
22
+ "import { dirname, resolve } from 'node:path'",
23
+ "export const runStartCommand = (args = []) => { loadDotEnv([]); return __run(args) }",
24
+ "export { loadDotEnv }",
25
+ "",
26
+ "// DIRECT-INVOKE ENTRY. `node startEntry.js` is the PRODUCTION container command",
27
+ "// — no `pnpm voltro start` wrapper, so the container never resolves the @voltro/cli",
28
+ "// bin and `voltro prune-runtime` can drop the CLI (and the whole inlined",
29
+ "// effect/@voltro/react tree) from the runtime image: the trace roots at THIS",
30
+ "// self-contained bundle, which is now also the real entrypoint. When this module",
31
+ "// is IMPORTED instead (bin/voltro.mjs's dev fast path) the guard is inert.",
32
+ "if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {",
33
+ " // Relocation-safe: the app root is 3 dirs up from",
34
+ " // .framework/dist-web/startBundle/startEntry.js — chdir there so tryRunStart",
35
+ " // resolves the SSR bundle + appConfig from cwd regardless of the launch dir",
36
+ " // (WORKDIR already sets it in our image; this makes it robust anywhere).",
37
+ " process.chdir(resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..'))",
38
+ " runStartCommand(process.argv.slice(2)).then((c) => process.exit(typeof c === 'number' ? c : 0))",
39
+ "}",
40
+ ""
41
+ ].join("\n"), "utf8"), await n.build({
42
+ entryPoints: [c],
43
+ bundle: !0,
44
+ format: "esm",
45
+ platform: "node",
46
+ target: "node22",
47
+ outdir: i,
48
+ splitting: !0,
49
+ write: !0,
50
+ plugins: [O([], e, s)],
51
+ banner: { js: "import { createRequire as __voltroRequire } from 'node:module'; const require = __voltroRequire(import.meta.url);" },
52
+ jsx: "automatic",
53
+ jsxImportSource: "react",
54
+ logLevel: "silent",
55
+ absWorkingDir: e,
56
+ alias: D("startEntry"),
57
+ ...P(o) ? { tsconfig: o } : {}
58
+ });
59
+ let l = await k(i, a);
60
+ return z.info("web build: start bundle written", {
61
+ out: M(".framework", "dist-web", "startBundle", "startEntry.js"),
62
+ ...s.size > 0 ? { externalizedOptionalPeers: [...s].join(", ") } : {},
63
+ ...l > 0 ? { prunedStaleChunks: l } : {}
64
+ }), M(i, "startEntry.js");
65
+ }, V = I({ scope: "voltro:build" }), H = (e, t) => ({
66
+ name: "voltro:ssr-optional-peer-external",
67
+ enforce: "pre",
68
+ resolveId(n, r) {
69
+ if (n.startsWith(".") || n.startsWith("/") || n.startsWith("\0") || n.startsWith("node:") || n === "effect" || n.startsWith("@effect/") || n.startsWith("@voltro/")) return null;
70
+ for (let t of [r ? j(r) : void 0, e]) if (t !== void 0) try {
71
+ return R(M(t, "_.js")).resolve(n), null;
72
+ } catch {}
73
+ return t.add(n), {
74
+ id: n,
75
+ external: !0
76
+ };
77
+ }
78
+ }), U = (e) => /\[/.test(e), W = (e, t) => {
79
+ let n = e.split("/").filter(Boolean), r = [];
80
+ for (let i of n) if (i.startsWith("[[...") && i.endsWith("]]")) {
81
+ let e = t[i.slice(5, -2)];
82
+ e && e.length > 0 && r.push(e);
83
+ } else if (i.startsWith("[...") && i.endsWith("]")) {
84
+ let n = i.slice(4, -1), a = t[n];
85
+ if (!a) throw Error(`resolvePattern: missing required catch-all param "${n}" for pattern ${e}`);
86
+ r.push(a);
87
+ } else if (i.startsWith("[") && i.endsWith("]")) {
88
+ let n = i.slice(1, -1), a = t[n];
89
+ if (!a) throw Error(`resolvePattern: missing required param "${n}" for pattern ${e}`);
90
+ if (a.includes("/")) throw Error(`resolvePattern: param "${n}" contains "/" but pattern segment is single-component: ${e}`);
91
+ r.push(a);
92
+ } else r.push(i);
93
+ return r.length === 0 ? "/" : "/" + r.join("/");
94
+ }, G = (e, t) => {
95
+ if (t === "/" || t === "") return M(e, "index.html");
96
+ let n = t.replace(/^\//, "").split("/");
97
+ return M(e, ...n, "index.html");
98
+ }, K = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), q = (e, t) => {
99
+ let n = e.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`), r = [
100
+ t.metaHtml,
101
+ `<meta name="voltro-interactive" content="${t.interactive}" />`,
102
+ t.stateScript
103
+ ].filter((e) => e.length > 0).join("\n ");
104
+ return n = i(a(n, r), t.documentAttrs), t.interactive === "none" && (n = K(n)), n;
105
+ }, J = async (e) => {
106
+ let { page: t, chainEntries: n, pageMod: r, helpers: i } = e, o = n.filter((e) => e.hasLayout);
107
+ if (o.length === 0) return V.debug("skip page", {
108
+ pattern: t.pattern,
109
+ reason: "renderMode=spa with no layout — nothing to shell"
110
+ }), null;
111
+ if (U(t.pattern)) return V.debug("skip page", {
112
+ pattern: t.pattern,
113
+ reason: "renderMode=spa with a dynamic pattern"
114
+ }), null;
115
+ let s = await Promise.all(o.map(e.loadLayout)), c = o.filter((e, t) => typeof s[t]?.loader == "function").map((e) => e.dir || "/");
116
+ if (c.length > 0) return V.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`, {
117
+ pattern: t.pattern,
118
+ layouts: c
119
+ }), null;
120
+ let { chain: l, segmentLoaderData: u } = await g({
121
+ entries: n,
122
+ loadLayout: e.loadLayout,
123
+ loadError: e.loadError,
124
+ loadPending: e.loadPending,
125
+ ctx: e.ctx
126
+ }), d = {
127
+ pattern: t.pattern,
128
+ Component: r.default,
129
+ meta: r.meta,
130
+ ErrorBoundary: r.ErrorBoundary,
131
+ Pending: r.Pending,
132
+ renderMode: "spa",
133
+ chain: l
134
+ }, f = r.interactive ?? "full", p = x({
135
+ helpers: i,
136
+ page: t.pattern,
137
+ interactive: f,
138
+ delivery: "artefact",
139
+ renderInput: {
140
+ descriptor: d,
141
+ params: {},
142
+ pathname: t.pattern,
143
+ segmentLoaderData: u,
144
+ ...e.outerWrap ? { outerWrap: e.outerWrap } : {},
145
+ ...e.locale ? { locale: e.locale } : {}
146
+ }
147
+ }), m = h({
148
+ helpers: i,
149
+ prepared: p
150
+ }), _ = y({
151
+ helpers: i,
152
+ prepared: p,
153
+ meta: m.meta,
154
+ interactive: f
155
+ }), v = a(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${m.body}</div>`), _), b = G(e.distDir, t.pattern);
156
+ return await F.mkdir(j(b), { recursive: !0 }), await F.writeFile(b, v, "utf8"), V.debug("prerendered spa layout shell", { pattern: t.pattern }), {
157
+ pattern: t.pattern,
158
+ outPath: b
159
+ };
160
+ }, Y = async (e) => {
161
+ let { root: t, distDir: n, pages: i, dirs: a, vite: o } = e, s = M(n, "index.html"), c = await F.readFile(s, "utf8"), l = M(n, "_voltro", "shell.html");
162
+ await F.mkdir(j(l), { recursive: !0 }), await F.writeFile(l, c, "utf8");
163
+ let d = /* @__PURE__ */ new Map();
164
+ for (let t of e.islandsPlans ?? []) {
165
+ let e = M(n, "island-shells", `${t.name}.html`);
166
+ try {
167
+ let n = S(await F.readFile(e, "utf8"), c);
168
+ await F.writeFile(e, n, "utf8"), d.set(t.pattern, n);
169
+ } catch {
170
+ V.warn("islands shell missing — page ships the full entry", {
171
+ pattern: t.pattern,
172
+ expected: e
173
+ });
174
+ }
175
+ }
176
+ let p = M(t, "node_modules", "@voltro", "ui-shadcn"), m = P(M(p, "package.json")) ? p : null, h = [...m ? [
177
+ {
178
+ find: "@voltro/ui-shadcn/tokens.css",
179
+ replacement: M(m, "src/tokens.css")
180
+ },
181
+ {
182
+ find: "@voltro/ui-shadcn/cn",
183
+ replacement: M(m, "src/cn.ts")
184
+ },
185
+ {
186
+ find: "@voltro/ui-shadcn/brand",
187
+ replacement: M(m, "src/brand/voltroLogo.tsx")
188
+ },
189
+ {
190
+ find: "@voltro/ui-shadcn",
191
+ replacement: M(m, "src/index.ts")
192
+ }
193
+ ] : [], ...f(t)], _ = await o.createServer({
194
+ root: M(t, ".framework"),
195
+ envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
196
+ plugins: [(await import("@vitejs/plugin-react")).default(), (await import("@tailwindcss/vite")).default()],
197
+ resolve: {
198
+ alias: h,
199
+ dedupe: [
200
+ "react",
201
+ "react-dom",
202
+ "react-intl",
203
+ "@voltro/i18n"
204
+ ]
205
+ },
206
+ ssr: { noExternal: ["react-intl", "@voltro/i18n"] },
207
+ optimizeDeps: { exclude: ["@voltro/devtools", "@voltro/devtools/styles.css"] },
208
+ server: {
209
+ middlewareMode: !0,
210
+ hmr: !1
211
+ },
212
+ appType: "custom",
213
+ logLevel: "warn"
214
+ }), v = await _.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: y, renderMetaToHtml: b, renderRouterStateScript: x, isDeferredLoaderResult: C, assertDeferralSupported: w, beginStoreSeeds: T, seedPreloadedSubscription: D, seedPreloadedSubscriptionFailure: O } = v, k, A = /* @__PURE__ */ new Map();
215
+ if (e.locales && e.locales.length > 0 && e.defaultLocale) try {
216
+ let n = await _.ssrLoadModule("@voltro/i18n");
217
+ try {
218
+ k = (await _.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
219
+ configured: e.timeZone ?? null,
220
+ defaultTimeZone: e.defaultTimeZone ?? null
221
+ });
222
+ } catch {}
223
+ let r = n.makeSsgWrap;
224
+ 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.");
225
+ for (let n of e.locales) try {
226
+ let i = await _.ssrLoadModule(M(t, "src", "locales", `${n}.ts`)), a = i.default ?? i;
227
+ A.set(n, r(n, a, e.defaultLocale));
228
+ } catch (e) {
229
+ V.warn(`i18n catalog missing for locale '${n}' — pages rendered at /${n}/* will crash. Add src/locales/${n}.ts.`, {}, e);
230
+ }
231
+ } catch (e) {
232
+ V.warn("i18n wrapper unavailable for SSG — pages that call useT() will fail. Check that @voltro/i18n is installed.", {}, e);
233
+ }
234
+ let N = [], I = {}, L = (e) => e.dir === "" ? M(t, "src", "pages") : M(t, "src", "pages", e.dir), R = async (e) => await _.ssrLoadModule(M(L(e), "layout.tsx")), z = async (e) => await _.ssrLoadModule(M(L(e), "error.tsx")), B = async (e) => await _.ssrLoadModule(M(L(e), "loading.tsx")), H = (e, t) => ({
235
+ params: e.params,
236
+ pathname: e.pathname,
237
+ search: "",
238
+ signal: t,
239
+ headers: {},
240
+ query: void 0,
241
+ isServer: !0
242
+ });
243
+ for (let o of i) {
244
+ let i = `${M(t, "src", "pages", o.file)}`, s = await _.ssrLoadModule(i), l = E(s, M("src", "pages", o.file));
245
+ I[o.pattern] = l;
246
+ let f = l.renderMode, p = u(a, o.dirChain);
247
+ if (f === "spa") {
248
+ let t = await J({
249
+ page: o,
250
+ chainEntries: p,
251
+ pageMod: s,
252
+ shellTemplate: c,
253
+ distDir: n,
254
+ helpers: v,
255
+ loadLayout: R,
256
+ loadError: z,
257
+ loadPending: B,
258
+ ctx: H({
259
+ params: {},
260
+ pathname: o.pattern
261
+ }, new AbortController().signal),
262
+ outerWrap: A.get(e.defaultLocale ?? ""),
263
+ locale: e.defaultLocale
264
+ });
265
+ t && N.push(t);
266
+ continue;
267
+ }
268
+ if (f !== "static") {
269
+ V.debug("skip page", {
270
+ pattern: o.pattern,
271
+ reason: `renderMode=${f}`
272
+ });
273
+ continue;
274
+ }
275
+ let m;
276
+ if (U(o.pattern)) {
277
+ if (typeof s.getStaticPaths != "function") {
278
+ V.debug("skip page", {
279
+ pattern: o.pattern,
280
+ reason: "no getStaticPaths export"
281
+ });
282
+ continue;
283
+ }
284
+ try {
285
+ let e = await s.getStaticPaths();
286
+ if (!Array.isArray(e)) {
287
+ V.warn("skip page — getStaticPaths did not return an array", { pattern: o.pattern });
288
+ continue;
289
+ }
290
+ m = e.map((e) => ({
291
+ params: e.params,
292
+ pathname: W(o.pattern, e.params)
293
+ }));
294
+ } catch (e) {
295
+ V.warn("skip page — getStaticPaths threw", { pattern: o.pattern }, e);
296
+ continue;
297
+ }
298
+ if (m.length === 0) {
299
+ V.debug("skip page", {
300
+ pattern: o.pattern,
301
+ reason: "getStaticPaths returned []"
302
+ });
303
+ continue;
304
+ }
305
+ } else m = [{
306
+ params: {},
307
+ pathname: o.pattern
308
+ }];
309
+ let h = s.interactive ?? "full";
310
+ for (let t of m) {
311
+ T();
312
+ let i, a, l = new AbortController();
313
+ try {
314
+ ({chain: i, segmentLoaderData: a} = await g({
315
+ entries: p,
316
+ loadLayout: R,
317
+ loadError: z,
318
+ loadPending: B,
319
+ ctx: H(t, l.signal)
320
+ }));
321
+ } catch (e) {
322
+ let n = e?._voltroControl;
323
+ if (e instanceof Error && n === "redirect") throw Error(`Static page "${t.pathname}" threw RedirectError from a LAYOUT loader at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
324
+ if (e instanceof Error && n === "not-found") {
325
+ V.warn("layout loader threw NotFoundError at build time — skipping artifact", { pathname: t.pathname });
326
+ continue;
327
+ }
328
+ V.warn("layout loader threw, falling back to no layout data", { pathname: t.pathname }, e), {chain: i, segmentLoaderData: a} = await g({
329
+ entries: p,
330
+ loadLayout: async (e) => ({ default: (await R(e)).default }),
331
+ loadError: z,
332
+ loadPending: B,
333
+ ctx: H(t, l.signal)
334
+ });
335
+ }
336
+ let u = {
337
+ pattern: o.pattern,
338
+ Component: s.default,
339
+ meta: s.meta,
340
+ loader: s.loader,
341
+ ErrorBoundary: s.ErrorBoundary,
342
+ Pending: s.Pending,
343
+ renderMode: f,
344
+ chain: i
345
+ }, m = null;
346
+ if (typeof s.loader == "function") {
347
+ let e = new AbortController();
348
+ try {
349
+ m = await s.loader({
350
+ params: t.params,
351
+ pathname: t.pathname,
352
+ search: "",
353
+ headers: {},
354
+ query: void 0,
355
+ signal: e.signal,
356
+ isServer: !0
357
+ });
358
+ } catch (e) {
359
+ if (e instanceof Error && e._voltroControl === "redirect") throw Error(`Static page "${t.pathname}" threw RedirectError at build time. Static pages can't redirect per-request — switch it to renderMode 'ssr'.`);
360
+ if (e instanceof Error && e._voltroControl === "not-found") {
361
+ V.warn("loader threw NotFoundError at build time — skipping artifact", { pathname: t.pathname });
362
+ continue;
363
+ }
364
+ V.warn("loader threw, falling back to null", { pathname: t.pathname }, e);
365
+ }
366
+ }
367
+ C(m) && w({
368
+ page: t.pathname,
369
+ renderMode: f,
370
+ interactive: h
371
+ });
372
+ for (let e of Object.values(a)) C(e) && w({
373
+ page: t.pathname,
374
+ renderMode: f,
375
+ interactive: h
376
+ });
377
+ await r({
378
+ pageMod: s,
379
+ params: t.params,
380
+ query: void 0,
381
+ apiName: void 0,
382
+ seed: D,
383
+ seedFailure: O
384
+ });
385
+ let _ = t.params.locale ?? e.defaultLocale ?? "en", v = A.get(_) ?? A.get(e.defaultLocale ?? ""), S = Date.now(), E = v ? (e) => v(e, {
386
+ timeZone: k,
387
+ renderedAt: S
388
+ }) : void 0, { html: M, meta: P } = y({
389
+ descriptor: u,
390
+ params: t.params,
391
+ pathname: t.pathname,
392
+ loaderData: m,
393
+ segmentLoaderData: a,
394
+ ...E ? { outerWrap: E } : {},
395
+ locale: _
396
+ }), I = h === "islands" ? d.get(o.pattern) : void 0;
397
+ h === "islands" && I === void 0 && V.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: o.pattern });
398
+ let L = q(I ?? c, {
399
+ body: M,
400
+ metaHtml: b(P),
401
+ stateScript: x({
402
+ path: t.pathname,
403
+ loaderData: m,
404
+ segmentLoaderData: a,
405
+ pageLoaderRan: typeof s.loader == "function"
406
+ }),
407
+ interactive: h,
408
+ documentAttrs: {
409
+ lang: _,
410
+ ...k === void 0 ? {} : { timeZone: k },
411
+ renderedAt: S
412
+ }
413
+ }), U = G(n, t.pathname);
414
+ await F.mkdir(j(U), { recursive: !0 }), await F.writeFile(U, L, "utf8"), N.push({
415
+ pattern: t.pathname,
416
+ outPath: U,
417
+ ...P?.noIndex ? { noIndex: !0 } : {}
418
+ });
419
+ }
420
+ }
421
+ return await _.close(), {
422
+ rendered: N,
423
+ pageMeta: I
424
+ };
425
+ }, X = async (e, t, n, r, i, a, o, s) => {
426
+ let c = M(e, ".framework"), l = [];
427
+ for (let e of t) l.push(` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`);
428
+ let u = [], d = [], f = [];
429
+ for (let e of n) {
430
+ let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`, n = e.dir === "" ? "/" : e.dir;
431
+ e.hasLayout && u.push(` ${JSON.stringify(n)}: () => import('${t}/layout.tsx'),`), e.hasError && d.push(` ${JSON.stringify(n)}: () => import('${t}/error.tsx'),`), e.hasPending && f.push(` ${JSON.stringify(n)}: () => import('${t}/loading.tsx'),`);
432
+ }
433
+ let p = [], m = [];
434
+ if (r && r.length > 0 && i) for (let t of r) {
435
+ if (!P(M(e, "src", "locales", `${t}.ts`))) continue;
436
+ let n = `__i18nCat_${t.replace(/[^a-zA-Z0-9]/g, "_")}`;
437
+ 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)}),`);
438
+ }
439
+ let h = m.length > 0, g = !h && r !== void 0 && r.length > 0 && i !== void 0, _ = h ? [
440
+ "import { makeSsgWrap } from '@voltro/i18n'",
441
+ "import { makeSsrI18nResolver } from '@voltro/i18n/server'",
442
+ ...p
443
+ ] : g ? ["import { resolveLocale, resolveTimeZone } from '@voltro/i18n/server'"] : [], v = h ? [
444
+ "",
445
+ `const __I18N_SUPPORTED = ${JSON.stringify(r)} as ReadonlyArray<string>`,
446
+ `const __I18N_DEFAULT = ${JSON.stringify(i)}`,
447
+ "const __i18nWraps: Record<string, (children: unknown, request?: { timeZone?: string | undefined; renderedAt?: number | undefined }) => unknown> = {",
448
+ ...m,
449
+ "}",
450
+ "// Cookie voltro:locale > Accept-Language > default → the matching wrapper.",
451
+ "// The SAME resolver `voltro dev` calls (webDev.ts) — this used to be a",
452
+ "// hand-written copy here and NOTHING at all in dev, which is why a",
453
+ "// localized page rendered under `voltro start` and threw under `voltro dev`.",
454
+ "const __resolveI18n = makeSsrI18nResolver({",
455
+ " wraps: __i18nWraps,",
456
+ " supported: __I18N_SUPPORTED,",
457
+ " defaultLocale: __I18N_DEFAULT,",
458
+ ` timeZone: ${JSON.stringify(o?.timeZone ?? null)},`,
459
+ ` defaultTimeZone: ${JSON.stringify(o?.defaultTimeZone ?? null)},`,
460
+ "})"
461
+ ] : g ? [
462
+ "",
463
+ `const __I18N_SUPPORTED = ${JSON.stringify(r)} as ReadonlyArray<string>`,
464
+ `const __I18N_DEFAULT = ${JSON.stringify(i)}`,
465
+ "// `locales:` declared, no src/locales/* catalogs: resolve the language,",
466
+ "// wrap nothing. `outerWrap` is identity so every caller downstream is",
467
+ "// unchanged — the ONE difference from the wired path is that no provider",
468
+ "// is mounted, which is exactly what an app on its own i18n stack wants.",
469
+ "const __resolveI18n = (cookieHeader?: string | null, acceptLanguageHeader?: string | null) => ({",
470
+ " locale: resolveLocale({",
471
+ " cookieHeader: cookieHeader ?? null,",
472
+ " acceptLanguageHeader: acceptLanguageHeader ?? null,",
473
+ " supported: __I18N_SUPPORTED,",
474
+ " defaultLocale: __I18N_DEFAULT,",
475
+ " }),",
476
+ " timeZone: resolveTimeZone({",
477
+ " cookieHeader: cookieHeader ?? null,",
478
+ ` configured: ${JSON.stringify(o?.timeZone ?? null)},`,
479
+ ` defaultTimeZone: ${JSON.stringify(o?.defaultTimeZone ?? null)},`,
480
+ " }),",
481
+ " outerWrap: (children: unknown) => children,",
482
+ "})"
483
+ ] : [], y = (s ?? []).map((e) => `${JSON.stringify(e.name)}: () => import('${e.pkg}/rpcGroup').then((m) => m.appDescriptors)`).join(", "), b = y === "" ? "" : `, apiDescriptors: { ${y} }`, x = "renderPageToHtml, renderPageToStream, renderMetaToHtml, renderRouterStateScript, renderDeferredRegistryScript, prepareDeferredLoaderData, assertDeferralSupported, parseCookieHeader, withStoreSeeds, beginStoreSeeds", S = h || g ? `export const helpers = { ${x}, i18n: { resolve: __resolveI18n }${b} }` : `export const helpers = { ${x}${b} }`, C = [
484
+ "// GENERATED BY `voltro build` — do not edit; will be overwritten on next build.",
485
+ "// Entry for the pre-built SSR bundle. Imported by `voltro start`'s",
486
+ "// production runtime; bypasses Vite middleware-mode SSR loading.",
487
+ "",
488
+ "import { renderPageToHtml, renderPageToStream, renderMetaToHtml, renderRouterStateScript, renderDeferredRegistryScript, prepareDeferredLoaderData, assertDeferralSupported, parseCookieHeader, withStoreSeeds, beginStoreSeeds } from '@voltro/web/ssr'",
489
+ ..._,
490
+ "",
491
+ "// Lazy page loaders — a page's module (and content) loads only when its",
492
+ "// route is rendered, so importing this entry never pulls every page into memory.",
493
+ "export const pages: Record<string, () => Promise<unknown>> = {",
494
+ ...l,
495
+ "}",
496
+ "// Build-time per-route metadata — `voltro start` reads this instead of",
497
+ "// importing every page module at boot just to inspect its render mode.",
498
+ `export const pageMeta: Record<string, unknown> = ${JSON.stringify(a ?? {}, null, 2)}`,
499
+ "export const layouts: Record<string, () => Promise<unknown>> = {",
500
+ ...u,
501
+ "}",
502
+ "export const errors: Record<string, () => Promise<unknown>> = {",
503
+ ...d,
504
+ "}",
505
+ "export const pendings: Record<string, () => Promise<unknown>> = {",
506
+ ...f,
507
+ "}",
508
+ ...v,
509
+ "",
510
+ S,
511
+ ""
512
+ ].join("\n"), w = M(c, "ssrEntry.ts");
513
+ return await F.writeFile(w, C, "utf8"), w;
514
+ }, Z = async (e) => {
515
+ let { checkRpcGroupFreshness: t } = await import("./codegen-CctkDO-1.js"), n = await t(e);
516
+ if (n.kind === "fresh") return;
517
+ n.kind === "stale" && V.info("rpcGroup.generated.ts is stale — regenerating", {
518
+ file: n.file,
519
+ reason: n.reason
520
+ });
521
+ let { regenerateRpcGroup: r } = await import("./codegenCommand-DCdG2JN-.js"), i = await r(e);
522
+ if (i.kind === "refused") {
523
+ V.warn("could not regenerate the rpc group — building against what is on disk", { reason: i.reason });
524
+ return;
525
+ }
526
+ i.kind === "wrote" && n.kind === "stale" && V.info("rpc group regenerated", {
527
+ plugins: i.plugins,
528
+ routes: i.routes
529
+ });
530
+ }, Q = async (e) => {
531
+ let r = await d(e);
532
+ if (!r) {
533
+ let { loadApiConfig: t } = await import("./dev--A3nsxA3.js"), n = await t(e);
534
+ if (n) {
535
+ V.info("building api app", { app: n.name ?? "(unnamed)" }), await Z(e);
536
+ let { runApiBuild: t, runServeBundleBuild: r } = await import("./apiBuild-BYBpL7Pz.js");
537
+ await t(e);
538
+ try {
539
+ await r(e);
540
+ } catch (e) {
541
+ return V.fatal("serve bundle build FAILED — refusing to ship a bundle-less image. Fix the error above (production serves from the bundle, never tsx).", {}, e), {
542
+ ran: !0,
543
+ exitCode: 1
544
+ };
545
+ }
546
+ return {
547
+ ran: !0,
548
+ exitCode: 0
549
+ };
550
+ }
551
+ return {
552
+ ran: !1,
553
+ exitCode: 0
554
+ };
555
+ }
556
+ V.info("building web app", { app: r.name ?? "(unnamed)" });
557
+ let { resolved: i } = await n({
558
+ rawEnv: r.env,
559
+ appType: "web",
560
+ root: e,
561
+ log: V,
562
+ generateTypes: !0
563
+ }), a = await v(e, r);
564
+ await C(e, r, a, i.publicValues);
565
+ let { pages: u } = await l(M(e, "src", "pages")), h = [];
566
+ for (let t of u) {
567
+ let n = await F.readFile(M(e, "src", "pages", t.file), "utf8").catch(() => "");
568
+ m(n) === "islands" && h.push({
569
+ pattern: t.pattern,
570
+ file: t.file
571
+ });
572
+ }
573
+ let g = p(a, "../../app.config"), y = await _({
574
+ webRoot: e,
575
+ pages: h,
576
+ headSnippets: b(await F.readFile(M(e, ".framework", "index.html"), "utf8").catch(() => "")),
577
+ apiImports: g.imports,
578
+ apiEntriesLiteral: `[\n${g.providerEntryLines.join("\n")}\n ]`
579
+ });
580
+ y.length > 0 && V.info("per-page islands entries", { pages: y.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
581
+ let { pages: x } = await l(M(e, "src", "pages"));
582
+ await o({
583
+ appRoot: e,
584
+ pages: x,
585
+ mode: "prod"
586
+ });
587
+ let S = M(e, ".framework"), T = M(S, "dist"), E = M(e, "node_modules", "@voltro", "ui-shadcn"), D = P(M(E, "package.json")) ? E : null, k = [...D ? [
588
+ {
589
+ find: "@voltro/ui-shadcn/tokens.css",
590
+ replacement: M(D, "src/tokens.css")
591
+ },
592
+ {
593
+ find: "@voltro/ui-shadcn/cn",
594
+ replacement: M(D, "src/cn.ts")
595
+ },
596
+ {
597
+ find: "@voltro/ui-shadcn/brand",
598
+ replacement: M(D, "src/brand/voltroLogo.tsx")
599
+ },
600
+ {
601
+ find: "@voltro/ui-shadcn",
602
+ replacement: M(D, "src/index.ts")
603
+ }
604
+ ] : [], ...f(e)];
605
+ V.info("running vite build");
606
+ let j = await t("vite", () => import("vite")), N = (await import("@vitejs/plugin-react")).default, I = (await import("@tailwindcss/vite")).default;
607
+ await j.build({
608
+ root: S,
609
+ envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
610
+ plugins: [N(), I()],
611
+ resolve: {
612
+ alias: k,
613
+ dedupe: [
614
+ "react",
615
+ "react-dom",
616
+ "react-intl",
617
+ "@voltro/i18n"
618
+ ]
619
+ },
620
+ publicDir: M(e, "public"),
621
+ build: {
622
+ outDir: "dist",
623
+ emptyOutDir: !0,
624
+ rollupOptions: {
625
+ input: {
626
+ index: M(S, "index.html"),
627
+ ...Object.fromEntries(y.map((e) => [`island_${e.name}`, M(S, e.htmlFile)]))
628
+ },
629
+ output: { manualChunks: w }
630
+ }
631
+ },
632
+ logLevel: "warn"
633
+ });
634
+ let L = M(e, "src", "pages"), { pages: R, dirs: z } = await l(L);
635
+ if (R.length === 0) return V.info("no pages found — client-only bundle written", {
636
+ pagesDir: L,
637
+ distDir: T
638
+ }), {
639
+ ran: !0,
640
+ exitCode: 0
641
+ };
642
+ let { rendered: U, pageMeta: W } = await Y({
643
+ root: e,
644
+ distDir: T,
645
+ pages: R,
646
+ dirs: z,
647
+ vite: j,
648
+ islandsPlans: y,
649
+ ...r.locales ? { locales: r.locales } : {},
650
+ ...r.defaultLocale ? { defaultLocale: r.defaultLocale } : {},
651
+ ...r.timeZone ? { timeZone: r.timeZone } : {},
652
+ ...r.defaultTimeZone ? { defaultTimeZone: r.defaultTimeZone } : {}
653
+ });
654
+ V.info("generating .framework/ssrEntry.ts"), await X(e, R, z, r.locales, r.defaultLocale, W, {
655
+ ...r.timeZone ? { timeZone: r.timeZone } : {},
656
+ ...r.defaultTimeZone ? { defaultTimeZone: r.defaultTimeZone } : {}
657
+ }, a.map((e) => ({
658
+ name: e.name,
659
+ pkg: e.pkg
660
+ }))), V.info("vite build --ssr → dist/server/");
661
+ let G = /* @__PURE__ */ new Set();
662
+ try {
663
+ await j.build({
664
+ root: S,
665
+ envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
666
+ plugins: [
667
+ N(),
668
+ I(),
669
+ H(e, G)
670
+ ],
671
+ resolve: {
672
+ alias: k,
673
+ dedupe: [
674
+ "react",
675
+ "react-dom",
676
+ "react-intl",
677
+ "@voltro/i18n"
678
+ ]
679
+ },
680
+ ssr: { noExternal: !0 },
681
+ build: {
682
+ outDir: "dist/server",
683
+ ssr: "ssrEntry.ts",
684
+ emptyOutDir: !0,
685
+ rollupOptions: { output: { format: "esm" } }
686
+ },
687
+ logLevel: "warn"
688
+ }), V.info("SSR bundle ready", {
689
+ path: "dist/server/ssrEntry.js",
690
+ ...G.size > 0 ? { externalizedOptionalPeers: [...G].join(", ") } : {}
691
+ });
692
+ } catch (e) {
693
+ return V.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), {
694
+ ran: !0,
695
+ exitCode: 1
696
+ };
697
+ }
698
+ let K = M(e, "app.config.ts");
699
+ if (P(K)) {
700
+ V.info("precompiling app.config.ts → dist/server/appConfig.js");
701
+ try {
702
+ await (await t("esbuild", () => import("esbuild"))).build({
703
+ entryPoints: [K],
704
+ outfile: M(T, "server", "appConfig.js"),
705
+ bundle: !0,
706
+ format: "esm",
707
+ platform: "node",
708
+ target: "node22",
709
+ plugins: [O([], e, /* @__PURE__ */ new Set())],
710
+ banner: { js: "import { createRequire as __voltroRequire } from 'node:module'; const require = __voltroRequire(import.meta.url);" },
711
+ jsx: "automatic",
712
+ jsxImportSource: "react",
713
+ absWorkingDir: e,
714
+ logLevel: "silent",
715
+ ...P(M(e, "tsconfig.json")) ? { tsconfig: M(e, "tsconfig.json") } : {}
716
+ });
717
+ } catch (e) {
718
+ return V.fatal("app.config precompile FAILED — production `voltro start` would need the tsx loader to read it.", {}, e), {
719
+ ran: !0,
720
+ exitCode: 1
721
+ };
722
+ }
723
+ }
724
+ try {
725
+ await B(e);
726
+ } catch (e) {
727
+ V.warn("start bundle build failed — `voltro start` will use the slower per-module boot", {}, e);
728
+ }
729
+ V.info(`pre-rendered ${U.length} static route(s)`, {
730
+ count: U.length,
731
+ routes: U.map((e) => e.pattern)
732
+ });
733
+ try {
734
+ let e = process.env.VOLTRO_SEO_NOINDEX !== "1", t = r.seo?.siteUrl, n = r.locales ?? [], i = r.defaultLocale ?? n[0];
735
+ if (t && !P(M(T, "sitemap.xml"))) {
736
+ let r = new Set(n.filter((e) => e !== i)), a = U.filter((e) => !e.noIndex).map((e) => e.pattern).filter((e) => {
737
+ let t = e.split("/").filter(Boolean)[0];
738
+ return t === void 0 || !r.has(t);
739
+ }).filter((e) => !e.includes("[")).map((e) => ({ path: e })), o = c({
740
+ siteUrl: t,
741
+ entries: a,
742
+ ...n.length > 1 ? { locales: n } : {},
743
+ ...i ? { defaultLocale: i } : {}
744
+ });
745
+ await F.writeFile(M(T, "sitemap.xml"), o, "utf8"), V.info("wrote dist/sitemap.xml", {
746
+ urls: a.length,
747
+ indexable: e
748
+ });
749
+ }
750
+ if (!P(M(T, "robots.txt"))) {
751
+ let n = s({
752
+ indexable: e,
753
+ ...e && t ? { sitemapUrl: `${t.replace(/\/$/, "")}/sitemap.xml` } : {},
754
+ ...r.seo?.disallow ? { disallow: r.seo.disallow } : {}
755
+ });
756
+ await F.writeFile(M(T, "robots.txt"), n, "utf8"), V.info("wrote dist/robots.txt", { indexable: e });
757
+ }
758
+ } catch (e) {
759
+ V.warn("SEO artefact generation failed (non-fatal)", {}, e);
760
+ }
761
+ try {
762
+ let t = await A(e);
763
+ await F.writeFile(M(T, ".voltro-build.json"), JSON.stringify({
764
+ version: 1,
765
+ profile: t
766
+ }, null, 2), "utf8"), V.info("wrote deploy profile manifest", {
767
+ staticSafe: t.staticSafe,
768
+ ssr: t.counts.ssr,
769
+ isr: t.counts.isr
770
+ });
771
+ } catch (e) {
772
+ V.warn("could not write .voltro-build.json deploy manifest", {}, e);
773
+ }
774
+ return V.info("build complete", { distDir: T }), {
775
+ ran: !0,
776
+ exitCode: 0
777
+ };
778
+ }, $ = (e) => L.gen(function* () {
779
+ let t = yield* L.tryPromise({
780
+ try: () => Q(N(e)),
781
+ catch: (e) => e
782
+ }).pipe(L.orDie);
783
+ return t.ran ? t.exitCode : (yield* L.logError("no web app found at this path", { hint: "looked for app.config.ts with `type: 'web'`" }), 1);
784
+ }), ee = async (t) => {
785
+ if (t.includes("--target")) {
786
+ let { runSdkBuildCommand: e } = await import("./sdkgen-Se88ifTd.js");
787
+ return e(t);
788
+ }
789
+ let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await T($(n), { scope: "voltro:build" }), i = e(n);
790
+ return i.warning !== void 0 && V.warn(i.warning), r;
791
+ };
792
+ //#endregion
793
+ export { ee as runBuildCommand };