@voltro/cli 0.52.0 → 0.54.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 (244) hide show
  1. package/CHANGELOG.md +424 -0
  2. package/THIRD-PARTY-NOTICES.md +8311 -3318
  3. package/dist/{agentsMd-0l980yhL.js → agentsMd-BaLC10Na.js} +110 -82
  4. package/dist/agentsMd-DCY1RSs8.js +2 -0
  5. package/dist/apiBuild-CeUN55uk.js +2 -0
  6. package/dist/{apiBuild-CSFI8QGq.js → apiBuild-DTWp0S_q.js} +11 -5
  7. package/dist/bin.js +1 -1
  8. package/dist/build-D4ygSbnV.js +843 -0
  9. package/dist/{checkCommand-COmqc2cB.js → checkCommand-Dg1G7Gwd.js} +6 -6
  10. package/dist/{checkCommand-2SbqzukH.js → checkCommand-L7DTlpIF.js} +1 -1
  11. package/dist/{cloudCmd-QUXh-b5w.js → cloudCmd-DzKcSYuy.js} +1 -1
  12. package/dist/{codegen-VF479Cnb.js → codegen-DSLM8Su9.js} +1 -1
  13. package/dist/codegen-DjgxEOnD.js +2 -0
  14. package/dist/codegenCommand-CG_Vx4lc.js +41 -0
  15. package/dist/{codemodRunner-r7J9lIa7.js → codemodRunner-Cd4xkC6u.js} +109 -11
  16. package/dist/{commands-Cc_nV8WI.js → commands-6Kzi92Np.js} +96 -73
  17. package/dist/{dashboardCommand-C-gKvwqh.js → dashboardCommand-Cq1PWvI1.js} +5 -5
  18. package/dist/{dataCommand-BgpBHnlB.js → dataCommand-DYzW8vkv.js} +3 -3
  19. package/dist/{dbCommand-sHedr-NJ.js → dbCommand-B4NWZtGL.js} +278 -237
  20. package/dist/dbCommand-CSFWs9ev.js +2 -0
  21. package/dist/{dev-CRHoCEiy.js → dev-CmuvUKRq.js} +2903 -2306
  22. package/dist/{dev--A3nsxA3.js → dev-cKUiZZsB.js} +1 -1
  23. package/dist/{doctorCommand-DtfJ3FA6.js → doctorCommand-DCiFVMtZ.js} +101 -69
  24. package/dist/doctorCommand-J3qu4E0Y.js +2 -0
  25. package/dist/{dormancyCommand-Drn7o0No.js → dormancyCommand-w1TrmgYP.js} +1 -1
  26. package/dist/{embeddingsCommand-Z-jO1fWN.js → embeddingsCommand-CMgPyRTr.js} +1 -1
  27. package/dist/{envCommand-D4gCrrTZ.js → envCommand-Cyynmcfa.js} +8 -8
  28. package/dist/{evolveCommand-CMROeKeA.js → evolveCommand-BwvQ8dVH.js} +2 -2
  29. package/dist/fileConventions-l-RIXbx8.js +36 -0
  30. package/dist/{fileTaxonomy-DvDUV9wq.js → fileTaxonomy-CbyMQYx_.js} +42 -42
  31. package/dist/fontPipeline-LxIHa1vo.js +2 -0
  32. package/dist/fontPipeline-Tsh8kZfA.js +152 -0
  33. package/dist/{frameworkTableAssembly-w-XnLa3q.js → frameworkTableAssembly-D7LJuALW.js} +5 -5
  34. package/dist/frameworkTableAssembly-IPD1pUnZ.js +2 -0
  35. package/dist/imagePipeline-B_GVJgm6.js +2 -0
  36. package/dist/imagePipeline-CBZmjT4i.js +127 -0
  37. package/dist/index.js +2 -2
  38. package/dist/{infoCommand-DXM868o_.js → infoCommand-DlYlUPqs.js} +1 -1
  39. package/dist/{inspect-CtL_xTbu.js → inspect-Bd8-9wsi.js} +1 -1
  40. package/dist/inspect-CuoDInfZ.js +2 -0
  41. package/dist/{inspectGateHint-BjnFubmH.js → inspectGateHint-4LxkNtrz.js} +1 -1
  42. package/dist/manifestBuild-C4-J1-m_.js +2 -0
  43. package/dist/{manifestBuild-CuU1VrSm.js → manifestBuild-Cqgsx2bM.js} +1 -1
  44. package/dist/{metaCommands-C6RFmF1r.js → metaCommands-x7RCi2AF.js} +9 -3
  45. package/dist/{migrate-D0F-eTlK.js → migrate-BK_Bbx-_.js} +2 -2
  46. package/dist/mobileCommand-D9O6iq3D.js +428 -0
  47. package/dist/mobileCommand-DAum7tsG.js +2 -0
  48. package/dist/{pageConvention-CzUiSbtU.js → pageConvention-CMpfDN6r.js} +1 -1
  49. package/dist/{privacyCommand-DGdopOI6.js → privacyCommand-BCa2OoZG.js} +1 -1
  50. package/dist/{probeCommand-C9gazU0H.js → probeCommand-_C0YU207.js} +83 -24
  51. package/dist/{projectScaffold-EzlErR4E.js → projectScaffold-CJfP-xbT.js} +1 -1
  52. package/dist/{projectScaffold-B4dmTlwT.js → projectScaffold-CSN0OzBV.js} +2 -2
  53. package/dist/renderModeScan-43yQ2opo.js +147 -0
  54. package/dist/{renderProfile-Ck32Fzxr.js → renderProfile-DvrhVJHa.js} +2 -2
  55. package/dist/{runtimeTrace-BPQyCmC5.js → runtimeTrace-CGWx1Q6l.js} +1 -1
  56. package/dist/{sdkgen-Se88ifTd.js → sdkgen-CDGHQUFj.js} +1 -1
  57. package/dist/serveCommand-BiPe8BJm.js +2 -0
  58. package/dist/{serveCommand-DkP3OT0W.js → serveCommand-Bje09q1v.js} +889 -825
  59. package/dist/serveEntry.js +1 -1
  60. package/dist/start-B0bnJgxI.js +3 -0
  61. package/dist/{start-jw89Xbqy.js → start-Clz-1BHB.js} +633 -455
  62. package/dist/startEntry.js +1 -1
  63. package/dist/{staticCommand-BwNEDlSU.js → staticCommand-ey0kYmOT.js} +1 -1
  64. package/dist/{subcommandNames-DpYs3DXr.js → subcommandNames-CDzfEtKV.js} +3 -3
  65. package/dist/{templates-BR-fb4SP.js → templates-BTWZkJJT.js} +41 -9
  66. package/dist/{test-f3amja6a.js → test-D_kW4KMj.js} +1 -1
  67. package/dist/updateCommand-CIoVDKnj.js +2 -0
  68. package/dist/{updateCommand-BMk2e4ky.js → updateCommand-CRJlAOaM.js} +139 -115
  69. package/dist/{webDev-BgWL9gKV.js → webDev-DSI9SOhs.js} +1598 -1028
  70. package/dist/webDev-DlvZO30c.js +2 -0
  71. package/dist/{webhooksCommand-CoIO3jbj.js → webhooksCommand-BvzXNHji.js} +1 -1
  72. package/dist/workspaceDeps-RKEkX92S.js +45 -0
  73. package/package.json +60 -19
  74. package/templates/AGENTS.core.md +2 -0
  75. package/templates/AGENTS.md +8 -4
  76. package/templates/agent-docs/_index.md +6 -4
  77. package/templates/agent-docs/_manifest.json +21 -5
  78. package/templates/agent-docs/ai.md +6 -6
  79. package/templates/agent-docs/authentication.md +73 -1
  80. package/templates/agent-docs/cli.md +6 -3
  81. package/templates/agent-docs/configuration.md +17 -0
  82. package/templates/agent-docs/data.md +522 -29
  83. package/templates/agent-docs/database/advancedqueries.md +8 -8
  84. package/templates/agent-docs/database/columntypes.md +2 -2
  85. package/templates/agent-docs/database/migrations.md +1 -1
  86. package/templates/agent-docs/database/querying.md +1 -1
  87. package/templates/agent-docs/database/schema.md +1 -1
  88. package/templates/agent-docs/database/seedsdialects.md +65 -3
  89. package/templates/agent-docs/database/transactions.md +3 -3
  90. package/templates/agent-docs/deployment.md +8 -0
  91. package/templates/agent-docs/internationalization.md +4 -2
  92. package/templates/agent-docs/introduction.md +32 -1
  93. package/templates/agent-docs/local-first-mobile.md +226 -30
  94. package/templates/agent-docs/observability.md +5 -1
  95. package/templates/agent-docs/plugins/atlassian.md +2 -2
  96. package/templates/agent-docs/plugins/audit.md +2 -2
  97. package/templates/agent-docs/plugins/auth.md +1 -1
  98. package/templates/agent-docs/plugins/billing.md +1 -1
  99. package/templates/agent-docs/plugins/cdc-out.md +8 -3
  100. package/templates/agent-docs/plugins/comments.md +164 -0
  101. package/templates/agent-docs/plugins/notifications.md +47 -4
  102. package/templates/agent-docs/plugins/presence.md +45 -3
  103. package/templates/agent-docs/plugins/prometheus.md +3 -1
  104. package/templates/agent-docs/plugins/queue.md +172 -0
  105. package/templates/agent-docs/plugins.md +17 -13
  106. package/templates/agent-docs/reference.md +35 -4
  107. package/templates/agent-docs/routing.md +585 -7
  108. package/templates/agent-docs/scheduling.md +1 -1
  109. package/templates/agent-docs/schema-driven-ui.md +226 -4
  110. package/templates/agent-docs/security.md +3 -3
  111. package/templates/agent-docs/templates/appshells.md +36 -4
  112. package/templates/agent-docs/whats-new.md +134 -66
  113. package/templates/apps/api-ai/package.json +6 -6
  114. package/templates/apps/api-auth/package.json +8 -8
  115. package/templates/apps/api-backend/package.json +7 -7
  116. package/templates/apps/api-backend-deactivation/package.json +7 -7
  117. package/templates/apps/api-backend-mail/package.json +8 -8
  118. package/templates/apps/api-backend-mariadb/package.json +9 -9
  119. package/templates/apps/api-backend-sqlite/package.json +8 -8
  120. package/templates/apps/api-backend-storage/package.json +8 -8
  121. package/templates/apps/api-cms/package.json +9 -9
  122. package/templates/apps/api-collab/README.md +3 -3
  123. package/templates/apps/api-collab/app.config.ts +1 -1
  124. package/templates/apps/api-collab/database/schema.ts +12 -8
  125. package/templates/apps/api-collab/mutations/documents.create.mutation.server.ts +1 -1
  126. package/templates/apps/api-collab/mutations/documents.setBody.mutation.server.ts +1 -1
  127. package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +1 -1
  128. package/templates/apps/api-collab/package.json +8 -8
  129. package/templates/apps/api-collab/template.json +1 -1
  130. package/templates/apps/api-collab/tests/documents.setBody.test.ts +10 -2
  131. package/templates/apps/api-data-advanced/package.json +8 -8
  132. package/templates/apps/api-durable/package.json +8 -8
  133. package/templates/apps/api-feature-flags/package.json +9 -9
  134. package/templates/apps/api-governance/package.json +8 -8
  135. package/templates/apps/api-kv/package.json +8 -8
  136. package/templates/apps/api-moderation/package.json +8 -8
  137. package/templates/apps/api-observability/package.json +8 -8
  138. package/templates/apps/api-ratelimit/package.json +8 -8
  139. package/templates/apps/api-rbac/package.json +8 -8
  140. package/templates/apps/api-rest/package.json +7 -7
  141. package/templates/apps/api-row-history/package.json +8 -8
  142. package/templates/apps/api-saas/package.json +11 -10
  143. package/templates/apps/api-saas-starter/package.json +10 -10
  144. package/templates/apps/api-search/package.json +8 -8
  145. package/templates/apps/api-status/package.json +8 -8
  146. package/templates/apps/api-webhooks/package.json +9 -9
  147. package/templates/apps/changelog/app.config.ts +26 -2
  148. package/templates/apps/changelog/content/releases/{0.1.0.mdx → v0-1-0.mdx} +0 -1
  149. package/templates/apps/changelog/content/releases/{0.2.0.mdx → v0-2-0.mdx} +0 -1
  150. package/templates/apps/changelog/package.json +9 -8
  151. package/templates/apps/changelog/src/collections/releases.collection.ts +48 -0
  152. package/templates/apps/changelog/src/globals.d.ts +1 -1
  153. package/templates/apps/changelog/src/locales/de.ts +1 -1
  154. package/templates/apps/changelog/src/locales/en.ts +1 -1
  155. package/templates/apps/changelog/src/pages/[locale]/[slug]/page.tsx +7 -4
  156. package/templates/apps/changelog/src/pages/[locale]/mirrors.test.tsx +13 -41
  157. package/templates/apps/changelog/src/pages/[slug]/page.test.tsx +26 -51
  158. package/templates/apps/changelog/src/pages/[slug]/page.tsx +21 -19
  159. package/templates/apps/changelog/src/pages/page.test.tsx +14 -37
  160. package/templates/apps/changelog/src/pages/page.tsx +18 -12
  161. package/templates/apps/edge-functions/package.json +2 -2
  162. package/templates/apps/frontend-admin/package.json +8 -8
  163. package/templates/apps/frontend-app/package.json +9 -9
  164. package/templates/apps/frontend-auth/package.json +8 -8
  165. package/templates/apps/frontend-blank/package.json +7 -7
  166. package/templates/apps/frontend-cms/package.json +9 -9
  167. package/templates/apps/frontend-collab/README.md +43 -24
  168. package/templates/apps/frontend-collab/app.config.ts +3 -3
  169. package/templates/apps/frontend-collab/package.json +14 -10
  170. package/templates/apps/frontend-collab/src/locales/de.ts +1 -2
  171. package/templates/apps/frontend-collab/src/locales/en.ts +1 -2
  172. package/templates/apps/frontend-collab/src/pages/page.test.tsx +72 -76
  173. package/templates/apps/frontend-collab/src/pages/page.tsx +45 -22
  174. package/templates/apps/frontend-collab/template.json +2 -2
  175. package/templates/apps/frontend-contact/package.json +7 -7
  176. package/templates/apps/frontend-dashboard/package.json +7 -7
  177. package/templates/apps/frontend-docs/content/docs/de/guides/first-page.md +4 -0
  178. package/templates/apps/frontend-docs/content/docs/de/intro/getting-started.md +4 -0
  179. package/templates/apps/frontend-docs/content/docs/en/guides/first-page.md +4 -0
  180. package/templates/apps/frontend-docs/content/docs/en/intro/getting-started.md +4 -0
  181. package/templates/apps/frontend-docs/package.json +9 -6
  182. package/templates/apps/frontend-docs/src/collections/docs.collection.ts +21 -0
  183. package/templates/apps/frontend-docs/src/locales/de.ts +0 -5
  184. package/templates/apps/frontend-docs/src/locales/en.ts +0 -5
  185. package/templates/apps/frontend-docs/src/pages/[locale]/docs/[...slug]/page.tsx +17 -9
  186. package/templates/apps/frontend-docs/src/pages/[locale]/mirrors.test.tsx +10 -5
  187. package/templates/apps/frontend-docs/src/pages/[locale]/page.tsx +8 -0
  188. package/templates/apps/frontend-docs/src/pages/docs/[...slug]/page.test.tsx +53 -15
  189. package/templates/apps/frontend-docs/src/pages/docs/[...slug]/page.tsx +27 -33
  190. package/templates/apps/frontend-docs/src/pages/page.test.tsx +17 -3
  191. package/templates/apps/frontend-docs/src/pages/page.tsx +16 -12
  192. package/templates/apps/frontend-i18n/package.json +6 -6
  193. package/templates/apps/frontend-landing/README.md +48 -0
  194. package/templates/apps/frontend-landing/app.config.ts +28 -0
  195. package/templates/apps/frontend-landing/package.json +7 -6
  196. package/templates/apps/frontend-landing/src/assets/hero.jpg +0 -0
  197. package/templates/apps/frontend-landing/src/fonts/Geist-Variable.woff2 +0 -0
  198. package/templates/apps/frontend-landing/src/fonts/LICENSE-Geist.txt +92 -0
  199. package/templates/apps/frontend-landing/src/globals.css +15 -0
  200. package/templates/apps/frontend-landing/src/globals.d.ts +17 -0
  201. package/templates/apps/frontend-landing/src/locales/de.ts +3 -2
  202. package/templates/apps/frontend-landing/src/locales/en.ts +5 -2
  203. package/templates/apps/frontend-landing/src/pages/page.test.tsx +79 -0
  204. package/templates/apps/frontend-landing/src/pages/page.tsx +26 -3
  205. package/templates/apps/frontend-landing/template.json +2 -2
  206. package/templates/apps/frontend-portal/package.json +8 -8
  207. package/templates/apps/frontend-saas/package.json +8 -8
  208. package/templates/apps/frontend-spa/package.json +7 -7
  209. package/templates/apps/frontend-ssr/package.json +7 -7
  210. package/templates/apps/frontend-ssr-api/package.json +8 -8
  211. package/templates/apps/frontend-static-blog/content/posts/cms-to-ssg.md +12 -0
  212. package/templates/apps/frontend-static-blog/content/posts/hello-static.md +12 -0
  213. package/templates/apps/frontend-static-blog/content/posts/islands-not-hydration.md +14 -0
  214. package/templates/apps/frontend-static-blog/package.json +9 -6
  215. package/templates/apps/frontend-static-blog/src/collections/posts.collection.ts +27 -0
  216. package/templates/apps/frontend-static-blog/src/pages/[locale]/blog/[slug]/page.tsx +7 -4
  217. package/templates/apps/frontend-static-blog/src/pages/[locale]/mirrors.test.tsx +7 -1
  218. package/templates/apps/frontend-static-blog/src/pages/blog/[slug]/page.test.tsx +19 -9
  219. package/templates/apps/frontend-static-blog/src/pages/blog/[slug]/page.tsx +19 -21
  220. package/templates/apps/frontend-static-blog/src/pages/page.test.tsx +18 -5
  221. package/templates/apps/frontend-static-blog/src/pages/page.tsx +21 -14
  222. package/templates/apps/frontend-status/package.json +8 -8
  223. package/templates/apps/mobile-app/package.json +12 -11
  224. package/templates/apps/mobile-app/src/lib/deeplinks.ts +29 -17
  225. package/templates/apps/mobile-app/tests/deeplinks.test.ts +16 -0
  226. package/dist/agentsMd-SDDSkyl4.js +0 -2
  227. package/dist/apiBuild-BYBpL7Pz.js +0 -2
  228. package/dist/build-CPgcMQug.js +0 -793
  229. package/dist/codegen-CctkDO-1.js +0 -2
  230. package/dist/codegenCommand-DCdG2JN-.js +0 -137
  231. package/dist/dbCommand-DNb6yeOG.js +0 -2
  232. package/dist/doctorCommand-CqoWA2p5.js +0 -2
  233. package/dist/fileConventions-DOqD3lPS.js +0 -34
  234. package/dist/frameworkTableAssembly-C6ETawPR.js +0 -2
  235. package/dist/inspect-CuGDYES0.js +0 -2
  236. package/dist/manifestBuild-CPjhvM62.js +0 -2
  237. package/dist/renderModeScan-CcH2X1_D.js +0 -120
  238. package/dist/serveCommand-DLc-BznW.js +0 -2
  239. package/dist/start-DfL3fOiN.js +0 -3
  240. package/dist/updateCommand-5gFVfK5q.js +0 -2
  241. package/dist/webDev-CZbTsDcH.js +0 -2
  242. package/templates/apps/changelog/scripts/generate-rss.mjs +0 -38
  243. package/templates/apps/changelog/src/lib/releases.ts +0 -21
  244. package/templates/apps/frontend-static-blog/src/content/posts.ts +0 -64
@@ -2,40 +2,45 @@ 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-DOqD3lPS.js";
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-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
- import { i as x, n as S, r as C, t as w } from "./runtimeRegistry-DMeKfTHP.js";
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, 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
- import { homedir as H } from "node:os";
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
- import { createConnection as K } from "node:net";
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";
5
+ import { M as i, _ as a, c as o, g as s, v as c, y as l } from "./fileConventions-l-RIXbx8.js";
6
+ import { A as u, D as d, a as f, h as p, j as m, k as h } from "./inspect-Bd8-9wsi.js";
7
+ import { n as g, t as _ } from "./workspaceDeps-RKEkX92S.js";
8
+ import { n as v } from "./agentsMd-BaLC10Na.js";
9
+ import { c as y, f as b, p as x, t as S } from "./renderModeScan-43yQ2opo.js";
10
+ import { a as C, c as w, d as T, f as E, i as D, l as O, o as ee, p as k, r as te, s as A, t as j } from "./imagePipeline-CBZmjT4i.js";
11
+ import { d as ne, n as M } from "./fontPipeline-Tsh8kZfA.js";
12
+ import { t as re } from "./pageConvention-CMpfDN6r.js";
13
+ import { i as ie, n as ae, r as oe, t as se } from "./runtimeRegistry-DMeKfTHP.js";
14
+ import { n as ce } from "./logFileSink-B4uP8pvf.js";
15
+ import { basename as N, dirname as P, extname as le, join as F, relative as I, resolve as L, sep as R } from "node:path";
16
+ import { existsSync as z, mkdirSync as ue, promises as B, readFileSync as V, readdirSync as H, statSync as de, unwatchFile as U, watchFile as fe, writeFileSync as pe } from "node:fs";
17
+ import { fileURLToPath as W, pathToFileURL as me } from "node:url";
18
+ import { addSink as he, createLogger as G, printReadyBlock as ge } from "@voltro/logger";
19
+ import { Metric as _e, MetricBoundaries as ve } from "effect";
20
+ import { createRequire as ye } from "node:module";
21
+ import { classifyRequestOrigin as be, currentTraceContext as xe, resolveOriginGuardConfig as Se, resolveSecret as Ce } from "@voltro/runtime";
22
+ import { homedir as we } from "node:os";
23
+ import { FRAMEWORK_ENV_CATALOG as Te, appEnvEntries as Ee, checkEnvNaming as De, formatEnvErrors as Oe, installEnvSnapshot as ke, isEnvContract as Ae, pluginEnvEntries as je, renderDotEnvExample as Me, resolveEnv as Ne } from "@voltro/env";
24
+ import { __installPublicEnv as Pe } from "@voltro/env/public";
25
+ import { mkdir as K, readFile as Fe, writeFile as q } from "node:fs/promises";
26
+ import { createHash as J, createHmac as Ie, randomBytes as Le, timingSafeEqual as Re } from "node:crypto";
27
+ import { spawn as ze } from "node:child_process";
28
+ import { createConnection as Y } from "node:net";
29
+ import { FORM_FLASH_SCRIPT_ID as Be, FORM_KEY_FIELD as Ve, FORM_PATH_PREFIX as He, FORM_PATH_PREFIX as Ue, FORM_REDIRECT_FIELD as We, formDataToInput as Ge, validateFields as Ke } from "@voltro/client/form";
30
+ import { buildFeed as qe, contentArtifactPath as Je, getCollection as Ye, getEntry as Xe, invalidateContentCache as Ze, registeredCollections as Qe, setContentAssetResolver as $e, setContentRoot as et, validateReferences as tt } from "@voltro/content";
31
+ import { PassThrough as nt } from "node:stream";
27
32
  //#region src/buildToolImport.ts
28
- var Ee = (e) => {
33
+ var rt = (e) => {
29
34
  let t = e;
30
35
  return t?.code === "ERR_MODULE_NOT_FOUND" || /Cannot find (package|module)/.test(String(t?.message ?? ""));
31
- }, De = async (e, t) => {
36
+ }, it = async (e, t) => {
32
37
  try {
33
38
  return await t();
34
39
  } catch (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;
40
+ throw rt(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;
36
41
  }
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}
42
+ }, at = "// AUTO-GENERATED by Voltro — DO NOT EDIT.\n// Source: app.config.ts `env` (defineEnv). Regenerated on every `voltro dev` boot.\n", ot = (e, t) => t ? `${e} | undefined` : e, st = (e, t) => Object.entries(e.vars).filter(([, e]) => t(e.access)).map(([e, t]) => `${t.description ? ` /** ${t.description} */\n` : ""} readonly ${e}: ${ot(t.tsType, t.optional)}`).join("\n"), ct = async (e, t) => {
43
+ let n = st(t, () => !0), r = `${at}
39
44
  import '@voltro/env/server'
40
45
 
41
46
  declare module '@voltro/env/server' {
@@ -44,9 +49,9 @@ ${n.length > 0 ? n : " // (no variables declared)"}
44
49
  }
45
50
  }
46
51
  `;
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}
52
+ await q(F(e, "env.generated.d.ts"), r, "utf8");
53
+ }, lt = async (e, t) => {
54
+ let n = st(t, (e) => e === "public"), r = `${at}
50
55
  import '@voltro/env/public'
51
56
 
52
57
  declare module '@voltro/env/public' {
@@ -54,10 +59,10 @@ declare module '@voltro/env/public' {
54
59
  ${n.length > 0 ? n : " // (no public variables declared)"}
55
60
  }
56
61
  }
57
- `, i = O(e, "src");
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}
62
+ `, i = F(e, "src");
63
+ await K(i, { recursive: !0 }), await q(F(i, "voltro-env.d.ts"), r, "utf8");
64
+ }, ut = async (e, t) => {
65
+ let n = `${at}
61
66
  import { __installPublicEnv } from '@voltro/env/public'
62
67
 
63
68
  export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
@@ -65,14 +70,14 @@ export const publicEnvValues = ${JSON.stringify(t, null, 2)} as const
65
70
  // Set the browser/SSR-shared global the \`publicEnv\` accessor reads.
66
71
  __installPublicEnv(publicEnvValues)
67
72
  `;
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({
73
+ await K(e, { recursive: !0 }), await q(F(e, "env.public.ts"), n, "utf8");
74
+ }, dt = async (e) => {
75
+ let t = Ae(e.rawEnv) ? e.rawEnv : void 0, n = await Ne({
71
76
  contract: t,
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);
77
+ resolveSecret: Ce
78
+ }), r = [...n.errors, ...De(t, e.appType)];
79
+ if (r.length > 0) throw Error(Oe(r));
80
+ ke(n.values), e.appType === "web" && Pe(n.publicValues);
76
81
  let i = t ? Object.keys(t.vars).length : 0;
77
82
  if (i > 0) {
78
83
  let r = Object.keys(n.publicValues).length;
@@ -84,20 +89,20 @@ __installPublicEnv(publicEnvValues)
84
89
  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 });
85
90
  }
86
91
  }
87
- return e.generateTypes && t && (e.appType === "api" ? await je(e.root, t) : await Me(e.root, t)), {
92
+ return e.generateTypes && t && (e.appType === "api" ? await ct(e.root, t) : await lt(e.root, t)), {
88
93
  resolved: n,
89
94
  contract: t
90
95
  };
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 = [];
96
+ }, ft = (e) => {
97
+ let t = Ee(e.contract), n = (e.plugins ?? []).flatMap((e) => je(e.name, e.declaredEnv)), r = e.includeFramework === !1 ? [] : Te, i = /* @__PURE__ */ new Set(), a = [];
93
98
  for (let e of [
94
99
  ...t,
95
100
  ...n,
96
101
  ...r
97
102
  ]) i.has(e.key) || (i.add(e.key), a.push(e));
98
103
  return a;
99
- }, Fe = (e, t, n = (e) => process.env[e]) => {
100
- let r = q(t).map((e) => {
104
+ }, pt = (e, t, n = (e) => process.env[e]) => {
105
+ let r = ft(t).map((e) => {
101
106
  let t = n(e.key) !== void 0;
102
107
  return {
103
108
  ...e,
@@ -114,59 +119,20 @@ __installPublicEnv(publicEnvValues)
114
119
  missingRequired: r.filter((e) => e.required && !e.isSet && e.default === void 0).length
115
120
  }
116
121
  };
117
- }, Ie = (e, t) => {
118
- let n = q({
122
+ }, mt = (e, t) => {
123
+ let n = ft({
119
124
  ...e,
120
125
  includeFramework: !1
121
126
  });
122
- return fe(n, {
127
+ return Me(n, {
123
128
  includeFramework: e.includeFramework !== !1,
124
129
  ...t ? { header: t } : {}
125
130
  });
126
- }, Le = async (e, t) => {
127
- let n = e;
128
- for (;;) {
129
- let e = O(n, "node_modules", t);
130
- try {
131
- if ((await N.stat(e)).isDirectory()) {
132
- let t = await N.realpath(e);
133
- return t.includes("/node_modules/") ? null : t;
134
- }
135
- } catch {}
136
- let r = D(n);
137
- if (r === n) return null;
138
- n = r;
139
- }
140
- }, Re = async (e) => {
141
- let t;
142
- try {
143
- let n = await N.readFile(O(e, "package.json"), "utf8"), r = JSON.parse(n);
144
- t = Object.keys({
145
- ...r.dependencies,
146
- ...r.devDependencies
147
- });
148
- } catch {
149
- return [];
150
- }
151
- return (await Promise.all(t.map(async (t) => {
152
- let n = await Le(e, t);
153
- if (n === null) return null;
154
- let r = O(n, "src");
155
- try {
156
- if (!(await N.stat(r)).isDirectory()) return null;
157
- } catch {
158
- return null;
159
- }
160
- return {
161
- pkg: t,
162
- dir: r
163
- };
164
- }))).filter((e) => e !== null);
165
- }, ze = 500, Be = (e, t, n = {}) => {
131
+ }, ht = 500, gt = (e, t, n = {}) => {
166
132
  if (e.length === 0) return () => {};
167
- let r = (e) => n.root ? k(n.root, e) : e, i = !1, a = (e) => {
133
+ let r = (e) => n.root ? I(n.root, e) : e, i = !1, a = (e) => {
168
134
  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(() => {
169
- let e = _e(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
135
+ let e = ze(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
170
136
  stdio: "inherit",
171
137
  env: process.env,
172
138
  cwd: n.cwd ?? process.cwd()
@@ -180,22 +146,22 @@ __installPublicEnv(publicEnvValues)
180
146
  });
181
147
  }));
182
148
  };
183
- for (let t of e) ne(t, { interval: ze }, (e, n) => {
149
+ for (let t of e) fe(t, { interval: ht }, (e, n) => {
184
150
  e.mtimeMs !== n.mtimeMs && a(t);
185
151
  });
186
152
  return t.info("watching .env files for changes", {
187
153
  files: e.map(r),
188
- intervalMs: ze
154
+ intervalMs: ht
189
155
  }), () => {
190
- for (let t of e) te(t);
156
+ for (let t of e) U(t);
191
157
  };
192
- }, Ve = [{
158
+ }, _t = [{
193
159
  host: "127.0.0.1",
194
160
  family: "IPv4"
195
161
  }, {
196
162
  host: "::1",
197
163
  family: "IPv6"
198
- }], J = (e, t, n) => new Promise((r) => {
164
+ }], vt = (e, t, n) => new Promise((r) => {
199
165
  let i = !1, a = (e) => {
200
166
  if (!i) {
201
167
  i = !0;
@@ -204,15 +170,15 @@ __installPublicEnv(publicEnvValues)
204
170
  } catch {}
205
171
  r(e);
206
172
  }
207
- }, o = K({
173
+ }, o = Y({
208
174
  host: e,
209
175
  port: t
210
176
  });
211
177
  o.once("connect", () => a(!0)), o.once("error", () => a(!1)), o.setTimeout(n, () => a(!1));
212
- }), He = async (e, t = 400) => ({ families: (await Promise.all(Ve.map(async (n) => ({
178
+ }), yt = async (e, t = 400) => ({ families: (await Promise.all(_t.map(async (n) => ({
213
179
  family: n.family,
214
- taken: await J(n.host, e, t)
215
- })))).filter((e) => e.taken).map((e) => e.family) }), Ue = (e, t, n) => [
180
+ taken: await vt(n.host, e, t)
181
+ })))).filter((e) => e.taken).map((e) => e.family) }), bt = (e, t, n) => [
216
182
  `${t}: port ${e} is already being served (${n.join(" + ")}).`,
217
183
  "",
218
184
  " Refusing to start. This is NOT a spurious check — a second listener can",
@@ -227,26 +193,26 @@ __installPublicEnv(publicEnvValues)
227
193
  "",
228
194
  " Then re-run. To use a different port instead, change `port` in",
229
195
  " app.config.ts."
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) => {
196
+ ].join("\n"), xt = async (e, t) => {
197
+ let { families: r } = await yt(e);
198
+ if (r.length !== 0) throw n(bt(e, t, r));
199
+ }, St = (e) => e === "effect" || e.startsWith("@effect/") || e.startsWith("@voltro/") || e === "react" || e === "react-dom", Ct = /(^|\/)(\.bin|\.cache|\.pnpm-store|dist|build)(\/|$)/, wt = (e) => {
234
200
  let t = [], n = e;
235
201
  for (let e = 0; e < 12; e++) {
236
- let e = O(n, "node_modules");
237
- M(e) && t.push(e);
238
- let r = D(n);
202
+ let e = F(n, "node_modules");
203
+ z(e) && t.push(e);
204
+ let r = P(n);
239
205
  if (r === n) break;
240
206
  n = r;
241
207
  }
242
208
  return t;
243
- }, Je = (e) => {
209
+ }, Tt = (e) => {
244
210
  let t = /* @__PURE__ */ new Set([e]), n = e;
245
211
  for (let e = 0; e < 12; e++) {
246
212
  for (let e of ["pnpm-workspace.yaml", "pnpm-workspace.yml"]) {
247
213
  let r;
248
214
  try {
249
- r = P(O(n, e), "utf8");
215
+ r = V(F(n, e), "utf8");
250
216
  } catch {
251
217
  continue;
252
218
  }
@@ -257,38 +223,38 @@ __installPublicEnv(publicEnvValues)
257
223
  if (i === "" || i.includes("*")) continue;
258
224
  let a;
259
225
  try {
260
- a = F(O(n, i), { withFileTypes: !0 });
226
+ a = H(F(n, i), { withFileTypes: !0 });
261
227
  } catch {
262
228
  continue;
263
229
  }
264
- for (let e of a) e.isDirectory() && t.add(O(n, i, e.name));
230
+ for (let e of a) e.isDirectory() && t.add(F(n, i, e.name));
265
231
  }
266
232
  }
267
233
  for (let e of ["packages", "apps"]) {
268
234
  let r;
269
235
  try {
270
- r = F(O(n, e), { withFileTypes: !0 });
236
+ r = H(F(n, e), { withFileTypes: !0 });
271
237
  } catch {
272
238
  continue;
273
239
  }
274
- for (let i of r) i.isDirectory() && t.add(O(n, e, i.name));
240
+ for (let i of r) i.isDirectory() && t.add(F(n, e, i.name));
275
241
  }
276
- let e = D(n);
242
+ let e = P(n);
277
243
  if (e === n) break;
278
244
  n = e;
279
245
  }
280
246
  return [...t];
281
- }, Ye = (e) => {
247
+ }, Et = (e) => {
282
248
  let t = [];
283
- for (let n of Je(e)) {
284
- let e = O(n, "node_modules", "@voltro"), r;
249
+ for (let n of Tt(e)) {
250
+ let e = F(n, "node_modules", "@voltro"), r;
285
251
  try {
286
- r = F(e);
252
+ r = H(e);
287
253
  } catch {
288
254
  continue;
289
255
  }
290
256
  for (let n of r) {
291
- let r = O(e, n), i = Xe(r);
257
+ let r = F(e, n), i = Dt(r);
292
258
  i !== void 0 && t.push({
293
259
  pkg: `@voltro/${n}`,
294
260
  version: i,
@@ -297,38 +263,38 @@ __installPublicEnv(publicEnvValues)
297
263
  }
298
264
  }
299
265
  return t;
300
- }, Xe = (e) => {
266
+ }, Dt = (e) => {
301
267
  try {
302
- let t = JSON.parse(P(O(e, "package.json"), "utf8"));
268
+ let t = JSON.parse(V(F(e, "package.json"), "utf8"));
303
269
  return typeof t.version == "string" ? t.version : void 0;
304
270
  } catch {
305
271
  return;
306
272
  }
307
- }, Ze = (e) => {
273
+ }, Ot = (e) => {
308
274
  let t = [], n;
309
275
  try {
310
- n = F(e);
276
+ n = H(e);
311
277
  } catch {
312
278
  return t;
313
279
  }
314
280
  for (let r of n) {
315
- if (r.startsWith(".") || Ke.test(r)) continue;
316
- let n = O(e, r);
281
+ if (r.startsWith(".") || Ct.test(r)) continue;
282
+ let n = F(e, r);
317
283
  if (r.startsWith("@")) {
318
284
  let e;
319
285
  try {
320
- e = F(n);
286
+ e = H(n);
321
287
  } catch {
322
288
  continue;
323
289
  }
324
290
  for (let i of e) t.push({
325
291
  pkg: `${r}/${i}`,
326
- dir: O(n, i)
292
+ dir: F(n, i)
327
293
  });
328
294
  continue;
329
295
  }
330
296
  try {
331
- if (!ee(n).isDirectory()) continue;
297
+ if (!de(n).isDirectory()) continue;
332
298
  } catch {
333
299
  continue;
334
300
  }
@@ -338,25 +304,25 @@ __installPublicEnv(publicEnvValues)
338
304
  });
339
305
  }
340
306
  return t;
341
- }, Qe = (e) => {
307
+ }, kt = (e) => {
342
308
  let t = /* @__PURE__ */ new Map(), n = (e, n, r) => {
343
- if (!Ge(e)) return;
309
+ if (!St(e)) return;
344
310
  let i = t.get(e) ?? /* @__PURE__ */ new Map();
345
311
  i.has(n) || i.set(n, r), t.set(e, i);
346
312
  };
347
- for (let t of qe(e)) for (let { pkg: e, dir: r } of Ze(t)) {
348
- let t = Xe(r);
313
+ for (let t of wt(e)) for (let { pkg: e, dir: r } of Ot(t)) {
314
+ let t = Dt(r);
349
315
  t !== void 0 && n(e, t, r);
350
316
  }
351
- for (let { pkg: t, version: r, dir: i } of Ye(e)) n(t, r, i);
317
+ for (let { pkg: t, version: r, dir: i } of Et(e)) n(t, r, i);
352
318
  let r = [];
353
319
  for (let [n, i] of t) i.size < 2 || r.push({
354
320
  pkg: n,
355
321
  versions: [...i.keys()].sort(),
356
- paths: [...i.values()].map((t) => k(e, t)).sort()
322
+ paths: [...i.values()].map((t) => I(e, t)).sort()
357
323
  });
358
324
  return r.sort((e, t) => e.pkg.localeCompare(t.pkg));
359
- }, $e = (e) => {
325
+ }, At = (e) => {
360
326
  if (e.length !== 0) return [
361
327
  `• ${e.length} package(s) resolved at more than one version:`,
362
328
  ...e.flatMap((e) => [` ${e.pkg} — ${e.versions.join(", ")}`, ...e.paths.map((e) => ` ${e}`)]),
@@ -374,11 +340,11 @@ __installPublicEnv(publicEnvValues)
374
340
  " instrument), then reinstall. Do not silence the generated file — it is where",
375
341
  " a genuine mistake in your own descriptors surfaces."
376
342
  ].join("\n");
377
- }, et = (e) => {
343
+ }, jt = (e) => {
378
344
  let t = /* @__PURE__ */ new Map();
379
- for (let n of qe(e)) for (let { pkg: e, dir: r } of Ze(n)) {
345
+ for (let n of wt(e)) for (let { pkg: e, dir: r } of Ot(n)) {
380
346
  if (!e.startsWith("@voltro/")) continue;
381
- let n = Xe(r);
347
+ let n = Dt(r);
382
348
  n !== void 0 && !t.has(e) && t.set(e, n);
383
349
  }
384
350
  if (t.size < 2) return;
@@ -393,7 +359,7 @@ __installPublicEnv(publicEnvValues)
393
359
  version: t
394
360
  })).sort((e, t) => e.pkg.localeCompare(t.pkg))
395
361
  };
396
- }, tt = (e) => {
362
+ }, Mt = (e) => {
397
363
  if (e !== void 0) return [
398
364
  `• ${e.behind.length} @voltro/* package(s) are not on ${e.majority}:`,
399
365
  ...e.behind.map((e) => ` ${e.pkg} ${e.version}`),
@@ -411,59 +377,59 @@ __installPublicEnv(publicEnvValues)
411
377
  " its pattern: the one that produced this report was `@voltro/[a-z-]+`,",
412
378
  " which silently skips `@voltro/i18n` because the name contains digits."
413
379
  ].join("\n");
414
- }, nt = (e, t) => {
415
- let n = et(e);
380
+ }, Nt = (e, t) => {
381
+ let n = jt(e);
416
382
  n !== void 0 && t.warn?.(`@voltro/* version skew: ${n.behind.length} package(s) are not on ${n.majority}`, {
417
383
  majority: n.majority,
418
384
  behind: n.behind.map((e) => `${e.pkg}@${e.version}`),
419
385
  fix: "the framework ships in lockstep; bump the listed packages and reinstall"
420
386
  });
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 = [
387
+ }, Pt = G({ scope: "vite" }), Ft = /\x1b\[[0-9;]*m/g, It = /^\s*\[?vite\]?\s*(\([a-z-]+\)\s*)?/, Lt = (e) => e.replace(Ft, "").replace(It, "").trim(), Rt = /proxy error/i, zt = [
422
388
  "ECONNREFUSED",
423
389
  "ECONNRESET",
424
390
  "ECONNABORTED",
425
391
  "EPIPE",
426
392
  "ETIMEDOUT"
427
- ], lt = (e, t = 0) => {
393
+ ], Bt = (e, t = 0) => {
428
394
  if (e == null || t > 5) return !1;
429
395
  let n = 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 = () => {
396
+ return typeof n.code == "string" && zt.includes(n.code) || typeof n.message == "string" && zt.some((e) => n.message.includes(e)) || Array.isArray(n.errors) && n.errors.some((e) => Bt(e, t + 1)) ? !0 : Bt(n.cause, t + 1);
397
+ }, Vt = 4e3, Ht = () => {
432
398
  let e = /* @__PURE__ */ new Set(), t = 0, n = {
433
399
  hasWarned: !1,
434
400
  info: (e) => {
435
- let t = ot(e);
436
- t.length !== 0 && rt.info(t);
401
+ let t = Lt(e);
402
+ t.length !== 0 && Pt.info(t);
437
403
  },
438
404
  warn: (e) => {
439
405
  n.hasWarned = !0;
440
- let t = ot(e);
441
- t.length !== 0 && rt.warn(t);
406
+ let t = Lt(e);
407
+ t.length !== 0 && Pt.warn(t);
442
408
  },
443
409
  warnOnce: (t) => {
444
- let r = ot(t);
445
- e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && rt.warn(r));
410
+ let r = Lt(t);
411
+ e.has(r) || (e.add(r), n.hasWarned = !0, r.length !== 0 && Pt.warn(r));
446
412
  },
447
413
  error: (e, n) => {
448
- let r = ot(e), i = n?.error;
414
+ let r = Lt(e), i = n?.error;
449
415
  if (r.length !== 0) {
450
- if (st.test(r) && lt(i)) {
416
+ if (Rt.test(r) && Bt(i)) {
451
417
  let e = Date.now();
452
- e - t > ut && (t = e, rt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
418
+ e - t > Vt && (t = e, Pt.info("waiting for api — proxy upstream not accepting connections yet (still starting?)"));
453
419
  return;
454
420
  }
455
- rt.error(r, {}, i);
421
+ Pt.error(r, {}, i);
456
422
  }
457
423
  },
458
424
  clearScreen: () => {},
459
425
  hasErrorLogged: (e) => !1
460
426
  };
461
427
  return n;
462
- }, ft = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), pt = (e) => {
428
+ }, Ut = (e) => e.replace(/\\"|"(?:[^"\\]|\\.)*"|(\/\/[^\n]*|\/\*[\s\S]*?\*\/)/g, (e, t) => t ? "" : e), Wt = (e) => {
463
429
  try {
464
- let t = O(e, "tsconfig.json");
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 = [];
430
+ let t = F(e, "tsconfig.json");
431
+ if (!z(t)) return [];
432
+ let n = JSON.parse(Ut(V(t, "utf8"))).compilerOptions ?? {}, r = n.paths ?? {}, i = n.baseUrl ?? ".", a = L(e, i), o = [];
467
433
  for (let [e, t] of Object.entries(r)) {
468
434
  let n = t[0];
469
435
  if (!n) continue;
@@ -473,11 +439,11 @@ __installPublicEnv(publicEnvValues)
473
439
  let t = e.slice(0, -2).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
474
440
  o.push({
475
441
  find: RegExp(`^${t}/(.*)$`),
476
- replacement: `${O(a, n.slice(0, -2))}/$1`
442
+ replacement: `${F(a, n.slice(0, -2))}/$1`
477
443
  });
478
444
  } else o.push({
479
445
  find: e,
480
- replacement: O(a, n)
446
+ replacement: F(a, n)
481
447
  });
482
448
  }
483
449
  }
@@ -485,12 +451,12 @@ __installPublicEnv(publicEnvValues)
485
451
  } catch {
486
452
  return [];
487
453
  }
488
- }, mt = (e = process.env) => {
454
+ }, Gt = (e = process.env) => {
489
455
  let t = e.VOLTRO_DEV_SSR_COMPILE_CONCURRENCY;
490
456
  if (t === void 0 || t.trim() === "") return 4;
491
457
  let n = Number(t);
492
458
  return Number.isFinite(n) && n >= 1 ? Math.floor(n) : 4;
493
- }, ht = (e) => {
459
+ }, Kt = (e) => {
494
460
  let t = Math.max(1, Math.floor(e)), n = 0, r = [], i = () => n < t ? (n++, Promise.resolve()) : new Promise((e) => r.push(e)), a = () => {
495
461
  let e = r.shift();
496
462
  e ? e() : n--;
@@ -508,8 +474,8 @@ __installPublicEnv(publicEnvValues)
508
474
  return n;
509
475
  }
510
476
  };
511
- }, gt = (e) => {
512
- let t = ht(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
477
+ }, qt = (e) => {
478
+ let t = Kt(e.limit), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
513
479
  return {
514
480
  load: (i, a) => {
515
481
  if (r.has(i)) return a();
@@ -539,19 +505,23 @@ __installPublicEnv(publicEnvValues)
539
505
  return r.size;
540
506
  }
541
507
  };
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>`;
508
+ }, Jt = 1048576, Yt = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), Xt = (e) => JSON.stringify(e).replace(/</g, "\\u003c"), Zt = (e, t) => {
509
+ let n = `<script type="application/json" id="${Be}">${Xt(t)}<\/script>`;
544
510
  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") => {
511
+ }, Qt = (e) => {
512
+ let t = Object.entries(e.errors).map(([e, t]) => `<li><strong>${Yt(e)}</strong>: ${Yt(t)}</li>`).join("");
513
+ 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>${Yt(e.formError)}</p>`}<ul>${t}</ul><p><a href="javascript:history.back()">Go back</a> to correct the form.</p></body></html>`;
514
+ }, X = (e, t, n, r = "text/plain; charset=utf-8") => {
549
515
  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) => {
516
+ }, $t = (e, t, n) => {
517
+ e.setHeader("cache-control", "no-store"), X(e, t, n, "text/html; charset=utf-8");
518
+ }, en = (e) => {
553
519
  if (e !== void 0 && e !== "" && !(!e.startsWith("/") || e.startsWith("//") || e.includes("\\"))) return e;
554
- }, wt = (e) => {
520
+ }, tn = (e, t) => {
521
+ if (e === void 0 || t === void 0 || t.length === 0) return;
522
+ let n = e.replace(/^\/+/, "").split(/[/?#]/)[0];
523
+ if (n !== void 0 && n !== "") return t.includes(n) ? n : void 0;
524
+ }, nn = (e) => {
555
525
  let t = e.referer;
556
526
  if (t !== void 0) try {
557
527
  let e = new URL(t);
@@ -559,10 +529,10 @@ __installPublicEnv(publicEnvValues)
559
529
  } catch {
560
530
  return;
561
531
  }
562
- }, Tt = (e) => new Promise((t) => {
532
+ }, rn = (e) => new Promise((t) => {
563
533
  let n = [], r = 0;
564
534
  e.on("data", (i) => {
565
- if (r += i.length, r > _t) {
535
+ if (r += i.length, r > Jt) {
566
536
  e.removeAllListeners("data"), e.removeAllListeners("end"), t({ ok: !1 });
567
537
  return;
568
538
  }
@@ -571,32 +541,32 @@ __installPublicEnv(publicEnvValues)
571
541
  ok: !0,
572
542
  body: Buffer.concat(n).toString("utf8")
573
543
  })), e.on("error", () => t({ ok: !1 }));
574
- }), Et = (e) => {
544
+ }), an = (e) => {
575
545
  let t = {};
576
546
  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
547
  return t;
578
- }, Dt = (e) => {
579
- let t = e.originGuard ?? ae(void 0, process.env);
548
+ }, on = (e) => {
549
+ let t = e.originGuard ?? Se(void 0, process.env);
580
550
  return async (n, r, i) => {
581
551
  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({
552
+ if (!a.startsWith(He)) return !1;
553
+ if (n.method !== "POST") return r.setHeader("allow", "POST"), X(r, 405, "method not allowed — a /form/* endpoint accepts native form POSTs only"), !0;
554
+ let o = an(n);
555
+ if (!be({
586
556
  headers: o,
587
557
  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]);
558
+ }).allowed) return X(r, 403, "origin not allowed"), !0;
559
+ if ((o["content-type"] ?? "").includes("multipart/form-data")) return X(r, 415, "file uploads need JavaScript — the no-JS form path accepts application/x-www-form-urlencoded only"), !0;
560
+ let s = await rn(n);
561
+ if (!s.ok) return X(r, 413, `form body exceeds ${Jt} bytes`), !0;
562
+ let c = new URLSearchParams(s.body), l = decodeURIComponent(a.slice(He.length)), u = (await e.loadDescriptors())?.[l];
563
+ if (u === void 0 || u.kind !== "mutation") return X(r, 404, `no mutation '${l}' — /form/* serves declared mutations only`), !0;
564
+ let d = c.get(Ve) ?? l, f = en(c.get(We) ?? void 0), p = [];
565
+ for (let [e, t] of c) e !== Ve && e !== We && p.push([e, t]);
596
566
  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);
567
+ if (m === void 0) return X(r, 404, `mutation '${l}' carries no input schema — the no-JS path cannot map its POST`), !0;
568
+ let h = Ge(m, p), g = Ke(m, h, { locale: await e.resolveLocale(o, nn(o)) }), _ = async (t) => {
569
+ let n = nn(o);
600
570
  if (n !== void 0) {
601
571
  if (i !== void 0) {
602
572
  i(n, t);
@@ -608,11 +578,11 @@ __installPublicEnv(publicEnvValues)
608
578
  flash: t
609
579
  });
610
580
  if (a !== void 0) {
611
- St(r, 422, bt(a, t));
581
+ $t(r, 422, Zt(a, t));
612
582
  return;
613
583
  }
614
584
  }
615
- St(r, 422, xt(t));
585
+ $t(r, 422, Qt(t));
616
586
  };
617
587
  if (!g.valid) return await _({
618
588
  formKey: d,
@@ -620,7 +590,7 @@ __installPublicEnv(publicEnvValues)
620
590
  errors: g.errors
621
591
  }), !0;
622
592
  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;
593
+ if (v === void 0) return X(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
594
  try {
625
595
  await v(l, h);
626
596
  } catch (e) {
@@ -632,10 +602,10 @@ __installPublicEnv(publicEnvValues)
632
602
  formError: t?.message ?? t?._tag ?? "The server rejected this submission. Please try again."
633
603
  }), !0;
634
604
  }
635
- let y = f ?? wt(o) ?? "/";
605
+ let y = f ?? nn(o) ?? "/";
636
606
  return r.statusCode = 303, r.setHeader("location", y), r.end(), !0;
637
607
  };
638
- }, Ot = /^\s*(?:import|export)\s[^;'"]*?['"]([^'"]+)['"]/gm, kt = [
608
+ }, sn = /^\s*(?:import|export)\s[^;'"]*?['"]([^'"]+)['"]/gm, cn = [
639
609
  "",
640
610
  ".tsx",
641
611
  ".ts",
@@ -643,87 +613,87 @@ __installPublicEnv(publicEnvValues)
643
613
  ".js",
644
614
  "/index.tsx",
645
615
  "/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) => {
616
+ ], ln = (e) => /\.island\.(tsx|ts|jsx|js)$/.test(e), un = ["@voltro/web", "@voltro/i18n"], dn = ["@voltro/client", "@voltro/ui"], fn = (e, t) => e === t || e.startsWith(`${t}/`), pn = (e) => e !== "@voltro/web/islands" && un.some((t) => fn(e, t)), mn = (e) => {
647
617
  let t = [];
648
- for (let n of e.matchAll(Ot)) t.push(n[1]);
618
+ for (let n of e.matchAll(sn)) t.push(n[1]);
649
619
  return t;
650
- }, It = async (e, t) => {
651
- let n = A(D(e), t);
652
- for (let e of kt) {
620
+ }, hn = async (e, t) => {
621
+ let n = L(P(e), t);
622
+ for (let e of cn) {
653
623
  let t = n + e;
654
624
  try {
655
- if ((await N.stat(t)).isFile()) return t;
625
+ if ((await B.stat(t)).isFile()) return t;
656
626
  } catch {}
657
627
  }
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) => {
628
+ }, gn = async (e, t) => {
629
+ let n = F(e, "src", "pages", t), r = /* @__PURE__ */ new Set(), i = [], a = !1, o = [], s = async (t, n) => {
660
630
  let c = `${t}\u0000${n ? "i" : "p"}`;
661
631
  if (r.has(c)) return;
662
632
  r.add(c);
663
633
  let l;
664
634
  try {
665
- l = await N.readFile(t, "utf8");
635
+ l = await B.readFile(t, "utf8");
666
636
  } catch {
667
637
  return;
668
638
  }
669
- for (let r of Ft(l)) {
639
+ for (let r of mn(l)) {
670
640
  if (n) {
671
- if (Pt(r)) {
672
- o.push([k(e, t).split(j).join("/"), r]);
641
+ if (pn(r)) {
642
+ o.push([I(e, t).split(R).join("/"), r]);
673
643
  continue;
674
644
  }
675
- if (Mt.some((e) => Nt(r, e))) {
645
+ if (dn.some((e) => fn(r, e))) {
676
646
  a = !0;
677
647
  continue;
678
648
  }
679
649
  }
680
650
  if (!r.startsWith(".")) continue;
681
- let c = await It(t, r);
651
+ let c = await hn(t, r);
682
652
  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("/");
653
+ let l = n || ln(c);
654
+ if (!n && ln(c)) {
655
+ let t = I(e, c).split(R).join("/");
686
656
  i.includes(t) || i.push(t);
687
657
  }
688
658
  await s(c, l);
689
659
  }
690
660
  };
691
- return await s(n, At(n)), At(n) && i.unshift(k(e, n).split(j).join("/")), {
661
+ return await s(n, ln(n)), ln(n) && i.unshift(I(e, n).split(R).join("/")), {
692
662
  islandFiles: i,
693
663
  usesClient: a,
694
664
  violations: o
695
665
  };
696
- }, Rt = (e) => {
666
+ }, _n = (e) => {
697
667
  let t = /^export const interactive\s*=\s*['"](full|islands|none)['"]/m.exec(e);
698
668
  return t === null ? void 0 : t[1];
699
- }, zt = (e) => {
669
+ }, vn = (e) => {
700
670
  let t = e.indexOf("</head>"), n = t === -1 ? e : e.slice(0, t), r = [];
701
671
  for (let e of n.matchAll(/<script\b([^>]*)>([\s\S]*?)<\/script>/gi)) {
702
672
  let t = e[1] ?? "";
703
673
  /\bsrc\s*=/.test(t) || /type\s*=\s*["']module["']/.test(t) || r.push(e[0]);
704
674
  }
705
675
  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));
676
+ }, yn = (e) => [...e.matchAll(/<link\b[^>]*\brel\s*=\s*["']stylesheet["'][^>]*>/gi)].map((e) => e[0]), bn = (e, t) => {
677
+ let n = yn(t).filter((t) => !e.includes(t));
708
678
  if (n.length === 0) return e;
709
679
  let r = n.map((e) => ` ${e}`).join("\n");
710
680
  return e.includes("</head>") ? e.replace("</head>", `${r}\n </head>`) : e + r;
711
- }, Ht = (e) => {
681
+ }, xn = (e) => {
712
682
  let t = e.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "");
713
683
  return t === "" ? "root" : t;
714
- }, Ut = class extends Error {
684
+ }, Sn = class extends Error {
715
685
  constructor(e, t) {
716
686
  let n = t.map(([e, t]) => ` ${e} imports '${t}'`).join("\n");
717
687
  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
688
  }
719
- }, Wt = async (e) => {
720
- let t = O(e.webRoot, ".framework", "island-shells"), n = [];
689
+ }, Cn = async (e) => {
690
+ let t = F(e.webRoot, ".framework", "island-shells"), n = [];
721
691
  if (e.pages.length === 0) return n;
722
- await N.mkdir(t, { recursive: !0 });
692
+ await B.mkdir(t, { recursive: !0 });
723
693
  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 ? [
694
+ let i = await gn(e.webRoot, r.file);
695
+ if (i.violations.length > 0) throw new Sn(r.pattern, i.violations);
696
+ let a = xn(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
697
  `// GENERATED by voltro — the islands entry for '${r.pattern}' (client boot:`,
728
698
  "// an island here imports @voltro/client, so the roots get a live runtime).",
729
699
  ...e.apiImports ?? [],
@@ -759,7 +729,7 @@ __installPublicEnv(publicEnvValues)
759
729
  "</html>",
760
730
  ""
761
731
  ].join("\n");
762
- await N.writeFile(O(t, `${a}.tsx`), l), await N.writeFile(O(t, `${a}.html`), u), n.push({
732
+ await B.writeFile(F(t, `${a}.tsx`), l), await B.writeFile(F(t, `${a}.html`), u), n.push({
763
733
  pattern: r.pattern,
764
734
  name: a,
765
735
  htmlFile: s,
@@ -768,111 +738,441 @@ __installPublicEnv(publicEnvValues)
768
738
  });
769
739
  }
770
740
  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"
741
+ }, wn = G({ scope: "voltro:images" }), Tn = /[?&]image(?:&|$)/, En = /\.(png|jpe?g|webp|avif)(\?|$)/i, Dn = {
742
+ avif: "image/avif",
743
+ webp: "image/webp",
744
+ jpeg: "image/jpeg",
745
+ png: "image/png"
746
+ }, On = (e) => J("sha256").update(e).digest("hex").slice(0, 12), kn = (e) => `export default ${JSON.stringify(e)}\n`, An = (e) => {
747
+ let t = e.config ?? j, n = C(e.root), r = /* @__PURE__ */ new Map(), i = "/", a = !1;
748
+ return {
749
+ name: "voltro:image-assets",
750
+ enforce: "pre",
751
+ configResolved(e) {
752
+ i = e.base, a = e.command === "build";
795
753
  },
796
- body: "not found"
754
+ async load(o) {
755
+ if (!Tn.test(o) || !En.test(o)) return null;
756
+ let s = o.split("?")[0], c = s, l = await O(c);
757
+ if (l === null && s.startsWith("/") && (c = F(e.root, s.slice(1)), l = await O(c)), l === null && this.error(`?image import points at a file that does not exist or is unreadable: ${s}`), await w() === null) {
758
+ E(wn);
759
+ let t;
760
+ if (a || e.urlMode === "build-urls") {
761
+ let e = `assets/${On(c)}${c.slice(c.lastIndexOf("."))}`;
762
+ a && this.emitFile({
763
+ type: "asset",
764
+ fileName: e,
765
+ source: Buffer.from(l)
766
+ }), t = `${i}${e}`;
767
+ } else t = `/@fs${c}`;
768
+ return kn({
769
+ src: t,
770
+ width: 0,
771
+ height: 0,
772
+ blurDataURL: "",
773
+ srcSet: "",
774
+ sources: []
775
+ });
776
+ }
777
+ if (a || e.urlMode === "build-urls") {
778
+ let e = await D({
779
+ sourceBytes: l,
780
+ cacheDir: n,
781
+ config: t
782
+ });
783
+ e === null && this.error(`?image import is not a raster image sharp can read: ${c}`);
784
+ let r = /* @__PURE__ */ new Map();
785
+ for (let t of e.variants) {
786
+ let e = t.format === "jpeg" ? "jpg" : t.format, n = `assets/${t.hash}.${e}`;
787
+ a && this.emitFile({
788
+ type: "asset",
789
+ fileName: n,
790
+ source: Buffer.from(t.bytes)
791
+ }), r.set(`${t.format}:${t.width}`, `${i}${n}`);
792
+ }
793
+ let o = (t) => e.widths.map((e) => `${r.get(`${t}:${e}`)} ${e}w`).join(", ");
794
+ return kn({
795
+ src: r.get(`${e.fallbackFormat}:${e.widths[e.widths.length - 1]}`),
796
+ width: e.width,
797
+ height: e.height,
798
+ blurDataURL: e.blurDataURL,
799
+ srcSet: o(e.fallbackFormat),
800
+ sources: t.formats.map((e) => ({
801
+ type: Dn[e],
802
+ srcSet: o(e)
803
+ }))
804
+ });
805
+ }
806
+ let u = await A(l);
807
+ u === null && this.error(`?image import is not a raster image sharp can read: ${c}`);
808
+ let d = J("sha256").update(l).digest("hex").slice(0, 16), f = await te(l, d, n), p = On(c);
809
+ r.set(p, c);
810
+ let m = k(u.width), h = u.format === "png" ? "png" : "jpeg", g = (e, t) => `/_voltro/image/${p}?w=${e}&f=${t}`, _ = (e) => m.map((t) => `${g(t, e)} ${t}w`).join(", ");
811
+ return kn({
812
+ src: g(m[m.length - 1], h),
813
+ width: u.width,
814
+ height: u.height,
815
+ blurDataURL: f ?? "",
816
+ srcSet: _(h),
817
+ sources: t.formats.map((e) => ({
818
+ type: Dn[e],
819
+ srcSet: _(e)
820
+ }))
821
+ });
822
+ },
823
+ configureServer(e) {
824
+ e.middlewares.use("/_voltro/image", (e, i, a) => {
825
+ (async () => {
826
+ let a = new URL(e.url ?? "/", "http://localhost"), o = a.pathname.replace(/^\//, ""), s = r.get(o);
827
+ if (s === void 0) {
828
+ i.statusCode = 404, i.end("unknown image asset");
829
+ return;
830
+ }
831
+ let c = Number(a.searchParams.get("w")), l = a.searchParams.get("f") ?? "";
832
+ if (!Number.isInteger(c) || c <= 0 || c > 8192 || Dn[l] === void 0) {
833
+ i.statusCode = 400, i.end("bad transform params");
834
+ return;
835
+ }
836
+ let u = await O(s);
837
+ if (u === null) {
838
+ i.statusCode = 404, i.end("source asset gone");
839
+ return;
840
+ }
841
+ let d = J("sha256").update(u).digest("hex").slice(0, 16), f = await T({
842
+ sourceBytes: u,
843
+ sourceHash: d,
844
+ width: c,
845
+ format: l,
846
+ quality: t.quality,
847
+ cacheDir: n
848
+ });
849
+ if (f === null) {
850
+ E(wn), i.statusCode = 200, i.setHeader("content-type", Dn[l] ?? "application/octet-stream"), i.end(Buffer.from(u));
851
+ return;
852
+ }
853
+ i.statusCode = 200, i.setHeader("content-type", Dn[l]), i.setHeader("cache-control", "max-age=31536000, immutable"), i.end(Buffer.from(f));
854
+ })().catch((e) => {
855
+ wn.warn("image transform failed", {}, e), a();
856
+ });
857
+ });
858
+ }
797
859
  };
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 } : {}
860
+ }, jn = G({ scope: "voltro:fonts" }), Mn = /* @__PURE__ */ new Map(), Nn = async (e, t) => {
861
+ if (t === void 0 || t.length === 0) return null;
862
+ let n = Mn.get(e);
863
+ return n === void 0 && (n = M(t, async (t) => new Uint8Array(await Fe(F(e, t)))).then((e) => {
864
+ for (let t of e.warnings) ne(t, jn);
865
+ return e;
866
+ }), Mn.set(e, n)), n;
867
+ }, Pn = {
868
+ woff2: "font/woff2",
869
+ woff: "font/woff",
870
+ otf: "font/otf",
871
+ ttf: "font/ttf"
872
+ }, Fn = (e, t) => ({
873
+ name: "voltro:font-assets",
874
+ configureServer(n) {
875
+ n.middlewares.use("/assets/fonts", (n, r, i) => {
876
+ (async () => {
877
+ let a = await Nn(e, t), o = (n.url ?? "/").replace(/^\//, "").split("?")[0], s = a?.files.find((e) => e.fileName === `assets/fonts/${o}`);
878
+ if (s === void 0) {
879
+ i();
880
+ return;
881
+ }
882
+ let c = o.slice(o.lastIndexOf(".") + 1);
883
+ r.statusCode = 200, r.setHeader("content-type", Pn[c] ?? "application/octet-stream"), r.setHeader("cache-control", "max-age=31536000, immutable"), r.end(Buffer.from(s.bytes));
884
+ })().catch(() => i());
811
885
  });
812
- } catch (e) {
813
- throw new Gt(e instanceof Error ? e.message : String(e));
814
886
  }
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 } : {}
887
+ }), In = G({ scope: "voltro:content" }), Ln = (e) => {
888
+ et(e);
889
+ }, Rn = (e, t) => `/assets/content-media/${e}${t}`, zn = "assets/content-media", Bn = (e) => {
890
+ let t = /* @__PURE__ */ new Map(), n = [];
891
+ return $e(({ src: r, entryFile: i }) => {
892
+ let [a = "", o = ""] = Wn(r), s = L(P(i), decodeURIComponent(a)), c = t.get(s);
893
+ if (c !== void 0) return c + o;
894
+ if (!z(s)) {
895
+ let e = I(process.cwd(), s);
896
+ return n.includes(e) || n.push(e), r;
827
897
  }
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
898
+ let l = V(s), u = J("sha256").update(l).digest("hex").slice(0, 16), d = le(s).toLowerCase(), f = Rn(u, d), p = F(e, zn, `${u}${d}`);
899
+ return ue(P(p), { recursive: !0 }), pe(p, l), t.set(s, f), f + o;
900
+ }), { missing: n };
901
+ }, Vn = () => {
902
+ $e(({ src: e, entryFile: t }) => {
903
+ let [n = "", r = ""] = Wn(e), i = L(P(t), decodeURIComponent(n));
904
+ if (!z(i)) return e;
905
+ let a = V(i), o = J("sha256").update(a).digest("hex").slice(0, 16);
906
+ return Hn.set(o, i), Rn(o, le(i).toLowerCase()) + r;
840
907
  });
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
908
+ }, Hn = /* @__PURE__ */ new Map(), Un = (e) => {
909
+ let t = /^\/assets\/content-media\/([0-9a-f]{16})(\.[a-z0-9]+)$/i.exec(e);
910
+ if (t === null) return null;
911
+ let n = Hn.get(t[1].toLowerCase());
912
+ return n === void 0 || !z(n) ? null : {
913
+ bytes: V(n),
914
+ contentType: Kn(t[2])
850
915
  };
851
- }, Xt = (e) => {
852
- let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
916
+ }, Wn = (e) => {
917
+ let t = e.search(/[?#]/);
918
+ return t === -1 ? [e, ""] : [e.slice(0, t), e.slice(t)];
919
+ }, Gn = {
920
+ ".png": "image/png",
921
+ ".jpg": "image/jpeg",
922
+ ".jpeg": "image/jpeg",
923
+ ".gif": "image/gif",
924
+ ".svg": "image/svg+xml",
925
+ ".webp": "image/webp",
926
+ ".avif": "image/avif",
927
+ ".ico": "image/x-icon"
928
+ }, Kn = (e) => Gn[e.toLowerCase()] ?? "application/octet-stream", qn = async (e, t) => {
929
+ let n = await Ye(e.collection, e.locale === void 0 ? {} : { locale: e.locale });
930
+ return qe(n, {
931
+ title: e.title,
932
+ siteUrl: t,
933
+ ...e.description === void 0 ? {} : { description: e.description },
934
+ feedPath: e.path,
935
+ item: e.item
936
+ });
937
+ }, Jn = async (e, t, n) => {
938
+ if (t.length !== 0) {
939
+ if (n === void 0 || n === "") throw Error("config.feeds needs seo.siteUrl — RSS links must be absolute. Set seo: { siteUrl } in app.config.ts.");
940
+ for (let r of t) {
941
+ let t = await qn(r, n), i = F(e, r.path.replace(/^\/+/, ""));
942
+ await K(P(i), { recursive: !0 }), await q(i, t), In.info(`feed: ${r.path} (${r.collection})`);
943
+ }
944
+ }
945
+ }, Yn = async (e, t) => {
946
+ let n = await Ye(e, t === void 0 ? {} : { locale: t });
947
+ return JSON.stringify(n.map(({ html: e, body: t, headings: n, ...r }) => r));
948
+ }, Xn = async (e, t, n) => {
949
+ let r = await Xe(e, t, n === void 0 ? {} : { locale: n });
950
+ if (r === null) return null;
951
+ let { body: i, ...a } = r;
952
+ return JSON.stringify(a);
953
+ }, Zn = async (e) => {
954
+ await tt();
955
+ let t = Bn(e), n = 0;
956
+ for (let t of Qe()) {
957
+ let r = t.i18n?.locales ?? [void 0];
958
+ for (let i of r) {
959
+ let r = await Yn(t.name, i), a = F(e, Je(t.name, i));
960
+ await K(P(a), { recursive: !0 }), await q(a, r), n += 1;
961
+ let o = JSON.parse(r);
962
+ for (let { slug: r } of o) {
963
+ let a = await Xn(t.name, r, i);
964
+ if (a === null) continue;
965
+ let o = F(e, Je(t.name, i, r));
966
+ await K(P(o), { recursive: !0 }), await q(o, a), n += 1;
967
+ }
968
+ }
969
+ }
970
+ if (t.missing.length > 0) throw Error(`content: ${t.missing.length} image reference(s) in markdown point at files that do not exist:\n` + t.missing.map((e) => ` - ${e}`).join("\n") + "\n\nA relative image is resolved against the markdown file that references it. Fix the path, or use an absolute `/…` src for an asset you serve yourself.");
971
+ return n > 0 && In.info(`content: ${n} artifact(s) into dist/assets/content`), n;
972
+ }, Qn = async (e) => {
973
+ let t = /^\/assets\/content\/([A-Za-z0-9_-]+)(?:\.([A-Za-z0-9-]+))?\/(.+)$/.exec(e);
974
+ if (t === null) return null;
975
+ let [, n, r, i] = t;
976
+ if (Qe().every((e) => e.name !== n)) return null;
977
+ try {
978
+ if (i === "index.json") return {
979
+ status: 200,
980
+ body: await Yn(n, r)
981
+ };
982
+ let e = await Xn(n, i.replace(/\.json$/, ""), r);
983
+ return e === null ? {
984
+ status: 404,
985
+ body: "\"not found\""
986
+ } : {
987
+ status: 200,
988
+ body: e
989
+ };
990
+ } catch (t) {
991
+ return In.warn("content request failed", { pathname: e }, t), {
992
+ status: 500,
993
+ body: "\"content error\""
994
+ };
995
+ }
996
+ }, $n = async (e) => {
997
+ let { readdir: t } = await import("node:fs/promises"), n = [], r;
998
+ try {
999
+ r = await t(e, { withFileTypes: !0 });
1000
+ } catch {
1001
+ return n;
1002
+ }
1003
+ for (let t of r) {
1004
+ if (t.name.startsWith(".") || t.name === "node_modules") continue;
1005
+ let r = F(e, t.name);
1006
+ t.isDirectory() ? n.push(...await $n(r)) : /\.collection\.tsx?$/.test(t.name) && n.push(r);
1007
+ }
1008
+ return n;
1009
+ }, er = (e, t = [], n) => ({
1010
+ name: "voltro:content",
1011
+ configureServer(r) {
1012
+ Vn(), r.middlewares.use("/assets/content-media", (e, t, n) => {
1013
+ let r = Un(`/assets/content-media${(e.url ?? "/").split("?")[0]}`);
1014
+ if (r === null) {
1015
+ n();
1016
+ return;
1017
+ }
1018
+ t.setHeader("content-type", r.contentType), t.end(r.bytes);
1019
+ });
1020
+ let i = null, a = () => (i ??= (async () => {
1021
+ for (let t of await $n(F(e, "src"))) try {
1022
+ await r.ssrLoadModule(t);
1023
+ } catch (e) {
1024
+ In.warn("failed to load collection module", { file: t }, e);
1025
+ }
1026
+ })(), i);
1027
+ r.watcher.add(F(e, "content")), r.watcher.on("all", (t, n) => {
1028
+ typeof n == "string" && n.startsWith(F(e, "content")) && (Ze(), r.ws.send({ type: "full-reload" }));
1029
+ });
1030
+ for (let e of t) r.middlewares.use(e.path, (t, r) => {
1031
+ (async () => {
1032
+ await a();
1033
+ let t = await qn(e, n ?? "http://localhost");
1034
+ r.setHeader("content-type", "application/rss+xml"), r.end(t);
1035
+ })().catch((t) => {
1036
+ In.warn("feed render failed", { path: e.path }, t), r.statusCode = 500, r.end("feed error");
1037
+ });
1038
+ });
1039
+ r.middlewares.use("/assets/content", (e, t, n) => {
1040
+ (async () => {
1041
+ await a();
1042
+ let r = await Qn(`/assets/content${(e.url ?? "/").split("?")[0]}`);
1043
+ if (r === null) {
1044
+ n();
1045
+ return;
1046
+ }
1047
+ t.statusCode = r.status, t.setHeader("content-type", "application/json"), t.end(r.body);
1048
+ })().catch(() => n());
1049
+ });
1050
+ }
1051
+ }), tr, nr = async () => {
1052
+ if (tr !== void 0) return tr;
1053
+ try {
1054
+ let e = await import("satori");
1055
+ tr = e.default ?? e;
1056
+ } catch {
1057
+ tr = null;
1058
+ }
1059
+ return tr;
1060
+ }, rr, ir = async () => {
1061
+ if (rr !== void 0) return rr;
1062
+ try {
1063
+ rr = await import("@resvg/resvg-js");
1064
+ } catch {
1065
+ rr = null;
1066
+ }
1067
+ return rr;
1068
+ }, ar = async (e, t) => {
1069
+ if (t === void 0 || t.length === 0) throw Error("ogImage needs a declared font: satori cannot render text without a font buffer, and there is no bundled default (that would ship a license artifact most projects replace). Declare one in app.config.ts — fonts: [{ family: 'Inter', src: [{ path: 'src/fonts/Inter.woff2' }] }] — see the Fonts docs.");
1070
+ let n = [];
1071
+ for (let r of t) for (let t of r.src) {
1072
+ let i = await Fe(F(e, t.path)), a = typeof t.weight == "number" ? t.weight : void 0;
1073
+ n.push({
1074
+ name: r.family,
1075
+ data: i.buffer.slice(i.byteOffset, i.byteOffset + i.byteLength),
1076
+ ...a === void 0 ? {} : { weight: a },
1077
+ ...t.style === void 0 ? {} : { style: t.style }
1078
+ });
1079
+ }
1080
+ return n;
1081
+ }, or = async (e) => {
1082
+ let t = await nr(), n = await ir();
1083
+ if (t === null || n === null) {
1084
+ let e = [t === null ? "satori" : null, n === null ? "@resvg/resvg-js" : null].filter((e) => e !== null).join(" + ");
1085
+ throw Error(`ogImage cannot render: ${e} is not loadable. Both ship as optional dependencies of @voltro/cli — if your installer omitted optional dependencies, run \`pnpm add -D satori @resvg/resvg-js\` in this app.`);
1086
+ }
1087
+ let r = await t(e.element, {
1088
+ width: e.width ?? 1200,
1089
+ height: e.height ?? 630,
1090
+ fonts: e.fonts.map((e) => ({
1091
+ ...e,
1092
+ data: e.data
1093
+ }))
1094
+ });
853
1095
  return {
854
- body: t,
855
- meta: n
1096
+ svg: r,
1097
+ png: new Uint8Array(new n.Resvg(r).render().asPng())
856
1098
  };
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: ""
1099
+ }, sr = (e, t, n, r) => `${e}\u0000${t}\u0000${n}\u0000${r}`, cr = (e, t) => Ie("sha256", e).update(t).digest("hex"), lr = () => {
1100
+ let e = process.env.VOLTRO_OG_SECRET;
1101
+ return e !== void 0 && e !== "" ? {
1102
+ secret: e,
1103
+ fromEnv: !0
871
1104
  } : {
872
- pathname: e.slice(0, t) || "/",
873
- search: e.slice(t)
1105
+ secret: Le(32).toString("hex"),
1106
+ fromEnv: !1
874
1107
  };
875
- }, en = (e) => {
1108
+ }, ur = "/_voltro/og", dr = (e) => {
1109
+ let t = e.ttlMs ?? 36e5, n, r = () => (n ??= ar(e.root, e.fonts), n);
1110
+ return {
1111
+ signOgUrl: ({ pattern: t, params: n, tenant: r, locale: i }) => {
1112
+ let a = JSON.stringify(n), o = r ?? "", s = i ?? "", c = cr(e.secret, sr(t, a, o, s));
1113
+ return `${ur}?${new URLSearchParams({
1114
+ route: t,
1115
+ p: a,
1116
+ ...o === "" ? {} : { t: o },
1117
+ ...s === "" ? {} : { l: s },
1118
+ sig: c
1119
+ }).toString()}`;
1120
+ },
1121
+ handle: async (n) => {
1122
+ if (n.pathname !== "/_voltro/og") return null;
1123
+ let i = n.searchParams.get("route") ?? "", a = n.searchParams.get("p") ?? "{}", o = n.searchParams.get("t") ?? "", s = n.searchParams.get("l") ?? "", c = n.searchParams.get("sig") ?? "", l = cr(e.secret, sr(i, a, o, s)), u = Buffer.from(c, "utf8"), d = Buffer.from(l, "utf8");
1124
+ if (u.length !== d.length || !Re(u, d)) return {
1125
+ status: 403,
1126
+ headers: { "content-type": "text/plain" },
1127
+ body: new TextEncoder().encode("bad signature")
1128
+ };
1129
+ if (!e.isOgSsrRoute(i)) return {
1130
+ status: 404,
1131
+ headers: { "content-type": "text/plain" },
1132
+ body: new TextEncoder().encode("no such og route")
1133
+ };
1134
+ let f = `og:${i}|p=${a}${o === "" ? "" : `|tenant=${o}`}${s === "" ? "" : `|lang=${s}`}`, p = e.cache.get(f), m = Date.now();
1135
+ if (p !== void 0 && p.expiresAt > m) return {
1136
+ status: 200,
1137
+ headers: {
1138
+ "content-type": "image/png",
1139
+ "x-voltro-og-cache": "HIT"
1140
+ },
1141
+ body: new Uint8Array(Buffer.from(p.html, "base64"))
1142
+ };
1143
+ let h = (await e.getPageModule(i))?.ogImage;
1144
+ if (typeof h != "function") return {
1145
+ status: 404,
1146
+ headers: { "content-type": "text/plain" },
1147
+ body: new TextEncoder().encode("page has no ogImage")
1148
+ };
1149
+ let { png: g } = await or({
1150
+ element: await h({
1151
+ params: JSON.parse(a),
1152
+ loaderData: void 0,
1153
+ ...s === "" ? { locale: "en" } : { locale: s },
1154
+ ...o === "" ? {} : { tenant: o }
1155
+ }),
1156
+ fonts: await r()
1157
+ }), _ = e.cache.generation(f);
1158
+ return e.cache.set(f, {
1159
+ html: Buffer.from(g).toString("base64"),
1160
+ renderedAt: m,
1161
+ expiresAt: m + t,
1162
+ servableUntil: m + t,
1163
+ revalidateMs: t,
1164
+ staleWhileRevalidateMs: 0
1165
+ }, { ifGeneration: _ }), {
1166
+ status: 200,
1167
+ headers: {
1168
+ "content-type": "image/png",
1169
+ "x-voltro-og-cache": "MISS"
1170
+ },
1171
+ body: g
1172
+ };
1173
+ }
1174
+ };
1175
+ }, fr = (e) => {
876
1176
  let t = [];
877
1177
  for (let n of e.split("/").filter(Boolean)) n.startsWith("[[...") && n.endsWith("]]") ? t.push({
878
1178
  name: n.slice(5, -2),
@@ -888,12 +1188,12 @@ __installPublicEnv(publicEnvValues)
888
1188
  optional: !1
889
1189
  });
890
1190
  return t;
891
- }, tn = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), nn = async (e) => {
892
- let t = A(e);
1191
+ }, pr = (e) => e.replace(/-([a-z0-9])/g, (e, t) => t.toUpperCase()), mr = async (e) => {
1192
+ let t = L(e);
893
1193
  for (let e = 0; e < 4; e++) {
894
- let e = O(t, "project.json");
895
- if (M(e)) try {
896
- let n = await N.readFile(e, "utf8");
1194
+ let e = F(t, "project.json");
1195
+ if (z(e)) try {
1196
+ let n = await B.readFile(e, "utf8");
897
1197
  return {
898
1198
  projectDir: t,
899
1199
  manifest: JSON.parse(n)
@@ -901,38 +1201,38 @@ __installPublicEnv(publicEnvValues)
901
1201
  } catch {
902
1202
  return null;
903
1203
  }
904
- let n = D(t);
1204
+ let n = P(t);
905
1205
  if (n === t) break;
906
1206
  t = n;
907
1207
  }
908
1208
  return null;
909
- }, rn = async (e) => {
910
- let t = await nn(e);
1209
+ }, hr = async (e) => {
1210
+ let t = await mr(e);
911
1211
  if (!t) return [];
912
- let { projectDir: n, manifest: r } = t, i = E(e), a = r.apps ?? {}, o = [];
1212
+ let { projectDir: n, manifest: r } = t, i = N(e), a = r.apps ?? {}, o = [];
913
1213
  for (let [e, t] of Object.entries(a)) {
914
1214
  if (e === i || t.kind !== "web" || typeof t.port != "number") continue;
915
- let r = O(n, t.path ?? e), a = O(r, "src", "pages");
916
- if (!M(a)) continue;
1215
+ let r = F(n, t.path ?? e), a = F(r, "src", "pages");
1216
+ if (!z(a)) continue;
917
1217
  let s;
918
1218
  try {
919
- let { pages: e } = await $(a);
1219
+ let { pages: e } = await Mo(a);
920
1220
  s = e.map((e) => ({
921
1221
  pattern: e.pattern,
922
- params: en(e.pattern)
1222
+ params: fr(e.pattern)
923
1223
  }));
924
1224
  } catch {
925
1225
  continue;
926
1226
  }
927
1227
  o.push({
928
- key: tn(e),
1228
+ key: pr(e),
929
1229
  origin: `http://localhost:${t.port}`,
930
1230
  ...typeof t.origin == "string" && t.origin.length > 0 ? { prodOrigin: t.origin } : {},
931
1231
  routes: s
932
1232
  });
933
1233
  }
934
1234
  return o;
935
- }, an = (e) => {
1235
+ }, gr = (e) => {
936
1236
  if (e.params.length === 0) return `'${e.pattern}'`;
937
1237
  let t = e.pattern;
938
1238
  for (let n of e.params) {
@@ -940,21 +1240,21 @@ __installPublicEnv(publicEnvValues)
940
1240
  t = t.replace(e, r);
941
1241
  }
942
1242
  return "`" + t + "`";
943
- }, on = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
1243
+ }, _r = (e) => e.params.length === 0 ? "EmptyParams" : `{ ${e.params.map((e) => {
944
1244
  let t = "string";
945
1245
  return e.optional ? `readonly ${e.name}?: ${t}` : `readonly ${e.name}: ${t}`;
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} + ` : "";
1246
+ }).join("; ")} }`, vr = (e, t, n) => {
1247
+ let r = _r(e), i = gr(e), a = t ? "VoltroExternalUrl" : e.search === void 0 ? "VoltroRouteUrl" : `VoltroRouteUrl<Schema.Schema.Type<typeof ${e.search.alias}>>`, o = t && n ? `${n} + ` : "";
948
1248
  return e.params.length === 0 ? `() => (${o}${i}) as ${a}` : `({ ${e.params.map((e) => e.name).join(", ")} }: ${r}) => (${o}${i}) as ${a}`;
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) => {
1249
+ }, yr = (e) => `{\n${[...e].sort((e, t) => e.pattern.localeCompare(t.pattern)).map((e) => ` ${JSON.stringify(e.pattern)}: ${vr(e, !1)},`).join("\n")}\n}`, br = (e, t) => {
950
1250
  if (e.routes.length === 0) return ` ${e.key}: {} as Record<string, never>,`;
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)},`);
1251
+ 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)}: ${vr(e, !0, i)},`);
952
1252
  return ` ${e.key}: {\n${a.join("\n")}\n },`;
953
- }, un = async (e) => {
1253
+ }, xr = async (e) => {
954
1254
  let t = await Promise.all(e.pages.map(async (t) => {
955
1255
  let n;
956
1256
  try {
957
- let r = await N.readFile(O(e.appRoot, "src", "pages", t.file), "utf8");
1257
+ let r = await B.readFile(F(e.appRoot, "src", "pages", t.file), "utf8");
958
1258
  /^export const searchParams\b/m.test(r) && (n = {
959
1259
  alias: `SP_${t.ident}`,
960
1260
  specifier: `../src/pages/${t.file.replace(/\.tsx?$/, "")}`
@@ -962,10 +1262,10 @@ __installPublicEnv(publicEnvValues)
962
1262
  } catch {}
963
1263
  return {
964
1264
  pattern: t.pattern,
965
- params: en(t.pattern),
1265
+ params: fr(t.pattern),
966
1266
  ...n === void 0 ? {} : { search: n }
967
1267
  };
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 = [
1268
+ })), n = await hr(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 = [
969
1269
  "// THIS FILE IS GENERATED — DO NOT EDIT BY HAND.",
970
1270
  "// Re-emitted by `voltro dev` whenever `src/pages/**` changes.",
971
1271
  "// Type-safe route builders consumed by <Link to={...}>.",
@@ -981,50 +1281,50 @@ __installPublicEnv(publicEnvValues)
981
1281
  "",
982
1282
  "type EmptyParams = Record<string, never>",
983
1283
  ""
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 });
1284
+ ].join("\n"), a = e.mode ?? "dev", o = `${i}\n${`export const routes = ${yr(t)} as const\n`}\n${n.length === 0 ? "export const siblingApps = {} as Record<string, never>\n" : `export const siblingApps = {\n${n.map((e) => br(e, a)).join("\n")}\n} as const\n`}`, s = F(e.appRoot, ".framework", "routes.generated.ts");
1285
+ await B.mkdir(P(s), { recursive: !0 });
986
1286
  let c = null;
987
1287
  try {
988
- c = await N.readFile(s, "utf8");
1288
+ c = await B.readFile(s, "utf8");
989
1289
  } catch {}
990
1290
  return c === o ? {
991
1291
  path: s,
992
1292
  wrote: !1
993
- } : (await N.writeFile(s, o, "utf8"), {
1293
+ } : (await B.writeFile(s, o, "utf8"), {
994
1294
  path: s,
995
1295
  wrote: !0
996
1296
  });
997
- }, dn = (e) => {
1297
+ }, Sr = (e) => {
998
1298
  if (e === "" || e === "/") return "/";
999
1299
  let t = e.startsWith("/") ? e : `/${e}`;
1000
1300
  return t.endsWith("/") ? t.slice(0, -1) : t;
1001
- }, fn = (e, t) => {
1002
- let n = e.endsWith("/") ? e.slice(0, -1) : e, r = dn(t);
1301
+ }, Cr = (e, t) => {
1302
+ let n = e.endsWith("/") ? e.slice(0, -1) : e, r = Sr(t);
1003
1303
  return r === "/" ? `${n}/` : `${n}${r}`;
1004
- }, pn = (e, t, n) => {
1005
- let r = dn(e);
1304
+ }, wr = (e, t, n) => {
1305
+ let r = Sr(e);
1006
1306
  return t === n ? r : r === "/" ? `/${t}` : `/${t}${r}`;
1007
- }, mn = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), hn = (e) => {
1307
+ }, Tr = (e) => e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;"), Er = (e) => {
1008
1308
  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) => {
1009
1309
  if (!r) return "";
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")}`;
1310
+ let n = r.map((n) => ` <xhtml:link rel="alternate" hreflang="${Tr(n)}" href="${Tr(Cr(t, wr(e, n, i)))}" />`);
1311
+ return n.push(` <xhtml:link rel="alternate" hreflang="x-default" href="${Tr(Cr(t, wr(e, i, i)))}" />`), `\n${n.join("\n")}`;
1012
1312
  };
1013
1313
  for (let e of n) {
1014
1314
  let n = r ?? [i];
1015
1315
  for (let r of n) {
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>`);
1316
+ let n = Cr(t, wr(e.path, r, i)), a = e.lastmod ? `\n <lastmod>${Tr(e.lastmod)}</lastmod>` : "";
1317
+ o.set(n, ` <url>\n <loc>${Tr(n)}</loc>${a}${s(e.path)}\n </url>`);
1018
1318
  }
1019
1319
  }
1020
1320
  let c = [...o.keys()].sort().map((e) => o.get(e)).join("\n");
1021
1321
  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`;
1022
- }, gn = (e) => {
1322
+ }, Dr = (e) => {
1023
1323
  if (!e.indexable) return "User-agent: *\nDisallow: /\n";
1024
1324
  let t = ["User-agent: *", "Allow: /"];
1025
- for (let n of e.disallow ?? []) t.push(`Disallow: ${dn(n)}`);
1325
+ for (let n of e.disallow ?? []) t.push(`Disallow: ${Sr(n)}`);
1026
1326
  return e.sitemapUrl && t.push("", `Sitemap: ${e.sitemapUrl}`), `${t.join("\n")}\n`;
1027
- }, _n = 256, vn = (e = _n) => {
1327
+ }, Or = 256, kr = (e = Or) => {
1028
1328
  let t = [], n = /* @__PURE__ */ new Set();
1029
1329
  return {
1030
1330
  emit(r, i) {
@@ -1047,18 +1347,18 @@ __installPublicEnv(publicEnvValues)
1047
1347
  return t.slice();
1048
1348
  }
1049
1349
  };
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);
1350
+ }, Ar = (e) => `event: ${e.channel}\ndata: ${JSON.stringify(e)}\n\n`, jr = () => `: keep-alive ${Date.now()}\n\n`, Mr = 8e3, Nr = (e, t = Mr) => {
1351
+ let n = Fr(e);
1052
1352
  return n.length <= t ? n : `${n.slice(0, t)}\n… [voltro] truncated at ${t} chars (${n.length} total)`;
1053
- }, Cn = 4, wn = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
1353
+ }, Pr = 4, Fr = (e, t = 0, n = /* @__PURE__ */ new Set()) => {
1054
1354
  if (e instanceof Error) {
1055
1355
  let r = e.stack ?? `${e.name}: ${e.message}`;
1056
1356
  if (n.has(e)) return `${r}\n [cycle]`;
1057
1357
  n.add(e);
1058
1358
  let i = [];
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))}`);
1359
+ if (t < Pr) {
1360
+ if (e instanceof AggregateError && Array.isArray(e.errors)) for (let [r, a] of e.errors.entries()) i.push(`\n [aggregate ${r}] ${Ir(Fr(a, t + 1, n))}`);
1361
+ else e.cause !== void 0 && e.cause !== null && i.push(`\n [cause] ${Ir(Fr(e.cause, t + 1, n))}`);
1062
1362
  }
1063
1363
  return r + i.join("");
1064
1364
  }
@@ -1067,30 +1367,30 @@ __installPublicEnv(publicEnvValues)
1067
1367
  } catch {
1068
1368
  return "[unstringifiable thrown value]";
1069
1369
  }
1070
- }, Tn = (e) => {
1370
+ }, Ir = (e) => {
1071
1371
  let t = e.split("\n");
1072
1372
  return t.length <= 3 ? e : `${t.slice(0, 3).join("\n")}\n …`;
1073
- }, En = {
1373
+ }, Lr = {
1074
1374
  trace: 0,
1075
1375
  debug: 1,
1076
1376
  info: 2,
1077
1377
  warn: 3,
1078
1378
  error: 4,
1079
1379
  fatal: 5
1080
- }, Dn = 2e3, On = 200, kn = class {
1380
+ }, Rr = 2e3, zr = 200, Br = class {
1081
1381
  capacity;
1082
1382
  buffer = [];
1083
- constructor(e = Dn) {
1383
+ constructor(e = Rr) {
1084
1384
  this.capacity = e;
1085
1385
  }
1086
1386
  append(e) {
1087
1387
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
1088
1388
  }
1089
1389
  query(e = {}) {
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 = [];
1390
+ let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? zr, this.capacity), i = e.minLevel === void 0 ? Lr.trace : Lr[e.minLevel], a = e.scope?.toLowerCase(), o = e.source, s = e.filter?.toLowerCase(), c = e.traceId, l = [];
1091
1391
  for (let e = this.buffer.length - 1; e >= 0 && l.length < r; e--) {
1092
1392
  let r = this.buffer[e];
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));
1393
+ r.ts < t || r.ts > n || Lr[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));
1094
1394
  }
1095
1395
  return l.reverse();
1096
1396
  }
@@ -1103,7 +1403,7 @@ __installPublicEnv(publicEnvValues)
1103
1403
  clear() {
1104
1404
  this.buffer = [];
1105
1405
  }
1106
- }, An = null, jn = () => (An === null && (An = new kn()), An), Mn = (e) => {
1406
+ }, Vr = null, Hr = () => (Vr === null && (Vr = new Br()), Vr), Ur = (e) => {
1107
1407
  if (typeof e == "string") return e;
1108
1408
  if (e instanceof Error) return e.message;
1109
1409
  try {
@@ -1111,28 +1411,28 @@ __installPublicEnv(publicEnvValues)
1111
1411
  } catch {
1112
1412
  return String(e);
1113
1413
  }
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) => {
1414
+ }, Wr = 8e3, Gr = (e) => typeof e == "string" ? e.length <= Wr ? e : `${e.slice(0, Wr)}… [voltro: truncated]` : typeof e != "object" || !e ? e : Nr(e, Wr), Kr = (e, t) => {
1115
1415
  try {
1116
1416
  e(...t);
1117
1417
  } catch (n) {
1118
1418
  try {
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.`);
1419
+ e(...t.map(Gr)), e(` ↑ [voltro] an argument above was too large for console formatting (${n?.message ?? "inspect failed"}) — printed bounded to ${Wr} chars per argument.`);
1120
1420
  } catch {
1121
1421
  e(`[voltro] a console.error argument could not be formatted at all (${t.length} arg(s)).`);
1122
1422
  }
1123
1423
  }
1124
- }, In = (e) => {
1424
+ }, qr = (e) => {
1125
1425
  let t = {
1126
1426
  log: console.log.bind(console),
1127
1427
  info: console.info.bind(console),
1128
1428
  warn: console.warn.bind(console),
1129
1429
  error: console.error.bind(console),
1130
1430
  debug: console.debug.bind(console)
1131
- }, n = jn(), r = !1, i = (i) => (...a) => {
1132
- if (Fn(t[i], a), !r) {
1431
+ }, n = Hr(), r = !1, i = (i) => (...a) => {
1432
+ if (Kr(t[i], a), !r) {
1133
1433
  r = !0;
1134
1434
  try {
1135
- let t = a.length > 0 ? Mn(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = V();
1435
+ let t = a.length > 0 ? Ur(a[0]) : "", r = t.length > 500 ? t.slice(0, 500) + "…" : t, o = xe();
1136
1436
  e.emit("log", {
1137
1437
  level: i,
1138
1438
  message: r,
@@ -1159,7 +1459,7 @@ __installPublicEnv(publicEnvValues)
1159
1459
  }
1160
1460
  };
1161
1461
  console.log = i("log"), console.info = i("info"), console.warn = i("warn"), console.error = i("error"), console.debug = i("debug");
1162
- let a = L((t) => {
1462
+ let a = he((t) => {
1163
1463
  if (!r) {
1164
1464
  r = !0;
1165
1465
  try {
@@ -1170,7 +1470,7 @@ __installPublicEnv(publicEnvValues)
1170
1470
  argsCount: 1,
1171
1471
  ...t.scope === void 0 ? {} : { scope: t.scope }
1172
1472
  });
1173
- let a = V(), o = a !== void 0 && t.fields.traceId === void 0 ? {
1473
+ let a = xe(), o = a !== void 0 && t.fields.traceId === void 0 ? {
1174
1474
  ...t.fields,
1175
1475
  traceId: a.traceId
1176
1476
  } : t.fields;
@@ -1190,24 +1490,24 @@ __installPublicEnv(publicEnvValues)
1190
1490
  return () => {
1191
1491
  console.log = t.log, console.info = t.info, console.warn = t.warn, console.error = t.error, console.debug = t.debug, a();
1192
1492
  };
1193
- }, Ln = 2e3, Rn = 8, zn = 1e3, Bn = 200, Vn = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, Hn = (e) => {
1493
+ }, Jr = 2e3, Yr = 8, Xr = 1e3, Zr = 200, Qr = (e, t) => e.length > t ? `${e.slice(0, t)}…` : e, $r = (e) => {
1194
1494
  switch (e) {
1195
1495
  case "error": return "error";
1196
1496
  case "warn": return "warn";
1197
1497
  case "debug": return "debug";
1198
1498
  default: return "info";
1199
1499
  }
1200
- }, Un = R({ scope: "client" }), Wn = (e, t) => {
1500
+ }, ei = G({ scope: "client" }), ti = (e, t) => {
1201
1501
  let n;
1202
1502
  try {
1203
1503
  n = JSON.parse(e);
1204
1504
  } catch {
1205
- return Gn(400, { error: "invalid JSON body" });
1505
+ return ni(400, { error: "invalid JSON body" });
1206
1506
  }
1207
- if (typeof n != "object" || !n) return Gn(400, { error: "body must be a JSON object" });
1507
+ if (typeof n != "object" || !n) return ni(400, { error: "body must be a JSON object" });
1208
1508
  let r = n;
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;
1509
+ if (!Array.isArray(r.entries)) return ni(400, { error: "entries must be an array" });
1510
+ let i = typeof r.app == "string" ? Qr(r.app, 120) : void 0, a = typeof r.page == "string" ? Qr(r.page, 200) : void 0, o = typeof r.ua == "string" ? Qr(r.ua, 200) : void 0, s = r.entries.slice(0, Zr), c = 0;
1211
1511
  for (let e of s) {
1212
1512
  if (typeof e != "object" || !e) continue;
1213
1513
  let n = e;
@@ -1218,7 +1518,7 @@ __installPublicEnv(publicEnvValues)
1218
1518
  "warn",
1219
1519
  "error",
1220
1520
  "debug"
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;
1521
+ ].includes(n.level) ? n.level : "log", s = typeof n.ts == "number" && Number.isFinite(n.ts) ? n.ts : Date.now(), l = Qr(n.message, Jr), u = Array.isArray(n.args) ? n.args.slice(0, Yr).filter((e) => typeof e == "string").map((e) => Qr(e, Xr)) : void 0, d = typeof n.stack == "string" ? Qr(n.stack, Jr) : void 0;
1222
1522
  t.emit("clientLog", {
1223
1523
  ts: s,
1224
1524
  level: r,
@@ -1233,35 +1533,35 @@ __installPublicEnv(publicEnvValues)
1233
1533
  ...i === void 0 ? {} : { app: i },
1234
1534
  ...a === void 0 ? {} : { page: a },
1235
1535
  ...u !== void 0 && u.length > 0 ? { args: u } : {}
1236
- }, p = Hn(r);
1237
- (p === "error" || p === "warn") && d !== void 0 ? Un[p](l, f, { stack: d }) : Un[p](l, {
1536
+ }, p = $r(r);
1537
+ (p === "error" || p === "warn") && d !== void 0 ? ei[p](l, f, { stack: d }) : ei[p](l, {
1238
1538
  ...f,
1239
1539
  ...d === void 0 ? {} : { stack: d }
1240
1540
  }), c++;
1241
1541
  }
1242
- return Gn(202, {
1542
+ return ni(202, {
1243
1543
  accepted: c,
1244
1544
  dropped: r.entries.length - c
1245
1545
  });
1246
- }, Gn = (e, t) => ({
1546
+ }, ni = (e, t) => ({
1247
1547
  status: e,
1248
1548
  contentType: "application/json; charset=utf-8",
1249
1549
  body: JSON.stringify(t)
1250
- }), Kn = "/_voltro/inspect/clientLog", qn = [
1550
+ }), ri = "/_voltro/inspect/clientLog", ii = [
1251
1551
  "trace",
1252
1552
  "debug",
1253
1553
  "info",
1254
1554
  "warn",
1255
1555
  "error",
1256
1556
  "fatal"
1257
- ], Jn = {
1557
+ ], ai = {
1258
1558
  trace: "TRACE",
1259
1559
  debug: "DEBUG",
1260
1560
  info: "INFO ",
1261
1561
  warn: "WARN ",
1262
1562
  error: "ERROR",
1263
1563
  fatal: "FATAL"
1264
- }, Yn = (e) => qn.includes(e), Xn = (e, t, n = {}) => {
1564
+ }, oi = (e) => ii.includes(e), si = (e, t, n = {}) => {
1265
1565
  if (u()) return {
1266
1566
  status: 503,
1267
1567
  contentType: "application/json",
@@ -1292,7 +1592,7 @@ __installPublicEnv(publicEnvValues)
1292
1592
  Number.isFinite(e) && e > 0 && (o.max = Math.floor(e));
1293
1593
  }
1294
1594
  let d = a.get("level");
1295
- d !== null && Yn(d) && (o.minLevel = d);
1595
+ d !== null && oi(d) && (o.minLevel = d);
1296
1596
  let p = a.get("source");
1297
1597
  (p === "server" || p === "client") && (o.source = p);
1298
1598
  let m = a.get("scope");
@@ -1305,7 +1605,7 @@ __installPublicEnv(publicEnvValues)
1305
1605
  if ((a.get("format") ?? "json") === "text") return {
1306
1606
  status: 200,
1307
1607
  contentType: "text/plain; charset=utf-8",
1308
- body: _.map(Zn).join("\n") + (_.length > 0 ? "\n" : "")
1608
+ body: _.map(ci).join("\n") + (_.length > 0 ? "\n" : "")
1309
1609
  };
1310
1610
  let v = {
1311
1611
  capturedAt: Date.now(),
@@ -1319,40 +1619,40 @@ __installPublicEnv(publicEnvValues)
1319
1619
  contentType: "application/json; charset=utf-8",
1320
1620
  body: JSON.stringify(v)
1321
1621
  };
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) => {
1622
+ }, ci = (e) => {
1623
+ 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 = ui(e.fields);
1624
+ return `${n}:${r}:${i}.${a} ${ai[e.level]} ${o} ${e.message}${s}`;
1625
+ }, li = 80, ui = (e) => {
1326
1626
  let t = Object.entries(e);
1327
1627
  if (t.length === 0) return "";
1328
1628
  let n = [];
1329
1629
  for (let [e, r] of t) {
1330
1630
  if (r === void 0) continue;
1331
- let t = er(r);
1631
+ let t = di(r);
1332
1632
  n.push(`${e}=${t}`);
1333
1633
  }
1334
1634
  return n.length > 0 ? " " + n.join(" ") : "";
1335
- }, er = (e) => {
1635
+ }, di = (e) => {
1336
1636
  if (typeof e == "string") {
1337
- let t = e.length > Qn ? e.slice(0, Qn) + "…" : e;
1637
+ let t = e.length > li ? e.slice(0, li) + "…" : e;
1338
1638
  return /[\s=]/.test(t) ? `"${t.replace(/"/g, "\\\"")}"` : t;
1339
1639
  }
1340
1640
  if (e === null) return "null";
1341
1641
  if (typeof e == "number" || typeof e == "boolean") return String(e);
1342
1642
  try {
1343
1643
  let t = JSON.stringify(e);
1344
- return t.length > Qn ? t.slice(0, Qn) + "…" : t;
1644
+ return t.length > li ? t.slice(0, li) + "…" : t;
1345
1645
  } catch {
1346
1646
  return "[unserialisable]";
1347
1647
  }
1348
- }, tr = "/_voltro/inspect/logs", nr = (e, t, n) => {
1648
+ }, fi = "/_voltro/inspect/logs", pi = (e, t, n) => {
1349
1649
  if (t.headers.authorization !== void 0) return !1;
1350
1650
  let { token: r } = n;
1351
1651
  if (r === void 0 || r === "" || !n.isLoopback(n.target)) return !1;
1352
1652
  e.setHeader("authorization", `Bearer ${r}`);
1353
1653
  let i = n.writeToken;
1354
1654
  return i !== void 0 && i !== "" && t.headers["x-voltro-inspect-write"] === void 0 && e.setHeader("x-voltro-inspect-write", i), !0;
1355
- }, rr = [{
1655
+ }, mi = [{
1356
1656
  match: (e) => typeof e == "string" && e.startsWith("[BABEL] Note: The code generator has deoptimised"),
1357
1657
  handle: (e, t) => {
1358
1658
  let n = e[0], r = n.match(/deoptimised the styling of (.+?) as it exceeds the max of (\d+\w*B)\.?/);
@@ -1364,13 +1664,13 @@ __installPublicEnv(publicEnvValues)
1364
1664
  });
1365
1665
  } else t.info(n);
1366
1666
  }
1367
- }], ir = () => {
1667
+ }], hi = () => {
1368
1668
  let e = {
1369
1669
  warn: console.warn.bind(console),
1370
1670
  error: console.error.bind(console)
1371
- }, t = R({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1671
+ }, t = G({ scope: "babel" }), n = !1, r = (r) => (...i) => {
1372
1672
  if (!n) {
1373
- for (let e of rr) if (e.match(i[0])) {
1673
+ for (let e of mi) if (e.match(i[0])) {
1374
1674
  n = !0;
1375
1675
  try {
1376
1676
  e.handle(i, t);
@@ -1385,7 +1685,7 @@ __installPublicEnv(publicEnvValues)
1385
1685
  return console.warn = r("warn"), console.error = r("error"), () => {
1386
1686
  console.warn = e.warn, console.error = e.error;
1387
1687
  };
1388
- }, ar = {
1688
+ }, gi = {
1389
1689
  loader: "it runs on the server, and the router caches its result per route + params",
1390
1690
  renderMode: "it picks the server render strategy",
1391
1691
  dynamic: "it picks the server render strategy",
@@ -1395,8 +1695,10 @@ __installPublicEnv(publicEnvValues)
1395
1695
  staleWhileRevalidate: "it sets the ISR stale-while-revalidate window",
1396
1696
  cacheInvalidatesOn: "it wires this page into the ISR cache invalidator",
1397
1697
  interactive: "it decides how much client JS the server ships",
1398
- tenantAware: "it is part of the server-side cache key"
1399
- }, or = Object.keys(ar), sr = "virtual:voltro-route-refresh", cr = `\0${sr}`, lr = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, ur = () => `
1698
+ tenantAware: "it is part of the server-side cache key",
1699
+ ogImage: "the server renders it into the og:image PNG",
1700
+ ppr: "it switches the isr path to partial prerendering (cached shell + per-request holes)"
1701
+ }, _i = Object.keys(gi), vi = "virtual:voltro-route-refresh", yi = `\0${vi}`, bi = /(?:^|&)(raw|url|inline|worker|sharedworker|direct)(?:&|=|$)/, xi = () => `
1400
1702
  // GENERATED by @voltro/cli — the \`voltro dev\` route Fast Refresh runtime.
1401
1703
 
1402
1704
  /** Mirrors react-refresh's own \`isLikelyComponentType\` closely enough for the
@@ -1425,11 +1727,11 @@ const stableForm = (value) => {
1425
1727
  * readers (\`build.ts\` prerender, \`webDev.ts\` dev SSR, \`start.ts\`). A change to
1426
1728
  * one of THESE cannot be hot-applied: the server already ran with the old
1427
1729
  * value. Everything else a page exports is plain client-side data. */
1428
- const serverRelevantExports = ${JSON.stringify(or)}
1730
+ const serverRelevantExports = ${JSON.stringify(_i)}
1429
1731
 
1430
1732
  /** Name → the server step that already consumed it, so the reload message can
1431
1733
  * say WHY rather than just WHAT. Injected from the same single source. */
1432
- const serverExportEffect = ${JSON.stringify(ar)}
1734
+ const serverExportEffect = ${JSON.stringify(gi)}
1433
1735
 
1434
1736
  /** The reason \`name\` forces a reload, for the console line. */
1435
1737
  export const serverEffectOf = (name) =>
@@ -1472,7 +1774,7 @@ export const routeUpdateNeedsReload = (prevExports, nextExports) => {
1472
1774
  const previousHook = globalThis.__getReactRefreshIgnoredExports
1473
1775
  globalThis.__getReactRefreshIgnoredExports = (args) =>
1474
1776
  ignoredExports.get(args.id) ?? previousHook?.(args) ?? []
1475
- `, dr = (e) => `
1777
+ `, Si = (e) => `
1476
1778
  if (import.meta.hot) {
1477
1779
  // Self-import to read our OWN exports, the same technique the react plugin
1478
1780
  // uses; the namespace is only complete after evaluation, hence the promise.
@@ -1499,97 +1801,97 @@ import {
1499
1801
  registerRouteModule as __voltro_registerRouteModule,
1500
1802
  routeUpdateNeedsReload as __voltro_routeUpdateNeedsReload,
1501
1803
  serverEffectOf as __voltro_serverEffect,
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(/\/$/, "");
1507
- return n.startsWith(`${i}/`) ? c.test(n) || s.has(n.slice(n.lastIndexOf("/") + 1)) : !1;
1508
- }, mr = (e, t, n) => pr(t, n) ? `${e}${dr(fr(t).split("?")[0] ?? t)}` : null, hr = (e) => ({
1804
+ } from '${vi}'
1805
+ `, Ci = (e) => e.replace(/\\/g, "/"), wi = (e, t) => {
1806
+ let [n = "", r] = Ci(e).split("?");
1807
+ if (!n.endsWith(".tsx") || r !== void 0 && bi.test(r)) return !1;
1808
+ let i = Ci(t).replace(/\/$/, "");
1809
+ return n.startsWith(`${i}/`) ? s.test(n) || a.has(n.slice(n.lastIndexOf("/") + 1)) : !1;
1810
+ }, Ti = (e, t, n) => wi(t, n) ? `${e}${Si(Ci(t).split("?")[0] ?? t)}` : null, Ei = (e) => ({
1509
1811
  name: "voltro:route-fast-refresh",
1510
1812
  enforce: "pre",
1511
- resolveId: (e) => e === "virtual:voltro-route-refresh" ? cr : void 0,
1512
- load: (e) => e === cr ? ur() : void 0,
1813
+ resolveId: (e) => e === "virtual:voltro-route-refresh" ? yi : void 0,
1814
+ load: (e) => e === yi ? xi() : void 0,
1513
1815
  transform: (t, n, r) => {
1514
1816
  if (r?.ssr === !0) return null;
1515
- let i = mr(t, n, e);
1817
+ let i = Ti(t, n, e);
1516
1818
  return i === null ? null : {
1517
1819
  code: i,
1518
1820
  map: null
1519
1821
  };
1520
1822
  }
1521
- }), gr = R({ scope: "voltro:dashboard" }), _r = ie(import.meta.url), vr = 5179, yr = (e) => {
1823
+ }), Di = G({ scope: "voltro:dashboard" }), Oi = ye(import.meta.url), ki = 5179, Ai = (e) => {
1522
1824
  let t = process.env.VOLTRO_DASHBOARD_PATH;
1523
- if (t && M(O(A(t), "app.config.ts"))) return A(t);
1825
+ if (t && z(F(L(t), "app.config.ts"))) return L(t);
1524
1826
  try {
1525
- let e = D(_r.resolve("@voltro/dashboard/package.json"));
1526
- if (M(O(e, "app.config.ts"))) return e;
1827
+ let e = P(Oi.resolve("@voltro/dashboard/package.json"));
1828
+ if (z(F(e, "app.config.ts"))) return e;
1527
1829
  } catch {}
1528
- let n = O("voltro-devtools", "apps", "dashboard"), r = A(e);
1830
+ let n = F("voltro-devtools", "apps", "dashboard"), r = L(e);
1529
1831
  for (let e = 0; e < 10; e++) {
1530
- let e = O(r, n);
1531
- if (M(O(e, "app.config.ts"))) return e;
1532
- let t = D(r);
1832
+ let e = F(r, n);
1833
+ if (z(F(e, "app.config.ts"))) return e;
1834
+ let t = P(r);
1533
1835
  if (t === r) break;
1534
1836
  r = t;
1535
1837
  }
1536
1838
  return null;
1537
- }, br = "VOLTRO_IS_DASHBOARD", xr = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1538
- let i = K({
1839
+ }, ji = "VOLTRO_IS_DASHBOARD", Mi = (e, t = "127.0.0.1", n = 250) => new Promise((r) => {
1840
+ let i = Y({
1539
1841
  port: e,
1540
1842
  host: t
1541
1843
  }), a = !1, o = (e) => {
1542
1844
  a || (a = !0, i.destroy(), r(e));
1543
1845
  };
1544
1846
  i.once("connect", () => o(!0)), i.once("error", () => o(!1)), setTimeout(() => o(!1), n);
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 () => {
1847
+ }), Ni = () => !!(process.env.VOLTRO_DASHBOARD === "off" || process.argv.includes("--disable-dashboard")), Pi = () => process.env[ji] === "1", Fi = () => process.stdout.isTTY === !0, Ii = F(we(), ".voltro", "dashboard-launch.lock"), Li = 1e4, Ri = async () => {
1546
1848
  try {
1547
- await N.mkdir(D(Tr), { recursive: !0 });
1548
- let e = await N.open(Tr, "wx");
1849
+ await B.mkdir(P(Ii), { recursive: !0 });
1850
+ let e = await B.open(Ii, "wx");
1549
1851
  return await e.write(`${process.pid}\n${Date.now()}\n`), await e.close(), !0;
1550
1852
  } catch {
1551
1853
  try {
1552
- let e = await N.stat(Tr);
1553
- if (Date.now() - e.mtimeMs > Er) return await N.unlink(Tr).catch(() => void 0), Dr();
1854
+ let e = await B.stat(Ii);
1855
+ if (Date.now() - e.mtimeMs > Li) return await B.unlink(Ii).catch(() => void 0), Ri();
1554
1856
  } catch {}
1555
1857
  return !1;
1556
1858
  }
1557
- }, Or = async () => {
1859
+ }, zi = async () => {
1558
1860
  try {
1559
- await N.unlink(Tr);
1861
+ await B.unlink(Ii);
1560
1862
  } catch {}
1561
- }, kr = async (e) => {
1863
+ }, Bi = async (e) => {
1562
1864
  let t = e.port ?? 5179;
1563
- if (Sr()) return {
1865
+ if (Ni()) return {
1564
1866
  status: "skipped",
1565
1867
  reason: "disabled by flag/env",
1566
1868
  port: t
1567
1869
  };
1568
- if (Cr()) return {
1870
+ if (Pi()) return {
1569
1871
  status: "skipped",
1570
1872
  reason: "this process IS the dashboard",
1571
1873
  port: t
1572
1874
  };
1573
- if (!wr()) return {
1875
+ if (!Fi()) return {
1574
1876
  status: "skipped",
1575
1877
  reason: "stdout is not a TTY (CI/smoke)",
1576
1878
  port: t
1577
1879
  };
1578
- if (!await Dr()) return {
1880
+ if (!await Ri()) return {
1579
1881
  status: "skipped",
1580
1882
  reason: "another voltro process is currently launching the dashboard",
1581
1883
  port: t
1582
1884
  };
1583
- if (await xr(t)) return await Or(), {
1885
+ if (await Mi(t)) return await zi(), {
1584
1886
  status: "already-running",
1585
1887
  port: t
1586
1888
  };
1587
1889
  let n = e.voltroBin;
1588
1890
  if (!n) {
1589
1891
  let e = process.argv[1];
1590
- n = e && e.endsWith("/src/bin.ts") ? O(D(e), "..", "bin", "voltro.mjs") : e ?? "voltro";
1892
+ n = e && e.endsWith("/src/bin.ts") ? F(P(e), "..", "bin", "voltro.mjs") : e ?? "voltro";
1591
1893
  }
1592
- let r = O(e.dashboardAppPath, ".framework", "dist", "index.html"), i = M(r), a = i ? "start" : "dev", o = _e(process.execPath, [
1894
+ let r = F(e.dashboardAppPath, ".framework", "dist", "index.html"), i = z(r), a = i ? "start" : "dev", o = ze(process.execPath, [
1593
1895
  n,
1594
1896
  a,
1595
1897
  e.dashboardAppPath
@@ -1597,7 +1899,7 @@ import {
1597
1899
  stdio: "ignore",
1598
1900
  env: {
1599
1901
  ...process.env,
1600
- [br]: "1",
1902
+ [ji]: "1",
1601
1903
  VOLTRO_DASHBOARD_PORT: String(t)
1602
1904
  }
1603
1905
  });
@@ -1605,19 +1907,121 @@ import {
1605
1907
  if (o.exitCode === null && o.signalCode === null) try {
1606
1908
  o.kill("SIGTERM");
1607
1909
  } catch {}
1608
- }), gr.info(`auto-launching dashboard at http://localhost:${t}`, {
1910
+ }), Di.info(`auto-launching dashboard at http://localhost:${t}`, {
1609
1911
  port: t,
1610
1912
  mode: a,
1611
1913
  prebuilt: i
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();
1914
+ }), i || Di.debug("no pre-built dashboard — running `voltro dev`. Build with `cd voltro-devtools && pnpm build` for a fast prod boot."), Di.debug("disable via --disable-dashboard or VOLTRO_DASHBOARD=off"), setTimeout(() => {
1915
+ zi();
1614
1916
  }, 4e3).unref(), {
1615
1917
  status: "launched",
1616
1918
  port: t
1617
1919
  };
1618
- }, Ar = /Could not find required `intl` object/, jr = "__voltro_i18n_instances__", Mr = (e = globalThis) => {
1920
+ }, Vi = class extends Error {
1921
+ _voltroDeferral = !0;
1922
+ constructor(e) {
1923
+ super(e), this.name = "DeferralNotSupportedError";
1924
+ }
1925
+ }, Hi = (e) => typeof e == "object" && !!e && e._voltroDeferral === !0, Ui = (e) => {
1926
+ if (!(e instanceof Error)) return;
1927
+ let t = e._voltroControl;
1928
+ if (t === "redirect") {
1929
+ let { location: t, status: n } = e;
1930
+ return typeof t == "string" ? {
1931
+ status: n === 307 || n === 308 ? n : 303,
1932
+ headers: {
1933
+ location: t,
1934
+ "x-voltro-rendered-by": "loader-redirect"
1935
+ },
1936
+ body: ""
1937
+ } : void 0;
1938
+ }
1939
+ if (t === "not-found") return {
1940
+ status: 404,
1941
+ headers: {
1942
+ "content-type": "text/plain; charset=utf-8",
1943
+ "x-voltro-rendered-by": "loader-not-found"
1944
+ },
1945
+ body: "not found"
1946
+ };
1947
+ }, Wi = (e) => {
1948
+ let { helpers: t } = e, n = t.prepareDeferredLoaderData(e.loaderData, "page"), r = {}, i = {}, a = {};
1949
+ for (let [n, o] of Object.entries(e.segmentLoaderData)) {
1950
+ let e = Number(n), s = t.prepareDeferredLoaderData(o, e);
1951
+ r[e] = s.renderData, i[e] = s.stateData, s.deferredIds && (a[e] = s.deferredIds);
1952
+ }
1953
+ let o = n.deferredIds !== void 0 || Object.keys(a).length > 0;
1954
+ if (o) try {
1955
+ t.assertDeferralSupported({
1956
+ page: e.page,
1957
+ renderMode: e.renderMode,
1958
+ interactive: e.interactive,
1959
+ ...e.layoutShell ? { layoutShell: e.layoutShell } : {},
1960
+ ...e.ppr === !0 ? { ppr: !0 } : {}
1961
+ });
1962
+ } catch (e) {
1963
+ throw new Vi(e instanceof Error ? e.message : String(e));
1964
+ }
1965
+ return {
1966
+ loaderData: n.renderData,
1967
+ segmentLoaderData: r,
1968
+ hasDeferred: o,
1969
+ stateInput: {
1970
+ path: e.pathname,
1971
+ loaderData: n.stateData,
1972
+ segmentLoaderData: i,
1973
+ pageLoaderRan: e.pageLoaderRan,
1974
+ ...e.layoutShell ? { pageClientOnly: !0 } : {},
1975
+ ...n.deferredIds ? { deferredPageIds: n.deferredIds } : {},
1976
+ ...Object.keys(a).length > 0 ? { deferredSegmentIds: a } : {}
1977
+ }
1978
+ };
1979
+ }, Gi = (e) => {
1980
+ let { helpers: t, renderInput: n } = e, r = Wi({
1981
+ helpers: t,
1982
+ page: e.page,
1983
+ pathname: n.pathname,
1984
+ renderMode: "spa",
1985
+ interactive: e.interactive,
1986
+ loaderData: null,
1987
+ segmentLoaderData: n.segmentLoaderData ?? {},
1988
+ pageLoaderRan: !1,
1989
+ layoutShell: e.delivery
1990
+ });
1991
+ return {
1992
+ renderInput: {
1993
+ ...n,
1994
+ pageSlot: !0,
1995
+ loaderData: null,
1996
+ segmentLoaderData: r.segmentLoaderData
1997
+ },
1998
+ stateScript: t.renderRouterStateScript(r.stateInput),
1999
+ hasDeferred: r.hasDeferred
2000
+ };
2001
+ }, Ki = (e) => {
2002
+ let { html: t, meta: n } = e.helpers.renderPageToHtml(e.prepared.renderInput);
2003
+ return {
2004
+ body: t,
2005
+ meta: n
2006
+ };
2007
+ }, qi = (e) => [
2008
+ ...e.extra ?? [],
2009
+ e.helpers.renderMetaToHtml(e.meta),
2010
+ `<meta name="voltro-interactive" content="${e.interactive}" />`,
2011
+ ...e.prepared.hasDeferred ? [e.helpers.renderDeferredRegistryScript()] : [],
2012
+ e.prepared.stateScript
2013
+ ].filter((e) => e.length > 0).join("\n "), Ji = (e) => {
2014
+ let t = e.indexOf("?");
2015
+ return t === -1 ? {
2016
+ pathname: e || "/",
2017
+ search: ""
2018
+ } : {
2019
+ pathname: e.slice(0, t) || "/",
2020
+ search: e.slice(t)
2021
+ };
2022
+ }, Yi = /Could not find required `intl` object/, Xi = "__voltro_i18n_instances__", Zi = (e = globalThis) => {
1619
2023
  try {
1620
- let t = e[jr]?.records;
2024
+ let t = e[Xi]?.records;
1621
2025
  return t === void 0 || t.length === 0 ? void 0 : {
1622
2026
  instances: t.length,
1623
2027
  reactIntlCopies: new Set(t.map((e) => e.intlProvider)).size,
@@ -1626,7 +2030,7 @@ import {
1626
2030
  } catch {
1627
2031
  return;
1628
2032
  }
1629
- }, Nr = (e, t) => [
2033
+ }, Qi = (e, t) => [
1630
2034
  "",
1631
2035
  "── voltro diagnosis ───────────────────────────────────────────────────",
1632
2036
  `${e} DID wrap this render in <I18nProvider>, and this process`,
@@ -1644,7 +2048,7 @@ import {
1644
2048
  " versions on disk; this counts instances in the running process, and one",
1645
2049
  " file loaded down two paths is two instances.",
1646
2050
  "───────────────────────────────────────────────────────────────────────"
1647
- ].join("\n"), Pr = (e, t) => [
2051
+ ].join("\n"), $i = (e, t) => [
1648
2052
  "",
1649
2053
  "── voltro diagnosis ───────────────────────────────────────────────────",
1650
2054
  `${e} DID wrap this render in <I18nProvider>, and this process`,
@@ -1660,7 +2064,7 @@ import {
1660
2064
  " direct import can land on a second copy that this count does not see —",
1661
2065
  " it counts what @voltro/i18n is bound to.",
1662
2066
  "───────────────────────────────────────────────────────────────────────"
1663
- ].join("\n"), Fr = (e) => [
2067
+ ].join("\n"), ea = (e) => [
1664
2068
  "",
1665
2069
  "── voltro diagnosis ───────────────────────────────────────────────────",
1666
2070
  `${e} DID wrap this render in <I18nProvider> — the framework`,
@@ -1676,40 +2080,45 @@ import {
1676
2080
  " Do NOT use `pnpm ls` to rule that out: it lists versions on disk, and",
1677
2081
  " the duplication here is of module instances in one process.",
1678
2082
  "───────────────────────────────────────────────────────────────────────"
1679
- ].join("\n"), Ir = (e, t, n, r = Mr()) => {
2083
+ ].join("\n"), ta = (e, t, n, r = Zi()) => {
1680
2084
  if (!t) return;
1681
2085
  let i = String(e?.message ?? e);
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];
2086
+ if (Yi.test(i)) return r === void 0 ? ea(n) : r.reactIntlCopies > 1 || r.instances > 1 ? Qi(n, r) : $i(n, r);
2087
+ }, na = "<div id=\"root\"></div>", ra = "<div id=\"root\">", ia = "</div>", aa = /<script\b[^>]*\btype=["']module["'][^>]*><\/script>[ \t]*\n?/gi, oa = /\bsrc=["']([^"']+)["']/i, sa = /<script(?![^>]*\basync\b)([^>]*\btype=["']module["'][^>]*)>/gi, ca = (e) => {
2088
+ let t = e.keepScriptInHead ?? ((e) => e.startsWith("/@")), n = [], r = e.shell.replace(aa, (e) => {
2089
+ let r = oa.exec(e)?.[1];
1686
2090
  return r === void 0 || t(r) ? e : (n.push(r), "");
1687
2091
  });
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.`);
2092
+ e.inlineModuleScriptsAsync && (r = r.replace(sa, "<script async$1>"));
2093
+ let i = r.indexOf(na);
2094
+ if (i === -1) throw Error(`[voltro] the generated shell has no \`${na}\` 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.`);
1691
2095
  return {
1692
- head: `${r.slice(0, i)}${Rr}`,
1693
- tail: `${zr}${r.slice(i + 21)}`,
2096
+ head: `${r.slice(0, i)}${ra}`,
2097
+ tail: `${ia}${r.slice(i + 21)}`,
1694
2098
  bootstrapModules: n
1695
2099
  };
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) => {
2100
+ }, la = (e, t) => (/<title>/i.test(t) ? e.replace(/[^\S\n]*<title>[\s\S]*?<\/title>\n?/i, "") : e).replace("</head>", ` ${t}\n </head>`), ua = (e, t) => {
2101
+ let n = t.replace(/[^A-Za-z0-9+/=_-]/g, "");
2102
+ return e.replace(/<script(?![^>]*\snonce\s*=)/gi, `<script nonce="${n}"`);
2103
+ }, da = (e) => e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;"), fa = (e, t) => {
2104
+ let n = [t.timeZone === void 0 ? "" : ` data-voltro-tz="${da(t.timeZone)}"`, t.renderedAt === void 0 ? "" : ` data-voltro-now="${t.renderedAt}"`].join("");
2105
+ return e.replace(/<html(\s+lang="[^"]*")?/i, `<html lang="${da(t.lang)}"${n}`);
2106
+ }, pa = (e) => fa(la(e.head, e.headInjection), e.documentAttrs), ma = (e) => {
1700
2107
  let { res: t, shell: n, documentAttrs: r, headInjection: i } = e, a = null, o = !1, s = !1, c = () => {
1701
2108
  if (s || !o || a === null) return;
1702
2109
  s = !0, t.statusCode = e.statusCode ?? 200;
1703
2110
  for (let [n, r] of Object.entries(e.headers ?? {})) t.setHeader(n, r);
1704
- t.flushHeaders?.(), t.write(qr({
2111
+ t.flushHeaders?.();
2112
+ let c = pa({
1705
2113
  head: n.head,
1706
2114
  headInjection: i(a.meta),
1707
2115
  documentAttrs: r
1708
- }));
1709
- let c = new Te();
1710
- c.pipe(t, { end: !1 }), c.on("end", () => {
2116
+ });
2117
+ t.write(e.nonce === void 0 ? c : ua(c, e.nonce));
2118
+ let l = new nt();
2119
+ l.pipe(t, { end: !1 }), l.on("end", () => {
1711
2120
  t.end(n.tail);
1712
- }), a.stream.pipe(c);
2121
+ }), a.stream.pipe(l);
1713
2122
  }, l = () => {
1714
2123
  a?.stream.abort();
1715
2124
  };
@@ -1731,16 +2140,16 @@ import {
1731
2140
  return;
1732
2141
  }
1733
2142
  c();
1734
- }, Yr = (e) => Array.isArray(e.preload) && e.preload.length > 0, Xr = (e, t) => typeof e == "string" ? {
2143
+ }, ha = (e) => Array.isArray(e.preload) && e.preload.length > 0, ga = (e, t) => typeof e == "string" ? {
1735
2144
  tag: e,
1736
2145
  input: {}
1737
2146
  } : {
1738
2147
  tag: e.tag,
1739
2148
  input: e.input?.(t) ?? {}
1740
- }, Zr = async (e) => {
2149
+ }, _a = async (e) => {
1741
2150
  let { pageMod: t, params: n, query: r, apiName: i, seed: a, seedFailure: o, onError: s } = e;
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);
2151
+ if (ha(t) && r !== void 0 && i !== void 0) for (let e of t.preload) {
2152
+ let { tag: t, input: c } = ga(e, n);
1744
2153
  try {
1745
2154
  a(i, t, c, await r(t, c));
1746
2155
  } catch (e) {
@@ -1750,62 +2159,62 @@ import {
1750
2159
  }, e);
1751
2160
  }
1752
2161
  }
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([
2162
+ }, va = (e) => l.test(e) || e.endsWith(".workflow.server.tsx") ? !1 : c.test(e) || o.test(e) || i.test(e), ya = /* @__PURE__ */ new Set([
1754
2163
  "node_modules",
1755
2164
  "dist",
1756
2165
  ".framework",
1757
2166
  ".git"
1758
- ]), ei = async (e) => {
2167
+ ]), ba = async (e) => {
1759
2168
  let t = [], n = async (e) => {
1760
2169
  let r;
1761
2170
  try {
1762
- r = await N.readdir(e, { withFileTypes: !0 });
2171
+ r = await B.readdir(e, { withFileTypes: !0 });
1763
2172
  } catch {
1764
2173
  return;
1765
2174
  }
1766
2175
  for (let i of r) if (!(i.name.startsWith(".") && i.isDirectory())) {
1767
2176
  if (i.isDirectory()) {
1768
- if ($r.has(i.name)) continue;
1769
- await n(O(e, i.name));
1770
- } else Qr(i.name) && t.push(O(e, i.name));
2177
+ if (ya.has(i.name)) continue;
2178
+ await n(F(e, i.name));
2179
+ } else va(i.name) && t.push(F(e, i.name));
1771
2180
  }
1772
2181
  };
1773
2182
  return await n(e), t.sort();
1774
- }, ti = async (e) => {
1775
- let t = ge("sha1");
1776
- for (let n of await ei(e)) {
2183
+ }, xa = async (e) => {
2184
+ let t = J("sha1");
2185
+ for (let n of await ba(e)) {
1777
2186
  t.update(n.slice(e.length)), t.update("\0");
1778
2187
  try {
1779
- t.update(await N.readFile(n));
2188
+ t.update(await B.readFile(n));
1780
2189
  } catch {}
1781
2190
  t.update("\0");
1782
2191
  }
1783
2192
  try {
1784
- t.update(await N.readFile(O(e, "rpcGroup.generated.ts")));
2193
+ t.update(await B.readFile(F(e, "rpcGroup.generated.ts")));
1785
2194
  } catch {}
1786
2195
  return t.digest("hex");
1787
- }, ni = async (e) => {
2196
+ }, Sa = async (e) => {
1788
2197
  if (e.length === 0) return;
1789
2198
  let t = [];
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) => {
2199
+ for (let n of [...e].sort()) t.push(await xa(n));
2200
+ return J("sha1").update(t.join("\0")).digest("hex");
2201
+ }, Ca = (e) => typeof e == "object" && !!e && e._tag === "VoltroMiddleware" && typeof e.run == "function", wa = ["middleware.ts", "middleware.tsx"], Ta = (e) => {
1793
2202
  let t = e.replace(/\/+$/, "");
1794
2203
  return t === "" ? "/" : t;
1795
- }, X = (e, t) => {
1796
- let n = ai(e);
2204
+ }, Z = (e, t) => {
2205
+ let n = Ta(e);
1797
2206
  if (n === "/") return !0;
1798
- let r = ai(t);
2207
+ let r = Ta(t);
1799
2208
  return r === n || r.startsWith(`${n}/`);
1800
- }, oi = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, si = (e, t) => {
2209
+ }, Ea = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, Da = (e, t) => {
1801
2210
  if (e === void 0) return !0;
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) => {
2211
+ let n = Ea(e.under), r = e.routes ?? [];
2212
+ 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;
2213
+ }, Oa = (e) => {
1805
2214
  if (e?.assets !== !0) return [];
1806
- let t = oi(e.under);
2215
+ let t = Ea(e.under);
1807
2216
  return t.length > 0 ? t : (e.routes ?? []).length > 0 ? [] : ["/"];
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) => {
2217
+ }, ka = (e, t) => Oa(e).some((e) => Z(e, t)) ? !(e?.except ?? []).some((e) => Z(e, t)) : !1, Aa = (e, t) => e.find(({ middleware: e }) => t.route === void 0 ? ka(e.match, t.pathname) : Da(e.match, t.route))?.middleware, ja = (e, t) => {
1809
2218
  let n = [];
1810
2219
  for (let { exportName: r, middleware: i } of e) {
1811
2220
  let e = i.match;
@@ -1813,13 +2222,13 @@ import {
1813
2222
  kind: "dead-matcher",
1814
2223
  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]\`.`
1815
2224
  });
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({
2225
+ if (e?.assets !== !0) for (let [i, a] of [["under", Ea(e?.under)], ["except", e?.except ?? []]]) for (let e of a) t.some((t) => Z(e, t)) || n.push({
1817
2226
  kind: "dead-matcher",
1818
2227
  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.")
1819
2228
  });
1820
2229
  }
1821
2230
  for (let r = 0; r < e.length; r += 1) for (let i = r + 1; i < e.length; i += 1) {
1822
- let a = e[r], o = e[i], s = t.find((e) => si(a.middleware.match, e) && si(o.middleware.match, e));
2231
+ let a = e[r], o = e[i], s = t.find((e) => Da(a.middleware.match, e) && Da(o.middleware.match, e));
1823
2232
  if (s !== void 0) {
1824
2233
  n.push({
1825
2234
  kind: "overlap",
@@ -1828,7 +2237,7 @@ import {
1828
2237
  continue;
1829
2238
  }
1830
2239
  {
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)));
2240
+ let e = Oa(a.middleware.match), t = Oa(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)));
1832
2241
  r && !i && n.push({
1833
2242
  kind: "overlap",
1834
2243
  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.`
@@ -1836,10 +2245,10 @@ import {
1836
2245
  }
1837
2246
  }
1838
2247
  return n;
1839
- }, fi = (e, t) => {
1840
- let r = di(e, t);
2248
+ }, Ma = (e, t) => {
2249
+ let r = ja(e, t);
1841
2250
  if (r.length !== 0) throw n(`middleware.ts: ${r.length} problem(s)\n\n` + r.map((e) => ` • ${e.message}`).join("\n\n"));
1842
- }, pi = (e) => {
2251
+ }, Na = (e) => {
1843
2252
  let t = {};
1844
2253
  if (!e) return t;
1845
2254
  for (let n of e.split(";")) {
@@ -1853,20 +2262,20 @@ import {
1853
2262
  }
1854
2263
  }
1855
2264
  return t;
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) => {
2265
+ }, Pa = (e) => Object.entries(e).map(([e, t]) => `${e}=${encodeURIComponent(t)}`).join("; "), Fa = /(^|[-_.])(auth[-_.]?token|session|access[-_.]?token)([-_.]|$)|^sb-.*-auth-token$/i, Ia = (e) => e.httpOnly === void 0 && Fa.test(e.name), La = (e) => {
1857
2266
  let t = [`${e.name}=${encodeURIComponent(e.value)}`];
1858
2267
  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("; ");
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) {
2268
+ }, Ra = (e) => e.length === 0 ? {} : { "set-cookie": e.map(La) }, za = async (e, t = (e) => import(me(e).href)) => {
2269
+ for (let r of wa) {
1861
2270
  let i;
1862
2271
  try {
1863
- i = await t(O(e, r));
2272
+ i = await t(F(e, r));
1864
2273
  } catch (e) {
1865
2274
  let t = e?.code;
1866
2275
  if (t === "ERR_MODULE_NOT_FOUND" || t === "MODULE_NOT_FOUND") continue;
1867
2276
  throw e;
1868
2277
  }
1869
- let a = Object.entries(i ?? {}), o = a.filter((e) => ri(e[1])).map(([e, t]) => ({
2278
+ let a = Object.entries(i ?? {}), o = a.filter((e) => Ca(e[1])).map(([e, t]) => ({
1870
2279
  exportName: e,
1871
2280
  middleware: t
1872
2281
  }));
@@ -1884,7 +2293,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1884
2293
  return o;
1885
2294
  }
1886
2295
  return [];
1887
- }, bi = async (e, t, n) => {
2296
+ }, Ba = async (e, t, n) => {
1888
2297
  let r = {
1889
2298
  headers: t.headers,
1890
2299
  cookies: t.cookies,
@@ -1895,7 +2304,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1895
2304
  let i = await e.run(t);
1896
2305
  if (!i) return r;
1897
2306
  let a = i.setCookies ?? [];
1898
- if (n !== void 0) for (let e of a) gi(e) && n(e);
2307
+ if (n !== void 0) for (let e of a) Ia(e) && n(e);
1899
2308
  let o = i.headers ? {
1900
2309
  ...t.headers,
1901
2310
  ...i.headers
@@ -1909,25 +2318,25 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1909
2318
  };
1910
2319
  let l = { ...t.cookies };
1911
2320
  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)), {
2321
+ return i.headers?.cookie === void 0 && (o.cookie = Pa(l)), {
1913
2322
  headers: o,
1914
2323
  cookies: l,
1915
2324
  setCookies: a,
1916
2325
  responseHeaders: s,
1917
2326
  ...c
1918
2327
  };
1919
- }, xi = /* @__PURE__ */ new Set(["voltro:locale"]), Si = /* @__PURE__ */ new Set(["authorization", "cookie"]), Ci = (e) => {
2328
+ }, Va = /* @__PURE__ */ new Set(["voltro:locale"]), Ha = /* @__PURE__ */ new Set(["authorization", "cookie"]), Ua = (e) => {
1920
2329
  let t = e.split(";").map((e) => e.trim()).filter((e) => {
1921
2330
  let t = e.indexOf("="), n = (t === -1 ? e : e.slice(0, t)).trim();
1922
- return xi.has(n);
2331
+ return Va.has(n);
1923
2332
  });
1924
2333
  return t.length > 0 ? t.join("; ") : void 0;
1925
- }, wi = (e) => {
2334
+ }, Wa = (e) => {
1926
2335
  let t = {};
1927
2336
  for (let [n, r] of Object.entries(e)) if (!n.startsWith("x-voltro-")) {
1928
- if (Si.has(n)) {
2337
+ if (Ha.has(n)) {
1929
2338
  if (n === "cookie") {
1930
- let e = Ci(r);
2339
+ let e = Ua(r);
1931
2340
  e !== void 0 && (t.cookie = e);
1932
2341
  }
1933
2342
  continue;
@@ -1935,27 +2344,91 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1935
2344
  t[n] = r;
1936
2345
  }
1937
2346
  return t;
1938
- }, Ti = (e) => {
2347
+ }, Ga = (e) => {
1939
2348
  let t = {};
1940
- for (let [n, r] of Object.entries(e)) xi.has(n) && (t[n] = r);
2349
+ for (let [n, r] of Object.entries(e)) Va.has(n) && (t[n] = r);
1941
2350
  return t;
1942
- }, Z = R({ scope: "voltro:dev:web" }), Ei = R({ scope: "vite" }), Di = await (async () => {
2351
+ }, Ka = ve.exponential({
2352
+ start: .001,
2353
+ factor: 2,
2354
+ count: 16
2355
+ }), qa = _e.counter("voltro_ppr_shell_serves_total", { description: "ppr responses whose cached shell was written, by page." }), Ja = _e.counter("voltro_ppr_hole_passes_total", { description: "ppr per-request hole passes started, by page." }), Ya = _e.counter("voltro_ppr_hole_settles_total", { description: "Deferred ppr holes settled and appended to a response, by page." }), Xa = _e.counter("voltro_ppr_hole_errors_total", { description: "ppr hole passes that failed as a whole (every hole stays on its fallback), by page." }), Za = _e.histogram("voltro_ppr_hole_pass_seconds", Ka, "ppr hole-pass duration in seconds (loader re-run to last hole settled), by page."), Qa = [], $a = /* @__PURE__ */ new Map(), eo = (e) => {
2356
+ let t = $a.get(e);
2357
+ if (t !== void 0) return t;
2358
+ let n = (t) => _e.tagged(t, "page", e), r = {
2359
+ shellServes: n(qa),
2360
+ holePasses: n(Ja),
2361
+ holeSettles: n(Ya),
2362
+ holeErrors: n(Xa),
2363
+ holePassSeconds: n(Za)
2364
+ };
2365
+ return $a.set(e, r), r;
2366
+ }, to = (e) => {
2367
+ eo(e).shellServes.unsafeUpdate(1, Qa);
2368
+ }, no = (e) => {
2369
+ eo(e).holePasses.unsafeUpdate(1, Qa);
2370
+ }, ro = (e) => {
2371
+ eo(e).holeSettles.unsafeUpdate(1, Qa);
2372
+ }, io = (e) => {
2373
+ eo(e).holeErrors.unsafeUpdate(1, Qa);
2374
+ }, ao = (e, t) => {
2375
+ eo(e).holePassSeconds.unsafeUpdate(t / 1e3, Qa);
2376
+ }, oo = ["cookie", "authorization"], so = (e) => oo.includes(e) || e.startsWith("x-voltro-"), co = ["voltro:locale"], lo = class extends Error {
2377
+ constructor(e, t, n) {
2378
+ super(`[voltro] ppr page '${n}': the SHELL render read the ${e} '${t}'. A ppr shell is CACHED and served to every visitor, so it must be computed without credentials — there is no way to prove request-independence by inspection, so the read itself is the error. Move this read into a deferred hole (the second argument of defer(), which runs per request with the full context), or drop ppr and use renderMode 'ssr'.`), this.name = "PprShellCredentialAccessError";
2379
+ }
2380
+ }, uo = (e, t) => new Proxy({ ...e }, { get(e, n, r) {
2381
+ if (typeof n == "string" && so(n)) throw new lo("header", n, t);
2382
+ return Reflect.get(e, n, r);
2383
+ } }), fo = (e, t) => new Proxy({ ...e }, { get(e, n, r) {
2384
+ if (typeof n == "string" && !co.includes(n) && !(n in Object.prototype)) throw new lo("cookie", n, t);
2385
+ return Reflect.get(e, n, r);
2386
+ } }), po = async (e) => {
2387
+ no(e.page);
2388
+ let t = Date.now(), n = () => e.res.destroyed === !0 || e.res.writableEnded === !0;
2389
+ try {
2390
+ let t = await e.loader(e.ctx), r = e.helpers.prepareDeferredLoaderData(t, "page"), i = r.deferredIds;
2391
+ if (i === void 0) {
2392
+ n() || e.res.end();
2393
+ return;
2394
+ }
2395
+ let a = r.renderData;
2396
+ await Promise.all(Object.entries(i).map(async ([t, r]) => {
2397
+ let i = await a[t];
2398
+ ro(e.page), !n() && e.res.write(`<script>${e.helpers.deferredSettleScript(r, i)}<\/script>`);
2399
+ }));
2400
+ } catch (t) {
2401
+ io(e.page), e.log.warn("ppr hole pass failed — holes stay on their fallbacks", { page: e.page }, t);
2402
+ } finally {
2403
+ ao(e.page, Date.now() - t), n() || e.res.end();
2404
+ }
2405
+ }, mo = (e, t) => {
2406
+ if (e.deferredSegmentIds !== void 0) throw Error(`[voltro] ppr page '${t}': a LAYOUT loader in its chain uses defer(). ppr appends holes for the PAGE loader only — move the deferred field into the page loader, or return the value directly from the layout.`);
2407
+ }, Q = G({ scope: "voltro:dev:web" }), ho = G({ scope: "vite" }), go = await (async () => {
1943
2408
  try {
1944
- let e = O(D(re(import.meta.url)), "..", "package.json"), t = await N.readFile(e, "utf8");
2409
+ let e = F(P(W(import.meta.url)), "..", "package.json"), t = await B.readFile(e, "utf8");
1945
2410
  return JSON.parse(t).version ?? "0.0.0";
1946
2411
  } catch {
1947
2412
  return "0.0.0";
1948
2413
  }
1949
- })(), Oi = async () => {
2414
+ })(), _o = (e, t) => {
2415
+ let n;
2416
+ for (let r of e) {
2417
+ if (!r.hasNotFound) continue;
2418
+ let e = "/" + r.dir.split("/").filter((e) => e !== "" && !/^\(.*\)$/.test(e)).join("/"), i = e === "/" ? "/" : e;
2419
+ i !== "/" && !(t === i || t.startsWith(i + "/")) || (n === void 0 || r.dir.length > n.dir.length) && (n = r);
2420
+ }
2421
+ return n;
2422
+ }, vo = async () => {
1950
2423
  try {
1951
- let e = D(re(import.meta.url)), t = A(e, "..", "..", "devtools");
1952
- if (M(O(t, "package.json"))) return t;
1953
- let n = A(e, "..", "..", "..", "devtools");
1954
- return M(O(n, "package.json")) ? n : null;
2424
+ let e = P(W(import.meta.url)), t = L(e, "..", "..", "devtools");
2425
+ if (z(F(t, "package.json"))) return t;
2426
+ let n = L(e, "..", "..", "..", "devtools");
2427
+ return z(F(n, "package.json")) ? n : null;
1955
2428
  } catch {
1956
2429
  return null;
1957
2430
  }
1958
- }, ki = (e, t) => e.disableDevtools || !t ? [] : [
2431
+ }, yo = (e, t) => e.disableDevtools || !t ? [] : [
1959
2432
  "",
1960
2433
  "// Dev-only in-page devtools overlay. The `import.meta.env.DEV` guard is a",
1961
2434
  "// compile-time constant, so prod builds strip this whole `if` block — the",
@@ -1965,85 +2438,85 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
1965
2438
  " await import('@voltro/devtools/styles.css')",
1966
2439
  " Devtools = (await import('@voltro/devtools')).VoltroDevtools",
1967
2440
  "}"
1968
- ], Ai = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], ji = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], Mi = (e) => e.sentry ? [
2441
+ ], bo = (e, t) => e.disableDevtools || !t ? [] : [" ...(Devtools ? { Devtools } : {}),"], xo = (e) => e.sentry ? ["import { initSentryBrowser } from '@voltro/plugin-sentry/web'"] : [], So = (e) => e.sentry ? [
1969
2442
  "",
1970
2443
  "// Browser-side Sentry (frontend half of the deep integration). Errors +",
1971
2444
  "// browser rpc spans flow to Sentry, sharing the server transactions' trace.",
1972
2445
  `await initSentryBrowser(${JSON.stringify(e.sentry)})`
1973
- ] : [], Ni = (e) => e.env ? ["import './env.public'"] : [], Pi = (e) => {
1974
- let t = [], n = A(e);
2446
+ ] : [], Co = (e) => e.env ? ["import './env.public'"] : [], wo = (e) => {
2447
+ let t = [], n = L(e);
1975
2448
  for (;;) {
1976
- M(O(n, "pnpm-workspace.yaml")) && t.push(n);
1977
- let e = D(n);
2449
+ z(F(n, "pnpm-workspace.yaml")) && t.push(n);
2450
+ let e = P(n);
1978
2451
  if (e === n) break;
1979
2452
  n = e;
1980
2453
  }
1981
2454
  return t;
1982
- }, Fi = b, Ii = (e) => {
2455
+ }, To = re, Eo = (e) => {
1983
2456
  if (/\/node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(?:react|react-dom|scheduler)\//.test(e)) return "react";
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));
2457
+ }, Do = /export\s+(?:async\s+)?(?:const|function|let|var)\s+loader\b/, Oo = (e) => e.startsWith("(") && e.endsWith(")"), ko = (e) => e.filter((e) => !Oo(e)), Ao = (e) => {
2458
+ let t = e.replace(s, "").split("/").filter(Boolean).filter((e) => !Oo(e));
1986
2459
  return t.length === 0 ? "/" : "/" + t.join("/");
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) => {
2460
+ }, jo = (e) => `${e.replace(s, "").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}`, Mo = async (e) => {
1988
2461
  let t = [], n = [], r = async (e, i) => {
1989
- let a = [];
2462
+ let o = [];
1990
2463
  try {
1991
- a = await N.readdir(e, { withFileTypes: !0 });
2464
+ o = await B.readdir(e, { withFileTypes: !0 });
1992
2465
  } catch {
1993
2466
  return;
1994
2467
  }
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("/");
1996
- if (l.some((e) => s.has(e))) {
2468
+ let c = o.filter((e) => e.isDirectory()).map((e) => e.name).sort(), l = o.filter((e) => e.isFile() && e.name.endsWith(".tsx") && !To(e.name)).map((e) => e.name).sort(), u = new Set(l), d = i.join("/");
2469
+ if (l.some((e) => a.has(e))) {
1997
2470
  let t = u.has("layout.tsx"), r = !1;
1998
2471
  if (t) try {
1999
- let t = await N.readFile(O(e, "layout.tsx"), "utf8");
2000
- r = Li.test(t);
2472
+ let t = await B.readFile(F(e, "layout.tsx"), "utf8");
2473
+ r = Do.test(t);
2001
2474
  } catch {}
2002
2475
  n.push({
2003
2476
  dir: d,
2004
2477
  chain: i,
2005
- contributesToUrl: i.length === 0 || !Ri(i[i.length - 1]),
2478
+ contributesToUrl: i.length === 0 || !Oo(i[i.length - 1]),
2006
2479
  hasLayout: t,
2007
2480
  hasLayoutLoader: r,
2008
2481
  hasError: u.has("error.tsx"),
2009
2482
  hasPending: u.has("loading.tsx"),
2010
2483
  hasNotFound: u.has("not-found.tsx"),
2011
- specialFiles: l.filter((e) => s.has(e))
2484
+ specialFiles: l.filter((e) => a.has(e))
2012
2485
  });
2013
2486
  }
2014
2487
  for (let e of l) {
2015
- if (!c.test(e)) continue;
2488
+ if (!s.test(e)) continue;
2016
2489
  let n = d ? `${d}/${e}` : e;
2017
2490
  t.push({
2018
2491
  file: n,
2019
- pattern: Bi(n),
2020
- ident: Vi(n),
2492
+ pattern: Ao(n),
2493
+ ident: jo(n),
2021
2494
  dirChain: i
2022
2495
  });
2023
2496
  }
2024
- for (let t of o) await r(O(e, t), [...i, t]);
2497
+ for (let t of c) await r(F(e, t), [...i, t]);
2025
2498
  };
2026
2499
  await r(e, []), t.sort((e, t) => e.file < t.file ? -1 : 1);
2027
2500
  let i = /* @__PURE__ */ new Set();
2028
2501
  for (let e of t) for (let t = e.dirChain.length; t >= 0; t--) i.add(e.dirChain.slice(0, t).join("/"));
2029
- let a = [], o = [];
2030
- for (let { specialFiles: e, ...t } of n) i.has(t.dir) ? a.push(t) : o.push({
2502
+ let o = [], c = [];
2503
+ for (let { specialFiles: e, ...t } of n) i.has(t.dir) ? o.push(t) : c.push({
2031
2504
  dir: t.dir,
2032
2505
  files: e
2033
2506
  });
2034
2507
  return {
2035
2508
  pages: t,
2036
- dirs: a,
2037
- orphanedSpecials: o
2509
+ dirs: o,
2510
+ orphanedSpecials: c
2038
2511
  };
2039
- }, Hi = (e, t) => {
2512
+ }, No = (e, t) => {
2040
2513
  let n = [];
2041
2514
  for (let r = 0; r <= t.length; r++) {
2042
2515
  let i = t.slice(0, r).join("/"), a = e.find((e) => e.dir === i);
2043
2516
  a && n.push(a);
2044
2517
  }
2045
2518
  return n;
2046
- }, Ui = async (e) => {
2519
+ }, Po = async (e) => {
2047
2520
  let { entries: t, loadLayout: n, loadError: r, loadPending: i, ctx: a } = e, o = {};
2048
2521
  return {
2049
2522
  chain: await Promise.all(t.map(async (e, t) => {
@@ -2067,10 +2540,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2067
2540
  })),
2068
2541
  segmentLoaderData: o
2069
2542
  };
2070
- }, Wi = (e) => {
2071
- let t = zi(e);
2543
+ }, Fo = (e) => {
2544
+ let t = ko(e);
2072
2545
  return t.length === 0 ? "" : "/" + t.join("/");
2073
- }, Gi = [
2546
+ }, Io = [
2074
2547
  "// Hot-reload bridge: keep SSR-injected <link rel=\"stylesheet\"> tags",
2075
2548
  "// in sync with Vite's CSS HMR. Without this, edits to .css files",
2076
2549
  "// only update the JS-injected <style> overlay; the underlying <link>",
@@ -2163,7 +2636,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2163
2636
  " _vdtErrorStart('Build error')",
2164
2637
  " })",
2165
2638
  "}"
2166
- ].join("\n"), Ki = (e) => {
2639
+ ].join("\n"), Lo = (e) => {
2167
2640
  let t = [], n = 0, r = e.split("/").filter(Boolean), i = [];
2168
2641
  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, "\\$&"));
2169
2642
  let a = i.join("/");
@@ -2172,8 +2645,8 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2172
2645
  paramNames: t,
2173
2646
  priority: n
2174
2647
  };
2175
- }, qi = (e) => e.map((e) => {
2176
- let { regex: t, paramNames: n, priority: r } = Ki(e.pattern);
2648
+ }, Ro = (e) => e.map((e) => {
2649
+ let { regex: t, paramNames: n, priority: r } = Lo(e.pattern);
2177
2650
  return {
2178
2651
  pattern: e.pattern,
2179
2652
  file: e.file,
@@ -2182,7 +2655,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2182
2655
  paramNames: n,
2183
2656
  priority: r
2184
2657
  };
2185
- }).slice().sort((e, t) => e.priority - t.priority), Ji = (e, t) => {
2658
+ }).slice().sort((e, t) => e.priority - t.priority), zo = (e, t) => {
2186
2659
  for (let n of t) {
2187
2660
  let t = n.regex.exec(e);
2188
2661
  if (!t) continue;
@@ -2194,9 +2667,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2194
2667
  };
2195
2668
  }
2196
2669
  return null;
2197
- }, Yi = Le, Xi = async (e) => {
2670
+ }, Bo = _, Vo = async (e) => {
2198
2671
  try {
2199
- let t = await import(I(O(e, "app.config.ts")).href), n = t.default?.port, i = r({
2672
+ let t = await import(me(F(e, "app.config.ts")).href), n = t.default?.port, i = r({
2200
2673
  kind: "api",
2201
2674
  configPort: typeof n == "number" ? n : void 0,
2202
2675
  env: {}
@@ -2210,7 +2683,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2210
2683
  kind: "api",
2211
2684
  env: {}
2212
2685
  }).port };
2213
- }, Zi = (e, t) => ({
2686
+ }, Ho = (e, t) => ({
2214
2687
  name: e,
2215
2688
  pkg: t.package,
2216
2689
  browserWsUrl: t.url,
@@ -2218,7 +2691,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2218
2691
  ...t.serverUrl ? { serverOrigin: t.serverUrl } : {},
2219
2692
  ...t.headers ? { headers: t.headers } : {},
2220
2693
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
2221
- }), Qi = (e, t, n) => {
2694
+ }), Uo = (e, t, n) => {
2222
2695
  let r = t.transport?.wsPath ?? n.wsPath;
2223
2696
  return {
2224
2697
  name: e,
@@ -2230,7 +2703,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2230
2703
  ...t.headers ? { headers: t.headers } : {},
2231
2704
  ...t.authHeaders ? { hasAuthHeaders: !0 } : {}
2232
2705
  };
2233
- }, $i = (e) => {
2706
+ }, Wo = (e) => {
2234
2707
  let t = /* @__PURE__ */ new Map();
2235
2708
  for (let n of e) {
2236
2709
  if (n.proxyTarget === void 0) continue;
@@ -2238,43 +2711,43 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2238
2711
  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>.`);
2239
2712
  t.set(n.browserWsUrl, n.name);
2240
2713
  }
2241
- }, ea = async (e, t) => {
2714
+ }, Go = async (e, t) => {
2242
2715
  let n = Object.entries(t.apis ?? {}), r = [];
2243
2716
  for (let [t, i] of n) {
2244
2717
  if (i.url) {
2245
- r.push(Zi(t, i));
2718
+ r.push(Ho(t, i));
2246
2719
  continue;
2247
2720
  }
2248
- let n = await Yi(e, i.package);
2721
+ let n = await Bo(e, i.package);
2249
2722
  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.`);
2250
- r.push(Qi(t, i, await Xi(n)));
2723
+ r.push(Uo(t, i, await Vo(n)));
2251
2724
  }
2252
- return $i(r), r;
2253
- }, ta = (e) => {
2725
+ return Wo(r), r;
2726
+ }, Ko = (e) => {
2254
2727
  if (!(!/^wss?:\/\//.test(e) && !/^https?:\/\//.test(e))) try {
2255
2728
  let t = new URL(e);
2256
2729
  return t.protocol = t.protocol === "wss:" || t.protocol === "https:" ? "https:" : "http:", `${t.protocol}//${t.host}`;
2257
2730
  } catch {
2258
2731
  return;
2259
2732
  }
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) => {
2733
+ }, qo = (e) => `VOLTRO_API_ORIGIN_${e.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, Jo = (e) => process.env[qo(e)] ?? process.env.VOLTRO_API_ORIGIN, Yo = (e, t) => {
2261
2734
  if (!e) return;
2262
- let n = ra(e.name) ?? e.serverOrigin;
2735
+ let n = Jo(e.name) ?? e.serverOrigin;
2263
2736
  if (n) {
2264
- let e = ta(n);
2737
+ let e = Ko(n);
2265
2738
  if (e) return e;
2266
2739
  }
2267
2740
  if (t?.allowDevProxy && e.proxyTarget) {
2268
- let t = ta(e.proxyTarget);
2741
+ let t = Ko(e.proxyTarget);
2269
2742
  if (t) return t;
2270
2743
  }
2271
- if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return ta(e.browserWsUrl);
2272
- }, aa = (e, t, n) => {
2744
+ if (!e.proxyTarget && /^wss?:\/\//.test(e.browserWsUrl)) return Ko(e.browserWsUrl);
2745
+ }, Xo = (e, t, n) => {
2273
2746
  if (!e) {
2274
2747
  if (n?.apiName === void 0) return;
2275
2748
  let e = n.apiName;
2276
2749
  return async () => {
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.`);
2750
+ 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 ${qo(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.`);
2278
2751
  };
2279
2752
  }
2280
2753
  return async (r, i) => {
@@ -2297,7 +2770,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2297
2770
  });
2298
2771
  } catch (t) {
2299
2772
  let i = t?.cause?.code ?? String(t?.message ?? 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 });
2773
+ throw Error(`[loader.query] ${r}: could not reach the api at ${e}/rpc (${i}). ${n?.apiName ? `Set ${qo(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 });
2301
2774
  }
2302
2775
  if (!o.ok) throw Error(`[loader.query] ${r}: HTTP ${o.status} ${await o.text()}`);
2303
2776
  let s = await o.json();
@@ -2327,7 +2800,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2327
2800
  }
2328
2801
  if (u) return l;
2329
2802
  };
2330
- }, oa = (e, t) => {
2803
+ }, Zo = (e, t) => {
2331
2804
  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
2805
  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
2806
  let a = (e) => {
@@ -2339,8 +2812,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2339
2812
  entryLines: e.map((e) => ` ${JSON.stringify(e.name)}: { ${a(e).join(", ")} },`),
2340
2813
  providerEntryLines: e.map((e) => ` { name: ${JSON.stringify(e.name)}, ${a(e).join(", ")} },`)
2341
2814
  };
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" ? [
2815
+ }, Qo = async (e, t, n, r = {}) => {
2816
+ let i = t.title ?? t.name ?? "app";
2817
+ Ln(e);
2818
+ let a = await Nn(e, t.fonts), o = a === null ? [] : [...a.preloads.map((e) => ` <link rel="preload" as="font" type="font/${e.endsWith(".woff2") ? "woff2" : e.endsWith(".woff") ? "woff" : e.endsWith(".otf") ? "otf" : "ttf"}" href="${e}" crossorigin />`), ` <style data-voltro-fonts>${a.css}</style>`], s = t.theme === "dark" ? " class=\"dark\"" : t.theme === "light" ? " class=\"light\"" : "", c = z(F(e, "node_modules", "@voltro", "devtools", "package.json")) || await vo() !== null, l = t.theme === "system" ? [
2344
2819
  " <script>",
2345
2820
  " (function () {",
2346
2821
  " var root = document.documentElement",
@@ -2361,7 +2836,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2361
2836
  " }",
2362
2837
  " })()",
2363
2838
  " <\/script>"
2364
- ].join("\n") : "", c = t.timeZone === "viewer" ? [
2839
+ ].join("\n") : "", u = t.timeZone === "viewer" ? [
2365
2840
  " <script>",
2366
2841
  " (function () {",
2367
2842
  " try {",
@@ -2373,17 +2848,18 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2373
2848
  " } catch (e) {}",
2374
2849
  " })()",
2375
2850
  " <\/script>"
2376
- ].join("\n") : "", l = [
2851
+ ].join("\n") : "", d = [
2377
2852
  "<!doctype html>",
2378
2853
  "<!-- GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot. -->",
2379
- `<html lang="en"${a}>`,
2854
+ `<html lang="en"${s}>`,
2380
2855
  " <head>",
2381
2856
  " <meta charset=\"UTF-8\" />",
2382
2857
  " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />",
2383
2858
  ` <title>${i}</title>`,
2384
2859
  " <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />",
2385
- ...s ? [s] : [],
2386
- ...c ? [c] : [],
2860
+ ...o,
2861
+ ...l ? [l] : [],
2862
+ ...u ? [u] : [],
2387
2863
  " </head>",
2388
2864
  " <body>",
2389
2865
  " <div id=\"root\"></div>",
@@ -2391,70 +2867,70 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2391
2867
  " </body>",
2392
2868
  "</html>",
2393
2869
  ""
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) {
2870
+ ].join("\n"), f = F(e, "src", "pages"), { pages: p, dirs: m, orphanedSpecials: h } = await Mo(f);
2871
+ await S(f, p);
2872
+ for (let e of h) 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.`);
2873
+ let { imports: g, entryLines: _ } = Zo(n, "../app.config"), v, y, b;
2874
+ if (p.length > 0) {
2875
+ let n = p.map((e) => ` ${JSON.stringify(e.pattern)}: () => import('../src/pages/${e.file}'),`), r = [];
2876
+ for (let e of m) {
2401
2877
  let t = e.dir === "" ? "../src/pages" : `../src/pages/${e.dir}`;
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'`);
2878
+ 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'`);
2403
2879
  }
2404
- let i = d.map((e) => {
2405
- let t = Hi(f, e.dirChain).map((e) => {
2880
+ let i = p.map((e) => {
2881
+ let t = No(m, e.dirChain).map((e) => {
2406
2882
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2407
2883
  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(", ")} }`;
2408
2884
  }).join(",\n");
2409
2885
  return ` makePageRoute(${JSON.stringify(e.pattern)}, ${t.length > 0 ? `[\n${t},\n ]` : "undefined"}),`;
2410
- }), a = f.filter((e) => e.hasNotFound).map((e) => {
2411
- let t = Wi(e.chain), n = Hi(f, e.chain).map((e) => {
2886
+ }), a = m.filter((e) => e.hasNotFound).map((e) => {
2887
+ let t = Fo(e.chain), n = No(m, e.chain).map((e) => {
2412
2888
  let t = [`id: ${JSON.stringify(e.dir || "/")}`], n = JSON.stringify(e.dir);
2413
2889
  return e.hasLayout && t.push(`Layout: refs.layouts[${n}]`), e.hasError && t.push(`Error: refs.errors[${n}]`), ` { ${t.join(", ")} }`;
2414
2890
  }).join(",\n"), r = n.length > 0 ? `\n chain: [\n${n},\n ],` : "";
2415
2891
  return ` {\n prefix: ${JSON.stringify(t)},\n Component: refs.notFounds[${JSON.stringify(e.dir)}],${r}\n },`;
2416
- }), s = [], c = [], l = [], u = [], p = [], y = [];
2417
- for (let e of f) {
2892
+ }), o = [], s = [], l = [], u = [], d = [], f = [];
2893
+ for (let e of m) {
2418
2894
  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);
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({
2895
+ e.hasLayout && e.hasLayoutLoader ? (s.push(` ${a}: ${$(e.dir, "Layout")}Mod.default,`), l.push(` ${a}: ${$(e.dir, "Layout")}Mod.loader,`), o.push({
2420
2896
  relPath: t,
2421
2897
  kind: "layout",
2422
2898
  slotKey: e.dir
2423
- })) : e.hasLayout && (c.push(` ${a}: ${Q(e.dir, "Layout")},`), s.push({
2899
+ })) : e.hasLayout && (s.push(` ${a}: ${$(e.dir, "Layout")},`), o.push({
2424
2900
  relPath: t,
2425
2901
  kind: "layout",
2426
2902
  slotKey: e.dir
2427
- })), e.hasError && (u.push(` ${a}: ${Q(e.dir, "Error")},`), s.push({
2903
+ })), e.hasError && (u.push(` ${a}: ${$(e.dir, "Error")},`), o.push({
2428
2904
  relPath: n,
2429
2905
  kind: "error",
2430
2906
  slotKey: e.dir
2431
- })), e.hasPending && (p.push(` ${a}: ${Q(e.dir, "Pending")},`), s.push({
2907
+ })), e.hasPending && (d.push(` ${a}: ${$(e.dir, "Pending")},`), o.push({
2432
2908
  relPath: r,
2433
2909
  kind: "pending",
2434
2910
  slotKey: e.dir
2435
- })), e.hasNotFound && (y.push(` ${a}: ${Q(e.dir, "NotFound")},`), s.push({
2911
+ })), e.hasNotFound && (f.push(` ${a}: ${$(e.dir, "NotFound")},`), o.push({
2436
2912
  relPath: i,
2437
2913
  kind: "notFound",
2438
2914
  slotKey: e.dir
2439
2915
  }));
2440
2916
  }
2441
- for (let e of d) s.push({
2917
+ for (let e of p) o.push({
2442
2918
  relPath: `../src/pages/${e.file}`,
2443
2919
  kind: "page",
2444
2920
  slotKey: e.pattern
2445
2921
  });
2446
- let b = s.map((e) => ` ${JSON.stringify(e.relPath)},`), x = s.map((e, t) => {
2922
+ let h = o.map((e) => ` ${JSON.stringify(e.relPath)},`), x = o.map((e, t) => {
2447
2923
  let n = JSON.stringify(e.slotKey);
2448
2924
  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 }`;
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(", ")}]`);
2925
+ }), S = t.locales ?? [], C = S.length > 0 && S.every((t) => z(F(e, "src", "locales", `${t}.ts`)) || z(F(e, "src", "locales", `${t}.tsx`))), w = C, T = t.defaultLocale ?? S[0] ?? "en", E = t.router?.viewTransitions === !0 ? " viewTransitions" : "";
2926
+ 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(", ")}]`);
2451
2927
  let D = w ? [
2452
2928
  "import { I18nProvider } from '@voltro/i18n'",
2453
2929
  "import { resolveLocale } from '@voltro/i18n/server'",
2454
2930
  "import { useServerRequest } from '@voltro/web'",
2455
2931
  ...S.map((e) => `import i18nCatalog_${e} from '../src/locales/${e}'`)
2456
2932
  ] : [];
2457
- _ = [
2933
+ y = [
2458
2934
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2459
2935
  "// Routes + per-page chain + not-found scopes assembled from src/pages/.",
2460
2936
  "//",
@@ -2488,7 +2964,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2488
2964
  " pages: Record<string, unknown>",
2489
2965
  "} = {",
2490
2966
  " layouts: {",
2491
- ...c,
2967
+ ...s,
2492
2968
  " },",
2493
2969
  " layoutLoaders: {",
2494
2970
  ...l,
@@ -2497,10 +2973,10 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2497
2973
  ...u,
2498
2974
  " },",
2499
2975
  " pendings: {",
2500
- ...p,
2976
+ ...d,
2501
2977
  " },",
2502
2978
  " notFounds: {",
2503
- ...y,
2979
+ ...f,
2504
2980
  " },",
2505
2981
  " pages: {},",
2506
2982
  "}",
@@ -2565,7 +3041,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2565
3041
  "if (import.meta.hot) {",
2566
3042
  " import.meta.hot.accept(",
2567
3043
  " [",
2568
- ...b,
3044
+ ...h,
2569
3045
  " ],",
2570
3046
  " (newMods: Array<Record<string, unknown> | undefined>) => {",
2571
3047
  " let changed = false",
@@ -2575,7 +3051,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2575
3051
  " )",
2576
3052
  "}",
2577
3053
  ""
2578
- ].join("\n"), g = [
3054
+ ].join("\n"), v = [
2579
3055
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2580
3056
  "// The app's root component. It exports `App` and NOTHING ELSE: react-refresh",
2581
3057
  "// only accepts a module whose every export is a component, and a module it",
@@ -2690,20 +3166,20 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2690
3166
  ] : [` return <Router routes={routes} notFounds={notFounds}${E} />`],
2691
3167
  "}",
2692
3168
  ""
2693
- ].join("\n"), v = [
3169
+ ].join("\n"), b = [
2694
3170
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2695
3171
  "// Entry: imports the generated App component and calls mount() with the",
2696
3172
  "// resolved apis map. Side-effect only — no local component definitions —",
2697
3173
  "// so downstream invalidations (user page edits) terminate at app.tsx.",
2698
3174
  "",
2699
- ...Ni(t),
3175
+ ...Co(t),
2700
3176
  "import { mount } from '@voltro/web'",
2701
- ...m,
3177
+ ...g,
2702
3178
  "import { App } from './app'",
2703
3179
  "import { preloadCurrentRoute } from './routeTable'",
2704
- ...ji(t),
2705
- ...ki(t, o),
2706
- ...Mi(t),
3180
+ ...xo(t),
3181
+ ...yo(t, c),
3182
+ ...So(t),
2707
3183
  "",
2708
3184
  "// Preload the current route's page chunk BEFORE hydration so the first",
2709
3185
  "// client render matches the SSG/SSR-prerendered HTML. Without it, a lazy",
@@ -2718,101 +3194,111 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2718
3194
  "",
2719
3195
  "mount(App, {",
2720
3196
  " apis: {",
2721
- ...h,
3197
+ ..._,
2722
3198
  " },",
2723
- ...Ai(t, o),
3199
+ ...bo(t, c),
2724
3200
  "})",
2725
3201
  "",
2726
- Gi
3202
+ Io
2727
3203
  ].join("\n");
2728
- } else g = "", _ = "", v = [
3204
+ } else v = "", y = "", b = [
2729
3205
  "// GENERATED BY `voltro dev` — do not edit; will be overwritten on next boot.",
2730
3206
  "// The user's root component lives at ../src/App.tsx; this file imports it",
2731
3207
  "// and calls mount(). Side-effect only, no component definitions, so the",
2732
3208
  "// user's component file remains the Fast Refresh boundary.",
2733
3209
  "",
2734
- ...Ni(t),
3210
+ ...Co(t),
2735
3211
  "import { mount } from '@voltro/web'",
2736
- ...m,
3212
+ ...g,
2737
3213
  "import App from '../src/App'",
2738
- ...ji(t),
2739
- ...ki(t, o),
2740
- ...Mi(t),
3214
+ ...xo(t),
3215
+ ...yo(t, c),
3216
+ ...So(t),
2741
3217
  "",
2742
3218
  "mount(App, {",
2743
3219
  " apis: {",
2744
- ...h,
3220
+ ..._,
2745
3221
  " },",
2746
- ...Ai(t, o),
3222
+ ...bo(t, c),
2747
3223
  "})",
2748
3224
  "",
2749
- Gi
3225
+ Io
2750
3226
  ].join("\n");
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 = "";
3227
+ let x = F(e, ".framework");
3228
+ await B.mkdir(x, { recursive: !0 }), t.env ? await ut(x, r) : await B.rm(F(x, "env.public.ts"), { force: !0 }), await B.writeFile(F(x, "index.html"), d, "utf8"), await B.writeFile(F(x, "main.tsx"), b, "utf8"), v ? (await B.writeFile(F(x, "app.tsx"), v, "utf8"), await B.writeFile(F(x, "routeTable.ts"), y, "utf8")) : (await B.rm(F(x, "app.tsx"), { force: !0 }), await B.rm(F(x, "routeTable.ts"), { force: !0 }));
3229
+ let C = F(e, ".gitignore"), w = "";
2754
3230
  try {
2755
- S = await N.readFile(x, "utf8");
3231
+ w = await B.readFile(C, "utf8");
2756
3232
  } catch {}
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";
3233
+ let T = ["/.framework/"], E = new Set(w.split("\n").map((e) => e.trim())), D = T.filter((e) => !E.has(e));
3234
+ if (D.length > 0) {
3235
+ let e = w === "" || w.endsWith("\n") ? "" : "\n";
2760
3236
  try {
2761
- await N.appendFile(x, `${e}${T.join("\n")}\n`, "utf8");
3237
+ await B.appendFile(C, `${e}${D.join("\n")}\n`, "utf8");
2762
3238
  } catch (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) });
3239
+ Q.warn(`could not add ${D.join(", ")} to ${C} — add it by hand so the generated directory stays out of git. The build is unaffected.`, { reason: e?.message ?? String(e) });
2764
3240
  }
2765
3241
  }
2766
- }, ca = async (e, t) => {
3242
+ }, $o = async (e, t) => {
2767
3243
  try {
2768
- let n = D(e), r = O(n, "project.json");
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 = [];
3244
+ let n = P(e), r = F(n, "project.json");
3245
+ if (!z(r)) return;
3246
+ let i = await B.readFile(r, "utf8"), a = JSON.parse(i).apps ?? {}, o = e.split("/").filter(Boolean).pop() ?? "", s = [];
2771
3247
  for (let [e, n] of Object.entries(a)) e !== o && n.port === t && s.push(e);
2772
3248
  if (s.length === 0) return;
2773
- Z.warn("sibling app(s) claim the same port — only one boots", {
3249
+ Q.warn("sibling app(s) claim the same port — only one boots", {
2774
3250
  port: t,
2775
3251
  conflicts: s,
2776
3252
  projectJson: r
2777
3253
  });
2778
3254
  } catch {}
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");
3255
+ }, es = (e) => F(e, ".framework", "dist", "server", "appConfig.js"), ts = async (e, t = {}) => {
3256
+ let n = es(e), r = t.preferSource !== !0 && z(n) ? n : F(e, "app.config.ts");
2781
3257
  try {
2782
- let e = (await import(I(r).href)).default;
3258
+ let e = (await import(me(r).href)).default;
2783
3259
  return typeof e == "object" && e && "type" in e && e.type === "web" ? e : null;
2784
3260
  } catch {
2785
3261
  return null;
2786
3262
  }
2787
- }, da = async (e) => {
2788
- let n = await ua(e, { preferSource: !0 });
3263
+ }, ns = (e) => {
3264
+ let t = e.restRoutes;
3265
+ if (t !== void 0 && t.length !== 0) return `app.config.ts declares ${t.length} restRoute(s) on a type:'web' app — REST routes mount on the API process and were silently ignored here, so a health probe hitting one gets the SPA shell (200) and a POST gets 404.\n Move them to the API app's app.config.ts (they mount under the api origin), and call them there;\n for same-origin paths in front of the web app, terminate them at your ingress/proxy instead.`;
3266
+ }, rs = async (e) => {
3267
+ let n = await ts(e, { preferSource: !0 });
2789
3268
  if (!n) return {
2790
3269
  ran: !1,
2791
3270
  exitCode: 0
2792
3271
  };
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", {
3272
+ {
3273
+ let e = ns(n);
3274
+ if (e !== void 0) return Q.error(`voltro dev (web): refusing to boot ${e}`), {
3275
+ ran: !0,
3276
+ exitCode: 1
3277
+ };
3278
+ }
3279
+ hi();
3280
+ let i = kr();
3281
+ qr(i), Q.info("booting voltro dev (web)", { app: n.name ?? "(unnamed)" }), Nt(e, Q);
3282
+ let a = await Go(e, n);
3283
+ for (let e of a) Q.info("api wired", {
2798
3284
  name: e.name,
2799
3285
  pkg: e.pkg,
2800
3286
  ...e.proxyTarget ? { proxyTo: e.proxyTarget } : { directWs: e.browserWsUrl }
2801
3287
  });
2802
- g(e).then((e) => {
3288
+ v(e).then((e) => {
2803
3289
  for (let t of e.files) if (t.action === "created") {
2804
3290
  let e = t.path.split("/").pop() ?? t.path;
2805
- Z.info(`${e} seeded`, { path: t.path });
3291
+ Q.info(`${e} seeded`, { path: t.path });
2806
3292
  }
2807
3293
  }).catch(() => {});
2808
- let { resolved: o } = await Pe({
3294
+ let { resolved: o } = await dt({
2809
3295
  rawEnv: n.env,
2810
3296
  appType: "web",
2811
3297
  root: e,
2812
- log: Z,
3298
+ log: Q,
2813
3299
  generateTypes: !0
2814
3300
  }), s = o.publicValues;
2815
- await sa(e, n, a, s), Z.debug("generated framework entry files", { files: [
3301
+ await Qo(e, n, a, s), Q.debug("generated framework entry files", { files: [
2816
3302
  "index.html",
2817
3303
  ".framework/main.tsx",
2818
3304
  ...n.env ? [".framework/env.public.ts"] : []
@@ -2821,34 +3307,46 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2821
3307
  kind: "web",
2822
3308
  configPort: n.port,
2823
3309
  env: process.env,
2824
- dashboardPin: process.env[br] === "1"
3310
+ dashboardPin: process.env[ji] === "1"
2825
3311
  });
2826
- for (let e of c.warnings) Z.warn(e);
2827
- let l = c.port, y = n.name ?? "unnamed", b = w("web", y, l), D = T(y);
2828
- await x({
2829
- id: b,
2830
- name: y,
3312
+ for (let e of c.warnings) Q.warn(e);
3313
+ let l = c.port, _ = n.name ?? "unnamed", S = se("web", _, l), C = ce(_);
3314
+ await ie({
3315
+ id: S,
3316
+ name: _,
2831
3317
  kind: "web",
2832
3318
  url: `http://localhost:${l}`,
2833
3319
  pid: process.pid,
2834
3320
  status: "booting",
2835
- logFile: D.path
2836
- }).catch(() => {}), await ca(e, l);
2837
- let { pages: j, dirs: P } = await $(O(e, "src", "pages")), F = {
2838
- dirs: P,
2839
- ssrRoutes: qi(j)
2840
- }, ee = P.map((e) => ({
3321
+ logFile: C.path
3322
+ }).catch(() => {}), await $o(e, l);
3323
+ let { pages: w, dirs: T } = await Mo(F(e, "src", "pages")), E = null, D = n.fonts !== void 0 && n.fonts.length > 0 ? dr({
3324
+ root: e,
3325
+ fonts: n.fonts,
3326
+ cache: b(),
3327
+ secret: lr().secret,
3328
+ isOgSsrRoute: (e) => O.ssrRoutes.some((t) => t.pattern === e),
3329
+ getPageModule: async (e) => {
3330
+ let t = O.ssrRoutes.find((t) => t.pattern === e);
3331
+ if (t === void 0 || E === null) return null;
3332
+ let n = await E(t.file), r = y(n, t.file);
3333
+ return r === "ssr" || r === "isr" ? n : null;
3334
+ }
3335
+ }) : null, O = {
3336
+ dirs: T,
3337
+ ssrRoutes: Ro(w)
3338
+ }, k = T.map((e) => ({
2841
3339
  dir: e.dir,
2842
3340
  hasLayout: e.hasLayout,
2843
3341
  hasError: e.hasError,
2844
3342
  hasPending: e.hasPending,
2845
3343
  hasNotFound: e.hasNotFound
2846
- })), te = await un({
3344
+ })), te = await xr({
2847
3345
  appRoot: e,
2848
- pages: j
3346
+ pages: w
2849
3347
  });
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([
3348
+ te.wrote && Q.debug("routes codegen wrote", { path: I(e, te.path) });
3349
+ let A = await it("vite", () => import("vite")), j = (await import("@vitejs/plugin-react")).default, ne = (await import("@tailwindcss/vite")).default, M = F(e, ".framework"), re = F(e, "src"), P = /* @__PURE__ */ new Set([
2852
3350
  ".framework",
2853
3351
  "node_modules",
2854
3352
  "dist",
@@ -2856,36 +3354,36 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2856
3354
  ".vite",
2857
3355
  ".turbo",
2858
3356
  ".cache"
2859
- ]), B = {
3357
+ ]), le = {
2860
3358
  name: "framework:watch-app-sources",
2861
3359
  async configureServer(t) {
2862
3360
  try {
2863
- let n = (await N.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !ie.has(e.name));
2864
- for (let r of n) t.watcher.add(O(e, r.name));
2865
- n.length === 0 && t.watcher.add(R);
3361
+ let n = (await B.readdir(e, { withFileTypes: !0 })).filter((e) => e.isDirectory() && !P.has(e.name));
3362
+ for (let r of n) t.watcher.add(F(e, r.name));
3363
+ n.length === 0 && t.watcher.add(re);
2866
3364
  } catch {
2867
- t.watcher.add(R);
3365
+ t.watcher.add(re);
2868
3366
  }
2869
- for (let n of await Re(e)) t.watcher.add(n.dir);
3367
+ for (let n of await g(e)) t.watcher.add(n.dir);
2870
3368
  }
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) => {
3369
+ }, R = F(e, "src", "pages"), ue = (e) => e.endsWith(".tsx") && (e === R || e.startsWith(R + "/")), V = (e) => e === R || e.startsWith(R + "/"), H = async (t) => {
2872
3370
  try {
2873
3371
  let r = Date.now();
2874
- await sa(e, n, a, s);
2875
- let { pages: i, dirs: o } = await $(V);
2876
- await un({
3372
+ await Qo(e, n, a, s);
3373
+ let { pages: i, dirs: o } = await Mo(R);
3374
+ await xr({
2877
3375
  appRoot: e,
2878
3376
  pages: i
2879
- }), F.dirs = o, F.ssrRoutes = qi(i), Z.info("page tree regenerated", {
3377
+ }), O.dirs = o, O.ssrRoutes = Ro(i), Q.info("page tree regenerated", {
2880
3378
  reason: t,
2881
3379
  ms: Date.now() - r,
2882
- routes: F.ssrRoutes.length
3380
+ routes: O.ssrRoutes.length
2883
3381
  });
2884
- for (let e of di(J, F.ssrRoutes.map((e) => e.pattern))) Z.error(`middleware.ts: ${e.message}`);
3382
+ for (let e of ja(Y, O.ssrRoutes.map((e) => e.pattern))) Q.error(`middleware.ts: ${e.message}`);
2885
3383
  } catch (e) {
2886
- Z.error("page tree regen failed", { reason: t }, e);
3384
+ Q.error("page tree regen failed", { reason: t }, e);
2887
3385
  }
2888
- }, se = {
3386
+ }, de = {
2889
3387
  name: "framework:regenerate-on-page-tree-change",
2890
3388
  configureServer(t) {
2891
3389
  let n = null, r = [], i = (e) => {
@@ -2896,24 +3394,24 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2896
3394
  }, 50);
2897
3395
  };
2898
3396
  t.watcher.on("add", (t) => {
2899
- ae(t) && i(`add ${k(e, t)}`);
3397
+ ue(t) && i(`add ${I(e, t)}`);
2900
3398
  }), t.watcher.on("unlink", (t) => {
2901
- ae(t) && i(`unlink ${k(e, t)}`);
3399
+ ue(t) && i(`unlink ${I(e, t)}`);
2902
3400
  }), t.watcher.on("addDir", (t) => {
2903
- oe(t) && i(`addDir ${k(e, t)}`);
3401
+ V(t) && i(`addDir ${I(e, t)}`);
2904
3402
  }), t.watcher.on("unlinkDir", (t) => {
2905
- oe(t) && i(`unlinkDir ${k(e, t)}`);
3403
+ V(t) && i(`unlinkDir ${I(e, t)}`);
2906
3404
  });
2907
3405
  }
2908
- }, U = O(e, "app.config.ts"), ce = (e) => {
2909
- if (!ue(e.env)) return "";
3406
+ }, U = F(e, "app.config.ts"), fe = (e) => {
3407
+ if (!Ae(e.env)) return "";
2910
3408
  let t = Object.entries(e.env.vars).map(([e, t]) => `${e}:${t.access}`).sort();
2911
3409
  return `${String(e.env.publicPrefix)}|${t.join(",")}`;
2912
- }, le = (e, t) => {
3410
+ }, pe = (e, t) => {
2913
3411
  let n = [];
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)], {
3412
+ 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"), fe(e) !== fe(t) && n.push("env"), n;
3413
+ }, W = n, me = L(U), he = () => {
3414
+ let e = ze(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
2917
3415
  stdio: "inherit",
2918
3416
  env: process.env,
2919
3417
  cwd: process.cwd()
@@ -2923,17 +3421,17 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2923
3421
  process.on("SIGINT", n), process.on("SIGTERM", r), e.on("exit", (e, t) => {
2924
3422
  process.off("SIGINT", n), process.off("SIGTERM", r), t ? process.kill(process.pid, t) : process.exit(e ?? 0);
2925
3423
  }), e.on("error", (e) => {
2926
- Z.error("restart spawn failed", {}, e), process.exit(1);
3424
+ Q.error("restart spawn failed", {}, e), process.exit(1);
2927
3425
  });
2928
- }, pe = {
3426
+ }, G = {
2929
3427
  name: "framework:watch-app-config",
2930
3428
  async configureServer(n) {
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)));
3429
+ n.watcher.add(U), Q.info("watching app.config.ts for changes", { path: I(e, U) });
3430
+ let r = wa.map((t) => F(e, t)), i = new Set(r.map((e) => L(e)));
2933
3431
  for (let e of r) n.watcher.add(e);
2934
3432
  n.watcher.on("all", (t, r) => {
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();
3433
+ i.has(L(r)) && (Q.warn("middleware.ts changed — restarting (it is loaded once per boot)", { path: I(e, r) }), n.close().catch(() => void 0).then(() => {
3434
+ he();
2937
3435
  }));
2938
3436
  });
2939
3437
  let a = async () => {
@@ -2943,9 +3441,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2943
3441
  e && n.moduleGraph.invalidateModule(e);
2944
3442
  } catch {}
2945
3443
  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);
3444
+ 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);
2947
3445
  } catch (e) {
2948
- return Z.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
3446
+ return Q.warn("app.config.ts re-load failed — ignoring this change", {}, e), null;
2949
3447
  }
2950
3448
  }, o = null, s = () => {
2951
3449
  o && clearTimeout(o), o = setTimeout(() => {
@@ -2954,104 +3452,104 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
2954
3452
  }, c = async () => {
2955
3453
  let t = await a();
2956
3454
  if (!t) {
2957
- Z.info("app.config.ts onConfigChange: load returned null — skipping");
3455
+ Q.info("app.config.ts onConfigChange: load returned null — skipping");
2958
3456
  return;
2959
3457
  }
2960
- if (Z.info("app.config.ts onConfigChange: loaded", {
3458
+ if (Q.info("app.config.ts onConfigChange: loaded", {
2961
3459
  theme: t.theme,
2962
3460
  port: t.port,
2963
3461
  name: t.name
2964
3462
  }), JSON.stringify(t) === JSON.stringify(W)) {
2965
- Z.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
3463
+ Q.info("app.config.ts onConfigChange: parsed config unchanged — skipping (no-op edit?)");
2966
3464
  return;
2967
3465
  }
2968
- let r = le(W, t);
3466
+ let r = pe(W, t);
2969
3467
  if (r.length > 0) {
2970
- Z.warn("app.config.ts changed — hard restart required", { fields: r });
3468
+ Q.warn("app.config.ts changed — hard restart required", { fields: r });
2971
3469
  try {
2972
3470
  await n.close();
2973
3471
  } catch {}
2974
- fe();
3472
+ he();
2975
3473
  return;
2976
3474
  }
2977
3475
  try {
2978
3476
  let r = Date.now();
2979
- await sa(e, t, await ea(e, t)), W = t, n.ws && n.ws.send({
3477
+ await Qo(e, t, await Go(e, t)), W = t, n.ws && n.ws.send({
2980
3478
  type: "full-reload",
2981
3479
  path: "*"
2982
- }), Z.info("app.config.ts soft-regen", {
3480
+ }), Q.info("app.config.ts soft-regen", {
2983
3481
  ms: Date.now() - r,
2984
3482
  reload: "full"
2985
3483
  });
2986
3484
  } catch (e) {
2987
- Z.error("app.config.ts soft-regen failed", {}, e);
3485
+ Q.error("app.config.ts soft-regen failed", {}, e);
2988
3486
  }
2989
- }, l = (e) => E(e) === "app.config.ts" ? e === U || A(e) === de : !1;
3487
+ }, l = (e) => N(e) === "app.config.ts" ? e === U || L(e) === me : !1;
2990
3488
  n.watcher.on("change", (e) => {
2991
- l(e) && (Z.info("app.config.ts change event (chokidar)", { file: e }), s());
3489
+ l(e) && (Q.info("app.config.ts change event (chokidar)", { file: e }), s());
2992
3490
  }), n.watcher.on("add", (e) => {
2993
- l(e) && (Z.info("app.config.ts add event (chokidar)", { file: e }), s());
3491
+ l(e) && (Q.info("app.config.ts add event (chokidar)", { file: e }), s());
2994
3492
  });
2995
3493
  try {
2996
3494
  let { watchFile: e } = await import("node:fs");
2997
3495
  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 });
3496
+ e.mtimeMs !== t.mtimeMs && (Q.info("app.config.ts change event (poll)", { mtime: e.mtimeMs }), s());
3497
+ }), Q.info("app.config.ts polling watcher attached", { intervalMs: 500 });
3000
3498
  } catch (e) {
3001
- Z.warn("app.config.ts polling watcher could not attach", {}, e);
3499
+ Q.warn("app.config.ts polling watcher could not attach", {}, e);
3002
3500
  }
3003
- Be(t, Z, {
3501
+ gt(t, Q, {
3004
3502
  root: e,
3005
3503
  onBeforeRestart: () => n.close()
3006
3504
  });
3007
3505
  }
3008
- }, me = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, G = 0, he = {
3506
+ }, _e = /\/apps\/[^/]+\/.*\.(route|mutation|workflow|schema)\.tsx?$/, ve = 0, ye = {
3009
3507
  name: "framework:suppress-api-hmr",
3010
3508
  handleHotUpdate(e) {
3011
- if (G += 1, me.test(e.file)) return [];
3509
+ if (ve += 1, _e.test(e.file)) return [];
3012
3510
  }
3013
- }, ge = {
3511
+ }, be = {
3014
3512
  name: "framework:reoptimize-on-rpcgroup-change",
3015
3513
  async configureServer(t) {
3016
3514
  let n = [];
3017
3515
  for (let r of a) {
3018
- let i = await Yi(e, r.pkg);
3516
+ let i = await Bo(e, r.pkg);
3019
3517
  if (i) {
3020
3518
  n.push(i);
3021
3519
  try {
3022
- t.watcher.add(O(i, "rpcGroup.generated.ts"));
3520
+ t.watcher.add(F(i, "rpcGroup.generated.ts"));
3023
3521
  } catch {}
3024
- for (let e of await ei(i)) try {
3522
+ for (let e of await ba(i)) try {
3025
3523
  t.watcher.add(e);
3026
3524
  } catch {}
3027
3525
  }
3028
3526
  }
3029
3527
  if (n.length === 0) return;
3030
- let r = await ni(n), i = null, o = !1, s = async () => {
3528
+ let r = await Sa(n), i = null, o = !1, s = async () => {
3031
3529
  if (o) return;
3032
- let e = await ni(n);
3530
+ let e = await Sa(n);
3033
3531
  if (e !== void 0 && e !== r) {
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)");
3532
+ r = e, o = !0, Q.info("the api surface changed — re-bundling the api client + reloading (descriptor edits propagate automatically; no manual restart needed)");
3035
3533
  try {
3036
- await N.rm(O(L, ".vite", "deps"), {
3534
+ await B.rm(F(M, ".vite", "deps"), {
3037
3535
  recursive: !0,
3038
3536
  force: !0
3039
3537
  }), await t.restart(!0);
3040
3538
  } catch (e) {
3041
- o = !1, Z.error("rpcGroup re-optimize failed", {}, e);
3539
+ o = !1, Q.error("rpcGroup re-optimize failed", {}, e);
3042
3540
  }
3043
3541
  }
3044
3542
  }, c = (e) => {
3045
- let t = A(e);
3046
- !Qr(t) && !t.endsWith("rpcGroup.generated.ts") || (i && clearTimeout(i), i = setTimeout(() => {
3543
+ let t = L(e);
3544
+ !va(t) && !t.endsWith("rpcGroup.generated.ts") || (i && clearTimeout(i), i = setTimeout(() => {
3047
3545
  s();
3048
3546
  }, 120));
3049
3547
  };
3050
3548
  t.watcher.on("change", c), t.watcher.on("add", c);
3051
3549
  }
3052
- }, K = {}, ve = (e) => (t) => {
3550
+ }, xe = {}, Se = (e) => (t) => {
3053
3551
  t.on("proxyReq", (t, n) => {
3054
- nr(t, n, {
3552
+ pi(t, n, {
3055
3553
  target: e,
3056
3554
  token: process.env.VOLTRO_INSPECT_TOKEN,
3057
3555
  writeToken: process.env.VOLTRO_INSPECT_WRITE_TOKEN,
@@ -3061,59 +3559,59 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3061
3559
  };
3062
3560
  for (let e of a) {
3063
3561
  if (!e.proxyTarget) continue;
3064
- K[e.browserWsUrl] = {
3562
+ xe[e.browserWsUrl] = {
3065
3563
  target: e.proxyTarget,
3066
3564
  ws: !0,
3067
3565
  changeOrigin: !0,
3068
3566
  ...e.wsPath ? {} : { rewrite: () => "/ws" }
3069
3567
  };
3070
3568
  let t = e.proxyTarget.replace(/^ws/, "http");
3071
- K[`/_voltro/api/${e.name}`] = {
3569
+ xe[`/_voltro/api/${e.name}`] = {
3072
3570
  target: t,
3073
3571
  changeOrigin: !0,
3074
3572
  rewrite: (t) => t.replace(RegExp(`^/_voltro/api/${e.name}`), ""),
3075
- configure: ve(t)
3573
+ configure: Se(t)
3076
3574
  };
3077
3575
  }
3078
3576
  for (let [e, t] of Object.entries(n.proxies ?? {})) {
3079
- if (K[e]) {
3080
- Z.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
3577
+ if (xe[e]) {
3578
+ Q.warn("user proxy ignored — prefix already claimed by an api ws proxy", { prefix: e });
3081
3579
  continue;
3082
3580
  }
3083
- K[e] = {
3581
+ xe[e] = {
3084
3582
  target: t.target,
3085
3583
  changeOrigin: t.changeOrigin ?? !0,
3086
3584
  ...t.rewrite === void 0 ? {} : { rewrite: (n) => n.replace(RegExp(`^${e}`), t.rewrite) }
3087
- }, Z.info(`proxy ${e} → ${t.target}`, {
3585
+ }, Q.info(`proxy ${e} → ${t.target}`, {
3088
3586
  prefix: e,
3089
3587
  target: t.target,
3090
3588
  ...t.rewrite === void 0 ? {} : { rewrite: t.rewrite }
3091
3589
  });
3092
3590
  }
3093
- let ye = {
3591
+ let Ce = {
3094
3592
  name: "framework:inspect",
3095
3593
  configureServer(t) {
3096
3594
  let r = null, a = async () => {
3097
3595
  if (r !== null) return r;
3098
3596
  let n = [];
3099
- for (let r of j) try {
3100
- let i = await t.ssrLoadModule(O(e, "src", "pages", r.file));
3597
+ for (let r of w) try {
3598
+ let i = await t.ssrLoadModule(F(e, "src", "pages", r.file));
3101
3599
  n.push({
3102
3600
  pattern: r.pattern,
3103
3601
  file: r.file,
3104
3602
  dirChain: r.dirChain,
3105
- renderMode: _(i, O("src", "pages", r.file)),
3603
+ renderMode: y(i, F("src", "pages", r.file)),
3106
3604
  interactive: i.interactive ?? "full",
3107
3605
  tenantAware: i.tenantAware === !0,
3108
- revalidateMs: v(i.revalidate),
3109
- staleWhileRevalidateMs: v(i.staleWhileRevalidate) ?? 0,
3606
+ revalidateMs: x(i.revalidate),
3607
+ staleWhileRevalidateMs: x(i.staleWhileRevalidate) ?? 0,
3110
3608
  cacheInvalidatesOn: Array.isArray(i.cacheInvalidatesOn) ? i.cacheInvalidatesOn : [],
3111
3609
  hasLoader: typeof i.loader == "function",
3112
3610
  hasMeta: i.meta != null,
3113
3611
  hasGetStaticPaths: typeof i.getStaticPaths == "function"
3114
3612
  });
3115
3613
  } catch (e) {
3116
- Z.warn("inspect: failed to load page metadata", { pattern: r.pattern }, e);
3614
+ Q.warn("inspect: failed to load page metadata", { pattern: r.pattern }, e);
3117
3615
  }
3118
3616
  return r = n, n;
3119
3617
  };
@@ -3133,9 +3631,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3133
3631
  }), n();
3134
3632
  }), t.middlewares.use((t, n, r) => {
3135
3633
  if (t.method !== "GET" && t.method !== "HEAD") return r();
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 }));
3634
+ let { pathname: i } = Ji(t.url ?? "/");
3635
+ if (i !== "/robots.txt" || z(F(e, "public", "robots.txt"))) return r();
3636
+ n.statusCode = 200, n.setHeader("Content-Type", "text/plain; charset=utf-8"), n.end(Dr({ indexable: !1 }));
3139
3637
  }), n.name === "voltroDashboard" && t.middlewares.use(async (e, t, n) => {
3140
3638
  let r = e.url ?? "", i = r.split("?")[0];
3141
3639
  if (i === "/api/dashboard/proxy") {
@@ -3226,7 +3724,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3226
3724
  for (let [t, n] of Object.entries(e.headers ?? {})) n !== void 0 && (s[String(t).toLowerCase()] = Array.isArray(n) ? n.join(", ") : String(n));
3227
3725
  let c = o.split("?")[0];
3228
3726
  if (e.method === "GET" && (c === "/_voltro/inspect/logs" || o.startsWith("/_voltro/inspect/logs?"))) {
3229
- let e = d(s.origin), n = Xn(o, jn(), s);
3727
+ let e = d(s.origin), n = si(o, Hr(), s);
3230
3728
  t.statusCode = n.status, t.setHeader("content-type", n.contentType);
3231
3729
  for (let [n, r] of Object.entries(e)) t.setHeader(n, r);
3232
3730
  t.end(n.body);
@@ -3244,7 +3742,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3244
3742
  e.setEncoding("utf-8"), e.on("data", (e) => {
3245
3743
  r += e;
3246
3744
  }), e.on("end", () => {
3247
- let e = Wn(r, i);
3745
+ let e = ti(r, i);
3248
3746
  t.statusCode = e.status, t.setHeader("content-type", e.contentType);
3249
3747
  for (let [e, r] of Object.entries(n)) t.setHeader(e, r);
3250
3748
  t.end(e.body);
@@ -3275,14 +3773,14 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3275
3773
  for (let [e, r] of Object.entries(n)) t.setHeader(e, r);
3276
3774
  t.flushHeaders?.(), t.write("retry: 5000\n\n");
3277
3775
  let a = o.indexOf("?");
3278
- if (a === -1 || new URLSearchParams(o.slice(a + 1)).get("live") !== "1") for (let e of i.buffered()) t.write(yn(e));
3776
+ if (a === -1 || new URLSearchParams(o.slice(a + 1)).get("live") !== "1") for (let e of i.buffered()) t.write(Ar(e));
3279
3777
  let c = i.subscribe((e) => {
3280
3778
  try {
3281
- t.write(yn(e));
3779
+ t.write(Ar(e));
3282
3780
  } catch {}
3283
3781
  }), l = setInterval(() => {
3284
3782
  try {
3285
- t.write(bn());
3783
+ t.write(jr());
3286
3784
  } catch {}
3287
3785
  }, 15e3), p = () => {
3288
3786
  clearInterval(l), c();
@@ -3295,7 +3793,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3295
3793
  kind: "web",
3296
3794
  meta: {
3297
3795
  name: n.name ?? "(unnamed)",
3298
- voltroVersion: Di,
3796
+ voltroVersion: go,
3299
3797
  port: l,
3300
3798
  mode: "dev",
3301
3799
  apis: Object.entries(n.apis ?? {}).map(([e, t]) => {
@@ -3307,13 +3805,13 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3307
3805
  })
3308
3806
  },
3309
3807
  routes: await a(),
3310
- dirs: ee,
3808
+ dirs: k,
3311
3809
  cache: () => ({
3312
3810
  backend: "memory",
3313
3811
  size: 0,
3314
3812
  entries: []
3315
3813
  }),
3316
- env: () => Fe(n.name ?? "app", { contract: ue(n.env) ? n.env : void 0 })
3814
+ env: () => pt(n.name ?? "app", { contract: Ae(n.env) ? n.env : void 0 })
3317
3815
  }, c = p(o, i, s, { method: e.method ?? "GET" });
3318
3816
  if (c === null) return r();
3319
3817
  t.statusCode = c.status, t.setHeader("content-type", c.contentType);
@@ -3324,25 +3822,25 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3324
3822
  }
3325
3823
  });
3326
3824
  }
3327
- }, be = n.name === "voltroDashboard" ? {
3825
+ }, we = n.name === "voltroDashboard" ? {
3328
3826
  name: "framework:dashboard-registry",
3329
3827
  configureServer(e) {
3330
3828
  e.middlewares.use(async (e, t, n) => {
3331
3829
  if (!(e.url ?? "").startsWith("/api/dashboard/registry")) return n();
3332
3830
  try {
3333
- let e = await S();
3831
+ let e = await ae();
3334
3832
  t.statusCode = 200, t.setHeader("content-type", "application/json; charset=utf-8"), t.end(JSON.stringify(e));
3335
3833
  } catch (e) {
3336
3834
  t.statusCode = 500, t.setHeader("content-type", "text/plain"), t.end(`registry read error: ${e.message}`);
3337
3835
  }
3338
3836
  });
3339
3837
  }
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`, {
3838
+ } : null, Te = /* @__PURE__ */ new Set(), Ee = (e, t, n, r, i, a = !1) => {
3839
+ let o = ta(i, a, t) ?? "";
3840
+ if (Q.error(`${t} render failed`, {
3343
3841
  pathname: n,
3344
3842
  pattern: r,
3345
- cause: Sn(i) + o
3843
+ cause: Nr(i) + o
3346
3844
  }), e.headersSent) {
3347
3845
  e.end();
3348
3846
  return;
@@ -3350,33 +3848,33 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3350
3848
  e.writeHead(500, {
3351
3849
  "content-type": "text/plain; charset=utf-8",
3352
3850
  "x-voltro-rendered-by": `${t}-failed`,
3353
- "x-voltro-ssr-generation": String(G)
3851
+ "x-voltro-ssr-generation": String(ve)
3354
3852
  });
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({
3358
- limit: we,
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`, {
3853
+ let s = ve === 0 ? "" : `\n[voltro] this process has absorbed ${ve} 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`;
3854
+ e.end(`${t} render failed for ${n}\n\n${Nr(i)}\n${o}\n${s}`);
3855
+ }, De = Gt(), Oe = qt({
3856
+ limit: De,
3857
+ onColdStart: (e) => Q.debug("ssr cold-compile start", { id: e }),
3858
+ onColdEnd: (e, { durationMs: t, failed: n }) => Q.debug(`ssr cold-compile ${n ? "FAILED" : "end"} ${t}ms`, {
3361
3859
  id: e,
3362
3860
  ms: t,
3363
3861
  ...n ? { failed: !0 } : {}
3364
3862
  })
3365
3863
  });
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 = {
3864
+ Q.debug(`ssr cold-compile concurrency ${De}`, { concurrency: De });
3865
+ let ke = null, je = async () => (ke === null && (ke = await B.readFile(F(e, ".framework", "index.html"), "utf8")), ke), Me = {
3368
3866
  name: "framework:ssr",
3369
3867
  configureServer(t) {
3370
- let r = (e) => Te.load(e, async () => await t.ssrLoadModule(e)), i, o = !1, s = () => {
3868
+ let r = (e) => Oe.load(e, async () => await t.ssrLoadModule(e)), i, o = !1, s = () => {
3371
3869
  if (i !== void 0) return i;
3372
3870
  let t = n.locales ?? [], a = n.defaultLocale ?? t[0] ?? "en";
3373
3871
  return t.length === 0 ? (i = Promise.resolve(() => void 0), i) : (i = (async () => {
3374
3872
  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;
3873
+ for (let n of t) if (z(F(e, "src", "locales", `${n}.ts`))) try {
3874
+ let t = (await r(F(e, "src", "locales", `${n}.ts`))).default;
3377
3875
  t !== void 0 && (c[n] = i(n, t, a));
3378
3876
  } catch (e) {
3379
- Z.warn("locale catalog failed to load for SSR", { locale: n }, e);
3877
+ Q.warn("locale catalog failed to load for SSR", { locale: n }, e);
3380
3878
  }
3381
3879
  if (o = Object.keys(c).length > 0, Object.keys(c).length === 0) {
3382
3880
  let { resolveLocale: e, resolveTimeZone: i } = await r("@voltro/i18n/server");
@@ -3403,62 +3901,92 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3403
3901
  defaultTimeZone: n.defaultTimeZone ?? null
3404
3902
  });
3405
3903
  })(), i);
3406
- }, c = Dt({
3904
+ }, c = on({
3407
3905
  apiName: a[0]?.name,
3408
- apiOrigin: ia(a[0], { allowDevProxy: !0 }),
3906
+ apiOrigin: Yo(a[0], { allowDevProxy: !0 }),
3409
3907
  loadDescriptors: async () => {
3410
3908
  let e = a[0];
3411
3909
  if (e !== void 0) return (await r(`${e.pkg}/rpcGroup`)).appDescriptors;
3412
3910
  },
3413
- rpcQuery: (e, t) => aa(ia(a[0], { allowDevProxy: !0 }), e, {
3911
+ rpcQuery: (e, t) => Xo(Yo(a[0], { allowDevProxy: !0 }), e, {
3414
3912
  apiName: a[0]?.name,
3415
3913
  headers: t
3416
3914
  }),
3915
+ resolveLocale: async (e, t) => {
3916
+ let r = tn(t, n.locales);
3917
+ return r === void 0 ? (await s())(e.cookie, e["accept-language"])?.locale ?? "en" : r;
3918
+ },
3417
3919
  renderErrorPage: async () => void 0
3418
3920
  });
3419
3921
  t.middlewares.use((e, t, n) => {
3420
- if (!(e.url ?? "/").split("?")[0].startsWith(xe)) return n();
3922
+ if (!(e.url ?? "/").split("?")[0].startsWith(Ue)) return n();
3421
3923
  c(e, t, (t, r) => {
3422
3924
  e.url = t, e.method = "GET", e.__voltroFormFlash = r, n();
3423
3925
  }).then((e) => {
3424
3926
  e || n();
3425
3927
  });
3928
+ }), E = async (n) => await t.ssrLoadModule(F(e, "src", "pages", n)), t.middlewares.use(async (e, t, n) => {
3929
+ let r = e.url ?? "/";
3930
+ if (!r.startsWith("/_voltro/og") || D === null) return n();
3931
+ try {
3932
+ let e = await D.handle(new URL(r, "http://localhost"));
3933
+ if (e === null) return n();
3934
+ t.statusCode = e.status;
3935
+ for (let [n, r] of Object.entries(e.headers)) t.setHeader(n, r);
3936
+ t.end(Buffer.from(e.body));
3937
+ } catch (e) {
3938
+ t.statusCode = 500, t.setHeader("content-type", "text/plain"), t.end(`og render error: ${e.message}`);
3939
+ }
3426
3940
  }), t.middlewares.use(async (i, c, l) => {
3427
3941
  if (i.method !== "GET" && i.method !== "HEAD") return l();
3428
3942
  let u = i.url ?? "/";
3429
3943
  u.indexOf("?");
3430
- let { pathname: d, search: f } = $t(u), p = i.__voltroFormFlash;
3944
+ let { pathname: d, search: f } = Ji(u), p = i.__voltroFormFlash;
3431
3945
  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();
3432
3946
  let m = async () => {
3433
- if (J.length === 0) return;
3434
- let e = ui(J, {
3947
+ if (Y.length === 0) return;
3948
+ let e = Aa(Y, {
3435
3949
  route: void 0,
3436
3950
  pathname: d
3437
3951
  });
3438
3952
  if (e === void 0) return;
3439
3953
  let t = {};
3440
3954
  for (let [e, n] of Object.entries(i.headers ?? {})) typeof n == "string" ? t[e] = n : Array.isArray(n) && (t[e] = n.join(", "));
3441
- let n = await bi(e, {
3955
+ let n = await Ba(e, {
3442
3956
  pathname: d,
3443
3957
  search: f,
3444
3958
  headers: t,
3445
- cookies: pi(t.cookie),
3959
+ cookies: Na(t.cookie),
3446
3960
  route: void 0
3447
3961
  });
3448
- for (let e of n.setCookies) c.appendHeader("set-cookie", _i(e));
3962
+ for (let e of n.setCookies) c.appendHeader("set-cookie", La(e));
3449
3963
  };
3450
3964
  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}`, {
3965
+ let h = zo(d, O.ssrRoutes), g = !1;
3966
+ if (!h) {
3967
+ let e = _o(O.dirs, d);
3968
+ if (e === void 0) return await m(), l();
3969
+ g = !0, h = {
3970
+ route: {
3971
+ pattern: "<not-found>",
3972
+ file: e.dir === "" ? "not-found.tsx" : `${e.dir}/not-found.tsx`,
3973
+ dirChain: e.chain,
3974
+ regex: /^$/,
3975
+ paramNames: [],
3976
+ priority: 2 ** 53 - 1
3977
+ },
3978
+ params: {}
3979
+ };
3980
+ }
3981
+ let _ = !Te.has(h.route.pattern), v = Date.now();
3982
+ _ && Q.info(`ssr compiling ${h.route.pattern}`, {
3455
3983
  pattern: h.route.pattern,
3456
3984
  pathname: d
3457
3985
  });
3458
- let y = {}, b = async (e, t) => {
3986
+ let b = {}, x = async (e, t) => {
3459
3987
  let n = Date.now(), r = await t();
3460
- return y[e] = (y[e] ?? 0) + (Date.now() - n), r;
3461
- }, x = async (e, n, r) => {
3988
+ return b[e] = (b[e] ?? 0) + (Date.now() - n), r;
3989
+ }, S = async (e, n, r) => {
3462
3990
  let i = await t.moduleGraph.getModuleById(e);
3463
3991
  if (!(!i || n.has(e))) {
3464
3992
  if (n.add(e), i.id && /\.(css|sass|scss|less|stylus|pcss|postcss)(\?|$)/.test(i.id)) {
@@ -3466,293 +3994,329 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3466
3994
  r.includes(e) || r.push(e);
3467
3995
  return;
3468
3996
  }
3469
- for (let e of i.importedModules ?? []) e.id && await x(e.id, n, r);
3997
+ for (let e of i.importedModules ?? []) e.id && await S(e.id, n, r);
3470
3998
  }
3471
- }, S = !1;
3999
+ }, C = !1;
3472
4000
  try {
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, {
4001
+ let w = await x("loadPage", async () => await r(F(e, "src", "pages", h.route.file))), T = g ? "ssr" : y(w, F("src", "pages", h.route.file)), E = No(O.dirs, h.route.dirChain), ee = T === "spa" && E.some((e) => e.hasLayout), k = w.interactive ?? "full";
4002
+ if (T !== "ssr" && T !== "isr" && !ee && k !== "islands") return await m(), l();
4003
+ let te = {};
4004
+ for (let [e, t] of Object.entries(i.headers ?? {})) typeof t == "string" ? te[e] = t : Array.isArray(t) && (te[e] = t.join(", "));
4005
+ let A = await Ba(Aa(Y, {
3478
4006
  route: h.route.pattern,
3479
4007
  pathname: d
3480
4008
  }), {
3481
4009
  pathname: d,
3482
4010
  search: f,
3483
- headers: k,
3484
- cookies: pi(k.cookie),
4011
+ headers: te,
4012
+ cookies: Na(te.cookie),
3485
4013
  route: h.route.pattern
3486
- }, Ve);
3487
- for (let e of A.setCookies) c.appendHeader("set-cookie", _i(e));
4014
+ }, Re);
4015
+ for (let e of A.setCookies) c.appendHeader("set-cookie", La(e));
3488
4016
  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, {
4017
+ if (T === "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.`);
4018
+ let j = T === "isr" ? Wa(A.headers) : A.headers, ne = T === "isr" && w.ppr === !0, M = ne ? uo(j, h.route.pattern) : j, re = Xo(Yo(a[0], { allowDevProxy: !0 }), j.cookie, {
3491
4019
  apiName: a[0]?.name,
3492
4020
  headers: j
3493
- }), P = new AbortController(), ee = () => P.abort();
3494
- c.once("close", ee);
3495
- let te = null, ne = [], re = {};
4021
+ }), ie = new AbortController(), ae = () => ie.abort();
4022
+ c.once("close", ae);
4023
+ let oe = null, se = [], ce = {};
3496
4024
  try {
3497
- (await r("@voltro/web/ssr")).beginStoreSeeds(), {chain: ne, segmentLoaderData: re} = await b("loadChain", () => Ui({
3498
- entries: T,
3499
- loadLayout: (t) => r(O(e, "src", "pages", t.dir, "layout.tsx")),
3500
- loadError: (t) => r(O(e, "src", "pages", t.dir, "error.tsx")),
3501
- loadPending: (t) => r(O(e, "src", "pages", t.dir, "loading.tsx")),
4025
+ (await r("@voltro/web/ssr")).beginStoreSeeds(), {chain: se, segmentLoaderData: ce} = await x("loadChain", () => Po({
4026
+ entries: E,
4027
+ loadLayout: (t) => r(F(e, "src", "pages", t.dir, "layout.tsx")),
4028
+ loadError: (t) => r(F(e, "src", "pages", t.dir, "error.tsx")),
4029
+ loadPending: (t) => r(F(e, "src", "pages", t.dir, "loading.tsx")),
3502
4030
  ctx: {
3503
4031
  params: h.params,
3504
4032
  pathname: d,
3505
4033
  search: f,
3506
- signal: P.signal,
3507
- headers: j,
3508
- query: M,
4034
+ signal: ie.signal,
4035
+ headers: M,
4036
+ query: re,
3509
4037
  isServer: !0
3510
4038
  }
3511
4039
  }));
3512
- let t = C.loader;
3513
- typeof t == "function" && !E && (te = await b("loader", () => t({
4040
+ let t = w.loader;
4041
+ typeof t == "function" && !ee && (oe = await x("loader", () => t({
3514
4042
  params: h.params,
3515
4043
  pathname: d,
3516
4044
  search: f,
3517
- signal: P.signal,
3518
- headers: j,
3519
- query: M,
4045
+ signal: ie.signal,
4046
+ headers: M,
4047
+ query: re,
3520
4048
  isServer: !0
3521
4049
  })));
3522
4050
  } finally {
3523
- c.off("close", ee);
4051
+ c.off("close", ae);
3524
4052
  }
3525
- let I = await b("loadSsrHelpers", async () => await r("@voltro/web/ssr"));
3526
- E || await Zr({
3527
- pageMod: C,
4053
+ let N = await x("loadSsrHelpers", async () => await r("@voltro/web/ssr"));
4054
+ ee || await _a({
4055
+ pageMod: w,
3528
4056
  params: h.params,
3529
- query: M,
4057
+ query: re,
3530
4058
  apiName: a[0]?.name,
3531
- seed: I.seedPreloadedSubscription,
3532
- seedFailure: I.seedPreloadedSubscriptionFailure,
3533
- onError: ({ tag: e, apiName: t }, n) => Z.warn("preload seed failed", {
4059
+ seed: N.seedPreloadedSubscription,
4060
+ seedFailure: N.seedPreloadedSubscriptionFailure,
4061
+ onError: ({ tag: e, apiName: t }, n) => Q.warn("preload seed failed", {
3534
4062
  tag: e,
3535
4063
  apiName: t,
3536
4064
  pathname: d
3537
4065
  }, n)
3538
4066
  });
3539
- let L = {
4067
+ let P = {
3540
4068
  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,
4069
+ Component: w.default,
4070
+ meta: w.meta,
4071
+ loader: w.loader,
4072
+ ErrorBoundary: w.ErrorBoundary,
4073
+ Pending: w.Pending,
4074
+ renderMode: T,
4075
+ chain: se
4076
+ }, le = {
4077
+ cookies: ne ? fo(Ga(A.cookies), h.route.pattern) : T === "isr" ? Ga(A.cookies) : A.cookies,
4078
+ headers: M,
3551
4079
  url: u,
3552
4080
  ...p === void 0 ? {} : { formFlash: p }
3553
- }, z = (await s())(j.cookie, j["accept-language"]);
3554
- S = z !== void 0 && o;
3555
- let ie = z ? {
3556
- outerWrap: z.outerWrap,
3557
- locale: z.locale
3558
- } : {}, B = E ? Yt({
3559
- helpers: I,
4081
+ }, I = (await s())(j.cookie, j["accept-language"]);
4082
+ C = I !== void 0 && o;
4083
+ let L = I ? {
4084
+ outerWrap: I.outerWrap,
4085
+ locale: I.locale
4086
+ } : {}, R = ee ? Gi({
4087
+ helpers: N,
3560
4088
  page: `src/pages/${h.route.file}`,
3561
- interactive: D,
4089
+ interactive: k,
3562
4090
  delivery: "stream",
3563
4091
  renderInput: {
3564
- descriptor: L,
4092
+ descriptor: P,
3565
4093
  params: h.params,
3566
4094
  pathname: d,
3567
4095
  search: f,
3568
- segmentLoaderData: re,
3569
- requestContext: R,
3570
- ...ie
4096
+ segmentLoaderData: ce,
4097
+ requestContext: le,
4098
+ ...L
3571
4099
  }
3572
- }) : null, V = E ? null : Jt({
3573
- helpers: I,
4100
+ }) : null, z = ee ? null : Wi({
4101
+ helpers: N,
3574
4102
  page: `src/pages/${h.route.file}`,
3575
4103
  pathname: d,
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 () => {
4104
+ renderMode: T,
4105
+ interactive: k,
4106
+ loaderData: oe,
4107
+ segmentLoaderData: ce,
4108
+ pageLoaderRan: typeof w.loader == "function",
4109
+ ...ne ? { ppr: !0 } : {}
4110
+ });
4111
+ ne && z !== null && mo(z.stateInput, h.route.pattern);
4112
+ let ue = [];
4113
+ await x("collectCss", async () => {
3583
4114
  let t = /* @__PURE__ */ new Set(), n = [
3584
- O(e, "src", "pages", h.route.file),
3585
- ...T.flatMap((t) => [
3586
- ...t.hasLayout ? [O(e, "src", "pages", t.dir, "layout.tsx")] : [],
3587
- ...t.hasError ? [O(e, "src", "pages", t.dir, "error.tsx")] : [],
3588
- ...t.hasPending ? [O(e, "src", "pages", t.dir, "loading.tsx")] : []
4115
+ F(e, "src", "pages", h.route.file),
4116
+ ...E.flatMap((t) => [
4117
+ ...t.hasLayout ? [F(e, "src", "pages", t.dir, "layout.tsx")] : [],
4118
+ ...t.hasError ? [F(e, "src", "pages", t.dir, "error.tsx")] : [],
4119
+ ...t.hasPending ? [F(e, "src", "pages", t.dir, "loading.tsx")] : []
3589
4120
  ]),
3590
- O(e, ".framework", "main.tsx")
4121
+ F(e, ".framework", "main.tsx")
3591
4122
  ];
3592
- for (let e of n) await x(e, t, ae);
4123
+ for (let e of n) await S(e, t, ue);
3593
4124
  });
3594
- let oe = (D === "islands" ? await b("islandsEntry", async () => {
3595
- let t = oa(a, "../../app.config"), n = (await Wt({
4125
+ let V = (k === "islands" ? await x("islandsEntry", async () => {
4126
+ let t = Zo(a, "../../app.config"), n = (await Cn({
3596
4127
  webRoot: e,
3597
4128
  pages: [{
3598
4129
  pattern: h.route.pattern,
3599
4130
  file: h.route.file
3600
4131
  }],
3601
- headSnippets: zt(await Oe()),
4132
+ headSnippets: vn(await je()),
3602
4133
  apiImports: t.imports,
3603
4134
  apiEntriesLiteral: `[\n${t.providerEntryLines.join("\n")}\n ]`
3604
4135
  }))[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 = {
4136
+ return n === void 0 ? void 0 : await B.readFile(F(e, ".framework", n.htmlFile), "utf8");
4137
+ }) : void 0) ?? await x("readShell", je), H = await x("transformShell", () => t.transformIndexHtml(u, V)), de = ue.map((e) => `<link rel="stylesheet" href="${e}?direct" />`).join("\n "), U = I?.locale ?? le.cookies["voltro:locale"] ?? n.defaultLocale ?? (n.locales ?? [])[0] ?? "en", fe = Date.now(), pe = {
3607
4138
  lang: U,
3608
- ...z?.timeZone === void 0 ? {} : { timeZone: z.timeZone },
3609
- renderedAt: ce
4139
+ ...I?.timeZone === void 0 ? {} : { timeZone: I.timeZone },
4140
+ renderedAt: fe
3610
4141
  };
3611
- if (B) {
3612
- let e = (e) => Zt({
3613
- helpers: I,
3614
- prepared: B,
4142
+ if (R) {
4143
+ let e = (e) => qi({
4144
+ helpers: N,
4145
+ prepared: R,
3615
4146
  meta: e,
3616
- interactive: D,
3617
- extra: [se]
4147
+ interactive: k,
4148
+ extra: [de]
3618
4149
  });
3619
- if (B.hasDeferred) Jr({
4150
+ if (R.hasDeferred) ma({
3620
4151
  res: c,
3621
- shell: Ur({
4152
+ shell: ca({
3622
4153
  shell: H,
3623
4154
  inlineModuleScriptsAsync: !0
3624
4155
  }),
3625
- documentAttrs: le,
4156
+ documentAttrs: pe,
3626
4157
  headers: {
3627
4158
  "content-type": "text/html; charset=utf-8",
3628
4159
  "x-voltro-rendered-by": "spa-shell-dev"
3629
4160
  },
3630
4161
  headInjection: e,
3631
- render: (e) => I.renderPageToStream({
3632
- ...B.renderInput,
3633
- ...e
4162
+ ...A.cspNonce === void 0 ? {} : { nonce: A.cspNonce },
4163
+ render: (e) => N.renderPageToStream({
4164
+ ...R.renderInput,
4165
+ ...e,
4166
+ ...A.cspNonce === void 0 ? {} : { nonce: A.cspNonce }
3634
4167
  }),
3635
4168
  onShellError: (e) => {
3636
- Ce(c, "spa-shell-dev", d, h.route.pattern, e, S);
4169
+ Ee(c, "spa-shell-dev", d, h.route.pattern, e, C);
3637
4170
  }
3638
4171
  });
3639
4172
  else {
3640
- let t = Xt({
3641
- helpers: I,
3642
- prepared: B
3643
- }), n = Kr(H.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`), le);
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);
4173
+ let t = Ki({
4174
+ helpers: N,
4175
+ prepared: R
4176
+ }), n = fa(H.replace("<div id=\"root\"></div>", `<div id="root">${t.body}</div>`).replace("</head>", ` ${e(t.meta)}\n </head>`), pe);
4177
+ c.statusCode = 200, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", "spa-shell-dev"), c.end(A.cspNonce === void 0 ? n : ua(n, A.cspNonce));
3645
4178
  }
3646
- } else if (V) {
3647
- let e = (e) => [
3648
- se,
3649
- I.renderMetaToHtml(e),
3650
- `<meta name="voltro-interactive" content="${D}" />`,
3651
- ...V.hasDeferred ? [I.renderDeferredRegistryScript()] : [],
3652
- I.renderRouterStateScript(V.stateInput)
3653
- ].filter((e) => e.length > 0).join("\n "), t = {
3654
- descriptor: L,
4179
+ } else if (z) {
4180
+ let e = (e) => {
4181
+ if (D === null || T !== "ssr" && T !== "isr" || typeof w.ogImage != "function" || e.includes("og:image")) return "";
4182
+ let t = i.headers["x-tenant"], n = D.signOgUrl({
4183
+ pattern: h.route.pattern,
4184
+ params: h.params,
4185
+ ...typeof t == "string" ? { tenant: t } : {}
4186
+ });
4187
+ return `<meta property="og:image" content="${n}" /><meta name="twitter:image" content="${n}" /><meta name="twitter:card" content="summary_large_image" />`;
4188
+ }, t = (t) => [
4189
+ de,
4190
+ N.renderMetaToHtml(t) + e(N.renderMetaToHtml(t)),
4191
+ `<meta name="voltro-interactive" content="${k}" />`,
4192
+ ...z.hasDeferred ? [N.renderDeferredRegistryScript()] : [],
4193
+ N.renderRouterStateScript(z.stateInput)
4194
+ ].filter((e) => e.length > 0).join("\n "), n = {
4195
+ descriptor: P,
3655
4196
  params: h.params,
3656
4197
  pathname: d,
3657
4198
  search: f,
3658
- loaderData: V.loaderData,
3659
- segmentLoaderData: V.segmentLoaderData,
3660
- requestContext: R,
3661
- ...ie
4199
+ loaderData: z.loaderData,
4200
+ segmentLoaderData: z.segmentLoaderData,
4201
+ requestContext: le,
4202
+ ...L
3662
4203
  };
3663
- if (w === "ssr" && D === "full" && p === void 0) Jr({
4204
+ if (T === "ssr" && k === "full" && p === void 0) ma({
3664
4205
  res: c,
3665
- shell: Ur({
4206
+ shell: ca({
3666
4207
  shell: H,
3667
4208
  inlineModuleScriptsAsync: !0
3668
4209
  }),
3669
- documentAttrs: le,
4210
+ documentAttrs: pe,
3670
4211
  headers: {
3671
4212
  "content-type": "text/html; charset=utf-8",
3672
4213
  "x-voltro-rendered-by": "ssr-dev"
3673
4214
  },
3674
- headInjection: e,
3675
- render: (e) => I.renderPageToStream({
3676
- ...t,
4215
+ headInjection: t,
4216
+ ...A.cspNonce === void 0 ? {} : { nonce: A.cspNonce },
4217
+ render: (e) => N.renderPageToStream({
4218
+ ...n,
3677
4219
  ...e,
3678
4220
  ...A.cspNonce === void 0 ? {} : { nonce: A.cspNonce }
3679
4221
  }),
3680
4222
  onShellError: (e) => {
3681
- Ce(c, "ssr-dev", d, h.route.pattern, e, S);
4223
+ Ee(c, "ssr-dev", d, h.route.pattern, e, C);
3682
4224
  }
3683
4225
  });
3684
4226
  else {
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));
4227
+ let { html: e, meta: r } = N.renderPageToHtml(n), i = fa(H.replace("<div id=\"root\"></div>", `<div id="root">${e}</div>`).replace("</head>", ` ${t(r)}\n </head>`), pe);
4228
+ c.statusCode = p === void 0 ? g ? 404 : 200 : 422, c.setHeader("content-type", "text/html; charset=utf-8"), c.setHeader("x-voltro-rendered-by", g ? "ssr-not-found" : "ssr-dev"), p !== void 0 && c.setHeader("cache-control", "no-store");
4229
+ let o = p === void 0 ? i : Zt(i, p);
4230
+ if (ne && p === void 0 && typeof w.loader == "function") {
4231
+ c.setHeader("x-voltro-ppr", "shell+holes"), to(h.route.pattern), c.write(o);
4232
+ let e = Xo(Yo(a[0], { allowDevProxy: !0 }), A.headers.cookie, {
4233
+ apiName: a[0]?.name,
4234
+ headers: A.headers
4235
+ }), t = new AbortController();
4236
+ await po({
4237
+ loader: w.loader,
4238
+ ctx: {
4239
+ params: h.params,
4240
+ pathname: d,
4241
+ search: f,
4242
+ signal: t.signal,
4243
+ headers: A.headers,
4244
+ query: e,
4245
+ isServer: !0
4246
+ },
4247
+ res: c,
4248
+ helpers: N,
4249
+ page: h.route.pattern,
4250
+ log: Q
4251
+ });
4252
+ } else c.end(A.cspNonce === void 0 ? o : ua(o, A.cspNonce));
3689
4253
  }
3690
4254
  }
3691
- y.render = Date.now() - ce;
4255
+ b.render = Date.now() - fe;
3692
4256
  let W = Date.now() - v;
3693
- g ? (Se.add(h.route.pattern), Z.info(`ssr compiled ${h.route.pattern} in ${W}ms`, {
4257
+ _ ? (Te.add(h.route.pattern), Q.info(`ssr compiled ${h.route.pattern} in ${W}ms`, {
3694
4258
  pattern: h.route.pattern,
3695
4259
  pathname: d,
3696
4260
  elapsedMs: W,
3697
4261
  cold: !0,
3698
- phases: y
3699
- })) : W > 200 && Z.info(`ssr rendered ${d} in ${W}ms`, {
4262
+ phases: b
4263
+ })) : W > 200 && Q.info(`ssr rendered ${d} in ${W}ms`, {
3700
4264
  pattern: h.route.pattern,
3701
4265
  pathname: d,
3702
4266
  elapsedMs: W,
3703
4267
  cold: !1,
3704
- phases: y
4268
+ phases: b
3705
4269
  });
3706
4270
  } catch (e) {
3707
- if (Kt(e)) {
3708
- Z.error("ssr-dev render refused", {
4271
+ if (Hi(e)) {
4272
+ Q.error("ssr-dev render refused", {
3709
4273
  pathname: d,
3710
4274
  pattern: h.route.pattern
3711
4275
  }, e), c.statusCode = 500, c.setHeader("content-type", "text/plain; charset=utf-8"), c.end(e.message);
3712
4276
  return;
3713
4277
  }
3714
- let t = qt(e);
4278
+ let t = Ui(e);
3715
4279
  if (t) {
3716
4280
  c.statusCode = t.status;
3717
4281
  for (let [e, n] of Object.entries(t.headers)) c.setHeader(e, String(n));
3718
4282
  c.end(t.body);
3719
4283
  return;
3720
4284
  }
3721
- Ce(c, "ssr-dev", d, h.route.pattern, e, S);
4285
+ Ee(c, "ssr-dev", d, h.route.pattern, e, C);
3722
4286
  }
3723
4287
  });
3724
4288
  }
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 () => {
4289
+ }, Ne = Date.now(), Pe = A.version ?? "?", K = await vo(), Fe = F(e, "node_modules", "@voltro", "ui-shadcn"), q = z(F(Fe, "package.json")) ? Fe : null, J = [], Ie = await (async () => {
3726
4290
  let t = [];
3727
4291
  for (let n of a) {
3728
- let r = await Yi(e, n.pkg);
4292
+ let r = await Bo(e, n.pkg);
3729
4293
  r && t.push(r);
3730
4294
  }
3731
- let n = await ni(t);
4295
+ let n = await Sa(t);
3732
4296
  if (n === void 0) return !1;
3733
- let r = O(L, ".voltro-rpcgroup-optimize"), i = "";
4297
+ let r = F(M, ".voltro-rpcgroup-optimize"), i = "";
3734
4298
  try {
3735
- i = (await N.readFile(r, "utf8")).trim();
4299
+ i = (await B.readFile(r, "utf8")).trim();
3736
4300
  } catch {}
3737
4301
  if (i === n) return !1;
3738
4302
  try {
3739
- await N.writeFile(r, n);
4303
+ await B.writeFile(r, n);
3740
4304
  } catch {}
3741
4305
  return !0;
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`, {
4306
+ })(), Le = /* @__PURE__ */ new Set(), Re = (e) => {
4307
+ Le.has(e.name) || (Le.add(e.name), Q.warn(`middleware.ts wrote the cookie "${e.name}" with the HttpOnly default — a browser SDK cannot read it`, {
3744
4308
  cookie: e.name,
3745
4309
  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."
3746
4310
  }));
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");
4311
+ }, Y = await za(e);
4312
+ Y.length > 0 && Q.info(`middleware.ts loaded — ${Y.length} middleware(s): ` + Y.map((e) => e.exportName).join(", ")), Ma(Y, O.ssrRoutes.map((e) => e.pattern)), Ie && Q.info("rpcGroup changed since last boot — forcing a dep re-optimize so the browser loads the current api client");
3749
4313
  try {
3750
- await We(l, "voltro dev (web)");
4314
+ await xt(l, "voltro dev (web)");
3751
4315
  } catch (e) {
3752
- Z.error(String(e.message ?? e)), process.exit(1);
4316
+ Q.error(String(e.message ?? e)), process.exit(1);
3753
4317
  }
3754
- await (await ne.createServer({
3755
- root: L,
4318
+ await (await A.createServer({
4319
+ root: M,
3756
4320
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3757
4321
  ssr: { noExternal: ["react-intl", "@voltro/i18n"] },
3758
4322
  resolve: {
@@ -3763,131 +4327,137 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3763
4327
  "@voltro/i18n"
3764
4328
  ],
3765
4329
  alias: [
3766
- ...Me ? [{
4330
+ ...K ? [{
3767
4331
  find: "@voltro/devtools/styles.css",
3768
- replacement: O(Me, "src/styles.css")
4332
+ replacement: F(K, "src/styles.css")
3769
4333
  }, {
3770
4334
  find: "@voltro/devtools",
3771
- replacement: O(Me, "src/index.ts")
4335
+ replacement: F(K, "src/index.ts")
3772
4336
  }] : [],
3773
4337
  ...q ? [
3774
4338
  {
3775
4339
  find: "@voltro/ui-shadcn/tokens.css",
3776
- replacement: O(q, "src/tokens.css")
4340
+ replacement: F(q, "src/tokens.css")
3777
4341
  },
3778
4342
  {
3779
4343
  find: "@voltro/ui-shadcn/cn",
3780
- replacement: O(q, "src/cn.ts")
4344
+ replacement: F(q, "src/cn.ts")
3781
4345
  },
3782
4346
  {
3783
4347
  find: "@voltro/ui-shadcn/brand",
3784
- replacement: O(q, "src/brand/voltroLogo.tsx")
4348
+ replacement: F(q, "src/brand/voltroLogo.tsx")
3785
4349
  },
3786
4350
  {
3787
4351
  find: "@voltro/ui-shadcn",
3788
- replacement: O(q, "src/index.ts")
4352
+ replacement: F(q, "src/index.ts")
3789
4353
  }
3790
4354
  ] : [],
3791
- ...pt(e)
4355
+ ...Wt(e)
3792
4356
  ]
3793
4357
  },
3794
4358
  optimizeDeps: {
3795
- include: [...a.map((e) => `${e.pkg}/rpcGroup`), ...Ie],
3796
- force: Le
4359
+ include: [...a.map((e) => `${e.pkg}/rpcGroup`), ...J],
4360
+ force: Ie
3797
4361
  },
3798
- customLogger: dt(),
4362
+ customLogger: Ht(),
3799
4363
  plugins: [
3800
- hr(O(e, "src", "pages")),
3801
- re(),
3802
- I(),
3803
- B,
3804
- se,
3805
- pe,
3806
- he,
3807
- ge,
4364
+ Ei(F(e, "src", "pages")),
4365
+ An({
4366
+ root: e,
4367
+ config: ee(n.images)
4368
+ }),
4369
+ Fn(e, n.fonts),
4370
+ er(e, n.feeds ?? [], n.seo?.siteUrl),
4371
+ j(),
4372
+ ne(),
4373
+ le,
4374
+ de,
4375
+ G,
3808
4376
  ye,
3809
- ke,
3810
- ...be ? [be] : []
4377
+ be,
4378
+ Ce,
4379
+ Me,
4380
+ ...we ? [we] : []
3811
4381
  ],
3812
4382
  server: {
3813
4383
  port: l,
3814
4384
  strictPort: !0,
3815
4385
  host: !0,
3816
4386
  allowedHosts: n.allowedHosts === !0 || [...n.allowedHosts ?? []],
3817
- proxy: K,
3818
- fs: { allow: [e, ...Pi(e)] }
4387
+ proxy: xe,
4388
+ fs: { allow: [e, ...wo(e)] }
3819
4389
  },
3820
4390
  appType: "spa",
3821
- cacheDir: O(L, ".vite"),
3822
- publicDir: O(e, "public")
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}`, {
4391
+ cacheDir: F(M, ".vite"),
4392
+ publicDir: F(e, "public")
4393
+ })).listen(), ho.info(`v${Pe} ready in ${Date.now() - Ne}ms`, {
4394
+ version: Pe,
4395
+ bootMs: Date.now() - Ne
4396
+ }), Q.info(`listening on http://localhost:${l}`, {
3827
4397
  port: l,
3828
4398
  app: n.name ?? "(unnamed)"
3829
4399
  });
3830
- for (let e of a) e.proxyTarget && (Z.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
4400
+ for (let e of a) e.proxyTarget && (Q.info(`proxy /ws/${e.name} → ${e.proxyTarget}`, {
3831
4401
  api: e.name,
3832
4402
  target: e.proxyTarget
3833
- }), Z.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
4403
+ }), Q.info(`proxy /_voltro/api/${e.name} → ${e.proxyTarget.replace(/^ws/, "http")}/_voltro/inspect`, { api: e.name }));
3834
4404
  try {
3835
- await x({
3836
- id: b,
3837
- name: y,
4405
+ await ie({
4406
+ id: S,
4407
+ name: _,
3838
4408
  kind: "web",
3839
4409
  url: `http://localhost:${l}`,
3840
4410
  pid: process.pid,
3841
4411
  status: "live",
3842
- logFile: D.path
4412
+ logFile: C.path
3843
4413
  });
3844
- let t = yr(e);
4414
+ let t = Ai(e);
3845
4415
  if (t) {
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 });
4416
+ let e = await Bi({ dashboardAppPath: t });
4417
+ 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 });
3848
4418
  }
3849
4419
  setInterval(() => {
3850
- x({
3851
- id: b,
3852
- name: y,
4420
+ ie({
4421
+ id: S,
4422
+ name: _,
3853
4423
  kind: "web",
3854
4424
  url: `http://localhost:${l}`,
3855
4425
  pid: process.pid,
3856
4426
  status: "live",
3857
- logFile: D.path
4427
+ logFile: C.path
3858
4428
  }).catch(() => {});
3859
4429
  }, 1e4).unref();
3860
4430
  let n = () => {
3861
- C(b), D.dispose();
4431
+ oe(S), C.dispose();
3862
4432
  };
3863
4433
  process.on("SIGINT", n), process.on("SIGTERM", n);
3864
4434
  } catch (e) {
3865
- Z.warn("runtime-registry write failed", {}, e);
4435
+ Q.warn("runtime-registry write failed", {}, e);
3866
4436
  }
3867
- return z({
4437
+ return ge({
3868
4438
  app: n.name ?? "unnamed",
3869
4439
  kind: "web",
3870
4440
  url: `http://localhost:${l}`,
3871
- bootMs: Date.now() - Ae
4441
+ bootMs: Date.now() - Ne
3872
4442
  }), new Promise(() => {});
3873
- }, fa = async (t) => {
4443
+ }, is = async (t) => {
3874
4444
  e("serve");
3875
- let n = await ua(t);
4445
+ let n = await ts(t);
3876
4446
  if (!n) return {
3877
4447
  ran: !1,
3878
4448
  exitCode: 0
3879
4449
  };
3880
- let i = Date.now(), a = Z.child("serve");
4450
+ let i = Date.now(), a = Q.child("serve");
3881
4451
  a.info("booting voltro serve (preview)", { app: n.name ?? "(unnamed)" });
3882
- let o = await ea(t, n);
4452
+ let o = await Go(t, n);
3883
4453
  for (let e of o) a.info("api wired", {
3884
4454
  name: e.name,
3885
4455
  pkg: e.pkg
3886
4456
  });
3887
- await sa(t, n, o);
4457
+ await Qo(t, n, o);
3888
4458
  {
3889
- let { pages: e } = await $(O(t, "src", "pages"));
3890
- await un({
4459
+ let { pages: e } = await Mo(F(t, "src", "pages"));
4460
+ await xr({
3891
4461
  appRoot: t,
3892
4462
  pages: e
3893
4463
  });
@@ -3896,12 +4466,12 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3896
4466
  kind: "web",
3897
4467
  configPort: n.port,
3898
4468
  env: process.env
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({
4469
+ }).port, c = await it("vite", () => import("vite")), l = (await import("@vitejs/plugin-react")).default, u = F(t, ".framework");
4470
+ Q.info("running production build"), await c.build({
3901
4471
  root: u,
3902
4472
  envPrefix: "__VOLTRO_VITE_ENV_DISABLED__",
3903
4473
  plugins: [l()],
3904
- customLogger: dt(),
4474
+ customLogger: Ht(),
3905
4475
  resolve: { dedupe: [
3906
4476
  "react",
3907
4477
  "react-dom",
@@ -3910,9 +4480,9 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3910
4480
  ] },
3911
4481
  build: {
3912
4482
  outDir: "dist",
3913
- rollupOptions: { output: { manualChunks: Ii } }
4483
+ rollupOptions: { output: { manualChunks: Eo } }
3914
4484
  },
3915
- publicDir: O(t, "public")
4485
+ publicDir: F(t, "public")
3916
4486
  });
3917
4487
  let d = (await c.preview({
3918
4488
  root: u,
@@ -3923,7 +4493,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3923
4493
  label: "Local",
3924
4494
  url: e
3925
4495
  })) ?? [];
3926
- return z({
4496
+ return ge({
3927
4497
  app: n.name ?? "unnamed",
3928
4498
  kind: "preview",
3929
4499
  url: f,
@@ -3932,4 +4502,4 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
3932
4502
  }), new Promise(() => {});
3933
4503
  };
3934
4504
  //#endregion
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 };
4505
+ export { Bi as $, Wa as A, on as At, fa as B, gt as Bt, Qo as C, Cn as Ct, uo as D, bn as Dt, fo as E, _n as Et, Na as F, jt as Ft, Hi as G, ct as Gt, ca as H, mt as Ht, Ba as I, At as It, Ki as J, Wi as K, it as Kt, Aa as L, Mt as Lt, Ra as M, Gt as Mt, za as N, Wt as Nt, to as O, Ue as Ot, ja as P, kt as Pt, ki as Q, La as R, Nt as Rt, ns as S, An as St, mo as T, xn as Tt, ua as U, dt as Ut, la as V, pt as Vt, ma as W, lt as Wt, Ji as X, qi as Y, ji as Z, qo as _, or as _t, Zo as a, qr as at, Eo as b, Ln as bt, es as c, kr as ct, $ as d, Er as dt, Ai as et, jo as f, xr as ft, Uo as g, ar as gt, Ho as h, lr as ht, _o as i, ti as it, Ma as j, qt as jt, Ga as k, tn as kt, No as l, jr as lt, Go as m, dr as mt, Yo as n, si as nt, Xo as o, Hr as ot, ts as p, ur as pt, Gi as q, Wo as r, ri as rt, Po as s, Ar as st, Do as t, fi as tt, Ao as u, Dr as ut, rs as v, Zn as vt, po as w, vn as wt, Mo as x, Nn as xt, is as y, Jn as yt, _a as z, xt as zt };