@voltro/cli 0.57.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 +256 -0
- package/dist/apiBuild-B9OvhITV.js +2 -0
- package/dist/{apiBuild-DDr2aNFd.js → apiBuild-BU5cd-Fn.js} +52 -50
- package/dist/bin.js +1 -1
- package/dist/build-uRMZrT8z.js +1066 -0
- package/dist/{checkCommand-BISqx1OJ.js → checkCommand-C1CQc8lD.js} +1 -1
- package/dist/{checkCommand-DUtMWjcR.js → checkCommand-DC7k1_hP.js} +3 -3
- package/dist/{codegenCommand-DnVuDxwT.js → codegenCommand-kS3Twuc9.js} +7 -7
- package/dist/{codemodRunner-BlQPfjzA.js → codemodRunner-kNnh1I7_.js} +1227 -911
- package/dist/{commands-CRbxgxv0.js → commands-cu34ENUT.js} +21 -21
- package/dist/{dashboardCommand-Bf_-Ne3P.js → dashboardCommand-gG1y4PFG.js} +5 -5
- package/dist/{dataCommand-BoBJJ-Gb.js → dataCommand-hNOGKz4K.js} +6 -6
- package/dist/{dev-DOEJXicj.js → dev-Ce2gEziv.js} +2422 -2419
- package/dist/dev-Dff_pdik.js +3 -0
- package/dist/{doctorCommand-BrWu67JZ.js → doctorCommand-CGjefPmk.js} +505 -284
- package/dist/doctorCommand-DXnNpKQT.js +2 -0
- package/dist/{dormancyCommand-xn2y-pJm.js → dormancyCommand-DYgI0Kf-.js} +3 -3
- package/dist/{embeddingsCommand-Cn5MbRDM.js → embeddingsCommand-yJivQSrI.js} +2 -2
- package/dist/{envCommand-UJmJIbs9.js → envCommand-ORJUf8r_.js} +8 -8
- package/dist/{evolveCommand-Db30twUy.js → evolveCommand-8CuFBlbQ.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-BjVXpMlP.js → infoCommand-D02A4WI2.js} +1 -1
- package/dist/inspect-CZvsmp8t.js +2 -0
- package/dist/{inspect-DZnan87F.js → inspect-PcC5J-Dl.js} +6 -7
- package/dist/manifestBuild-AUh31bFU.js +2 -0
- package/dist/{manifestBuild-DnbFKF6w.js → manifestBuild-BwiS4iYm.js} +1 -1
- package/dist/{probeCommand-C5fuN6Z2.js → probeCommand-BUYzc0CT.js} +1 -1
- package/dist/{runtimeTrace-BQL_lfz6.js → runtimeTrace-DDuKJgVi.js} +1 -1
- package/dist/{sdkgen-CMUPrDjH.js → sdkgen-vq1fF9D_.js} +1 -1
- package/dist/serveCommand-1R52mo6F.js +2 -0
- package/dist/{serveCommand-B_w-Mpb_.js → serveCommand-Dr4KXmTS.js} +726 -725
- package/dist/serveEntry.js +1 -1
- package/dist/{start-s25GAIgn.js → start-C75w6ftA.js} +1 -1
- package/dist/{start-YaUehtDV.js → start-DNtIlBcn.js} +641 -609
- package/dist/startEntry.js +1 -1
- package/dist/{updateCommand-C9n_Z_oG.js → updateCommand-Bw3mCUDT.js} +1 -1
- package/dist/updateCommand-inInBIAh.js +2 -0
- package/dist/webDev-Bzb8ZFus.js +2 -0
- package/dist/{webDev-BgdkyjP6.js → webDev-CBN9KkyQ.js} +154 -146
- package/dist/{webhooksCommand-CYXTNvXq.js → webhooksCommand-BPJQOGTe.js} +1 -1
- package/package.json +73 -19
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/_manifest.json +1 -1
- package/templates/agent-docs/ai.md +223 -0
- package/templates/agent-docs/authentication.md +34 -0
- package/templates/agent-docs/cli.md +7 -6
- package/templates/agent-docs/data.md +30 -0
- package/templates/agent-docs/database/transactions.md +48 -0
- package/templates/agent-docs/observability.md +13 -2
- package/templates/agent-docs/plugins/auth-supabase.md +21 -0
- package/templates/agent-docs/plugins/sentry.md +131 -9
- package/templates/agent-docs/schema-driven-ui.md +29 -0
- package/templates/agent-docs/whats-new.md +26 -165
- 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-B83Cb2Rv.js +0 -2
- package/dist/build-QKP6Bm0J.js +0 -872
- package/dist/dev-Bl9HqtV7.js +0 -3
- package/dist/doctorCommand-DrQv9SL3.js +0 -2
- package/dist/inspect-B0hL41s0.js +0 -2
- package/dist/manifestBuild-UXrnUcXP.js +0 -2
- package/dist/serveCommand-Dtb48ffg.js +0 -2
- package/dist/updateCommand-DsXEAHbd.js +0 -2
- package/dist/webDev-B6ZMX42w.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as e } from "./loadEnv-D9nEOClM.js";
|
|
2
2
|
import { t } from "./bootRefusal-pgvDxlrU.js";
|
|
3
|
-
import { A as n, I as r, M as i, O as a, g as o, j as s, o as c } from "./inspect-
|
|
3
|
+
import { A as n, I as r, M as i, O as a, g as o, j as s, o as c } from "./inspect-PcC5J-Dl.js";
|
|
4
4
|
import { r as l } from "./appPort-B_HpJ_ck.js";
|
|
5
5
|
import { M as u, _ as d, c as f, g as p, v as m, y as h } from "./fileConventions-l-RIXbx8.js";
|
|
6
6
|
import { n as g, t as _ } from "./workspaceDeps-RKEkX92S.js";
|
|
@@ -86,15 +86,15 @@ ${n.length > 0 ? n : " // (no public variables declared)"}
|
|
|
86
86
|
`, i = P(e, "src");
|
|
87
87
|
await Fe(i, { recursive: !0 }), await q(P(i, "voltro-env.d.ts"), r, "utf8");
|
|
88
88
|
}, ht = async (e, t) => {
|
|
89
|
-
let n = `${ut}
|
|
89
|
+
let n = JSON.stringify(t, null, 2), r = `${ut}
|
|
90
90
|
import { __installPublicEnv } from '@voltro/env/public'
|
|
91
91
|
|
|
92
|
-
export const publicEnvValues = ${
|
|
92
|
+
export const publicEnvValues = ${n} as const
|
|
93
93
|
|
|
94
94
|
// Set the browser/SSR-shared global the \`publicEnv\` accessor reads.
|
|
95
95
|
__installPublicEnv(publicEnvValues)
|
|
96
96
|
`;
|
|
97
|
-
await Fe(e, { recursive: !0 }), await q(P(e, "env.public.ts"),
|
|
97
|
+
await Fe(e, { recursive: !0 }), await q(P(e, "env.public.ts"), r, "utf8"), await q(P(e, "env.public.json"), `${n}\n`, "utf8");
|
|
98
98
|
}, gt = (e, t) => {
|
|
99
99
|
let n = new Set(Object.keys(Ae(e) ? e.vars : {})), r = /* @__PURE__ */ new Map();
|
|
100
100
|
for (let [e, i] of (t ?? []).entries()) {
|
|
@@ -1298,7 +1298,7 @@ __installPublicEnv(publicEnvValues)
|
|
|
1298
1298
|
if (!L(a)) continue;
|
|
1299
1299
|
let s;
|
|
1300
1300
|
try {
|
|
1301
|
-
let { pages: e } = await
|
|
1301
|
+
let { pages: e } = await Wo(a);
|
|
1302
1302
|
s = e.map((e) => ({
|
|
1303
1303
|
pattern: e.pattern,
|
|
1304
1304
|
params: br(e.pattern)
|
|
@@ -2546,12 +2546,20 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2546
2546
|
} catch {}
|
|
2547
2547
|
}
|
|
2548
2548
|
return [...t].map((e) => ` <link rel="preconnect" href="${e}" crossorigin />`);
|
|
2549
|
-
}, Ao = (e) => e.web?.api?.connect === "lazy" ? [" connect: 'lazy',"] : [], jo = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Mo = (e
|
|
2550
|
-
|
|
2551
|
-
"
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2549
|
+
}, Ao = (e) => e.web?.api?.connect === "lazy" ? [" connect: 'lazy',"] : [], jo = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Mo = (e, t) => {
|
|
2550
|
+
if (!No(e, t)) return [];
|
|
2551
|
+
let n = ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"], r = typeof e.sentry == "object" ? e.sentry.optionsFrom : void 0;
|
|
2552
|
+
return r !== void 0 && n.push(`import __sentryOptions from '../${r.replace(/^\.?\//, "")}'`), n;
|
|
2553
|
+
}, No = (e, t) => e.sentry !== void 0 || t, Po = (e, t) => {
|
|
2554
|
+
if (!No(e, t)) return [];
|
|
2555
|
+
let { optionsFrom: n, ...r } = e.sentry ?? {};
|
|
2556
|
+
return [
|
|
2557
|
+
"",
|
|
2558
|
+
"// Browser-side Sentry (frontend half of the deep integration). Errors +",
|
|
2559
|
+
"// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
|
|
2560
|
+
n === void 0 ? `await initSentryBrowser(${JSON.stringify(r)})` : `await initSentryBrowser({ ...${JSON.stringify(r)}, ...(await __sentryOptions()) })`
|
|
2561
|
+
];
|
|
2562
|
+
}, Fo = (e) => e.env ? ["import './env.public'"] : [], Io = (e) => {
|
|
2555
2563
|
let t = [], n = I(e);
|
|
2556
2564
|
for (;;) {
|
|
2557
2565
|
L(P(n, "pnpm-workspace.yaml")) && t.push(n);
|
|
@@ -2560,12 +2568,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2560
2568
|
n = e;
|
|
2561
2569
|
}
|
|
2562
2570
|
return t;
|
|
2563
|
-
},
|
|
2571
|
+
}, Lo = re, Ro = (e) => {
|
|
2564
2572
|
if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
|
|
2565
|
-
},
|
|
2566
|
-
let t = e.replace(p, "").split("/").filter(Boolean).filter((e) => !
|
|
2573
|
+
}, zo = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Bo = (e) => e.startsWith("(") && e.endsWith(")"), Vo = (e) => e.filter((e) => !Bo(e)), Ho = (e) => {
|
|
2574
|
+
let t = e.replace(p, "").split("/").filter(Boolean).filter((e) => !Bo(e));
|
|
2567
2575
|
return t.length === 0 ? "/" : "/" + t.join("/");
|
|
2568
|
-
},
|
|
2576
|
+
}, Uo = (e) => `${e.replace(p, "").split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Index"}Page`, $ = (e, t) => e === "" ? `Root${t}` : `${e.split("/").filter(Boolean).map((e) => e.replace(/[()]/g, "").replace(/\[\.\.\./g, "_rest_").replace(/[[\]]/g, "_")).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_") || "Root"}${t}`, Wo = async (e) => {
|
|
2569
2577
|
let t = [], n = [], r = async (e, i) => {
|
|
2570
2578
|
let a = [];
|
|
2571
2579
|
try {
|
|
@@ -2573,17 +2581,17 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2573
2581
|
} catch {
|
|
2574
2582
|
return;
|
|
2575
2583
|
}
|
|
2576
|
-
let o = a.filter((e) => e.isDirectory()).map((e) => e.name).sort(), s = a.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !
|
|
2584
|
+
let o = a.filter((e) => e.isDirectory()).map((e) => e.name).sort(), s = a.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Lo(e.name)).map((e) => e.name).sort(), c = new Set(s), l = i.join("/");
|
|
2577
2585
|
if (s.some((e) => d.has(e))) {
|
|
2578
2586
|
let t = c.has("layout.tsx"), r = !1;
|
|
2579
2587
|
if (t) try {
|
|
2580
2588
|
let t = await z.readFile(P(e, "layout.tsx"), "utf8");
|
|
2581
|
-
r =
|
|
2589
|
+
r = zo.test(t);
|
|
2582
2590
|
} catch {}
|
|
2583
2591
|
n.push({
|
|
2584
2592
|
dir: l,
|
|
2585
2593
|
chain: i,
|
|
2586
|
-
contributesToUrl: i.length === 0 || !
|
|
2594
|
+
contributesToUrl: i.length === 0 || !Bo(i[i.length - 1]),
|
|
2587
2595
|
hasLayout: t,
|
|
2588
2596
|
hasLayoutLoader: r,
|
|
2589
2597
|
hasError: c.has("error.tsx"),
|
|
@@ -2597,8 +2605,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2597
2605
|
let n = l ? `${l}/${e}` : e;
|
|
2598
2606
|
t.push({
|
|
2599
2607
|
file: n,
|
|
2600
|
-
pattern:
|
|
2601
|
-
ident:
|
|
2608
|
+
pattern: Ho(n),
|
|
2609
|
+
ident: Uo(n),
|
|
2602
2610
|
dirChain: i
|
|
2603
2611
|
});
|
|
2604
2612
|
}
|
|
@@ -2617,14 +2625,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2617
2625
|
dirs: a,
|
|
2618
2626
|
orphanedSpecials: o
|
|
2619
2627
|
};
|
|
2620
|
-
},
|
|
2628
|
+
}, Go = (e, t) => {
|
|
2621
2629
|
let n = [];
|
|
2622
2630
|
for (let r = 0; r <= t.length; r++) {
|
|
2623
2631
|
let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
|
|
2624
2632
|
a && n.push(a);
|
|
2625
2633
|
}
|
|
2626
2634
|
return n;
|
|
2627
|
-
},
|
|
2635
|
+
}, Ko = async (e) => {
|
|
2628
2636
|
let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
|
|
2629
2637
|
return {
|
|
2630
2638
|
chain: await Promise.all(t.map(async (e, t) => {
|
|
@@ -2648,10 +2656,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2648
2656
|
})),
|
|
2649
2657
|
segmentLoaderData: o
|
|
2650
2658
|
};
|
|
2651
|
-
},
|
|
2652
|
-
let t =
|
|
2659
|
+
}, qo = (e) => {
|
|
2660
|
+
let t = Vo(e);
|
|
2653
2661
|
return t.length === 0 ? "" : "/" + t.join("/");
|
|
2654
|
-
},
|
|
2662
|
+
}, Jo = [
|
|
2655
2663
|
"// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
|
|
2656
2664
|
"// in sync with Vite's CSS HMR. Without this, edits to .css files",
|
|
2657
2665
|
"// only update the JS-injected <style> overlay; the underlying <link>",
|
|
@@ -2744,7 +2752,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2744
2752
|
" _vdtErrorStart('Build error')",
|
|
2745
2753
|
" })",
|
|
2746
2754
|
"}"
|
|
2747
|
-
].join("\n"),
|
|
2755
|
+
].join("\n"), Yo = (e) => {
|
|
2748
2756
|
let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
|
|
2749
2757
|
for (let e of r) e.startsWith("[[...") && e.endsWith("]]") ? (i.push("(.*)"), t.push(e.slice(5, -2)), n += 2) : e.startsWith("[...") && e.endsWith("]") ? (i.push("(.+)"), t.push(e.slice(4, -1)), n += 3) : e.startsWith("[") && e.endsWith("]") ? (i.push("([^/]+)"), t.push(e.slice(1, -1)), n += 1) : i.push(e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
2750
2758
|
let a = i.join("/");
|
|
@@ -2753,8 +2761,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2753
2761
|
paramNames: t,
|
|
2754
2762
|
priority: n
|
|
2755
2763
|
};
|
|
2756
|
-
},
|
|
2757
|
-
let { regex: t, paramNames: n, priority: r } =
|
|
2764
|
+
}, Xo = (e) => e.map((e) => {
|
|
2765
|
+
let { regex: t, paramNames: n, priority: r } = Yo(e.pattern);
|
|
2758
2766
|
return {
|
|
2759
2767
|
pattern: e.pattern,
|
|
2760
2768
|
file: e.file,
|
|
@@ -2763,7 +2771,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2763
2771
|
paramNames: n,
|
|
2764
2772
|
priority: r
|
|
2765
2773
|
};
|
|
2766
|
-
}).slice().sort((e, t) => e.priority - t.priority),
|
|
2774
|
+
}).slice().sort((e, t) => e.priority - t.priority), Zo = (e, t) => {
|
|
2767
2775
|
for (let n of t) {
|
|
2768
2776
|
let t = n.regex.exec(e);
|
|
2769
2777
|
if (!t) continue;
|
|
@@ -2775,7 +2783,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2775
2783
|
};
|
|
2776
2784
|
}
|
|
2777
2785
|
return null;
|
|
2778
|
-
},
|
|
2786
|
+
}, Qo = _, $o = async (e) => {
|
|
2779
2787
|
try {
|
|
2780
2788
|
let t = await import(G(P(e, "app.config.ts")).href), n = t.default?.port, r = l({
|
|
2781
2789
|
kind: "api",
|
|
@@ -2791,7 +2799,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2791
2799
|
kind: "api",
|
|
2792
2800
|
env: {}
|
|
2793
2801
|
}).port };
|
|
2794
|
-
},
|
|
2802
|
+
}, es = (e, t) => ({
|
|
2795
2803
|
name: e,
|
|
2796
2804
|
pkg: t.package,
|
|
2797
2805
|
browserWsUrl: t.url,
|
|
@@ -2799,7 +2807,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2799
2807
|
...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
|
|
2800
2808
|
...t.headers ? { headers: t.headers } : {},
|
|
2801
2809
|
...t.authHeaders ? { hasAuthHeaders: !0 } : {}
|
|
2802
|
-
}),
|
|
2810
|
+
}), ts = (e, t, n) => {
|
|
2803
2811
|
let r = t.transport?.wsPath ?? n.wsPath;
|
|
2804
2812
|
return {
|
|
2805
2813
|
name: e,
|
|
@@ -2811,7 +2819,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2811
2819
|
...t.headers ? { headers: t.headers } : {},
|
|
2812
2820
|
...t.authHeaders ? { hasAuthHeaders: !0 } : {}
|
|
2813
2821
|
};
|
|
2814
|
-
},
|
|
2822
|
+
}, ns = (e) => {
|
|
2815
2823
|
let t = /* @__PURE__ */ new Map();
|
|
2816
2824
|
for (let n of e) {
|
|
2817
2825
|
if (n.proxyTarget === void 0) continue;
|
|
@@ -2819,43 +2827,43 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2819
2827
|
if (e) throw Error(`[voltro] api ${JSON.stringify(n.name)} and ${JSON.stringify(e)} both resolve the same-origin WS path ${JSON.stringify(n.browserWsUrl)}. A custom transport.wsPath must be unique per origin (one api per origin may use a fixed path). Give each a distinct wsPath, or drop the override to use the default /ws/<name>.`);
|
|
2820
2828
|
t.set(n.browserWsUrl, n.name);
|
|
2821
2829
|
}
|
|
2822
|
-
},
|
|
2830
|
+
}, rs = async (e, t) => {
|
|
2823
2831
|
let n = Object.entries(t.apis ?? {}), r = [];
|
|
2824
2832
|
for (let [t, i] of n) {
|
|
2825
2833
|
if (i.url) {
|
|
2826
|
-
r.push(
|
|
2834
|
+
r.push(es(t, i));
|
|
2827
2835
|
continue;
|
|
2828
2836
|
}
|
|
2829
|
-
let n = await
|
|
2837
|
+
let n = await Qo(e, i.package);
|
|
2830
2838
|
if (!n) throw Error(`[voltro dev] api ${JSON.stringify(t)} (package ${JSON.stringify(i.package)}) is not a workspace dep and has no \`url\` set in app.config.ts. External apis need an explicit \`url\` because the framework can't discover their dev port.`);
|
|
2831
|
-
r.push(
|
|
2839
|
+
r.push(ts(t, i, await $o(n)));
|
|
2832
2840
|
}
|
|
2833
|
-
return
|
|
2834
|
-
},
|
|
2841
|
+
return ns(r), r;
|
|
2842
|
+
}, is = (e) => {
|
|
2835
2843
|
if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
|
|
2836
2844
|
let t = new URL(e);
|
|
2837
2845
|
return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
|
|
2838
2846
|
} catch {
|
|
2839
2847
|
return;
|
|
2840
2848
|
}
|
|
2841
|
-
},
|
|
2849
|
+
}, as = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, os = (e) => process.env[as(e)] ?? process.env.VOLTRO_API_ORIGIN, ss = (e, t) => {
|
|
2842
2850
|
if (!e) return;
|
|
2843
|
-
let n =
|
|
2851
|
+
let n = os(e.name) ?? e.serverOrigin;
|
|
2844
2852
|
if (n) {
|
|
2845
|
-
let e =
|
|
2853
|
+
let e = is(n);
|
|
2846
2854
|
if (e) return e;
|
|
2847
2855
|
}
|
|
2848
2856
|
if (t?.allowDevProxy && e.proxyTarget) {
|
|
2849
|
-
let t =
|
|
2857
|
+
let t = is(e.proxyTarget);
|
|
2850
2858
|
if (t) return t;
|
|
2851
2859
|
}
|
|
2852
|
-
if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return
|
|
2853
|
-
},
|
|
2860
|
+
if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return is(e.browserWsUrl);
|
|
2861
|
+
}, cs = (e, t, n) => {
|
|
2854
2862
|
if (!e) {
|
|
2855
2863
|
if (n?.apiName === void 0) return;
|
|
2856
2864
|
let e = n.apiName;
|
|
2857
2865
|
return async () => {
|
|
2858
|
-
throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${
|
|
2866
|
+
throw Error(`[loader.query] api '${e}' has no server-side origin for SSR. In a split web/api deployment the web pod reaches the api by internal DNS, not the browser's relative wsPath — set ${as(e)} (or VOLTRO_API_ORIGIN, or apis.${e}.serverUrl in app.config.ts) to the api's internal origin, e.g. http://api.<namespace>.svc.cluster.local. The browser transport is unaffected.`);
|
|
2859
2867
|
};
|
|
2860
2868
|
}
|
|
2861
2869
|
return async (r, i) => {
|
|
@@ -2878,7 +2886,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2878
2886
|
});
|
|
2879
2887
|
} catch (t) {
|
|
2880
2888
|
let i = t?.cause?.code ?? String(t?.message ?? t);
|
|
2881
|
-
throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${
|
|
2889
|
+
throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${as(n.apiName)} / VOLTRO_API_ORIGIN` : "Set the api server origin"} to the api's SSR-reachable origin (internal cluster DNS in a split deployment).`, { cause: t });
|
|
2882
2890
|
}
|
|
2883
2891
|
if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
|
|
2884
2892
|
let s = await o.json();
|
|
@@ -2908,7 +2916,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2908
2916
|
}
|
|
2909
2917
|
if (u) return l;
|
|
2910
2918
|
};
|
|
2911
|
-
},
|
|
2919
|
+
}, ls = (e, t) => {
|
|
2912
2920
|
let n = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppGroup`, r = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppDescriptors`, i = e.map((e) => `import { appGroup as ${n(e.name)}, appDescriptors as ${r(e.name)} } from '${e.pkg}/rpcGroup'`);
|
|
2913
2921
|
e.some((e) => e.hasAuthHeaders) && (i.push(`import __voltroAppConfig from '${t}'`), i.push("const __voltroAuthHeaders = (__voltroAppConfig as { readonly apis?: Record<string, { readonly authHeaders?: () => Record<string, string> | Promise<Record<string, string>> }> }).apis"));
|
|
2914
2922
|
let a = (e) => {
|
|
@@ -2920,10 +2928,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2920
2928
|
entryLines: e.map((e) => ` ${JSON.stringify(e.name)}: { ${a(e).join(", ")} },`),
|
|
2921
2929
|
providerEntryLines: e.map((e) => ` { name: ${JSON.stringify(e.name)}, ${a(e).join(", ")} },`)
|
|
2922
2930
|
};
|
|
2923
|
-
},
|
|
2931
|
+
}, us = async (e, t, n, r = {}) => {
|
|
2924
2932
|
let i = t.title ?? t.name ?? "app";
|
|
2925
2933
|
Gn(e);
|
|
2926
|
-
let a = await Vn(e, t.fonts), o = a === null ? [] : [...a.preloads.map((e) => ` <link rel="preload" as="font" type="font/${e.endsWith(".woff2") ? "woff2" : e.endsWith(".woff") ? "woff" : e.endsWith(".otf") ? "otf" : "ttf"}" href="${e}" crossorigin />`), ` <style data-voltro-fonts>${a.css}</style>`], s = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", c = L(P(e, "node_modules", "@voltro", "devtools", "package.json")) || await Do() !== null, l = t.theme === "system" ? [
|
|
2934
|
+
let a = await Vn(e, t.fonts), o = a === null ? [] : [...a.preloads.map((e) => ` <link rel="preload" as="font" type="font/${e.endsWith(".woff2") ? "woff2" : e.endsWith(".woff") ? "woff" : e.endsWith(".otf") ? "otf" : "ttf"}" href="${e}" crossorigin />`), ` <style data-voltro-fonts>${a.css}</style>`], s = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", c = L(P(e, "node_modules", "@voltro", "devtools", "package.json")) || await Do() !== null, l = L(P(e, "node_modules", "@voltro", "plugin-sentry", "package.json")), u = t.theme === "system" ? [
|
|
2927
2935
|
" <script>",
|
|
2928
2936
|
" (function () {",
|
|
2929
2937
|
" var root = document.documentElement",
|
|
@@ -2944,7 +2952,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2944
2952
|
" }",
|
|
2945
2953
|
" })()",
|
|
2946
2954
|
" <\/script>"
|
|
2947
|
-
].join("\n") : "",
|
|
2955
|
+
].join("\n") : "", d = t.timeZone === "viewer" ? [
|
|
2948
2956
|
" <script>",
|
|
2949
2957
|
" (function () {",
|
|
2950
2958
|
" try {",
|
|
@@ -2956,7 +2964,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2956
2964
|
" } catch (e) {}",
|
|
2957
2965
|
" })()",
|
|
2958
2966
|
" <\/script>"
|
|
2959
|
-
].join("\n") : "",
|
|
2967
|
+
].join("\n") : "", f = [
|
|
2960
2968
|
"<!doctype html>",
|
|
2961
2969
|
"<!-- GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot. -->",
|
|
2962
2970
|
`<html lang="en"${s}>`,
|
|
@@ -2967,8 +2975,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2967
2975
|
" <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />",
|
|
2968
2976
|
...ko(n),
|
|
2969
2977
|
...o,
|
|
2970
|
-
...l ? [l] : [],
|
|
2971
2978
|
...u ? [u] : [],
|
|
2979
|
+
...d ? [d] : [],
|
|
2972
2980
|
" </head>",
|
|
2973
2981
|
" <body>",
|
|
2974
2982
|
" <div id=\"root\"></div>",
|
|
@@ -2976,32 +2984,32 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2976
2984
|
" </body>",
|
|
2977
2985
|
"</html>",
|
|
2978
2986
|
""
|
|
2979
|
-
].join("\n"),
|
|
2980
|
-
await x(
|
|
2981
|
-
for (let e of
|
|
2982
|
-
let { imports:
|
|
2983
|
-
if (
|
|
2984
|
-
let n =
|
|
2985
|
-
for (let e of
|
|
2987
|
+
].join("\n"), p = P(e, "src", "pages"), { pages: m, dirs: h, orphanedSpecials: g } = await Wo(p);
|
|
2988
|
+
await x(p, m);
|
|
2989
|
+
for (let e of g) Q.warn(`src/pages/${e.dir || "."}/ contains ${e.files.join(", ")} but no page.tsx at or below it — ${e.files.length > 1 ? "those files are" : "that file is"} inert. A layout/error/loading/not-found file only applies to routes in its own directory tree; if this is an ordinary component, rename it so it does not read as a route boundary.`);
|
|
2990
|
+
let { imports: _, entryLines: v } = ls(n, "../app.config"), y, ee, b;
|
|
2991
|
+
if (m.length > 0) {
|
|
2992
|
+
let n = m.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
|
|
2993
|
+
for (let e of h) {
|
|
2986
2994
|
let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`;
|
|
2987
2995
|
e.hasLayout && e.hasLayoutLoader ? r.push(`import * as ${$(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && r.push(`import ${$(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && r.push(`import ${$(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && r.push(`import ${$(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && r.push(`import ${$(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
|
|
2988
2996
|
}
|
|
2989
|
-
let i =
|
|
2990
|
-
let t =
|
|
2997
|
+
let i = m.map((e) => {
|
|
2998
|
+
let t = Go(h, e.dirChain).map((e) => {
|
|
2991
2999
|
let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
|
|
2992
3000
|
return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasLayoutLoader && t.push(`loader: refs.layoutLoaders[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), e.hasPending && t.push(`Pending: refs.pendings[${n}]`), ` { ${t.join(", ")} }`;
|
|
2993
3001
|
}).join(",\n");
|
|
2994
3002
|
return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
|
|
2995
|
-
}), a =
|
|
2996
|
-
let t =
|
|
3003
|
+
}), a = h.filter((e) => e.hasNotFound).map((e) => {
|
|
3004
|
+
let t = qo(e.chain), n = Go(h, e.chain).map((e) => {
|
|
2997
3005
|
let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
|
|
2998
3006
|
return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
|
|
2999
3007
|
}).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
|
|
3000
3008
|
return ` {\n prefix: ${JSON.stringify(t)},\n Component: refs.notFounds[${JSON.stringify(e.dir)}],${r}\n },`;
|
|
3001
|
-
}), o = [], s = [],
|
|
3002
|
-
for (let e of
|
|
3009
|
+
}), o = [], s = [], u = [], d = [], f = [], p = [];
|
|
3010
|
+
for (let e of h) {
|
|
3003
3011
|
let t = e.dir === "" ? "../src/pages/layout.tsx" : `../src/pages/${e.dir}/layout.tsx`, n = e.dir === "" ? "../src/pages/error.tsx" : `../src/pages/${e.dir}/error.tsx`, r = e.dir === "" ? "../src/pages/loading.tsx" : `../src/pages/${e.dir}/loading.tsx`, i = e.dir === "" ? "../src/pages/not-found.tsx" : `../src/pages/${e.dir}/not-found.tsx`, a = JSON.stringify(e.dir);
|
|
3004
|
-
e.hasLayout && e.hasLayoutLoader ? (s.push(` ${a}: ${$(e.dir, "Layout")}Mod.default,`),
|
|
3012
|
+
e.hasLayout && e.hasLayoutLoader ? (s.push(` ${a}: ${$(e.dir, "Layout")}Mod.default,`), u.push(` ${a}: ${$(e.dir, "Layout")}Mod.loader,`), o.push({
|
|
3005
3013
|
relPath: t,
|
|
3006
3014
|
kind: "layout",
|
|
3007
3015
|
slotKey: e.dir
|
|
@@ -3009,37 +3017,37 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3009
3017
|
relPath: t,
|
|
3010
3018
|
kind: "layout",
|
|
3011
3019
|
slotKey: e.dir
|
|
3012
|
-
})), e.hasError && (
|
|
3020
|
+
})), e.hasError && (d.push(` ${a}: ${$(e.dir, "Error")},`), o.push({
|
|
3013
3021
|
relPath: n,
|
|
3014
3022
|
kind: "error",
|
|
3015
3023
|
slotKey: e.dir
|
|
3016
|
-
})), e.hasPending && (
|
|
3024
|
+
})), e.hasPending && (f.push(` ${a}: ${$(e.dir, "Pending")},`), o.push({
|
|
3017
3025
|
relPath: r,
|
|
3018
3026
|
kind: "pending",
|
|
3019
3027
|
slotKey: e.dir
|
|
3020
|
-
})), e.hasNotFound && (
|
|
3028
|
+
})), e.hasNotFound && (p.push(` ${a}: ${$(e.dir, "NotFound")},`), o.push({
|
|
3021
3029
|
relPath: i,
|
|
3022
3030
|
kind: "notFound",
|
|
3023
3031
|
slotKey: e.dir
|
|
3024
3032
|
}));
|
|
3025
3033
|
}
|
|
3026
|
-
for (let e of
|
|
3034
|
+
for (let e of m) o.push({
|
|
3027
3035
|
relPath: `../src/pages/${e.file}`,
|
|
3028
3036
|
kind: "page",
|
|
3029
3037
|
slotKey: e.pattern
|
|
3030
3038
|
});
|
|
3031
|
-
let
|
|
3039
|
+
let g = o.map((e) => ` ${JSON.stringify(e.relPath)},`), x = o.map((e, t) => {
|
|
3032
3040
|
let n = JSON.stringify(e.slotKey);
|
|
3033
3041
|
return e.kind === "page" ? ` if (newMods[${t}] && refs.pages[${n}] !== undefined) { refs.pages[${n}] = newMods[${t}]; changed = true }` : ` if (newMods[${t}]?.default) { refs.${e.kind === "layout" ? "layouts" : e.kind === "error" ? "errors" : e.kind === "pending" ? "pendings" : "notFounds"}[${n}] = newMods[${t}].default;${e.kind === "layout" ? ` refs.layoutLoaders[${n}] = newMods[${t}].loader;` : ""} changed = true }`;
|
|
3034
|
-
}),
|
|
3035
|
-
if (
|
|
3036
|
-
let
|
|
3042
|
+
}), S = t.locales ?? [], C = S.length > 0 && S.every((t) => L(P(e, "src", "locales", `${t}.ts`)) || L(P(e, "src", "locales", `${t}.tsx`))), w = C, T = t.defaultLocale ?? S[0] ?? "en", E = t.router?.viewTransitions === !0 ? " viewTransitions" : "";
|
|
3043
|
+
if (S.length > 0 && !C && Q.info(`i18n: locales [${S.join(", ")}] declared with no src/locales/<code>.ts — using them for <html lang> and the resolved locale only. Add the catalogs to get <I18nProvider> wired, or keep your own i18n stack.`), S.length > 0 && !S.includes(T)) throw Error(`[voltro dev] app.config.ts: defaultLocale '${T}' must be one of locales [${S.join(", ")}]`);
|
|
3044
|
+
let D = w ? [
|
|
3037
3045
|
"import { I18nProvider } from '@voltro/i18n'",
|
|
3038
3046
|
"import { resolveLocale } from '@voltro/i18n/server'",
|
|
3039
3047
|
"import { useServerRequest } from '@voltro/web'",
|
|
3040
|
-
...
|
|
3048
|
+
...S.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
|
|
3041
3049
|
] : [];
|
|
3042
|
-
|
|
3050
|
+
ee = [
|
|
3043
3051
|
"// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
|
|
3044
3052
|
"// Routes + per-page chain + not-found scopes assembled from src/pages/.",
|
|
3045
3053
|
"//",
|
|
@@ -3076,16 +3084,16 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3076
3084
|
...s,
|
|
3077
3085
|
" },",
|
|
3078
3086
|
" layoutLoaders: {",
|
|
3079
|
-
...
|
|
3087
|
+
...u,
|
|
3080
3088
|
" },",
|
|
3081
3089
|
" errors: {",
|
|
3082
|
-
...
|
|
3090
|
+
...d,
|
|
3083
3091
|
" },",
|
|
3084
3092
|
" pendings: {",
|
|
3085
|
-
...
|
|
3093
|
+
...f,
|
|
3086
3094
|
" },",
|
|
3087
3095
|
" notFounds: {",
|
|
3088
|
-
...
|
|
3096
|
+
...p,
|
|
3089
3097
|
" },",
|
|
3090
3098
|
" pages: {},",
|
|
3091
3099
|
"}",
|
|
@@ -3150,17 +3158,17 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3150
3158
|
"if (import.meta.hot) {",
|
|
3151
3159
|
" import.meta.hot.accept(",
|
|
3152
3160
|
" [",
|
|
3153
|
-
...
|
|
3161
|
+
...g,
|
|
3154
3162
|
" ],",
|
|
3155
3163
|
" (newMods: Array<Record<string, unknown> | undefined>) => {",
|
|
3156
3164
|
" let changed = false",
|
|
3157
|
-
...
|
|
3165
|
+
...x,
|
|
3158
3166
|
" if (changed) bump()",
|
|
3159
3167
|
" },",
|
|
3160
3168
|
" )",
|
|
3161
3169
|
"}",
|
|
3162
3170
|
""
|
|
3163
|
-
].join("\n"),
|
|
3171
|
+
].join("\n"), y = [
|
|
3164
3172
|
"// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
|
|
3165
3173
|
"// The app's root component. It exports `App` and NOTHING ELSE: react-refresh",
|
|
3166
3174
|
"// only accepts a module whose every export is a component, and a module it",
|
|
@@ -3171,16 +3179,16 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3171
3179
|
"",
|
|
3172
3180
|
"import { useMemo, useSyncExternalStore } from 'react'",
|
|
3173
3181
|
"import { Router } from '@voltro/web'",
|
|
3174
|
-
...
|
|
3182
|
+
...D,
|
|
3175
3183
|
"import { subscribe, getVersion, buildRoutes, buildNotFounds } from './routeTable'",
|
|
3176
3184
|
"",
|
|
3177
|
-
...
|
|
3178
|
-
`// i18n auto-wiring (config.locales = [${
|
|
3185
|
+
...w ? [
|
|
3186
|
+
`// i18n auto-wiring (config.locales = [${S.map((e) => JSON.stringify(e)).join(", ")}]).`,
|
|
3179
3187
|
"const I18N_CATALOGS: Record<string, import('@voltro/i18n').MessageCatalog> = {",
|
|
3180
|
-
...
|
|
3188
|
+
...S.map((e) => ` ${JSON.stringify(e)}: i18nCatalog_${e},`),
|
|
3181
3189
|
"}",
|
|
3182
|
-
`const I18N_SUPPORTED: ReadonlyArray<string> = [${
|
|
3183
|
-
`const I18N_DEFAULT = ${JSON.stringify(
|
|
3190
|
+
`const I18N_SUPPORTED: ReadonlyArray<string> = [${S.map((e) => JSON.stringify(e)).join(", ")}]`,
|
|
3191
|
+
`const I18N_DEFAULT = ${JSON.stringify(T)}`,
|
|
3184
3192
|
"",
|
|
3185
3193
|
"// The zone + clock the SERVER decided for this document, read back off",
|
|
3186
3194
|
"// <html>. Same contract as <html lang> below and for the same reason:",
|
|
@@ -3254,7 +3262,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3254
3262
|
" const v = useSyncExternalStore(subscribe, getVersion, getVersion)",
|
|
3255
3263
|
" const routes = useMemo(() => buildRoutes(), [v])",
|
|
3256
3264
|
" const notFounds = useMemo(() => buildNotFounds(), [v])",
|
|
3257
|
-
...
|
|
3265
|
+
...w ? [
|
|
3258
3266
|
" const ssr = useServerRequest()",
|
|
3259
3267
|
" const locale = pickI18nLocale(ssr)",
|
|
3260
3268
|
" const messages = I18N_CATALOGS[locale] ?? I18N_CATALOGS[I18N_DEFAULT]!",
|
|
@@ -3269,26 +3277,26 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3269
3277
|
" defaultLocale={I18N_DEFAULT}",
|
|
3270
3278
|
" {...published}",
|
|
3271
3279
|
" >",
|
|
3272
|
-
` <Router routes={routes} notFounds={notFounds}${
|
|
3280
|
+
` <Router routes={routes} notFounds={notFounds}${E} />`,
|
|
3273
3281
|
" </I18nProvider>",
|
|
3274
3282
|
" )"
|
|
3275
|
-
] : [` return <Router routes={routes} notFounds={notFounds}${
|
|
3283
|
+
] : [` return <Router routes={routes} notFounds={notFounds}${E} />`],
|
|
3276
3284
|
"}",
|
|
3277
3285
|
""
|
|
3278
|
-
].join("\n"),
|
|
3286
|
+
].join("\n"), b = [
|
|
3279
3287
|
"// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
|
|
3280
3288
|
"// Entry: imports the generated App component and calls mount() with the",
|
|
3281
3289
|
"// resolved apis map. Side-effect only — no local component definitions —",
|
|
3282
3290
|
"// so downstream invalidations (user page edits) terminate at app.tsx.",
|
|
3283
3291
|
"",
|
|
3284
|
-
...
|
|
3292
|
+
...Fo(t),
|
|
3285
3293
|
"import { mount } from '@voltro/web'",
|
|
3286
|
-
...
|
|
3294
|
+
..._,
|
|
3287
3295
|
"import { App } from './app'",
|
|
3288
3296
|
"import { preloadCurrentRoute } from './routeTable'",
|
|
3289
|
-
...Mo(t),
|
|
3297
|
+
...Mo(t, l),
|
|
3290
3298
|
...Oo(t, c),
|
|
3291
|
-
...
|
|
3299
|
+
...Po(t, l),
|
|
3292
3300
|
"",
|
|
3293
3301
|
"// Preload the current route's page chunk BEFORE hydration so the first",
|
|
3294
3302
|
"// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
|
|
@@ -3303,54 +3311,54 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3303
3311
|
"",
|
|
3304
3312
|
"mount(App, {",
|
|
3305
3313
|
" apis: {",
|
|
3306
|
-
...
|
|
3314
|
+
...v,
|
|
3307
3315
|
" },",
|
|
3308
3316
|
...jo(t, c),
|
|
3309
3317
|
...Ao(t),
|
|
3310
3318
|
"})",
|
|
3311
3319
|
"",
|
|
3312
|
-
|
|
3320
|
+
Jo
|
|
3313
3321
|
].join("\n");
|
|
3314
|
-
} else
|
|
3322
|
+
} else y = "", ee = "", b = [
|
|
3315
3323
|
"// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
|
|
3316
3324
|
"// The user's root component lives at ../src/App.tsx; this file imports it",
|
|
3317
3325
|
"// and calls mount(). Side-effect only, no component definitions, so the",
|
|
3318
3326
|
"// user's component file remains the Fast Refresh boundary.",
|
|
3319
3327
|
"",
|
|
3320
|
-
...
|
|
3328
|
+
...Fo(t),
|
|
3321
3329
|
"import { mount } from '@voltro/web'",
|
|
3322
|
-
...
|
|
3330
|
+
..._,
|
|
3323
3331
|
"import App from '../src/App'",
|
|
3324
|
-
...Mo(t),
|
|
3332
|
+
...Mo(t, l),
|
|
3325
3333
|
...Oo(t, c),
|
|
3326
|
-
...
|
|
3334
|
+
...Po(t, l),
|
|
3327
3335
|
"",
|
|
3328
3336
|
"mount(App, {",
|
|
3329
3337
|
" apis: {",
|
|
3330
|
-
...
|
|
3338
|
+
...v,
|
|
3331
3339
|
" },",
|
|
3332
3340
|
...jo(t, c),
|
|
3333
3341
|
...Ao(t),
|
|
3334
3342
|
"})",
|
|
3335
3343
|
"",
|
|
3336
|
-
|
|
3344
|
+
Jo
|
|
3337
3345
|
].join("\n");
|
|
3338
|
-
let
|
|
3339
|
-
await z.mkdir(
|
|
3340
|
-
let
|
|
3346
|
+
let S = P(e, ".framework");
|
|
3347
|
+
await z.mkdir(S, { recursive: !0 }), t.env ? await ht(S, r) : await z.rm(P(S, "env.public.ts"), { force: !0 }), await z.writeFile(P(S, "index.html"), f, "utf8"), await z.writeFile(P(S, "main.tsx"), b, "utf8"), y ? (await z.writeFile(P(S, "app.tsx"), y, "utf8"), await z.writeFile(P(S, "routeTable.ts"), ee, "utf8")) : (await z.rm(P(S, "app.tsx"), { force: !0 }), await z.rm(P(S, "routeTable.ts"), { force: !0 }));
|
|
3348
|
+
let C = P(e, ".gitignore"), w = "";
|
|
3341
3349
|
try {
|
|
3342
|
-
|
|
3350
|
+
w = await z.readFile(C, "utf8");
|
|
3343
3351
|
} catch {}
|
|
3344
|
-
let
|
|
3345
|
-
if (
|
|
3346
|
-
let e =
|
|
3352
|
+
let T = ["/.framework/"], E = new Set(w.split("\n").map((e) => e.trim())), D = T.filter((e) => !E.has(e));
|
|
3353
|
+
if (D.length > 0) {
|
|
3354
|
+
let e = w === "" || w.endsWith("\n") ? "" : "\n";
|
|
3347
3355
|
try {
|
|
3348
|
-
await z.appendFile(
|
|
3356
|
+
await z.appendFile(C, `${e}${D.join("\n")}\n`, "utf8");
|
|
3349
3357
|
} catch (e) {
|
|
3350
|
-
Q.warn(`could not add ${
|
|
3358
|
+
Q.warn(`could not add ${D.join(", ")} to ${C} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
|
|
3351
3359
|
}
|
|
3352
3360
|
}
|
|
3353
|
-
},
|
|
3361
|
+
}, ds = async (e, t) => {
|
|
3354
3362
|
try {
|
|
3355
3363
|
let n = N(e), r = P(n, "project.json");
|
|
3356
3364
|
if (!L(r)) return;
|
|
@@ -3363,26 +3371,26 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3363
3371
|
projectJson: r
|
|
3364
3372
|
});
|
|
3365
3373
|
} catch {}
|
|
3366
|
-
},
|
|
3367
|
-
let n =
|
|
3374
|
+
}, fs = (e) => P(e, ".framework", "dist", "server", "appConfig.js"), ps = async (e, t = {}) => {
|
|
3375
|
+
let n = fs(e), r = t.preferSource !== !0 && L(n) ? n : P(e, "app.config.ts");
|
|
3368
3376
|
try {
|
|
3369
3377
|
let e = (await import(G(r).href)).default;
|
|
3370
3378
|
return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
|
|
3371
3379
|
} catch {
|
|
3372
3380
|
return null;
|
|
3373
3381
|
}
|
|
3374
|
-
},
|
|
3382
|
+
}, ms = (e) => {
|
|
3375
3383
|
let t = e.restRoutes;
|
|
3376
3384
|
if (t !== void 0 && t.length !== 0) return `app.config.ts declares ${t.length} restRoute(s) on a type:'web' app — REST routes mount on the API process and were silently ignored here, so a health probe hitting one gets the SPA shell (200) and a POST gets 404.\n Move them to the API app's app.config.ts (they mount under the api origin), and call them there;\n for same-origin paths in front of the web app, terminate them at your ingress/proxy instead.`;
|
|
3377
|
-
},
|
|
3378
|
-
let u = await
|
|
3385
|
+
}, hs = async (t) => {
|
|
3386
|
+
let u = await ps(t, { preferSource: !0 });
|
|
3379
3387
|
if (!u) return {
|
|
3380
3388
|
ran: !1,
|
|
3381
3389
|
exitCode: 0
|
|
3382
3390
|
};
|
|
3383
3391
|
let d = xo(u.health, () => !0);
|
|
3384
3392
|
{
|
|
3385
|
-
let e =
|
|
3393
|
+
let e = ms(u);
|
|
3386
3394
|
if (e !== void 0) return Q.error(`voltro dev (web): refusing to boot — ${e}`), {
|
|
3387
3395
|
ran: !0,
|
|
3388
3396
|
exitCode: 1
|
|
@@ -3391,7 +3399,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3391
3399
|
bi();
|
|
3392
3400
|
let f = at();
|
|
3393
3401
|
Qr(f), Q.info("booting voltro dev (web)", { app: u.name ?? "(unnamed)" }), Vt(t, Q);
|
|
3394
|
-
let p = await
|
|
3402
|
+
let p = await rs(t, u);
|
|
3395
3403
|
for (let e of p) Q.info("api wired", {
|
|
3396
3404
|
name: e.name,
|
|
3397
3405
|
pkg: e.pkg,
|
|
@@ -3410,7 +3418,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3410
3418
|
log: Q,
|
|
3411
3419
|
generateTypes: !0
|
|
3412
3420
|
}), h = m.publicValues;
|
|
3413
|
-
await
|
|
3421
|
+
await us(t, u, p, h), Q.debug("generated framework entry files", { files: [
|
|
3414
3422
|
"index.html",
|
|
3415
3423
|
".framework/main.tsx",
|
|
3416
3424
|
...u.env ? [".framework/env.public.ts"] : []
|
|
@@ -3431,8 +3439,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3431
3439
|
pid: process.pid,
|
|
3432
3440
|
status: "booting",
|
|
3433
3441
|
logFile: w.path
|
|
3434
|
-
}).catch(() => {}), await
|
|
3435
|
-
let { pages: T, dirs: E } = await
|
|
3442
|
+
}).catch(() => {}), await ds(t, x);
|
|
3443
|
+
let { pages: T, dirs: E } = await Wo(P(t, "src", "pages")), D = null, te = u.fonts !== void 0 && u.fonts.length > 0 ? yr({
|
|
3436
3444
|
root: t,
|
|
3437
3445
|
fonts: u.fonts,
|
|
3438
3446
|
cache: ee(),
|
|
@@ -3446,7 +3454,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3446
3454
|
}
|
|
3447
3455
|
}) : null, k = {
|
|
3448
3456
|
dirs: E,
|
|
3449
|
-
ssrRoutes:
|
|
3457
|
+
ssrRoutes: Xo(T)
|
|
3450
3458
|
}, ne = E.map((e) => ({
|
|
3451
3459
|
dir: e.dir,
|
|
3452
3460
|
hasLayout: e.hasLayout,
|
|
@@ -3481,12 +3489,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3481
3489
|
}, B = P(t, "src", "pages"), V = (e) => e.endsWith(".tsx") && (e === B || e.startsWith(B + "/")), H = (e) => e === B || e.startsWith(B + "/"), fe = async (e) => {
|
|
3482
3490
|
try {
|
|
3483
3491
|
let n = Date.now();
|
|
3484
|
-
await
|
|
3485
|
-
let { pages: r, dirs: i } = await
|
|
3492
|
+
await us(t, u, p, h);
|
|
3493
|
+
let { pages: r, dirs: i } = await Wo(B);
|
|
3486
3494
|
await kr({
|
|
3487
3495
|
appRoot: t,
|
|
3488
3496
|
pages: r
|
|
3489
|
-
}), k.dirs = i, k.ssrRoutes =
|
|
3497
|
+
}), k.dirs = i, k.ssrRoutes = Xo(r), Q.info("page tree regenerated", {
|
|
3490
3498
|
reason: e,
|
|
3491
3499
|
ms: Date.now() - n,
|
|
3492
3500
|
routes: k.ssrRoutes.length
|
|
@@ -3586,7 +3594,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3586
3594
|
}
|
|
3587
3595
|
try {
|
|
3588
3596
|
let r = Date.now();
|
|
3589
|
-
await
|
|
3597
|
+
await us(t, e, await rs(t, e)), me = e, n.ws && n.ws.send({
|
|
3590
3598
|
type: "full-reload",
|
|
3591
3599
|
path: "*"
|
|
3592
3600
|
}), Q.info("app.config.ts soft-regen", {
|
|
@@ -3625,7 +3633,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
3625
3633
|
async configureServer(e) {
|
|
3626
3634
|
let n = [];
|
|
3627
3635
|
for (let r of p) {
|
|
3628
|
-
let i = await
|
|
3636
|
+
let i = await Qo(t, r.pkg);
|
|
3629
3637
|
if (i) {
|
|
3630
3638
|
n.push(i);
|
|
3631
3639
|
try {
|
|
@@ -4035,12 +4043,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4035
4043
|
} catch {}
|
|
4036
4044
|
})(), o), c = mn({
|
|
4037
4045
|
apiName: p[0]?.name,
|
|
4038
|
-
apiOrigin:
|
|
4046
|
+
apiOrigin: ss(p[0], { allowDevProxy: !0 }),
|
|
4039
4047
|
loadDescriptors: async () => {
|
|
4040
4048
|
let e = p[0];
|
|
4041
4049
|
if (e !== void 0) return (await n(`${e.pkg}/rpcGroup`)).appDescriptors;
|
|
4042
4050
|
},
|
|
4043
|
-
rpcQuery: (e, t) => ss(
|
|
4051
|
+
rpcQuery: (e, t) => cs(ss(p[0], { allowDevProxy: !0 }), e, {
|
|
4044
4052
|
apiName: p[0]?.name,
|
|
4045
4053
|
headers: t
|
|
4046
4054
|
}),
|
|
@@ -4094,7 +4102,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4094
4102
|
for (let e of n.setCookies) o.appendHeader("set-cookie", Ha(e));
|
|
4095
4103
|
};
|
|
4096
4104
|
if (/\.[a-z0-9]+$/i.test(d)) return await h(), c();
|
|
4097
|
-
let g =
|
|
4105
|
+
let g = Zo(d, k.ssrRoutes), _ = !1;
|
|
4098
4106
|
if (!g) {
|
|
4099
4107
|
let e = Eo(k.dirs, d);
|
|
4100
4108
|
if (e === void 0) return await h(), c();
|
|
@@ -4130,7 +4138,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4130
4138
|
}
|
|
4131
4139
|
}, C = !1;
|
|
4132
4140
|
try {
|
|
4133
|
-
let w = await x("loadPage", async () => await n(P(t, "src", "pages", g.route.file))), T = _ ? "ssr" : y(w, P("src", "pages", g.route.file)), E =
|
|
4141
|
+
let w = await x("loadPage", async () => await n(P(t, "src", "pages", g.route.file))), T = _ ? "ssr" : y(w, P("src", "pages", g.route.file)), E = Go(k.dirs, g.route.dirChain), D = T === "spa" && E.some((e) => e.hasLayout), O = w.interactive ?? "full";
|
|
4134
4142
|
if (T !== "ssr" && T !== "isr" && !D && O !== "islands") return await h(), c();
|
|
4135
4143
|
let ne = {};
|
|
4136
4144
|
for (let [e, t] of Object.entries(r.headers ?? {})) typeof t == "string" ? ne[e] = t : Array.isArray(t) && (ne[e] = t.join(", "));
|
|
@@ -4147,14 +4155,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4147
4155
|
for (let e of A.setCookies) o.appendHeader("set-cookie", Ha(e));
|
|
4148
4156
|
for (let [e, t] of Object.entries(A.responseHeaders)) o.setHeader(e, t);
|
|
4149
4157
|
if (T === "isr" && A.cspNonce !== void 0) throw Error(`page '${g.route.pattern}' is renderMode 'isr' while middleware.ts mints a cspNonce — an isr render is CACHED and a cached nonce is a lie the browser enforces. Use renderMode 'ssr' for nonce'd pages, or a hash-based CSP for isr.`);
|
|
4150
|
-
let j = T === "isr" ? Ya(A.headers) : A.headers, M = T === "isr" && w.ppr === !0, re = M ? go(j, g.route.pattern) : j, ie = ss(
|
|
4158
|
+
let j = T === "isr" ? Ya(A.headers) : A.headers, M = T === "isr" && w.ppr === !0, re = M ? go(j, g.route.pattern) : j, ie = cs(ss(p[0], { allowDevProxy: !0 }), j.cookie, {
|
|
4151
4159
|
apiName: p[0]?.name,
|
|
4152
4160
|
headers: j
|
|
4153
4161
|
}), ae = new AbortController(), oe = () => ae.abort();
|
|
4154
4162
|
o.once("close", oe);
|
|
4155
4163
|
let se = null, ce = [], le = {};
|
|
4156
4164
|
try {
|
|
4157
|
-
(await n("@voltro/web/ssr")).beginStoreSeeds(), await s(), {chain: ce, segmentLoaderData: le} = await x("loadChain", () =>
|
|
4165
|
+
(await n("@voltro/web/ssr")).beginStoreSeeds(), await s(), {chain: ce, segmentLoaderData: le} = await x("loadChain", () => Ko({
|
|
4158
4166
|
entries: E,
|
|
4159
4167
|
loadLayout: (e) => n(P(t, "src", "pages", e.dir, "layout.tsx")),
|
|
4160
4168
|
loadError: (e) => n(P(t, "src", "pages", e.dir, "error.tsx")),
|
|
@@ -4255,7 +4263,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4255
4263
|
for (let t of n) await S(t, e, B);
|
|
4256
4264
|
});
|
|
4257
4265
|
let V = (O === "islands" ? await x("islandsEntry", async () => {
|
|
4258
|
-
let e =
|
|
4266
|
+
let e = ls(p, "../../app.config"), n = (await jn({
|
|
4259
4267
|
webRoot: t,
|
|
4260
4268
|
pages: [{
|
|
4261
4269
|
pattern: g.route.pattern,
|
|
@@ -4361,7 +4369,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4361
4369
|
let a = m === void 0 ? i : on(i, m);
|
|
4362
4370
|
if (M && m === void 0 && typeof w.loader == "function") {
|
|
4363
4371
|
o.setHeader("x-voltro-ppr", "shell+holes"), oo(g.route.pattern), o.write(a);
|
|
4364
|
-
let e = ss(
|
|
4372
|
+
let e = cs(ss(p[0], { allowDevProxy: !0 }), A.headers.cookie, {
|
|
4365
4373
|
apiName: p[0]?.name,
|
|
4366
4374
|
headers: A.headers
|
|
4367
4375
|
}), t = new AbortController();
|
|
@@ -4421,7 +4429,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4421
4429
|
}, Pe = Date.now(), Fe = j.version ?? "?", Ie = await Do(), q = P(t, "node_modules", "@voltro", "ui-shadcn"), J = L(P(q, "package.json")) ? q : null, Le = [], Re = await (async () => {
|
|
4422
4430
|
let e = [];
|
|
4423
4431
|
for (let n of p) {
|
|
4424
|
-
let r = await
|
|
4432
|
+
let r = await Qo(t, n.pkg);
|
|
4425
4433
|
r && e.push(r);
|
|
4426
4434
|
}
|
|
4427
4435
|
let n = await Da(e);
|
|
@@ -4517,7 +4525,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4517
4525
|
host: !0,
|
|
4518
4526
|
allowedHosts: u.allowedHosts === !0 || [...u.allowedHosts ?? []],
|
|
4519
4527
|
proxy: Se,
|
|
4520
|
-
fs: { allow: [t, ...
|
|
4528
|
+
fs: { allow: [t, ...Io(t)] }
|
|
4521
4529
|
},
|
|
4522
4530
|
appType: "spa",
|
|
4523
4531
|
cacheDir: P(N, ".vite"),
|
|
@@ -4572,8 +4580,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4572
4580
|
url: `http://localhost:${x}`,
|
|
4573
4581
|
bootMs: Date.now() - Pe
|
|
4574
4582
|
}), new Promise(() => {});
|
|
4575
|
-
},
|
|
4576
|
-
let t = await
|
|
4583
|
+
}, gs = async (e) => {
|
|
4584
|
+
let t = await ps(e);
|
|
4577
4585
|
return t ? (Q.child("serve").error("`voltro serve` is the production server for an API app — this is a WEB app.\n\n production voltro start .\n development voltro dev .\n\nBoth read the artefacts `voltro build` produces. `serve` cannot: it has no\nSSR bundle to render from, and building a second time here would overwrite\nthe one `voltro build` wrote.", {
|
|
4578
4586
|
app: t.name ?? "(unnamed)",
|
|
4579
4587
|
root: e
|
|
@@ -4586,4 +4594,4 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
4586
4594
|
};
|
|
4587
4595
|
};
|
|
4588
4596
|
//#endregion
|
|
4589
|
-
export {
|
|
4597
|
+
export { Yi as $, ot as $t, xo as A, En as At, Wa as B, Lt as Bt, gs as C, mr as Ct, us as D, Vn as Dt, ms as E, Gn as Et, oo as F, un as Ft, Ha as G, kt as Gt, Ra as H, Rt as Ht, Xa as I, mn as It, ma as J, St as Jt, Sa as K, wt as Kt, Ya as L, tn as Lt, yo as M, Tn as Mt, _o as N, On as Nt, Co as O, Rn as Ot, go as P, We as Pt, qi as Q, lt as Qt, La as R, $t as Rt, hs as S, pr as St, Wo as T, nr as Tt, Ga as U, Bt as Ut, Ia as V, zt as Vt, Fa as W, Vt as Wt, ha as X, mt as Xt, pa as Y, yt as Yt, ya as Z, pt as Zt, ts as _, Pr as _t, Eo as a, Pi as at, Po as b, yr as bt, Ko as c, _i as ct, Ho as d, oi as dt, at as en, Xi as et, $ as f, Qr as ft, es as g, Fr as gt, rs as h, qr as ht, ns as i, Ii as it, vo as j, kn as jt, So as k, jn as kt, fs as l, fi as lt, ps as m, Kr as mt, ss as n, Qi as nt, ls as o, Gi as ot, Uo as p, Wr as pt, _a as q, xt as qt, ko as r, $i as rt, cs as s, Fi as st, zo as t, st as tn, Zi as tt, Go as u, ci as ut, No as v, kr as vt, Ro as w, ar as wt, as as x, _r as xt, Mo as y, vr as yt, Ua as z, Qt as zt };
|