@voltro/cli 0.50.1 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +231 -0
  2. package/dist/{agentsMd-D6yD7IQv.js → agentsMd-0l980yhL.js} +4 -1
  3. package/dist/agentsMd-SDDSkyl4.js +2 -0
  4. package/dist/apiBuild-BYBpL7Pz.js +2 -0
  5. package/dist/{apiBuild-D3s7lx57.js → apiBuild-CSFI8QGq.js} +3 -3
  6. package/dist/appGraph-CFmFKHb2.js +2 -0
  7. package/dist/appGraph-yRuKjOba.js +111 -0
  8. package/dist/bin.js +1 -1
  9. package/dist/build-CPgcMQug.js +793 -0
  10. package/dist/checkCommand-2SbqzukH.js +2 -0
  11. package/dist/{checkCommand-DsKIjL6k.js → checkCommand-COmqc2cB.js} +107 -60
  12. package/dist/{cloudCmd-F4YJeqM3.js → cloudCmd-QUXh-b5w.js} +1 -1
  13. package/dist/codegen-CctkDO-1.js +2 -0
  14. package/dist/{codegen-CrMXs4hb.js → codegen-VF479Cnb.js} +1 -1
  15. package/dist/{codegenCommand-C0S27nbB.js → codegenCommand-DCdG2JN-.js} +12 -12
  16. package/dist/{codemodRunner-DwY8Rjbl.js → codemodRunner-r7J9lIa7.js} +771 -636
  17. package/dist/{commands-Brp4DI8u.js → commands-Cc_nV8WI.js} +37 -36
  18. package/dist/{dashboardCommand-bbLfc9FW.js → dashboardCommand-C-gKvwqh.js} +3 -3
  19. package/dist/{dataCommand-k9mXTXin.js → dataCommand-BgpBHnlB.js} +299 -253
  20. package/dist/dbCommand-DNb6yeOG.js +2 -0
  21. package/dist/{dbCommand-Bf7Cy0mn.js → dbCommand-sHedr-NJ.js} +3 -3
  22. package/dist/dev--A3nsxA3.js +3 -0
  23. package/dist/{dev-C0cbqysu.js → dev-CRHoCEiy.js} +2258 -2219
  24. package/dist/doctorCommand-CqoWA2p5.js +2 -0
  25. package/dist/{doctorCommand-DyViaaCP.js → doctorCommand-DtfJ3FA6.js} +314 -234
  26. package/dist/{dormancyCommand-DMZPA_HW.js → dormancyCommand-Drn7o0No.js} +1 -1
  27. package/dist/{embeddingsCommand-CMxRPkg6.js → embeddingsCommand-Z-jO1fWN.js} +1 -1
  28. package/dist/{envCommand-CDLr-yD4.js → envCommand-D4gCrrTZ.js} +15 -15
  29. package/dist/{evolveCommand-Ct4NesL3.js → evolveCommand-CMROeKeA.js} +2 -2
  30. package/dist/fileConventions-DOqD3lPS.js +34 -0
  31. package/dist/{fileTaxonomy-CJfgOllU.js → fileTaxonomy-DvDUV9wq.js} +1 -1
  32. package/dist/frameworkTableAssembly-C6ETawPR.js +2 -0
  33. package/dist/{frameworkTableAssembly-BwJVEKLr.js → frameworkTableAssembly-w-XnLa3q.js} +1 -1
  34. package/dist/{generateCommand-BDdOxhnv.js → generateCommand-DTNPGjxo.js} +1 -1
  35. package/dist/index.js +1 -1
  36. package/dist/{infoCommand-orsKJKUy.js → infoCommand-DXM868o_.js} +1 -1
  37. package/dist/inspectMetrics-CGF94puw.js +143 -0
  38. package/dist/{metaCommands-CfRLra0s.js → metaCommands-C6RFmF1r.js} +2 -2
  39. package/dist/{migrate-D3MK9BpK.js → migrate-D0F-eTlK.js} +2 -2
  40. package/dist/{pageConvention-cEiRxdab.js → pageConvention-CzUiSbtU.js} +1 -1
  41. package/dist/{privacyCommand-XejDMvmu.js → privacyCommand-DGdopOI6.js} +1 -1
  42. package/dist/{projectScaffold-mIX_DpSe.js → projectScaffold-B4dmTlwT.js} +1 -1
  43. package/dist/{projectScaffold-BIl97_E6.js → projectScaffold-EzlErR4E.js} +1 -1
  44. package/dist/{renderModeScan-D7J1B7Kw.js → renderModeScan-CcH2X1_D.js} +25 -10
  45. package/dist/{renderProfile-1OWWAAtx.js → renderProfile-Ck32Fzxr.js} +2 -2
  46. package/dist/{runtimeTrace-Bo8jWsNe.js → runtimeTrace-BPQyCmC5.js} +1 -1
  47. package/dist/{sdkgen-OZhiT2vz.js → sdkgen-Se88ifTd.js} +1 -1
  48. package/dist/serveCommand-DLc-BznW.js +2 -0
  49. package/dist/{serveCommand-YbD5VgfV.js → serveCommand-DkP3OT0W.js} +885 -868
  50. package/dist/serveEntry.js +1 -1
  51. package/dist/start-DfL3fOiN.js +3 -0
  52. package/dist/start-jw89Xbqy.js +1339 -0
  53. package/dist/startEntry.js +1 -1
  54. package/dist/{staticCommand-Dr2M6tpU.js → staticCommand-BwNEDlSU.js} +1 -1
  55. package/dist/{test-rXFq4S76.js → test-f3amja6a.js} +1 -1
  56. package/dist/updateCommand-5gFVfK5q.js +2 -0
  57. package/dist/{updateCommand-BgH6vTtq.js → updateCommand-BMk2e4ky.js} +1 -1
  58. package/dist/{webDev-BbdkzMbd.js → webDev-BgWL9gKV.js} +1233 -853
  59. package/dist/webDev-CZbTsDcH.js +2 -0
  60. package/dist/{webhooksCommand-DjE6u0r4.js → webhooksCommand-CoIO3jbj.js} +1 -1
  61. package/package.json +48 -17
  62. package/templates/AGENTS.core.md +26 -5
  63. package/templates/AGENTS.md +30 -9
  64. package/templates/agent-docs/_index.md +4 -4
  65. package/templates/agent-docs/_manifest.json +11 -11
  66. package/templates/agent-docs/cli.md +125 -14
  67. package/templates/agent-docs/data.md +210 -7
  68. package/templates/agent-docs/database/schema.md +1 -1
  69. package/templates/agent-docs/database/seedsdialects.md +1 -1
  70. package/templates/agent-docs/deployment.md +22 -3
  71. package/templates/agent-docs/internationalization.md +131 -13
  72. package/templates/agent-docs/introduction.md +46 -0
  73. package/templates/agent-docs/local-first-mobile.md +34 -7
  74. package/templates/agent-docs/plugins/ai-flows.md +1 -1
  75. package/templates/agent-docs/plugins/audit.md +5 -5
  76. package/templates/agent-docs/plugins/cdc-out.md +2 -2
  77. package/templates/agent-docs/plugins/{versioning.md → row-history.md} +22 -22
  78. package/templates/agent-docs/plugins/storage.md +2 -2
  79. package/templates/agent-docs/plugins.md +29 -7
  80. package/templates/agent-docs/reference.md +39 -2
  81. package/templates/agent-docs/routing.md +341 -47
  82. package/templates/agent-docs/schema-driven-ui.md +78 -2
  83. package/templates/agent-docs/security.md +125 -8
  84. package/templates/agent-docs/templates/apibackends.md +14 -14
  85. package/templates/agent-docs/templates/overview.md +1 -1
  86. package/templates/agent-docs/whats-new.md +100 -29
  87. package/templates/apps/api-ai/package.json +6 -7
  88. package/templates/apps/api-ai/tests/summarize.test.ts +1 -1
  89. package/templates/apps/api-auth/package.json +8 -8
  90. package/templates/apps/api-backend/package.json +7 -7
  91. package/templates/apps/api-backend-deactivation/package.json +7 -7
  92. package/templates/apps/api-backend-mail/package.json +8 -8
  93. package/templates/apps/api-backend-mariadb/package.json +9 -9
  94. package/templates/apps/api-backend-sqlite/package.json +8 -8
  95. package/templates/apps/api-backend-storage/package.json +8 -8
  96. package/templates/apps/api-cms/package.json +9 -10
  97. package/templates/apps/api-collab/package.json +8 -8
  98. package/templates/apps/api-data-advanced/package.json +8 -8
  99. package/templates/apps/api-durable/package.json +8 -8
  100. package/templates/apps/api-feature-flags/package.json +9 -9
  101. package/templates/apps/api-governance/package.json +8 -8
  102. package/templates/apps/api-kv/package.json +8 -8
  103. package/templates/apps/api-moderation/package.json +8 -8
  104. package/templates/apps/api-observability/package.json +8 -8
  105. package/templates/apps/api-ratelimit/package.json +8 -8
  106. package/templates/apps/api-rbac/package.json +8 -8
  107. package/templates/apps/api-rest/package.json +7 -7
  108. package/templates/apps/{api-versioning → api-row-history}/README.md +3 -3
  109. package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.server.ts +1 -1
  110. package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.server.ts +1 -1
  111. package/templates/apps/{api-versioning → api-row-history}/app.config.ts +3 -3
  112. package/templates/apps/{api-versioning → api-row-history}/database/schema.ts +1 -1
  113. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.server.ts +1 -1
  114. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.create.mutation.ts +1 -1
  115. package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.ts +1 -1
  116. package/templates/apps/{api-versioning → api-row-history}/package.json +8 -8
  117. package/templates/apps/api-row-history/template.json +6 -0
  118. package/templates/apps/{api-versioning → api-row-history}/tests/documents.create.test.ts +1 -1
  119. package/templates/apps/api-saas/app.config.ts +1 -0
  120. package/templates/apps/api-saas/package.json +10 -11
  121. package/templates/apps/api-saas-starter/package.json +10 -10
  122. package/templates/apps/api-search/package.json +8 -8
  123. package/templates/apps/api-status/package.json +8 -8
  124. package/templates/apps/api-webhooks/package.json +9 -9
  125. package/templates/apps/changelog/package.json +6 -6
  126. package/templates/apps/edge-functions/package.json +2 -2
  127. package/templates/apps/frontend-admin/package.json +8 -8
  128. package/templates/apps/frontend-app/package.json +9 -9
  129. package/templates/apps/frontend-auth/package.json +8 -8
  130. package/templates/apps/frontend-blank/package.json +7 -7
  131. package/templates/apps/frontend-cms/package.json +9 -9
  132. package/templates/apps/frontend-collab/package.json +10 -10
  133. package/templates/apps/frontend-collab/src/pages/page.test.tsx +10 -9
  134. package/templates/apps/frontend-collab/src/pages/page.tsx +42 -65
  135. package/templates/apps/frontend-contact/package.json +7 -7
  136. package/templates/apps/frontend-dashboard/package.json +7 -7
  137. package/templates/apps/frontend-docs/package.json +6 -7
  138. package/templates/apps/frontend-i18n/package.json +6 -6
  139. package/templates/apps/frontend-landing/package.json +6 -7
  140. package/templates/apps/frontend-portal/package.json +8 -8
  141. package/templates/apps/frontend-saas/package.json +8 -8
  142. package/templates/apps/frontend-spa/package.json +7 -7
  143. package/templates/apps/frontend-ssr/package.json +7 -7
  144. package/templates/apps/frontend-ssr-api/package.json +8 -8
  145. package/templates/apps/frontend-static-blog/package.json +6 -6
  146. package/templates/apps/frontend-status/package.json +8 -8
  147. package/templates/apps/mobile-app/package.json +4 -4
  148. package/dist/agentsMd-Bu_XQgVf.js +0 -2
  149. package/dist/apiBuild-BZ-plaQN.js +0 -2
  150. package/dist/appGraph-CM9wvUmD.js +0 -2
  151. package/dist/appGraph-Cv2W_wO5.js +0 -111
  152. package/dist/build-CFmqF39c.js +0 -721
  153. package/dist/checkCommand-DomvYDi1.js +0 -2
  154. package/dist/codegen-DiMn2KkZ.js +0 -2
  155. package/dist/dbCommand-Bnl7MSGC.js +0 -2
  156. package/dist/dev-Dz9GqA6P.js +0 -3
  157. package/dist/doctorCommand-BlciWUJb.js +0 -2
  158. package/dist/fileConventions-Cof68_BL.js +0 -33
  159. package/dist/frameworkTableAssembly-CVDB2hCq.js +0 -2
  160. package/dist/inspectMetrics-CfdKLh6t.js +0 -72
  161. package/dist/serveCommand-Bbgg7Paq.js +0 -2
  162. package/dist/start-7b_bL8Uc.js +0 -3
  163. package/dist/start-B1nH9ahf.js +0 -1150
  164. package/dist/updateCommand-BweY17z-.js +0 -2
  165. package/dist/webDev-BcRFTsMA.js +0 -2
  166. package/templates/apps/api-versioning/template.json +0 -6
  167. /package/templates/apps/{api-versioning → api-row-history}/actions/documents.asOf.action.ts +0 -0
  168. /package/templates/apps/{api-versioning → api-row-history}/actions/documents.history.action.ts +0 -0
  169. /package/templates/apps/{api-versioning → api-row-history}/mutations/documents.update.mutation.server.ts +0 -0
  170. /package/templates/apps/{api-versioning → api-row-history}/tsconfig.json +0 -0
@@ -2,39 +2,40 @@ import { t as e } from "./nodeEnvironment-cGFAj1J8.js";
2
2
  import { n as t } from "./loadEnv-D9nEOClM.js";
3
3
  import { t as n } from "./bootRefusal-pgvDxlrU.js";
4
4
  import { r } from "./appPort-B_HpJ_ck.js";
5
- import { A as i, _ as a, g as o, h as s, m as c, o as l } from "./fileConventions-Cof68_BL.js";
5
+ import { A as i, _ as a, g as o, h as s, m as c, o as l } from "./fileConventions-DOqD3lPS.js";
6
6
  import { A as u, D as d, a as f, h as p, j as m, k as h } from "./inspect-CtL_xTbu.js";
7
- import { n as g } from "./agentsMd-D6yD7IQv.js";
8
- import { c as _, p as v, t as y } from "./renderModeScan-D7J1B7Kw.js";
9
- import { t as b } from "./pageConvention-cEiRxdab.js";
7
+ import { n as g } from "./agentsMd-0l980yhL.js";
8
+ import { c as _, p as v, t as y } from "./renderModeScan-CcH2X1_D.js";
9
+ import { t as b } from "./pageConvention-CzUiSbtU.js";
10
10
  import { i as x, n as S, r as C, t as w } from "./runtimeRegistry-DMeKfTHP.js";
11
11
  import { n as T } from "./logFileSink-B4uP8pvf.js";
12
- import { basename as E, dirname as D, join as O, relative as k, resolve as A } from "node:path";
13
- import { existsSync as j, promises as M, readFileSync as N, readdirSync as P, statSync as F, unwatchFile as ee, watchFile as I } from "node:fs";
14
- import { fileURLToPath as te, pathToFileURL as L } from "node:url";
15
- import { addSink as R, createLogger as z, printReadyBlock as ne } from "@voltro/logger";
16
- import { createRequire as B } from "node:module";
17
- import { currentTraceContext as V, resolveSecret as re } from "@voltro/runtime";
12
+ import { basename as E, dirname as D, join as O, relative as k, resolve as A, sep as j } from "node:path";
13
+ import { existsSync as M, promises as N, readFileSync as P, readdirSync as F, statSync as ee, unwatchFile as te, watchFile as ne } from "node:fs";
14
+ import { fileURLToPath as re, pathToFileURL as I } from "node:url";
15
+ import { addSink as L, createLogger as R, printReadyBlock as z } from "@voltro/logger";
16
+ import { createRequire as ie } from "node:module";
17
+ import { classifyRequestOrigin as B, currentTraceContext as V, resolveOriginGuardConfig as ae, resolveSecret as oe } from "@voltro/runtime";
18
18
  import { homedir as H } from "node:os";
19
- import { FRAMEWORK_ENV_CATALOG as U, appEnvEntries as ie, checkEnvNaming as W, formatEnvErrors as ae, installEnvSnapshot as G, isEnvContract as oe, pluginEnvEntries as se, renderDotEnvExample as ce, resolveEnv as le } from "@voltro/env";
20
- import { __installPublicEnv as ue } from "@voltro/env/public";
21
- import { mkdir as de, writeFile as fe } from "node:fs/promises";
22
- import { createHash as pe } from "node:crypto";
23
- import { spawn as me } from "node:child_process";
19
+ import { FRAMEWORK_ENV_CATALOG as se, appEnvEntries as U, checkEnvNaming as ce, formatEnvErrors as le, installEnvSnapshot as W, isEnvContract as ue, pluginEnvEntries as de, renderDotEnvExample as fe, resolveEnv as pe } from "@voltro/env";
20
+ import { __installPublicEnv as me } from "@voltro/env/public";
21
+ import { mkdir as G, writeFile as he } from "node:fs/promises";
22
+ import { createHash as ge } from "node:crypto";
23
+ import { spawn as _e } from "node:child_process";
24
24
  import { createConnection as K } from "node:net";
25
- import { PassThrough as he } from "node:stream";
25
+ import { FORM_FLASH_SCRIPT_ID as ve, FORM_KEY_FIELD as ye, FORM_PATH_PREFIX as be, FORM_PATH_PREFIX as xe, FORM_REDIRECT_FIELD as Se, formDataToInput as Ce, validateFields as we } from "@voltro/client/form";
26
+ import { PassThrough as Te } from "node:stream";
26
27
  //#region src/buildToolImport.ts
27
- var ge = (e) => {
28
+ var Ee = (e) => {
28
29
  let t = e;
29
30
  return t?.code === "ERR_MODULE_NOT_FOUND" || /Cannot find (package|module)/.test(String(t?.message ?? ""));
30
- }, _e = async (e, t) => {
31
+ }, De = async (e, t) => {
31
32
  try {
32
33
  return await t();
33
34
  } catch (t) {
34
- throw ge(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
35
+ throw Ee(t) ? Error(`voltro: the build tool '${e}' is not installed.\n\nIt's an OPTIONAL dependency of @voltro/cli — needed by 'voltro dev' and 'voltro build', but excluded from a serve-only production install (that's how prod images stay lean). If you are building, reinstall WITHOUT '--no-optional' (e.g. 'pnpm install'). A production SERVE container does not need '${e}' — it boots from the precompiled bundle.`) : t;
35
36
  }
36
- }, q = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", ve = (e, t) => t ? `${e} | undefined` : e, ye = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${ve(t.tsType, t.optional)}`).join("\n"), be = async (e, t) => {
37
- let n = ye(t, () => !0), r = `${q}
37
+ }, Oe = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", ke = (e, t) => t ? `${e} | undefined` : e, Ae = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${ke(t.tsType, t.optional)}`).join("\n"), je = async (e, t) => {
38
+ let n = Ae(t, () => !0), r = `${Oe}
38
39
  import '@voltro/env/server'
39
40
 
40
41
  declare module '@voltro/env/server' {
@@ -43,9 +44,9 @@ ${n.length > 0 ? n : " // (no variables declared)"}
43
44
  }
44
45
  }
45
46
  `;
46
- await fe(O(e, "env.generated.d.ts"), r, "utf8");
47
- }, xe = async (e, t) => {
48
- let n = ye(t, (e) => e === "public"), r = `${q}
47
+ await he(O(e, "env.generated.d.ts"), r, "utf8");
48
+ }, Me = async (e, t) => {
49
+ let n = Ae(t, (e) => e === "public"), r = `${Oe}
49
50
  import '@voltro/env/public'
50
51
 
51
52
  declare module '@voltro/env/public' {
@@ -54,9 +55,9 @@ ${n.length > 0 ? n : " // (no public variables declared)"}
54
55
  }
55
56
  }
56
57
  `, i = O(e, "src");
57
- await de(i, { recursive: !0 }), await fe(O(i, "voltro-env.d.ts"), r, "utf8");
58
- }, Se = async (e, t) => {
59
- let n = `${q}
58
+ await G(i, { recursive: !0 }), await he(O(i, "voltro-env.d.ts"), r, "utf8");
59
+ }, Ne = async (e, t) => {
60
+ let n = `${Oe}
60
61
  import { __installPublicEnv } from '@voltro/env/public'
61
62
 
62
63
  export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
@@ -64,14 +65,14 @@ export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
64
65
  // Set the browser/SSR-shared global the \`publicEnv\` accessor reads.
65
66
  __installPublicEnv(publicEnvValues)
66
67
  `;
67
- await de(e, { recursive: !0 }), await fe(O(e, "env.public.ts"), n, "utf8");
68
- }, Ce = async (e) => {
69
- let t = oe(e.rawEnv) ? e.rawEnv : void 0, n = await le({
68
+ await G(e, { recursive: !0 }), await he(O(e, "env.public.ts"), n, "utf8");
69
+ }, Pe = async (e) => {
70
+ let t = ue(e.rawEnv) ? e.rawEnv : void 0, n = await pe({
70
71
  contract: t,
71
- resolveSecret: re
72
- }), r = [...n.errors, ...W(t, e.appType)];
73
- if (r.length > 0) throw Error(ae(r));
74
- G(n.values), e.appType === "web" && ue(n.publicValues);
72
+ resolveSecret: oe
73
+ }), r = [...n.errors, ...ce(t, e.appType)];
74
+ if (r.length > 0) throw Error(le(r));
75
+ W(n.values), e.appType === "web" && me(n.publicValues);
75
76
  let i = t ? Object.keys(t.vars).length : 0;
76
77
  if (i > 0) {
77
78
  let r = Object.keys(n.publicValues).length;
@@ -83,20 +84,20 @@ __installPublicEnv(publicEnvValues)
83
84
  n.length > 0 && e.log.warn(`env: ${n.length} secret var(s) declared on a web app — secrets are reachable only from server-side render code and are NEVER bundled. Prefer declaring secrets on the api.`, { keys: n });
84
85
  }
85
86
  }
86
- return e.generateTypes && t && (e.appType === "api" ? await be(e.root, t) : await xe(e.root, t)), {
87
+ return e.generateTypes && t && (e.appType === "api" ? await je(e.root, t) : await Me(e.root, t)), {
87
88
  resolved: n,
88
89
  contract: t
89
90
  };
90
- }, we = (e) => {
91
- let t = ie(e.contract), n = (e.plugins ?? []).flatMap((e) => se(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : U, i = /* @__PURE__ */ new Set(), a = [];
91
+ }, q = (e) => {
92
+ let t = U(e.contract), n = (e.plugins ?? []).flatMap((e) => de(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : se, i = /* @__PURE__ */ new Set(), a = [];
92
93
  for (let e of [
93
94
  ...t,
94
95
  ...n,
95
96
  ...r
96
97
  ]) i.has(e.key) || (i.add(e.key), a.push(e));
97
98
  return a;
98
- }, Te = (e, t, n = (e) => process.env[e]) => {
99
- let r = we(t).map((e) => {
99
+ }, Fe = (e, t, n = (e) => process.env[e]) => {
100
+ let r = q(t).map((e) => {
100
101
  let t = n(e.key) !== void 0;
101
102
  return {
102
103
  ...e,
@@ -113,22 +114,22 @@ __installPublicEnv(publicEnvValues)
113
114
  missingRequired: r.filter((e) => e.required && !e.isSet && e.default === void 0).length
114
115
  }
115
116
  };
116
- }, Ee = (e, t) => {
117
- let n = we({
117
+ }, Ie = (e, t) => {
118
+ let n = q({
118
119
  ...e,
119
120
  includeFramework: !1
120
121
  });
121
- return ce(n, {
122
+ return fe(n, {
122
123
  includeFramework: e.includeFramework !== !1,
123
124
  ...t ? { header: t } : {}
124
125
  });
125
- }, J = async (e, t) => {
126
+ }, Le = async (e, t) => {
126
127
  let n = e;
127
128
  for (;;) {
128
129
  let e = O(n, "node_modules", t);
129
130
  try {
130
- if ((await M.stat(e)).isDirectory()) {
131
- let t = await M.realpath(e);
131
+ if ((await N.stat(e)).isDirectory()) {
132
+ let t = await N.realpath(e);
132
133
  return t.includes("/node_modules/") ? null : t;
133
134
  }
134
135
  } catch {}
@@ -136,10 +137,10 @@ __installPublicEnv(publicEnvValues)
136
137
  if (r === n) return null;
137
138
  n = r;
138
139
  }
139
- }, De = async (e) => {
140
+ }, Re = async (e) => {
140
141
  let t;
141
142
  try {
142
- let n = await M.readFile(O(e, "package.json"), "utf8"), r = JSON.parse(n);
143
+ let n = await N.readFile(O(e, "package.json"), "utf8"), r = JSON.parse(n);
143
144
  t = Object.keys({
144
145
  ...r.dependencies,
145
146
  ...r.devDependencies
@@ -148,11 +149,11 @@ __installPublicEnv(publicEnvValues)
148
149
  return [];
149
150
  }
150
151
  return (await Promise.all(t.map(async (t) => {
151
- let n = await J(e, t);
152
+ let n = await Le(e, t);
152
153
  if (n === null) return null;
153
154
  let r = O(n, "src");
154
155
  try {
155
- if (!(await M.stat(r)).isDirectory()) return null;
156
+ if (!(await N.stat(r)).isDirectory()) return null;
156
157
  } catch {
157
158
  return null;
158
159
  }
@@ -161,11 +162,11 @@ __installPublicEnv(publicEnvValues)
161
162
  dir: r
162
163
  };
163
164
  }))).filter((e) => e !== null);
164
- }, Oe = 500, ke = (e, t, n = {}) => {
165
+ }, ze = 500, Be = (e, t, n = {}) => {
165
166
  if (e.length === 0) return () => {};
166
167
  let r = (e) => n.root ? k(n.root, e) : e, i = !1, a = (e) => {
167
168
  i || (i = !0, t.warn(`.env changed (${r(e)}) — hard-restarting: process.env is read once at boot, a reload would keep stale values`, { file: r(e) }), Promise.resolve().then(() => n.onBeforeRestart?.()).catch((e) => t.warn(".env restart: onBeforeRestart failed (continuing)", {}, e)).finally(() => {
168
- let e = me(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
169
+ let e = _e(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
169
170
  stdio: "inherit",
170
171
  env: process.env,
171
172
  cwd: n.cwd ?? process.cwd()
@@ -179,22 +180,22 @@ __installPublicEnv(publicEnvValues)
179
180
  });
180
181
  }));
181
182
  };
182
- for (let t of e) I(t, { interval: Oe }, (e, n) => {
183
+ for (let t of e) ne(t, { interval: ze }, (e, n) => {
183
184
  e.mtimeMs !== n.mtimeMs && a(t);
184
185
  });
185
186
  return t.info("watching .env files for changes", {
186
187
  files: e.map(r),
187
- intervalMs: Oe
188
+ intervalMs: ze
188
189
  }), () => {
189
- for (let t of e) ee(t);
190
+ for (let t of e) te(t);
190
191
  };
191
- }, Ae = [{
192
+ }, Ve = [{
192
193
  host: "127.0.0.1",
193
194
  family: "IPv4"
194
195
  }, {
195
196
  host: "::1",
196
197
  family: "IPv6"
197
- }], je = (e, t, n) => new Promise((r) => {
198
+ }], J = (e, t, n) => new Promise((r) => {
198
199
  let i = !1, a = (e) => {
199
200
  if (!i) {
200
201
  i = !0;
@@ -208,10 +209,10 @@ __installPublicEnv(publicEnvValues)
208
209
  port: t
209
210
  });
210
211
  o.once("connect", () => a(!0)), o.once("error", () => a(!1)), o.setTimeout(n, () => a(!1));
211
- }), Me = async (e, t = 400) => ({ families: (await Promise.all(Ae.map(async (n) => ({
212
+ }), He = async (e, t = 400) => ({ families: (await Promise.all(Ve.map(async (n) => ({
212
213
  family: n.family,
213
- taken: await je(n.host, e, t)
214
- })))).filter((e) => e.taken).map((e) => e.family) }), Ne = (e, t, n) => [
214
+ taken: await J(n.host, e, t)
215
+ })))).filter((e) => e.taken).map((e) => e.family) }), Ue = (e, t, n) => [
215
216
  `${t}: port ${e} is already being served (${n.join(" + ")}).`,
216
217
  "",
217
218
  " Refusing to start. This is NOT a spurious check — a second listener can",
@@ -226,26 +227,26 @@ __installPublicEnv(publicEnvValues)
226
227
  "",
227
228
  " Then re-run. To use a different port instead, change `port` in",
228
229
  " app.config.ts."
229
- ].join("\n"), Pe = async (e, t) => {
230
- let { families: r } = await Me(e);
231
- if (r.length !== 0) throw n(Ne(e, t, r));
232
- }, Fe = (e) => e === "effect" || e.startsWith("@effect/") || e.startsWith("@voltro/") || e === "react" || e === "react-dom", Y = /(^|\/)(\.bin|\.cache|\.pnpm-store|dist|build)(\/|$)/, Ie = (e) => {
230
+ ].join("\n"), We = async (e, t) => {
231
+ let { families: r } = await He(e);
232
+ if (r.length !== 0) throw n(Ue(e, t, r));
233
+ }, Ge = (e) => e === "effect" || e.startsWith("@effect/") || e.startsWith("@voltro/") || e === "react" || e === "react-dom", Ke = /(^|\/)(\.bin|\.cache|\.pnpm-store|dist|build)(\/|$)/, qe = (e) => {
233
234
  let t = [], n = e;
234
235
  for (let e = 0; e < 12; e++) {
235
236
  let e = O(n, "node_modules");
236
- j(e) && t.push(e);
237
+ M(e) && t.push(e);
237
238
  let r = D(n);
238
239
  if (r === n) break;
239
240
  n = r;
240
241
  }
241
242
  return t;
242
- }, Le = (e) => {
243
+ }, Je = (e) => {
243
244
  let t = /* @__PURE__ */ new Set([e]), n = e;
244
245
  for (let e = 0; e < 12; e++) {
245
246
  for (let e of ["pnpm-workspace.yaml", "pnpm-workspace.yml"]) {
246
247
  let r;
247
248
  try {
248
- r = N(O(n, e), "utf8");
249
+ r = P(O(n, e), "utf8");
249
250
  } catch {
250
251
  continue;
251
252
  }
@@ -256,7 +257,7 @@ __installPublicEnv(publicEnvValues)
256
257
  if (i === "" || i.includes("*")) continue;
257
258
  let a;
258
259
  try {
259
- a = P(O(n, i), { withFileTypes: !0 });
260
+ a = F(O(n, i), { withFileTypes: !0 });
260
261
  } catch {
261
262
  continue;
262
263
  }
@@ -266,7 +267,7 @@ __installPublicEnv(publicEnvValues)
266
267
  for (let e of ["packages", "apps"]) {
267
268
  let r;
268
269
  try {
269
- r = P(O(n, e), { withFileTypes: !0 });
270
+ r = F(O(n, e), { withFileTypes: !0 });
270
271
  } catch {
271
272
  continue;
272
273
  }
@@ -277,17 +278,17 @@ __installPublicEnv(publicEnvValues)
277
278
  n = e;
278
279
  }
279
280
  return [...t];
280
- }, Re = (e) => {
281
+ }, Ye = (e) => {
281
282
  let t = [];
282
- for (let n of Le(e)) {
283
+ for (let n of Je(e)) {
283
284
  let e = O(n, "node_modules", "@voltro"), r;
284
285
  try {
285
- r = P(e);
286
+ r = F(e);
286
287
  } catch {
287
288
  continue;
288
289
  }
289
290
  for (let n of r) {
290
- let r = O(e, n), i = ze(r);
291
+ let r = O(e, n), i = Xe(r);
291
292
  i !== void 0 && t.push({
292
293
  pkg: `@voltro/${n}`,
293
294
  version: i,
@@ -296,27 +297,27 @@ __installPublicEnv(publicEnvValues)
296
297
  }
297
298
  }
298
299
  return t;
299
- }, ze = (e) => {
300
+ }, Xe = (e) => {
300
301
  try {
301
- let t = JSON.parse(N(O(e, "package.json"), "utf8"));
302
+ let t = JSON.parse(P(O(e, "package.json"), "utf8"));
302
303
  return typeof t.version == "string" ? t.version : void 0;
303
304
  } catch {
304
305
  return;
305
306
  }
306
- }, X = (e) => {
307
+ }, Ze = (e) => {
307
308
  let t = [], n;
308
309
  try {
309
- n = P(e);
310
+ n = F(e);
310
311
  } catch {
311
312
  return t;
312
313
  }
313
314
  for (let r of n) {
314
- if (r.startsWith(".") || Y.test(r)) continue;
315
+ if (r.startsWith(".") || Ke.test(r)) continue;
315
316
  let n = O(e, r);
316
317
  if (r.startsWith("@")) {
317
318
  let e;
318
319
  try {
319
- e = P(n);
320
+ e = F(n);
320
321
  } catch {
321
322
  continue;
322
323
  }
@@ -327,7 +328,7 @@ __installPublicEnv(publicEnvValues)
327
328
  continue;
328
329
  }
329
330
  try {
330
- if (!F(n).isDirectory()) continue;
331
+ if (!ee(n).isDirectory()) continue;
331
332
  } catch {
332
333
  continue;
333
334
  }
@@ -337,17 +338,17 @@ __installPublicEnv(publicEnvValues)
337
338
  });
338
339
  }
339
340
  return t;
340
- }, Be = (e) => {
341
+ }, Qe = (e) => {
341
342
  let t = /* @__PURE__ */ new Map(), n = (e, n, r) => {
342
- if (!Fe(e)) return;
343
+ if (!Ge(e)) return;
343
344
  let i = t.get(e) ?? /* @__PURE__ */ new Map();
344
345
  i.has(n) || i.set(n, r), t.set(e, i);
345
346
  };
346
- for (let t of Ie(e)) for (let { pkg: e, dir: r } of X(t)) {
347
- let t = ze(r);
347
+ for (let t of qe(e)) for (let { pkg: e, dir: r } of Ze(t)) {
348
+ let t = Xe(r);
348
349
  t !== void 0 && n(e, t, r);
349
350
  }
350
- for (let { pkg: t, version: r, dir: i } of Re(e)) n(t, r, i);
351
+ for (let { pkg: t, version: r, dir: i } of Ye(e)) n(t, r, i);
351
352
  let r = [];
352
353
  for (let [n, i] of t) i.size < 2 || r.push({
353
354
  pkg: n,
@@ -355,7 +356,7 @@ __installPublicEnv(publicEnvValues)
355
356
  paths: [...i.values()].map((t) => k(e, t)).sort()
356
357
  });
357
358
  return r.sort((e, t) => e.pkg.localeCompare(t.pkg));
358
- }, Ve = (e) => {
359
+ }, $e = (e) => {
359
360
  if (e.length !== 0) return [
360
361
  `• ${e.length} package(s) resolved at more than one version:`,
361
362
  ...e.flatMap((e) => [` ${e.pkg} — ${e.versions.join(", ")}`, ...e.paths.map((e) => ` ${e}`)]),
@@ -373,11 +374,11 @@ __installPublicEnv(publicEnvValues)
373
374
  " instrument), then reinstall. Do not silence the generated file — it is where",
374
375
  " a genuine mistake in your own descriptors surfaces."
375
376
  ].join("\n");
376
- }, He = (e) => {
377
+ }, et = (e) => {
377
378
  let t = /* @__PURE__ */ new Map();
378
- for (let n of Ie(e)) for (let { pkg: e, dir: r } of X(n)) {
379
+ for (let n of qe(e)) for (let { pkg: e, dir: r } of Ze(n)) {
379
380
  if (!e.startsWith("@voltro/")) continue;
380
- let n = ze(r);
381
+ let n = Xe(r);
381
382
  n !== void 0 && !t.has(e) && t.set(e, n);
382
383
  }
383
384
  if (t.size < 2) return;
@@ -392,7 +393,7 @@ __installPublicEnv(publicEnvValues)
392
393
  version: t
393
394
  })).sort((e, t) => e.pkg.localeCompare(t.pkg))
394
395
  };
395
- }, Ue = (e) => {
396
+ }, tt = (e) => {
396
397
  if (e !== void 0) return [
397
398
  `• ${e.behind.length} @voltro/* package(s) are not on ${e.majority}:`,
398
399
  ...e.behind.map((e) => ` ${e.pkg} ${e.version}`),
@@ -410,59 +411,59 @@ __installPublicEnv(publicEnvValues)
410
411
  " its pattern: the one that produced this report was `@voltro/[a-z-]+`,",
411
412
  " which silently skips `@voltro/i18n` because the name contains digits."
412
413
  ].join("\n");
413
- }, We = (e, t) => {
414
- let n = He(e);
414
+ }, nt = (e, t) => {
415
+ let n = et(e);
415
416
  n !== void 0 && t.warn?.(`@voltro/* version skew: ${n.behind.length} package(s) are not on ${n.majority}`, {
416
417
  majority: n.majority,
417
418
  behind: n.behind.map((e) => `${e.pkg}@${e.version}`),
418
419
  fix: "the framework ships in lockstep; bump the listed packages and reinstall"
419
420
  });
420
- }, Ge = z({ scope: "vite" }), Ke = /\x1b\[[0-9;]*m/g, qe = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, Je = (e) => e.replace(Ke, "").replace(qe, "").trim(), Ye = /proxy error/i, Xe = [
421
+ }, rt = R({ scope: "vite" }), it = /\x1b\[[0-9;]*m/g, at = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, ot = (e) => e.replace(it, "").replace(at, "").trim(), st = /proxy error/i, ct = [
421
422
  "ECONNREFUSED",
422
423
  "ECONNRESET",
423
424
  "ECONNABORTED",
424
425
  "EPIPE",
425
426
  "ETIMEDOUT"
426
- ], Ze = (e, t = 0) => {
427
+ ], lt = (e, t = 0) => {
427
428
  if (e == null || t > 5) return !1;
428
429
  let n = e;
429
- return typeof n.code == "string" && Xe.includes(n.code) || typeof n.message == "string" && Xe.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => Ze(e, t + 1)) ? !0 : Ze(n.cause, t + 1);
430
- }, Qe = 4e3, $e = () => {
430
+ return typeof n.code == "string" && ct.includes(n.code) || typeof n.message == "string" && ct.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => lt(e, t + 1)) ? !0 : lt(n.cause, t + 1);
431
+ }, ut = 4e3, dt = () => {
431
432
  let e = /* @__PURE__ */ new Set(), t = 0, n = {
432
433
  hasWarned: !1,
433
434
  info: (e) => {
434
- let t = Je(e);
435
- t.length !== 0 && Ge.info(t);
435
+ let t = ot(e);
436
+ t.length !== 0 && rt.info(t);
436
437
  },
437
438
  warn: (e) => {
438
439
  n.hasWarned = !0;
439
- let t = Je(e);
440
- t.length !== 0 && Ge.warn(t);
440
+ let t = ot(e);
441
+ t.length !== 0 && rt.warn(t);
441
442
  },
442
443
  warnOnce: (t) => {
443
- let r = Je(t);
444
- e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && Ge.warn(r));
444
+ let r = ot(t);
445
+ e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && rt.warn(r));
445
446
  },
446
447
  error: (e, n) => {
447
- let r = Je(e), i = n?.error;
448
+ let r = ot(e), i = n?.error;
448
449
  if (r.length !== 0) {
449
- if (Ye.test(r) && Ze(i)) {
450
+ if (st.test(r) && lt(i)) {
450
451
  let e = Date.now();
451
- e - t > Qe && (t = e, Ge.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
452
+ e - t > ut && (t = e, rt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
452
453
  return;
453
454
  }
454
- Ge.error(r, {}, i);
455
+ rt.error(r, {}, i);
455
456
  }
456
457
  },
457
458
  clearScreen: () => {},
458
459
  hasErrorLogged: (e) => !1
459
460
  };
460
461
  return n;
461
- }, et = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), tt = (e) => {
462
+ }, ft = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), pt = (e) => {
462
463
  try {
463
464
  let t = O(e, "tsconfig.json");
464
- if (!j(t)) return [];
465
- let n = JSON.parse(et(N(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = n.baseUrl ?? ".", a = A(e, i), o = [];
465
+ if (!M(t)) return [];
466
+ let n = JSON.parse(ft(P(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = n.baseUrl ?? ".", a = A(e, i), o = [];
466
467
  for (let [e, t] of Object.entries(r)) {
467
468
  let n = t[0];
468
469
  if (!n) continue;
@@ -484,12 +485,12 @@ __installPublicEnv(publicEnvValues)
484
485
  } catch {
485
486
  return [];
486
487
  }
487
- }, nt = (e = process.env) => {
488
+ }, mt = (e = process.env) => {
488
489
  let t = e.VOLTRO_DEV_SSR_COMPILE_CONCURRENCY;
489
490
  if (t === void 0 || t.trim() === "") return 4;
490
491
  let n = Number(t);
491
492
  return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
492
- }, rt = (e) => {
493
+ }, ht = (e) => {
493
494
  let t = Math.max(1, Math.floor(e)), n = 0, r = [], i = () => n < t ? (n++, Promise.resolve()) : new Promise((e) => r.push(e)), a = () => {
494
495
  let e = r.shift();
495
496
  e ? e() : n--;
@@ -507,8 +508,8 @@ __installPublicEnv(publicEnvValues)
507
508
  return n;
508
509
  }
509
510
  };
510
- }, it = (e) => {
511
- let t = rt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
511
+ }, gt = (e) => {
512
+ let t = ht(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
512
513
  return {
513
514
  load: (i, a) => {
514
515
  if (r.has(i)) return a();
@@ -538,7 +539,340 @@ __installPublicEnv(publicEnvValues)
538
539
  return r.size;
539
540
  }
540
541
  };
541
- }, at = (e) => {
542
+ }, _t = 1048576, vt = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), yt = (e) => JSON.stringify(e).replace(/</g, "\\u003c"), bt = (e, t) => {
543
+ let n = `<script type="application/json" id="${ve}">${yt(t)}<\/script>`;
544
+ return e.includes("</body>") ? e.replace("</body>", `${n}</body>`) : e + n;
545
+ }, xt = (e) => {
546
+ let t = Object.entries(e.errors).map(([e, t]) => `<li><strong>${vt(e)}</strong>: ${vt(t)}</li>`).join("");
547
+ return `<!doctype html><html><head><meta charset="utf-8"><title>Form submission failed</title></head><body><h1>Submission failed</h1>${e.formError === void 0 ? "" : `<p>${vt(e.formError)}</p>`}<ul>${t}</ul><p><a href="javascript:history.back()">Go back</a> to correct the form.</p></body></html>`;
548
+ }, Y = (e, t, n, r = "text/plain; charset=utf-8") => {
549
+ e.statusCode = t, e.setHeader("content-type", r), e.end(n);
550
+ }, St = (e, t, n) => {
551
+ e.setHeader("cache-control", "no-store"), Y(e, t, n, "text/html; charset=utf-8");
552
+ }, Ct = (e) => {
553
+ if (e !== void 0 && e !== "" && !(!e.startsWith("/") || e.startsWith("//") || e.includes("\\"))) return e;
554
+ }, wt = (e) => {
555
+ let t = e.referer;
556
+ if (t !== void 0) try {
557
+ let e = new URL(t);
558
+ return e.pathname + e.search;
559
+ } catch {
560
+ return;
561
+ }
562
+ }, Tt = (e) => new Promise((t) => {
563
+ let n = [], r = 0;
564
+ e.on("data", (i) => {
565
+ if (r += i.length, r > _t) {
566
+ e.removeAllListeners("data"), e.removeAllListeners("end"), t({ ok: !1 });
567
+ return;
568
+ }
569
+ n.push(i);
570
+ }), e.on("end", () => t({
571
+ ok: !0,
572
+ body: Buffer.concat(n).toString("utf8")
573
+ })), e.on("error", () => t({ ok: !1 }));
574
+ }), Et = (e) => {
575
+ let t = {};
576
+ for (let [n, r] of Object.entries(e.headers)) typeof r == "string" ? t[n.toLowerCase()] = r : Array.isArray(r) && (t[n.toLowerCase()] = r.join(", "));
577
+ return t;
578
+ }, Dt = (e) => {
579
+ let t = e.originGuard ?? ae(void 0, process.env);
580
+ return async (n, r, i) => {
581
+ let a = (n.url ?? "/").split("?")[0];
582
+ if (!a.startsWith(be)) return !1;
583
+ if (n.method !== "POST") return r.setHeader("allow", "POST"), Y(r, 405, "method not allowed — a /form/* endpoint accepts native form POSTs only"), !0;
584
+ let o = Et(n);
585
+ if (!B({
586
+ headers: o,
587
+ config: t
588
+ }).allowed) return Y(r, 403, "origin not allowed"), !0;
589
+ if ((o["content-type"] ?? "").includes("multipart/form-data")) return Y(r, 415, "file uploads need JavaScript — the no-JS form path accepts application/x-www-form-urlencoded only"), !0;
590
+ let s = await Tt(n);
591
+ if (!s.ok) return Y(r, 413, `form body exceeds ${_t} bytes`), !0;
592
+ let c = new URLSearchParams(s.body), l = decodeURIComponent(a.slice(be.length)), u = (await e.loadDescriptors())?.[l];
593
+ if (u === void 0 || u.kind !== "mutation") return Y(r, 404, `no mutation '${l}' — /form/* serves declared mutations only`), !0;
594
+ let d = c.get(ye) ?? l, f = Ct(c.get(Se) ?? void 0), p = [];
595
+ for (let [e, t] of c) e !== ye && e !== Se && p.push([e, t]);
596
+ let m = u.input;
597
+ if (m === void 0) return Y(r, 404, `mutation '${l}' carries no input schema — the no-JS path cannot map its POST`), !0;
598
+ let h = Ce(m, p), g = we(m, h), _ = async (t) => {
599
+ let n = wt(o);
600
+ if (n !== void 0) {
601
+ if (i !== void 0) {
602
+ i(n, t);
603
+ return;
604
+ }
605
+ let a = await e.renderErrorPage({
606
+ path: n,
607
+ headers: o,
608
+ flash: t
609
+ });
610
+ if (a !== void 0) {
611
+ St(r, 422, bt(a, t));
612
+ return;
613
+ }
614
+ }
615
+ St(r, 422, xt(t));
616
+ };
617
+ if (!g.valid) return await _({
618
+ formKey: d,
619
+ values: h,
620
+ errors: g.errors
621
+ }), !0;
622
+ let v = e.rpcQuery(o.cookie, o);
623
+ if (v === void 0) return Y(r, 503, `api '${e.apiName ?? "?"}' has no server-side origin — the no-JS form path forwards over POST /rpc; set VOLTRO_API_ORIGIN (or apis.<name>.serverUrl) as for SSR loaders`), !0;
624
+ try {
625
+ await v(l, h);
626
+ } catch (e) {
627
+ let t = e.voltroError;
628
+ return await _({
629
+ formKey: d,
630
+ values: h,
631
+ errors: {},
632
+ formError: t?.message ?? t?._tag ?? "The server rejected this submission. Please try again."
633
+ }), !0;
634
+ }
635
+ let y = f ?? wt(o) ?? "/";
636
+ return r.statusCode = 303, r.setHeader("location", y), r.end(), !0;
637
+ };
638
+ }, Ot = /^\s*(?:import|export)\s[^;'"]*?['"]([^'"]+)['"]/gm, kt = [
639
+ "",
640
+ ".tsx",
641
+ ".ts",
642
+ ".jsx",
643
+ ".js",
644
+ "/index.tsx",
645
+ "/index.ts"
646
+ ], At = (e) => /\.island\.(tsx|ts|jsx|js)$/.test(e), jt = ["@voltro/web", "@voltro/i18n"], Mt = ["@voltro/client", "@voltro/ui"], Nt = (e, t) => e === t || e.startsWith(`${t}/`), Pt = (e) => e !== "@voltro/web/islands" && jt.some((t) => Nt(e, t)), Ft = (e) => {
647
+ let t = [];
648
+ for (let n of e.matchAll(Ot)) t.push(n[1]);
649
+ return t;
650
+ }, It = async (e, t) => {
651
+ let n = A(D(e), t);
652
+ for (let e of kt) {
653
+ let t = n + e;
654
+ try {
655
+ if ((await N.stat(t)).isFile()) return t;
656
+ } catch {}
657
+ }
658
+ }, Lt = async (e, t) => {
659
+ let n = O(e, "src", "pages", t), r = /* @__PURE__ */ new Set(), i = [], a = !1, o = [], s = async (t, n) => {
660
+ let c = `${t}\u0000${n ? "i" : "p"}`;
661
+ if (r.has(c)) return;
662
+ r.add(c);
663
+ let l;
664
+ try {
665
+ l = await N.readFile(t, "utf8");
666
+ } catch {
667
+ return;
668
+ }
669
+ for (let r of Ft(l)) {
670
+ if (n) {
671
+ if (Pt(r)) {
672
+ o.push([k(e, t).split(j).join("/"), r]);
673
+ continue;
674
+ }
675
+ if (Mt.some((e) => Nt(r, e))) {
676
+ a = !0;
677
+ continue;
678
+ }
679
+ }
680
+ if (!r.startsWith(".")) continue;
681
+ let c = await It(t, r);
682
+ if (c === void 0) continue;
683
+ let l = n || At(c);
684
+ if (!n && At(c)) {
685
+ let t = k(e, c).split(j).join("/");
686
+ i.includes(t) || i.push(t);
687
+ }
688
+ await s(c, l);
689
+ }
690
+ };
691
+ return await s(n, At(n)), At(n) && i.unshift(k(e, n).split(j).join("/")), {
692
+ islandFiles: i,
693
+ usesClient: a,
694
+ violations: o
695
+ };
696
+ }, Rt = (e) => {
697
+ let t = /^export const interactive\s*=\s*['"](full|islands|none)['"]/m.exec(e);
698
+ return t === null ? void 0 : t[1];
699
+ }, zt = (e) => {
700
+ let t = e.indexOf("</head>"), n = t === -1 ? e : e.slice(0, t), r = [];
701
+ for (let e of n.matchAll(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi)) {
702
+ let t = e[1] ?? "";
703
+ /\bsrc\s*=/.test(t) || /type\s*=\s*["']module["']/.test(t) || r.push(e[0]);
704
+ }
705
+ return r.map((e) => ` ${e}`).join("\n");
706
+ }, Bt = (e) => [...e.matchAll(/<link\b[^>]*\brel\s*=\s*["']stylesheet["'][^>]*>/gi)].map((e) => e[0]), Vt = (e, t) => {
707
+ let n = Bt(t).filter((t) => !e.includes(t));
708
+ if (n.length === 0) return e;
709
+ let r = n.map((e) => ` ${e}`).join("\n");
710
+ return e.includes("</head>") ? e.replace("</head>", `${r}\n </head>`) : e + r;
711
+ }, Ht = (e) => {
712
+ let t = e.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
713
+ return t === "" ? "root" : t;
714
+ }, Ut = class extends Error {
715
+ constructor(e, t) {
716
+ let n = t.map(([e, t]) => ` ${e} imports '${t}'`).join("\n");
717
+ super(`interactive: 'islands' page '${e}' has island code importing the framework barrel:\n${n}\n\nAn island hydrates in its own provider-less root — router hooks, <Link> and useT() throw there, and the '@voltro/web' barrel additionally pulls the Effect runtime into the slim islands entry (the bytes this mode exists to shed).\n\nFix: import island()/hydration APIs from '@voltro/web/islands' (the react-only subpath), move router/i18n-dependent UI out of the island, and keep island files to react + relative browser-safe imports. '@voltro/client' IS allowed — a useSubscription island gets the client boot automatically.`), this.name = "IslandsEntryViolation";
718
+ }
719
+ }, Wt = async (e) => {
720
+ let t = O(e.webRoot, ".framework", "island-shells"), n = [];
721
+ if (e.pages.length === 0) return n;
722
+ await N.mkdir(t, { recursive: !0 });
723
+ for (let r of e.pages) {
724
+ let i = await Lt(e.webRoot, r.file);
725
+ if (i.violations.length > 0) throw new Ut(r.pattern, i.violations);
726
+ let a = Ht(r.pattern), o = `island-shells/${a}.tsx`, s = `island-shells/${a}.html`, c = i.islandFiles.map((e) => `import '../../${e}'`).join("\n"), l = i.usesClient ? [
727
+ `// GENERATED by voltro — the islands entry for '${r.pattern}' (client boot:`,
728
+ "// an island here imports @voltro/client, so the roots get a live runtime).",
729
+ ...e.apiImports ?? [],
730
+ "import { VoltroRuntimeProvider } from '@voltro/web/runtime'",
731
+ "import { hydrateIslandsOnPage } from '@voltro/web/islands'",
732
+ c,
733
+ "hydrateIslandsOnPage({",
734
+ " wrap: (children) => (",
735
+ ` <VoltroRuntimeProvider apis={${e.apiEntriesLiteral ?? "{}"}}>{children}</VoltroRuntimeProvider>`,
736
+ " ),",
737
+ "})",
738
+ ""
739
+ ].join("\n") : [
740
+ `// GENERATED by voltro — the slim islands entry for '${r.pattern}'.`,
741
+ "// react + the island runtime + this page's islands; no router, no",
742
+ "// Effect runtime, no subscription cache.",
743
+ "import { hydrateIslandsOnPage } from '@voltro/web/islands'",
744
+ c,
745
+ "hydrateIslandsOnPage()",
746
+ ""
747
+ ].join("\n"), u = [
748
+ "<!doctype html>",
749
+ "<html lang=\"en\">",
750
+ " <head>",
751
+ " <meta charset=\"UTF-8\" />",
752
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />",
753
+ ...e.headSnippets !== void 0 && e.headSnippets !== "" ? [e.headSnippets] : [],
754
+ " </head>",
755
+ " <body>",
756
+ " <div id=\"root\"></div>",
757
+ ` <script type="module" src="/island-shells/${a}.tsx"><\/script>`,
758
+ " </body>",
759
+ "</html>",
760
+ ""
761
+ ].join("\n");
762
+ await N.writeFile(O(t, `${a}.tsx`), l), await N.writeFile(O(t, `${a}.html`), u), n.push({
763
+ pattern: r.pattern,
764
+ name: a,
765
+ htmlFile: s,
766
+ entryFile: o,
767
+ usesClient: i.usesClient
768
+ });
769
+ }
770
+ return n;
771
+ }, Gt = class extends Error {
772
+ _voltroDeferral = !0;
773
+ constructor(e) {
774
+ super(e), this.name = "DeferralNotSupportedError";
775
+ }
776
+ }, Kt = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, qt = (e) => {
777
+ if (!(e instanceof Error)) return;
778
+ let t = e._voltroControl;
779
+ if (t === "redirect") {
780
+ let { location: t, status: n } = e;
781
+ return typeof t == "string" ? {
782
+ status: n === 307 || n === 308 ? n : 303,
783
+ headers: {
784
+ location: t,
785
+ "x-voltro-rendered-by": "loader-redirect"
786
+ },
787
+ body: ""
788
+ } : void 0;
789
+ }
790
+ if (t === "not-found") return {
791
+ status: 404,
792
+ headers: {
793
+ "content-type": "text/plain; charset=utf-8",
794
+ "x-voltro-rendered-by": "loader-not-found"
795
+ },
796
+ body: "not found"
797
+ };
798
+ }, Jt = (e) => {
799
+ let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
800
+ for (let [n, o] of Object.entries(e.segmentLoaderData)) {
801
+ let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
802
+ r[e] = s.renderData, i[e] = s.stateData, s.deferredIds && (a[e] = s.deferredIds);
803
+ }
804
+ let o = n.deferredIds !== void 0 || Object.keys(a).length > 0;
805
+ if (o) try {
806
+ t.assertDeferralSupported({
807
+ page: e.page,
808
+ renderMode: e.renderMode,
809
+ interactive: e.interactive,
810
+ ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
811
+ });
812
+ } catch (e) {
813
+ throw new Gt(e instanceof Error ? e.message : String(e));
814
+ }
815
+ return {
816
+ loaderData: n.renderData,
817
+ segmentLoaderData: r,
818
+ hasDeferred: o,
819
+ stateInput: {
820
+ path: e.pathname,
821
+ loaderData: n.stateData,
822
+ segmentLoaderData: i,
823
+ pageLoaderRan: e.pageLoaderRan,
824
+ ...e.layoutShell ? { pageClientOnly: !0 } : {},
825
+ ...n.deferredIds ? { deferredPageIds: n.deferredIds } : {},
826
+ ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
827
+ }
828
+ };
829
+ }, Yt = (e) => {
830
+ let { helpers: t, renderInput: n } = e, r = Jt({
831
+ helpers: t,
832
+ page: e.page,
833
+ pathname: n.pathname,
834
+ renderMode: "spa",
835
+ interactive: e.interactive,
836
+ loaderData: null,
837
+ segmentLoaderData: n.segmentLoaderData ?? {},
838
+ pageLoaderRan: !1,
839
+ layoutShell: e.delivery
840
+ });
841
+ return {
842
+ renderInput: {
843
+ ...n,
844
+ pageSlot: !0,
845
+ loaderData: null,
846
+ segmentLoaderData: r.segmentLoaderData
847
+ },
848
+ stateScript: t.renderRouterStateScript(r.stateInput),
849
+ hasDeferred: r.hasDeferred
850
+ };
851
+ }, Xt = (e) => {
852
+ let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
853
+ return {
854
+ body: t,
855
+ meta: n
856
+ };
857
+ }, Zt = (e) => [
858
+ ...e.extra ?? [],
859
+ e.helpers.renderMetaToHtml(e.meta),
860
+ `<meta name="voltro-interactive" content="${e.interactive}" />`,
861
+ ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
862
+ e.prepared.stateScript
863
+ ].filter((e) => e.length > 0).join("\n "), Qt = (e, t) => {
864
+ let n = t.replace(/[^A-Za-z0-9+/=_-]/g, "");
865
+ return e.replace(/<script(?![^>]*\bnonce=)/gi, `<script nonce="${n}"`);
866
+ }, $t = (e) => {
867
+ let t = e.indexOf("?");
868
+ return t === -1 ? {
869
+ pathname: e || "/",
870
+ search: ""
871
+ } : {
872
+ pathname: e.slice(0, t) || "/",
873
+ search: e.slice(t)
874
+ };
875
+ }, en = (e) => {
542
876
  let t = [];
543
877
  for (let n of e.split("/").filter(Boolean)) n.startsWith("[[...") && n.endsWith("]]") ? t.push({
544
878
  name: n.slice(5, -2),
@@ -554,12 +888,12 @@ __installPublicEnv(publicEnvValues)
554
888
  optional: !1
555
889
  });
556
890
  return t;
557
- }, ot = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), st = async (e) => {
891
+ }, tn = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), nn = async (e) => {
558
892
  let t = A(e);
559
893
  for (let e = 0; e < 4; e++) {
560
894
  let e = O(t, "project.json");
561
- if (j(e)) try {
562
- let n = await M.readFile(e, "utf8");
895
+ if (M(e)) try {
896
+ let n = await N.readFile(e, "utf8");
563
897
  return {
564
898
  projectDir: t,
565
899
  manifest: JSON.parse(n)
@@ -572,33 +906,33 @@ __installPublicEnv(publicEnvValues)
572
906
  t = n;
573
907
  }
574
908
  return null;
575
- }, ct = async (e) => {
576
- let t = await st(e);
909
+ }, rn = async (e) => {
910
+ let t = await nn(e);
577
911
  if (!t) return [];
578
912
  let { projectDir: n, manifest: r } = t, i = E(e), a = r.apps ?? {}, o = [];
579
913
  for (let [e, t] of Object.entries(a)) {
580
914
  if (e === i || t.kind !== "web" || typeof t.port != "number") continue;
581
915
  let r = O(n, t.path ?? e), a = O(r, "src", "pages");
582
- if (!j(a)) continue;
916
+ if (!M(a)) continue;
583
917
  let s;
584
918
  try {
585
- let { pages: e } = await Jr(a);
919
+ let { pages: e } = await $(a);
586
920
  s = e.map((e) => ({
587
921
  pattern: e.pattern,
588
- params: at(e.pattern)
922
+ params: en(e.pattern)
589
923
  }));
590
924
  } catch {
591
925
  continue;
592
926
  }
593
927
  o.push({
594
- key: ot(e),
928
+ key: tn(e),
595
929
  origin: `http://localhost:${t.port}`,
596
930
  ...typeof t.origin == "string" && t.origin.length > 0 ? { prodOrigin: t.origin } : {},
597
931
  routes: s
598
932
  });
599
933
  }
600
934
  return o;
601
- }, lt = (e) => {
935
+ }, an = (e) => {
602
936
  if (e.params.length === 0) return `'${e.pattern}'`;
603
937
  let t = e.pattern;
604
938
  for (let n of e.params) {
@@ -606,73 +940,91 @@ __installPublicEnv(publicEnvValues)
606
940
  t = t.replace(e, r);
607
941
  }
608
942
  return "`" + t + "`";
609
- }, ut = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
943
+ }, on = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
610
944
  let t = "string";
611
945
  return e.optional ? `readonly ${e.name}?: ${t}` : `readonly ${e.name}: ${t}`;
612
- }).join("; ")} }`, dt = (e, t, n) => {
613
- let r = ut(e), i = lt(e), a = t ? "VoltroExternalUrl" : "VoltroRouteUrl", o = t && n ? `${n} + ` : "";
946
+ }).join("; ")} }`, sn = (e, t, n) => {
947
+ let r = on(e), i = an(e), a = t ? "VoltroExternalUrl" : e.search === void 0 ? "VoltroRouteUrl" : `VoltroRouteUrl<Schema.Schema.Type<typeof ${e.search.alias}>>`, o = t && n ? `${n} + ` : "";
614
948
  return e.params.length === 0 ? `() => (${o}${i}) as ${a}` : `({ ${e.params.map((e) => e.name).join(", ")} }: ${r}) => (${o}${i}) as ${a}`;
615
- }, ft = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${dt(e, !1)},`).join("\n")}\n}`, pt = (e, t) => {
949
+ }, cn = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${sn(e, !1)},`).join("\n")}\n}`, ln = (e, t) => {
616
950
  if (e.routes.length === 0) return ` ${e.key}: {} as Record<string, never>,`;
617
- let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${dt(e, !0, i)},`);
951
+ let n = [...e.routes].sort((e, t) => e.pattern.localeCompare(t.pattern)), r = t === "prod" && e.prodOrigin ? e.prodOrigin : e.origin, i = JSON.stringify(r), a = n.map((e) => ` ${JSON.stringify(e.pattern)}: ${sn(e, !0, i)},`);
618
952
  return ` ${e.key}: {\n${a.join("\n")}\n },`;
619
- }, mt = async (e) => {
620
- let t = e.pages.map((e) => ({
621
- pattern: e.pattern,
622
- params: at(e.pattern)
623
- })), n = await ct(e.appRoot), r = [
953
+ }, un = async (e) => {
954
+ let t = await Promise.all(e.pages.map(async (t) => {
955
+ let n;
956
+ try {
957
+ let r = await N.readFile(O(e.appRoot, "src", "pages", t.file), "utf8");
958
+ /^export const searchParams\b/m.test(r) && (n = {
959
+ alias: `SP_${t.ident}`,
960
+ specifier: `../src/pages/${t.file.replace(/\.tsx?$/, "")}`
961
+ });
962
+ } catch {}
963
+ return {
964
+ pattern: t.pattern,
965
+ params: en(t.pattern),
966
+ ...n === void 0 ? {} : { search: n }
967
+ };
968
+ })), n = await rn(e.appRoot), r = t.filter((e) => e.search !== void 0).sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => `import type { searchParams as ${e.search.alias} } from '${e.search.specifier}'`), i = [
624
969
  "// THIS FILE IS GENERATED — DO NOT EDIT BY HAND.",
625
970
  "// Re-emitted by `voltro dev` whenever `src/pages/**` changes.",
626
971
  "// Type-safe route builders consumed by <Link to={...}>.",
627
972
  "",
628
973
  "import type { VoltroRouteUrl, VoltroExternalUrl } from '@voltro/web'",
974
+ ...r.length > 0 ? [
975
+ "// Type-ONLY page imports: they brand each schema-carrying route's URL with",
976
+ "// its searchParams shape and are erased at compile time — no page enters",
977
+ "// this module's value graph (plans/parity/05, the code-splitting decision).",
978
+ "import type { Schema } from 'effect'",
979
+ ...r
980
+ ] : [],
629
981
  "",
630
982
  "type EmptyParams = Record<string, never>",
631
983
  ""
632
- ].join("\n"), i = e.mode ?? "dev", a = `${r}\n${`export const routes = ${ft(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => pt(e, i)).join("\n")}\n} as const\n`}`, o = O(e.appRoot, ".framework", "routes.generated.ts");
633
- await M.mkdir(D(o), { recursive: !0 });
634
- let s = null;
984
+ ].join("\n"), a = e.mode ?? "dev", o = `${i}\n${`export const routes = ${cn(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => ln(e, a)).join("\n")}\n} as const\n`}`, s = O(e.appRoot, ".framework", "routes.generated.ts");
985
+ await N.mkdir(D(s), { recursive: !0 });
986
+ let c = null;
635
987
  try {
636
- s = await M.readFile(o, "utf8");
988
+ c = await N.readFile(s, "utf8");
637
989
  } catch {}
638
- return s === a ? {
639
- path: o,
990
+ return c === o ? {
991
+ path: s,
640
992
  wrote: !1
641
- } : (await M.writeFile(o, a, "utf8"), {
642
- path: o,
993
+ } : (await N.writeFile(s, o, "utf8"), {
994
+ path: s,
643
995
  wrote: !0
644
996
  });
645
- }, ht = (e) => {
997
+ }, dn = (e) => {
646
998
  if (e === "" || e === "/") return "/";
647
999
  let t = e.startsWith("/") ? e : `/${e}`;
648
1000
  return t.endsWith("/") ? t.slice(0, -1) : t;
649
- }, gt = (e, t) => {
650
- let n = e.endsWith("/") ? e.slice(0, -1) : e, r = ht(t);
1001
+ }, fn = (e, t) => {
1002
+ let n = e.endsWith("/") ? e.slice(0, -1) : e, r = dn(t);
651
1003
  return r === "/" ? `${n}/` : `${n}${r}`;
652
- }, _t = (e, t, n) => {
653
- let r = ht(e);
1004
+ }, pn = (e, t, n) => {
1005
+ let r = dn(e);
654
1006
  return t === n ? r : r === "/" ? `/${t}` : `/${t}${r}`;
655
- }, vt = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), yt = (e) => {
1007
+ }, mn = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), hn = (e) => {
656
1008
  let { siteUrl: t, entries: n } = e, r = e.locales && e.locales.length > 1 ? e.locales : void 0, i = e.defaultLocale ?? r?.[0] ?? "en", a = r !== void 0, o = /* @__PURE__ */ new Map(), s = (e) => {
657
1009
  if (!r) return "";
658
- let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${vt(n)}" href="${vt(gt(t, _t(e, n, i)))}" />`);
659
- return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${vt(gt(t, _t(e, i, i)))}" />`), `\n${n.join("\n")}`;
1010
+ let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${mn(n)}" href="${mn(fn(t, pn(e, n, i)))}" />`);
1011
+ return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${mn(fn(t, pn(e, i, i)))}" />`), `\n${n.join("\n")}`;
660
1012
  };
661
1013
  for (let e of n) {
662
1014
  let n = r ?? [i];
663
1015
  for (let r of n) {
664
- let n = gt(t, _t(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${vt(e.lastmod)}</lastmod>` : "";
665
- o.set(n, ` <url>\n <loc>${vt(n)}</loc>${a}${s(e.path)}\n </url>`);
1016
+ let n = fn(t, pn(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${mn(e.lastmod)}</lastmod>` : "";
1017
+ o.set(n, ` <url>\n <loc>${mn(n)}</loc>${a}${s(e.path)}\n </url>`);
666
1018
  }
667
1019
  }
668
1020
  let c = [...o.keys()].sort().map((e) => o.get(e)).join("\n");
669
1021
  return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset${a ? " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" : " xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\""}>\n${c}\n</urlset>\n`;
670
- }, bt = (e) => {
1022
+ }, gn = (e) => {
671
1023
  if (!e.indexable) return "User-agent: *\nDisallow: /\n";
672
1024
  let t = ["User-agent: *", "Allow: /"];
673
- for (let n of e.disallow ?? []) t.push(`Disallow: ${ht(n)}`);
1025
+ for (let n of e.disallow ?? []) t.push(`Disallow: ${dn(n)}`);
674
1026
  return e.sitemapUrl && t.push("", `Sitemap: ${e.sitemapUrl}`), `${t.join("\n")}\n`;
675
- }, xt = 256, St = (e = xt) => {
1027
+ }, _n = 256, vn = (e = _n) => {
676
1028
  let t = [], n = /* @__PURE__ */ new Set();
677
1029
  return {
678
1030
  emit(r, i) {
@@ -695,18 +1047,18 @@ __installPublicEnv(publicEnvValues)
695
1047
  return t.slice();
696
1048
  }
697
1049
  };
698
- }, Ct = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, wt = () => `: keep-alive ${Date.now()}\n\n`, Tt = 8e3, Et = (e, t = Tt) => {
699
- let n = Ot(e);
1050
+ }, yn = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, bn = () => `: keep-alive ${Date.now()}\n\n`, xn = 8e3, Sn = (e, t = xn) => {
1051
+ let n = wn(e);
700
1052
  return n.length <= t ? n : `${n.slice(0, t)}\n… [voltro] truncated at ${t} chars (${n.length} total)`;
701
- }, Dt = 4, Ot = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
1053
+ }, Cn = 4, wn = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
702
1054
  if (e instanceof Error) {
703
1055
  let r = e.stack ?? `${e.name}: ${e.message}`;
704
1056
  if (n.has(e)) return `${r}\n [cycle]`;
705
1057
  n.add(e);
706
1058
  let i = [];
707
- if (t < Dt) {
708
- if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${kt(Ot(a, t + 1, n))}`);
709
- else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${kt(Ot(e.cause, t + 1, n))}`);
1059
+ if (t < Cn) {
1060
+ if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${Tn(wn(a, t + 1, n))}`);
1061
+ else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${Tn(wn(e.cause, t + 1, n))}`);
710
1062
  }
711
1063
  return r + i.join("");
712
1064
  }
@@ -715,30 +1067,30 @@ __installPublicEnv(publicEnvValues)
715
1067
  } catch {
716
1068
  return "[unstringifiable thrown value]";
717
1069
  }
718
- }, kt = (e) => {
1070
+ }, Tn = (e) => {
719
1071
  let t = e.split("\n");
720
1072
  return t.length <= 3 ? e : `${t.slice(0, 3).join("\n")}\n …`;
721
- }, At = {
1073
+ }, En = {
722
1074
  trace: 0,
723
1075
  debug: 1,
724
1076
  info: 2,
725
1077
  warn: 3,
726
1078
  error: 4,
727
1079
  fatal: 5
728
- }, jt = 2e3, Mt = 200, Nt = class {
1080
+ }, Dn = 2e3, On = 200, kn = class {
729
1081
  capacity;
730
1082
  buffer = [];
731
- constructor(e = jt) {
1083
+ constructor(e = Dn) {
732
1084
  this.capacity = e;
733
1085
  }
734
1086
  append(e) {
735
1087
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
736
1088
  }
737
1089
  query(e = {}) {
738
- let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? Mt, this.capacity), i = e.minLevel === void 0 ? At.trace : At[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
1090
+ let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? On, this.capacity), i = e.minLevel === void 0 ? En.trace : En[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
739
1091
  for (let e = this.buffer.length - 1; e >= 0 && l.length < r; e--) {
740
1092
  let r = this.buffer[e];
741
- r.ts < t || r.ts > n || At[r.level] < i || (o === void 0 || r.source === o) && (a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || (c === void 0 || r.fields.traceId === c) && l.push(r));
1093
+ r.ts < t || r.ts > n || En[r.level] < i || (o === void 0 || r.source === o) && (a !== void 0 && (r.scope === void 0 || !r.scope.toLowerCase().includes(a)) || s !== void 0 && !r.message.toLowerCase().includes(s) || (c === void 0 || r.fields.traceId === c) && l.push(r));
742
1094
  }
743
1095
  return l.reverse();
744
1096
  }
@@ -751,7 +1103,7 @@ __installPublicEnv(publicEnvValues)
751
1103
  clear() {
752
1104
  this.buffer = [];
753
1105
  }
754
- }, Pt = null, Ft = () => (Pt === null && (Pt = new Nt()), Pt), It = (e) => {
1106
+ }, An = null, jn = () => (An === null && (An = new kn()), An), Mn = (e) => {
755
1107
  if (typeof e == "string") return e;
756
1108
  if (e instanceof Error) return e.message;
757
1109
  try {
@@ -759,28 +1111,28 @@ __installPublicEnv(publicEnvValues)
759
1111
  } catch {
760
1112
  return String(e);
761
1113
  }
762
- }, Lt = 8e3, Rt = (e) => typeof e == "string" ? e.length <= Lt ? e : `${e.slice(0, Lt)}… [voltro: truncated]` : typeof e != "object" || !e ? e : Et(e, Lt), zt = (e, t) => {
1114
+ }, Nn = 8e3, Pn = (e) => typeof e == "string" ? e.length <= Nn ? e : `${e.slice(0, Nn)}… [voltro: truncated]` : typeof e != "object" || !e ? e : Sn(e, Nn), Fn = (e, t) => {
763
1115
  try {
764
1116
  e(...t);
765
1117
  } catch (n) {
766
1118
  try {
767
- e(...t.map(Rt)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${Lt} chars per argument.`);
1119
+ e(...t.map(Pn)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${Nn} chars per argument.`);
768
1120
  } catch {
769
1121
  e(`[voltro] a console.error argument could not be formatted at all (${t.length} arg(s)).`);
770
1122
  }
771
1123
  }
772
- }, Bt = (e) => {
1124
+ }, In = (e) => {
773
1125
  let t = {
774
1126
  log: console.log.bind(console),
775
1127
  info: console.info.bind(console),
776
1128
  warn: console.warn.bind(console),
777
1129
  error: console.error.bind(console),
778
1130
  debug: console.debug.bind(console)
779
- }, n = Ft(), r = !1, i = (i) => (...a) => {
780
- if (zt(t[i], a), !r) {
1131
+ }, n = jn(), r = !1, i = (i) => (...a) => {
1132
+ if (Fn(t[i], a), !r) {
781
1133
  r = !0;
782
1134
  try {
783
- let t = a.length > 0 ? It(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = V();
1135
+ let t = a.length > 0 ? Mn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = V();
784
1136
  e.emit("log", {
785
1137
  level: i,
786
1138
  message: r,
@@ -807,7 +1159,7 @@ __installPublicEnv(publicEnvValues)
807
1159
  }
808
1160
  };
809
1161
  console.log = i("log"), console.info = i("info"), console.warn = i("warn"), console.error = i("error"), console.debug = i("debug");
810
- let a = R((t) => {
1162
+ let a = L((t) => {
811
1163
  if (!r) {
812
1164
  r = !0;
813
1165
  try {
@@ -838,24 +1190,24 @@ __installPublicEnv(publicEnvValues)
838
1190
  return () => {
839
1191
  console.log = t.log, console.info = t.info, console.warn = t.warn, console.error = t.error, console.debug = t.debug, a();
840
1192
  };
841
- }, Vt = 2e3, Ht = 8, Ut = 1e3, Wt = 200, Gt = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, Kt = (e) => {
1193
+ }, Ln = 2e3, Rn = 8, zn = 1e3, Bn = 200, Vn = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, Hn = (e) => {
842
1194
  switch (e) {
843
1195
  case "error": return "error";
844
1196
  case "warn": return "warn";
845
1197
  case "debug": return "debug";
846
1198
  default: return "info";
847
1199
  }
848
- }, qt = z({ scope: "client" }), Jt = (e, t) => {
1200
+ }, Un = R({ scope: "client" }), Wn = (e, t) => {
849
1201
  let n;
850
1202
  try {
851
1203
  n = JSON.parse(e);
852
1204
  } catch {
853
- return Yt(400, { error: "invalid JSON body" });
1205
+ return Gn(400, { error: "invalid JSON body" });
854
1206
  }
855
- if (typeof n != "object" || !n) return Yt(400, { error: "body must be a JSON object" });
1207
+ if (typeof n != "object" || !n) return Gn(400, { error: "body must be a JSON object" });
856
1208
  let r = n;
857
- if (!Array.isArray(r.entries)) return Yt(400, { error: "entries must be an array" });
858
- let i = typeof r.app == "string" ? Gt(r.app, 120) : void 0, a = typeof r.page == "string" ? Gt(r.page, 200) : void 0, o = typeof r.ua == "string" ? Gt(r.ua, 200) : void 0, s = r.entries.slice(0, Wt), c = 0;
1209
+ if (!Array.isArray(r.entries)) return Gn(400, { error: "entries must be an array" });
1210
+ let i = typeof r.app == "string" ? Vn(r.app, 120) : void 0, a = typeof r.page == "string" ? Vn(r.page, 200) : void 0, o = typeof r.ua == "string" ? Vn(r.ua, 200) : void 0, s = r.entries.slice(0, Bn), c = 0;
859
1211
  for (let e of s) {
860
1212
  if (typeof e != "object" || !e) continue;
861
1213
  let n = e;
@@ -866,7 +1218,7 @@ __installPublicEnv(publicEnvValues)
866
1218
  "warn",
867
1219
  "error",
868
1220
  "debug"
869
- ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Gt(n.message, Vt), u = Array.isArray(n.args) ? n.args.slice(0, Ht).filter((e) => typeof e == "string").map((e) => Gt(e, Ut)) : void 0, d = typeof n.stack == "string" ? Gt(n.stack, Vt) : void 0;
1221
+ ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Vn(n.message, Ln), u = Array.isArray(n.args) ? n.args.slice(0, Rn).filter((e) => typeof e == "string").map((e) => Vn(e, zn)) : void 0, d = typeof n.stack == "string" ? Vn(n.stack, Ln) : void 0;
870
1222
  t.emit("clientLog", {
871
1223
  ts: s,
872
1224
  level: r,
@@ -881,35 +1233,35 @@ __installPublicEnv(publicEnvValues)
881
1233
  ...i === void 0 ? {} : { app: i },
882
1234
  ...a === void 0 ? {} : { page: a },
883
1235
  ...u !== void 0 && u.length > 0 ? { args: u } : {}
884
- }, p = Kt(r);
885
- (p === "error" || p === "warn") && d !== void 0 ? qt[p](l, f, { stack: d }) : qt[p](l, {
1236
+ }, p = Hn(r);
1237
+ (p === "error" || p === "warn") && d !== void 0 ? Un[p](l, f, { stack: d }) : Un[p](l, {
886
1238
  ...f,
887
1239
  ...d === void 0 ? {} : { stack: d }
888
1240
  }), c++;
889
1241
  }
890
- return Yt(202, {
1242
+ return Gn(202, {
891
1243
  accepted: c,
892
1244
  dropped: r.entries.length - c
893
1245
  });
894
- }, Yt = (e, t) => ({
1246
+ }, Gn = (e, t) => ({
895
1247
  status: e,
896
1248
  contentType: "application/json; charset=utf-8",
897
1249
  body: JSON.stringify(t)
898
- }), Xt = "/_voltro/inspect/clientLog", Zt = [
1250
+ }), Kn = "/_voltro/inspect/clientLog", qn = [
899
1251
  "trace",
900
1252
  "debug",
901
1253
  "info",
902
1254
  "warn",
903
1255
  "error",
904
1256
  "fatal"
905
- ], Qt = {
1257
+ ], Jn = {
906
1258
  trace: "TRACE",
907
1259
  debug: "DEBUG",
908
1260
  info: "INFO ",
909
1261
  warn: "WARN ",
910
1262
  error: "ERROR",
911
1263
  fatal: "FATAL"
912
- }, $t = (e) => Zt.includes(e), en = (e, t, n = {}) => {
1264
+ }, Yn = (e) => qn.includes(e), Xn = (e, t, n = {}) => {
913
1265
  if (u()) return {
914
1266
  status: 503,
915
1267
  contentType: "application/json",
@@ -940,7 +1292,7 @@ __installPublicEnv(publicEnvValues)
940
1292
  Number.isFinite(e) && e > 0 && (o.max = Math.floor(e));
941
1293
  }
942
1294
  let d = a.get("level");
943
- d !== null && $t(d) && (o.minLevel = d);
1295
+ d !== null && Yn(d) && (o.minLevel = d);
944
1296
  let p = a.get("source");
945
1297
  (p === "server" || p === "client") && (o.source = p);
946
1298
  let m = a.get("scope");
@@ -953,7 +1305,7 @@ __installPublicEnv(publicEnvValues)
953
1305
  if ((a.get("format") ?? "json") === "text") return {
954
1306
  status: 200,
955
1307
  contentType: "text/plain; charset=utf-8",
956
- body: _.map(tn).join("\n") + (_.length > 0 ? "\n" : "")
1308
+ body: _.map(Zn).join("\n") + (_.length > 0 ? "\n" : "")
957
1309
  };
958
1310
  let v = {
959
1311
  capturedAt: Date.now(),
@@ -967,40 +1319,40 @@ __installPublicEnv(publicEnvValues)
967
1319
  contentType: "application/json; charset=utf-8",
968
1320
  body: JSON.stringify(v)
969
1321
  };
970
- }, tn = (e) => {
971
- let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = rn(e.fields);
972
- return `${n}:${r}:${i}.${a} ${Qt[e.level]} ${o} ${e.message}${s}`;
973
- }, nn = 80, rn = (e) => {
1322
+ }, Zn = (e) => {
1323
+ let t = new Date(e.ts), n = String(t.getHours()).padStart(2, "0"), r = String(t.getMinutes()).padStart(2, "0"), i = String(t.getSeconds()).padStart(2, "0"), a = String(t.getMilliseconds()).padStart(3, "0"), o = `[${e.scope ?? "?"}/${e.source}]`, s = $n(e.fields);
1324
+ return `${n}:${r}:${i}.${a} ${Jn[e.level]} ${o} ${e.message}${s}`;
1325
+ }, Qn = 80, $n = (e) => {
974
1326
  let t = Object.entries(e);
975
1327
  if (t.length === 0) return "";
976
1328
  let n = [];
977
1329
  for (let [e, r] of t) {
978
1330
  if (r === void 0) continue;
979
- let t = an(r);
1331
+ let t = er(r);
980
1332
  n.push(`${e}=${t}`);
981
1333
  }
982
1334
  return n.length > 0 ? " " + n.join(" ") : "";
983
- }, an = (e) => {
1335
+ }, er = (e) => {
984
1336
  if (typeof e == "string") {
985
- let t = e.length > nn ? e.slice(0, nn) + "…" : e;
1337
+ let t = e.length > Qn ? e.slice(0, Qn) + "…" : e;
986
1338
  return /[\s=]/.test(t) ? `"${t.replace(/"/g, "\\\"")}"` : t;
987
1339
  }
988
1340
  if (e === null) return "null";
989
1341
  if (typeof e == "number" || typeof e == "boolean") return String(e);
990
1342
  try {
991
1343
  let t = JSON.stringify(e);
992
- return t.length > nn ? t.slice(0, nn) + "…" : t;
1344
+ return t.length > Qn ? t.slice(0, Qn) + "…" : t;
993
1345
  } catch {
994
1346
  return "[unserialisable]";
995
1347
  }
996
- }, on = "/_voltro/inspect/logs", sn = (e, t, n) => {
1348
+ }, tr = "/_voltro/inspect/logs", nr = (e, t, n) => {
997
1349
  if (t.headers.authorization !== void 0) return !1;
998
1350
  let { token: r } = n;
999
1351
  if (r === void 0 || r === "" || !n.isLoopback(n.target)) return !1;
1000
1352
  e.setHeader("authorization", `Bearer ${r}`);
1001
1353
  let i = n.writeToken;
1002
1354
  return i !== void 0 && i !== "" && t.headers["x-voltro-inspect-write"] === void 0 && e.setHeader("x-voltro-inspect-write", i), !0;
1003
- }, cn = [{
1355
+ }, rr = [{
1004
1356
  match: (e) => typeof e == "string" && e.startsWith("[BABEL] Note: The code generator has deoptimised"),
1005
1357
  handle: (e, t) => {
1006
1358
  let n = e[0], r = n.match(/deoptimised the styling of (.+?) as it exceeds the max of (\d+\w*B)\.?/);
@@ -1012,13 +1364,13 @@ __installPublicEnv(publicEnvValues)
1012
1364
  });
1013
1365
  } else t.info(n);
1014
1366
  }
1015
- }], ln = () => {
1367
+ }], ir = () => {
1016
1368
  let e = {
1017
1369
  warn: console.warn.bind(console),
1018
1370
  error: console.error.bind(console)
1019
- }, t = z({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1371
+ }, t = R({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1020
1372
  if (!n) {
1021
- for (let e of cn) if (e.match(i[0])) {
1373
+ for (let e of rr) if (e.match(i[0])) {
1022
1374
  n = !0;
1023
1375
  try {
1024
1376
  e.handle(i, t);
@@ -1033,7 +1385,7 @@ __installPublicEnv(publicEnvValues)
1033
1385
  return console.warn = r("warn"), console.error = r("error"), () => {
1034
1386
  console.warn = e.warn, console.error = e.error;
1035
1387
  };
1036
- }, un = {
1388
+ }, ar = {
1037
1389
  loader: "it runs on the server, and the router caches its result per route + params",
1038
1390
  renderMode: "it picks the server render strategy",
1039
1391
  dynamic: "it picks the server render strategy",
@@ -1044,7 +1396,7 @@ __installPublicEnv(publicEnvValues)
1044
1396
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1045
1397
  interactive: "it decides how much client JS the server ships",
1046
1398
  tenantAware: "it is part of the server-side cache key"
1047
- }, dn = Object.keys(un), fn = "virtual:voltro-route-refresh", pn = `\0${fn}`, mn = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, hn = () => `
1399
+ }, or = Object.keys(ar), sr = "virtual:voltro-route-refresh", cr = `\0${sr}`, lr = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, ur = () => `
1048
1400
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1049
1401
 
1050
1402
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1073,11 +1425,11 @@ const stableForm = (value) => {
1073
1425
  * readers (\`build.ts\` prerender, \`webDev.ts\` dev SSR, \`start.ts\`). A change to
1074
1426
  * one of THESE cannot be hot-applied: the server already ran with the old
1075
1427
  * value. Everything else a page exports is plain client-side data. */
1076
- const serverRelevantExports = ${JSON.stringify(dn)}
1428
+ const serverRelevantExports = ${JSON.stringify(or)}
1077
1429
 
1078
1430
  /** Name → the server step that already consumed it, so the reload message can
1079
1431
  * say WHY rather than just WHAT. Injected from the same single source. */
1080
- const serverExportEffect = ${JSON.stringify(un)}
1432
+ const serverExportEffect = ${JSON.stringify(ar)}
1081
1433
 
1082
1434
  /** The reason \`name\` forces a reload, for the console line. */
1083
1435
  export const serverEffectOf = (name) =>
@@ -1120,7 +1472,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1120
1472
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1121
1473
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1122
1474
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1123
- `, gn = (e) => `
1475
+ `, dr = (e) => `
1124
1476
  if (import.meta.hot) {
1125
1477
  // Self-import to read our OWN exports, the same technique the react plugin
1126
1478
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1147,42 +1499,42 @@ import {
1147
1499
  registerRouteModule as __voltro_registerRouteModule,
1148
1500
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1149
1501
  serverEffectOf as __voltro_serverEffect,
1150
- } from '${fn}'
1151
- `, _n = (e) => e.replace(/\\/g, "/"), vn = (e, t) => {
1152
- let [n = "", r] = _n(e).split("?");
1153
- if (!n.endsWith(".tsx") || r !== void 0 && mn.test(r)) return !1;
1154
- let i = _n(t).replace(/\/$/, "");
1502
+ } from '${sr}'
1503
+ `, fr = (e) => e.replace(/\\/g, "/"), pr = (e, t) => {
1504
+ let [n = "", r] = fr(e).split("?");
1505
+ if (!n.endsWith(".tsx") || r !== void 0 && lr.test(r)) return !1;
1506
+ let i = fr(t).replace(/\/$/, "");
1155
1507
  return n.startsWith(`${i}/`) ? c.test(n) || s.has(n.slice(n.lastIndexOf("/") + 1)) : !1;
1156
- }, yn = (e, t, n) => vn(t, n) ? `${e}${gn(_n(t).split("?")[0] ?? t)}` : null, bn = (e) => ({
1508
+ }, mr = (e, t, n) => pr(t, n) ? `${e}${dr(fr(t).split("?")[0] ?? t)}` : null, hr = (e) => ({
1157
1509
  name: "voltro:route-fast-refresh",
1158
1510
  enforce: "pre",
1159
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? pn : void 0,
1160
- load: (e) => e === pn ? hn() : void 0,
1511
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? cr : void 0,
1512
+ load: (e) => e === cr ? ur() : void 0,
1161
1513
  transform: (t, n, r) => {
1162
1514
  if (r?.ssr === !0) return null;
1163
- let i = yn(t, n, e);
1515
+ let i = mr(t, n, e);
1164
1516
  return i === null ? null : {
1165
1517
  code: i,
1166
1518
  map: null
1167
1519
  };
1168
1520
  }
1169
- }), xn = z({ scope: "voltro:dashboard" }), Sn = B(import.meta.url), Cn = 5179, wn = (e) => {
1521
+ }), gr = R({ scope: "voltro:dashboard" }), _r = ie(import.meta.url), vr = 5179, yr = (e) => {
1170
1522
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1171
- if (t && j(O(A(t), "app.config.ts"))) return A(t);
1523
+ if (t && M(O(A(t), "app.config.ts"))) return A(t);
1172
1524
  try {
1173
- let e = D(Sn.resolve("@voltro/dashboard/package.json"));
1174
- if (j(O(e, "app.config.ts"))) return e;
1525
+ let e = D(_r.resolve("@voltro/dashboard/package.json"));
1526
+ if (M(O(e, "app.config.ts"))) return e;
1175
1527
  } catch {}
1176
1528
  let n = O("voltro-devtools", "apps", "dashboard"), r = A(e);
1177
1529
  for (let e = 0; e < 10; e++) {
1178
1530
  let e = O(r, n);
1179
- if (j(O(e, "app.config.ts"))) return e;
1531
+ if (M(O(e, "app.config.ts"))) return e;
1180
1532
  let t = D(r);
1181
1533
  if (t === r) break;
1182
1534
  r = t;
1183
1535
  }
1184
1536
  return null;
1185
- }, Tn = "VOLTRO_IS_DASHBOARD", En = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1537
+ }, br = "VOLTRO_IS_DASHBOARD", xr = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1186
1538
  let i = K({
1187
1539
  port: e,
1188
1540
  host: t
@@ -1190,45 +1542,45 @@ import {
1190
1542
  a || (a = !0, i.destroy(), r(e));
1191
1543
  };
1192
1544
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
1193
- }), Dn = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), On = () => process.env[Tn] === "1", kn = () => process.stdout.isTTY === !0, An = O(H(), ".voltro", "dashboard-launch.lock"), jn = 1e4, Mn = async () => {
1545
+ }), Sr = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Cr = () => process.env[br] === "1", wr = () => process.stdout.isTTY === !0, Tr = O(H(), ".voltro", "dashboard-launch.lock"), Er = 1e4, Dr = async () => {
1194
1546
  try {
1195
- await M.mkdir(D(An), { recursive: !0 });
1196
- let e = await M.open(An, "wx");
1547
+ await N.mkdir(D(Tr), { recursive: !0 });
1548
+ let e = await N.open(Tr, "wx");
1197
1549
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1198
1550
  } catch {
1199
1551
  try {
1200
- let e = await M.stat(An);
1201
- if (Date.now() - e.mtimeMs > jn) return await M.unlink(An).catch(() => void 0), Mn();
1552
+ let e = await N.stat(Tr);
1553
+ if (Date.now() - e.mtimeMs > Er) return await N.unlink(Tr).catch(() => void 0), Dr();
1202
1554
  } catch {}
1203
1555
  return !1;
1204
1556
  }
1205
- }, Nn = async () => {
1557
+ }, Or = async () => {
1206
1558
  try {
1207
- await M.unlink(An);
1559
+ await N.unlink(Tr);
1208
1560
  } catch {}
1209
- }, Pn = async (e) => {
1561
+ }, kr = async (e) => {
1210
1562
  let t = e.port ?? 5179;
1211
- if (Dn()) return {
1563
+ if (Sr()) return {
1212
1564
  status: "skipped",
1213
1565
  reason: "disabled by flag/env",
1214
1566
  port: t
1215
1567
  };
1216
- if (On()) return {
1568
+ if (Cr()) return {
1217
1569
  status: "skipped",
1218
1570
  reason: "this process IS the dashboard",
1219
1571
  port: t
1220
1572
  };
1221
- if (!kn()) return {
1573
+ if (!wr()) return {
1222
1574
  status: "skipped",
1223
1575
  reason: "stdout is not a TTY (CI/smoke)",
1224
1576
  port: t
1225
1577
  };
1226
- if (!await Mn()) return {
1578
+ if (!await Dr()) return {
1227
1579
  status: "skipped",
1228
1580
  reason: "another voltro process is currently launching the dashboard",
1229
1581
  port: t
1230
1582
  };
1231
- if (await En(t)) return await Nn(), {
1583
+ if (await xr(t)) return await Or(), {
1232
1584
  status: "already-running",
1233
1585
  port: t
1234
1586
  };
@@ -1237,7 +1589,7 @@ import {
1237
1589
  let e = process.argv[1];
1238
1590
  n = e && e.endsWith("/src/bin.ts") ? O(D(e), "..", "bin", "voltro.mjs") : e ?? "voltro";
1239
1591
  }
1240
- let r = O(e.dashboardAppPath, ".framework", "dist", "index.html"), i = j(r), a = i ? "start" : "dev", o = me(process.execPath, [
1592
+ let r = O(e.dashboardAppPath, ".framework", "dist", "index.html"), i = M(r), a = i ? "start" : "dev", o = _e(process.execPath, [
1241
1593
  n,
1242
1594
  a,
1243
1595
  e.dashboardAppPath
@@ -1245,7 +1597,7 @@ import {
1245
1597
  stdio: "ignore",
1246
1598
  env: {
1247
1599
  ...process.env,
1248
- [Tn]: "1",
1600
+ [br]: "1",
1249
1601
  VOLTRO_DASHBOARD_PORT: String(t)
1250
1602
  }
1251
1603
  });
@@ -1253,120 +1605,19 @@ import {
1253
1605
  if (o.exitCode === null && o.signalCode === null) try {
1254
1606
  o.kill("SIGTERM");
1255
1607
  } catch {}
1256
- }), xn.info(`auto-launching dashboard at http://localhost:${t}`, {
1608
+ }), gr.info(`auto-launching dashboard at http://localhost:${t}`, {
1257
1609
  port: t,
1258
1610
  mode: a,
1259
1611
  prebuilt: i
1260
- }), i || xn.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), xn.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1261
- Nn();
1612
+ }), i || gr.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), gr.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1613
+ Or();
1262
1614
  }, 4e3).unref(), {
1263
1615
  status: "launched",
1264
1616
  port: t
1265
1617
  };
1266
- }, Fn = class extends Error {
1267
- _voltroDeferral = !0;
1268
- constructor(e) {
1269
- super(e), this.name = "DeferralNotSupportedError";
1270
- }
1271
- }, In = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Ln = (e) => {
1272
- if (!(e instanceof Error)) return;
1273
- let t = e._voltroControl;
1274
- if (t === "redirect") {
1275
- let { location: t, status: n } = e;
1276
- return typeof t == "string" ? {
1277
- status: n === 307 || n === 308 ? n : 303,
1278
- headers: {
1279
- location: t,
1280
- "x-voltro-rendered-by": "loader-redirect"
1281
- },
1282
- body: ""
1283
- } : void 0;
1284
- }
1285
- if (t === "not-found") return {
1286
- status: 404,
1287
- headers: {
1288
- "content-type": "text/plain; charset=utf-8",
1289
- "x-voltro-rendered-by": "loader-not-found"
1290
- },
1291
- body: "not found"
1292
- };
1293
- }, Rn = (e) => {
1294
- let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1295
- for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1296
- let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
1297
- r[e] = s.renderData, i[e] = s.stateData, s.deferredIds && (a[e] = s.deferredIds);
1298
- }
1299
- let o = n.deferredIds !== void 0 || Object.keys(a).length > 0;
1300
- if (o) try {
1301
- t.assertDeferralSupported({
1302
- page: e.page,
1303
- renderMode: e.renderMode,
1304
- interactive: e.interactive,
1305
- ...e.layoutShell ? { layoutShell: e.layoutShell } : {}
1306
- });
1307
- } catch (e) {
1308
- throw new Fn(e instanceof Error ? e.message : String(e));
1309
- }
1310
- return {
1311
- loaderData: n.renderData,
1312
- segmentLoaderData: r,
1313
- hasDeferred: o,
1314
- stateInput: {
1315
- path: e.pathname,
1316
- loaderData: n.stateData,
1317
- segmentLoaderData: i,
1318
- pageLoaderRan: e.pageLoaderRan,
1319
- ...e.layoutShell ? { pageClientOnly: !0 } : {},
1320
- ...n.deferredIds ? { deferredPageIds: n.deferredIds } : {},
1321
- ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1322
- }
1323
- };
1324
- }, zn = (e) => {
1325
- let { helpers: t, renderInput: n } = e, r = Rn({
1326
- helpers: t,
1327
- page: e.page,
1328
- pathname: n.pathname,
1329
- renderMode: "spa",
1330
- interactive: e.interactive,
1331
- loaderData: null,
1332
- segmentLoaderData: n.segmentLoaderData ?? {},
1333
- pageLoaderRan: !1,
1334
- layoutShell: e.delivery
1335
- });
1336
- return {
1337
- renderInput: {
1338
- ...n,
1339
- pageSlot: !0,
1340
- loaderData: null,
1341
- segmentLoaderData: r.segmentLoaderData
1342
- },
1343
- stateScript: t.renderRouterStateScript(r.stateInput),
1344
- hasDeferred: r.hasDeferred
1345
- };
1346
- }, Bn = (e) => {
1347
- let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
1348
- return {
1349
- body: t,
1350
- meta: n
1351
- };
1352
- }, Vn = (e) => [
1353
- ...e.extra ?? [],
1354
- e.helpers.renderMetaToHtml(e.meta),
1355
- `<meta name="voltro-interactive" content="${e.interactive}" />`,
1356
- ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
1357
- e.prepared.stateScript
1358
- ].filter((e) => e.length > 0).join("\n "), Hn = (e) => {
1359
- let t = e.indexOf("?");
1360
- return t === -1 ? {
1361
- pathname: e || "/",
1362
- search: ""
1363
- } : {
1364
- pathname: e.slice(0, t) || "/",
1365
- search: e.slice(t)
1366
- };
1367
- }, Un = /Could not find required `intl` object/, Wn = "__voltro_i18n_instances__", Gn = (e = globalThis) => {
1618
+ }, Ar = /Could not find required `intl` object/, jr = "__voltro_i18n_instances__", Mr = (e = globalThis) => {
1368
1619
  try {
1369
- let t = e[Wn]?.records;
1620
+ let t = e[jr]?.records;
1370
1621
  return t === void 0 || t.length === 0 ? void 0 : {
1371
1622
  instances: t.length,
1372
1623
  reactIntlCopies: new Set(t.map((e) => e.intlProvider)).size,
@@ -1375,7 +1626,7 @@ import {
1375
1626
  } catch {
1376
1627
  return;
1377
1628
  }
1378
- }, Kn = (e, t) => [
1629
+ }, Nr = (e, t) => [
1379
1630
  "",
1380
1631
  "── voltro diagnosis ───────────────────────────────────────────────────",
1381
1632
  `${e} DID wrap this render in <I18nProvider>, and this process`,
@@ -1393,7 +1644,7 @@ import {
1393
1644
  " versions on disk; this counts instances in the running process, and one",
1394
1645
  " file loaded down two paths is two instances.",
1395
1646
  "───────────────────────────────────────────────────────────────────────"
1396
- ].join("\n"), qn = (e, t) => [
1647
+ ].join("\n"), Pr = (e, t) => [
1397
1648
  "",
1398
1649
  "── voltro diagnosis ───────────────────────────────────────────────────",
1399
1650
  `${e} DID wrap this render in <I18nProvider>, and this process`,
@@ -1409,7 +1660,7 @@ import {
1409
1660
  " direct import can land on a second copy that this count does not see —",
1410
1661
  " it counts what @voltro/i18n is bound to.",
1411
1662
  "───────────────────────────────────────────────────────────────────────"
1412
- ].join("\n"), Jn = (e) => [
1663
+ ].join("\n"), Fr = (e) => [
1413
1664
  "",
1414
1665
  "── voltro diagnosis ───────────────────────────────────────────────────",
1415
1666
  `${e} DID wrap this render in <I18nProvider> — the framework`,
@@ -1425,34 +1676,37 @@ import {
1425
1676
  " Do NOT use `pnpm ls` to rule that out: it lists versions on disk, and",
1426
1677
  " the duplication here is of module instances in one process.",
1427
1678
  "───────────────────────────────────────────────────────────────────────"
1428
- ].join("\n"), Yn = (e, t, n, r = Gn()) => {
1679
+ ].join("\n"), Ir = (e, t, n, r = Mr()) => {
1429
1680
  if (!t) return;
1430
1681
  let i = String(e?.message ?? e);
1431
- if (Un.test(i)) return r === void 0 ? Jn(n) : r.reactIntlCopies > 1 || r.instances > 1 ? Kn(n, r) : qn(n, r);
1432
- }, Xn = "<div id=\"root\"></div>", Zn = "<div id=\"root\">", Qn = "</div>", $n = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, er = /\bsrc=["']([^"']+)["']/i, tr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, nr = (e) => {
1433
- let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace($n, (e) => {
1434
- let r = er.exec(e)?.[1];
1682
+ if (Ar.test(i)) return r === void 0 ? Fr(n) : r.reactIntlCopies > 1 || r.instances > 1 ? Nr(n, r) : Pr(n, r);
1683
+ }, Lr = "<div id=\"root\"></div>", Rr = "<div id=\"root\">", zr = "</div>", Br = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, Vr = /\bsrc=["']([^"']+)["']/i, Hr = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, Ur = (e) => {
1684
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(Br, (e) => {
1685
+ let r = Vr.exec(e)?.[1];
1435
1686
  return r === void 0 || t(r) ? e : (n.push(r), "");
1436
1687
  });
1437
- e.inlineModuleScriptsAsync && (r = r.replace(tr, "<script async$1>"));
1438
- let i = r.indexOf(Xn);
1439
- if (i === -1) throw Error(`[voltro] the generated shell has no \`${Xn}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1688
+ e.inlineModuleScriptsAsync && (r = r.replace(Hr, "<script async$1>"));
1689
+ let i = r.indexOf(Lr);
1690
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${Lr}\` element, so a streamed response cannot be split around the page body. This is a framework bug unless the app overrode \`.framework/index.html\` by hand.`);
1440
1691
  return {
1441
- head: `${r.slice(0, i)}${Zn}`,
1442
- tail: `${Qn}${r.slice(i + 21)}`,
1692
+ head: `${r.slice(0, i)}${Rr}`,
1693
+ tail: `${zr}${r.slice(i + 21)}`,
1443
1694
  bootstrapModules: n
1444
1695
  };
1445
- }, rr = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), ir = (e) => rr(e.head, e.headInjection).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${e.htmlLang}"`), ar = (e) => {
1446
- let { res: t, shell: n, htmlLang: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1696
+ }, Wr = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), Gr = (e) => e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), Kr = (e, t) => {
1697
+ let n = [t.timeZone === void 0 ? "" : ` data-voltro-tz="${Gr(t.timeZone)}"`, t.renderedAt === void 0 ? "" : ` data-voltro-now="${t.renderedAt}"`].join("");
1698
+ return e.replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${Gr(t.lang)}"${n}`);
1699
+ }, qr = (e) => Kr(Wr(e.head, e.headInjection), e.documentAttrs), Jr = (e) => {
1700
+ let { res: t, shell: n, documentAttrs: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1447
1701
  if (s || !o || a === null) return;
1448
1702
  s = !0, t.statusCode = e.statusCode ?? 200;
1449
1703
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1450
- t.flushHeaders?.(), t.write(ir({
1704
+ t.flushHeaders?.(), t.write(qr({
1451
1705
  head: n.head,
1452
1706
  headInjection: i(a.meta),
1453
- htmlLang: r
1707
+ documentAttrs: r
1454
1708
  }));
1455
- let c = new he();
1709
+ let c = new Te();
1456
1710
  c.pipe(t, { end: !1 }), c.on("end", () => {
1457
1711
  t.end(n.tail);
1458
1712
  }), a.stream.pipe(c);
@@ -1477,16 +1731,16 @@ import {
1477
1731
  return;
1478
1732
  }
1479
1733
  c();
1480
- }, or = (e) => Array.isArray(e.preload) && e.preload.length > 0, sr = (e, t) => typeof e == "string" ? {
1734
+ }, Yr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Xr = (e, t) => typeof e == "string" ? {
1481
1735
  tag: e,
1482
1736
  input: {}
1483
1737
  } : {
1484
1738
  tag: e.tag,
1485
1739
  input: e.input?.(t) ?? {}
1486
- }, cr = async (e) => {
1740
+ }, Zr = async (e) => {
1487
1741
  let { pageMod: t, params: n, query: r, apiName: i, seed: a, seedFailure: o, onError: s } = e;
1488
- if (or(t) && r !== void 0 && i !== void 0) for (let e of t.preload) {
1489
- let { tag: t, input: c } = sr(e, n);
1742
+ if (Yr(t) && r !== void 0 && i !== void 0) for (let e of t.preload) {
1743
+ let { tag: t, input: c } = Xr(e, n);
1490
1744
  try {
1491
1745
  a(i, t, c, await r(t, c));
1492
1746
  } catch (e) {
@@ -1496,62 +1750,62 @@ import {
1496
1750
  }, e);
1497
1751
  }
1498
1752
  }
1499
- }, lr = (e) => a.test(e) || e.endsWith(".workflow.server.tsx") ? !1 : o.test(e) || l.test(e) || i.test(e), ur = /* @__PURE__ */ new Set([
1753
+ }, Qr = (e) => a.test(e) || e.endsWith(".workflow.server.tsx") ? !1 : o.test(e) || l.test(e) || i.test(e), $r = /* @__PURE__ */ new Set([
1500
1754
  "node_modules",
1501
1755
  "dist",
1502
1756
  ".framework",
1503
1757
  ".git"
1504
- ]), dr = async (e) => {
1758
+ ]), ei = async (e) => {
1505
1759
  let t = [], n = async (e) => {
1506
1760
  let r;
1507
1761
  try {
1508
- r = await M.readdir(e, { withFileTypes: !0 });
1762
+ r = await N.readdir(e, { withFileTypes: !0 });
1509
1763
  } catch {
1510
1764
  return;
1511
1765
  }
1512
1766
  for (let i of r) if (!(i.name.startsWith(".") && i.isDirectory())) {
1513
1767
  if (i.isDirectory()) {
1514
- if (ur.has(i.name)) continue;
1768
+ if ($r.has(i.name)) continue;
1515
1769
  await n(O(e, i.name));
1516
- } else lr(i.name) && t.push(O(e, i.name));
1770
+ } else Qr(i.name) && t.push(O(e, i.name));
1517
1771
  }
1518
1772
  };
1519
1773
  return await n(e), t.sort();
1520
- }, fr = async (e) => {
1521
- let t = pe("sha1");
1522
- for (let n of await dr(e)) {
1774
+ }, ti = async (e) => {
1775
+ let t = ge("sha1");
1776
+ for (let n of await ei(e)) {
1523
1777
  t.update(n.slice(e.length)), t.update("\0");
1524
1778
  try {
1525
- t.update(await M.readFile(n));
1779
+ t.update(await N.readFile(n));
1526
1780
  } catch {}
1527
1781
  t.update("\0");
1528
1782
  }
1529
1783
  try {
1530
- t.update(await M.readFile(O(e, "rpcGroup.generated.ts")));
1784
+ t.update(await N.readFile(O(e, "rpcGroup.generated.ts")));
1531
1785
  } catch {}
1532
1786
  return t.digest("hex");
1533
- }, pr = async (e) => {
1787
+ }, ni = async (e) => {
1534
1788
  if (e.length === 0) return;
1535
1789
  let t = [];
1536
- for (let n of [...e].sort()) t.push(await fr(n));
1537
- return pe("sha1").update(t.join("\0")).digest("hex");
1538
- }, mr = (e) => typeof e == "object" && !!e && e._tag === "VoltroMiddleware" && typeof e.run == "function", hr = ["middleware.ts", "middleware.tsx"], gr = (e) => {
1790
+ for (let n of [...e].sort()) t.push(await ti(n));
1791
+ return ge("sha1").update(t.join("\0")).digest("hex");
1792
+ }, ri = (e) => typeof e == "object" && !!e && e._tag === "VoltroMiddleware" && typeof e.run == "function", ii = ["middleware.ts", "middleware.tsx"], ai = (e) => {
1539
1793
  let t = e.replace(/\/+$/, "");
1540
1794
  return t === "" ? "/" : t;
1541
- }, Z = (e, t) => {
1542
- let n = gr(e);
1795
+ }, X = (e, t) => {
1796
+ let n = ai(e);
1543
1797
  if (n === "/") return !0;
1544
- let r = gr(t);
1798
+ let r = ai(t);
1545
1799
  return r === n || r.startsWith(`${n}/`);
1546
- }, _r = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, vr = (e, t) => {
1800
+ }, oi = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, si = (e, t) => {
1547
1801
  if (e === void 0) return !0;
1548
- let n = _r(e.under), r = e.routes ?? [];
1549
- return n.length === 0 && r.length === 0 || r.includes(t) || n.some((e) => Z(e, t)) ? !(e.except ?? []).some((e) => e === t || Z(e, t)) : !1;
1550
- }, yr = (e) => {
1802
+ let n = oi(e.under), r = e.routes ?? [];
1803
+ return n.length === 0 && r.length === 0 || r.includes(t) || n.some((e) => X(e, t)) ? !(e.except ?? []).some((e) => e === t || X(e, t)) : !1;
1804
+ }, ci = (e) => {
1551
1805
  if (e?.assets !== !0) return [];
1552
- let t = _r(e.under);
1806
+ let t = oi(e.under);
1553
1807
  return t.length > 0 ? t : (e.routes ?? []).length > 0 ? [] : ["/"];
1554
- }, br = (e, t) => yr(e).some((e) => Z(e, t)) ? !(e?.except ?? []).some((e) => Z(e, t)) : !1, xr = (e, t) => e.find(({ middleware: e }) => t.route === void 0 ? br(e.match, t.pathname) : vr(e.match, t.route))?.middleware, Sr = (e, t) => {
1808
+ }, li = (e, t) => ci(e).some((e) => X(e, t)) ? !(e?.except ?? []).some((e) => X(e, t)) : !1, ui = (e, t) => e.find(({ middleware: e }) => t.route === void 0 ? li(e.match, t.pathname) : si(e.match, t.route))?.middleware, di = (e, t) => {
1555
1809
  let n = [];
1556
1810
  for (let { exportName: r, middleware: i } of e) {
1557
1811
  let e = i.match;
@@ -1559,13 +1813,13 @@ import {
1559
1813
  kind: "dead-matcher",
1560
1814
  message: `\`${r}\` matches routes: ['${i}'], which is not a route in this app. Route patterns are spelled as the router spells them, e.g. \`/notes/[id]\`.`
1561
1815
  });
1562
- if (e?.assets !== !0) for (let [i, a] of [["under", _r(e?.under)], ["except", e?.except ?? []]]) for (let e of a) t.some((t) => Z(e, t)) || n.push({
1816
+ if (e?.assets !== !0) for (let [i, a] of [["under", oi(e?.under)], ["except", e?.except ?? []]]) for (let e of a) t.some((t) => X(e, t)) || n.push({
1563
1817
  kind: "dead-matcher",
1564
1818
  message: `\`${r}\` matches ${i}: ['${e}'], which covers no route in this app. ` + (i === "except" ? "An `except` that excludes nothing is a rule that reads as active and is not." : "Add `assets: true` if you meant a path the router does not serve.")
1565
1819
  });
1566
1820
  }
1567
1821
  for (let r = 0; r < e.length; r += 1) for (let i = r + 1; i < e.length; i += 1) {
1568
- let a = e[r], o = e[i], s = t.find((e) => vr(a.middleware.match, e) && vr(o.middleware.match, e));
1822
+ let a = e[r], o = e[i], s = t.find((e) => si(a.middleware.match, e) && si(o.middleware.match, e));
1569
1823
  if (s !== void 0) {
1570
1824
  n.push({
1571
1825
  kind: "overlap",
@@ -1574,7 +1828,7 @@ import {
1574
1828
  continue;
1575
1829
  }
1576
1830
  {
1577
- let e = yr(a.middleware.match), t = yr(o.middleware.match), r = e.some((e) => t.some((t) => Z(e, t) || Z(t, e))), i = (a.middleware.match?.except ?? []).some((e) => t.length > 0 && t.every((t) => Z(e, t))) || (o.middleware.match?.except ?? []).some((t) => e.length > 0 && e.every((e) => Z(t, e)));
1831
+ let e = ci(a.middleware.match), t = ci(o.middleware.match), r = e.some((e) => t.some((t) => X(e, t) || X(t, e))), i = (a.middleware.match?.except ?? []).some((e) => t.length > 0 && t.every((t) => X(e, t))) || (o.middleware.match?.except ?? []).some((t) => e.length > 0 && e.every((e) => X(t, e)));
1578
1832
  r && !i && n.push({
1579
1833
  kind: "overlap",
1580
1834
  message: `\`${a.exportName}\` and \`${o.exportName}\` both declare \`assets: true\` over overlapping paths. A non-page request would match both, and there is no route to tell them apart.`
@@ -1582,10 +1836,10 @@ import {
1582
1836
  }
1583
1837
  }
1584
1838
  return n;
1585
- }, Cr = (e, t) => {
1586
- let r = Sr(e, t);
1839
+ }, fi = (e, t) => {
1840
+ let r = di(e, t);
1587
1841
  if (r.length !== 0) throw n(`middleware.ts: ${r.length} problem(s)\n\n` + r.map((e) => ` • ${e.message}`).join("\n\n"));
1588
- }, wr = (e) => {
1842
+ }, pi = (e) => {
1589
1843
  let t = {};
1590
1844
  if (!e) return t;
1591
1845
  for (let n of e.split(";")) {
@@ -1599,11 +1853,11 @@ import {
1599
1853
  }
1600
1854
  }
1601
1855
  return t;
1602
- }, Tr = (e) => Object.entries(e).map(([e, t]) => `${e}=${encodeURIComponent(t)}`).join("; "), Er = /(^|[-_.])(auth[-_.]?token|session|access[-_.]?token)([-_.]|$)|^sb-.*-auth-token$/i, Dr = (e) => e.httpOnly === void 0 && Er.test(e.name), Or = (e) => {
1856
+ }, mi = (e) => Object.entries(e).map(([e, t]) => `${e}=${encodeURIComponent(t)}`).join("; "), hi = /(^|[-_.])(auth[-_.]?token|session|access[-_.]?token)([-_.]|$)|^sb-.*-auth-token$/i, gi = (e) => e.httpOnly === void 0 && hi.test(e.name), _i = (e) => {
1603
1857
  let t = [`${e.name}=${encodeURIComponent(e.value)}`];
1604
1858
  return t.push(`Path=${e.path ?? "/"}`), e.maxAge !== void 0 && t.push(`Max-Age=${Math.trunc(e.maxAge)}`), e.httpOnly !== !1 && t.push("HttpOnly"), e.secure === !0 && t.push("Secure"), t.push(`SameSite=${e.sameSite ?? "lax"}`), t.join("; ");
1605
- }, kr = (e) => e.length === 0 ? {} : { "set-cookie": e.map(Or) }, Ar = async (e, t = (e) => import(L(e).href)) => {
1606
- for (let r of hr) {
1859
+ }, vi = (e) => e.length === 0 ? {} : { "set-cookie": e.map(_i) }, yi = async (e, t = (e) => import(I(e).href)) => {
1860
+ for (let r of ii) {
1607
1861
  let i;
1608
1862
  try {
1609
1863
  i = await t(O(e, r));
@@ -1612,7 +1866,7 @@ import {
1612
1866
  if (t === "ERR_MODULE_NOT_FOUND" || t === "MODULE_NOT_FOUND") continue;
1613
1867
  throw e;
1614
1868
  }
1615
- let a = Object.entries(i ?? {}), o = a.filter((e) => mr(e[1])).map(([e, t]) => ({
1869
+ let a = Object.entries(i ?? {}), o = a.filter((e) => ri(e[1])).map(([e, t]) => ({
1616
1870
  exportName: e,
1617
1871
  middleware: t
1618
1872
  }));
@@ -1630,50 +1884,78 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1630
1884
  return o;
1631
1885
  }
1632
1886
  return [];
1633
- }, jr = async (e, t, n) => {
1887
+ }, bi = async (e, t, n) => {
1634
1888
  let r = {
1635
1889
  headers: t.headers,
1636
1890
  cookies: t.cookies,
1637
- setCookies: []
1891
+ setCookies: [],
1892
+ responseHeaders: {}
1638
1893
  };
1639
1894
  if (e === void 0) return r;
1640
1895
  let i = await e.run(t);
1641
1896
  if (!i) return r;
1642
1897
  let a = i.setCookies ?? [];
1643
- if (n !== void 0) for (let e of a) Dr(e) && n(e);
1898
+ if (n !== void 0) for (let e of a) gi(e) && n(e);
1644
1899
  let o = i.headers ? {
1645
1900
  ...t.headers,
1646
1901
  ...i.headers
1647
- } : { ...t.headers };
1902
+ } : { ...t.headers }, s = i.responseHeaders ?? {}, c = i.cspNonce === void 0 ? {} : { cspNonce: i.cspNonce };
1648
1903
  if (a.length === 0) return {
1649
1904
  headers: o,
1650
1905
  cookies: t.cookies,
1651
- setCookies: a
1906
+ setCookies: a,
1907
+ responseHeaders: s,
1908
+ ...c
1652
1909
  };
1653
- let s = { ...t.cookies };
1654
- for (let e of a) e.maxAge !== void 0 && e.maxAge <= 0 ? delete s[e.name] : s[e.name] = e.value;
1655
- return i.headers?.cookie === void 0 && (o.cookie = Tr(s)), {
1910
+ let l = { ...t.cookies };
1911
+ for (let e of a) e.maxAge !== void 0 && e.maxAge <= 0 ? delete l[e.name] : l[e.name] = e.value;
1912
+ return i.headers?.cookie === void 0 && (o.cookie = mi(l)), {
1656
1913
  headers: o,
1657
- cookies: s,
1658
- setCookies: a
1914
+ cookies: l,
1915
+ setCookies: a,
1916
+ responseHeaders: s,
1917
+ ...c
1659
1918
  };
1660
- }, Q = z({ scope: "voltro:dev:web" }), Mr = z({ scope: "vite" }), Nr = await (async () => {
1919
+ }, xi = /* @__PURE__ */ new Set(["voltro:locale"]), Si = /* @__PURE__ */ new Set(["authorization", "cookie"]), Ci = (e) => {
1920
+ let t = e.split(";").map((e) => e.trim()).filter((e) => {
1921
+ let t = e.indexOf("="), n = (t === -1 ? e : e.slice(0, t)).trim();
1922
+ return xi.has(n);
1923
+ });
1924
+ return t.length > 0 ? t.join("; ") : void 0;
1925
+ }, wi = (e) => {
1926
+ let t = {};
1927
+ for (let [n, r] of Object.entries(e)) if (!n.startsWith("x-voltro-")) {
1928
+ if (Si.has(n)) {
1929
+ if (n === "cookie") {
1930
+ let e = Ci(r);
1931
+ e !== void 0 && (t.cookie = e);
1932
+ }
1933
+ continue;
1934
+ }
1935
+ t[n] = r;
1936
+ }
1937
+ return t;
1938
+ }, Ti = (e) => {
1939
+ let t = {};
1940
+ for (let [n, r] of Object.entries(e)) xi.has(n) && (t[n] = r);
1941
+ return t;
1942
+ }, Z = R({ scope: "voltro:dev:web" }), Ei = R({ scope: "vite" }), Di = await (async () => {
1661
1943
  try {
1662
- let e = O(D(te(import.meta.url)), "..", "package.json"), t = await M.readFile(e, "utf8");
1944
+ let e = O(D(re(import.meta.url)), "..", "package.json"), t = await N.readFile(e, "utf8");
1663
1945
  return JSON.parse(t).version ?? "0.0.0";
1664
1946
  } catch {
1665
1947
  return "0.0.0";
1666
1948
  }
1667
- })(), Pr = async () => {
1949
+ })(), Oi = async () => {
1668
1950
  try {
1669
- let e = D(te(import.meta.url)), t = A(e, "..", "..", "devtools");
1670
- if (j(O(t, "package.json"))) return t;
1951
+ let e = D(re(import.meta.url)), t = A(e, "..", "..", "devtools");
1952
+ if (M(O(t, "package.json"))) return t;
1671
1953
  let n = A(e, "..", "..", "..", "devtools");
1672
- return j(O(n, "package.json")) ? n : null;
1954
+ return M(O(n, "package.json")) ? n : null;
1673
1955
  } catch {
1674
1956
  return null;
1675
1957
  }
1676
- }, Fr = (e, t) => e.disableDevtools || !t ? [] : [
1958
+ }, ki = (e, t) => e.disableDevtools || !t ? [] : [
1677
1959
  "",
1678
1960
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1679
1961
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1683,46 +1965,44 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1683
1965
  " await import('@voltro/devtools/styles.css')",
1684
1966
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1685
1967
  "}"
1686
- ], Ir = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], Lr = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Rr = (e) => e.sentry ? [
1968
+ ], Ai = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ji = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Mi = (e) => e.sentry ? [
1687
1969
  "",
1688
1970
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1689
1971
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1690
1972
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1691
- ] : [], zr = (e) => e.env ? ["import './env.public'"] : [], Br = (e) => {
1973
+ ] : [], Ni = (e) => e.env ? ["import './env.public'"] : [], Pi = (e) => {
1692
1974
  let t = [], n = A(e);
1693
1975
  for (;;) {
1694
- j(O(n, "pnpm-workspace.yaml")) && t.push(n);
1976
+ M(O(n, "pnpm-workspace.yaml")) && t.push(n);
1695
1977
  let e = D(n);
1696
1978
  if (e === n) break;
1697
1979
  n = e;
1698
1980
  }
1699
1981
  return t;
1700
- }, Vr = b, Hr = (e) => {
1982
+ }, Fi = b, Ii = (e) => {
1701
1983
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
1702
- let t = /\/([^/]+)\.island\.tsx?$/.exec(e);
1703
- if (t) return `island-${t[1]}`;
1704
- }, Ur = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Wr = (e) => e.startsWith("(") && e.endsWith(")"), Gr = (e) => e.filter((e) => !Wr(e)), Kr = (e) => {
1705
- let t = e.replace(c, "").split("/").filter(Boolean).filter((e) => !Wr(e));
1984
+ }, Li = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Ri = (e) => e.startsWith("(") && e.endsWith(")"), zi = (e) => e.filter((e) => !Ri(e)), Bi = (e) => {
1985
+ let t = e.replace(c, "").split("/").filter(Boolean).filter((e) => !Ri(e));
1706
1986
  return t.length === 0 ? "/" : "/" + t.join("/");
1707
- }, qr = (e) => `${e.replace(c, "").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}`, Jr = async (e) => {
1987
+ }, Vi = (e) => `${e.replace(c, "").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`, Q = (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}`, $ = async (e) => {
1708
1988
  let t = [], n = [], r = async (e, i) => {
1709
1989
  let a = [];
1710
1990
  try {
1711
- a = await M.readdir(e, { withFileTypes: !0 });
1991
+ a = await N.readdir(e, { withFileTypes: !0 });
1712
1992
  } catch {
1713
1993
  return;
1714
1994
  }
1715
- let o = a.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = a.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Vr(e.name)).map((e) => e.name).sort(), u = new Set(l), d = i.join("/");
1995
+ let o = a.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = a.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !Fi(e.name)).map((e) => e.name).sort(), u = new Set(l), d = i.join("/");
1716
1996
  if (l.some((e) => s.has(e))) {
1717
1997
  let t = u.has("layout.tsx"), r = !1;
1718
1998
  if (t) try {
1719
- let t = await M.readFile(O(e, "layout.tsx"), "utf8");
1720
- r = Ur.test(t);
1999
+ let t = await N.readFile(O(e, "layout.tsx"), "utf8");
2000
+ r = Li.test(t);
1721
2001
  } catch {}
1722
2002
  n.push({
1723
2003
  dir: d,
1724
2004
  chain: i,
1725
- contributesToUrl: i.length === 0 || !Wr(i[i.length - 1]),
2005
+ contributesToUrl: i.length === 0 || !Ri(i[i.length - 1]),
1726
2006
  hasLayout: t,
1727
2007
  hasLayoutLoader: r,
1728
2008
  hasError: u.has("error.tsx"),
@@ -1736,8 +2016,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1736
2016
  let n = d ? `${d}/${e}` : e;
1737
2017
  t.push({
1738
2018
  file: n,
1739
- pattern: Kr(n),
1740
- ident: qr(n),
2019
+ pattern: Bi(n),
2020
+ ident: Vi(n),
1741
2021
  dirChain: i
1742
2022
  });
1743
2023
  }
@@ -1756,14 +2036,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1756
2036
  dirs: a,
1757
2037
  orphanedSpecials: o
1758
2038
  };
1759
- }, Yr = (e, t) => {
2039
+ }, Hi = (e, t) => {
1760
2040
  let n = [];
1761
2041
  for (let r = 0; r <= t.length; r++) {
1762
2042
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
1763
2043
  a && n.push(a);
1764
2044
  }
1765
2045
  return n;
1766
- }, Xr = async (e) => {
2046
+ }, Ui = async (e) => {
1767
2047
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
1768
2048
  return {
1769
2049
  chain: await Promise.all(t.map(async (e, t) => {
@@ -1787,10 +2067,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1787
2067
  })),
1788
2068
  segmentLoaderData: o
1789
2069
  };
1790
- }, Zr = (e) => {
1791
- let t = Gr(e);
2070
+ }, Wi = (e) => {
2071
+ let t = zi(e);
1792
2072
  return t.length === 0 ? "" : "/" + t.join("/");
1793
- }, Qr = [
2073
+ }, Gi = [
1794
2074
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
1795
2075
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
1796
2076
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -1883,7 +2163,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1883
2163
  " _vdtErrorStart('Build error')",
1884
2164
  " })",
1885
2165
  "}"
1886
- ].join("\n"), $r = (e) => {
2166
+ ].join("\n"), Ki = (e) => {
1887
2167
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
1888
2168
  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, "\\$&"));
1889
2169
  let a = i.join("/");
@@ -1892,8 +2172,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1892
2172
  paramNames: t,
1893
2173
  priority: n
1894
2174
  };
1895
- }, ei = (e) => e.map((e) => {
1896
- let { regex: t, paramNames: n, priority: r } = $r(e.pattern);
2175
+ }, qi = (e) => e.map((e) => {
2176
+ let { regex: t, paramNames: n, priority: r } = Ki(e.pattern);
1897
2177
  return {
1898
2178
  pattern: e.pattern,
1899
2179
  file: e.file,
@@ -1902,7 +2182,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1902
2182
  paramNames: n,
1903
2183
  priority: r
1904
2184
  };
1905
- }).slice().sort((e, t) => e.priority - t.priority), ti = (e, t) => {
2185
+ }).slice().sort((e, t) => e.priority - t.priority), Ji = (e, t) => {
1906
2186
  for (let n of t) {
1907
2187
  let t = n.regex.exec(e);
1908
2188
  if (!t) continue;
@@ -1914,9 +2194,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1914
2194
  };
1915
2195
  }
1916
2196
  return null;
1917
- }, ni = J, ri = async (e) => {
2197
+ }, Yi = Le, Xi = async (e) => {
1918
2198
  try {
1919
- let t = await import(L(O(e, "app.config.ts")).href), n = t.default?.port, i = r({
2199
+ let t = await import(I(O(e, "app.config.ts")).href), n = t.default?.port, i = r({
1920
2200
  kind: "api",
1921
2201
  configPort: typeof n == "number" ? n : void 0,
1922
2202
  env: {}
@@ -1930,7 +2210,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1930
2210
  kind: "api",
1931
2211
  env: {}
1932
2212
  }).port };
1933
- }, ii = (e, t) => ({
2213
+ }, Zi = (e, t) => ({
1934
2214
  name: e,
1935
2215
  pkg: t.package,
1936
2216
  browserWsUrl: t.url,
@@ -1938,7 +2218,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1938
2218
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
1939
2219
  ...t.headers ? { headers: t.headers } : {},
1940
2220
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1941
- }), ai = (e, t, n) => {
2221
+ }), Qi = (e, t, n) => {
1942
2222
  let r = t.transport?.wsPath ?? n.wsPath;
1943
2223
  return {
1944
2224
  name: e,
@@ -1950,7 +2230,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1950
2230
  ...t.headers ? { headers: t.headers } : {},
1951
2231
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
1952
2232
  };
1953
- }, oi = (e) => {
2233
+ }, $i = (e) => {
1954
2234
  let t = /* @__PURE__ */ new Map();
1955
2235
  for (let n of e) {
1956
2236
  if (n.proxyTarget === void 0) continue;
@@ -1958,43 +2238,43 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1958
2238
  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>.`);
1959
2239
  t.set(n.browserWsUrl, n.name);
1960
2240
  }
1961
- }, si = async (e, t) => {
2241
+ }, ea = async (e, t) => {
1962
2242
  let n = Object.entries(t.apis ?? {}), r = [];
1963
2243
  for (let [t, i] of n) {
1964
2244
  if (i.url) {
1965
- r.push(ii(t, i));
2245
+ r.push(Zi(t, i));
1966
2246
  continue;
1967
2247
  }
1968
- let n = await ni(e, i.package);
2248
+ let n = await Yi(e, i.package);
1969
2249
  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.`);
1970
- r.push(ai(t, i, await ri(n)));
2250
+ r.push(Qi(t, i, await Xi(n)));
1971
2251
  }
1972
- return oi(r), r;
1973
- }, ci = (e) => {
2252
+ return $i(r), r;
2253
+ }, ta = (e) => {
1974
2254
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
1975
2255
  let t = new URL(e);
1976
2256
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
1977
2257
  } catch {
1978
2258
  return;
1979
2259
  }
1980
- }, li = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, ui = (e) => process.env[li(e)] ?? process.env.VOLTRO_API_ORIGIN, di = (e, t) => {
2260
+ }, na = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, ra = (e) => process.env[na(e)] ?? process.env.VOLTRO_API_ORIGIN, ia = (e, t) => {
1981
2261
  if (!e) return;
1982
- let n = ui(e.name) ?? e.serverOrigin;
2262
+ let n = ra(e.name) ?? e.serverOrigin;
1983
2263
  if (n) {
1984
- let e = ci(n);
2264
+ let e = ta(n);
1985
2265
  if (e) return e;
1986
2266
  }
1987
2267
  if (t?.allowDevProxy && e.proxyTarget) {
1988
- let t = ci(e.proxyTarget);
2268
+ let t = ta(e.proxyTarget);
1989
2269
  if (t) return t;
1990
2270
  }
1991
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return ci(e.browserWsUrl);
1992
- }, fi = (e, t, n) => {
2271
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return ta(e.browserWsUrl);
2272
+ }, aa = (e, t, n) => {
1993
2273
  if (!e) {
1994
2274
  if (n?.apiName === void 0) return;
1995
2275
  let e = n.apiName;
1996
2276
  return async () => {
1997
- 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 ${li(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.`);
2277
+ 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 ${na(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.`);
1998
2278
  };
1999
2279
  }
2000
2280
  return async (r, i) => {
@@ -2017,7 +2297,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2017
2297
  });
2018
2298
  } catch (t) {
2019
2299
  let i = t?.cause?.code ?? String(t?.message ?? t);
2020
- throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${li(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 });
2300
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${na(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 });
2021
2301
  }
2022
2302
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2023
2303
  let s = await o.json();
@@ -2047,8 +2327,20 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2047
2327
  }
2048
2328
  if (u) return l;
2049
2329
  };
2050
- }, pi = async (e, t, n, r = {}) => {
2051
- let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = j(O(e, "node_modules", "@voltro", "devtools", "package.json")) || await Pr() !== null, s = t.theme === "system" ? [
2330
+ }, oa = (e, t) => {
2331
+ 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'`);
2332
+ 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"));
2333
+ let a = (e) => {
2334
+ let t = [`group: ${n(e.name)}`];
2335
+ return t.push(`descriptors: ${r(e.name)}`), t.push(`wsUrl: ${JSON.stringify(e.browserWsUrl)}`), e.hasAuthHeaders ? t.push(`headers: __voltroAuthHeaders?.[${JSON.stringify(e.name)}]?.authHeaders`) : e.headers && t.push(`headers: ${JSON.stringify(e.headers)}`), t;
2336
+ };
2337
+ return {
2338
+ imports: i,
2339
+ entryLines: e.map((e) => ` ${JSON.stringify(e.name)}: { ${a(e).join(", ")} },`),
2340
+ providerEntryLines: e.map((e) => ` { name: ${JSON.stringify(e.name)}, ${a(e).join(", ")} },`)
2341
+ };
2342
+ }, sa = async (e, t, n, r = {}) => {
2343
+ let i = t.title ?? t.name ?? "app", a = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", o = M(O(e, "node_modules", "@voltro", "devtools", "package.json")) || await Oi() !== null, s = t.theme === "system" ? [
2052
2344
  " <script>",
2053
2345
  " (function () {",
2054
2346
  " var root = document.documentElement",
@@ -2069,7 +2361,19 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2069
2361
  " }",
2070
2362
  " })()",
2071
2363
  " <\/script>"
2072
- ].join("\n") : "", c = [
2364
+ ].join("\n") : "", c = t.timeZone === "viewer" ? [
2365
+ " <script>",
2366
+ " (function () {",
2367
+ " try {",
2368
+ " if (/(?:^|;\\s*)voltro:tz=/.test(document.cookie)) return",
2369
+ " var tz = Intl.DateTimeFormat().resolvedOptions().timeZone",
2370
+ " if (!tz) return",
2371
+ " document.cookie = 'voltro:tz=' + encodeURIComponent(tz)",
2372
+ " + '; path=/; max-age=31536000; SameSite=Lax'",
2373
+ " } catch (e) {}",
2374
+ " })()",
2375
+ " <\/script>"
2376
+ ].join("\n") : "", l = [
2073
2377
  "<!doctype html>",
2074
2378
  "<!-- GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot. -->",
2075
2379
  `<html lang="en"${a}>`,
@@ -2079,6 +2383,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2079
2383
  ` <title>${i}</title>`,
2080
2384
  " <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />",
2081
2385
  ...s ? [s] : [],
2386
+ ...c ? [c] : [],
2082
2387
  " </head>",
2083
2388
  " <body>",
2084
2389
  " <div id=\"root\"></div>",
@@ -2086,75 +2391,70 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2086
2391
  " </body>",
2087
2392
  "</html>",
2088
2393
  ""
2089
- ].join("\n"), l = O(e, "src", "pages"), { pages: u, dirs: d, orphanedSpecials: f } = await Jr(l);
2090
- await y(l, u);
2091
- for (let e of f) 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.`);
2092
- let p = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppGroup`, m = (e) => `${e.replace(/[^a-zA-Z0-9]/g, "_")}AppDescriptors`, h = n.map((e) => `import { appGroup as ${p(e.name)}, appDescriptors as ${m(e.name)} } from '${e.pkg}/rpcGroup'`);
2093
- n.some((e) => e.hasAuthHeaders) && (h.push("import __voltroAppConfig from '../app.config'"), h.push("const __voltroAuthHeaders = (__voltroAppConfig as { readonly apis?: Record<string, { readonly authHeaders?: () => Record<string, string> | Promise<Record<string, string>> }> }).apis"));
2094
- let g = n.map((e) => {
2095
- let t = [`group: ${p(e.name)}`];
2096
- return t.push(`descriptors: ${m(e.name)}`), t.push(`wsUrl: ${JSON.stringify(e.browserWsUrl)}`), e.hasAuthHeaders ? t.push(`headers: __voltroAuthHeaders?.[${JSON.stringify(e.name)}]?.authHeaders`) : e.headers && t.push(`headers: ${JSON.stringify(e.headers)}`), ` ${JSON.stringify(e.name)}: { ${t.join(", ")} },`;
2097
- }), _, v, b;
2098
- if (u.length > 0) {
2099
- let n = u.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2100
- for (let e of d) {
2394
+ ].join("\n"), u = O(e, "src", "pages"), { pages: d, dirs: f, orphanedSpecials: p } = await $(u);
2395
+ await y(u, d);
2396
+ for (let e of p) Z.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.`);
2397
+ let { imports: m, entryLines: h } = oa(n, "../app.config"), g, _, v;
2398
+ if (d.length > 0) {
2399
+ let n = d.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2400
+ for (let e of f) {
2101
2401
  let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`;
2102
- 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'`);
2402
+ e.hasLayout && e.hasLayoutLoader ? r.push(`import * as ${Q(e.dir, "Layout")}Mod from '${t}/layout.tsx'`) : e.hasLayout && r.push(`import ${Q(e.dir, "Layout")} from '${t}/layout.tsx'`), e.hasError && r.push(`import ${Q(e.dir, "Error")} from '${t}/error.tsx'`), e.hasPending && r.push(`import ${Q(e.dir, "Pending")} from '${t}/loading.tsx'`), e.hasNotFound && r.push(`import ${Q(e.dir, "NotFound")} from '${t}/not-found.tsx'`);
2103
2403
  }
2104
- let i = u.map((e) => {
2105
- let t = Yr(d, e.dirChain).map((e) => {
2404
+ let i = d.map((e) => {
2405
+ let t = Hi(f, e.dirChain).map((e) => {
2106
2406
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2107
2407
  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(", ")} }`;
2108
2408
  }).join(",\n");
2109
2409
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2110
- }), a = d.filter((e) => e.hasNotFound).map((e) => {
2111
- let t = Zr(e.chain), n = Yr(d, e.chain).map((e) => {
2410
+ }), a = f.filter((e) => e.hasNotFound).map((e) => {
2411
+ let t = Wi(e.chain), n = Hi(f, e.chain).map((e) => {
2112
2412
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2113
2413
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2114
2414
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
2115
2415
  return ` {\n prefix: ${JSON.stringify(t)},\n Component: refs.notFounds[${JSON.stringify(e.dir)}],${r}\n },`;
2116
- }), s = [], c = [], l = [], f = [], p = [], m = [];
2117
- for (let e of d) {
2416
+ }), s = [], c = [], l = [], u = [], p = [], y = [];
2417
+ for (let e of f) {
2118
2418
  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);
2119
- e.hasLayout && e.hasLayoutLoader ? (c.push(` ${a}: ${$(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${$(e.dir, "Layout")}Mod.loader,`), s.push({
2419
+ e.hasLayout && e.hasLayoutLoader ? (c.push(` ${a}: ${Q(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${Q(e.dir, "Layout")}Mod.loader,`), s.push({
2120
2420
  relPath: t,
2121
2421
  kind: "layout",
2122
2422
  slotKey: e.dir
2123
- })) : e.hasLayout && (c.push(` ${a}: ${$(e.dir, "Layout")},`), s.push({
2423
+ })) : e.hasLayout && (c.push(` ${a}: ${Q(e.dir, "Layout")},`), s.push({
2124
2424
  relPath: t,
2125
2425
  kind: "layout",
2126
2426
  slotKey: e.dir
2127
- })), e.hasError && (f.push(` ${a}: ${$(e.dir, "Error")},`), s.push({
2427
+ })), e.hasError && (u.push(` ${a}: ${Q(e.dir, "Error")},`), s.push({
2128
2428
  relPath: n,
2129
2429
  kind: "error",
2130
2430
  slotKey: e.dir
2131
- })), e.hasPending && (p.push(` ${a}: ${$(e.dir, "Pending")},`), s.push({
2431
+ })), e.hasPending && (p.push(` ${a}: ${Q(e.dir, "Pending")},`), s.push({
2132
2432
  relPath: r,
2133
2433
  kind: "pending",
2134
2434
  slotKey: e.dir
2135
- })), e.hasNotFound && (m.push(` ${a}: ${$(e.dir, "NotFound")},`), s.push({
2435
+ })), e.hasNotFound && (y.push(` ${a}: ${Q(e.dir, "NotFound")},`), s.push({
2136
2436
  relPath: i,
2137
2437
  kind: "notFound",
2138
2438
  slotKey: e.dir
2139
2439
  }));
2140
2440
  }
2141
- for (let e of u) s.push({
2441
+ for (let e of d) s.push({
2142
2442
  relPath: `../src/pages/${e.file}`,
2143
2443
  kind: "page",
2144
2444
  slotKey: e.pattern
2145
2445
  });
2146
- let y = s.map((e) => ` ${JSON.stringify(e.relPath)},`), x = s.map((e, t) => {
2446
+ let b = s.map((e) => ` ${JSON.stringify(e.relPath)},`), x = s.map((e, t) => {
2147
2447
  let n = JSON.stringify(e.slotKey);
2148
2448
  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 }`;
2149
- }), S = t.locales ?? [], C = S.length > 0 && S.every((t) => j(O(e, "src", "locales", `${t}.ts`)) || j(O(e, "src", "locales", `${t}.tsx`))), w = C, T = t.defaultLocale ?? S[0] ?? "en";
2150
- 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(", ")}]`);
2151
- let E = w ? [
2449
+ }), S = t.locales ?? [], C = S.length > 0 && S.every((t) => M(O(e, "src", "locales", `${t}.ts`)) || M(O(e, "src", "locales", `${t}.tsx`))), w = C, T = t.defaultLocale ?? S[0] ?? "en", E = t.router?.viewTransitions === !0 ? " viewTransitions" : "";
2450
+ if (S.length > 0 && !C && Z.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(", ")}]`);
2451
+ let D = w ? [
2152
2452
  "import { I18nProvider } from '@voltro/i18n'",
2153
2453
  "import { resolveLocale } from '@voltro/i18n/server'",
2154
2454
  "import { useServerRequest } from '@voltro/web'",
2155
2455
  ...S.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2156
2456
  ] : [];
2157
- v = [
2457
+ _ = [
2158
2458
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2159
2459
  "// Routes + per-page chain + not-found scopes assembled from src/pages/.",
2160
2460
  "//",
@@ -2194,13 +2494,13 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2194
2494
  ...l,
2195
2495
  " },",
2196
2496
  " errors: {",
2197
- ...f,
2497
+ ...u,
2198
2498
  " },",
2199
2499
  " pendings: {",
2200
2500
  ...p,
2201
2501
  " },",
2202
2502
  " notFounds: {",
2203
- ...m,
2503
+ ...y,
2204
2504
  " },",
2205
2505
  " pages: {},",
2206
2506
  "}",
@@ -2265,7 +2565,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2265
2565
  "if (import.meta.hot) {",
2266
2566
  " import.meta.hot.accept(",
2267
2567
  " [",
2268
- ...y,
2568
+ ...b,
2269
2569
  " ],",
2270
2570
  " (newMods: Array<Record<string, unknown> | undefined>) => {",
2271
2571
  " let changed = false",
@@ -2275,7 +2575,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2275
2575
  " )",
2276
2576
  "}",
2277
2577
  ""
2278
- ].join("\n"), _ = [
2578
+ ].join("\n"), g = [
2279
2579
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2280
2580
  "// The app's root component. It exports `App` and NOTHING ELSE: react-refresh",
2281
2581
  "// only accepts a module whose every export is a component, and a module it",
@@ -2286,7 +2586,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2286
2586
  "",
2287
2587
  "import { useMemo, useSyncExternalStore } from 'react'",
2288
2588
  "import { Router } from '@voltro/web'",
2289
- ...E,
2589
+ ...D,
2290
2590
  "import { subscribe, getVersion, buildRoutes, buildNotFounds } from './routeTable'",
2291
2591
  "",
2292
2592
  ...w ? [
@@ -2297,6 +2597,29 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2297
2597
  `const I18N_SUPPORTED: ReadonlyArray<string> = [${S.map((e) => JSON.stringify(e)).join(", ")}]`,
2298
2598
  `const I18N_DEFAULT = ${JSON.stringify(T)}`,
2299
2599
  "",
2600
+ "// The zone + clock the SERVER decided for this document, read back off",
2601
+ "// <html>. Same contract as <html lang> below and for the same reason:",
2602
+ "// the browser could answer both of these itself, its answer would",
2603
+ "// differ from the server's, and a difference is a hydration mismatch.",
2604
+ "//",
2605
+ "// Reading the ATTRIBUTE rather than the browser is the whole point.",
2606
+ "// 'Intl.DateTimeFormat().resolvedOptions().timeZone' is the viewer's",
2607
+ "// TRUE zone and is therefore the wrong value here — the server could",
2608
+ "// not know it, so it did not render with it. The app makes the server",
2609
+ "// know it by writing the 'voltro:tz' cookie (the pre-paint script",
2610
+ "// seeds it from the browser; a login overwrites it with the user's",
2611
+ "// own), and then the server's answer IS the viewer's zone.",
2612
+ "const readPublishedDocumentAttrs = (): { timeZone?: string; renderedAt?: number } => {",
2613
+ " if (typeof document === 'undefined') return {}",
2614
+ " const el = document.documentElement",
2615
+ " const tz = el.getAttribute('data-voltro-tz')",
2616
+ " const now = Number(el.getAttribute('data-voltro-now'))",
2617
+ " return {",
2618
+ " ...(tz ? { timeZone: tz } : {}),",
2619
+ " ...(Number.isFinite(now) && now > 0 ? { renderedAt: now } : {}),",
2620
+ " }",
2621
+ "}",
2622
+ "",
2300
2623
  "const pickI18nLocale = (ssr: ReturnType<typeof useServerRequest>): string => {",
2301
2624
  " if (ssr) {",
2302
2625
  " return resolveLocale({",
@@ -2350,28 +2673,37 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2350
2673
  " const ssr = useServerRequest()",
2351
2674
  " const locale = pickI18nLocale(ssr)",
2352
2675
  " const messages = I18N_CATALOGS[locale] ?? I18N_CATALOGS[I18N_DEFAULT]!",
2676
+ " // Read once per mount, not per render: the values are fixed for the",
2677
+ " // life of the document, and 'renderedAt' moving would defeat the",
2678
+ " // point of pinning it.",
2679
+ " const published = useMemo(readPublishedDocumentAttrs, [])",
2353
2680
  " return (",
2354
- " <I18nProvider locale={locale} messages={messages} defaultLocale={I18N_DEFAULT}>",
2355
- " <Router routes={routes} notFounds={notFounds} />",
2681
+ " <I18nProvider",
2682
+ " locale={locale}",
2683
+ " messages={messages}",
2684
+ " defaultLocale={I18N_DEFAULT}",
2685
+ " {...published}",
2686
+ " >",
2687
+ ` <Router routes={routes} notFounds={notFounds}${E} />`,
2356
2688
  " </I18nProvider>",
2357
2689
  " )"
2358
- ] : [" return <Router routes={routes} notFounds={notFounds} />"],
2690
+ ] : [` return <Router routes={routes} notFounds={notFounds}${E} />`],
2359
2691
  "}",
2360
2692
  ""
2361
- ].join("\n"), b = [
2693
+ ].join("\n"), v = [
2362
2694
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2363
2695
  "// Entry: imports the generated App component and calls mount() with the",
2364
2696
  "// resolved apis map. Side-effect only — no local component definitions —",
2365
2697
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2366
2698
  "",
2367
- ...zr(t),
2699
+ ...Ni(t),
2368
2700
  "import { mount } from '@voltro/web'",
2369
- ...h,
2701
+ ...m,
2370
2702
  "import { App } from './app'",
2371
2703
  "import { preloadCurrentRoute } from './routeTable'",
2372
- ...Lr(t),
2373
- ...Fr(t, o),
2374
- ...Rr(t),
2704
+ ...ji(t),
2705
+ ...ki(t, o),
2706
+ ...Mi(t),
2375
2707
  "",
2376
2708
  "// Preload the current route's page chunk BEFORE hydration so the first",
2377
2709
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2386,83 +2718,83 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2386
2718
  "",
2387
2719
  "mount(App, {",
2388
2720
  " apis: {",
2389
- ...g,
2721
+ ...h,
2390
2722
  " },",
2391
- ...Ir(t, o),
2723
+ ...Ai(t, o),
2392
2724
  "})",
2393
2725
  "",
2394
- Qr
2726
+ Gi
2395
2727
  ].join("\n");
2396
- } else _ = "", v = "", b = [
2728
+ } else g = "", _ = "", v = [
2397
2729
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2398
2730
  "// The user's root component lives at ../src/App.tsx; this file imports it",
2399
2731
  "// and calls mount(). Side-effect only, no component definitions, so the",
2400
2732
  "// user's component file remains the Fast Refresh boundary.",
2401
2733
  "",
2402
- ...zr(t),
2734
+ ...Ni(t),
2403
2735
  "import { mount } from '@voltro/web'",
2404
- ...h,
2736
+ ...m,
2405
2737
  "import App from '../src/App'",
2406
- ...Lr(t),
2407
- ...Fr(t, o),
2408
- ...Rr(t),
2738
+ ...ji(t),
2739
+ ...ki(t, o),
2740
+ ...Mi(t),
2409
2741
  "",
2410
2742
  "mount(App, {",
2411
2743
  " apis: {",
2412
- ...g,
2744
+ ...h,
2413
2745
  " },",
2414
- ...Ir(t, o),
2746
+ ...Ai(t, o),
2415
2747
  "})",
2416
2748
  "",
2417
- Qr
2749
+ Gi
2418
2750
  ].join("\n");
2419
- let x = O(e, ".framework");
2420
- await M.mkdir(x, { recursive: !0 }), t.env ? await Se(x, r) : await M.rm(O(x, "env.public.ts"), { force: !0 }), await M.writeFile(O(x, "index.html"), c, "utf8"), await M.writeFile(O(x, "main.tsx"), b, "utf8"), _ ? (await M.writeFile(O(x, "app.tsx"), _, "utf8"), await M.writeFile(O(x, "routeTable.ts"), v, "utf8")) : (await M.rm(O(x, "app.tsx"), { force: !0 }), await M.rm(O(x, "routeTable.ts"), { force: !0 }));
2421
- let S = O(e, ".gitignore"), C = "";
2751
+ let b = O(e, ".framework");
2752
+ await N.mkdir(b, { recursive: !0 }), t.env ? await Ne(b, r) : await N.rm(O(b, "env.public.ts"), { force: !0 }), await N.writeFile(O(b, "index.html"), l, "utf8"), await N.writeFile(O(b, "main.tsx"), v, "utf8"), g ? (await N.writeFile(O(b, "app.tsx"), g, "utf8"), await N.writeFile(O(b, "routeTable.ts"), _, "utf8")) : (await N.rm(O(b, "app.tsx"), { force: !0 }), await N.rm(O(b, "routeTable.ts"), { force: !0 }));
2753
+ let x = O(e, ".gitignore"), S = "";
2422
2754
  try {
2423
- C = await M.readFile(S, "utf8");
2755
+ S = await N.readFile(x, "utf8");
2424
2756
  } catch {}
2425
- let w = ["/.framework/"], T = new Set(C.split("\n").map((e) => e.trim())), E = w.filter((e) => !T.has(e));
2426
- if (E.length > 0) {
2427
- let e = C === "" || C.endsWith("\n") ? "" : "\n";
2757
+ let C = ["/.framework/"], w = new Set(S.split("\n").map((e) => e.trim())), T = C.filter((e) => !w.has(e));
2758
+ if (T.length > 0) {
2759
+ let e = S === "" || S.endsWith("\n") ? "" : "\n";
2428
2760
  try {
2429
- await M.appendFile(S, `${e}${E.join("\n")}\n`, "utf8");
2761
+ await N.appendFile(x, `${e}${T.join("\n")}\n`, "utf8");
2430
2762
  } catch (e) {
2431
- Q.warn(`could not add ${E.join(", ")} to ${S} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2763
+ Z.warn(`could not add ${T.join(", ")} to ${x} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2432
2764
  }
2433
2765
  }
2434
- }, mi = async (e, t) => {
2766
+ }, ca = async (e, t) => {
2435
2767
  try {
2436
2768
  let n = D(e), r = O(n, "project.json");
2437
- if (!j(r)) return;
2438
- let i = await M.readFile(r, "utf8"), a = JSON.parse(i).apps ?? {}, o = e.split("/").filter(Boolean).pop() ?? "", s = [];
2769
+ if (!M(r)) return;
2770
+ let i = await N.readFile(r, "utf8"), a = JSON.parse(i).apps ?? {}, o = e.split("/").filter(Boolean).pop() ?? "", s = [];
2439
2771
  for (let [e, n] of Object.entries(a)) e !== o && n.port === t && s.push(e);
2440
2772
  if (s.length === 0) return;
2441
- Q.warn("sibling app(s) claim the same port — only one boots", {
2773
+ Z.warn("sibling app(s) claim the same port — only one boots", {
2442
2774
  port: t,
2443
2775
  conflicts: s,
2444
2776
  projectJson: r
2445
2777
  });
2446
2778
  } catch {}
2447
- }, hi = (e) => O(e, ".framework", "dist", "server", "appConfig.js"), gi = async (e, t = {}) => {
2448
- let n = hi(e), r = t.preferSource !== !0 && j(n) ? n : O(e, "app.config.ts");
2779
+ }, la = (e) => O(e, ".framework", "dist", "server", "appConfig.js"), ua = async (e, t = {}) => {
2780
+ let n = la(e), r = t.preferSource !== !0 && M(n) ? n : O(e, "app.config.ts");
2449
2781
  try {
2450
- let e = (await import(L(r).href)).default;
2782
+ let e = (await import(I(r).href)).default;
2451
2783
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2452
2784
  } catch {
2453
2785
  return null;
2454
2786
  }
2455
- }, _i = async (e) => {
2456
- let n = await gi(e, { preferSource: !0 });
2787
+ }, da = async (e) => {
2788
+ let n = await ua(e, { preferSource: !0 });
2457
2789
  if (!n) return {
2458
2790
  ran: !1,
2459
2791
  exitCode: 0
2460
2792
  };
2461
- ln();
2462
- let i = St();
2463
- Bt(i), Q.info("booting voltro dev (web)", { app: n.name ?? "(unnamed)" }), We(e, Q);
2464
- let a = await si(e, n);
2465
- for (let e of a) Q.info("api wired", {
2793
+ ir();
2794
+ let i = vn();
2795
+ In(i), Z.info("booting voltro dev (web)", { app: n.name ?? "(unnamed)" }), nt(e, Z);
2796
+ let a = await ea(e, n);
2797
+ for (let e of a) Z.info("api wired", {
2466
2798
  name: e.name,
2467
2799
  pkg: e.pkg,
2468
2800
  ...e.proxyTarget ? { proxyTo: e.proxyTarget } : { directWs: e.browserWsUrl }
@@ -2470,17 +2802,17 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2470
2802
  g(e).then((e) => {
2471
2803
  for (let t of e.files) if (t.action === "created") {
2472
2804
  let e = t.path.split("/").pop() ?? t.path;
2473
- Q.info(`${e} seeded`, { path: t.path });
2805
+ Z.info(`${e} seeded`, { path: t.path });
2474
2806
  }
2475
2807
  }).catch(() => {});
2476
- let { resolved: o } = await Ce({
2808
+ let { resolved: o } = await Pe({
2477
2809
  rawEnv: n.env,
2478
2810
  appType: "web",
2479
2811
  root: e,
2480
- log: Q,
2812
+ log: Z,
2481
2813
  generateTypes: !0
2482
2814
  }), s = o.publicValues;
2483
- await pi(e, n, a, s), Q.debug("generated framework entry files", { files: [
2815
+ await sa(e, n, a, s), Z.debug("generated framework entry files", { files: [
2484
2816
  "index.html",
2485
2817
  ".framework/main.tsx",
2486
2818
  ...n.env ? [".framework/env.public.ts"] : []
@@ -2489,9 +2821,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2489
2821
  kind: "web",
2490
2822
  configPort: n.port,
2491
2823
  env: process.env,
2492
- dashboardPin: process.env[Tn] === "1"
2824
+ dashboardPin: process.env[br] === "1"
2493
2825
  });
2494
- for (let e of c.warnings) Q.warn(e);
2826
+ for (let e of c.warnings) Z.warn(e);
2495
2827
  let l = c.port, y = n.name ?? "unnamed", b = w("web", y, l), D = T(y);
2496
2828
  await x({
2497
2829
  id: b,
@@ -2501,22 +2833,22 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2501
2833
  pid: process.pid,
2502
2834
  status: "booting",
2503
2835
  logFile: D.path
2504
- }).catch(() => {}), await mi(e, l);
2505
- let { pages: N, dirs: P } = await Jr(O(e, "src", "pages")), F = {
2836
+ }).catch(() => {}), await ca(e, l);
2837
+ let { pages: j, dirs: P } = await $(O(e, "src", "pages")), F = {
2506
2838
  dirs: P,
2507
- ssrRoutes: ei(N)
2839
+ ssrRoutes: qi(j)
2508
2840
  }, ee = P.map((e) => ({
2509
2841
  dir: e.dir,
2510
2842
  hasLayout: e.hasLayout,
2511
2843
  hasError: e.hasError,
2512
2844
  hasPending: e.hasPending,
2513
2845
  hasNotFound: e.hasNotFound
2514
- })), I = await mt({
2846
+ })), te = await un({
2515
2847
  appRoot: e,
2516
- pages: N
2848
+ pages: j
2517
2849
  });
2518
- I.wrote && Q.debug("routes codegen wrote", { path: k(e, I.path) });
2519
- let te = await _e("vite", () => import("vite")), L = (await import("@vitejs/plugin-react")).default, R = (await import("@tailwindcss/vite")).default, z = O(e, ".framework"), B = O(e, "src"), V = /* @__PURE__ */ new Set([
2850
+ te.wrote && Z.debug("routes codegen wrote", { path: k(e, te.path) });
2851
+ let ne = await De("vite", () => import("vite")), re = (await import("@vitejs/plugin-react")).default, I = (await import("@tailwindcss/vite")).default, L = O(e, ".framework"), R = O(e, "src"), ie = /* @__PURE__ */ new Set([
2520
2852
  ".framework",
2521
2853
  "node_modules",
2522
2854
  "dist",
@@ -2524,64 +2856,64 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2524
2856
  ".vite",
2525
2857
  ".turbo",
2526
2858
  ".cache"
2527
- ]), re = {
2859
+ ]), B = {
2528
2860
  name: "framework:watch-app-sources",
2529
2861
  async configureServer(t) {
2530
2862
  try {
2531
- let n = (await M.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !V.has(e.name));
2863
+ let n = (await N.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !ie.has(e.name));
2532
2864
  for (let r of n) t.watcher.add(O(e, r.name));
2533
- n.length === 0 && t.watcher.add(B);
2865
+ n.length === 0 && t.watcher.add(R);
2534
2866
  } catch {
2535
- t.watcher.add(B);
2867
+ t.watcher.add(R);
2536
2868
  }
2537
- for (let n of await De(e)) t.watcher.add(n.dir);
2869
+ for (let n of await Re(e)) t.watcher.add(n.dir);
2538
2870
  }
2539
- }, H = O(e, "src", "pages"), U = (e) => e.endsWith(".tsx") && (e === H || e.startsWith(H + "/")), ie = (e) => e === H || e.startsWith(H + "/"), W = async (t) => {
2871
+ }, V = O(e, "src", "pages"), ae = (e) => e.endsWith(".tsx") && (e === V || e.startsWith(V + "/")), oe = (e) => e === V || e.startsWith(V + "/"), H = async (t) => {
2540
2872
  try {
2541
2873
  let r = Date.now();
2542
- await pi(e, n, a, s);
2543
- let { pages: i, dirs: o } = await Jr(H);
2544
- await mt({
2874
+ await sa(e, n, a, s);
2875
+ let { pages: i, dirs: o } = await $(V);
2876
+ await un({
2545
2877
  appRoot: e,
2546
2878
  pages: i
2547
- }), F.dirs = o, F.ssrRoutes = ei(i), Q.info("page tree regenerated", {
2879
+ }), F.dirs = o, F.ssrRoutes = qi(i), Z.info("page tree regenerated", {
2548
2880
  reason: t,
2549
2881
  ms: Date.now() - r,
2550
2882
  routes: F.ssrRoutes.length
2551
2883
  });
2552
- for (let e of Sr(X, F.ssrRoutes.map((e) => e.pattern))) Q.error(`middleware.ts: ${e.message}`);
2884
+ for (let e of di(J, F.ssrRoutes.map((e) => e.pattern))) Z.error(`middleware.ts: ${e.message}`);
2553
2885
  } catch (e) {
2554
- Q.error("page tree regen failed", { reason: t }, e);
2886
+ Z.error("page tree regen failed", { reason: t }, e);
2555
2887
  }
2556
- }, ae = {
2888
+ }, se = {
2557
2889
  name: "framework:regenerate-on-page-tree-change",
2558
2890
  configureServer(t) {
2559
2891
  let n = null, r = [], i = (e) => {
2560
2892
  r.push(e), n && clearTimeout(n), n = setTimeout(() => {
2561
2893
  n = null;
2562
2894
  let e = r.length === 1 ? r[0] : `${r.length} events (${r[0]}, …)`;
2563
- r.length = 0, W(e);
2895
+ r.length = 0, H(e);
2564
2896
  }, 50);
2565
2897
  };
2566
2898
  t.watcher.on("add", (t) => {
2567
- U(t) && i(`add ${k(e, t)}`);
2899
+ ae(t) && i(`add ${k(e, t)}`);
2568
2900
  }), t.watcher.on("unlink", (t) => {
2569
- U(t) && i(`unlink ${k(e, t)}`);
2901
+ ae(t) && i(`unlink ${k(e, t)}`);
2570
2902
  }), t.watcher.on("addDir", (t) => {
2571
- ie(t) && i(`addDir ${k(e, t)}`);
2903
+ oe(t) && i(`addDir ${k(e, t)}`);
2572
2904
  }), t.watcher.on("unlinkDir", (t) => {
2573
- ie(t) && i(`unlinkDir ${k(e, t)}`);
2905
+ oe(t) && i(`unlinkDir ${k(e, t)}`);
2574
2906
  });
2575
2907
  }
2576
- }, G = O(e, "app.config.ts"), se = (e) => {
2577
- if (!oe(e.env)) return "";
2908
+ }, U = O(e, "app.config.ts"), ce = (e) => {
2909
+ if (!ue(e.env)) return "";
2578
2910
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2579
2911
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2580
- }, ce = (e, t) => {
2912
+ }, le = (e, t) => {
2581
2913
  let n = [];
2582
- return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), se(e) !== se(t) && n.push("env"), n;
2583
- }, le = n, ue = A(G), de = () => {
2584
- let e = me(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2914
+ return e.port !== t.port && n.push(`port ${e.port ?? "(default)"} → ${t.port ?? "(default)"}`), JSON.stringify(e.proxies) !== JSON.stringify(t.proxies) && n.push("proxies"), JSON.stringify(e.allowedHosts) !== JSON.stringify(t.allowedHosts) && n.push("allowedHosts"), JSON.stringify(e.apis) !== JSON.stringify(t.apis) && n.push("apis"), ce(e) !== ce(t) && n.push("env"), n;
2915
+ }, W = n, de = A(U), fe = () => {
2916
+ let e = _e(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2585
2917
  stdio: "inherit",
2586
2918
  env: process.env,
2587
2919
  cwd: process.cwd()
@@ -2591,29 +2923,29 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2591
2923
  process.on("SIGINT", n), process.on("SIGTERM", r), e.on("exit", (e, t) => {
2592
2924
  process.off("SIGINT", n), process.off("SIGTERM", r), t ? process.kill(process.pid, t) : process.exit(e ?? 0);
2593
2925
  }), e.on("error", (e) => {
2594
- Q.error("restart spawn failed", {}, e), process.exit(1);
2926
+ Z.error("restart spawn failed", {}, e), process.exit(1);
2595
2927
  });
2596
- }, fe = {
2928
+ }, pe = {
2597
2929
  name: "framework:watch-app-config",
2598
2930
  async configureServer(n) {
2599
- n.watcher.add(G), Q.info("watching app.config.ts for changes", { path: k(e, G) });
2600
- let r = hr.map((t) => O(e, t)), i = new Set(r.map((e) => A(e)));
2931
+ n.watcher.add(U), Z.info("watching app.config.ts for changes", { path: k(e, U) });
2932
+ let r = ii.map((t) => O(e, t)), i = new Set(r.map((e) => A(e)));
2601
2933
  for (let e of r) n.watcher.add(e);
2602
2934
  n.watcher.on("all", (t, r) => {
2603
- i.has(A(r)) && (Q.warn("middleware.ts changed — restarting (it is loaded once per boot)", { path: k(e, r) }), n.close().catch(() => void 0).then(() => {
2604
- de();
2935
+ i.has(A(r)) && (Z.warn("middleware.ts changed — restarting (it is loaded once per boot)", { path: k(e, r) }), n.close().catch(() => void 0).then(() => {
2936
+ fe();
2605
2937
  }));
2606
2938
  });
2607
2939
  let a = async () => {
2608
2940
  try {
2609
2941
  try {
2610
- let e = n.moduleGraph.getModuleById(G);
2942
+ let e = n.moduleGraph.getModuleById(U);
2611
2943
  e && n.moduleGraph.invalidateModule(e);
2612
2944
  } catch {}
2613
- let e = (await n.ssrLoadModule(G, { fixStacktrace: !0 })).default;
2614
- return typeof e == "object" && e && "type" in e && e.type === "web" ? e : (Q.warn("app.config.ts re-load returned wrong shape", { hasDefault: e !== void 0 }), null);
2945
+ let e = (await n.ssrLoadModule(U, { fixStacktrace: !0 })).default;
2946
+ return typeof e == "object" && e && "type" in e && e.type === "web" ? e : (Z.warn("app.config.ts re-load returned wrong shape", { hasDefault: e !== void 0 }), null);
2615
2947
  } catch (e) {
2616
- return Q.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
2948
+ return Z.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
2617
2949
  }
2618
2950
  }, o = null, s = () => {
2619
2951
  o && clearTimeout(o), o = setTimeout(() => {
@@ -2622,104 +2954,104 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2622
2954
  }, c = async () => {
2623
2955
  let t = await a();
2624
2956
  if (!t) {
2625
- Q.info("app.config.ts onConfigChange: load returned null — skipping");
2957
+ Z.info("app.config.ts onConfigChange: load returned null — skipping");
2626
2958
  return;
2627
2959
  }
2628
- if (Q.info("app.config.ts onConfigChange: loaded", {
2960
+ if (Z.info("app.config.ts onConfigChange: loaded", {
2629
2961
  theme: t.theme,
2630
2962
  port: t.port,
2631
2963
  name: t.name
2632
- }), JSON.stringify(t) === JSON.stringify(le)) {
2633
- Q.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2964
+ }), JSON.stringify(t) === JSON.stringify(W)) {
2965
+ Z.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2634
2966
  return;
2635
2967
  }
2636
- let r = ce(le, t);
2968
+ let r = le(W, t);
2637
2969
  if (r.length > 0) {
2638
- Q.warn("app.config.ts changed — hard restart required", { fields: r });
2970
+ Z.warn("app.config.ts changed — hard restart required", { fields: r });
2639
2971
  try {
2640
2972
  await n.close();
2641
2973
  } catch {}
2642
- de();
2974
+ fe();
2643
2975
  return;
2644
2976
  }
2645
2977
  try {
2646
2978
  let r = Date.now();
2647
- await pi(e, t, await si(e, t)), le = t, n.ws && n.ws.send({
2979
+ await sa(e, t, await ea(e, t)), W = t, n.ws && n.ws.send({
2648
2980
  type: "full-reload",
2649
2981
  path: "*"
2650
- }), Q.info("app.config.ts soft-regen", {
2982
+ }), Z.info("app.config.ts soft-regen", {
2651
2983
  ms: Date.now() - r,
2652
2984
  reload: "full"
2653
2985
  });
2654
2986
  } catch (e) {
2655
- Q.error("app.config.ts soft-regen failed", {}, e);
2987
+ Z.error("app.config.ts soft-regen failed", {}, e);
2656
2988
  }
2657
- }, l = (e) => E(e) === "app.config.ts" ? e === G || A(e) === ue : !1;
2989
+ }, l = (e) => E(e) === "app.config.ts" ? e === U || A(e) === de : !1;
2658
2990
  n.watcher.on("change", (e) => {
2659
- l(e) && (Q.info("app.config.ts change event (chokidar)", { file: e }), s());
2991
+ l(e) && (Z.info("app.config.ts change event (chokidar)", { file: e }), s());
2660
2992
  }), n.watcher.on("add", (e) => {
2661
- l(e) && (Q.info("app.config.ts add event (chokidar)", { file: e }), s());
2993
+ l(e) && (Z.info("app.config.ts add event (chokidar)", { file: e }), s());
2662
2994
  });
2663
2995
  try {
2664
2996
  let { watchFile: e } = await import("node:fs");
2665
- e(G, { interval: 500 }, (e, t) => {
2666
- e.mtimeMs !== t.mtimeMs && (Q.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), s());
2667
- }), Q.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2997
+ e(U, { interval: 500 }, (e, t) => {
2998
+ e.mtimeMs !== t.mtimeMs && (Z.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), s());
2999
+ }), Z.info("app.config.ts polling watcher attached", { intervalMs: 500 });
2668
3000
  } catch (e) {
2669
- Q.warn("app.config.ts polling watcher could not attach", {}, e);
3001
+ Z.warn("app.config.ts polling watcher could not attach", {}, e);
2670
3002
  }
2671
- ke(t, Q, {
3003
+ Be(t, Z, {
2672
3004
  root: e,
2673
3005
  onBeforeRestart: () => n.close()
2674
3006
  });
2675
3007
  }
2676
- }, pe = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, K = 0, he = {
3008
+ }, me = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, G = 0, he = {
2677
3009
  name: "framework:suppress-api-hmr",
2678
3010
  handleHotUpdate(e) {
2679
- if (K += 1, pe.test(e.file)) return [];
3011
+ if (G += 1, me.test(e.file)) return [];
2680
3012
  }
2681
3013
  }, ge = {
2682
3014
  name: "framework:reoptimize-on-rpcgroup-change",
2683
3015
  async configureServer(t) {
2684
3016
  let n = [];
2685
3017
  for (let r of a) {
2686
- let i = await ni(e, r.pkg);
3018
+ let i = await Yi(e, r.pkg);
2687
3019
  if (i) {
2688
3020
  n.push(i);
2689
3021
  try {
2690
3022
  t.watcher.add(O(i, "rpcGroup.generated.ts"));
2691
3023
  } catch {}
2692
- for (let e of await dr(i)) try {
3024
+ for (let e of await ei(i)) try {
2693
3025
  t.watcher.add(e);
2694
3026
  } catch {}
2695
3027
  }
2696
3028
  }
2697
3029
  if (n.length === 0) return;
2698
- let r = await pr(n), i = null, o = !1, s = async () => {
3030
+ let r = await ni(n), i = null, o = !1, s = async () => {
2699
3031
  if (o) return;
2700
- let e = await pr(n);
3032
+ let e = await ni(n);
2701
3033
  if (e !== void 0 && e !== r) {
2702
- r = e, o = !0, Q.info("the api surface changed — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)");
3034
+ r = e, o = !0, Z.info("the api surface changed — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)");
2703
3035
  try {
2704
- await M.rm(O(z, ".vite", "deps"), {
3036
+ await N.rm(O(L, ".vite", "deps"), {
2705
3037
  recursive: !0,
2706
3038
  force: !0
2707
3039
  }), await t.restart(!0);
2708
3040
  } catch (e) {
2709
- o = !1, Q.error("rpcGroup re-optimize failed", {}, e);
3041
+ o = !1, Z.error("rpcGroup re-optimize failed", {}, e);
2710
3042
  }
2711
3043
  }
2712
3044
  }, c = (e) => {
2713
3045
  let t = A(e);
2714
- !lr(t) && !t.endsWith("rpcGroup.generated.ts") || (i && clearTimeout(i), i = setTimeout(() => {
3046
+ !Qr(t) && !t.endsWith("rpcGroup.generated.ts") || (i && clearTimeout(i), i = setTimeout(() => {
2715
3047
  s();
2716
3048
  }, 120));
2717
3049
  };
2718
3050
  t.watcher.on("change", c), t.watcher.on("add", c);
2719
3051
  }
2720
- }, q = {}, ve = (e) => (t) => {
3052
+ }, K = {}, ve = (e) => (t) => {
2721
3053
  t.on("proxyReq", (t, n) => {
2722
- sn(t, n, {
3054
+ nr(t, n, {
2723
3055
  target: e,
2724
3056
  token: process.env.VOLTRO_INSPECT_TOKEN,
2725
3057
  writeToken: process.env.VOLTRO_INSPECT_WRITE_TOKEN,
@@ -2729,14 +3061,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2729
3061
  };
2730
3062
  for (let e of a) {
2731
3063
  if (!e.proxyTarget) continue;
2732
- q[e.browserWsUrl] = {
3064
+ K[e.browserWsUrl] = {
2733
3065
  target: e.proxyTarget,
2734
3066
  ws: !0,
2735
3067
  changeOrigin: !0,
2736
3068
  ...e.wsPath ? {} : { rewrite: () => "/ws" }
2737
3069
  };
2738
3070
  let t = e.proxyTarget.replace(/^ws/, "http");
2739
- q[`/_voltro/api/${e.name}`] = {
3071
+ K[`/_voltro/api/${e.name}`] = {
2740
3072
  target: t,
2741
3073
  changeOrigin: !0,
2742
3074
  rewrite: (t) => t.replace(RegExp(`^/_voltro/api/${e.name}`), ""),
@@ -2744,15 +3076,15 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2744
3076
  };
2745
3077
  }
2746
3078
  for (let [e, t] of Object.entries(n.proxies ?? {})) {
2747
- if (q[e]) {
2748
- Q.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
3079
+ if (K[e]) {
3080
+ Z.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
2749
3081
  continue;
2750
3082
  }
2751
- q[e] = {
3083
+ K[e] = {
2752
3084
  target: t.target,
2753
3085
  changeOrigin: t.changeOrigin ?? !0,
2754
3086
  ...t.rewrite === void 0 ? {} : { rewrite: (n) => n.replace(RegExp(`^${e}`), t.rewrite) }
2755
- }, Q.info(`proxy ${e} → ${t.target}`, {
3087
+ }, Z.info(`proxy ${e} → ${t.target}`, {
2756
3088
  prefix: e,
2757
3089
  target: t.target,
2758
3090
  ...t.rewrite === void 0 ? {} : { rewrite: t.rewrite }
@@ -2764,7 +3096,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2764
3096
  let r = null, a = async () => {
2765
3097
  if (r !== null) return r;
2766
3098
  let n = [];
2767
- for (let r of N) try {
3099
+ for (let r of j) try {
2768
3100
  let i = await t.ssrLoadModule(O(e, "src", "pages", r.file));
2769
3101
  n.push({
2770
3102
  pattern: r.pattern,
@@ -2781,7 +3113,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2781
3113
  hasGetStaticPaths: typeof i.getStaticPaths == "function"
2782
3114
  });
2783
3115
  } catch (e) {
2784
- Q.warn("inspect: failed to load page metadata", { pattern: r.pattern }, e);
3116
+ Z.warn("inspect: failed to load page metadata", { pattern: r.pattern }, e);
2785
3117
  }
2786
3118
  return r = n, n;
2787
3119
  };
@@ -2801,9 +3133,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2801
3133
  }), n();
2802
3134
  }), t.middlewares.use((t, n, r) => {
2803
3135
  if (t.method !== "GET" && t.method !== "HEAD") return r();
2804
- let { pathname: i } = Hn(t.url ?? "/");
2805
- if (i !== "/robots.txt" || j(O(e, "public", "robots.txt"))) return r();
2806
- n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(bt({ indexable: !1 }));
3136
+ let { pathname: i } = $t(t.url ?? "/");
3137
+ if (i !== "/robots.txt" || M(O(e, "public", "robots.txt"))) return r();
3138
+ n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(gn({ indexable: !1 }));
2807
3139
  }), n.name === "voltroDashboard" && t.middlewares.use(async (e, t, n) => {
2808
3140
  let r = e.url ?? "", i = r.split("?")[0];
2809
3141
  if (i === "/api/dashboard/proxy") {
@@ -2894,7 +3226,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2894
3226
  for (let [t, n] of Object.entries(e.headers ?? {})) n !== void 0 && (s[String(t).toLowerCase()] = Array.isArray(n) ? n.join(", ") : String(n));
2895
3227
  let c = o.split("?")[0];
2896
3228
  if (e.method === "GET" && (c === "/_voltro/inspect/logs" || o.startsWith("/_voltro/inspect/logs?"))) {
2897
- let e = d(s.origin), n = en(o, Ft(), s);
3229
+ let e = d(s.origin), n = Xn(o, jn(), s);
2898
3230
  t.statusCode = n.status, t.setHeader("content-type", n.contentType);
2899
3231
  for (let [n, r] of Object.entries(e)) t.setHeader(n, r);
2900
3232
  t.end(n.body);
@@ -2912,7 +3244,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2912
3244
  e.setEncoding("utf-8"), e.on("data", (e) => {
2913
3245
  r += e;
2914
3246
  }), e.on("end", () => {
2915
- let e = Jt(r, i);
3247
+ let e = Wn(r, i);
2916
3248
  t.statusCode = e.status, t.setHeader("content-type", e.contentType);
2917
3249
  for (let [e, r] of Object.entries(n)) t.setHeader(e, r);
2918
3250
  t.end(e.body);
@@ -2943,14 +3275,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2943
3275
  for (let [e, r] of Object.entries(n)) t.setHeader(e, r);
2944
3276
  t.flushHeaders?.(), t.write("retry: 5000\n\n");
2945
3277
  let a = o.indexOf("?");
2946
- if (a === -1 || new URLSearchParams(o.slice(a + 1)).get("live") !== "1") for (let e of i.buffered()) t.write(Ct(e));
3278
+ if (a === -1 || new URLSearchParams(o.slice(a + 1)).get("live") !== "1") for (let e of i.buffered()) t.write(yn(e));
2947
3279
  let c = i.subscribe((e) => {
2948
3280
  try {
2949
- t.write(Ct(e));
3281
+ t.write(yn(e));
2950
3282
  } catch {}
2951
3283
  }), l = setInterval(() => {
2952
3284
  try {
2953
- t.write(wt());
3285
+ t.write(bn());
2954
3286
  } catch {}
2955
3287
  }, 15e3), p = () => {
2956
3288
  clearInterval(l), c();
@@ -2963,7 +3295,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2963
3295
  kind: "web",
2964
3296
  meta: {
2965
3297
  name: n.name ?? "(unnamed)",
2966
- voltroVersion: Nr,
3298
+ voltroVersion: Di,
2967
3299
  port: l,
2968
3300
  mode: "dev",
2969
3301
  apis: Object.entries(n.apis ?? {}).map(([e, t]) => {
@@ -2981,7 +3313,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2981
3313
  size: 0,
2982
3314
  entries: []
2983
3315
  }),
2984
- env: () => Te(n.name ?? "app", { contract: oe(n.env) ? n.env : void 0 })
3316
+ env: () => Fe(n.name ?? "app", { contract: ue(n.env) ? n.env : void 0 })
2985
3317
  }, c = p(o, i, s, { method: e.method ?? "GET" });
2986
3318
  if (c === null) return r();
2987
3319
  t.statusCode = c.status, t.setHeader("content-type", c.contentType);
@@ -3005,12 +3337,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3005
3337
  }
3006
3338
  });
3007
3339
  }
3008
- } : null, xe = /* @__PURE__ */ new Set(), Se = (e, t, n, r, i, a = !1) => {
3009
- let o = Yn(i, a, t) ?? "";
3010
- if (Q.error(`${t} render failed`, {
3340
+ } : null, Se = /* @__PURE__ */ new Set(), Ce = (e, t, n, r, i, a = !1) => {
3341
+ let o = Ir(i, a, t) ?? "";
3342
+ if (Z.error(`${t} render failed`, {
3011
3343
  pathname: n,
3012
3344
  pattern: r,
3013
- cause: Et(i) + o
3345
+ cause: Sn(i) + o
3014
3346
  }), e.headersSent) {
3015
3347
  e.end();
3016
3348
  return;
@@ -3018,89 +3350,115 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3018
3350
  e.writeHead(500, {
3019
3351
  "content-type": "text/plain; charset=utf-8",
3020
3352
  "x-voltro-rendered-by": `${t}-failed`,
3021
- "x-voltro-ssr-generation": String(K)
3353
+ "x-voltro-ssr-generation": String(G)
3022
3354
  });
3023
- let s = K === 0 ? "" : `\n[voltro] this process has absorbed ${K} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3024
- e.end(`${t} render failed for ${n}\n\n${Et(i)}\n${o}\n${s}`);
3025
- }, we = nt(), Ee = it({
3355
+ let s = G === 0 ? "" : `\n[voltro] this process has absorbed ${G} hot update(s) since boot, so its SSR\nmodule graph may not match the files on disk. Before reporting this — to us or to\nyourself — restart \`voltro dev\` and measure once from a fresh boot.\n`;
3356
+ e.end(`${t} render failed for ${n}\n\n${Sn(i)}\n${o}\n${s}`);
3357
+ }, we = mt(), Te = gt({
3026
3358
  limit: we,
3027
- onColdStart: (e) => Q.debug("ssr cold-compile start", { id: e }),
3028
- onColdEnd: (e, { durationMs: t, failed: n }) => Q.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3359
+ onColdStart: (e) => Z.debug("ssr cold-compile start", { id: e }),
3360
+ onColdEnd: (e, { durationMs: t, failed: n }) => Z.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3029
3361
  id: e,
3030
3362
  ms: t,
3031
3363
  ...n ? { failed: !0 } : {}
3032
3364
  })
3033
3365
  });
3034
- Q.debug(`ssr cold-compile concurrency ${we}`, { concurrency: we });
3035
- let J = null, Oe = async () => (J === null && (J = await M.readFile(O(e, ".framework", "index.html"), "utf8")), J), Ae = {
3366
+ Z.debug(`ssr cold-compile concurrency ${we}`, { concurrency: we });
3367
+ let Ee = null, Oe = async () => (Ee === null && (Ee = await N.readFile(O(e, ".framework", "index.html"), "utf8")), Ee), ke = {
3036
3368
  name: "framework:ssr",
3037
3369
  configureServer(t) {
3038
- let r = (e) => Ee.load(e, async () => await t.ssrLoadModule(e)), i, o = !1, s = () => {
3370
+ let r = (e) => Te.load(e, async () => await t.ssrLoadModule(e)), i, o = !1, s = () => {
3039
3371
  if (i !== void 0) return i;
3040
3372
  let t = n.locales ?? [], a = n.defaultLocale ?? t[0] ?? "en";
3041
3373
  return t.length === 0 ? (i = Promise.resolve(() => void 0), i) : (i = (async () => {
3042
- let [{ makeSsgWrap: n }, { makeSsrI18nResolver: i }] = await Promise.all([r("@voltro/i18n"), r("@voltro/i18n/server")]), s = {};
3043
- for (let i of t) if (j(O(e, "src", "locales", `${i}.ts`))) try {
3044
- let t = (await r(O(e, "src", "locales", `${i}.ts`))).default;
3045
- t !== void 0 && (s[i] = n(i, t, a));
3374
+ let [{ makeSsgWrap: i }, { makeSsrI18nResolver: s }] = await Promise.all([r("@voltro/i18n"), r("@voltro/i18n/server")]), c = {};
3375
+ for (let n of t) if (M(O(e, "src", "locales", `${n}.ts`))) try {
3376
+ let t = (await r(O(e, "src", "locales", `${n}.ts`))).default;
3377
+ t !== void 0 && (c[n] = i(n, t, a));
3046
3378
  } catch (e) {
3047
- Q.warn("locale catalog failed to load for SSR", { locale: i }, e);
3379
+ Z.warn("locale catalog failed to load for SSR", { locale: n }, e);
3048
3380
  }
3049
- if (o = Object.keys(s).length > 0, Object.keys(s).length === 0) {
3050
- let { resolveLocale: e } = await r("@voltro/i18n/server");
3051
- return (n, r) => ({
3381
+ if (o = Object.keys(c).length > 0, Object.keys(c).length === 0) {
3382
+ let { resolveLocale: e, resolveTimeZone: i } = await r("@voltro/i18n/server");
3383
+ return (r, o) => ({
3052
3384
  locale: e({
3053
- cookieHeader: n ?? null,
3054
- acceptLanguageHeader: r ?? null,
3385
+ cookieHeader: r ?? null,
3386
+ acceptLanguageHeader: o ?? null,
3055
3387
  supported: t,
3056
3388
  defaultLocale: a
3057
3389
  }),
3390
+ timeZone: i({
3391
+ cookieHeader: r ?? null,
3392
+ configured: n.timeZone ?? null,
3393
+ defaultTimeZone: n.defaultTimeZone ?? null
3394
+ }),
3058
3395
  outerWrap: (e) => e
3059
3396
  });
3060
3397
  }
3061
- return i({
3062
- wraps: s,
3398
+ return s({
3399
+ wraps: c,
3063
3400
  supported: t,
3064
- defaultLocale: a
3401
+ defaultLocale: a,
3402
+ timeZone: n.timeZone ?? null,
3403
+ defaultTimeZone: n.defaultTimeZone ?? null
3065
3404
  });
3066
3405
  })(), i);
3067
- };
3068
- t.middlewares.use(async (i, c, l) => {
3406
+ }, c = Dt({
3407
+ apiName: a[0]?.name,
3408
+ apiOrigin: ia(a[0], { allowDevProxy: !0 }),
3409
+ loadDescriptors: async () => {
3410
+ let e = a[0];
3411
+ if (e !== void 0) return (await r(`${e.pkg}/rpcGroup`)).appDescriptors;
3412
+ },
3413
+ rpcQuery: (e, t) => aa(ia(a[0], { allowDevProxy: !0 }), e, {
3414
+ apiName: a[0]?.name,
3415
+ headers: t
3416
+ }),
3417
+ renderErrorPage: async () => void 0
3418
+ });
3419
+ t.middlewares.use((e, t, n) => {
3420
+ if (!(e.url ?? "/").split("?")[0].startsWith(xe)) return n();
3421
+ c(e, t, (t, r) => {
3422
+ e.url = t, e.method = "GET", e.__voltroFormFlash = r, n();
3423
+ }).then((e) => {
3424
+ e || n();
3425
+ });
3426
+ }), t.middlewares.use(async (i, c, l) => {
3069
3427
  if (i.method !== "GET" && i.method !== "HEAD") return l();
3070
3428
  let u = i.url ?? "/";
3071
3429
  u.indexOf("?");
3072
- let { pathname: d, search: f } = Hn(u);
3430
+ let { pathname: d, search: f } = $t(u), p = i.__voltroFormFlash;
3073
3431
  if (d.startsWith("/@") || d.startsWith("/node_modules/") || d.startsWith("/.framework/") || d.startsWith("/_voltro/") || d === "/main.tsx" || d === "/index.html" || d === "/sw.js" || d === "/favicon.ico" || d === "/robots.txt") return l();
3074
- let p = async () => {
3075
- if (X.length === 0) return;
3076
- let e = xr(X, {
3432
+ let m = async () => {
3433
+ if (J.length === 0) return;
3434
+ let e = ui(J, {
3077
3435
  route: void 0,
3078
3436
  pathname: d
3079
3437
  });
3080
3438
  if (e === void 0) return;
3081
3439
  let t = {};
3082
3440
  for (let [e, n] of Object.entries(i.headers ?? {})) typeof n == "string" ? t[e] = n : Array.isArray(n) && (t[e] = n.join(", "));
3083
- let n = await jr(e, {
3441
+ let n = await bi(e, {
3084
3442
  pathname: d,
3085
3443
  search: f,
3086
3444
  headers: t,
3087
- cookies: wr(t.cookie),
3445
+ cookies: pi(t.cookie),
3088
3446
  route: void 0
3089
3447
  });
3090
- for (let e of n.setCookies) c.appendHeader("set-cookie", Or(e));
3448
+ for (let e of n.setCookies) c.appendHeader("set-cookie", _i(e));
3091
3449
  };
3092
- if (/\.[a-z0-9]+$/i.test(d)) return await p(), l();
3093
- let m = ti(d, F.ssrRoutes);
3094
- if (!m) return await p(), l();
3095
- let h = !xe.has(m.route.pattern), g = Date.now();
3096
- h && Q.info(`ssr compiling ${m.route.pattern}`, {
3097
- pattern: m.route.pattern,
3450
+ if (/\.[a-z0-9]+$/i.test(d)) return await m(), l();
3451
+ let h = Ji(d, F.ssrRoutes);
3452
+ if (!h) return await m(), l();
3453
+ let g = !Se.has(h.route.pattern), v = Date.now();
3454
+ g && Z.info(`ssr compiling ${h.route.pattern}`, {
3455
+ pattern: h.route.pattern,
3098
3456
  pathname: d
3099
3457
  });
3100
- let v = {}, y = async (e, t) => {
3458
+ let y = {}, b = async (e, t) => {
3101
3459
  let n = Date.now(), r = await t();
3102
- return v[e] = (v[e] ?? 0) + (Date.now() - n), r;
3103
- }, b = async (e, n, r) => {
3460
+ return y[e] = (y[e] ?? 0) + (Date.now() - n), r;
3461
+ }, x = async (e, n, r) => {
3104
3462
  let i = await t.moduleGraph.getModuleById(e);
3105
3463
  if (!(!i || n.has(e))) {
3106
3464
  if (n.add(e), i.id && /\.(css|sass|scss|less|stylus|pcss|postcss)(\?|$)/.test(i.id)) {
@@ -3108,144 +3466,163 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3108
3466
  r.includes(e) || r.push(e);
3109
3467
  return;
3110
3468
  }
3111
- for (let e of i.importedModules ?? []) e.id && await b(e.id, n, r);
3469
+ for (let e of i.importedModules ?? []) e.id && await x(e.id, n, r);
3112
3470
  }
3113
- }, x = !1;
3471
+ }, S = !1;
3114
3472
  try {
3115
- let S = await y("loadPage", async () => await r(O(e, "src", "pages", m.route.file))), C = _(S, O("src", "pages", m.route.file)), w = Yr(F.dirs, m.route.dirChain), T = C === "spa" && w.some((e) => e.hasLayout);
3116
- if (C !== "ssr" && C !== "isr" && !T) return await p(), l();
3117
- let E = {};
3118
- for (let [e, t] of Object.entries(i.headers ?? {})) typeof t == "string" ? E[e] = t : Array.isArray(t) && (E[e] = t.join(", "));
3119
- let D = await jr(xr(X, {
3120
- route: m.route.pattern,
3473
+ let C = await b("loadPage", async () => await r(O(e, "src", "pages", h.route.file))), w = _(C, O("src", "pages", h.route.file)), T = Hi(F.dirs, h.route.dirChain), E = w === "spa" && T.some((e) => e.hasLayout), D = C.interactive ?? "full";
3474
+ if (w !== "ssr" && w !== "isr" && !E && D !== "islands") return await m(), l();
3475
+ let k = {};
3476
+ for (let [e, t] of Object.entries(i.headers ?? {})) typeof t == "string" ? k[e] = t : Array.isArray(t) && (k[e] = t.join(", "));
3477
+ let A = await bi(ui(J, {
3478
+ route: h.route.pattern,
3121
3479
  pathname: d
3122
3480
  }), {
3123
3481
  pathname: d,
3124
3482
  search: f,
3125
- headers: E,
3126
- cookies: wr(E.cookie),
3127
- route: m.route.pattern
3128
- }, ze);
3129
- for (let e of D.setCookies) c.appendHeader("set-cookie", Or(e));
3130
- let k = D.headers, A = fi(di(a[0], { allowDevProxy: !0 }), D.headers.cookie, {
3483
+ headers: k,
3484
+ cookies: pi(k.cookie),
3485
+ route: h.route.pattern
3486
+ }, Ve);
3487
+ for (let e of A.setCookies) c.appendHeader("set-cookie", _i(e));
3488
+ for (let [e, t] of Object.entries(A.responseHeaders)) c.setHeader(e, t);
3489
+ if (w === "isr" && A.cspNonce !== void 0) throw Error(`page '${h.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.`);
3490
+ let j = w === "isr" ? wi(A.headers) : A.headers, M = aa(ia(a[0], { allowDevProxy: !0 }), j.cookie, {
3131
3491
  apiName: a[0]?.name,
3132
- headers: D.headers
3133
- }), j = new AbortController(), M = () => j.abort();
3134
- c.once("close", M);
3135
- let N = null, P = [], ee = {};
3492
+ headers: j
3493
+ }), P = new AbortController(), ee = () => P.abort();
3494
+ c.once("close", ee);
3495
+ let te = null, ne = [], re = {};
3136
3496
  try {
3137
- (await r("@voltro/web/ssr")).beginStoreSeeds(), {chain: P, segmentLoaderData: ee} = await y("loadChain", () => Xr({
3138
- entries: w,
3497
+ (await r("@voltro/web/ssr")).beginStoreSeeds(), {chain: ne, segmentLoaderData: re} = await b("loadChain", () => Ui({
3498
+ entries: T,
3139
3499
  loadLayout: (t) => r(O(e, "src", "pages", t.dir, "layout.tsx")),
3140
3500
  loadError: (t) => r(O(e, "src", "pages", t.dir, "error.tsx")),
3141
3501
  loadPending: (t) => r(O(e, "src", "pages", t.dir, "loading.tsx")),
3142
3502
  ctx: {
3143
- params: m.params,
3503
+ params: h.params,
3144
3504
  pathname: d,
3145
3505
  search: f,
3146
- signal: j.signal,
3147
- headers: k,
3148
- query: A,
3506
+ signal: P.signal,
3507
+ headers: j,
3508
+ query: M,
3149
3509
  isServer: !0
3150
3510
  }
3151
3511
  }));
3152
- let t = S.loader;
3153
- typeof t == "function" && !T && (N = await y("loader", () => t({
3154
- params: m.params,
3512
+ let t = C.loader;
3513
+ typeof t == "function" && !E && (te = await b("loader", () => t({
3514
+ params: h.params,
3155
3515
  pathname: d,
3156
3516
  search: f,
3157
- signal: j.signal,
3158
- headers: k,
3159
- query: A,
3517
+ signal: P.signal,
3518
+ headers: j,
3519
+ query: M,
3160
3520
  isServer: !0
3161
3521
  })));
3162
3522
  } finally {
3163
- c.off("close", M);
3523
+ c.off("close", ee);
3164
3524
  }
3165
- let I = await y("loadSsrHelpers", async () => await r("@voltro/web/ssr"));
3166
- T || await cr({
3167
- pageMod: S,
3168
- params: m.params,
3169
- query: A,
3525
+ let I = await b("loadSsrHelpers", async () => await r("@voltro/web/ssr"));
3526
+ E || await Zr({
3527
+ pageMod: C,
3528
+ params: h.params,
3529
+ query: M,
3170
3530
  apiName: a[0]?.name,
3171
3531
  seed: I.seedPreloadedSubscription,
3172
3532
  seedFailure: I.seedPreloadedSubscriptionFailure,
3173
- onError: ({ tag: e, apiName: t }, n) => Q.warn("preload seed failed", {
3533
+ onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
3174
3534
  tag: e,
3175
3535
  apiName: t,
3176
3536
  pathname: d
3177
3537
  }, n)
3178
3538
  });
3179
- let te = {
3180
- pattern: m.route.pattern,
3181
- Component: S.default,
3182
- meta: S.meta,
3183
- loader: S.loader,
3184
- ErrorBoundary: S.ErrorBoundary,
3185
- Pending: S.Pending,
3186
- renderMode: C,
3187
- chain: P
3188
- }, L = {
3189
- cookies: D.cookies,
3190
- headers: k,
3191
- url: u
3192
- }, R = S.interactive ?? "full", z = (await s())(k.cookie, k["accept-language"]);
3193
- x = z !== void 0 && o;
3194
- let ne = z ? {
3539
+ let L = {
3540
+ pattern: h.route.pattern,
3541
+ Component: C.default,
3542
+ meta: C.meta,
3543
+ loader: C.loader,
3544
+ ErrorBoundary: C.ErrorBoundary,
3545
+ Pending: C.Pending,
3546
+ renderMode: w,
3547
+ chain: ne
3548
+ }, R = {
3549
+ cookies: w === "isr" ? Ti(A.cookies) : A.cookies,
3550
+ headers: j,
3551
+ url: u,
3552
+ ...p === void 0 ? {} : { formFlash: p }
3553
+ }, z = (await s())(j.cookie, j["accept-language"]);
3554
+ S = z !== void 0 && o;
3555
+ let ie = z ? {
3195
3556
  outerWrap: z.outerWrap,
3196
3557
  locale: z.locale
3197
- } : {}, B = T ? zn({
3558
+ } : {}, B = E ? Yt({
3198
3559
  helpers: I,
3199
- page: `src/pages/${m.route.file}`,
3200
- interactive: R,
3560
+ page: `src/pages/${h.route.file}`,
3561
+ interactive: D,
3201
3562
  delivery: "stream",
3202
3563
  renderInput: {
3203
- descriptor: te,
3204
- params: m.params,
3564
+ descriptor: L,
3565
+ params: h.params,
3205
3566
  pathname: d,
3206
3567
  search: f,
3207
- segmentLoaderData: ee,
3208
- requestContext: L,
3209
- ...ne
3568
+ segmentLoaderData: re,
3569
+ requestContext: R,
3570
+ ...ie
3210
3571
  }
3211
- }) : null, V = T ? null : Rn({
3572
+ }) : null, V = E ? null : Jt({
3212
3573
  helpers: I,
3213
- page: `src/pages/${m.route.file}`,
3574
+ page: `src/pages/${h.route.file}`,
3214
3575
  pathname: d,
3215
- renderMode: C,
3216
- interactive: R,
3217
- loaderData: N,
3218
- segmentLoaderData: ee,
3219
- pageLoaderRan: typeof S.loader == "function"
3220
- }), re = [];
3221
- await y("collectCss", async () => {
3576
+ renderMode: w,
3577
+ interactive: D,
3578
+ loaderData: te,
3579
+ segmentLoaderData: re,
3580
+ pageLoaderRan: typeof C.loader == "function"
3581
+ }), ae = [];
3582
+ await b("collectCss", async () => {
3222
3583
  let t = /* @__PURE__ */ new Set(), n = [
3223
- O(e, "src", "pages", m.route.file),
3224
- ...w.flatMap((t) => [
3584
+ O(e, "src", "pages", h.route.file),
3585
+ ...T.flatMap((t) => [
3225
3586
  ...t.hasLayout ? [O(e, "src", "pages", t.dir, "layout.tsx")] : [],
3226
3587
  ...t.hasError ? [O(e, "src", "pages", t.dir, "error.tsx")] : [],
3227
3588
  ...t.hasPending ? [O(e, "src", "pages", t.dir, "loading.tsx")] : []
3228
3589
  ]),
3229
3590
  O(e, ".framework", "main.tsx")
3230
3591
  ];
3231
- for (let e of n) await b(e, t, re);
3592
+ for (let e of n) await x(e, t, ae);
3232
3593
  });
3233
- let H = await y("readShell", Oe), U = await y("transformShell", () => t.transformIndexHtml(u, H)), ie = re.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), W = z?.locale ?? L.cookies["voltro:locale"] ?? n.defaultLocale ?? (n.locales ?? [])[0] ?? "en", ae = Date.now();
3594
+ let oe = (D === "islands" ? await b("islandsEntry", async () => {
3595
+ let t = oa(a, "../../app.config"), n = (await Wt({
3596
+ webRoot: e,
3597
+ pages: [{
3598
+ pattern: h.route.pattern,
3599
+ file: h.route.file
3600
+ }],
3601
+ headSnippets: zt(await Oe()),
3602
+ apiImports: t.imports,
3603
+ apiEntriesLiteral: `[\n${t.providerEntryLines.join("\n")}\n ]`
3604
+ }))[0];
3605
+ return n === void 0 ? void 0 : await N.readFile(O(e, ".framework", n.htmlFile), "utf8");
3606
+ }) : void 0) ?? await b("readShell", Oe), H = await b("transformShell", () => t.transformIndexHtml(u, oe)), se = ae.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), U = z?.locale ?? R.cookies["voltro:locale"] ?? n.defaultLocale ?? (n.locales ?? [])[0] ?? "en", ce = Date.now(), le = {
3607
+ lang: U,
3608
+ ...z?.timeZone === void 0 ? {} : { timeZone: z.timeZone },
3609
+ renderedAt: ce
3610
+ };
3234
3611
  if (B) {
3235
- let e = (e) => Vn({
3612
+ let e = (e) => Zt({
3236
3613
  helpers: I,
3237
3614
  prepared: B,
3238
3615
  meta: e,
3239
- interactive: R,
3240
- extra: [ie]
3616
+ interactive: D,
3617
+ extra: [se]
3241
3618
  });
3242
- if (B.hasDeferred) ar({
3619
+ if (B.hasDeferred) Jr({
3243
3620
  res: c,
3244
- shell: nr({
3245
- shell: U,
3621
+ shell: Ur({
3622
+ shell: H,
3246
3623
  inlineModuleScriptsAsync: !0
3247
3624
  }),
3248
- htmlLang: W,
3625
+ documentAttrs: le,
3249
3626
  headers: {
3250
3627
  "content-type": "text/html; charset=utf-8",
3251
3628
  "x-voltro-rendered-by": "spa-shell-dev"
@@ -3256,40 +3633,40 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3256
3633
  ...e
3257
3634
  }),
3258
3635
  onShellError: (e) => {
3259
- Se(c, "spa-shell-dev", d, m.route.pattern, e, x);
3636
+ Ce(c, "spa-shell-dev", d, h.route.pattern, e, S);
3260
3637
  }
3261
3638
  });
3262
3639
  else {
3263
- let t = Bn({
3640
+ let t = Xt({
3264
3641
  helpers: I,
3265
3642
  prepared: B
3266
- }), n = U.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${W}"`);
3643
+ }), n = Kr(H.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`), le);
3267
3644
  c.statusCode = 200, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "spa-shell-dev"), c.end(n);
3268
3645
  }
3269
3646
  } else if (V) {
3270
3647
  let e = (e) => [
3271
- ie,
3648
+ se,
3272
3649
  I.renderMetaToHtml(e),
3273
- `<meta name="voltro-interactive" content="${R}" />`,
3650
+ `<meta name="voltro-interactive" content="${D}" />`,
3274
3651
  ...V.hasDeferred ? [I.renderDeferredRegistryScript()] : [],
3275
3652
  I.renderRouterStateScript(V.stateInput)
3276
3653
  ].filter((e) => e.length > 0).join("\n "), t = {
3277
- descriptor: te,
3278
- params: m.params,
3654
+ descriptor: L,
3655
+ params: h.params,
3279
3656
  pathname: d,
3280
3657
  search: f,
3281
3658
  loaderData: V.loaderData,
3282
3659
  segmentLoaderData: V.segmentLoaderData,
3283
- requestContext: L,
3284
- ...ne
3660
+ requestContext: R,
3661
+ ...ie
3285
3662
  };
3286
- if (C === "ssr" && R === "full") ar({
3663
+ if (w === "ssr" && D === "full" && p === void 0) Jr({
3287
3664
  res: c,
3288
- shell: nr({
3289
- shell: U,
3665
+ shell: Ur({
3666
+ shell: H,
3290
3667
  inlineModuleScriptsAsync: !0
3291
3668
  }),
3292
- htmlLang: W,
3669
+ documentAttrs: le,
3293
3670
  headers: {
3294
3671
  "content-type": "text/html; charset=utf-8",
3295
3672
  "x-voltro-rendered-by": "ssr-dev"
@@ -3297,82 +3674,85 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3297
3674
  headInjection: e,
3298
3675
  render: (e) => I.renderPageToStream({
3299
3676
  ...t,
3300
- ...e
3677
+ ...e,
3678
+ ...A.cspNonce === void 0 ? {} : { nonce: A.cspNonce }
3301
3679
  }),
3302
3680
  onShellError: (e) => {
3303
- Se(c, "ssr-dev", d, m.route.pattern, e, x);
3681
+ Ce(c, "ssr-dev", d, h.route.pattern, e, S);
3304
3682
  }
3305
3683
  });
3306
3684
  else {
3307
- let { html: n, meta: r } = I.renderPageToHtml(t), i = U.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`).replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${W}"`);
3308
- c.statusCode = 200, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "ssr-dev"), c.end(i);
3685
+ let { html: n, meta: r } = I.renderPageToHtml(t), i = Kr(H.replace("<div id=\"root\"></div>", `<div id="root">${n}</div>`).replace("</head>", ` ${e(r)}\n </head>`), le);
3686
+ c.statusCode = p === void 0 ? 200 : 422, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "ssr-dev"), p !== void 0 && c.setHeader("cache-control", "no-store");
3687
+ let a = p === void 0 ? i : bt(i, p);
3688
+ c.end(A.cspNonce === void 0 ? a : Qt(a, A.cspNonce));
3309
3689
  }
3310
3690
  }
3311
- v.render = Date.now() - ae;
3312
- let G = Date.now() - g;
3313
- h ? (xe.add(m.route.pattern), Q.info(`ssr compiled ${m.route.pattern} in ${G}ms`, {
3314
- pattern: m.route.pattern,
3691
+ y.render = Date.now() - ce;
3692
+ let W = Date.now() - v;
3693
+ g ? (Se.add(h.route.pattern), Z.info(`ssr compiled ${h.route.pattern} in ${W}ms`, {
3694
+ pattern: h.route.pattern,
3315
3695
  pathname: d,
3316
- elapsedMs: G,
3696
+ elapsedMs: W,
3317
3697
  cold: !0,
3318
- phases: v
3319
- })) : G > 200 && Q.info(`ssr rendered ${d} in ${G}ms`, {
3320
- pattern: m.route.pattern,
3698
+ phases: y
3699
+ })) : W > 200 && Z.info(`ssr rendered ${d} in ${W}ms`, {
3700
+ pattern: h.route.pattern,
3321
3701
  pathname: d,
3322
- elapsedMs: G,
3702
+ elapsedMs: W,
3323
3703
  cold: !1,
3324
- phases: v
3704
+ phases: y
3325
3705
  });
3326
3706
  } catch (e) {
3327
- if (In(e)) {
3328
- Q.error("ssr-dev render refused", {
3707
+ if (Kt(e)) {
3708
+ Z.error("ssr-dev render refused", {
3329
3709
  pathname: d,
3330
- pattern: m.route.pattern
3710
+ pattern: h.route.pattern
3331
3711
  }, e), c.statusCode = 500, c.setHeader("content-type", "text/plain; charset=utf-8"), c.end(e.message);
3332
3712
  return;
3333
3713
  }
3334
- let t = Ln(e);
3714
+ let t = qt(e);
3335
3715
  if (t) {
3336
3716
  c.statusCode = t.status;
3337
3717
  for (let [e, n] of Object.entries(t.headers)) c.setHeader(e, String(n));
3338
3718
  c.end(t.body);
3339
3719
  return;
3340
3720
  }
3341
- Se(c, "ssr-dev", d, m.route.pattern, e, x);
3721
+ Ce(c, "ssr-dev", d, h.route.pattern, e, S);
3342
3722
  }
3343
3723
  });
3344
3724
  }
3345
- }, je = Date.now(), Me = te.version ?? "?", Ne = await Pr(), Fe = O(e, "node_modules", "@voltro", "ui-shadcn"), Y = j(O(Fe, "package.json")) ? Fe : null, Ie = [], Le = await (async () => {
3725
+ }, Ae = Date.now(), je = ne.version ?? "?", Me = await Oi(), Ne = O(e, "node_modules", "@voltro", "ui-shadcn"), q = M(O(Ne, "package.json")) ? Ne : null, Ie = [], Le = await (async () => {
3346
3726
  let t = [];
3347
3727
  for (let n of a) {
3348
- let r = await ni(e, n.pkg);
3728
+ let r = await Yi(e, n.pkg);
3349
3729
  r && t.push(r);
3350
3730
  }
3351
- let n = await pr(t);
3731
+ let n = await ni(t);
3352
3732
  if (n === void 0) return !1;
3353
- let r = O(z, ".voltro-rpcgroup-optimize"), i = "";
3733
+ let r = O(L, ".voltro-rpcgroup-optimize"), i = "";
3354
3734
  try {
3355
- i = (await M.readFile(r, "utf8")).trim();
3735
+ i = (await N.readFile(r, "utf8")).trim();
3356
3736
  } catch {}
3357
3737
  if (i === n) return !1;
3358
3738
  try {
3359
- await M.writeFile(r, n);
3739
+ await N.writeFile(r, n);
3360
3740
  } catch {}
3361
3741
  return !0;
3362
- })(), Re = /* @__PURE__ */ new Set(), ze = (e) => {
3363
- Re.has(e.name) || (Re.add(e.name), Q.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
3742
+ })(), ze = /* @__PURE__ */ new Set(), Ve = (e) => {
3743
+ ze.has(e.name) || (ze.add(e.name), Z.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
3364
3744
  cookie: e.name,
3365
3745
  hint: "If your IdP client reads this from `document.cookie` (Supabase's `createBrowserClient` does), pass `httpOnly: false`. Otherwise the SSR render succeeds and the user is signed out at the first client-side call. Set `httpOnly: true` explicitly to silence this."
3366
3746
  }));
3367
- }, X = await Ar(e);
3368
- X.length > 0 && Q.info(`middleware.ts loaded — ${X.length} middleware(s): ` + X.map((e) => e.exportName).join(", ")), Cr(X, F.ssrRoutes.map((e) => e.pattern)), Le && Q.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client");
3747
+ }, J = await yi(e);
3748
+ J.length > 0 && Z.info(`middleware.ts loaded — ${J.length} middleware(s): ` + J.map((e) => e.exportName).join(", ")), fi(J, F.ssrRoutes.map((e) => e.pattern)), Le && Z.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client");
3369
3749
  try {
3370
- await Pe(l, "voltro dev (web)");
3750
+ await We(l, "voltro dev (web)");
3371
3751
  } catch (e) {
3372
- Q.error(String(e.message ?? e)), process.exit(1);
3752
+ Z.error(String(e.message ?? e)), process.exit(1);
3373
3753
  }
3374
- await (await te.createServer({
3375
- root: z,
3754
+ await (await ne.createServer({
3755
+ root: L,
3376
3756
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3377
3757
  ssr: { noExternal: ["react-intl", "@voltro/i18n"] },
3378
3758
  resolve: {
@@ -3383,50 +3763,50 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3383
3763
  "@voltro/i18n"
3384
3764
  ],
3385
3765
  alias: [
3386
- ...Ne ? [{
3766
+ ...Me ? [{
3387
3767
  find: "@voltro/devtools/styles.css",
3388
- replacement: O(Ne, "src/styles.css")
3768
+ replacement: O(Me, "src/styles.css")
3389
3769
  }, {
3390
3770
  find: "@voltro/devtools",
3391
- replacement: O(Ne, "src/index.ts")
3771
+ replacement: O(Me, "src/index.ts")
3392
3772
  }] : [],
3393
- ...Y ? [
3773
+ ...q ? [
3394
3774
  {
3395
3775
  find: "@voltro/ui-shadcn/tokens.css",
3396
- replacement: O(Y, "src/tokens.css")
3776
+ replacement: O(q, "src/tokens.css")
3397
3777
  },
3398
3778
  {
3399
3779
  find: "@voltro/ui-shadcn/cn",
3400
- replacement: O(Y, "src/cn.ts")
3780
+ replacement: O(q, "src/cn.ts")
3401
3781
  },
3402
3782
  {
3403
3783
  find: "@voltro/ui-shadcn/brand",
3404
- replacement: O(Y, "src/brand/voltroLogo.tsx")
3784
+ replacement: O(q, "src/brand/voltroLogo.tsx")
3405
3785
  },
3406
3786
  {
3407
3787
  find: "@voltro/ui-shadcn",
3408
- replacement: O(Y, "src/index.ts")
3788
+ replacement: O(q, "src/index.ts")
3409
3789
  }
3410
3790
  ] : [],
3411
- ...tt(e)
3791
+ ...pt(e)
3412
3792
  ]
3413
3793
  },
3414
3794
  optimizeDeps: {
3415
3795
  include: [...a.map((e) => `${e.pkg}/rpcGroup`), ...Ie],
3416
3796
  force: Le
3417
3797
  },
3418
- customLogger: $e(),
3798
+ customLogger: dt(),
3419
3799
  plugins: [
3420
- bn(O(e, "src", "pages")),
3421
- L(),
3422
- R(),
3423
- re,
3424
- ae,
3425
- fe,
3800
+ hr(O(e, "src", "pages")),
3801
+ re(),
3802
+ I(),
3803
+ B,
3804
+ se,
3805
+ pe,
3426
3806
  he,
3427
3807
  ge,
3428
3808
  ye,
3429
- Ae,
3809
+ ke,
3430
3810
  ...be ? [be] : []
3431
3811
  ],
3432
3812
  server: {
@@ -3434,23 +3814,23 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3434
3814
  strictPort: !0,
3435
3815
  host: !0,
3436
3816
  allowedHosts: n.allowedHosts === !0 || [...n.allowedHosts ?? []],
3437
- proxy: q,
3438
- fs: { allow: [e, ...Br(e)] }
3817
+ proxy: K,
3818
+ fs: { allow: [e, ...Pi(e)] }
3439
3819
  },
3440
3820
  appType: "spa",
3441
- cacheDir: O(z, ".vite"),
3821
+ cacheDir: O(L, ".vite"),
3442
3822
  publicDir: O(e, "public")
3443
- })).listen(), Mr.info(`v${Me} ready in ${Date.now() - je}ms`, {
3444
- version: Me,
3445
- bootMs: Date.now() - je
3446
- }), Q.info(`listening on http://localhost:${l}`, {
3823
+ })).listen(), Ei.info(`v${je} ready in ${Date.now() - Ae}ms`, {
3824
+ version: je,
3825
+ bootMs: Date.now() - Ae
3826
+ }), Z.info(`listening on http://localhost:${l}`, {
3447
3827
  port: l,
3448
3828
  app: n.name ?? "(unnamed)"
3449
3829
  });
3450
- for (let e of a) e.proxyTarget && (Q.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
3830
+ for (let e of a) e.proxyTarget && (Z.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
3451
3831
  api: e.name,
3452
3832
  target: e.proxyTarget
3453
- }), Q.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3833
+ }), Z.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3454
3834
  try {
3455
3835
  await x({
3456
3836
  id: b,
@@ -3461,10 +3841,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3461
3841
  status: "live",
3462
3842
  logFile: D.path
3463
3843
  });
3464
- let t = wn(e);
3844
+ let t = yr(e);
3465
3845
  if (t) {
3466
- let e = await Pn({ dashboardAppPath: t });
3467
- e.status === "launched" ? Q.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && Q.debug(`dashboard already running on :${e.port}`, { port: e.port });
3846
+ let e = await kr({ dashboardAppPath: t });
3847
+ e.status === "launched" ? Z.info(`dashboard launched at http://localhost:${e.port}`, { port: e.port }) : e.status === "already-running" && Z.debug(`dashboard already running on :${e.port}`, { port: e.port });
3468
3848
  }
3469
3849
  setInterval(() => {
3470
3850
  x({
@@ -3482,32 +3862,32 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3482
3862
  };
3483
3863
  process.on("SIGINT", n), process.on("SIGTERM", n);
3484
3864
  } catch (e) {
3485
- Q.warn("runtime-registry write failed", {}, e);
3865
+ Z.warn("runtime-registry write failed", {}, e);
3486
3866
  }
3487
- return ne({
3867
+ return z({
3488
3868
  app: n.name ?? "unnamed",
3489
3869
  kind: "web",
3490
3870
  url: `http://localhost:${l}`,
3491
- bootMs: Date.now() - je
3871
+ bootMs: Date.now() - Ae
3492
3872
  }), new Promise(() => {});
3493
- }, vi = async (t) => {
3873
+ }, fa = async (t) => {
3494
3874
  e("serve");
3495
- let n = await gi(t);
3875
+ let n = await ua(t);
3496
3876
  if (!n) return {
3497
3877
  ran: !1,
3498
3878
  exitCode: 0
3499
3879
  };
3500
- let i = Date.now(), a = Q.child("serve");
3880
+ let i = Date.now(), a = Z.child("serve");
3501
3881
  a.info("booting voltro serve (preview)", { app: n.name ?? "(unnamed)" });
3502
- let o = await si(t, n);
3882
+ let o = await ea(t, n);
3503
3883
  for (let e of o) a.info("api wired", {
3504
3884
  name: e.name,
3505
3885
  pkg: e.pkg
3506
3886
  });
3507
- await pi(t, n, o);
3887
+ await sa(t, n, o);
3508
3888
  {
3509
- let { pages: e } = await Jr(O(t, "src", "pages"));
3510
- await mt({
3889
+ let { pages: e } = await $(O(t, "src", "pages"));
3890
+ await un({
3511
3891
  appRoot: t,
3512
3892
  pages: e
3513
3893
  });
@@ -3516,12 +3896,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3516
3896
  kind: "web",
3517
3897
  configPort: n.port,
3518
3898
  env: process.env
3519
- }).port, c = await _e("vite", () => import("vite")), l = (await import("@vitejs/plugin-react")).default, u = O(t, ".framework");
3520
- Q.info("running production build"), await c.build({
3899
+ }).port, c = await De("vite", () => import("vite")), l = (await import("@vitejs/plugin-react")).default, u = O(t, ".framework");
3900
+ Z.info("running production build"), await c.build({
3521
3901
  root: u,
3522
3902
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3523
3903
  plugins: [l()],
3524
- customLogger: $e(),
3904
+ customLogger: dt(),
3525
3905
  resolve: { dedupe: [
3526
3906
  "react",
3527
3907
  "react-dom",
@@ -3530,7 +3910,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3530
3910
  ] },
3531
3911
  build: {
3532
3912
  outDir: "dist",
3533
- rollupOptions: { output: { manualChunks: Hr } }
3913
+ rollupOptions: { output: { manualChunks: Ii } }
3534
3914
  },
3535
3915
  publicDir: O(t, "public")
3536
3916
  });
@@ -3543,7 +3923,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3543
3923
  label: "Local",
3544
3924
  url: e
3545
3925
  })) ?? [];
3546
- return ne({
3926
+ return z({
3547
3927
  app: n.name ?? "unnamed",
3548
3928
  kind: "preview",
3549
3929
  url: f,
@@ -3552,4 +3932,4 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3552
3932
  }), new Promise(() => {});
3553
3933
  };
3554
3934
  //#endregion
3555
- export { yt as $, rr as A, Cn as B, Ar as C, xr as D, jr as E, zn as F, Xt as G, wn as H, Bn as I, Ft as J, Jt as K, Vn as L, ar as M, In as N, Or as O, Rn as P, bt as Q, Hn as R, kr as S, wr as T, on as U, Pn as V, en as W, St as X, Ct as Y, wt as Z, vi as _, be as _t, Xr as a, He as at, pi as b, Kr as c, We as ct, gi as d, J as dt, mt as et, si as f, De as ft, _i as g, xe as gt, li as h, Ce as ht, fi as i, Be as it, nr as j, cr as k, $ as l, Pe as lt, ai as m, Ee as mt, di as n, nt, hi as o, Ve as ot, ii as p, Te as pt, Bt as q, oi as r, tt as rt, Yr as s, Ue as st, Ur as t, it as tt, qr as u, ke as ut, Hr as v, _e as vt, Sr as w, Cr as x, Jr as y, Tn as z };
3935
+ export { Kt as $, ui as A, De as At, yr as B, wi as C, Le as Ct, di as D, Pe as Dt, yi as E, Ie as Et, Ur as F, In as G, Xn as H, Jr as I, vn as J, jn as K, br as L, Zr as M, Kr as N, pi as O, Me as Ot, Wr as P, un as Q, vr as R, Ti as S, Be as St, vi as T, Fe as Tt, Kn as U, tr as V, Wn as W, gn as X, bn as Y, hn as Z, da as _, et as _t, aa as a, Qt as at, $ as b, nt as bt, Hi as c, Ht as ct, Vi as d, xe as dt, Jt as et, ua as f, Dt as ft, na as g, Qe as gt, Qi as h, pt as ht, oa as i, $t as it, _i as j, bi as k, je as kt, Bi as l, Rt as lt, Zi as m, mt, ia as n, Xt as nt, Ui as o, Wt as ot, ea as p, gt as pt, yn as q, $i as r, Zt as rt, la as s, zt as st, Li as t, Yt as tt, Q as u, Vt as ut, fa as v, $e as vt, fi as w, Re as wt, sa as x, We as xt, Ii as y, tt as yt, kr as z };