@voltro/cli 0.58.0 → 0.60.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 (83) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/dist/apiBuild-B9OvhITV.js +2 -0
  3. package/dist/{apiBuild-CkpsCqIu.js → apiBuild-BU5cd-Fn.js} +50 -48
  4. package/dist/bin.js +1 -1
  5. package/dist/{build-51qBWfYY.js → build-BxAsLzyU.js} +347 -258
  6. package/dist/{checkCommand-C1EbNmwl.js → checkCommand-C1CQc8lD.js} +1 -1
  7. package/dist/{checkCommand-C30J2F18.js → checkCommand-DC7k1_hP.js} +1 -1
  8. package/dist/{codemodRunner-BKjCwGiN.js → codemodRunner-ClUqkhvR.js} +523 -390
  9. package/dist/{commands-DowWkYtd.js → commands-Ro4hYBHD.js} +12 -12
  10. package/dist/{dashboardCommand-gG1y4PFG.js → dashboardCommand-t8Qsebjr.js} +1 -1
  11. package/dist/{doctorCommand-5ULMpL10.js → doctorCommand-CGjefPmk.js} +2 -2
  12. package/dist/doctorCommand-DXnNpKQT.js +2 -0
  13. package/dist/{evolveCommand-DTawtTxf.js → evolveCommand-CThb0EZZ.js} +2 -2
  14. package/dist/index.js +1 -1
  15. package/dist/{infoCommand-BFksHunl.js → infoCommand-a0WkKcUY.js} +1 -1
  16. package/dist/{runtimeTrace-BUk5zMXY.js → runtimeTrace-DDuKJgVi.js} +1 -1
  17. package/dist/{sdkgen-CAhmmbjx.js → sdkgen-vq1fF9D_.js} +1 -1
  18. package/dist/serveCommand-1R52mo6F.js +2 -0
  19. package/dist/{serveCommand-DhtC7WBq.js → serveCommand-Dr4KXmTS.js} +1 -1
  20. package/dist/serveEntry.js +1 -1
  21. package/dist/{start-C75w6ftA.js → start-BhoDQ25C.js} +1 -1
  22. package/dist/{start-DNtIlBcn.js → start-CcdPRG8L.js} +418 -367
  23. package/dist/startEntry.js +1 -1
  24. package/dist/{updateCommand-CtuD5r1t.js → updateCommand-D9avpQFT.js} +1 -1
  25. package/dist/updateCommand-QMOirvXC.js +2 -0
  26. package/package.json +37 -19
  27. package/templates/AGENTS.md +1 -1
  28. package/templates/agent-docs/_index.md +1 -1
  29. package/templates/agent-docs/ai.md +50 -1
  30. package/templates/agent-docs/cli.md +7 -6
  31. package/templates/agent-docs/plugins/sentry.md +142 -16
  32. package/templates/agent-docs/whats-new.md +25 -168
  33. package/templates/apps/api-ai/package.json +6 -6
  34. package/templates/apps/api-auth/package.json +8 -8
  35. package/templates/apps/api-backend/package.json +7 -7
  36. package/templates/apps/api-backend-deactivation/package.json +7 -7
  37. package/templates/apps/api-backend-mail/package.json +8 -8
  38. package/templates/apps/api-backend-mariadb/package.json +9 -9
  39. package/templates/apps/api-backend-sqlite/package.json +8 -8
  40. package/templates/apps/api-backend-storage/package.json +8 -8
  41. package/templates/apps/api-cms/package.json +9 -9
  42. package/templates/apps/api-collab/package.json +8 -8
  43. package/templates/apps/api-data-advanced/package.json +8 -8
  44. package/templates/apps/api-durable/package.json +8 -8
  45. package/templates/apps/api-feature-flags/package.json +9 -9
  46. package/templates/apps/api-governance/package.json +8 -8
  47. package/templates/apps/api-kv/package.json +8 -8
  48. package/templates/apps/api-moderation/package.json +8 -8
  49. package/templates/apps/api-observability/package.json +8 -8
  50. package/templates/apps/api-ratelimit/package.json +8 -8
  51. package/templates/apps/api-rbac/package.json +8 -8
  52. package/templates/apps/api-rest/package.json +7 -7
  53. package/templates/apps/api-row-history/package.json +8 -8
  54. package/templates/apps/api-saas/package.json +11 -11
  55. package/templates/apps/api-saas-starter/package.json +10 -10
  56. package/templates/apps/api-search/package.json +8 -8
  57. package/templates/apps/api-status/package.json +8 -8
  58. package/templates/apps/api-webhooks/package.json +9 -9
  59. package/templates/apps/changelog/package.json +7 -7
  60. package/templates/apps/edge-functions/package.json +2 -2
  61. package/templates/apps/frontend-admin/package.json +7 -7
  62. package/templates/apps/frontend-app/package.json +8 -8
  63. package/templates/apps/frontend-auth/package.json +7 -7
  64. package/templates/apps/frontend-blank/package.json +6 -6
  65. package/templates/apps/frontend-cms/package.json +8 -8
  66. package/templates/apps/frontend-collab/package.json +9 -9
  67. package/templates/apps/frontend-contact/package.json +7 -7
  68. package/templates/apps/frontend-dashboard/package.json +6 -6
  69. package/templates/apps/frontend-docs/package.json +8 -8
  70. package/templates/apps/frontend-i18n/package.json +6 -6
  71. package/templates/apps/frontend-landing/package.json +7 -7
  72. package/templates/apps/frontend-portal/package.json +7 -7
  73. package/templates/apps/frontend-saas/package.json +7 -7
  74. package/templates/apps/frontend-spa/package.json +6 -6
  75. package/templates/apps/frontend-ssr/package.json +6 -6
  76. package/templates/apps/frontend-ssr-api/package.json +7 -7
  77. package/templates/apps/frontend-static-blog/package.json +8 -8
  78. package/templates/apps/frontend-status/package.json +7 -7
  79. package/templates/apps/mobile-app/package.json +4 -4
  80. package/dist/apiBuild-CDE4NXNi.js +0 -2
  81. package/dist/doctorCommand-B8H2MYCE.js +0 -2
  82. package/dist/serveCommand-BUXUtSF5.js +0 -2
  83. package/dist/updateCommand-eVKVHj3N.js +0 -2
@@ -1,25 +1,25 @@
1
1
  import { An as e } from "./dev-Ce2gEziv.js";
2
- import { At as t, Ct as n, D as r, Dt as i, Et as a, J as o, K as s, Mt as c, Nt as l, Ot as u, Qt as d, St as f, T as p, Tt as m, Yt as h, _t as g, c as _, et as v, gt as y, h as b, kt as x, m as S, nt as C, o as w, q as T, tt as E, u as D, vt as ee, w as O, wt as k, zt as A } from "./webDev-CBN9KkyQ.js";
3
- import { d as j, i as M, o as N, s as P } from "./apiBuild-CkpsCqIu.js";
4
- import { t as F } from "./cliRuntime-Dh7UDinH.js";
5
- import { a as I } from "./renderModeScan-43yQ2opo.js";
6
- import { o as L } from "./imagePipeline-CBZmjT4i.js";
7
- import { a as R } from "./fontPipeline-Tsh8kZfA.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";
11
- import { pathToFileURL as G } from "node:url";
12
- import { createLogger as K } from "@voltro/logger";
13
- import { setProcessBootPath as q } from "@voltro/protocol/identity";
14
- import { Effect as J } from "effect";
15
- import { createRequire as Y } from "node:module";
16
- import { readdir as te, rm as X, stat as Z } from "node:fs/promises";
2
+ import { At as t, Ct as n, D as r, Dt as i, Et as a, J as o, K as s, Mt as c, Nt as l, Ot as u, Qt as d, St as f, T as p, Tt as m, Yt as h, _t as g, c as _, et as v, gt as y, h as b, kt as x, m as S, nt as C, o as w, q as T, tt as E, u as D, vt as ee, w as te, wt as O, zt as k } from "./webDev-CBN9KkyQ.js";
3
+ import { d as A, i as j, o as M, s as N } from "./apiBuild-BU5cd-Fn.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 ne } from "./renderProfile-DvrhVJHa.js";
9
+ import { dirname as R, join as z, resolve as B } from "node:path";
10
+ import { existsSync as V, promises as H } from "node:fs";
11
+ import { pathToFileURL as U } from "node:url";
12
+ import { createLogger as W } from "@voltro/logger";
13
+ import { setProcessBootPath as G } from "@voltro/protocol/identity";
14
+ import { Effect as K } from "effect";
15
+ import { createRequire as q } from "node:module";
16
+ import { readdir as J, rm as Y, stat as re } from "node:fs/promises";
17
17
  //#region src/webStartBundle.ts
18
- var ne = K({ scope: "voltro:build" }), re = async (e) => {
19
- let t = await d("esbuild", () => import("esbuild")), n = V(e, ".framework"), r = V(n, "dist-web", "startBundle");
20
- await W.mkdir(n, { recursive: !0 });
21
- let i = Date.now(), a = V(e, "tsconfig.json"), o = /* @__PURE__ */ new Set(), s = V(n, "startEntry.ts");
22
- await W.writeFile(s, [
18
+ var X = W({ scope: "voltro:build" }), ie = async (e, t = {}) => {
19
+ let n = await d("esbuild", () => import("esbuild")), r = z(e, ".framework"), i = z(r, "dist-web", "startBundle");
20
+ await H.mkdir(r, { recursive: !0 });
21
+ let a = Date.now(), o = z(e, "tsconfig.json"), s = /* @__PURE__ */ new Set(), c = z(r, "startEntry.ts");
22
+ await H.writeFile(c, [
23
23
  "// GENERATED BY `voltro build` — do not edit; overwritten on next build.",
24
24
  "import { runStartCommand as __run, loadDotEnv } from '@voltro/cli/startEntry'",
25
25
  "import { pathToFileURL, fileURLToPath } from 'node:url'",
@@ -42,33 +42,34 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
42
42
  " runStartCommand(process.argv.slice(2)).then((c) => process.exit(typeof c === 'number' ? c : 0))",
43
43
  "}",
44
44
  ""
45
- ].join("\n"), "utf8"), await t.build({
46
- entryPoints: [s],
45
+ ].join("\n"), "utf8"), await n.build({
46
+ entryPoints: [c],
47
47
  bundle: !0,
48
48
  format: "esm",
49
49
  platform: "node",
50
50
  target: "node22",
51
- outdir: r,
51
+ outdir: i,
52
52
  splitting: !0,
53
53
  write: !0,
54
54
  minify: !0,
55
55
  keepNames: !0,
56
- plugins: [N([], e, o)],
57
- banner: { js: j() },
56
+ sourcemap: t.sourcemaps === !0 && "external",
57
+ plugins: [M([], e, s)],
58
+ banner: { js: A() },
58
59
  jsx: "automatic",
59
60
  jsxImportSource: "react",
60
61
  logLevel: "silent",
61
62
  absWorkingDir: e,
62
- alias: M("startEntry"),
63
- ...U(a) ? { tsconfig: a } : {}
63
+ alias: j("startEntry"),
64
+ ...V(o) ? { tsconfig: o } : {}
64
65
  });
65
- let c = await P(r, i);
66
- return ne.info("web build: start bundle written", {
67
- out: V(".framework", "dist-web", "startBundle", "startEntry.js"),
68
- ...o.size > 0 ? { externalizedOptionalPeers: [...o].join(", ") } : {},
69
- ...c > 0 ? { prunedStaleChunks: c } : {}
70
- }), V(r, "startEntry.js");
71
- }, ie = "~/assets", ae = (e, t) => {
66
+ let l = await N(i, a);
67
+ return X.info("web build: start bundle written", {
68
+ out: z(".framework", "dist-web", "startBundle", "startEntry.js"),
69
+ ...s.size > 0 ? { externalizedOptionalPeers: [...s].join(", ") } : {},
70
+ ...l > 0 ? { prunedStaleChunks: l } : {}
71
+ }), z(i, "startEntry.js");
72
+ }, ae = "~/assets", oe = (e, t) => {
72
73
  if (e === void 0) return {
73
74
  emit: !1,
74
75
  keep: !1
@@ -82,9 +83,9 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
82
83
  keep: e.keep ?? !0
83
84
  };
84
85
  let { org: n, project: r, url: i, urlPrefix: a } = e.upload, o = e.upload.release ?? t.SENTRY_RELEASE;
85
- if (o === void 0 || o === "") return { problem: "web.sourcemaps.upload is configured but no release is known. Sentry matches an uploaded artifact to an event by RELEASE, so an upload without one resolves no frame — and says nothing, because an upload that matched nothing looks exactly like one that worked.\n → set SENTRY_RELEASE for the build (the same value `sentryPlugin` reports events under), or pass `release` explicitly." };
86
+ if (o === void 0 || o === "") return { problem: "sourcemaps.upload is configured but no release is known. Sentry matches an uploaded artifact to an event by RELEASE, so an upload without one resolves no frame — and says nothing, because an upload that matched nothing looks exactly like one that worked.\n → set SENTRY_RELEASE for the build (the same value `sentryPlugin` reports events under), or pass `release` explicitly." };
86
87
  let s = t.SENTRY_AUTH_TOKEN;
87
- return s === void 0 || s === "" ? { problem: "web.sourcemaps.upload is configured but SENTRY_AUTH_TOKEN is not set.\n It is read from the environment and is deliberately NOT a config field: `app.config.ts` is committed, and a token with `project:releases` scope can write to every project in the org.\n → provide it to the BUILD (a CI secret / a Docker build secret), not to the deployment — the upload happens while the bundle is being built." } : {
88
+ return s === void 0 || s === "" ? { problem: "sourcemaps.upload is configured but SENTRY_AUTH_TOKEN is not set.\n It is read from the environment and is deliberately NOT a config field: `app.config.ts` is committed, and a token with `project:releases` scope can write to every project in the org.\n → provide it to the BUILD (a CI secret / a Docker build secret), not to the deployment — the upload happens while the bundle is being built." } : {
88
89
  emit: !0,
89
90
  keep: e.keep ?? !1,
90
91
  upload: {
@@ -92,61 +93,85 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
92
93
  project: r,
93
94
  release: o,
94
95
  authToken: s,
95
- urlPrefix: a ?? ie,
96
+ ...a === void 0 ? {} : { urlPrefix: a },
96
97
  ...i === void 0 ? {} : { url: i }
97
98
  }
98
99
  };
99
- }, oe = (e) => "problem" in e, se = async (e) => {
100
+ }, se = (e) => "problem" in e, Z = async (e) => {
100
101
  let t = [], n = async (e) => {
101
102
  let r;
102
103
  try {
103
- r = await te(e);
104
+ r = await J(e);
104
105
  } catch {
105
106
  return;
106
107
  }
107
108
  for (let i of r) {
108
- let r = V(e, i), a = await Z(r).catch(() => void 0);
109
+ let r = z(e, i), a = await re(r).catch(() => void 0);
109
110
  a !== void 0 && (a.isDirectory() ? await n(r) : i.endsWith(".map") && t.push(r));
110
111
  }
111
112
  };
112
113
  return await n(e), t.sort();
113
- }, ce = (e) => async (t, n, r) => {
114
- let i = new (await (le(e)))(null, {
115
- authToken: t.authToken,
116
- org: t.org,
117
- project: t.project,
118
- ...t.url === void 0 ? {} : { url: t.url },
114
+ }, Q = (e, t) => {
115
+ let n = /* @__PURE__ */ new Map();
116
+ for (let r of e) {
117
+ let e = t ?? r.urlPrefix;
118
+ n.set(e, [...n.get(e) ?? [], r.dir]);
119
+ }
120
+ return [...n];
121
+ }, ce = (e, t = ue) => async (n, r, i) => {
122
+ let a = new (await (t(e)))(null, {
123
+ authToken: n.authToken,
124
+ org: n.org,
125
+ project: n.project,
126
+ ...n.url === void 0 ? {} : { url: n.url },
119
127
  silent: !1
120
128
  });
121
- await i.releases.new(t.release), await i.releases.uploadSourceMaps(t.release, {
122
- include: [r],
123
- urlPrefix: t.urlPrefix,
129
+ await a.execute([
130
+ "sourcemaps",
131
+ "inject",
132
+ ...i.map((e) => e.dir)
133
+ ], !0), await a.releases.new(n.release);
134
+ for (let [e, t] of Q(i, n.urlPrefix)) await a.releases.uploadSourceMaps(n.release, {
135
+ include: t,
136
+ urlPrefix: e,
124
137
  rewrite: !0
125
- }), await i.releases.finalize(t.release);
126
- }, le = async (e) => {
127
- let t = Y(V(e, "package.json")), n = [];
138
+ });
139
+ await a.releases.finalize(n.release);
140
+ }, le = (e) => {
141
+ let t = e, n = [
142
+ t?.SentryCli,
143
+ t?.default?.SentryCli,
144
+ t?.default,
145
+ e
146
+ ];
147
+ for (let e of n) if (typeof e == "function") return e;
148
+ }, ue = async (e) => {
149
+ let t = q(z(e, "package.json")), n = !1, r = [];
128
150
  try {
129
- let e = await import(G(t.resolve("@sentry/cli")).href), r = e.default ?? e;
130
- if (typeof r == "function") return r;
131
- n.push("resolved a module that is not the SentryCli constructor");
151
+ let e = t.resolve("@sentry/cli");
152
+ n = !0;
153
+ let i = await import(U(e).href), a = le(i);
154
+ if (a !== void 0) return a;
155
+ r.push(`loaded ${e} but found no SentryCli constructor on it (keys: ${Object.keys(i).join(", ") || "none"})`);
132
156
  } catch (e) {
133
- n.push(e instanceof Error ? e.message : String(e));
157
+ r.push(e instanceof Error ? e.message : String(e));
134
158
  }
135
- throw Error("web.sourcemaps.upload is configured but `@sentry/cli` could not be loaded.\n The framework does not ship it: its licence (FSL-1.1-MIT) restricts commercial use, so it is yours to install rather than ours to depend on.\n → `pnpm add -D @sentry/cli` in the web app.\n" + n.map((e) => ` · ${e}`).join("\n"));
136
- }, ue = async (e, t, n = {}) => {
159
+ throw Error((n ? "sourcemaps.upload is configured and `@sentry/cli` IS installed, but no constructor could be read from it.\n That is a module shape we do not recognise, not a missing install — the loader accepts both the 2.x (`module.exports =`) and 3.x (`exports.SentryCli =`) forms. Please report the version.\n" : "sourcemaps.upload is configured but `@sentry/cli` could not be resolved.\n The framework does not ship it: its licence (FSL-1.1-MIT) restricts commercial use, so it is yours to install rather than ours to depend on.\n → `pnpm add -D @sentry/cli` in the app being built.\n") + r.map((e) => ` · ${e}`).join("\n"));
160
+ }, de = async (e, t, n = {}) => {
137
161
  if (!t.emit) return {
138
162
  uploaded: 0,
139
163
  deleted: 0
140
164
  };
141
- let r = await se(e), i = 0;
165
+ let r = (await Promise.all(e.map((e) => Z(e.dir)))).flat(), i = 0;
142
166
  try {
143
- t.upload !== void 0 && r.length > 0 && (await (n.upload ?? ce(n.appRoot ?? e))(t.upload, r, e), i = r.length, n.log?.info("source maps uploaded to Sentry", {
167
+ t.upload !== void 0 && r.length > 0 && (await (n.upload ?? ce(n.appRoot ?? e[0]?.dir ?? "."))(t.upload, r, e), i = r.length, n.log?.info("source maps uploaded to Sentry", {
144
168
  release: t.upload.release,
145
- files: r.length
169
+ files: r.length,
170
+ dirs: e.length
146
171
  }));
147
172
  } finally {
148
173
  if (!t.keep) {
149
- for (let e of r) await X(e, { force: !0 });
174
+ for (let e of r) await Y(e, { force: !0 });
150
175
  n.log?.info("source maps removed from the build output", { files: r.length });
151
176
  }
152
177
  }
@@ -154,24 +179,27 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
154
179
  uploaded: i,
155
180
  deleted: t.keep ? 0 : r.length
156
181
  };
157
- }, Q = K({ scope: "voltro:build" }), $ = () => ({
182
+ }, fe = (e) => {
183
+ let t = e;
184
+ return t?.web?.sourcemaps === void 0 ? { option: t?.sourcemaps } : { problem: "`web.sourcemaps` moved to the top level of app.config.ts in 0.59.0.\n It now covers every bundle the build emits — the browser bundle AND the SSR, start and serve bundles, which were minified with no map and no way to ask for one.\n → move it out of `web:` (or run `voltro update`, which does it for you)." };
185
+ }, pe = (e) => "problem" in e, $ = W({ scope: "voltro:build" }), me = () => ({
158
186
  name: "voltro:stub-engine-devtools",
159
187
  resolveId: (e) => e === "@tanstack/devtools-event-client" ? "\0voltro-engine-devtools-stub" : void 0,
160
188
  load: (e) => e === "\0voltro-engine-devtools-stub" ? "export class EventClient { constructor() {} on() { return () => {} } emit() {} }\n" : void 0
161
- }), de = (e, t) => ({
189
+ }), he = (e, t) => ({
162
190
  name: "voltro:ssr-optional-peer-external",
163
191
  enforce: "pre",
164
192
  resolveId(n, r) {
165
193
  if (n.startsWith(".") || n.startsWith("/") || n.startsWith("\0") || n.startsWith("node:") || n === "effect" || n.startsWith("@effect/") || n.startsWith("@voltro/")) return null;
166
- for (let t of [r ? B(r) : void 0, e]) if (t !== void 0) try {
167
- return Y(V(t, "_.js")).resolve(n), null;
194
+ for (let t of [r ? R(r) : void 0, e]) if (t !== void 0) try {
195
+ return q(z(t, "_.js")).resolve(n), null;
168
196
  } catch {}
169
197
  return t.add(n), {
170
198
  id: n,
171
199
  external: !0
172
200
  };
173
201
  }
174
- }), fe = (e) => /\[/.test(e), pe = (e, t) => {
202
+ }), ge = (e) => /\[/.test(e), _e = (e, t) => {
175
203
  let n = e.split("/").filter(Boolean), r = [];
176
204
  for (let i of n) if (i.startsWith("[[...") && i.endsWith("]]")) {
177
205
  let e = t[i.slice(5, -2)];
@@ -187,29 +215,29 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
187
215
  r.push(a);
188
216
  } else r.push(i);
189
217
  return r.length === 0 ? "/" : "/" + r.join("/");
190
- }, me = (e, t) => {
191
- if (t === "/" || t === "") return V(e, "index.html");
218
+ }, ve = (e, t) => {
219
+ if (t === "/" || t === "") return z(e, "index.html");
192
220
  let n = t.replace(/^\//, "").split("/");
193
- return V(e, ...n, "index.html");
194
- }, he = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), ge = (e, t) => {
221
+ return z(e, ...n, "index.html");
222
+ }, ye = (e) => e.replace(/<script\b(?=[^>]*\btype="module")(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<script\b(?=[^>]*\bsrc=)(?:(?!<\/script>).)*<\/script>/gi, "").replace(/<link\b[^>]*\brel="modulepreload"[^>]*>/gi, ""), be = (e, t) => {
195
223
  let n = e.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`), r = [
196
224
  t.metaHtml,
197
225
  `<meta name="voltro-interactive" content="${t.interactive}" />`,
198
226
  t.stateScript
199
227
  ].filter((e) => e.length > 0).join("\n ");
200
- return n = T(o(n, r), t.documentAttrs), t.interactive === "none" && (n = he(n)), n;
201
- }, _e = async (e) => {
228
+ return n = T(o(n, r), t.documentAttrs), t.interactive === "none" && (n = ye(n)), n;
229
+ }, xe = async (e) => {
202
230
  let { page: t, chainEntries: n, pageMod: r, helpers: i } = e, a = n.filter((e) => e.hasLayout);
203
- if (a.length === 0) return Q.debug("skip page", {
231
+ if (a.length === 0) return $.debug("skip page", {
204
232
  pattern: t.pattern,
205
233
  reason: "renderMode=spa with no layout — nothing to shell"
206
234
  }), null;
207
- if (fe(t.pattern)) return Q.debug("skip page", {
235
+ if (ge(t.pattern)) return $.debug("skip page", {
208
236
  pattern: t.pattern,
209
237
  reason: "renderMode=spa with a dynamic pattern"
210
238
  }), null;
211
239
  let s = await Promise.all(a.map(e.loadLayout)), c = a.filter((e, t) => typeof s[t]?.loader == "function").map((e) => e.dir || "/");
212
- if (c.length > 0) return Q.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`, {
240
+ if (c.length > 0) return $.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`, {
213
241
  pattern: t.pattern,
214
242
  layouts: c
215
243
  }), null;
@@ -248,56 +276,56 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
248
276
  prepared: p,
249
277
  meta: m.meta,
250
278
  interactive: f
251
- }), g = o(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${m.body}</div>`), h), y = me(e.distDir, t.pattern);
252
- return await W.mkdir(B(y), { recursive: !0 }), await W.writeFile(y, g, "utf8"), Q.debug("prerendered spa layout shell", { pattern: t.pattern }), {
279
+ }), g = o(e.shellTemplate.replace("<div id=\"root\"></div>", `<div id="root">${m.body}</div>`), h), y = ve(e.distDir, t.pattern);
280
+ return await H.mkdir(R(y), { recursive: !0 }), await H.writeFile(y, g, "utf8"), $.debug("prerendered spa layout shell", { pattern: t.pattern }), {
253
281
  pattern: t.pattern,
254
282
  outPath: y
255
283
  };
256
- }, ve = async (e) => {
257
- let { root: t, distDir: r, pages: i, dirs: a, vite: o } = e, c = V(r, "index.html"), d = await W.readFile(c, "utf8"), p = V(r, "_voltro", "shell.html");
258
- await W.mkdir(B(p), { recursive: !0 }), await W.writeFile(p, d, "utf8");
284
+ }, Se = async (e) => {
285
+ let { root: t, distDir: r, pages: i, dirs: a, vite: o } = e, c = z(r, "index.html"), d = await H.readFile(c, "utf8"), p = z(r, "_voltro", "shell.html");
286
+ await H.mkdir(R(p), { recursive: !0 }), await H.writeFile(p, d, "utf8");
259
287
  let m = /* @__PURE__ */ new Map();
260
288
  for (let t of e.islandsPlans ?? []) {
261
- let e = V(r, "island-shells", `${t.name}.html`);
289
+ let e = z(r, "island-shells", `${t.name}.html`);
262
290
  try {
263
- let n = l(await W.readFile(e, "utf8"), d);
264
- await W.writeFile(e, n, "utf8"), m.set(t.pattern, n);
291
+ let n = l(await H.readFile(e, "utf8"), d);
292
+ await H.writeFile(e, n, "utf8"), m.set(t.pattern, n);
265
293
  } catch {
266
- Q.warn("islands shell missing — page ships the full entry", {
294
+ $.warn("islands shell missing — page ships the full entry", {
267
295
  pattern: t.pattern,
268
296
  expected: e
269
297
  });
270
298
  }
271
299
  }
272
- let h = V(t, "node_modules", "@voltro", "ui-shadcn"), g = U(V(h, "package.json")) ? h : null, v = [...g ? [
300
+ let h = z(t, "node_modules", "@voltro", "ui-shadcn"), g = V(z(h, "package.json")) ? h : null, v = [...g ? [
273
301
  {
274
302
  find: "@voltro/ui-shadcn/tokens.css",
275
- replacement: V(g, "src/tokens.css")
303
+ replacement: z(g, "src/tokens.css")
276
304
  },
277
305
  {
278
306
  find: "@voltro/ui-shadcn/cn",
279
- replacement: V(g, "src/cn.ts")
307
+ replacement: z(g, "src/cn.ts")
280
308
  },
281
309
  {
282
310
  find: "@voltro/ui-shadcn/brand",
283
- replacement: V(g, "src/brand/voltroLogo.tsx")
311
+ replacement: z(g, "src/brand/voltroLogo.tsx")
284
312
  },
285
313
  {
286
314
  find: "@voltro/ui-shadcn",
287
- replacement: V(g, "src/index.ts")
315
+ replacement: z(g, "src/index.ts")
288
316
  }
289
- ] : [], ...A(t)], y = await o.createServer({
290
- root: V(t, ".framework"),
317
+ ] : [], ...k(t)], y = await o.createServer({
318
+ root: z(t, ".framework"),
291
319
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
292
320
  plugins: [
293
321
  (await import("@vitejs/plugin-react")).default(),
294
322
  (await import("@tailwindcss/vite")).default(),
295
323
  u({
296
324
  root: t,
297
- config: L(e.images),
325
+ config: I(e.images),
298
326
  urlMode: "build-urls"
299
327
  }),
300
- $()
328
+ me()
301
329
  ],
302
330
  resolve: {
303
331
  alias: v,
@@ -316,11 +344,11 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
316
344
  },
317
345
  appType: "custom",
318
346
  logLevel: "warn"
319
- }), b = await y.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: x, renderMetaToHtml: S, renderRouterStateScript: C, isDeferredLoaderResult: w, assertDeferralSupported: T, beginStoreSeeds: E, seedPreloadedSubscription: ee, seedPreloadedSubscriptionFailure: O } = b, k, j = /* @__PURE__ */ new Map();
347
+ }), b = await y.ssrLoadModule("@voltro/web/ssr"), { renderPageToHtml: x, renderMetaToHtml: S, renderRouterStateScript: C, isDeferredLoaderResult: w, assertDeferralSupported: T, beginStoreSeeds: E, seedPreloadedSubscription: ee, seedPreloadedSubscriptionFailure: te } = b, O, A = /* @__PURE__ */ new Map();
320
348
  if (e.locales && e.locales.length > 0 && e.defaultLocale) try {
321
349
  let n = await y.ssrLoadModule("@voltro/i18n");
322
350
  try {
323
- k = (await y.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
351
+ O = (await y.ssrLoadModule("@voltro/i18n/server")).resolveTimeZone?.({
324
352
  configured: e.timeZone ?? null,
325
353
  defaultTimeZone: e.defaultTimeZone ?? null
326
354
  });
@@ -328,15 +356,15 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
328
356
  let r = n.makeSsgWrap;
329
357
  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.");
330
358
  for (let n of e.locales) try {
331
- let i = await y.ssrLoadModule(V(t, "src", "locales", `${n}.ts`)), a = i.default ?? i;
332
- j.set(n, r(n, a, e.defaultLocale));
359
+ let i = await y.ssrLoadModule(z(t, "src", "locales", `${n}.ts`)), a = i.default ?? i;
360
+ A.set(n, r(n, a, e.defaultLocale));
333
361
  } catch (e) {
334
- Q.warn(`i18n catalog missing for locale '${n}' — pages rendered at /${n}/* will crash. Add src/locales/${n}.ts.`, {}, e);
362
+ $.warn(`i18n catalog missing for locale '${n}' — pages rendered at /${n}/* will crash. Add src/locales/${n}.ts.`, {}, e);
335
363
  }
336
364
  } catch (e) {
337
- Q.warn("i18n wrapper unavailable for SSG — pages that call useT() will fail. Check that @voltro/i18n is installed.", {}, e);
365
+ $.warn("i18n wrapper unavailable for SSG — pages that call useT() will fail. Check that @voltro/i18n is installed.", {}, e);
338
366
  }
339
- let M = [], N = {}, P = (e) => e.dir === "" ? V(t, "src", "pages") : V(t, "src", "pages", e.dir), F = async (e) => await y.ssrLoadModule(V(P(e), "layout.tsx")), z = async (e) => await y.ssrLoadModule(V(P(e), "error.tsx")), H = async (e) => await y.ssrLoadModule(V(P(e), "loading.tsx")), G = (e, t) => ({
367
+ let j = [], M = {}, N = (e) => e.dir === "" ? z(t, "src", "pages") : z(t, "src", "pages", e.dir), P = async (e) => await y.ssrLoadModule(z(N(e), "layout.tsx")), ne = async (e) => await y.ssrLoadModule(z(N(e), "error.tsx")), B = async (e) => await y.ssrLoadModule(z(N(e), "loading.tsx")), U = (e, t) => ({
340
368
  params: e.params,
341
369
  pathname: e.pathname,
342
370
  search: "",
@@ -346,41 +374,41 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
346
374
  isServer: !0
347
375
  });
348
376
  for (let o of i) {
349
- let i = `${V(t, "src", "pages", o.file)}`, c = await y.ssrLoadModule(i), l = I(c, V("src", "pages", o.file));
350
- N[o.pattern] = l;
377
+ let i = `${z(t, "src", "pages", o.file)}`, c = await y.ssrLoadModule(i), l = F(c, z("src", "pages", o.file));
378
+ M[o.pattern] = l;
351
379
  let u = l.renderMode, p = D(a, o.dirChain);
352
380
  if (u === "spa") {
353
- let t = await _e({
381
+ let t = await xe({
354
382
  page: o,
355
383
  chainEntries: p,
356
384
  pageMod: c,
357
385
  shellTemplate: d,
358
386
  distDir: r,
359
387
  helpers: b,
360
- loadLayout: F,
361
- loadError: z,
362
- loadPending: H,
363
- ctx: G({
388
+ loadLayout: P,
389
+ loadError: ne,
390
+ loadPending: B,
391
+ ctx: U({
364
392
  params: {},
365
393
  pathname: o.pattern
366
394
  }, new AbortController().signal),
367
- outerWrap: j.get(e.defaultLocale ?? ""),
395
+ outerWrap: A.get(e.defaultLocale ?? ""),
368
396
  locale: e.defaultLocale
369
397
  });
370
- t && M.push(t);
398
+ t && j.push(t);
371
399
  continue;
372
400
  }
373
401
  if (u !== "static") {
374
- Q.debug("skip page", {
402
+ $.debug("skip page", {
375
403
  pattern: o.pattern,
376
404
  reason: `renderMode=${u}`
377
405
  });
378
406
  continue;
379
407
  }
380
408
  let h;
381
- if (fe(o.pattern)) {
409
+ if (ge(o.pattern)) {
382
410
  if (typeof c.getStaticPaths != "function") {
383
- Q.debug("skip page", {
411
+ $.debug("skip page", {
384
412
  pattern: o.pattern,
385
413
  reason: "no getStaticPaths export"
386
414
  });
@@ -389,19 +417,19 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
389
417
  try {
390
418
  let e = await c.getStaticPaths();
391
419
  if (!Array.isArray(e)) {
392
- Q.warn("skip page — getStaticPaths did not return an array", { pattern: o.pattern });
420
+ $.warn("skip page — getStaticPaths did not return an array", { pattern: o.pattern });
393
421
  continue;
394
422
  }
395
423
  h = e.map((e) => ({
396
424
  params: e.params,
397
- pathname: pe(o.pattern, e.params)
425
+ pathname: _e(o.pattern, e.params)
398
426
  }));
399
427
  } catch (e) {
400
- Q.warn("skip page — getStaticPaths threw", { pattern: o.pattern }, e);
428
+ $.warn("skip page — getStaticPaths threw", { pattern: o.pattern }, e);
401
429
  continue;
402
430
  }
403
431
  if (h.length === 0) {
404
- Q.debug("skip page", {
432
+ $.debug("skip page", {
405
433
  pattern: o.pattern,
406
434
  reason: "getStaticPaths returned []"
407
435
  });
@@ -418,16 +446,16 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
418
446
  try {
419
447
  ({chain: a, segmentLoaderData: l} = await _({
420
448
  entries: p,
421
- loadLayout: F,
422
- loadError: z,
423
- loadPending: H,
424
- ctx: G(i, h.signal)
449
+ loadLayout: P,
450
+ loadError: ne,
451
+ loadPending: B,
452
+ ctx: U(i, h.signal)
425
453
  }));
426
454
  } catch (e) {
427
455
  let t = e?._voltroControl;
428
456
  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'.`);
429
457
  if (e instanceof Error && t === "not-found") {
430
- Q.warn("layout loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
458
+ $.warn("layout loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
431
459
  continue;
432
460
  }
433
461
  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)}`);
@@ -457,7 +485,7 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
457
485
  } catch (e) {
458
486
  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'.`);
459
487
  if (e instanceof Error && e._voltroControl === "not-found") {
460
- Q.warn("loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
488
+ $.warn("loader threw NotFoundError at build time — skipping artifact", { pathname: i.pathname });
461
489
  continue;
462
490
  }
463
491
  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)}`);
@@ -479,20 +507,20 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
479
507
  query: void 0,
480
508
  apiName: void 0,
481
509
  seed: ee,
482
- seedFailure: O
510
+ seedFailure: te
483
511
  });
484
- let b = i.params.locale ?? e.defaultLocale ?? "en", D = j.get(b) ?? j.get(e.defaultLocale ?? ""), A = Date.now(), N = D ? (e) => D(e, {
485
- timeZone: k,
486
- renderedAt: A
487
- }) : void 0, { html: P, meta: I } = x({
512
+ let b = i.params.locale ?? e.defaultLocale ?? "en", D = A.get(b) ?? A.get(e.defaultLocale ?? ""), k = Date.now(), M = D ? (e) => D(e, {
513
+ timeZone: O,
514
+ renderedAt: k
515
+ }) : void 0, { html: N, meta: F } = x({
488
516
  descriptor: v,
489
517
  params: i.params,
490
518
  pathname: i.pathname,
491
519
  loaderData: y,
492
520
  segmentLoaderData: l,
493
- ...N ? { outerWrap: N } : {},
521
+ ...M ? { outerWrap: M } : {},
494
522
  locale: b
495
- }), L = "";
523
+ }), I = "";
496
524
  if (typeof c.ogImage == "function") {
497
525
  let a = await c.ogImage({
498
526
  params: i.params,
@@ -501,16 +529,16 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
501
529
  }), o = await f(t, e.fonts), { png: s } = await n({
502
530
  element: a,
503
531
  fonts: o
504
- }), l = `assets/og/${R(s)}.png`;
505
- await W.mkdir(V(r, "assets", "og"), { recursive: !0 }), await W.writeFile(V(r, l), Buffer.from(s));
532
+ }), l = `assets/og/${L(s)}.png`;
533
+ await H.mkdir(z(r, "assets", "og"), { recursive: !0 }), await H.writeFile(z(r, l), Buffer.from(s));
506
534
  let u = e.siteUrl === void 0 ? `/${l}` : `${e.siteUrl.replace(/\/$/, "")}/${l}`;
507
- L = S(I).includes("og:image") ? "" : `<meta property="og:image" content="${u}" /><meta name="twitter:image" content="${u}" /><meta name="twitter:card" content="summary_large_image" />`;
535
+ I = S(F).includes("og:image") ? "" : `<meta property="og:image" content="${u}" /><meta name="twitter:image" content="${u}" /><meta name="twitter:card" content="summary_large_image" />`;
508
536
  }
509
- let U = g === "islands" ? m.get(o.pattern) : void 0;
510
- g === "islands" && U === void 0 && Q.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: o.pattern });
511
- let K = ge(U ?? d, {
512
- body: P,
513
- metaHtml: S(I) + L,
537
+ let V = g === "islands" ? m.get(o.pattern) : void 0;
538
+ g === "islands" && V === void 0 && $.warn("islands page has no per-page entry (non-literal `interactive`?) — shipping the full app entry", { pattern: o.pattern });
539
+ let W = be(V ?? d, {
540
+ body: N,
541
+ metaHtml: S(F) + I,
514
542
  stateScript: C({
515
543
  path: i.pathname,
516
544
  loaderData: y,
@@ -520,23 +548,23 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
520
548
  interactive: g,
521
549
  documentAttrs: {
522
550
  lang: b,
523
- ...k === void 0 ? {} : { timeZone: k },
524
- renderedAt: A
551
+ ...O === void 0 ? {} : { timeZone: O },
552
+ renderedAt: k
525
553
  }
526
- }), q = me(r, i.pathname);
527
- await W.mkdir(B(q), { recursive: !0 }), await W.writeFile(q, K, "utf8"), M.push({
554
+ }), G = ve(r, i.pathname);
555
+ await H.mkdir(R(G), { recursive: !0 }), await H.writeFile(G, W, "utf8"), j.push({
528
556
  pattern: i.pathname,
529
- outPath: q,
530
- ...I?.noIndex ? { noIndex: !0 } : {}
557
+ outPath: G,
558
+ ...F?.noIndex ? { noIndex: !0 } : {}
531
559
  });
532
560
  }
533
561
  }
534
562
  return await y.close(), {
535
- rendered: M,
536
- pageMeta: N
563
+ rendered: j,
564
+ pageMeta: M
537
565
  };
538
- }, ye = async (e, t, n, r, i, a, o, s) => {
539
- let c = V(e, ".framework"), l = [];
566
+ }, Ce = async (e, t, n, r, i, a, o, s) => {
567
+ let c = z(e, ".framework"), l = [];
540
568
  for (let e of t) l.push(` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`);
541
569
  let u = [], d = [], f = [];
542
570
  for (let e of n) {
@@ -545,7 +573,7 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
545
573
  }
546
574
  let p = [], m = [];
547
575
  if (r && r.length > 0 && i) for (let t of r) {
548
- if (!U(V(e, "src", "locales", `${t}.ts`))) continue;
576
+ if (!V(z(e, "src", "locales", `${t}.ts`))) continue;
549
577
  let n = `__i18nCat_${t.replace(/[^a-zA-Z0-9]/g, "_")}`;
550
578
  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)}),`);
551
579
  }
@@ -622,40 +650,68 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
622
650
  "",
623
651
  S,
624
652
  ""
625
- ].join("\n"), w = V(c, "ssrEntry.ts");
626
- return await W.writeFile(w, C, "utf8"), w;
627
- }, be = async (e) => {
653
+ ].join("\n"), w = z(c, "ssrEntry.ts");
654
+ return await H.writeFile(w, C, "utf8"), w;
655
+ }, we = async (e) => {
628
656
  let { checkRpcGroupFreshness: t } = await import("./codegen-DbH7NbCR.js"), n = await t(e);
629
657
  if (n.kind === "fresh") return;
630
- n.kind === "stale" && Q.info("rpcGroup.generated.ts is stale — regenerating", {
658
+ n.kind === "stale" && $.info("rpcGroup.generated.ts is stale — regenerating", {
631
659
  file: n.file,
632
660
  reason: n.reason
633
661
  });
634
662
  let { regenerateRpcGroup: r } = await import("./codegenCommand-kS3Twuc9.js"), i = await r(e);
635
663
  if (i.kind === "refused") {
636
- Q.warn("could not regenerate the rpc group — building against what is on disk", { reason: i.reason });
664
+ $.warn("could not regenerate the rpc group — building against what is on disk", { reason: i.reason });
637
665
  return;
638
666
  }
639
- i.kind === "wrote" && n.kind === "stale" && Q.info("rpc group regenerated", {
667
+ i.kind === "wrote" && n.kind === "stale" && $.info("rpc group regenerated", {
640
668
  plugins: i.plugins,
641
669
  routes: i.routes
642
670
  });
643
- }, xe = async (e) => {
671
+ }, Te = async (e) => {
644
672
  let n = await S(e, { preferSource: !0 });
645
673
  if (!n) {
646
674
  let { loadApiConfigDiagnosed: t } = await import("./dev-Dff_pdik.js"), n = await t(e), r = n.config;
647
- if (!r && n.present) return Q.error("app.config.ts is present but could not be loaded — this is NOT a statement about the app's type", { path: V(e, "app.config.ts") }, n.error), {
675
+ if (!r && n.present) return $.error("app.config.ts is present but could not be loaded — this is NOT a statement about the app's type", { path: z(e, "app.config.ts") }, n.error), {
648
676
  ran: !0,
649
677
  exitCode: 1
650
678
  };
651
679
  if (r) {
652
- Q.info("building api app", { app: r.name ?? "(unnamed)" }), await be(e);
653
- let { runApiBuild: t, runServeBundleBuild: n } = await import("./apiBuild-CDE4NXNi.js");
654
- await t(e);
680
+ $.info("building api app", { app: r.name ?? "(unnamed)" }), await we(e);
681
+ let t = fe(r);
682
+ if (pe(t)) return $.fatal(t.problem), {
683
+ ran: !0,
684
+ exitCode: 1
685
+ };
686
+ let n = oe(t.option, process.env);
687
+ if (se(n)) return $.fatal(n.problem), {
688
+ ran: !0,
689
+ exitCode: 1
690
+ };
691
+ let { runApiBuild: i, runServeBundleBuild: a } = await import("./apiBuild-B9OvhITV.js");
692
+ await i(e, { sourcemaps: n.emit });
655
693
  try {
656
- await n(e);
694
+ await a(e, { sourcemaps: n.emit });
657
695
  } catch (e) {
658
- return Q.fatal("serve bundle build FAILED — refusing to ship a bundle-less image. Fix the error above (production serves from the bundle, never tsx).", {}, e), {
696
+ return $.fatal("serve bundle build FAILED — refusing to ship a bundle-less image. Fix the error above (production serves from the bundle, never tsx).", {}, e), {
697
+ ran: !0,
698
+ exitCode: 1
699
+ };
700
+ }
701
+ if (n.emit) try {
702
+ let t = await de([{
703
+ dir: z(e, ".framework", "dist-api"),
704
+ urlPrefix: "~/"
705
+ }], n, {
706
+ appRoot: e,
707
+ log: $
708
+ });
709
+ (t.uploaded > 0 || t.deleted > 0) && $.debug("source maps handled", {
710
+ uploaded: t.uploaded,
711
+ deleted: t.deleted
712
+ });
713
+ } catch (e) {
714
+ return $.fatal(`source map upload failed:\n${e instanceof Error ? e.message : String(e)}`), {
659
715
  ran: !0,
660
716
  exitCode: 1
661
717
  };
@@ -670,19 +726,19 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
670
726
  exitCode: 0
671
727
  };
672
728
  }
673
- Q.info("building web app", { app: n.name ?? "(unnamed)" });
729
+ $.info("building web app", { app: n.name ?? "(unnamed)" });
674
730
  let { resolved: o } = await h({
675
731
  rawEnv: n.env,
676
732
  appType: "web",
677
733
  root: e,
678
- log: Q,
734
+ log: $,
679
735
  generateTypes: !0
680
736
  }), s = await b(e, n);
681
737
  await r(e, n, s, o.publicValues);
682
- let { pages: l } = await p(V(e, "src", "pages")), f = [];
738
+ let { pages: l } = await p(z(e, "src", "pages")), f = [];
683
739
  for (let t of l) {
684
- let n = await W.readFile(V(e, "src", "pages", t.file), "utf8").catch(() => ""), r = c(n);
685
- n.includes("<Script") && (r === "none" || r === "islands") && Q.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({
740
+ let n = await H.readFile(z(e, "src", "pages", t.file), "utf8").catch(() => ""), r = c(n);
741
+ n.includes("<Script") && (r === "none" || r === "islands") && $.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({
686
742
  pattern: t.pattern,
687
743
  file: t.file
688
744
  });
@@ -690,61 +746,66 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
690
746
  let _ = w(s, "../../app.config"), v = await x({
691
747
  webRoot: e,
692
748
  pages: f,
693
- headSnippets: t(await W.readFile(V(e, ".framework", "index.html"), "utf8").catch(() => "")),
749
+ headSnippets: t(await H.readFile(z(e, ".framework", "index.html"), "utf8").catch(() => "")),
694
750
  apiImports: _.imports,
695
751
  apiEntriesLiteral: `[\n${_.providerEntryLines.join("\n")}\n ]`
696
752
  });
697
- v.length > 0 && Q.info("per-page islands entries", { pages: v.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
698
- let { pages: C } = await p(V(e, "src", "pages"));
753
+ v.length > 0 && $.info("per-page islands entries", { pages: v.map((e) => `${e.pattern}${e.usesClient ? " (client boot)" : ""}`) });
754
+ let { pages: C } = await p(z(e, "src", "pages"));
699
755
  await ee({
700
756
  appRoot: e,
701
757
  pages: C,
702
758
  mode: "prod"
703
759
  });
704
- let T = V(e, ".framework"), E = V(T, "dist"), D = V(e, "node_modules", "@voltro", "ui-shadcn"), M = U(V(D, "package.json")) ? D : null, P = [...M ? [
760
+ let T = z(e, ".framework"), E = z(T, "dist"), D = z(e, "node_modules", "@voltro", "ui-shadcn"), j = V(z(D, "package.json")) ? D : null, N = [...j ? [
705
761
  {
706
762
  find: "@voltro/ui-shadcn/tokens.css",
707
- replacement: V(M, "src/tokens.css")
763
+ replacement: z(j, "src/tokens.css")
708
764
  },
709
765
  {
710
766
  find: "@voltro/ui-shadcn/cn",
711
- replacement: V(M, "src/cn.ts")
767
+ replacement: z(j, "src/cn.ts")
712
768
  },
713
769
  {
714
770
  find: "@voltro/ui-shadcn/brand",
715
- replacement: V(M, "src/brand/voltroLogo.tsx")
771
+ replacement: z(j, "src/brand/voltroLogo.tsx")
716
772
  },
717
773
  {
718
774
  find: "@voltro/ui-shadcn",
719
- replacement: V(M, "src/index.ts")
775
+ replacement: z(j, "src/index.ts")
720
776
  }
721
- ] : [], ...A(e)];
722
- Q.info("running vite build");
723
- let F = await d("vite", () => import("vite")), I = (await import("@vitejs/plugin-react")).default, R = (await import("@tailwindcss/vite")).default, H = ae(n.web?.sourcemaps, process.env);
724
- if (oe(H)) return Q.fatal(H.problem), {
777
+ ] : [], ...k(e)];
778
+ $.info("running vite build");
779
+ let P = await d("vite", () => import("vite")), F = (await import("@vitejs/plugin-react")).default, L = (await import("@tailwindcss/vite")).default, B = fe(n);
780
+ if (pe(B)) return $.fatal(B.problem), {
781
+ ran: !0,
782
+ exitCode: 1
783
+ };
784
+ let U = oe(B.option, process.env);
785
+ if (se(U)) return $.fatal(U.problem), {
725
786
  ran: !0,
726
787
  exitCode: 1
727
788
  };
728
- let G = n.web?.assetPrefix;
729
- if (G !== void 0 && !/^https?:\/\/|^\//.test(G)) return Q.fatal(`web.assetPrefix must be an absolute URL or a root-relative path — got ${JSON.stringify(G)}. A bare host would be resolved against the page URL and 404 on every route but one.`), {
789
+ let W = n.web?.assetPrefix;
790
+ if (W !== void 0 && !/^https?:\/\/|^\//.test(W)) return $.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.`), {
730
791
  ran: !0,
731
792
  exitCode: 1
732
793
  };
733
- if (await F.build({
794
+ await P.build({
734
795
  root: T,
735
- ...G === void 0 ? {} : { base: G.endsWith("/") ? G : `${G}/` },
796
+ ...W === void 0 ? {} : { base: W.endsWith("/") ? W : `${W}/` },
736
797
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
737
798
  plugins: [
738
- I(),
739
- R(),
799
+ F(),
800
+ L(),
740
801
  u({
741
802
  root: e,
742
- config: L(n.images)
803
+ config: I(n.images)
743
804
  }),
744
- $()
805
+ me()
745
806
  ],
746
807
  resolve: {
747
- alias: P,
808
+ alias: N,
748
809
  dedupe: [
749
810
  "react",
750
811
  "react-dom",
@@ -752,63 +813,76 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
752
813
  "@voltro/i18n"
753
814
  ]
754
815
  },
755
- publicDir: V(e, "public"),
816
+ publicDir: z(e, "public"),
756
817
  build: {
757
818
  outDir: "dist",
758
819
  emptyOutDir: !0,
759
- ...H.emit ? { sourcemap: "hidden" } : {},
820
+ ...U.emit ? { sourcemap: "hidden" } : {},
760
821
  rollupOptions: {
761
822
  input: {
762
- index: V(T, "index.html"),
763
- ...Object.fromEntries(v.map((e) => [`island_${e.name}`, V(T, e.htmlFile)]))
823
+ index: z(T, "index.html"),
824
+ ...Object.fromEntries(v.map((e) => [`island_${e.name}`, z(T, e.htmlFile)]))
764
825
  },
765
- output: { manualChunks: O }
826
+ output: { manualChunks: te }
766
827
  }
767
828
  },
768
829
  logLevel: "warn"
769
- }), H.emit) {
770
- let t = V(T, "dist");
830
+ });
831
+ let G = async (t) => {
832
+ if (!U.emit) return null;
833
+ let n = z(T, "dist"), r = [{
834
+ dir: z(n, "assets"),
835
+ urlPrefix: ae
836
+ }, ...t.serverBundles ? [{
837
+ dir: z(n, "server"),
838
+ urlPrefix: "~/"
839
+ }, {
840
+ dir: z(T, "dist-web", "startBundle"),
841
+ urlPrefix: "~/"
842
+ }] : []], i = t.upload ? U : {
843
+ emit: U.emit,
844
+ keep: U.keep
845
+ };
771
846
  try {
772
- let n = await ue(t, H, {
847
+ let t = await de(r, i, {
773
848
  appRoot: e,
774
- log: Q
775
- });
776
- (n.uploaded > 0 || n.deleted > 0) && Q.debug("source maps handled", {
777
- uploaded: n.uploaded,
778
- deleted: n.deleted
849
+ log: $
779
850
  });
851
+ return (t.uploaded > 0 || t.deleted > 0) && $.debug("source maps handled", {
852
+ uploaded: t.uploaded,
853
+ deleted: t.deleted
854
+ }), null;
780
855
  } catch (e) {
781
- return Q.fatal(`source map upload failed:\n${e instanceof Error ? e.message : String(e)}`), {
782
- ran: !0,
783
- exitCode: 1
784
- };
856
+ return $.fatal(`source map upload failed:\n${e instanceof Error ? e.message : String(e)}`), 1;
785
857
  }
786
- }
787
- let K = V(e, "src", "pages"), { pages: q, dirs: J } = await p(K);
788
- if (q.length === 0) return Q.info("no pages found — client-only bundle written", {
858
+ }, K = z(e, "src", "pages"), { pages: q, dirs: J } = await p(K);
859
+ if (q.length === 0) return $.info("no pages found client-only bundle written", {
789
860
  pagesDir: K,
790
861
  distDir: E
791
862
  }), {
792
863
  ran: !0,
793
- exitCode: 0
864
+ exitCode: await G({
865
+ serverBundles: !1,
866
+ upload: !0
867
+ }) ?? 0
794
868
  };
795
869
  {
796
870
  let t = await i(e, n.fonts);
797
871
  if (t !== null) {
798
872
  for (let e of t.files) {
799
- let t = V(E, e.fileName);
800
- await W.mkdir(B(t), { recursive: !0 }), await W.writeFile(t, Buffer.from(e.bytes));
873
+ let t = z(E, e.fileName);
874
+ await H.mkdir(R(t), { recursive: !0 }), await H.writeFile(t, Buffer.from(e.bytes));
801
875
  }
802
- Q.info(`fonts: ${t.files.length} hashed file(s) into dist/assets/fonts`);
876
+ $.info(`fonts: ${t.files.length} hashed file(s) into dist/assets/fonts`);
803
877
  }
804
878
  }
805
879
  a(e);
806
- let { rendered: Y, pageMeta: te } = await ve({
880
+ let { rendered: Y, pageMeta: re } = await Se({
807
881
  root: e,
808
882
  distDir: E,
809
883
  pages: q,
810
884
  dirs: J,
811
- vite: F,
885
+ vite: P,
812
886
  islandsPlans: v,
813
887
  ...n.locales ? { locales: n.locales } : {},
814
888
  ...n.defaultLocale ? { defaultLocale: n.defaultLocale } : {},
@@ -818,30 +892,30 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
818
892
  ...n.fonts === void 0 ? {} : { fonts: n.fonts },
819
893
  ...n.seo?.siteUrl === void 0 ? {} : { siteUrl: n.seo.siteUrl }
820
894
  });
821
- await k(E), await m(E, n.feeds ?? [], n.seo?.siteUrl), Q.info("generating .framework/ssrEntry.ts"), await ye(e, q, J, n.locales, n.defaultLocale, te, {
895
+ await O(E), await m(E, n.feeds ?? [], n.seo?.siteUrl), $.info("generating .framework/ssrEntry.ts"), await Ce(e, q, J, n.locales, n.defaultLocale, re, {
822
896
  ...n.timeZone ? { timeZone: n.timeZone } : {},
823
897
  ...n.defaultTimeZone ? { defaultTimeZone: n.defaultTimeZone } : {}
824
898
  }, s.map((e) => ({
825
899
  name: e.name,
826
900
  pkg: e.pkg
827
- }))), Q.info("vite build --ssr → dist/server/");
901
+ }))), $.info("vite build --ssr → dist/server/");
828
902
  let X = /* @__PURE__ */ new Set();
829
903
  try {
830
- await F.build({
904
+ await P.build({
831
905
  root: T,
832
906
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
833
907
  plugins: [
834
- I(),
835
- R(),
908
+ F(),
909
+ L(),
836
910
  u({
837
911
  root: e,
838
- config: L(n.images)
912
+ config: I(n.images)
839
913
  }),
840
- de(e, X),
841
- $()
914
+ he(e, X),
915
+ me()
842
916
  ],
843
917
  resolve: {
844
- alias: P,
918
+ alias: N,
845
919
  dedupe: [
846
920
  "react",
847
921
  "react-dom",
@@ -855,58 +929,73 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
855
929
  outDir: "dist/server",
856
930
  ssr: "ssrEntry.ts",
857
931
  minify: "esbuild",
932
+ sourcemap: U.emit ? "hidden" : !1,
858
933
  emptyOutDir: !0,
859
934
  rollupOptions: { output: { format: "esm" } }
860
935
  },
861
936
  logLevel: "warn"
862
- }), Q.info("SSR bundle ready", {
937
+ }), $.info("SSR bundle ready", {
863
938
  path: "dist/server/ssrEntry.js",
864
939
  ...X.size > 0 ? { externalizedOptionalPeers: [...X].join(", ") } : {}
865
940
  });
866
941
  } catch (e) {
867
- return Q.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), {
942
+ return $.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), await G({
943
+ serverBundles: !0,
944
+ upload: !1
945
+ }), {
868
946
  ran: !0,
869
947
  exitCode: 1
870
948
  };
871
949
  }
872
- let Z = V(e, "app.config.ts");
873
- if (U(Z)) {
874
- Q.info("precompiling app.config.ts → dist/server/appConfig.js");
950
+ let Z = z(e, "app.config.ts");
951
+ if (V(Z)) {
952
+ $.info("precompiling app.config.ts → dist/server/appConfig.js");
875
953
  try {
876
954
  await (await d("esbuild", () => import("esbuild"))).build({
877
955
  entryPoints: [Z],
878
- outfile: V(E, "server", "appConfig.js"),
956
+ outfile: z(E, "server", "appConfig.js"),
879
957
  bundle: !0,
880
958
  format: "esm",
881
959
  platform: "node",
882
960
  target: "node22",
883
- plugins: [N([], e, /* @__PURE__ */ new Set())],
884
- banner: { js: j() },
961
+ plugins: [M([], e, /* @__PURE__ */ new Set())],
962
+ banner: { js: A() },
885
963
  jsx: "automatic",
886
964
  jsxImportSource: "react",
887
965
  absWorkingDir: e,
888
966
  logLevel: "silent",
889
- ...U(V(e, "tsconfig.json")) ? { tsconfig: V(e, "tsconfig.json") } : {}
967
+ ...V(z(e, "tsconfig.json")) ? { tsconfig: z(e, "tsconfig.json") } : {}
890
968
  });
891
969
  } catch (e) {
892
- return Q.fatal("app.config precompile FAILED — production `voltro start` would need the tsx loader to read it.", {}, e), {
970
+ return $.fatal("app.config precompile FAILED — production `voltro start` would need the tsx loader to read it.", {}, e), await G({
971
+ serverBundles: !0,
972
+ upload: !1
973
+ }), {
893
974
  ran: !0,
894
975
  exitCode: 1
895
976
  };
896
977
  }
897
978
  }
898
979
  try {
899
- await re(e);
980
+ await ie(e, { sourcemaps: U.emit });
900
981
  } catch (e) {
901
- Q.warn("start bundle build failed — `voltro start` will use the slower per-module boot", {}, e);
982
+ $.warn("start bundle build failed — `voltro start` will use the slower per-module boot", {}, e);
902
983
  }
903
- Q.info(`pre-rendered ${Y.length} static route(s)`, {
984
+ let Q = await G({
985
+ serverBundles: !0,
986
+ upload: !0
987
+ });
988
+ if (Q !== null) return {
989
+ ran: !0,
990
+ exitCode: Q
991
+ };
992
+ $.info(`pre-rendered ${Y.length} static route(s)`, {
904
993
  count: Y.length,
905
994
  routes: Y.map((e) => e.pattern)
906
995
  });
907
996
  try {
908
997
  let e = process.env.VOLTRO_SEO_NOINDEX !== "1", t = n.seo?.siteUrl, r = n.locales ?? [], i = n.defaultLocale ?? r[0];
909
- if (t && !U(V(E, "sitemap.xml"))) {
998
+ if (t && !V(z(E, "sitemap.xml"))) {
910
999
  let n = new Set(r.filter((e) => e !== i)), a = Y.filter((e) => !e.noIndex).map((e) => e.pattern).filter((e) => {
911
1000
  let t = e.split("/").filter(Boolean)[0];
912
1001
  return t === void 0 || !n.has(t);
@@ -916,22 +1005,22 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
916
1005
  ...r.length > 1 ? { locales: r } : {},
917
1006
  ...i ? { defaultLocale: i } : {}
918
1007
  });
919
- await W.writeFile(V(E, "sitemap.xml"), o, "utf8"), Q.info("wrote dist/sitemap.xml", {
1008
+ await H.writeFile(z(E, "sitemap.xml"), o, "utf8"), $.info("wrote dist/sitemap.xml", {
920
1009
  urls: a.length,
921
1010
  indexable: e
922
1011
  });
923
1012
  }
924
- if (!U(V(E, "robots.txt"))) {
1013
+ if (!V(z(E, "robots.txt"))) {
925
1014
  let r = y({
926
1015
  indexable: e,
927
1016
  ...e && t ? { sitemapUrl: `${t.replace(/\/$/, "")}/sitemap.xml` } : {},
928
1017
  ...n.seo?.disallow ? { disallow: n.seo.disallow } : {}
929
1018
  });
930
- await W.writeFile(V(E, "robots.txt"), r, "utf8"), Q.info("wrote dist/robots.txt", { indexable: e });
1019
+ await H.writeFile(z(E, "robots.txt"), r, "utf8"), $.info("wrote dist/robots.txt", { indexable: e });
931
1020
  }
932
1021
  {
933
1022
  let { precompressAssets: e } = await import("./precompressAssets-YhTi1aWp.js"), t = await e(E);
934
- t.files > 0 && Q.info("pre-compressed assets", {
1023
+ t.files > 0 && $.info("pre-compressed assets", {
935
1024
  files: t.files,
936
1025
  raw: t.originalBytes,
937
1026
  br: t.brotliBytes,
@@ -939,43 +1028,43 @@ var ne = K({ scope: "voltro:build" }), re = async (e) => {
939
1028
  });
940
1029
  }
941
1030
  } catch (e) {
942
- Q.warn("SEO artefact generation failed (non-fatal)", {}, e);
1031
+ $.warn("SEO artefact generation failed (non-fatal)", {}, e);
943
1032
  }
944
1033
  try {
945
- let t = await z(e);
946
- await W.writeFile(V(E, ".voltro-build.json"), JSON.stringify({
1034
+ let t = await ne(e);
1035
+ await H.writeFile(z(E, ".voltro-build.json"), JSON.stringify({
947
1036
  version: 1,
948
1037
  profile: t
949
- }, null, 2), "utf8"), Q.info("wrote deploy profile manifest", {
1038
+ }, null, 2), "utf8"), $.info("wrote deploy profile manifest", {
950
1039
  staticSafe: t.staticSafe,
951
1040
  ssr: t.counts.ssr,
952
1041
  isr: t.counts.isr
953
1042
  });
954
1043
  } catch (e) {
955
- Q.warn("could not write .voltro-build.json deploy manifest", {}, e);
1044
+ $.warn("could not write .voltro-build.json deploy manifest", {}, e);
956
1045
  }
957
- return Q.info("build complete", { distDir: E }), {
1046
+ return $.info("build complete", { distDir: E }), {
958
1047
  ran: !0,
959
1048
  exitCode: 0
960
1049
  };
961
- }, Se = (e) => J.gen(function* () {
962
- let t = yield* J.tryPromise({
963
- try: () => xe(H(e)),
1050
+ }, Ee = (e) => K.gen(function* () {
1051
+ let t = yield* K.tryPromise({
1052
+ try: () => Te(B(e)),
964
1053
  catch: (e) => e
965
- }).pipe(J.orDie);
966
- return t.ran ? t.exitCode : (yield* J.logError("no voltro app found at this path", { hint: "looked for an app.config.ts with `type: 'web'` or `type: 'api'` — a web app gets the vite build + prerender + start bundle, an api gets the precompiled serve bundle" }), 1);
967
- }), Ce = async (t) => {
968
- if (q("build"), t.includes("--target")) {
969
- let { runSdkBuildCommand: e } = await import("./sdkgen-CAhmmbjx.js");
1054
+ }).pipe(K.orDie);
1055
+ return t.ran ? t.exitCode : (yield* K.logError("no voltro app found at this path", { hint: "looked for an app.config.ts with `type: 'web'` or `type: 'api'` — a web app gets the vite build + prerender + start bundle, an api gets the precompiled serve bundle" }), 1);
1056
+ }), De = async (t) => {
1057
+ if (G("build"), t.includes("--target")) {
1058
+ let { runSdkBuildCommand: e } = await import("./sdkgen-vq1fF9D_.js");
970
1059
  return e(t);
971
1060
  }
972
- let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await F(Se(n), { scope: "voltro:build" });
1061
+ let n = t.find((e) => !e.startsWith("-")) ?? process.cwd(), r = await P(Ee(n), { scope: "voltro:build" });
973
1062
  if (r === 0 && t.includes("--report")) {
974
1063
  let { collectBuildReport: e, formatBuildReport: t } = await import("./buildReport-52gHKgfO.js");
975
1064
  for (let r of t(e(n))) console.log(r);
976
1065
  }
977
1066
  let i = e(n);
978
- return i.warning !== void 0 && Q.warn(i.warning), r;
1067
+ return i.warning !== void 0 && $.warn(i.warning), r;
979
1068
  };
980
1069
  //#endregion
981
- export { Ce as runBuildCommand };
1070
+ export { De as runBuildCommand };