void 0.20.2 → 0.21.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 (310) hide show
  1. package/README.md +2 -2
  2. package/dist/agents-gni4eqBu.mjs +111 -0
  3. package/dist/auth-3sGB0zJ1.mjs +22 -0
  4. package/dist/{auth-DPl6kck4.mjs → auth-B9_D6ygs.mjs} +6 -241
  5. package/dist/auth-CAw7zHqj.mjs +2 -0
  6. package/dist/auth-client-BWBT8HLp.mjs +6 -0
  7. package/dist/auth-client-Bawdj38n.d.mts +7 -0
  8. package/dist/auth-client-react-7GFffu8R.d.mts +7 -0
  9. package/dist/auth-client-react-CMLwT2xI.mjs +6 -0
  10. package/dist/auth-client-solid-DyTFL4cq.d.mts +7 -0
  11. package/dist/auth-client-solid-UoreJWZG.mjs +6 -0
  12. package/dist/auth-client-svelte-Cv_WvrRk.mjs +6 -0
  13. package/dist/auth-client-svelte-zetW0KIH.d.mts +7 -0
  14. package/dist/auth-client-vue-CFk7Xbv3.mjs +6 -0
  15. package/dist/auth-client-vue-bChShbQP.d.mts +7 -0
  16. package/dist/{auth-cmd-gniL2fNt.mjs → auth-cmd-MkBG2u1f.mjs} +5 -5
  17. package/dist/{auth-link-NZdjCmSc.mjs → auth-link-Devmv96E.mjs} +5 -5
  18. package/dist/{better-auth-shared-DSCeohOK.d.mts → better-auth-shared-BoVwA5Vm.d.mts} +1 -6
  19. package/dist/{better-auth-shared-CYw1T3k4.mjs → better-auth-shared-syGYYmnY.mjs} +1 -1
  20. package/dist/{build-cmd-sI18tX_O.mjs → build-cmd-DsBGwtfs.mjs} +6 -4
  21. package/dist/{cache-IHn5MwBC.mjs → cache-BMw8eMyF.mjs} +6 -4
  22. package/dist/{cancel-deploy-C5qTOdLi.mjs → cancel-deploy-B3_s9NIN.mjs} +5 -3
  23. package/dist/cf-access-rAZxzMkL.mjs +181 -0
  24. package/dist/cf-build-output-CTdlo6Rt.mjs +520 -0
  25. package/dist/cli/cf-compat.d.mts +1 -0
  26. package/dist/cli/cf-compat.mjs +934 -0
  27. package/dist/cli/cli.mjs +61 -38
  28. package/dist/cli/env-schema-probe.mjs +3 -3
  29. package/dist/client-DAAivdid.mjs +2 -0
  30. package/dist/{client-dHfSJvAN.mjs → client-PdAJ-F0t.mjs} +148 -89
  31. package/dist/{cloudflare-auth-6M5llVPC.mjs → cloudflare-auth-BCmTc1X_.mjs} +13 -44
  32. package/dist/{cloudflare-cmd-4RPGN3KB.mjs → cloudflare-cmd-D6PrKn7o.mjs} +4 -7
  33. package/dist/{cloudflare-connect-t1UU5svD.mjs → cloudflare-connect-DloREDlc.mjs} +6 -6
  34. package/dist/cloudflare-operations-BHNJVDbN.mjs +2 -0
  35. package/dist/{cloudflare-operations-BzWnlC1_.mjs → cloudflare-operations-CPEdHYhM.mjs} +37 -39
  36. package/dist/cloudflare-user-output-Q-k0QoNQ.mjs +20 -0
  37. package/dist/collect-DAUItMDS.mjs +2 -0
  38. package/dist/collect-DXHNWHcT.mjs +48 -0
  39. package/dist/config--T87TD8T.mjs +2 -0
  40. package/dist/{config-NOG_U1aK.mjs → config-BSe70f4T.mjs} +4 -6
  41. package/dist/config-DDIFxQYx.mjs +2 -0
  42. package/dist/{config-uNGuFsI2.mjs → config-Dxr6cTXn.mjs} +22 -37
  43. package/dist/config-DywxBLQC.d.mts +185 -0
  44. package/dist/config-entry.d.mts +6 -0
  45. package/dist/config-entry.mjs +7 -0
  46. package/dist/config-uP7ZDtVZ.mjs +21 -0
  47. package/dist/config-write-y3CBI_ux.mjs +60 -0
  48. package/dist/{connect-Bfk31O_8.mjs → connect-BvC9kolB.mjs} +8 -6
  49. package/dist/{create-project-Bk9Z0-Jg.mjs → create-project-C9lQhRzj.mjs} +9 -25
  50. package/dist/create-project-CI-17RVJ.mjs +2 -0
  51. package/dist/database-provider-Cx525bwX.mjs +6 -0
  52. package/dist/database-provider.mjs +1 -5
  53. package/dist/{db-BkRoptAt.mjs → db-R7IQgOv5.mjs} +48 -44
  54. package/dist/{delete-DouASY9P.mjs → delete-CghI_NXn.mjs} +6 -4
  55. package/dist/deploy-CYPymbtG.mjs +2 -0
  56. package/dist/{deploy-DTaWUS1S.mjs → deploy-H968Lo4T.mjs} +765 -197
  57. package/dist/discover-BBzDZe_o.mjs +2 -0
  58. package/dist/{discover-xvfrgJeo.mjs → discover-C4O6YxVS.mjs} +3 -8
  59. package/dist/{dist-BrsS7cai.mjs → dist-4WkAWhWx.mjs} +1 -15
  60. package/dist/{dist-m40_XgNh.mjs → dist-Bn8Kodjp.mjs} +1 -1
  61. package/dist/dist-C5fND3R0.mjs +2 -0
  62. package/dist/dist-D7-nEOXi.mjs +2 -0
  63. package/dist/{output-B0cfNSx5.mjs → dist-Dn6nn2IU.mjs} +3 -926
  64. package/dist/{domain-1RhhOVrC.mjs → domain-CITt8lC-.mjs} +7 -5
  65. package/dist/{route-types-Da-DpyUp.mjs → drizzle-Beb2Am5S.mjs} +1 -280
  66. package/dist/{email-Ce6SQq-i.mjs → email-C5kaZXzJ.mjs} +2 -2
  67. package/dist/{email-C-lGh51B.mjs → email-_8VmyX7V.mjs} +14 -12
  68. package/dist/{entry-DU3oDoQ3.mjs → entry-DdRFGK0y.mjs} +2 -2
  69. package/dist/{env-DJHsPE7Z.mjs → env-DV4r3nHz.mjs} +9 -7
  70. package/dist/{env-DBKmK4vc.mjs → env-DX_v-Q-v.mjs} +1 -1
  71. package/dist/env-Yz4HcvHs.mjs +78 -0
  72. package/dist/env-helpers--wFmQ_5Q.mjs +136 -0
  73. package/dist/{env-types-BNPhro-M.mjs → env-types-CWDtqHgw.mjs} +6 -2
  74. package/dist/{env-validation-CF6KvTRf.mjs → env-validation-BsFEXps5.mjs} +19 -28
  75. package/dist/env-validation-DIDGM7h4.mjs +2 -0
  76. package/dist/fetch-CXDChK7B.mjs +18 -0
  77. package/dist/fetch-_SeGZao9.d.mts +57 -0
  78. package/dist/fetch-stream-AOByI7Ki.mjs +81 -0
  79. package/dist/fetch-stream-Bjf0hoZb.d.mts +49 -0
  80. package/dist/gen-BBiIZw6g.mjs +2 -0
  81. package/dist/{gen-B_wPnVTK.mjs → gen-CFOEEc-t.mjs} +13 -11
  82. package/dist/{generate-RTK8_kK1.mjs → generate-C0VY6RVf.mjs} +2 -2
  83. package/dist/{github-cmd-PW7ZnWTp.mjs → github-cmd-jYjha2LO.mjs} +18 -22
  84. package/dist/{handler-D1hLsObx.d.mts → handler-BXJTXd02.d.mts} +6 -1
  85. package/dist/handler-DghKr6dU.mjs +150 -0
  86. package/dist/head-D_QRR5Yd.mjs +112 -0
  87. package/dist/head-client-DzmJGN4C.mjs +90 -0
  88. package/dist/{headers-BAHwgHdW.mjs → headers-B_HBMgi0.mjs} +2 -2
  89. package/dist/{help-CwOX-zmI.mjs → help-C46mnlUS.mjs} +17 -12
  90. package/dist/help-CS_nAsWu.mjs +2 -0
  91. package/dist/index.d.mts +2 -20
  92. package/dist/index.mjs +116 -60
  93. package/dist/{init-BWZ7q5Z4.mjs → init-CSXmvxKu.mjs} +49 -50
  94. package/dist/{link-Rmvu2Wl_.mjs → link-DxMOALXk.mjs} +7 -5
  95. package/dist/{list-DEE2S6mY.mjs → list-0wQs0oYg.mjs} +7 -5
  96. package/dist/live-CB1y5IuC.mjs +411 -0
  97. package/dist/live-CKiJilLr.d.mts +105 -0
  98. package/dist/local-d1-DzykTWY8.mjs +104 -0
  99. package/dist/{login-Uvferzmm.mjs → login-CKk5NX4d.mjs} +6 -11
  100. package/dist/login-Ch9cgWRF.mjs +2 -0
  101. package/dist/{logs-27FenuiC.mjs → logs-hxWBSoej.mjs} +6 -4
  102. package/dist/migrate-CLty4mZR.mjs +2 -0
  103. package/dist/migrate-DcW8F2W8.mjs +285 -0
  104. package/dist/migration-handler-DM4clYj5.d.mts +51 -0
  105. package/dist/{neon-DHwd2zvC.mjs → neon-n74ta1Pr.mjs} +1 -1
  106. package/dist/{node-Ez5KW5rn.mjs → node-Cupyf7-s.mjs} +6 -6
  107. package/dist/{operator-auth-B3e08unv.mjs → operator-auth-BkVgJqv-.mjs} +2 -2
  108. package/dist/{operator-client-LUZnlnYk.mjs → operator-client-A0iex2yi.mjs} +2 -1
  109. package/dist/{operator-cmd-CjOTmAYE.mjs → operator-cmd-BEUYhaHB.mjs} +6 -6
  110. package/dist/output-urU86XeT.mjs +146 -0
  111. package/dist/{package-json-CPoWX79C.mjs → package-json-iCbMg5XF.mjs} +1 -1
  112. package/dist/pages/client.d.mts +5 -2
  113. package/dist/pages/client.mjs +5 -3
  114. package/dist/pages/head-client.mjs +1 -89
  115. package/dist/pages/head.mjs +1 -111
  116. package/dist/pages/index.d.mts +2 -3
  117. package/dist/pages/index.mjs +7 -7
  118. package/dist/pages/islands-plugin.mjs +2 -2
  119. package/dist/pages/prefetch.d.mts +2 -30
  120. package/dist/pages/prefetch.mjs +1 -89
  121. package/dist/pages/protocol.d.mts +2 -2
  122. package/dist/pages/protocol.mjs +3 -3
  123. package/dist/pages/serialize.d.mts +2 -9
  124. package/dist/pages/serialize.mjs +1 -13
  125. package/dist/plan-BEZ8VJW0.mjs +256 -0
  126. package/dist/plan-DpuOr14e.mjs +2 -0
  127. package/dist/{platform-auth-config-DrbQXXiW.mjs → platform-auth-config-Df6yVw-e.mjs} +6 -6
  128. package/dist/{platform-auth-protection-Bhtvp0B_.mjs → platform-auth-protection-Jb0yftay.mjs} +7 -5
  129. package/dist/{platform-auth-recovery-CeOKGVeJ.mjs → platform-auth-recovery-DmRyIfW0.mjs} +6 -5
  130. package/dist/platform-cmd-C9Vt7m-d.mjs +2 -0
  131. package/dist/{platform-cmd-BFhieCdV.mjs → platform-cmd-DRxCOTwy.mjs} +8 -5
  132. package/dist/{platform-domain-C74PULqV.mjs → platform-domain-IjiXgrXJ.mjs} +4 -3
  133. package/dist/{platform-lifecycle-BwAIgz-t.mjs → platform-lifecycle-BquAaU-5.mjs} +263 -56
  134. package/dist/platform-lifecycle-CuJIZNvA.mjs +2 -0
  135. package/dist/{platform-management-COogu_Se.mjs → platform-management-CCQKGsq4.mjs} +12 -7
  136. package/dist/platform-management-Cgyed0WY.mjs +2 -0
  137. package/dist/{platform-recovery-ewqLefp1.mjs → platform-recovery-DS8ih1SW.mjs} +3 -3
  138. package/dist/platform-registry-BJbgZLS1.mjs +431 -0
  139. package/dist/{plugin-inference-BDRfZngg.mjs → plugin-inference-DsvtJLll.mjs} +4 -4
  140. package/dist/prefetch-Bsc_Pb6c.mjs +90 -0
  141. package/dist/prefetch-Ce6la4EI.d.mts +31 -0
  142. package/dist/{prepare-blNRQvQl.mjs → prepare-CaUxODOU.mjs} +3 -2
  143. package/dist/prepare-D4CkM3_v.mjs +2 -0
  144. package/dist/{prepare-CtDJjoOj.mjs → prepare-pcWcxSCh.mjs} +13 -11
  145. package/dist/prerender-render-Cf_WDE9W.mjs +111 -0
  146. package/dist/prerender-render.mjs +1 -110
  147. package/dist/{preset-lAy0B0BQ.mjs → preset-Dowh9tTt.mjs} +16 -118
  148. package/dist/project-BEBFDFLz.mjs +2 -0
  149. package/dist/project-CWNIPoXc.mjs +209 -0
  150. package/dist/{project-cmd-DmZK9Hxf.mjs → project-cmd-2lN--YAX.mjs} +18 -16
  151. package/dist/{project-paths-SK8nMHPp.mjs → project-paths-CKQ-Q5JS.mjs} +47 -14
  152. package/dist/project-slug-23TpquG4.mjs +8 -0
  153. package/dist/project-slug-DofjTFd-.mjs +2 -0
  154. package/dist/{project-team-D8jOJMUJ.mjs → project-team-Dapn9HZn.mjs} +9 -5
  155. package/dist/{project-token-DA34bf-C.mjs → project-token-C90v9SJK.mjs} +6 -4
  156. package/dist/{project-tsconfig-Ql2XsSQp.mjs → project-tsconfig-CwfqUnVp.mjs} +2 -2
  157. package/dist/{protocol-C-pqYJjE.d.mts → protocol-ZH3jP4a7.d.mts} +1 -1
  158. package/dist/providers-BNKRacMr.d.mts +7 -0
  159. package/dist/provision-CNgEBkVA.mjs +3 -0
  160. package/dist/{provision-CSJOjjQk.mjs → provision-Cck2m3jJ.mjs} +11 -25
  161. package/dist/queues-BWKt1Xo4.d.mts +7 -0
  162. package/dist/{requests-CUExwGQQ.mjs → requests-CzX46I0i.mjs} +5 -3
  163. package/dist/resolve-project-BTotl8Nn.mjs +2 -0
  164. package/dist/{resolve-project--Vxawf7z.mjs → resolve-project-Xvis70DG.mjs} +2 -8
  165. package/dist/response-Tn7rU0MV.mjs +30 -0
  166. package/dist/{rollback-CDNGU1gr.mjs → rollback-BEeyc73H.mjs} +6 -4
  167. package/dist/{rolldown-runtime-rQ84J-ij.mjs → rolldown-runtime-DXIUcv95.mjs} +1 -10
  168. package/dist/route-types-Id82-veQ.mjs +280 -0
  169. package/dist/{local-d1-D2I6Ox5F.mjs → runner-BGVsGgkb.mjs} +6 -114
  170. package/dist/runner-CQs_cDSG.mjs +2 -0
  171. package/dist/runner-mysql-1o47achK.mjs +2 -0
  172. package/dist/{runner-mysql-7BPUNGmL.mjs → runner-mysql-BhwMk2Bm.mjs} +2 -9
  173. package/dist/{runner-pg-BkEza-dX.mjs → runner-pg-CJ_JeGF6.mjs} +2 -9
  174. package/dist/runner-pg-D7z01mQS.mjs +2 -0
  175. package/dist/runtime/ai.mjs +1 -1
  176. package/dist/runtime/auth-client-react.d.mts +2 -6
  177. package/dist/runtime/auth-client-react.mjs +1 -5
  178. package/dist/runtime/auth-client-solid.d.mts +2 -6
  179. package/dist/runtime/auth-client-solid.mjs +1 -5
  180. package/dist/runtime/auth-client-svelte.d.mts +2 -6
  181. package/dist/runtime/auth-client-svelte.mjs +1 -5
  182. package/dist/runtime/auth-client-vue.d.mts +2 -6
  183. package/dist/runtime/auth-client-vue.mjs +1 -5
  184. package/dist/runtime/auth-client.d.mts +2 -6
  185. package/dist/runtime/auth-client.mjs +1 -5
  186. package/dist/runtime/auth.mjs +1 -21
  187. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  188. package/dist/runtime/better-auth-mysql.mjs +1 -1
  189. package/dist/runtime/better-auth-pg.d.mts +1 -1
  190. package/dist/runtime/better-auth-pg.mjs +1 -1
  191. package/dist/runtime/better-auth.d.mts +1 -1
  192. package/dist/runtime/better-auth.mjs +1 -1
  193. package/dist/runtime/client-react.d.mts +3 -3
  194. package/dist/runtime/client-react.mjs +3 -3
  195. package/dist/runtime/client-solid.d.mts +3 -3
  196. package/dist/runtime/client-solid.mjs +3 -3
  197. package/dist/runtime/client-svelte.d.mts +3 -3
  198. package/dist/runtime/client-svelte.mjs +3 -3
  199. package/dist/runtime/client-vue.d.mts +3 -3
  200. package/dist/runtime/client-vue.mjs +3 -3
  201. package/dist/runtime/client.d.mts +3 -3
  202. package/dist/runtime/client.mjs +3 -3
  203. package/dist/runtime/db.mjs +1 -1
  204. package/dist/runtime/durable.mjs +1 -1
  205. package/dist/runtime/email/testing.mjs +1 -1
  206. package/dist/runtime/env-helpers.mjs +1 -135
  207. package/dist/runtime/env-public-client.mjs +1 -1
  208. package/dist/runtime/env-public.mjs +2 -2
  209. package/dist/runtime/env.mjs +1 -77
  210. package/dist/runtime/fetch-stream.d.mts +2 -49
  211. package/dist/runtime/fetch-stream.mjs +2 -80
  212. package/dist/runtime/fetch.d.mts +2 -57
  213. package/dist/runtime/fetch.mjs +2 -17
  214. package/dist/runtime/handler.d.mts +1 -1
  215. package/dist/runtime/handler.mjs +1 -149
  216. package/dist/runtime/kv.mjs +1 -1
  217. package/dist/runtime/live-client.d.mts +1 -1
  218. package/dist/runtime/live-server.mjs +2 -2
  219. package/dist/runtime/live.d.mts +2 -104
  220. package/dist/runtime/live.mjs +1 -410
  221. package/dist/runtime/migration-handler-mysql.d.mts +1 -1
  222. package/dist/runtime/migration-handler-pg.d.mts +1 -1
  223. package/dist/runtime/migration-handler.d.mts +2 -50
  224. package/dist/runtime/queues.d.mts +2 -6
  225. package/dist/runtime/queues.mjs +1 -1
  226. package/dist/runtime/remote/index.mjs +49 -8
  227. package/dist/runtime/response.mjs +1 -29
  228. package/dist/runtime/sandbox.d.mts +4 -56
  229. package/dist/runtime/sandbox.mjs +82 -221
  230. package/dist/runtime/sse.mjs +1 -171
  231. package/dist/runtime/storage.mjs +1 -1
  232. package/dist/runtime/validator.d.mts +1 -1
  233. package/dist/runtime/validator.mjs +1 -71
  234. package/dist/runtime/ws-server.d.mts +2 -2
  235. package/dist/runtime/ws-server.mjs +2 -2
  236. package/dist/runtime/ws.d.mts +2 -121
  237. package/dist/{scan-CpK-57ug.mjs → scan-DJbooZm2.mjs} +3 -3
  238. package/dist/{scan-BMH4rzlv.mjs → scan-DdDvRCU1.mjs} +8 -26
  239. package/dist/{secret-Bzzi2e9E.mjs → secret-wnTel5Yw.mjs} +8 -6
  240. package/dist/serialize-BPvnNQuA.mjs +14 -0
  241. package/dist/serialize-CfSwWfF2.d.mts +10 -0
  242. package/dist/{skills-C0RvGjeE.mjs → skills-B-690E7h.mjs} +3 -2
  243. package/dist/sse-BaC1jXko.mjs +172 -0
  244. package/dist/{subcommand-prompt-Bmyn5Rlc.mjs → subcommand-prompt-Gj3VzLIh.mjs} +2 -1
  245. package/dist/sveltekit.d.mts +2 -1
  246. package/dist/sveltekit.mjs +3 -2
  247. package/dist/validate-DqJ33oHj.mjs +2 -0
  248. package/dist/validate-qNhV00PD.mjs +180 -0
  249. package/dist/validator-BTOu0fB0.mjs +72 -0
  250. package/dist/{wrangler--imS8n0d.mjs → wrangler-D01qs6VB.mjs} +259 -71
  251. package/dist/ws-BwcqizuH.d.mts +122 -0
  252. package/dist/{yarn-pnp-DxSInkzL.mjs → yarn-pnp-CVEc3gE7.mjs} +1 -1
  253. package/package.json +19 -8
  254. package/skills/void/SKILL.md +7 -5
  255. package/skills/void/docs/guide/ai.md +3 -3
  256. package/skills/void/docs/guide/app-types.md +12 -11
  257. package/skills/void/docs/guide/auth.md +2 -2
  258. package/skills/void/docs/guide/database/d1.md +1 -1
  259. package/skills/void/docs/guide/database/mysql.md +1 -1
  260. package/skills/void/docs/guide/database/postgresql.md +3 -3
  261. package/skills/void/docs/guide/deployment.md +16 -16
  262. package/skills/void/docs/guide/durable-state.md +2 -2
  263. package/skills/void/docs/guide/edge/headers.md +3 -3
  264. package/skills/void/docs/guide/edge/prerendering.md +1 -1
  265. package/skills/void/docs/guide/edge/redirects.md +4 -4
  266. package/skills/void/docs/guide/edge/revalidation.md +6 -6
  267. package/skills/void/docs/guide/edge/rewrites.md +28 -27
  268. package/skills/void/docs/guide/edge/static-assets.md +1 -1
  269. package/skills/void/docs/guide/email.md +27 -25
  270. package/skills/void/docs/guide/env-migration.md +1 -1
  271. package/skills/void/docs/guide/index.md +1 -1
  272. package/skills/void/docs/guide/pages-routing/head.md +1 -1
  273. package/skills/void/docs/guide/platform/administration/access.md +171 -0
  274. package/skills/void/docs/guide/platform/administration/email.md +121 -0
  275. package/skills/void/docs/guide/platform/administration/operations.md +97 -0
  276. package/skills/void/docs/guide/platform/administration/projects.md +56 -0
  277. package/skills/void/docs/guide/platform/development/local.md +119 -0
  278. package/skills/void/docs/guide/platform/development/runtime.md +124 -0
  279. package/skills/void/docs/guide/platform/development/schema-ci.md +95 -0
  280. package/skills/void/docs/guide/platform/installation/ci.md +58 -0
  281. package/skills/void/docs/guide/platform/installation/credentials.md +90 -0
  282. package/skills/void/docs/guide/platform/installation/domains.md +68 -0
  283. package/skills/void/docs/guide/platform/installation/first-deployment.md +82 -0
  284. package/skills/void/docs/guide/platform/installation/maintenance.md +137 -0
  285. package/skills/void/docs/guide/platform/installation/prerequisites.md +88 -0
  286. package/skills/void/docs/guide/platform/installation/setup.md +169 -0
  287. package/skills/void/docs/guide/platform/installation/uninstall.md +54 -0
  288. package/skills/void/docs/guide/platform-administration.md +6 -414
  289. package/skills/void/docs/guide/platform-development.md +5 -316
  290. package/skills/void/docs/guide/project-collaboration.md +1 -1
  291. package/skills/void/docs/guide/remote-dev.md +2 -2
  292. package/skills/void/docs/guide/sandboxes.md +10 -25
  293. package/skills/void/docs/guide/self-hosted-platform.md +11 -694
  294. package/skills/void/docs/guide/ssg.md +1 -1
  295. package/skills/void/docs/guide/websockets.md +1 -1
  296. package/skills/void/docs/integrations/cloudflare.md +86 -84
  297. package/skills/void/docs/integrations/frameworks/analog.md +14 -9
  298. package/skills/void/docs/integrations/frameworks/astro.md +14 -10
  299. package/skills/void/docs/integrations/frameworks/nuxt.md +14 -9
  300. package/skills/void/docs/integrations/frameworks/overview.md +35 -29
  301. package/skills/void/docs/integrations/frameworks/react-router.md +1 -1
  302. package/skills/void/docs/integrations/frameworks/sveltekit.md +33 -30
  303. package/skills/void/docs/integrations/frameworks/tanstack-start.md +1 -1
  304. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -5
  305. package/skills/void/docs/reference/api.md +55 -38
  306. package/skills/void/docs/reference/cli.md +60 -34
  307. package/skills/void/docs/reference/config.md +57 -34
  308. package/skills/void/docs/reference/resource-inference.md +10 -10
  309. package/skills/void/docs/reference/structure.md +2 -2
  310. package/dist/validate-tBBN_dXH.mjs +0 -505
@@ -0,0 +1,2 @@
1
+ import { r as runPlatformLifecycleCommand } from "./platform-lifecycle-BquAaU-5.mjs";
2
+ export { runPlatformLifecycleCommand };
@@ -1,5 +1,7 @@
1
- import { A as outro, D as log, I as isCancel, J as listInstallationManifests, M as select, W as acquirePlatformLifecycleLock, et as readInstallationRecoverySecrets, i as createSpinner, it as resolveInstallationManifest, k as note, nt as removeInstallationRecoverySecrets, rt as removePlatformConnectionForInstallation, st as writeInstallationManifest, w as confirm } from "./output-B0cfNSx5.mjs";
2
- import { C as PlatformCloudflareClient, D as verifyPlatformRuntimeTokenPermissions, E as hyperdriveOriginMatches, T as hyperdriveOriginFromConnectionString, _ as revalidatePlatformInstallAction, a as createPlatformInstallationSecrets, assertNoninteractivePlatformMutationAcknowledged, f as trackedPlatformWorkerTraffic, g as platformProvisionIntentHash, h as platformAdoptionIntentHash, m as formatPlatformInstallPlan, n as acquirePlatformDatabaseLifecycleLock, o as installPlatform, p as createPlatformInstallPlan, resolvePlatformInstallDatabaseUrl, s as loadPlatformRuntime, t as REMOTE_INSTALLATION_MANIFEST_KEY, u as resolveBootstrapGitHubId, v as assertPlatformOperatorCredentialCanApplyPlan, w as hyperdriveOriginConfigHash, y as resolvePlatformCloudflareCredential } from "./platform-lifecycle-BwAIgz-t.mjs";
1
+ import { i as createSpinner } from "./output-urU86XeT.mjs";
2
+ import { a as listInstallationManifests, d as readInstallationRecoverySecrets, h as resolveInstallationManifest, m as removePlatformConnectionForInstallation, p as removeInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-BJbgZLS1.mjs";
3
+ import { E as confirm, I as select, N as note, P as outro, W as isCancel, j as log } from "./dist-Dn6nn2IU.mjs";
4
+ import { A as hyperdriveOriginFromConnectionString, C as assertPlatformOperatorCredentialCanApplyPlan, M as verifyPlatformRuntimeTokenPermissions, O as PlatformCloudflareClient, S as platformDatabaseNameFromOwnerUrl, _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY, b as platformProvisionIntentHash, d as loadPlatformRuntime, g as trackedPlatformWorkerTraffic, j as hyperdriveOriginMatches, k as hyperdriveOriginConfigHash, l as createPlatformInstallationSecrets, m as resolveBootstrapGitHubId, n as resolvePlatformInstallDatabaseUrl, o as acquirePlatformDatabaseLifecycleLock, t as assertNoninteractivePlatformMutationAcknowledged, u as installPlatform, v as formatPlatformInstallPlan, w as resolvePlatformCloudflareCredential, x as revalidatePlatformInstallAction, y as platformAdoptionIntentHash } from "./platform-lifecycle-BquAaU-5.mjs";
3
5
  import { createHash } from "node:crypto";
4
6
  import { PLATFORM_DISABLED_KEY, PLATFORM_DISABLED_VALUE, PLATFORM_R2_OWNERSHIP_MARKER_KEY, createPlatformResourceOwnershipMarker, parsePlatformInstallationManifest, parsePlatformResourceOwnershipMarker, recordInstallationResource, recordInstallationStep, setInstallationDesiredState, transitionInstallation } from "@void/platform";
5
7
  //#region src/cli/platform-management.ts
@@ -72,7 +74,8 @@ async function runInstalledPlatformCommand(args) {
72
74
  authoritativeProvisionIntents: databaseCheckpointExists,
73
75
  repairMissing: args.subcommand === "repair",
74
76
  allowUnverifiedAiGateway: args.plan,
75
- includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0
77
+ includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
78
+ enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
76
79
  });
77
80
  note(formatPlatformInstallPlan(plan), args.subcommand === "upgrade" ? "Upgrade plan" : args.subcommand === "rollback" ? "Rollback plan" : args.subcommand === "enable" ? "Enable plan" : "Repair plan");
78
81
  note([
@@ -144,7 +147,8 @@ async function runInstalledPlatformCommand(args) {
144
147
  replanWorkers: async (recoveryManifest) => (await createPlatformInstallPlan(client, planInput, recoveryManifest, {
145
148
  authoritativeProvisionIntents: true,
146
149
  repairMissing: true,
147
- includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0
150
+ includeEmailGateway: runtime.manifest.artifacts.emailGateway !== void 0,
151
+ enableSandbox: runtime.manifest.safetyProtocols.sandboxDrain >= 3
148
152
  })).actions.filter((action) => action.kind === "worker"),
149
153
  revalidateBeforeWorkerDeploy: (manifest, action) => revalidatePlatformInstallAction(client, plan, manifest, action, { repairMissing: args.subcommand === "repair" })
150
154
  });
@@ -556,12 +560,13 @@ async function verifyPlatformMutationOwnership(client, manifest, targetKeys, opt
556
560
  name: resource.name
557
561
  })).digest("hex");
558
562
  const malformedLegacyHash = !/^[a-f0-9]{64}$/.test(resource.configHash);
559
- if (options.databaseUrl) {
563
+ if (options.databaseUrl && resource.ownership !== "adopted") {
560
564
  const expected = hyperdriveOriginFromConnectionString(options.databaseUrl);
561
565
  if (!hyperdriveOriginMatches(live.origin, expected)) throw ownershipError(`hyperdrive ${resource.name} targets a different PostgreSQL origin than this installation's pinned database`);
562
566
  const expectedHash = hyperdriveOriginConfigHash(expected);
563
567
  if (resource.configHash !== expectedHash && resource.configHash !== legacyHash && !malformedLegacyHash) throw ownershipError(`hyperdrive ${resource.name} does not match the installation's database fingerprint`);
564
- } else if (resource.configHash !== hyperdriveOriginConfigHash(live.origin) && resource.configHash !== legacyHash && !malformedLegacyHash) throw ownershipError(`hyperdrive ${resource.name} changed configuration`);
568
+ } else if (resource.ownership === "adopted" && (resource.configHash !== hyperdriveOriginConfigHash(live.origin) || options.databaseUrl && live.origin.database !== platformDatabaseNameFromOwnerUrl(options.databaseUrl))) throw ownershipError(`hyperdrive ${resource.name} changed configuration`);
569
+ else if (resource.ownership !== "adopted" && resource.configHash !== hyperdriveOriginConfigHash(live.origin) && resource.configHash !== legacyHash && !malformedLegacyHash) throw ownershipError(`hyperdrive ${resource.name} changed configuration`);
565
570
  }
566
571
  }
567
572
  } else if (resource.kind === "kv-namespace") exists = hasNamedResource(kvNamespaces, resource);
@@ -721,4 +726,4 @@ async function promptForConfirmation(message, initialValue) {
721
726
  return answer;
722
727
  }
723
728
  //#endregion
724
- export { isPlatformManifestMonotonicExtension, recoverDurablyMarkedProvisionIntents, resolveInstalledPlatformManifest, runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
729
+ export { resolveInstalledPlatformManifest as a, selectAuthoritativePlatformManifest as c, recoverDurablyMarkedProvisionIntents as i, uninstallPlatform as l, disablePlatform as n, resolvePlatformRuntimeTokenToPreflight as o, isPlatformManifestMonotonicExtension as r, runInstalledPlatformCommand as s, assertPlatformRollbackCompatibility as t, verifyPlatformInstallationOwnership as u };
@@ -0,0 +1,2 @@
1
+ import { c as selectAuthoritativePlatformManifest, s as runInstalledPlatformCommand, u as verifyPlatformInstallationOwnership } from "./platform-management-CCQKGsq4.mjs";
2
+ export { runInstalledPlatformCommand, selectAuthoritativePlatformManifest, verifyPlatformInstallationOwnership };
@@ -1,7 +1,7 @@
1
- import { J as listInstallationManifests, W as acquirePlatformLifecycleLock, at as savePlatformConnection, st as writeInstallationManifest } from "./output-B0cfNSx5.mjs";
2
1
  import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
3
- import { p as createPlatformInstallPlan, t as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-BwAIgz-t.mjs";
4
- import { isPlatformManifestMonotonicExtension, recoverDurablyMarkedProvisionIntents, verifyPlatformInstallationOwnership } from "./platform-management-COogu_Se.mjs";
2
+ import { a as listInstallationManifests, g as savePlatformConnection, t as acquirePlatformLifecycleLock, v as writeInstallationManifest } from "./platform-registry-BJbgZLS1.mjs";
3
+ import { _ as createPlatformInstallPlan, a as REMOTE_INSTALLATION_MANIFEST_KEY } from "./platform-lifecycle-BquAaU-5.mjs";
4
+ import { i as recoverDurablyMarkedProvisionIntents, r as isPlatformManifestMonotonicExtension, u as verifyPlatformInstallationOwnership } from "./platform-management-CCQKGsq4.mjs";
5
5
  import { parsePlatformInstallationManifest, setInstallationEndpoints } from "@void/platform";
6
6
  //#region src/cli/platform-recovery.ts
7
7
  async function recoverPlatformInstallations(client, accountId, verifyEndpoint = verifyInstallationEndpoint, selector = "") {
@@ -0,0 +1,431 @@
1
+ import { a as join, u as resolve } from "./dist-4WkAWhWx.mjs";
2
+ import { closeSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { createCipheriv, createDecipheriv, createHash, randomBytes } from "node:crypto";
4
+ import { homedir, hostname } from "node:os";
5
+ import { Entry } from "@napi-rs/keyring";
6
+ import { parsePlatformInstallationManifest } from "@void/platform";
7
+ //#region src/cli/keyring.ts
8
+ function readKeyringPassword(service, account) {
9
+ try {
10
+ return new Entry(service, account).getPassword();
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
15
+ function writeKeyringPassword(service, account, password) {
16
+ try {
17
+ new Entry(service, account).setPassword(password);
18
+ return true;
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+ function deleteKeyringPassword(service, account) {
24
+ try {
25
+ new Entry(service, account).deletePassword();
26
+ return true;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+ const DEFAULT_REGISTRY = {
32
+ activeConnectionId: null,
33
+ connections: [],
34
+ schemaVersion: 1
35
+ };
36
+ const PLATFORM_RECOVERY_KEYRING_SERVICE = "dev.void.cli.platform";
37
+ const PLATFORM_RECOVERY_ENVELOPE_VERSION = 1;
38
+ function platformRegistryDirectory() {
39
+ return process.env.VOID_PLATFORM_REGISTRY_DIR ?? join(homedir(), ".void", "platforms");
40
+ }
41
+ function normalizePlatformApiUrl(value) {
42
+ let url;
43
+ try {
44
+ url = new URL(value);
45
+ } catch {
46
+ throw new Error(`platform: Invalid platform URL ${JSON.stringify(value)}.`);
47
+ }
48
+ if (!(url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1")) && url.protocol !== "https:" || url.username || url.password) throw new Error("platform: Platform URLs must use HTTPS and must not contain credentials.");
49
+ if (url.search || url.hash) throw new Error("platform: Platform URLs must not contain query parameters or fragments.");
50
+ if (url.pathname !== "/" && url.pathname !== "") throw new Error("platform: Platform URLs must not contain a path.");
51
+ return url.origin;
52
+ }
53
+ function platformConnectionId(apiUrl) {
54
+ return createHash("sha256").update(normalizePlatformApiUrl(apiUrl)).digest("hex").slice(0, 20);
55
+ }
56
+ function platformCredentialAccount(apiUrl) {
57
+ return `platform:${createHash("sha256").update(normalizePlatformApiUrl(apiUrl)).digest("hex")}`;
58
+ }
59
+ function parseConnection(value) {
60
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("platform: Invalid connection entry in the local registry.");
61
+ const entry = value;
62
+ const apiUrl = normalizePlatformApiUrl(String(entry.apiUrl ?? ""));
63
+ const id = String(entry.id ?? "");
64
+ if (id !== platformConnectionId(apiUrl)) throw new Error("platform: Connection id does not match its API URL.");
65
+ if (entry.kind !== "connected" && entry.kind !== "installed") throw new Error("platform: Invalid connection kind in the local registry.");
66
+ const lastUsedAt = String(entry.lastUsedAt ?? "");
67
+ if (!Number.isFinite(Date.parse(lastUsedAt))) throw new Error("platform: Invalid connection timestamp in the local registry.");
68
+ const optionalString = (input) => typeof input === "string" && input !== "" ? input : null;
69
+ const proxyUrl = optionalString(entry.proxyUrl) ?? (apiUrl === "https://api.void.cloud" ? "https://proxy.void.cloud" : apiUrl === "https://api.staging.void.cloud" ? "https://proxy.staging.void.cloud" : null);
70
+ return {
71
+ accountId: optionalString(entry.accountId),
72
+ apiUrl,
73
+ applicationDomain: optionalString(entry.applicationDomain),
74
+ displayName: typeof entry.displayName === "string" && entry.displayName.trim() ? entry.displayName.trim() : new URL(apiUrl).hostname,
75
+ id,
76
+ installationId: optionalString(entry.installationId),
77
+ kind: entry.kind,
78
+ lastUsedAt,
79
+ proxyUrl: proxyUrl === null ? null : normalizePlatformApiUrl(proxyUrl)
80
+ };
81
+ }
82
+ function readRegistry(directory) {
83
+ try {
84
+ const parsed = JSON.parse(readFileSync(join(directory, "registry.json"), "utf8"));
85
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("registry must be an object");
86
+ const value = parsed;
87
+ if (value.schemaVersion !== 1 || !Array.isArray(value.connections)) throw new Error("unsupported schema");
88
+ const connections = value.connections.map(parseConnection);
89
+ return {
90
+ activeConnectionId: typeof value.activeConnectionId === "string" && connections.some((connection) => connection.id === value.activeConnectionId) ? value.activeConnectionId : null,
91
+ connections,
92
+ schemaVersion: 1
93
+ };
94
+ } catch (error) {
95
+ if (error.code === "ENOENT") return DEFAULT_REGISTRY;
96
+ throw new Error(`platform: Could not read ${join(directory, "registry.json")}: ${error instanceof Error ? error.message : String(error)}`);
97
+ }
98
+ }
99
+ function withRegistryLock(directory, operation) {
100
+ mkdirSync(directory, {
101
+ recursive: true,
102
+ mode: 448
103
+ });
104
+ const lockPath = join(directory, ".registry.lock");
105
+ let descriptor;
106
+ try {
107
+ descriptor = openSync(lockPath, "wx", 384);
108
+ } catch (error) {
109
+ if (error.code !== "EEXIST") throw error;
110
+ if (Date.now() - statSync(lockPath).mtimeMs < 6e5) throw new Error("platform: Another process is updating the platform registry.");
111
+ rmSync(lockPath, { force: true });
112
+ descriptor = openSync(lockPath, "wx", 384);
113
+ }
114
+ try {
115
+ return operation();
116
+ } finally {
117
+ closeSync(descriptor);
118
+ rmSync(lockPath, { force: true });
119
+ }
120
+ }
121
+ function writeJsonAtomically(path, value) {
122
+ const temporary = `${path}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
123
+ try {
124
+ writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, {
125
+ mode: 384,
126
+ flag: "wx"
127
+ });
128
+ renameSync(temporary, path);
129
+ } finally {
130
+ rmSync(temporary, { force: true });
131
+ }
132
+ }
133
+ function acquirePlatformLifecycleLock(accountId, installationSlug, directory = platformRegistryDirectory()) {
134
+ if (!/^[A-Za-z0-9_-]+$/.test(accountId) || !/^[a-z0-9][a-z0-9-]{0,79}$/.test(installationSlug)) throw new Error("platform: Invalid lifecycle lock identity.");
135
+ const lockDirectory = join(directory, "locks");
136
+ mkdirSync(lockDirectory, {
137
+ recursive: true,
138
+ mode: 448
139
+ });
140
+ const lockPath = join(lockDirectory, `${accountId}-${installationSlug}.lock`);
141
+ const acquire = () => {
142
+ try {
143
+ const descriptor = openSync(lockPath, "wx", 384);
144
+ writeFileSync(descriptor, `${JSON.stringify({
145
+ host: hostname(),
146
+ pid: process.pid,
147
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
148
+ })}\n`);
149
+ return descriptor;
150
+ } catch (error) {
151
+ if (error.code !== "EEXIST") throw error;
152
+ let stale = false;
153
+ try {
154
+ const owner = JSON.parse(readFileSync(lockPath, "utf8"));
155
+ if (owner.host === hostname() && typeof owner.pid === "number") try {
156
+ process.kill(owner.pid, 0);
157
+ } catch (ownerError) {
158
+ stale = ownerError.code === "ESRCH";
159
+ }
160
+ else {
161
+ const startedAt = typeof owner.startedAt === "string" ? Date.parse(owner.startedAt) : NaN;
162
+ stale = Number.isFinite(startedAt) && Date.now() - startedAt > 72e5;
163
+ }
164
+ } catch {
165
+ stale = Date.now() - statSync(lockPath).mtimeMs > 72e5;
166
+ }
167
+ if (!stale) throw new Error(`platform: Another lifecycle operation is active for ${installationSlug} in account ${accountId}.`);
168
+ rmSync(lockPath, { force: true });
169
+ return acquire();
170
+ }
171
+ };
172
+ const descriptor = acquire();
173
+ let released = false;
174
+ return () => {
175
+ if (released) return;
176
+ released = true;
177
+ closeSync(descriptor);
178
+ rmSync(lockPath, { force: true });
179
+ };
180
+ }
181
+ function listPlatformConnections(directory = platformRegistryDirectory()) {
182
+ return readRegistry(directory).connections;
183
+ }
184
+ function assertPlatformInstallationSlugAvailable(installationSlug, directory = platformRegistryDirectory()) {
185
+ const collision = listInstallationManifests(directory).find((manifest) => manifest.status !== "uninstalled" && manifest.deployment.installationSlug === installationSlug);
186
+ if (collision) throw new Error(`platform: Installation ${collision.id} already uses this name. Resume it with \`void platform install --resume --name ${collision.id}\`.`);
187
+ }
188
+ function getActivePlatformConnection(directory = platformRegistryDirectory()) {
189
+ const registry = readRegistry(directory);
190
+ return registry.connections.find((connection) => connection.id === registry.activeConnectionId) ?? (registry.connections.length === 1 ? registry.connections[0] : null);
191
+ }
192
+ function savePlatformConnection(input, directory = platformRegistryDirectory()) {
193
+ const apiUrl = normalizePlatformApiUrl(input.apiUrl);
194
+ const id = platformConnectionId(apiUrl);
195
+ const lastUsedAt = input.lastUsedAt ?? (/* @__PURE__ */ new Date()).toISOString();
196
+ const connection = parseConnection({
197
+ ...input,
198
+ apiUrl,
199
+ id,
200
+ lastUsedAt
201
+ });
202
+ return withRegistryLock(directory, () => {
203
+ const connections = readRegistry(directory).connections.filter((entry) => entry.id !== id);
204
+ connections.push(connection);
205
+ connections.sort((left, right) => left.displayName.localeCompare(right.displayName));
206
+ writeJsonAtomically(join(directory, "registry.json"), {
207
+ activeConnectionId: id,
208
+ connections,
209
+ schemaVersion: 1
210
+ });
211
+ return connection;
212
+ });
213
+ }
214
+ function selectPlatformConnection(selector, directory = platformRegistryDirectory()) {
215
+ return withRegistryLock(directory, () => {
216
+ const current = readRegistry(directory);
217
+ const normalizedUrl = (() => {
218
+ try {
219
+ return normalizePlatformApiUrl(selector);
220
+ } catch {
221
+ return null;
222
+ }
223
+ })();
224
+ const matches = current.connections.filter((entry) => entry.id === selector || entry.installationId === selector || entry.displayName.toLowerCase() === selector.toLowerCase() || normalizedUrl !== null && entry.apiUrl === normalizedUrl);
225
+ if (matches.length !== 1) throw new Error(matches.length === 0 ? `platform: No installed or connected platform matches ${JSON.stringify(selector)}.` : `platform: More than one platform matches ${JSON.stringify(selector)}. Use its id or URL.`);
226
+ const selected = {
227
+ ...matches[0],
228
+ lastUsedAt: (/* @__PURE__ */ new Date()).toISOString()
229
+ };
230
+ const connections = current.connections.map((entry) => entry.id === selected.id ? selected : entry);
231
+ writeJsonAtomically(join(directory, "registry.json"), {
232
+ activeConnectionId: selected.id,
233
+ connections,
234
+ schemaVersion: 1
235
+ });
236
+ return selected;
237
+ });
238
+ }
239
+ function installationManifestPath(accountId, installationId, directory = platformRegistryDirectory()) {
240
+ if (!/^[A-Za-z0-9_-]+$/.test(accountId) || !/^[a-z0-9][a-z0-9-]{7,79}$/.test(installationId)) throw new Error("platform: Invalid account or installation id.");
241
+ return join(directory, accountId, `${installationId}.json`);
242
+ }
243
+ function writeInstallationManifest(manifest, directory = platformRegistryDirectory()) {
244
+ const path = installationManifestPath(manifest.account.id, manifest.id, directory);
245
+ const parent = join(directory, manifest.account.id);
246
+ mkdirSync(parent, {
247
+ recursive: true,
248
+ mode: 448
249
+ });
250
+ writeJsonAtomically(path, manifest);
251
+ }
252
+ function listInstallationManifests(directory = platformRegistryDirectory()) {
253
+ const manifests = [];
254
+ let accountDirectories;
255
+ try {
256
+ accountDirectories = readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
257
+ } catch (error) {
258
+ if (error.code === "ENOENT") return [];
259
+ throw error;
260
+ }
261
+ for (const accountId of accountDirectories) {
262
+ const accountPath = join(directory, accountId);
263
+ for (const entry of readdirSync(accountPath, { withFileTypes: true })) {
264
+ if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
265
+ const path = join(accountPath, entry.name);
266
+ try {
267
+ manifests.push(parsePlatformInstallationManifest(JSON.parse(readFileSync(path, "utf8"))));
268
+ } catch (error) {
269
+ throw new Error(`platform: Invalid installation manifest ${path}: ${error instanceof Error ? error.message : String(error)}`);
270
+ }
271
+ }
272
+ }
273
+ return manifests.sort((left, right) => left.deployment.displayName.localeCompare(right.deployment.displayName));
274
+ }
275
+ function resolveInstallationManifest(selector, directory = platformRegistryDirectory()) {
276
+ const manifests = listInstallationManifests(directory).filter((manifest) => manifest.status !== "uninstalled" && (!selector || manifest.id === selector || manifest.deployment.installationSlug === selector || manifest.deployment.displayName.toLowerCase() === selector.toLowerCase()));
277
+ if (manifests.length !== 1) throw new Error(manifests.length === 0 ? `platform: No local installation matches ${JSON.stringify(selector)}.` : "platform: Multiple local installations match; specify an installation id.");
278
+ return manifests[0];
279
+ }
280
+ function writePendingInstallationSecrets(manifest, secrets, directory = platformRegistryDirectory()) {
281
+ const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
282
+ writeEncryptedRecoveryMaterial(manifest, "pending", manifestPath.replace(/\.json$/, ".secrets.enc"), secrets, directory);
283
+ rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
284
+ }
285
+ function readPendingInstallationSecrets(manifest, directory = platformRegistryDirectory()) {
286
+ return readRecoveryMaterial(manifest, "pending", directory);
287
+ }
288
+ function promoteInstallationSecrets(manifest, directory = platformRegistryDirectory()) {
289
+ const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
290
+ const values = readPendingInstallationSecrets(manifest, directory);
291
+ if (!values) throw new Error("platform: Pending installation recovery material is missing.");
292
+ writeEncryptedRecoveryMaterial(manifest, "recovery", manifestPath.replace(/\.json$/, ".recovery.enc"), values, directory);
293
+ rmSync(manifestPath.replace(/\.json$/, ".secrets.enc"), { force: true });
294
+ rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
295
+ rmSync(manifestPath.replace(/\.json$/, ".recovery"), { force: true });
296
+ }
297
+ function readInstallationRecoverySecrets(manifest, directory = platformRegistryDirectory()) {
298
+ const pending = readPendingInstallationSecrets(manifest, directory);
299
+ if (!pending) return readRecoveryMaterial(manifest, "recovery", directory);
300
+ const updateState = pendingWorkerSecretUpdateState(manifest, pending.workerSecretUpdatesJson);
301
+ if (updateState === "stale") return readRecoveryMaterial(manifest, "recovery", directory);
302
+ if (updateState === "committed") return Object.fromEntries(Object.entries(pending).filter(([name]) => name !== "workerSecretUpdatesJson"));
303
+ return pending;
304
+ }
305
+ function pendingWorkerSecretUpdateState(manifest, value) {
306
+ if (!value) return "active";
307
+ let parsed;
308
+ try {
309
+ parsed = JSON.parse(value);
310
+ } catch {
311
+ return "active";
312
+ }
313
+ if (!parsed || typeof parsed !== "object" || !("schema" in parsed) || parsed.schema !== 1 || !("id" in parsed) || typeof parsed.id !== "string" || !("baselineGeneration" in parsed) || !Number.isSafeInteger(parsed.baselineGeneration) || !("generation" in parsed) || parsed.generation !== null && !Number.isSafeInteger(parsed.generation)) return "active";
314
+ return platformWorkerSecretUpdateIntentState(manifest, {
315
+ baselineGeneration: Number(parsed.baselineGeneration),
316
+ generation: parsed.generation === null ? null : Number(parsed.generation),
317
+ id: parsed.id
318
+ });
319
+ }
320
+ function platformWorkerSecretUpdateIntentState(manifest, intent) {
321
+ const latestGeneration = latestPlatformWorkerCutoverGeneration(manifest);
322
+ const latestState = manifest.steps.flatMap((step) => {
323
+ const match = /^worker-secret-updates:(\d+):(pending|committed)$/.exec(step.key);
324
+ return match ? [{
325
+ generation: Number(match[1]),
326
+ id: step.resultHash,
327
+ state: match[2]
328
+ }] : [];
329
+ }).sort((left, right) => right.generation - left.generation || (left.state === right.state ? 0 : left.state === "committed" ? -1 : 1))[0];
330
+ if (!latestState) return intent.generation === null && intent.baselineGeneration === latestGeneration ? "active" : "stale";
331
+ if (latestState.generation !== latestGeneration || latestState.id !== intent.id) return "stale";
332
+ return latestState.state === "committed" ? "committed" : "active";
333
+ }
334
+ function latestPlatformWorkerCutoverGeneration(manifest) {
335
+ return Math.max(0, ...manifest.steps.flatMap((step) => {
336
+ const match = /^worker-(?:cutover|secret-updates|traffic-state):(\d+)/.exec(step.key);
337
+ return match ? [Number(match[1])] : [];
338
+ }));
339
+ }
340
+ function removeInstallationRecoverySecrets(manifest, directory = platformRegistryDirectory()) {
341
+ const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
342
+ rmSync(manifestPath.replace(/\.json$/, ".recovery.enc"), { force: true });
343
+ rmSync(manifestPath.replace(/\.json$/, ".secrets.enc"), { force: true });
344
+ rmSync(manifestPath.replace(/\.json$/, ".recovery"), { force: true });
345
+ rmSync(manifestPath.replace(/\.json$/, ".secrets"), { force: true });
346
+ }
347
+ function readRecoveryMaterial(manifest, kind, directory) {
348
+ const manifestPath = installationManifestPath(manifest.account.id, manifest.id, directory);
349
+ const encryptedPath = manifestPath.replace(/\.json$/, `.${kind === "pending" ? "secrets" : "recovery"}.enc`);
350
+ try {
351
+ const envelope = parseRecoveryEnvelope(JSON.parse(readFileSync(encryptedPath, "utf8")));
352
+ const key = platformRecoveryKey(directory, false);
353
+ if (!key) throw new Error("the encryption key is unavailable; restore it from the system keychain or set VOID_PLATFORM_RECOVERY_KEY");
354
+ const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(envelope.iv, "base64"));
355
+ decipher.setAAD(recoveryAad(manifest, kind));
356
+ decipher.setAuthTag(Buffer.from(envelope.tag, "base64"));
357
+ const plaintext = Buffer.concat([decipher.update(Buffer.from(envelope.ciphertext, "base64")), decipher.final()]);
358
+ return parseRecoveryValues(JSON.parse(plaintext.toString("utf8")), `${kind} recovery material`);
359
+ } catch (error) {
360
+ if (error.code !== "ENOENT") throw new Error(`platform: Could not read encrypted ${kind} material: ${error instanceof Error ? error.message : String(error)}`);
361
+ }
362
+ const legacyPath = manifestPath.replace(/\.json$/, kind === "pending" ? ".secrets" : ".recovery");
363
+ try {
364
+ const values = parseRecoveryValues(JSON.parse(readFileSync(legacyPath, "utf8")), `legacy ${kind} recovery material`);
365
+ writeEncryptedRecoveryMaterial(manifest, kind, encryptedPath, values, directory);
366
+ rmSync(legacyPath, { force: true });
367
+ return values;
368
+ } catch (error) {
369
+ if (error.code === "ENOENT") return null;
370
+ throw new Error(`platform: Could not migrate legacy ${kind} material: ${error instanceof Error ? error.message : String(error)}`);
371
+ }
372
+ }
373
+ function writeEncryptedRecoveryMaterial(manifest, kind, path, values, directory) {
374
+ const key = platformRecoveryKey(directory, true);
375
+ const iv = randomBytes(12);
376
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
377
+ cipher.setAAD(recoveryAad(manifest, kind));
378
+ writeJsonAtomically(path, {
379
+ algorithm: "aes-256-gcm",
380
+ ciphertext: Buffer.concat([cipher.update(JSON.stringify(parseRecoveryValues(values, `${kind} recovery material`)), "utf8"), cipher.final()]).toString("base64"),
381
+ iv: iv.toString("base64"),
382
+ schemaVersion: PLATFORM_RECOVERY_ENVELOPE_VERSION,
383
+ tag: cipher.getAuthTag().toString("base64")
384
+ });
385
+ }
386
+ function recoveryAad(manifest, kind) {
387
+ return Buffer.from(`void-platform-recovery-v1\0${manifest.account.id}\0${manifest.id}\0${manifest.ownershipNonce}\0${kind}`);
388
+ }
389
+ function platformRecoveryKey(directory, create) {
390
+ const fromEnvironment = process.env.VOID_PLATFORM_RECOVERY_KEY;
391
+ if (fromEnvironment) return parseRecoveryKey(fromEnvironment, "VOID_PLATFORM_RECOVERY_KEY");
392
+ const account = `recovery:${createHash("sha256").update(resolve(directory)).digest("hex")}`;
393
+ const saved = readKeyringPassword(PLATFORM_RECOVERY_KEYRING_SERVICE, account);
394
+ if (saved) return parseRecoveryKey(saved, "system keychain recovery key");
395
+ if (!create) return null;
396
+ const generated = randomBytes(32);
397
+ if (!writeKeyringPassword(PLATFORM_RECOVERY_KEYRING_SERVICE, account, generated.toString("base64"))) throw new Error("platform: The system keychain is unavailable. Refusing to write platform secrets to disk. Configure a system keychain or set a base64-encoded 32-byte VOID_PLATFORM_RECOVERY_KEY from your secret manager.");
398
+ return generated;
399
+ }
400
+ function parseRecoveryKey(value, name) {
401
+ const key = Buffer.from(value, "base64");
402
+ if (key.byteLength !== 32 || key.toString("base64") !== value) throw new Error(`platform: ${name} must be a canonical base64-encoded 32-byte key.`);
403
+ return key;
404
+ }
405
+ function parseRecoveryEnvelope(value) {
406
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("encrypted recovery envelope must be an object");
407
+ const envelope = value;
408
+ if (envelope.schemaVersion !== PLATFORM_RECOVERY_ENVELOPE_VERSION || envelope.algorithm !== "aes-256-gcm" || typeof envelope.ciphertext !== "string" || typeof envelope.iv !== "string" || typeof envelope.tag !== "string") throw new Error("encrypted recovery envelope is invalid");
409
+ if (Buffer.from(envelope.iv, "base64").byteLength !== 12) throw new Error("encrypted recovery IV is invalid");
410
+ if (Buffer.from(envelope.tag, "base64").byteLength !== 16) throw new Error("encrypted recovery tag is invalid");
411
+ return envelope;
412
+ }
413
+ function parseRecoveryValues(value, name) {
414
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
415
+ const entries = Object.entries(value);
416
+ if (entries.some(([, entry]) => typeof entry !== "string")) throw new Error(`${name} values must be strings`);
417
+ return Object.fromEntries(entries);
418
+ }
419
+ function removePlatformConnectionForInstallation(installationId, directory = platformRegistryDirectory()) {
420
+ withRegistryLock(directory, () => {
421
+ const current = readRegistry(directory);
422
+ const connections = current.connections.filter((connection) => connection.installationId !== installationId);
423
+ writeJsonAtomically(join(directory, "registry.json"), {
424
+ activeConnectionId: current.activeConnectionId && connections.some((connection) => connection.id === current.activeConnectionId) ? current.activeConnectionId : connections[0]?.id ?? null,
425
+ connections,
426
+ schemaVersion: 1
427
+ });
428
+ });
429
+ }
430
+ //#endregion
431
+ export { writeKeyringPassword as S, selectPlatformConnection as _, listInstallationManifests as a, deleteKeyringPassword as b, platformCredentialAccount as c, readInstallationRecoverySecrets as d, readPendingInstallationSecrets as f, savePlatformConnection as g, resolveInstallationManifest as h, latestPlatformWorkerCutoverGeneration as i, platformWorkerSecretUpdateIntentState as l, removePlatformConnectionForInstallation as m, assertPlatformInstallationSlugAvailable as n, listPlatformConnections as o, removeInstallationRecoverySecrets as p, getActivePlatformConnection as r, normalizePlatformApiUrl as s, acquirePlatformLifecycleLock as t, promoteInstallationSecrets as u, writeInstallationManifest as v, readKeyringPassword as x, writePendingInstallationSecrets as y };
@@ -1,7 +1,7 @@
1
- import { o as join } from "./dist-BrsS7cai.mjs";
2
- import { n as readProjectPaths } from "./project-paths-SK8nMHPp.mjs";
3
- import { n as globSync } from "./dist-m40_XgNh.mjs";
4
- import { c as isIdentifier, r as getSsrServerEntryPath, u as isMemberExpression } from "./entry-DU3oDoQ3.mjs";
1
+ import { a as join } from "./dist-4WkAWhWx.mjs";
2
+ import { n as readProjectPaths } from "./project-paths-CKQ-Q5JS.mjs";
3
+ import { n as globSync } from "./dist-Bn8Kodjp.mjs";
4
+ import { c as isIdentifier, r as getSsrServerEntryPath, u as isMemberExpression } from "./entry-DdRFGK0y.mjs";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { parse } from "es-module-lexer/js";
7
7
  import { parseSync } from "vite";
@@ -0,0 +1,90 @@
1
+ //#region src/pages/prefetch.ts
2
+ const UNITS = {
3
+ ms: 1,
4
+ s: 1e3,
5
+ m: 6e4,
6
+ h: 36e5,
7
+ d: 864e5
8
+ };
9
+ function parseUnit(value) {
10
+ const match = value.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/);
11
+ if (!match) throw new Error(`prefetch: Invalid cacheFor value '${value}'. Use a number with ms, s, m, h, or d.`);
12
+ return Number(match[1]) * UNITS[match[2]];
13
+ }
14
+ function parseCacheFor(value) {
15
+ if (typeof value === "number") return {
16
+ stale: value,
17
+ expires: value
18
+ };
19
+ if (Array.isArray(value)) return {
20
+ stale: parseUnit(value[0]),
21
+ expires: parseUnit(value[1])
22
+ };
23
+ const ms = parseUnit(value);
24
+ return {
25
+ stale: ms,
26
+ expires: ms
27
+ };
28
+ }
29
+ var PrefetchCache = class {
30
+ entries = /* @__PURE__ */ new Map();
31
+ key(url, method = "GET") {
32
+ return `${method}:${url}`;
33
+ }
34
+ has(url, method = "GET") {
35
+ return this.get(url, method) !== null;
36
+ }
37
+ get(url, method = "GET") {
38
+ const entry = this.entries.get(this.key(url, method));
39
+ if (!entry) return null;
40
+ if (Date.now() >= entry.expiresAt && !entry.singleUse) {
41
+ this.entries.delete(this.key(url, method));
42
+ return null;
43
+ }
44
+ return entry;
45
+ }
46
+ isFresh(entry) {
47
+ return Date.now() < entry.staleAt;
48
+ }
49
+ isUsable(entry) {
50
+ return Date.now() < entry.expiresAt || entry.singleUse;
51
+ }
52
+ set(url, method, response, ttl) {
53
+ const k = this.key(url, method);
54
+ const existing = this.entries.get(k);
55
+ if (existing && this.isUsable(existing)) return;
56
+ const now = Date.now();
57
+ const singleUse = ttl.stale === 0 && ttl.expires === 0;
58
+ const entry = {
59
+ url,
60
+ method,
61
+ response,
62
+ staleAt: now + ttl.stale,
63
+ expiresAt: now + ttl.expires,
64
+ singleUse,
65
+ timer: null
66
+ };
67
+ if (!singleUse && ttl.expires > 0) entry.timer = setTimeout(() => this.entries.delete(k), ttl.expires);
68
+ this.entries.set(k, entry);
69
+ }
70
+ /** Mark entry as consumed — removes it if singleUse. */
71
+ consume(url, method = "GET") {
72
+ const entry = this.entries.get(this.key(url, method));
73
+ if (entry?.singleUse) {
74
+ if (entry.timer) clearTimeout(entry.timer);
75
+ this.entries.delete(this.key(url, method));
76
+ }
77
+ }
78
+ flush(url, method = "GET") {
79
+ const k = this.key(url, method);
80
+ const entry = this.entries.get(k);
81
+ if (entry?.timer) clearTimeout(entry.timer);
82
+ this.entries.delete(k);
83
+ }
84
+ flushAll() {
85
+ for (const entry of this.entries.values()) if (entry.timer) clearTimeout(entry.timer);
86
+ this.entries.clear();
87
+ }
88
+ };
89
+ //#endregion
90
+ export { parseCacheFor as n, PrefetchCache as t };
@@ -0,0 +1,31 @@
1
+ //#region src/pages/prefetch.d.ts
2
+ type CacheForResult = {
3
+ stale: number;
4
+ expires: number;
5
+ };
6
+ type CacheForInput = number | string | [string, string];
7
+ declare function parseCacheFor(value: CacheForInput): CacheForResult;
8
+ type CacheEntry = {
9
+ url: string;
10
+ method: string;
11
+ response: Promise<unknown>;
12
+ staleAt: number;
13
+ expiresAt: number;
14
+ singleUse: boolean;
15
+ timer: ReturnType<typeof setTimeout> | null;
16
+ };
17
+ declare class PrefetchCache {
18
+ private readonly entries;
19
+ private key;
20
+ has(url: string, method?: string): boolean;
21
+ get(url: string, method?: string): CacheEntry | null;
22
+ isFresh(entry: CacheEntry): boolean;
23
+ isUsable(entry: CacheEntry): boolean;
24
+ set(url: string, method: string, response: Promise<unknown>, ttl: CacheForResult): void;
25
+ /** Mark entry as consumed — removes it if singleUse. */
26
+ consume(url: string, method?: string): void;
27
+ flush(url: string, method?: string): void;
28
+ flushAll(): void;
29
+ }
30
+ //#endregion
31
+ export { parseCacheFor as a, PrefetchCache as i, CacheForInput as n, CacheForResult as r, CacheEntry as t };
@@ -1,5 +1,6 @@
1
- import { A as outro, D as log, E as intro, k as note, r as cliTitle } from "./output-B0cfNSx5.mjs";
2
- import { prepareProject } from "./prepare-CtDJjoOj.mjs";
1
+ import { r as cliTitle } from "./output-urU86XeT.mjs";
2
+ import { N as note, O as intro, P as outro, j as log } from "./dist-Dn6nn2IU.mjs";
3
+ import { t as prepareProject } from "./prepare-pcWcxSCh.mjs";
3
4
  //#region src/cli/prepare.ts
4
5
  async function runPrepareCommand(root, _args) {
5
6
  console.log();
@@ -0,0 +1,2 @@
1
+ import { t as prepareProject } from "./prepare-pcWcxSCh.mjs";
2
+ export { prepareProject };