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