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