void 1.4.0 → 1.6.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 (455) hide show
  1. package/README.md +1 -1
  2. package/dist/{account-cmd-HP8bixYo.mjs → account-cmd-DRhmCWcm.mjs} +7 -8
  3. package/dist/{action-key-XZ9HkWAO.mjs → action-key-XtKKbbsi.mjs} +1 -2
  4. package/dist/{agents-CuNtT0D_.mjs → agents-DRo8gzni.mjs} +2 -3
  5. package/dist/{application-analysis-DDOQwiXk.mjs → application-analysis-HRFsZOv3.mjs} +18 -24
  6. package/dist/{application-routing-4719u_kf.mjs → application-routing-P4TggvWp.mjs} +2 -3
  7. package/dist/{ast-CsZ_q_gc.mjs → ast-Cv0JwXqb.mjs} +1 -2
  8. package/dist/{ast-bindings-C3yaPs1y.mjs → ast-bindings-BkivMJIo.mjs} +6 -11
  9. package/dist/{atomic-write-Dq6R0BPN.mjs → atomic-write-DA6eD1Kp.mjs} +1 -2
  10. package/dist/{auth-g2TQbDLD.d.mts → auth-CH4PLAX1.d.mts} +0 -2
  11. package/dist/{auth-Cbqi1iVX.mjs → auth-CL-p_rqV.mjs} +1 -1
  12. package/dist/{auth-B6iOCjKI.mjs → auth-Dy8svcqQ.mjs} +6 -7
  13. package/dist/{auth-3sGB0zJ1.mjs → auth-YVjBX5NY.mjs} +1 -2
  14. package/dist/{auth-client-Bawdj38n.d.mts → auth-client-6-Ft9i9T.d.mts} +0 -2
  15. package/dist/{auth-client-BWBT8HLp.mjs → auth-client-DwCdwKbw.mjs} +1 -2
  16. package/dist/{auth-client-react-CMLwT2xI.mjs → auth-client-react-CJdeErvM.mjs} +1 -2
  17. package/dist/{auth-client-react-7GFffu8R.d.mts → auth-client-react-DvQLe5Zb.d.mts} +0 -2
  18. package/dist/{auth-client-solid-UoreJWZG.mjs → auth-client-solid-BRvgvp6h.mjs} +1 -2
  19. package/dist/{auth-client-solid-DyTFL4cq.d.mts → auth-client-solid-P9pEtKGp.d.mts} +0 -2
  20. package/dist/{auth-client-svelte-zetW0KIH.d.mts → auth-client-svelte-B5j8irT6.d.mts} +0 -2
  21. package/dist/{auth-client-svelte-Cv_WvrRk.mjs → auth-client-svelte-BSqUCEed.mjs} +1 -2
  22. package/dist/{auth-client-vue-bChShbQP.d.mts → auth-client-vue-BEiAfavk.d.mts} +0 -2
  23. package/dist/{auth-client-vue-CFk7Xbv3.mjs → auth-client-vue-CPkbRtOO.mjs} +1 -2
  24. package/dist/{auth-link-CedYpDCy.mjs → auth-link-CVXP1G6G.mjs} +7 -8
  25. package/dist/{auth-migrations-BO27GDNr.mjs → auth-migrations-DDeifS3v.mjs} +1 -2
  26. package/dist/{auth-router-vafo7x8w.mjs → auth-router-D1pGdbvB.mjs} +6 -7
  27. package/dist/{base64-DVrOndmI.mjs → base64-ikl9yBy3.mjs} +1 -2
  28. package/dist/{better-auth-shared-BHB8kiTE.d.mts → better-auth-shared-BJyG2mH0.d.mts} +2 -6
  29. package/dist/{better-auth-shared-7FM3Uk2N.mjs → better-auth-shared-C958aM7W.mjs} +31 -7
  30. package/dist/{build-cmd-9vUAQ1_V.mjs → build-cmd-DmjbuT6d.mjs} +7 -8
  31. package/dist/{cache-jvwLNb0h.mjs → cache-2khBO1MR.mjs} +7 -8
  32. package/dist/{cancel-deploy-Dw0UmWKO.mjs → cancel-deploy-_itbbvY3.mjs} +6 -7
  33. package/dist/{cf-access-CWP4avfP.mjs → cf-access-BmBT2h8_.mjs} +3 -4
  34. package/dist/{cf-access-BM9G0lhO.mjs → cf-access-pejlJmuy.mjs} +1 -2
  35. package/dist/{cf-build-output-XpNR9zoh.mjs → cf-build-output-B1C8U83u.mjs} +41 -314
  36. package/dist/cf-build-output-CmDOcA7K.mjs +1 -0
  37. package/dist/{cf-command-values-ByHk0xg4.mjs → cf-command-values-Ccl-zRhl.mjs} +10 -7
  38. package/dist/cf-config-migrate-Dy8MrKgF.mjs +326 -0
  39. package/dist/{cf-worker-settings-Dg27RzyT.mjs → cf-worker-settings-CARs4Wy9.mjs} +3 -5
  40. package/dist/cli/cli.mjs +66 -76
  41. package/dist/cli/cloudflare-operation-process.mjs +14 -18
  42. package/dist/cli/env-schema-probe.d.mts +1 -5
  43. package/dist/cli/env-schema-probe.mjs +4 -5
  44. package/dist/client-CEtr5UOR.mjs +1 -0
  45. package/dist/{client-B3LnB_bE.mjs → client-CoxPEhJq.mjs} +15 -13
  46. package/dist/{cloudflare-auth-DyD_kVFr.mjs → cloudflare-auth-CEu-1Ps_.mjs} +2 -3
  47. package/dist/{cloudflare-cmd-D-b_u3T4.mjs → cloudflare-cmd-fZ6AMSWk.mjs} +7 -8
  48. package/dist/{cloudflare-config-CH1AylZT.mjs → cloudflare-config-eQunqX6A.mjs} +22 -17
  49. package/dist/{cloudflare-connect-zTJh8UnN.mjs → cloudflare-connect-9OZe4XVQ.mjs} +5 -6
  50. package/dist/{cloudflare-operations-Bc-7fN44.mjs → cloudflare-operations-CrskD4_O.mjs} +8 -9
  51. package/dist/{cloudflare-operations-BtulCNOg.mjs → cloudflare-operations-oLvAd9Nd.mjs} +1 -1
  52. package/dist/{cloudflare-process-8jEYIeim.mjs → cloudflare-process-DjJ638A-.mjs} +7 -9
  53. package/dist/{cloudflare-user-output-Q-k0QoNQ.mjs → cloudflare-user-output-zEwuGrEJ.mjs} +1 -2
  54. package/dist/collect-8i0wU63d.mjs +1 -0
  55. package/dist/{collect-Dew86qce.mjs → collect-C6Blu9yw.mjs} +2 -3
  56. package/dist/{config-tqMM6DwY.mjs → config-BBlVXZCU.mjs} +5 -6
  57. package/dist/{config-OFOAimzt.mjs → config-BITKQ3O6.mjs} +5 -5
  58. package/dist/{config-BV2ASlpn.mjs → config-BgysUhnm.mjs} +1 -1
  59. package/dist/{config-CAdZVTLN.d.mts → config-CPxJmt4M.d.mts} +4 -6
  60. package/dist/{config-D-6q7EBH.mjs → config-WlvEcL82.mjs} +3 -4
  61. package/dist/config-entry.d.mts +1 -3
  62. package/dist/config-entry.mjs +1 -2
  63. package/dist/{connect-BOM6zvFX.mjs → connect-CKvmkl2R.mjs} +10 -11
  64. package/dist/{create-project-C2K0DN2O.mjs → create-project-BiMmR5wA.mjs} +1 -1
  65. package/dist/{create-project-Bxd02EHN.mjs → create-project-Bq0M8MtO.mjs} +9 -11
  66. package/dist/{database-provider-Cx525bwX.mjs → database-provider-DkZo4VwN.mjs} +1 -2
  67. package/dist/database-provider.d.mts +1 -3
  68. package/dist/database-provider.mjs +1 -1
  69. package/dist/{db-Cdvr3zwG.mjs → db-cq5RW4Vy.mjs} +52 -54
  70. package/dist/{db-types-0eCiqYb1.mjs → db-types-C_8amnB0.mjs} +3 -4
  71. package/dist/{delete-lETE6Tpt.mjs → delete-CY4L8fi2.mjs} +7 -8
  72. package/dist/deploy-B029oHlE.mjs +2 -0
  73. package/dist/{deploy-CdM-LAxX.mjs → deploy-D_gEojD2.mjs} +144 -136
  74. package/dist/{deploy-managed-static-DjeBFG2c.mjs → deploy-managed-static-BHVbB_-A.mjs} +33 -40
  75. package/dist/{deploy-transport-DIq_gFTP.mjs → deploy-transport-DEyOUfac.mjs} +6 -7
  76. package/dist/deploy.d.mts +1 -3
  77. package/dist/deploy.mjs +11 -11
  78. package/dist/{dev-inbox-D0jxye_D.mjs → dev-inbox-CUUS6iUg.mjs} +3 -4
  79. package/dist/discover-D4mQthao.mjs +1 -0
  80. package/dist/{discover-LaV0tbIu.mjs → discover-Dhkzxgdt.mjs} +3 -4
  81. package/dist/{dispatch-CLa2LThw.mjs → dispatch-BNLB5_Gm.mjs} +12 -15
  82. package/dist/{dist-Cegxq8gs.mjs → dist-B6eN80gc.mjs} +199 -118
  83. package/dist/{dist-D15hFhP0.mjs → dist-BWNkVq50.mjs} +8 -15
  84. package/dist/{dist-Cor9XGoz.mjs → dist-D23AAMxT.mjs} +9 -16
  85. package/dist/{dist-ipQi0Q8y.mjs → dist-DMYe8CZJ.mjs} +1 -2
  86. package/dist/{dist-B1PLt4_8.mjs → dist-eV_Ep60B.mjs} +1 -1
  87. package/dist/{domain-DyhNtdYf.mjs → domain-BlH90Ods.mjs} +8 -9
  88. package/dist/{dotenv-CNazY3-w.mjs → dotenv-CEI8hapP.mjs} +1 -2
  89. package/dist/{drizzle-9TubSZvI.mjs → drizzle-C8MPqt5m.mjs} +1 -1
  90. package/dist/{drizzle-BQfyvQKX.mjs → drizzle-lFdzSEa9.mjs} +2 -3
  91. package/dist/{email-B9ayYQEG.mjs → email-BHY72ixO.mjs} +3 -4
  92. package/dist/{email-DM2wDcBN.mjs → email-Bkq8ZL1p.mjs} +14 -15
  93. package/dist/{email-cloudflare-PMbAev9Q.mjs → email-cloudflare-MvJIxrwx.mjs} +18 -123
  94. package/dist/{email-protocol-D9nTvhCp.mjs → email-protocol-DTs_TjCS.mjs} +1 -2
  95. package/dist/{entry-BEM8ZuGP.mjs → entry-CBZsCy3O.mjs} +5 -6
  96. package/dist/{env-78hbN-oI.mjs → env-AvuCSeCH.mjs} +10 -11
  97. package/dist/{env-BaMz0j7H.mjs → env-CuzZZyjB.mjs} +3 -4
  98. package/dist/{env-0jrMQJI_.mjs → env-DtKg5G26.mjs} +2 -3
  99. package/dist/{env-helpers--wFmQ_5Q.mjs → env-helpers-Dj_SIwPu.mjs} +1 -2
  100. package/dist/{env-helpers-CyKtOBpj.d.mts → env-helpers-U56xuFgL.d.mts} +1 -3
  101. package/dist/{env-public-6lqiSD2b.d.mts → env-public-CeNeO_AT.d.mts} +2 -4
  102. package/dist/{env-raw-D74P4ebM.mjs → env-raw-e8qgqAzQ.mjs} +1 -2
  103. package/dist/{env-types-BicfKBhV.mjs → env-types-DqzVBKnS.mjs} +4 -5
  104. package/dist/{env-validation-BUfFZ6bt.mjs → env-validation-C8Cmvas0.mjs} +1 -1
  105. package/dist/{env-validation-B3VobvXm.mjs → env-validation-GV1oD4EV.mjs} +9 -10
  106. package/dist/{error-pages-CLIJ7aYq.mjs → error-pages-COVBnzK7.mjs} +6 -12
  107. package/dist/{fetch-CUX0tB78.d.mts → fetch-B-gLGYVl.d.mts} +0 -4
  108. package/dist/{fetch-CtESUYWd.mjs → fetch-C8yhLoF3.mjs} +3 -4
  109. package/dist/{fetch-error-Bw0n-IY-.mjs → fetch-error-DmlRM6e4.mjs} +2 -4
  110. package/dist/{fetch-stream-BspOeTAI.mjs → fetch-stream-DafNtVJC.mjs} +4 -5
  111. package/dist/{fetch-stream-DfkAzZf-.d.mts → fetch-stream-DuwxWmBM.d.mts} +1 -3
  112. package/dist/{gen-CFmsUsW1.mjs → gen-BD-dfjxY.mjs} +12 -13
  113. package/dist/gen-CIHXh9I8.mjs +1 -0
  114. package/dist/{generate-DkEb9rL-.mjs → generate-BOp1g1H_.mjs} +1 -1
  115. package/dist/{generate-B1m4Cm4n.mjs → generate-CWb8aOsm.mjs} +4 -5
  116. package/dist/{generated-wrangler-config-DeWj5F9Y.mjs → generated-wrangler-config-CoDaaFsA.mjs} +1 -2
  117. package/dist/{git-metadata-D-gurjzG.mjs → git-metadata-Cukp5kV5.mjs} +1 -2
  118. package/dist/{github-cmd-De-_IWbM.mjs → github-cmd-CA-lBdkn.mjs} +8 -9
  119. package/dist/{handler-BHktmuTL.d.mts → handler-BR6Tvjkp.d.mts} +18 -26
  120. package/dist/{handler-BZ1t7-Rv.mjs → handler-CKeTtYID.mjs} +6 -17
  121. package/dist/{head-D2VF4ApL.mjs → head-5XPcnG-j.mjs} +1 -2
  122. package/dist/{head-C8K_iGe6.d.mts → head-MeF_5M_3.d.mts} +0 -2
  123. package/dist/headers-CuTEdP9C.mjs +445 -0
  124. package/dist/{help-CKbrhZha.mjs → help-1OCFDsRr.mjs} +28 -12
  125. package/dist/help-Ba8Dq5-r.mjs +1 -0
  126. package/dist/{inbound-Da7XsjH3.d.mts → inbound-BHt4dIlL.d.mts} +16 -9
  127. package/dist/{inbound-VrOLqwZY.mjs → inbound-CdO-qY0w.mjs} +6 -81
  128. package/dist/index.d.mts +23 -13
  129. package/dist/index.mjs +495 -223
  130. package/dist/{info-Yg0-V5Rs.mjs → info-CJxua_db.mjs} +6 -7
  131. package/dist/{init-CDiJQycf.mjs → init-B-4CluYx.mjs} +43 -59
  132. package/dist/{isr-config-fZaJJ8t7.mjs → isr-config-Czzb4mIq.mjs} +5 -55
  133. package/dist/{limits-D0vD1M9A.mjs → limits-CrHLm5Tk.mjs} +1 -2
  134. package/dist/{limits-CFsDKQvU.d.mts → limits-_xIf5z_P.d.mts} +0 -2
  135. package/dist/{link-Dllip08S.mjs → link-DAXOT-G_.mjs} +8 -9
  136. package/dist/{list-BYRP6am0.mjs → list-BYSOo9fm.mjs} +8 -9
  137. package/dist/{live-BllfDuzA.d.mts → live-0xrcVpyq.d.mts} +2 -4
  138. package/dist/{live-BcHoTDFe.mjs → live-DF4HUl2m.mjs} +5 -7
  139. package/dist/{load-user-env-DD5qveNU.mjs → load-user-env-CSwdofj0.mjs} +1 -2
  140. package/dist/{local-d1-CAwAs9GH.mjs → local-d1-BLgsNUj9.mjs} +4 -5
  141. package/dist/{log-BMwmN5Ae.mjs → log-D9hwSySP.mjs} +3 -4
  142. package/dist/login-BpbYeu-n.mjs +1 -0
  143. package/dist/{login-PcFy5mlC.mjs → login-CJopTWX4.mjs} +6 -7
  144. package/dist/{logs-DmJTBhed.mjs → logs-DE0weBsR.mjs} +19 -18
  145. package/dist/{migrate-B8S2xTcb.mjs → migrate-ChHHZBTi.mjs} +20 -16
  146. package/dist/migrate-HdA6Kh2p.mjs +1 -0
  147. package/dist/{migration-handler-CwlEQUoo.d.mts → migration-handler-D8mDx3Ew.d.mts} +0 -4
  148. package/dist/{migration-handler-Cg0Y4EPu.mjs → migration-handler-DCehTlWs.mjs} +1 -2
  149. package/dist/{mime-BAyHPskU.mjs → mime-CtP6-qAF.mjs} +145 -18
  150. package/dist/{mysql-migration-sql-BIS5vbNk.mjs → mysql-migration-sql-CI9VTwjt.mjs} +3 -5
  151. package/dist/{neon-DTZr7Bu7.mjs → neon-CJzQSycr.mjs} +2 -3
  152. package/dist/nitro.d.mts +0 -2
  153. package/dist/nitro.mjs +5 -6
  154. package/dist/{node-CDOPrGSl.mjs → node-CZ6lGNLn.mjs} +8 -9
  155. package/dist/{operator-args-BsJIYXaT.mjs → operator-args-D79WQP70.mjs} +2 -3
  156. package/dist/{operator-auth-Cr2zCc-J.mjs → operator-auth-CfDcmzpo.mjs} +2 -3
  157. package/dist/{operator-client-C-ROjk1I.mjs → operator-client-BIY4-N_6.mjs} +3 -4
  158. package/dist/{operator-cmd-DmkmS2wL.mjs → operator-cmd-BUqsdk2K.mjs} +32 -15
  159. package/dist/operator-cmd-wBYyp8iQ.mjs +1 -0
  160. package/dist/{output-BpgYODYx.mjs → output-BCdLioKP.mjs} +4 -5
  161. package/dist/output-E6gecbbV.mjs +1 -0
  162. package/dist/{package-json-BjYqR-So.mjs → package-json-DvS6IFRv.mjs} +2 -3
  163. package/dist/pages/client.d.mts +147 -31
  164. package/dist/pages/client.mjs +199 -43
  165. package/dist/pages/head.d.mts +1 -1
  166. package/dist/pages/head.mjs +1 -1
  167. package/dist/pages/index.d.mts +25 -18
  168. package/dist/pages/index.mjs +24 -12
  169. package/dist/pages/islands-plugin.d.mts +75 -13
  170. package/dist/pages/islands-plugin.mjs +92 -7
  171. package/dist/pages/prefetch.d.mts +2 -2
  172. package/dist/pages/prefetch.mjs +1 -1
  173. package/dist/pages/protocol.d.mts +2 -2
  174. package/dist/pages/protocol.mjs +2 -2
  175. package/dist/pages/serialize.d.mts +1 -1
  176. package/dist/pages/serialize.mjs +1 -1
  177. package/dist/{pg-J2HbZIkX.mjs → pg-DoyPxa_X.mjs} +1 -2
  178. package/dist/{picocolors-BsDfhxIw.mjs → picocolors-D1NxSLw-.mjs} +2 -3
  179. package/dist/{plan-BhLO2p4w.mjs → plan-BOD70XGS.mjs} +1 -2
  180. package/dist/plan-CQ-N4gws.mjs +1 -0
  181. package/dist/platform-args-C7XUw9mw.mjs +1 -0
  182. package/dist/{platform-args-BMD2gjc_.mjs → platform-args-Cx1M-7bq.mjs} +22 -11
  183. package/dist/{platform-auth-config-CImnfohz.mjs → platform-auth-config-K4m_LE8b.mjs} +10 -11
  184. package/dist/{platform-auth-protection-BogLhtHi.mjs → platform-auth-protection-KF5Vo-1I.mjs} +10 -11
  185. package/dist/{platform-auth-recovery-B-mEaWEi.mjs → platform-auth-recovery-BOdFrl7R.mjs} +9 -11
  186. package/dist/{platform-cmd-CV8NxIIn.mjs → platform-cmd-DpCHawGF.mjs} +1 -1
  187. package/dist/{platform-cmd-DZK2ixMl.mjs → platform-cmd-Ds3EAV5t.mjs} +13 -13
  188. package/dist/{platform-discovery-CHhNs8Nn.mjs → platform-discovery-B0eZjZ3B.mjs} +2 -3
  189. package/dist/{platform-domain-CRvelPGE.mjs → platform-domain-rWJshybd.mjs} +7 -8
  190. package/dist/{platform-lifecycle-DwXq7kZt.mjs → platform-lifecycle-BH34I0rh.mjs} +1 -1
  191. package/dist/{platform-lifecycle-CPYY7E9B.mjs → platform-lifecycle-D9RdGub1.mjs} +110 -110
  192. package/dist/{platform-management-BOnGbMSM.mjs → platform-management-BRefdHGD.mjs} +27 -11
  193. package/dist/{platform-management-lXdgGgAM.mjs → platform-management-BfLW0Zlo.mjs} +1 -1
  194. package/dist/{platform-plans-config-CeydDSj0.mjs → platform-plans-config-Dx1agneU.mjs} +5 -6
  195. package/dist/{platform-recovery-noaALXnE.mjs → platform-recovery-DZuZGJtt.mjs} +5 -6
  196. package/dist/{platform-registry-B9mWX9LO.mjs → platform-registry-DZ_2Xuqd.mjs} +4 -6
  197. package/dist/platform-runtime-logs-CdJGnk3f.mjs +68 -0
  198. package/dist/{platform-setup-Ca53gtt0.mjs → platform-setup-Vw1AaUN8.mjs} +19 -7
  199. package/dist/{plugin-inference-CeiB6BG5.mjs → plugin-inference-CdLbxZL_.mjs} +16 -24
  200. package/dist/{prefetch-Bsc_Pb6c.mjs → prefetch-Dx2jIbtg.mjs} +20 -3
  201. package/dist/{prefetch-Ce6la4EI.d.mts → prefetch-NdNeubbH.d.mts} +7 -3
  202. package/dist/{prepare-D604Yiyr.mjs → prepare-BJW-f1f1.mjs} +13 -14
  203. package/dist/{prepare-BuOS18AM.mjs → prepare-BMGeKL16.mjs} +4 -5
  204. package/dist/prepare-BdxJJCMv.mjs +1 -0
  205. package/dist/{prerender-render-CaShbHJ3.mjs → prerender-render-RlAj6hh8.mjs} +2 -3
  206. package/dist/prerender-render.d.mts +1 -3
  207. package/dist/prerender-render.mjs +1 -1
  208. package/dist/{project-rqDnVsJN.mjs → project-CLwxcEdq.mjs} +3 -4
  209. package/dist/{project-zdB3fs9G.mjs → project-DVsTAWFh.mjs} +1 -1
  210. package/dist/{project-cmd-DBYqAIbe.mjs → project-cmd-B_bUyZ3J.mjs} +21 -23
  211. package/dist/{project-paths-DGu_QZ_Q.mjs → project-paths-CdGv9Tmi.mjs} +3 -5
  212. package/dist/project-slug-BUy0lmyR.mjs +1 -0
  213. package/dist/{project-slug-23TpquG4.mjs → project-slug-CO6ci9XG.mjs} +0 -1
  214. package/dist/{project-team-BjCLgTRC.mjs → project-team-MjT5K4rQ.mjs} +7 -8
  215. package/dist/{project-token-BB6PwaA9.mjs → project-token-BKHGwY3k.mjs} +7 -8
  216. package/dist/{project-tsconfig-CVvk6Z_e.mjs → project-tsconfig-Cf2NFjlM.mjs} +4 -6
  217. package/dist/{project-zero-trust-CWDh1P_t.mjs → project-zero-trust-Bzdd05-h.mjs} +7 -8
  218. package/dist/{protocol-DimNxVRr.mjs → protocol-COyySMki.mjs} +135 -113
  219. package/dist/{protocol-D5XDySYu.d.mts → protocol-CkwjASep.d.mts} +4 -6
  220. package/dist/{providers-BNKRacMr.d.mts → providers-D5P8j_8D.d.mts} +0 -2
  221. package/dist/{providers-BUHwJlmM.mjs → providers-ZARwX2cL.mjs} +1 -2
  222. package/dist/{provision-DztLJ97X.mjs → provision-BbCzpbXs.mjs} +6 -7
  223. package/dist/{provision-DfxLCg-d.mjs → provision-DQF6Kw-6.mjs} +1 -1
  224. package/dist/{queues-BWKt1Xo4.d.mts → queues-DdM42xXW.d.mts} +0 -2
  225. package/dist/{r2-conditions-B8xUgJRc.mjs → r2-conditions-BqkQNt2n.mjs} +1 -2
  226. package/dist/{requests-D_pbzDyz.mjs → requests-daJmVpjk.mjs} +6 -7
  227. package/dist/resolve-project-CgfjtOwz.mjs +1 -0
  228. package/dist/{resolve-project-Xoi6eTWY.mjs → resolve-project-D0YNnJfm.mjs} +4 -5
  229. package/dist/{resource-name-C7LVpcRm.mjs → resource-name-DlJ9QXzg.mjs} +1 -2
  230. package/dist/{response-Tn7rU0MV.mjs → response-HmNjB30w.mjs} +1 -2
  231. package/dist/{rollback-CjfIYsJx.mjs → rollback-BgL0wY1J.mjs} +7 -8
  232. package/dist/{rolldown-runtime-3h0WiCiA.mjs → rolldown-runtime-uD8oG6U2.mjs} +1 -2
  233. package/dist/{route-types-DvEGmPif.mjs → route-types-CZc1YXjF.mjs} +80 -9
  234. package/dist/route-url-CRDF-I0I.mjs +57 -0
  235. package/dist/route-url-C_YIH_zO.d.mts +37 -0
  236. package/dist/routes-stub.d.mts +8 -3
  237. package/dist/routes-stub.mjs +1 -1
  238. package/dist/{routing-assets-DdSFxoLp.mjs → routing-assets-DJIVOrCh.mjs} +1 -2
  239. package/dist/{runner-3uGC-oLF.mjs → runner-5MCSimKx.mjs} +5 -6
  240. package/dist/{runner-WCdfeI0q.mjs → runner-QMeOpScZ.mjs} +1 -1
  241. package/dist/{runner-mysql-BcHnLUuM.mjs → runner-mysql-0zVmB1JW.mjs} +1 -1
  242. package/dist/{runner-mysql-BWmbk5IE.mjs → runner-mysql-Bdmsp_x4.mjs} +3 -4
  243. package/dist/{runner-pg-Cgp-cr_p.mjs → runner-pg-2pjltt0t.mjs} +1 -1
  244. package/dist/{runner-pg-Cr3qrqi4.mjs → runner-pg-mYc75KfH.mjs} +2 -3
  245. package/dist/runtime/ai.d.mts +0 -4
  246. package/dist/runtime/ai.mjs +6 -8
  247. package/dist/runtime/auth-client-react.d.mts +1 -1
  248. package/dist/runtime/auth-client-react.mjs +1 -1
  249. package/dist/runtime/auth-client-solid.d.mts +1 -1
  250. package/dist/runtime/auth-client-solid.mjs +1 -1
  251. package/dist/runtime/auth-client-svelte.d.mts +1 -1
  252. package/dist/runtime/auth-client-svelte.mjs +1 -1
  253. package/dist/runtime/auth-client-vue.d.mts +1 -1
  254. package/dist/runtime/auth-client-vue.mjs +1 -1
  255. package/dist/runtime/auth-client.d.mts +1 -1
  256. package/dist/runtime/auth-client.mjs +1 -1
  257. package/dist/runtime/auth.d.mts +1 -1
  258. package/dist/runtime/auth.mjs +1 -1
  259. package/dist/runtime/better-auth-mysql.d.mts +2 -4
  260. package/dist/runtime/better-auth-mysql.mjs +3 -4
  261. package/dist/runtime/better-auth-pg.d.mts +2 -4
  262. package/dist/runtime/better-auth-pg.mjs +4 -5
  263. package/dist/runtime/better-auth.d.mts +2 -4
  264. package/dist/runtime/better-auth.mjs +3 -4
  265. package/dist/runtime/client-react.d.mts +4 -4
  266. package/dist/runtime/client-react.mjs +4 -4
  267. package/dist/runtime/client-solid.d.mts +4 -4
  268. package/dist/runtime/client-solid.mjs +4 -4
  269. package/dist/runtime/client-svelte.d.mts +4 -4
  270. package/dist/runtime/client-svelte.mjs +4 -4
  271. package/dist/runtime/client-vue.d.mts +4 -4
  272. package/dist/runtime/client-vue.mjs +4 -4
  273. package/dist/runtime/client.d.mts +4 -4
  274. package/dist/runtime/client.mjs +4 -4
  275. package/dist/runtime/db.d.mts +0 -2
  276. package/dist/runtime/db.mjs +2 -3
  277. package/dist/runtime/durable.d.mts +0 -2
  278. package/dist/runtime/durable.mjs +3 -4
  279. package/dist/runtime/email/testing.d.mts +1 -5
  280. package/dist/runtime/email/testing.mjs +5 -6
  281. package/dist/runtime/email-protocol.d.mts +0 -2
  282. package/dist/runtime/email-protocol.mjs +1 -1
  283. package/dist/runtime/email.d.mts +1 -5
  284. package/dist/runtime/email.mjs +6 -7
  285. package/dist/runtime/env-public-client.d.mts +1 -3
  286. package/dist/runtime/env-public-client.mjs +2 -3
  287. package/dist/runtime/env-public.d.mts +2 -2
  288. package/dist/runtime/env-public.mjs +5 -7
  289. package/dist/runtime/env.d.mts +0 -4
  290. package/dist/runtime/env.mjs +1 -1
  291. package/dist/runtime/fetch-server.d.mts +1 -3
  292. package/dist/runtime/fetch-server.mjs +3 -4
  293. package/dist/runtime/fetch-stream.d.mts +2 -2
  294. package/dist/runtime/fetch-stream.mjs +2 -2
  295. package/dist/runtime/fetch.d.mts +1 -1
  296. package/dist/runtime/fetch.mjs +2 -2
  297. package/dist/runtime/handler.d.mts +1 -1
  298. package/dist/runtime/handler.mjs +2 -2
  299. package/dist/runtime/isr.d.mts +1 -3
  300. package/dist/runtime/isr.mjs +2 -3
  301. package/dist/runtime/kv.d.mts +1 -3
  302. package/dist/runtime/kv.mjs +2 -3
  303. package/dist/runtime/limits.d.mts +1 -1
  304. package/dist/runtime/limits.mjs +1 -1
  305. package/dist/runtime/live-client.d.mts +1 -3
  306. package/dist/runtime/live-client.mjs +1 -2
  307. package/dist/runtime/live-server.d.mts +0 -2
  308. package/dist/runtime/live-server.mjs +3 -4
  309. package/dist/runtime/live.d.mts +1 -1
  310. package/dist/runtime/live.mjs +1 -1
  311. package/dist/runtime/log.d.mts +3 -3
  312. package/dist/runtime/log.mjs +26 -18
  313. package/dist/runtime/migration-handler-mysql.d.mts +2 -4
  314. package/dist/runtime/migration-handler-mysql.mjs +2 -3
  315. package/dist/runtime/migration-handler-pg.d.mts +2 -4
  316. package/dist/runtime/migration-handler-pg.mjs +2 -3
  317. package/dist/runtime/migration-handler.d.mts +1 -1
  318. package/dist/runtime/migration-handler.mjs +1 -1
  319. package/dist/runtime/queues.d.mts +1 -1
  320. package/dist/runtime/queues.mjs +2 -3
  321. package/dist/runtime/remote/binding-handler.d.mts +1 -3
  322. package/dist/runtime/remote/binding-handler.mjs +3 -4
  323. package/dist/runtime/remote/index.d.mts +1 -3
  324. package/dist/runtime/remote/index.mjs +8 -13
  325. package/dist/runtime/response.d.mts +1 -3
  326. package/dist/runtime/response.mjs +1 -1
  327. package/dist/runtime/route-url.d.mts +2 -2
  328. package/dist/runtime/route-url.mjs +1 -1
  329. package/dist/runtime/routing.d.mts +8 -11
  330. package/dist/runtime/routing.mjs +52 -32
  331. package/dist/runtime/sandbox-container.d.mts +1 -1
  332. package/dist/runtime/sandbox-container.mjs +1 -1
  333. package/dist/runtime/sandbox.d.mts +2 -2
  334. package/dist/runtime/sandbox.mjs +5 -6
  335. package/dist/runtime/seed.d.mts +0 -2
  336. package/dist/runtime/seed.mjs +1 -2
  337. package/dist/runtime/sse-client.d.mts +1 -3
  338. package/dist/runtime/sse-client.mjs +1 -2
  339. package/dist/runtime/sse.d.mts +1 -3
  340. package/dist/runtime/sse.mjs +1 -1
  341. package/dist/runtime/storage.d.mts +1 -3
  342. package/dist/runtime/storage.mjs +2 -3
  343. package/dist/runtime/validator.d.mts +1 -1
  344. package/dist/runtime/validator.mjs +1 -1
  345. package/dist/runtime/ws-server.d.mts +3 -5
  346. package/dist/runtime/ws-server.mjs +3 -4
  347. package/dist/runtime/ws.d.mts +1 -1
  348. package/dist/runtime/ws.mjs +3 -4
  349. package/dist/{sandbox-q3waMc2T.d.mts → sandbox-DE1WsxuB.d.mts} +2 -4
  350. package/dist/{sandbox-container-a9LRUtii.mjs → sandbox-container-BuxhwCgt.mjs} +1 -2
  351. package/dist/{sandbox-container-ChQRum-j.d.mts → sandbox-container-CZFZdMso.d.mts} +0 -2
  352. package/dist/{scan-N9WzdcAl.mjs → scan-X2rDDRNa.mjs} +49 -35
  353. package/dist/{secret-3X0PxmuX.mjs → secret-CPq-B_vp.mjs} +17 -15
  354. package/dist/{serialize-YHvlcG3Q.mjs → serialize-DUuYuaY3.mjs} +2 -4
  355. package/dist/{serialize-DtR8Vwa_.d.mts → serialize-I4EmS-Wf.d.mts} +0 -2
  356. package/dist/{skills-CrUO3PJ0.mjs → skills-D393E4lB.mjs} +4 -5
  357. package/dist/{sqlite-validation-BzKMWnO4.mjs → sqlite-validation-CLJXXN93.mjs} +1 -2
  358. package/dist/{sse-CMvCgjNk.mjs → sse-CxR30yMF.mjs} +1 -2
  359. package/dist/{standard-schema-Fo_vCAZh.d.mts → standard-schema-CuDawHOC.d.mts} +0 -2
  360. package/dist/{static-asset-marker-Btf-6oCD.mjs → static-asset-marker-DsQKz6lt.mjs} +9 -3
  361. package/dist/{subcommand-prompt-D9OhhbGG.mjs → subcommand-prompt-CxJXporl.mjs} +3 -4
  362. package/dist/sveltekit.d.mts +0 -2
  363. package/dist/sveltekit.mjs +2 -3
  364. package/dist/{terminal-log-text-D9ACPOuG.mjs → terminal-log-text-DNsWJREL.mjs} +1 -2
  365. package/dist/{types-w72dljaA.d.mts → types-agfx0alu.d.mts} +0 -4
  366. package/dist/validate-DY1U9rET.mjs +1 -0
  367. package/dist/{validate-CnZPMq4q.mjs → validate-Ddzl-IwT.mjs} +4 -5
  368. package/dist/validation-error-uAAjlsiW.mjs +82 -0
  369. package/dist/{validator-BTOu0fB0.mjs → validator-CTfmzZYb.mjs} +2 -5
  370. package/dist/{version-metadata-D2vfMQzv.mjs → version-metadata-C8hLzQkv.mjs} +4 -6
  371. package/dist/{worker-conditions-AWFRcFxR.mjs → worker-conditions-CBZ0RYsZ.mjs} +1 -2
  372. package/dist/{wrangler-I-scB_1t.mjs → wrangler-DESSbN8L.mjs} +6 -8
  373. package/dist/wrangler-DUB3MGHV.mjs +1 -0
  374. package/dist/{wrapper-BBl1rC32.mjs → wrapper-C9SUxoj7.mjs} +17 -14
  375. package/dist/{ws-B3ClMVDh.d.mts → ws-Dmjg5NH2.d.mts} +3 -5
  376. package/dist/{yarn-pnp-DLbEFMT0.mjs → yarn-pnp-DgWbE7z5.mjs} +2 -3
  377. package/docs/guide/database.md +4 -4
  378. package/docs/guide/deployment.md +1 -1
  379. package/docs/guide/edge/headers.md +4 -6
  380. package/docs/guide/edge/redirects.md +4 -4
  381. package/docs/guide/edge/rewrites.md +1 -1
  382. package/docs/guide/edge/static-assets.md +0 -10
  383. package/docs/guide/email/domains.md +3 -1
  384. package/docs/guide/email/receiving.md +4 -4
  385. package/docs/guide/email/sending.md +43 -13
  386. package/docs/guide/pages-routing/actions-and-forms.md +26 -9
  387. package/docs/guide/pages-routing/islands.md +5 -5
  388. package/docs/guide/pages-routing/layouts.md +16 -2
  389. package/docs/guide/pages-routing/loaders.md +5 -5
  390. package/docs/guide/pages-routing/markdown.md +7 -7
  391. package/docs/guide/pages-routing/overview.md +137 -27
  392. package/docs/guide/platform/administration/connected-apps.md +4 -2
  393. package/docs/guide/platform/administration/email.md +6 -8
  394. package/docs/guide/platform/installation/credentials.md +12 -10
  395. package/docs/guide/platform/installation/maintenance.md +18 -21
  396. package/docs/guide/platform/installation/prerequisites.md +1 -1
  397. package/docs/guide/platform/installation/setup.md +23 -2
  398. package/docs/guide/platform/installation/uninstall.md +1 -1
  399. package/docs/guide/queues.md +4 -8
  400. package/docs/guide/self-hosted-platform.md +3 -3
  401. package/docs/guide/server-routing.md +7 -7
  402. package/docs/guide/ssg.md +3 -3
  403. package/docs/guide/type-safety.md +84 -1
  404. package/docs/guide/typed-fetch.md +1 -1
  405. package/docs/guide/websockets.md +1 -1
  406. package/docs/integrations/cloudflare.md +2 -2
  407. package/docs/integrations/frameworks/analog.md +1 -1
  408. package/docs/integrations/frameworks/astro.md +17 -12
  409. package/docs/integrations/frameworks/nuxt.md +1 -1
  410. package/docs/integrations/frameworks/overview.md +2 -2
  411. package/docs/integrations/frameworks/sveltekit.md +1 -1
  412. package/docs/integrations/frameworks/tanstack-start.md +1 -1
  413. package/docs/integrations/hono.md +5 -5
  414. package/docs/reference/api/auth.md +1 -1
  415. package/docs/reference/api/deploy.md +6 -6
  416. package/docs/reference/api/pages.md +109 -50
  417. package/docs/reference/api/plugin.md +4 -4
  418. package/docs/reference/api/resources.md +4 -1
  419. package/docs/reference/api/rewrites.md +24 -3
  420. package/docs/reference/api/types.md +45 -0
  421. package/docs/reference/api.md +2 -2
  422. package/docs/reference/cli/database.md +15 -9
  423. package/docs/reference/cli/email.md +4 -2
  424. package/docs/reference/cli/platform-installation.md +6 -3
  425. package/docs/reference/cli/project.md +2 -2
  426. package/docs/reference/cli/secrets.md +3 -1
  427. package/docs/reference/cli/setup.md +4 -4
  428. package/docs/reference/cli.md +1 -1
  429. package/docs/reference/config.md +12 -2
  430. package/package.json +36 -32
  431. package/sandbox.Dockerfile +1 -1
  432. package/schema.json +4 -0
  433. package/skills/void/SKILL.md +5 -0
  434. package/dist/cf-build-output-bd8Uwv1P.mjs +0 -1
  435. package/dist/client-BZb9j66F.mjs +0 -1
  436. package/dist/collect-BWhkgtAn.mjs +0 -1
  437. package/dist/deploy-CX94CmKa.mjs +0 -2
  438. package/dist/discover-D4TPKo57.mjs +0 -1
  439. package/dist/gen-BhWBT4iu.mjs +0 -1
  440. package/dist/headers--vaK_chu.mjs +0 -226
  441. package/dist/help-qOZr3wng.mjs +0 -1
  442. package/dist/login-BAPmYnb7.mjs +0 -1
  443. package/dist/migrate-BIYTPQE6.mjs +0 -1
  444. package/dist/operator-cmd-CjazwOyb.mjs +0 -1
  445. package/dist/output-BW9uK099.mjs +0 -1
  446. package/dist/plan-CKX_jWnD.mjs +0 -1
  447. package/dist/platform-args-BC8_hsDj.mjs +0 -1
  448. package/dist/prepare-DU-tOpS5.mjs +0 -1
  449. package/dist/project-slug-6cyz8E7k.mjs +0 -1
  450. package/dist/resolve-project-DD1vu8s9.mjs +0 -1
  451. package/dist/route-url-BgPja1GS.d.mts +0 -5
  452. package/dist/route-url-BjGv_KKY.mjs +0 -28
  453. package/dist/validate-D7Wn8PUX.mjs +0 -1
  454. package/dist/validation-error-Dg9Recn1.mjs +0 -49
  455. package/dist/wrangler-UnwdISay.mjs +0 -1
@@ -0,0 +1,82 @@
1
+ // src/runtime/handler-composition.ts
2
+ const compositionKey = "__voidHandlerComposition";
3
+ function getHandlerComposition(handler) {
4
+ return handler?.[compositionKey];
5
+ }
6
+ /** Record the composition; a nested composed leaf is flattened into one chain. */
7
+ function setHandlerComposition(handler, middlewares, leaf) {
8
+ const nested = getHandlerComposition(leaf);
9
+ const composition = nested ? {
10
+ middlewares: [...middlewares, ...nested.middlewares],
11
+ leaf: nested.leaf
12
+ } : {
13
+ middlewares,
14
+ leaf
15
+ };
16
+ Object.defineProperty(handler, compositionKey, { value: composition });
17
+ return handler;
18
+ }
19
+ /**
20
+ * Run middleware on the current context around `endpoint`, the way Hono's
21
+ * compose does: a Response returned by a middleware replaces `c.res`, the
22
+ * endpoint's Response becomes `c.res`, and middleware can edit `c.res` after
23
+ * `next()`. Returns the final `c.res`.
24
+ */
25
+ async function executeComposedHandler(c, middlewares, endpoint) {
26
+ let index = 0;
27
+ const dispatch = async () => {
28
+ if (index < middlewares.length) {
29
+ const response = await middlewares[index++](c, dispatch);
30
+ if (response instanceof Response) c.res = response;
31
+ } else c.res = await endpoint();
32
+ };
33
+ await dispatch();
34
+ return c.res;
35
+ }
36
+ // src/pages/defer.ts
37
+ const DEFERRED = Symbol("deferred");
38
+ function defer(groupOrResolver, maybeResolver) {
39
+ const [group, resolver] = typeof groupOrResolver === "string" ? [groupOrResolver, maybeResolver] : [null, groupOrResolver];
40
+ return {
41
+ [DEFERRED]: true,
42
+ group,
43
+ resolver
44
+ };
45
+ }
46
+ /**
47
+ * Separate a loader's return value into immediate props and deferred sentinels.
48
+ * For single-prop deferred (group=null), the object key becomes the group name.
49
+ * For named groups, all keys sharing the same group name are collected.
50
+ */
51
+ function separateDeferred(props) {
52
+ const immediateProps = {};
53
+ const deferredMap = {};
54
+ for (const [key, value] of Object.entries(props)) if (value && typeof value === "object" && DEFERRED in value) {
55
+ const sentinel = value;
56
+ const groupName = sentinel.group ?? key;
57
+ if (!deferredMap[groupName]) deferredMap[groupName] = {
58
+ resolver: sentinel.resolver,
59
+ keys: []
60
+ };
61
+ deferredMap[groupName].keys.push(key);
62
+ immediateProps[key] = {
63
+ value: null,
64
+ loading: true,
65
+ error: null
66
+ };
67
+ } else immediateProps[key] = value;
68
+ return {
69
+ immediateProps,
70
+ deferredMap
71
+ };
72
+ }
73
+ // src/pages/validation-error.ts
74
+ var ValidationError = class extends Error {
75
+ errors;
76
+ constructor(errors) {
77
+ super("Validation failed");
78
+ this.name = "ValidationError";
79
+ this.errors = errors;
80
+ }
81
+ };
82
+ export { executeComposedHandler as a, separateDeferred as i, DEFERRED as n, getHandlerComposition as o, defer as r, setHandlerComposition as s, ValidationError as t };
@@ -1,4 +1,4 @@
1
- //#region src/runtime/validator.ts
1
+ // src/runtime/validator.ts
2
2
  function flattenIssues(issues) {
3
3
  return Array.from(issues, (issue) => ({
4
4
  message: issue.message,
@@ -29,9 +29,7 @@ async function runValidation(validators, c) {
29
29
  });
30
30
  }
31
31
  if (validators.query) {
32
- const url = new URL(c.req.url);
33
- const raw = {};
34
- for (const [key, value] of url.searchParams) raw[key] = value;
32
+ const raw = Object.fromEntries(Object.entries(c.req.queries()).map(([key, values]) => [key, values.length === 1 ? values[0] : values]));
35
33
  const result = await validateSlot(validators.query, raw);
36
34
  if (result.ok) input.query = result.value;
37
35
  else allIssues.push({
@@ -68,5 +66,4 @@ async function runValidation(validators, c) {
68
66
  input
69
67
  };
70
68
  }
71
- //#endregion
72
69
  export { runValidation as t };
@@ -1,6 +1,6 @@
1
- import { a as join } from "./dist-ipQi0Q8y.mjs";
2
- import { l as bindingNamesForField, p as findBindingNameOwner } from "./wrangler-I-scB_1t.mjs";
3
- //#region src/shared/untrusted-env.ts
1
+ import { a as join } from "./dist-DMYe8CZJ.mjs";
2
+ import { l as bindingNamesForField, p as findBindingNameOwner } from "./wrangler-DESSbN8L.mjs";
3
+ // src/shared/untrusted-env.ts
4
4
  /** Authentication inputs that Wrangler may consume from the environment. */
5
5
  const WRANGLER_AUTH_CREDENTIAL_ENV_VARS = [
6
6
  "CLOUDFLARE_API_TOKEN",
@@ -48,8 +48,7 @@ function buildEnv(extra, options) {
48
48
  env[pathKey] = existing ? `${binDir}${delimiter}${existing}` : binDir;
49
49
  return env;
50
50
  }
51
- //#endregion
52
- //#region src/shared/version-metadata.ts
51
+ // src/shared/version-metadata.ts
53
52
  /** Build-only marker: an existing-site handoff must not add Worker bindings. */
54
53
  const CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV = "VOID_CLOUDFLARE_PRESERVE_BINDINGS";
55
54
  const DEFAULT_VERSION_METADATA_BINDING = "__VOID_VERSION_METADATA";
@@ -70,5 +69,4 @@ function selectNativeVersionMetadataBinding(config, options) {
70
69
  if (owner) throw new Error(`Cloudflare version metadata binding ${DEFAULT_VERSION_METADATA_BINDING} conflicts with ${owner}.`);
71
70
  return DEFAULT_VERSION_METADATA_BINDING;
72
71
  }
73
- //#endregion
74
72
  export { buildEnv as a, WRANGLER_AUTH_CREDENTIAL_ENV_VARS as i, readVersionMetadataBinding as n, selectNativeVersionMetadataBinding as r, CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV as t };
@@ -1,4 +1,4 @@
1
- //#region src/cli/worker-conditions.ts
1
+ // src/cli/worker-conditions.ts
2
2
  const WORKER_CONDITIONS = [
3
3
  "workerd",
4
4
  "worker",
@@ -7,5 +7,4 @@ const WORKER_CONDITIONS = [
7
7
  "import",
8
8
  "default"
9
9
  ];
10
- //#endregion
11
10
  export { WORKER_CONDITIONS as t };
@@ -1,14 +1,14 @@
1
- import { a as join, c as resolve, n as dirname, o as normalize, t as basename } from "./dist-ipQi0Q8y.mjs";
2
- import { o as TYPED_CONFIG_FILE, s as loadTypedVoidConfigFile } from "./project-paths-DGu_QZ_Q.mjs";
3
- import { h as validateConfig, p as readConfig } from "./config-OFOAimzt.mjs";
4
- import { a as persistCloudflareConfig, i as materializeCloudflareConfig, r as ignoreMaterializedCloudflareConfig } from "./cloudflare-config-CH1AylZT.mjs";
1
+ import { a as join, c as resolve, n as dirname, o as normalize, t as basename } from "./dist-DMYe8CZJ.mjs";
2
+ import { o as TYPED_CONFIG_FILE, s as loadTypedVoidConfigFile } from "./project-paths-CdGv9Tmi.mjs";
3
+ import { h as validateConfig, p as readConfig } from "./config-BITKQ3O6.mjs";
4
+ import { a as persistCloudflareConfig, i as materializeCloudflareConfig, r as ignoreMaterializedCloudflareConfig } from "./cloudflare-config-eQunqX6A.mjs";
5
5
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
6
6
  import { parseSync } from "vite";
7
7
  import { appendSqliteClassMigration, isRecord } from "@void/deploy-core";
8
8
  import { createHash } from "node:crypto";
9
9
  import { isDeepStrictEqual } from "node:util";
10
10
  import { SyntaxKind, applyEdits, createScanner, findNodeAtLocation, modify, parse, parseTree } from "jsonc-parser";
11
- //#region src/config-write.ts
11
+ // src/config-write.ts
12
12
  const GENERATED_MARKERS = [
13
13
  "// Generated by void migrate.",
14
14
  "// Generated from void.json by void migrate.",
@@ -62,8 +62,7 @@ function writeVoidProjectConfig(root, config) {
62
62
  }
63
63
  writeFileSync(path, renderVoidConfig(config, "// Generated by void init."));
64
64
  }
65
- //#endregion
66
- //#region src/cli/wrangler.ts
65
+ // src/cli/wrangler.ts
67
66
  const COMPAT_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
68
67
  /** UTF-8 byte-order mark. Node's utf-8 read preserves a leading one. */
69
68
  const UTF8_BOM = "";
@@ -1467,5 +1466,4 @@ function normalizeMigrationsPath(p) {
1467
1466
  const normalized = normalize(p.replace(/\\/g, "/"));
1468
1467
  return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
1469
1468
  }
1470
- //#endregion
1471
1469
  export { syncWranglerWebSockets as A, readWranglerManagedQueueCleanupCandidates as C, sameMigrationsDir as D, resolveLiveBindingConfig as E, canRewriteVoidProjectConfig as F, renderVoidConfig as I, writeVoidProjectConfig as L, writeProvisionedWranglerConfig as M, writeWranglerPublishedTrafficSnapshot as N, syncWranglerBindings as O, GENERATED_MARKERS as P, readWranglerCustomDomains as S, readWranglerWebSocketTombstones as T, persistMaterializedWranglerConfig as _, LIVE_MIGRATION_TAG as a, readRootWranglerConfig as b, bindingEntriesForField as c, ensureWranglerCompatibilityDate as d, ensureWranglerNodejsAlsFlag as f, normalizeWranglerCompatibilityFlags as g, nextDurableObjectMigrationTag as h, LATEST_KNOWN_COMPAT_DATE as i, updateWranglerCustomDomain as j, syncWranglerDurableObjects as k, bindingNamesForField as l, hasDurableObjectSqliteMigration as m, DEFAULT_LIVE_CLASS as n, acknowledgeWranglerManagedQueueRemovals as o, findBindingNameOwner as p, FRIENDLY_BINDING_NAMES as r, assertNoDuplicateMembers as s, DEFAULT_LIVE_BINDING as t, ensureWranglerCompat as u, readExistingLiveBindingConfig as v, readWranglerPublishedTrafficSnapshot as w, readWranglerCompat as x, readProvisionedBindingEntry as y };
@@ -0,0 +1 @@
1
+ export { b as readRootWranglerConfig } from "./wrangler-DESSbN8L.mjs";
@@ -1,16 +1,16 @@
1
- import { a as join, l as toSlash, n as dirname, r as extname } from "./dist-ipQi0Q8y.mjs";
2
- import { n as readProjectPaths } from "./project-paths-DGu_QZ_Q.mjs";
3
- import { l as getDatabaseDialect, p as readConfig } from "./config-OFOAimzt.mjs";
4
- import { n as isIdentifier, r as isLiteral } from "./ast-CsZ_q_gc.mjs";
5
- import { t as MagicString } from "./dist-Cegxq8gs.mjs";
6
- import { c as voidDbBundlerPlugin, r as cloudflareQueueName, t as generateQueueResolverSource } from "./dispatch-CLa2LThw.mjs";
7
- import { t as WORKER_CONDITIONS } from "./worker-conditions-AWFRcFxR.mjs";
1
+ import { a as join, l as toSlash, n as dirname, r as extname } from "./dist-DMYe8CZJ.mjs";
2
+ import { n as readProjectPaths } from "./project-paths-CdGv9Tmi.mjs";
3
+ import { l as getDatabaseDialect, p as readConfig } from "./config-BITKQ3O6.mjs";
4
+ import { n as isIdentifier, r as isLiteral } from "./ast-Cv0JwXqb.mjs";
5
+ import { t as MagicString } from "./dist-B6eN80gc.mjs";
6
+ import { c as voidDbBundlerPlugin, r as cloudflareQueueName, t as generateQueueResolverSource } from "./dispatch-BNLB5_Gm.mjs";
7
+ import { t as WORKER_CONDITIONS } from "./worker-conditions-CBZ0RYsZ.mjs";
8
8
  import { createRequire } from "node:module";
9
9
  import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
10
10
  import { build, parseSync } from "vite";
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { createHash } from "node:crypto";
13
- //#region src/cli/worker-require-transform.ts
13
+ // src/cli/worker-require-transform.ts
14
14
  function nodes(root) {
15
15
  const found = [];
16
16
  const pending = [root];
@@ -77,8 +77,7 @@ function transformWorkerRequireBundle(code, filename, requireShim, database) {
77
77
  if (transformed.includes("createRequire") || transformed.includes("__require(\"pgpass\")")) throw new Error(`deploy: ${database} bundle ${filename} still contains an unsupported require.`);
78
78
  return pgpassCalls > 0 ? `const __voidPgpassNoop = Object.assign(function pgpass(_connectionInfo, callback) { callback(undefined); }, { warnTo() {} });\n${transformed}` : transformed;
79
79
  }
80
- //#endregion
81
- //#region src/cli/wrapper.ts
80
+ // src/cli/wrapper.ts
82
81
  const BUNDLED_ENTRY_RE = /^index\.(?:m?js|cjs)$/;
83
82
  const envModuleFile = fileURLToPath(import.meta.resolve("#self/_env"));
84
83
  const WRAPPER_MARKER = "// Generated by Void: deployment wrapper.";
@@ -151,8 +150,8 @@ async function generateWrapper(workerDir, workerMain, root, features) {
151
150
  let migrations;
152
151
  let migrationPlanBundle;
153
152
  if (features.hasMigrations) {
154
- const { collectMigrations } = await import("./collect-BWhkgtAn.mjs");
155
- const { buildMigrationPlanBundle } = await import("./plan-CKX_jWnD.mjs");
153
+ const { collectMigrations } = await import("./collect-8i0wU63d.mjs");
154
+ const { buildMigrationPlanBundle } = await import("./plan-CQ-N4gws.mjs");
156
155
  const migrationsDir = readProjectPaths(root).migrationsDir;
157
156
  migrations = collectMigrations(migrationsDir);
158
157
  migrationPlanBundle = features.migrationDialect === "sqlite" ? buildMigrationPlanBundle(migrations) : void 0;
@@ -651,11 +650,15 @@ export async function handleQueueRelay(payload, env, ctx) {
651
650
  retryAll(options) { for (const message of messages) message.retry(options); },
652
651
  };
653
652
  let ok = true;
654
- try { await handleQueue(batch, env, ctx); } catch { ok = false; }
653
+ try {
654
+ await handleQueue(batch, env, ctx);
655
+ } catch (error) {
656
+ console.error(\`[void] Queue handler failed for queue "\${payload.queue}":\`, error);
657
+ ok = false;
658
+ }
655
659
  return { ok, ...(decisions.size ? { decisions: Object.fromEntries(decisions) } : {}) };
656
660
  }`);
657
661
  }
658
662
  return lines.join("\n");
659
663
  }
660
- //#endregion
661
664
  export { needsWrapper as a, generateWrapper as i, bundleWorkerSqlDriver as n, cleanupWrapper as r, bundleEntry as t };
@@ -1,8 +1,7 @@
1
- import { t as StandardSchemaV1 } from "./standard-schema-Fo_vCAZh.mjs";
2
- import { r as AuthUser } from "./auth-g2TQbDLD.mjs";
3
- import { a as CloudEnv } from "./handler-BHktmuTL.mjs";
1
+ import { t as StandardSchemaV1 } from "./standard-schema-CuDawHOC.mjs";
2
+ import { r as AuthUser } from "./auth-CH4PLAX1.mjs";
3
+ import { a as CloudEnv } from "./handler-BR6Tvjkp.mjs";
4
4
  import { WebSocketRouteMap } from "void/routes";
5
- //#region src/runtime/ws.d.ts
6
5
  type MaybePromise<T> = T | Promise<T>;
7
6
  type ParamsRecord = Record<string, string>;
8
7
  type WebSocketInstanceKey = (context: {
@@ -135,5 +134,4 @@ declare class VoidSocket<P extends keyof WebSocketRouteMap & string> {
135
134
  }
136
135
  declare function connect<P extends keyof WebSocketRouteMap & string>(path: HasParams<P> extends false ? P : never): VoidSocket<P>;
137
136
  declare function connect<P extends keyof WebSocketRouteMap & string>(path: P, options: ConnectOptions<P>): VoidSocket<P>;
138
- //#endregion
139
137
  export { RoomDefinition as a, VoidSocket as c, WebSocketConnection as d, WebSocketInstanceKey as f, defineWebSocket as h, RoomController as i, VoidSocketCloseEvent as l, defineRoom as m, ConnectCommonOptions as n, SocketContext as o, connect as p, RoomContext as r, SocketDefinition as s, AnyWebSocketDefinition as t, WebSocketBaseContext as u };
@@ -1,7 +1,7 @@
1
- import { a as join, n as dirname } from "./dist-ipQi0Q8y.mjs";
1
+ import { a as join, n as dirname } from "./dist-DMYe8CZJ.mjs";
2
2
  import { existsSync, readdirSync } from "node:fs";
3
3
  import { fileURLToPath, pathToFileURL } from "node:url";
4
- //#region src/cli/yarn-pnp.ts
4
+ // src/cli/yarn-pnp.ts
5
5
  const drizzleKitBin = join(fileURLToPath(import.meta.resolve("drizzle-kit")), "..", "bin.cjs");
6
6
  /** Read the PnP runtime files in `dir` only, or `undefined` when neither exists. */
7
7
  function readPnpRuntimeAt(dir) {
@@ -88,5 +88,4 @@ function buildDrizzleKitSpawnEnv(root) {
88
88
  env.NODE_OPTIONS = process.env.NODE_OPTIONS ? `${injected} ${process.env.NODE_OPTIONS}` : injected;
89
89
  return env;
90
90
  }
91
- //#endregion
92
91
  export { hasLocalLockfile as i, drizzleKitBin as n, findInstalledYarnPnpRuntime as r, buildDrizzleKitSpawnEnv as t };
@@ -56,8 +56,8 @@ Define your tables in `db/schema.ts` using column helpers from `void/schema-d1`,
56
56
  ::: code-group
57
57
 
58
58
  ```ts [SQLite (D1)]
59
- import { sql } from 'void/db';
60
59
  // db/schema.ts
60
+ import { sql } from 'void/db';
61
61
  import { sqliteTable, text, integer } from 'void/schema-d1';
62
62
 
63
63
  export const users = sqliteTable('users', {
@@ -314,8 +314,8 @@ export const insertUserSchema = createInsertSchema(users, {
314
314
  ```
315
315
 
316
316
  ```ts [Valibot]
317
- import { pipe, minLength, email } from 'valibot';
318
317
  // db/schema.ts
318
+ import { pipe, minLength, email } from 'valibot';
319
319
  import { createInsertSchema } from 'void/drizzle-valibot';
320
320
 
321
321
  export const insertUserSchema = createInsertSchema(users, {
@@ -325,8 +325,8 @@ export const insertUserSchema = createInsertSchema(users, {
325
325
  ```
326
326
 
327
327
  ```ts [ArkType]
328
- import { type } from 'arktype';
329
328
  // db/schema.ts
329
+ import { type } from 'arktype';
330
330
  import { createInsertSchema } from 'void/drizzle-arktype';
331
331
 
332
332
  export const insertUserSchema = createInsertSchema(users, {
@@ -342,8 +342,8 @@ export const insertUserSchema = createInsertSchema(users, {
342
342
  Use the derived schema in your route handlers with [`withValidator()`](./server-routing.md#validation):
343
343
 
344
344
  ```ts
345
- import { users, insertUserSchema } from '@schema';
346
345
  // routes/api/users/index.ts
346
+ import { users, insertUserSchema } from '@schema';
347
347
  import { defineHandler } from 'void';
348
348
  import { db } from 'void/db';
349
349
 
@@ -35,7 +35,7 @@ void db generate
35
35
 
36
36
  Review and commit the SQL, then deploy again. Rollback does not reverse database migrations. See [Database](./database.md) for the local workflow.
37
37
 
38
- On your own Cloudflare account, deploy saves a D1 [Time Travel](https://developers.cloudflare.com/d1/reference/time-travel/) restore point before it applies pending migrations and prints the [`void db restore`](../reference/cli/database.md#void-db-restore) command for it. If no restore point can be saved, deploy stops before it migrates. If deploy fails after it applied the migrations, for example when the upload fails, it prints the command again. Usually you fix the error and deploy again; restore only if the live version cannot run against the new schema. To recover from a bad migration, roll back the code with `void project rollback` if the new version is live, restore the database, then fix or remove the migration before you deploy again. After a one-off `void deploy --platform cloudflare`, add `--platform cloudflare` to each of these commands. Restoring discards every write made after the restore point. Restore points expire after 7 days on Workers Free and 30 days on Workers Paid; after that, undo a migration with a new one.
38
+ For D1 on your own Cloudflare account, deploy saves a restore point before applying migrations and prints a [`void db restore`](../reference/cli/database.md#void-db-restore) command. Use it to recover from a bad migration, then fix the migration before deploying again. A restore discards writes made after that point; check that your deployed code works with the restored schema. See the command reference for the recovery steps and retention limits.
39
39
 
40
40
  ### Environment variables
41
41
 
@@ -24,6 +24,8 @@ Define custom response headers in [`void.config.ts`](../../reference/config) usi
24
24
  - **Header values** use `Name: value` format. The value may contain colons.
25
25
  - All matching rules are merged. When multiple rules set the same header name, the **last match wins**.
26
26
  - User-defined `Cache-Control` overrides the built-in default. The default still applies when no rule matches.
27
+ - With [authentication](../auth.md), responses to requests that send cookies or credentials stay private, and auth endpoints stay uncached, during local development, with `void deploy --platform cloudflare`, and on [other runtimes](../deployment.md#other-runtimes). On a [Void platform](../deployment.md#deploy-to-a-team-platform), a `Cache-Control` rule replaces the app's value, so do not match signed-in pages or `/api/auth/*` with a public cache rule.
28
+ - Rules apply to matching error responses too, including 404 responses. An immutable cache rule can therefore cache a missing file. Use immutable caching only for URLs that change when their content changes.
27
29
 
28
30
  ## Scope
29
31
 
@@ -35,13 +37,9 @@ Header rules do not apply to ISR cache responses.
35
37
 
36
38
  ### Cookie headers
37
39
 
38
- On a [Void platform](../deployment.md#deploy-to-a-team-platform), apps usually share an application domain, such as `apps.example.com`. Header rules on a platform deploy change two headers on all hostnames of the app, including custom domains:
40
+ On a [Void platform](../deployment.md#deploy-to-a-team-platform), set cookies in your app's response. Header rules ignore `Set-Cookie`, remove `"cookies"` from `Clear-Site-Data`, and ignore `Clear-Site-Data` rules containing `"*"`. You can use directives such as `"cache"` and `"storage"` in header rules.
39
41
 
40
- - Void ignores `Set-Cookie` in header rules.
41
- - Void removes the `"cookies"` directive from `Clear-Site-Data` in header rules. Other directives, such as `"cache"` and `"storage"`, still apply.
42
- - Void ignores the full value of a `Clear-Site-Data` rule that includes `"*"`. The response then keeps the `Clear-Site-Data` value from your app's response, without `"cookies"`. If that value also includes `"*"`, the response has no `Clear-Site-Data`.
43
-
44
- This stops a header rule from setting or clearing cookies for other apps on the same domain. These limits apply only to header rules. Your app's own response can set cookies and send `Clear-Site-Data`, and on a shared domain those can affect other apps. See [Domains and Resources](../platform/installation/domains.md#adding-a-domain).
42
+ These limits apply on all of your app's hostnames, including custom domains, to protect cookies for other apps on the shared domain. Your app's own cookie headers can still affect those apps, so scope cookies carefully. See [Domains and Resources](../platform/installation/domains.md#adding-a-domain).
45
43
 
46
44
  During local development, with `void deploy --platform cloudflare`, and on [other runtimes](../deployment.md#other-runtimes), header rules apply both headers as written.
47
45
 
@@ -65,13 +65,13 @@ export default defineConfig({
65
65
  });
66
66
  ```
67
67
 
68
- Void answers with a permanent `308` redirect to the same URL over HTTPS. The path, query string, and request method stay the same. Omitted or `false` means off. `localhost` and loopback addresses such as `127.0.0.1` stay on HTTP, so local development and `vite preview` are unchanged.
68
+ Void returns a permanent `308` redirect that preserves the path, query string, and request method. The option defaults to `false`. Localhost and loopback addresses stay on HTTP for local development and previews.
69
69
 
70
- It works on the Void platform and for Void apps on `void deploy --platform cloudflare`. It needs the Cloudflare target: setting it with `target: 'node'`, `'bun'`, or `'deno'` is a config error.
70
+ This option requires the Cloudflare target and works for Void apps and static sites on either deployment platform.
71
71
 
72
- On `void deploy --platform cloudflare`, built files with a content hash in their name, such as `/assets/index-abc123.js`, can be served by Cloudflare before Void runs, so they may still answer over HTTP. Pages always redirect, so browsers load these files over HTTPS. To redirect every request, also turn on [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/) for your Cloudflare zone.
72
+ For direct Cloudflare deployments, also enable [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/) on your zone to cover assets served directly by Cloudflare.
73
73
 
74
- SvelteKit, Nuxt, Astro, Analog, TanStack Start, React Router, and vinext apps run their own Worker, so `void deploy --platform cloudflare` stops with an error when the option is on. Static builds of these frameworks, deployed with `--dir` or `inference.appType`, redirect as usual. For the others, redirect to HTTPS in the framework, or turn on [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/) for your Cloudflare zone.
74
+ For direct Cloudflare deployments of SvelteKit, Nuxt, Astro, Analog, TanStack Start, React Router, or vinext, configure HTTPS in the framework or your Cloudflare zone. Use `routing.alwaysUseHttps` only for their static builds, deployed with `--dir` or `inference.appType`.
75
75
 
76
76
  ## Framework `_redirects` files
77
77
 
@@ -56,7 +56,7 @@ Keep access checks on any destination that needs them.
56
56
 
57
57
  A destination without `?` preserves the incoming query string. `c.rewrite('/search')` keeps `?q=...`, while `c.rewrite('/search?q=all')` replaces it.
58
58
 
59
- Your editor suggests known routes through the [`RewriteDestination`](../../reference/api/rewrites.md#rewritedestination) type. Dynamic strings are also accepted.
59
+ Your editor suggests known routes through the [`RewriteDestination`](../../reference/api/rewrites.md#rewritedestination) type. Dynamic strings are also accepted. With [`routing.typedRoutes`](../../reference/config.md#routing-typedroutes), a string must match one of your routes; add `as RouteUrl` to a path built at runtime, such as ``c.rewrite(`/en${c.req.path}` as RouteUrl)``.
60
60
 
61
61
  ### Runtime rewrites cannot reach static assets
62
62
 
@@ -37,16 +37,6 @@ With `void deploy --platform cloudflare`, generated JavaScript bundles with cont
37
37
 
38
38
  Use [Custom Headers](./headers) to choose a cache policy for other files. Apply immutable caching only to URLs that change whenever their content changes.
39
39
 
40
- Cloudflare serves these fingerprinted JavaScript bundles without starting your Worker, so they do not count as Worker requests, when your app:
41
-
42
- - has no global middleware
43
- - has no header, redirect, rewrite or fallback rules, and no `routing.notFound` setting
44
- - uses the default `base` of `/`
45
- - has no route or page that matches paths in the assets directory (`assets/` by default)
46
- - builds at most 99 fingerprinted bundles
47
-
48
- Otherwise these bundles go through your Worker and keep the same caching.
49
-
50
40
  ## Non-hashed assets
51
41
 
52
42
  Other static files, such as `index.html` and `favicon.ico`, are cached until the next deploy. You do not need to purge them manually.
@@ -16,7 +16,9 @@ void email domain add acme.com
16
16
 
17
17
  `add` opens a Cloudflare API-token template. Restrict the token to the selected account and mail zone before creating it; Workers Scripts permission applies across that account. The CLI accepts a masked paste or a newly copied token and asks you to confirm those restrictions. The platform encrypts the credential for the zone connection, so projects sharing that zone do not need separate ingress Workers.
18
18
 
19
- Platform-managed custom inbound email requires the apex of a Cloudflare zone. Cloudflare’s catch-all only covers that apex, so a subdomain of the selected zone cannot receive arbitrary addresses. `add` refuses to register a new apex that already has MX records, or whose catch-all already routes elsewhere, so it never takes over mail hosted with another provider such as Microsoft 365 or Google Workspace. Use an apex that has no mail yet, or the platform’s shared mail address. To only send from an apex that keeps its current mail provider, ask your platform administrator to register it as [outbound-only](../platform/administration/email.md#sending-from-a-domain-that-already-receives-mail). Running `add` again for a registered apex, for example to renew its token, keeps working. Each custom apex belongs to one project; a project can register more than one apex.
19
+ For inbound mail, use a Cloudflare zone apex with no existing mail service, such as `example.com`. Each apex belongs to one project, and a project can register several. Existing MX records or a catch-all pointing elsewhere block registration to protect your current mail service.
20
+
21
+ To keep receiving mail through another provider, ask your platform administrator to register the domain as [outbound-only](../platform/administration/email.md#sending-from-a-domain-that-already-receives-mail). You can also use the platform's shared mail address.
20
22
 
21
23
  If setup is interrupted, use `void email domain status <domain>` to inspect the saved operation before retrying.
22
24
 
@@ -78,7 +78,7 @@ export default defineEmail(async (message, env, ctx, info) => {
78
78
  });
79
79
  ```
80
80
 
81
- `replyEmail()` replies to the original sender with a threaded subject. You can override `subject`.
81
+ `replyEmail()` replies to the original sender with a threaded subject. You can override `subject`. To reply after the handler returns, use [`sendEmail` with `threading`](./sending.md#reply-later).
82
82
 
83
83
  On a Void platform, the default sender is your project's shared address, or the address that received mail on your registered domain. Use that default for shared mail; `message.to` has the project prefix removed. Sender overrides must belong to your project.
84
84
 
@@ -94,15 +94,15 @@ deployed `email/` handlers without per-project DNS setup once the platform has v
94
94
  handlers once its inbound readiness is `ready`. Use `void email domain status`
95
95
  to check current provider routing and any remaining setup steps.
96
96
 
97
- A project with an [email alias](../../reference/cli/email.md#void-email-alias) also receives at `<alias>+anything@<mail domain>`. Routing ignores which prefix was used: with the slug `acme-store` and the alias `acme`, both `acme-store+support@…` and `acme+support@…` reach `email/support.ts`.
97
+ A project with an [email alias](../../reference/cli/email.md#void-email-alias) also receives at `<alias>+anything@<mail domain>`. For example, both `acme-store+support@…` and its alias `acme+support@…` reach `email/support.ts`.
98
98
 
99
99
  For direct deployments, follow [Your own Cloudflare account](./domains.md#your-own-cloudflare-account) to configure inbound addresses.
100
100
 
101
- The local dev server provides the outbound email inbox but has no inbound email trigger. Test inbound handlers with `createInboundTestHarness` below.
101
+ Test inbound handlers locally with `createInboundTestHarness` below.
102
102
 
103
103
  ## Testing inbound handlers {#testing-inbound-handlers}
104
104
 
105
- Use `createInboundTestHarness` to capture replies, forwards, and rejections. For shared platform mail, pass the full address including the project prefix, such as [`acme+support+abc-123@acme.dev`](mailto:acme+support+abc-123@acme.dev). For direct Cloudflare mail, set `slug: null` and use [`support+abc-123@mail.acme.com`](mailto:support+abc-123@mail.acme.com).
105
+ Use `createInboundTestHarness` to capture replies, forwards, and rejections. For shared platform mail, pass the full address including the project prefix, such as `acme+support+abc-123@acme.dev`. For direct Cloudflare mail, set `slug: null` and use `support+abc-123@mail.acme.com`.
106
106
 
107
107
  ```ts
108
108
  import { describe, it, expect } from 'vitest';
@@ -67,18 +67,19 @@ For mail to arbitrary users, [register your own domain](./domains.md#your-own-do
67
67
 
68
68
  ## Options {#options}
69
69
 
70
- | Option | Type | Notes |
71
- | ---------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
72
- | `from` | `string \| { email, name? }` | Optional. Pinned to the project sender — see below. |
73
- | `to` | `Address \| Address[]` | Required. One or more recipients. |
74
- | `subject` | `string` | Required. UTF-8 supported (encoded as RFC 2047). |
75
- | `text` | `string` | At least one of `text` / `html` is required. |
76
- | `html` | `string` | Sent as `multipart/alternative` if both are provided. |
77
- | `replyTo` | `Address` | Optional `Reply-To` header. |
78
- | `cc`, `bcc` | `Address \| Address[]` | Optional. Each recipient is sent its own message envelope. |
79
- | `headers` | `Record<string, string>` | Custom headers; reserved headers (From, Date, etc.) are ignored. |
80
- | `attachments` | `Attachment[]` | See [Attachments](#attachments). |
81
- | `idempotencyKey` | `string` | Optional on the Void Platform: 1–128 printable, non-space ASCII characters. Reuse for retries of the same send. |
70
+ | Option | Type | Notes |
71
+ | ---------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------- |
72
+ | `from` | `string \| { email, name? }` | Optional. Pinned to the project sender — see below. |
73
+ | `to` | `Address \| Address[]` | Required. One or more recipients. |
74
+ | `subject` | `string` | Required. UTF-8 supported (encoded as RFC 2047). |
75
+ | `text` | `string` | At least one of `text` / `html` is required. |
76
+ | `html` | `string` | Sent as `multipart/alternative` if both are provided. |
77
+ | `replyTo` | `Address` | Optional `Reply-To` header. |
78
+ | `cc`, `bcc` | `Address \| Address[]` | Optional. Each recipient is sent its own message envelope. |
79
+ | `headers` | `Record<string, string>` | Custom headers; reserved headers (From, Date, etc.) are ignored. |
80
+ | `threading` | `{ inReplyTo?, references? }` | Optional. Threads the email under an earlier message. See [Reply later](#reply-later). |
81
+ | `attachments` | `Attachment[]` | See [Attachments](#attachments). |
82
+ | `idempotencyKey` | `string` | Optional on the Void Platform: 1–128 printable, non-space ASCII characters. Reuse for retries of the same send. |
82
83
 
83
84
  You can send to at most 50 recipients across `to`, `cc`, and `bcc`. Use standard email addresses with ASCII local parts, and punycode for internationalized domains.
84
85
 
@@ -88,6 +89,35 @@ On the platform the sender is pinned to your project. `from` must be your projec
88
89
 
89
90
  On your own Cloudflare account, `from` defaults to `email.from` from `void.config.ts` and must be on a domain your account can send from; Cloudflare rejects any other sender and `sendEmail` reports it as `INVALID_FROM`.
90
91
 
92
+ ## Reply later {#reply-later}
93
+
94
+ `replyEmail()` works only while the inbound handler runs. To reply later, for example from a queue job, save the thread ids in the handler and pass them to `sendEmail` as `threading`:
95
+
96
+ ```ts
97
+ // email/support.ts
98
+ export default defineEmail(async (message) => {
99
+ await tickets.save({
100
+ from: message.from,
101
+ subject: message.headers.get('Subject') ?? '',
102
+ messageId: message.headers.get('Message-ID') ?? '',
103
+ references: message.headers.get('References') ?? '',
104
+ });
105
+ });
106
+
107
+ // Later, in a queue job
108
+ await sendEmail({
109
+ to: ticket.from,
110
+ subject: `Re: ${ticket.subject}`,
111
+ text: 'We fixed it.',
112
+ threading: {
113
+ inReplyTo: ticket.messageId,
114
+ references: `${ticket.references} ${ticket.messageId}`,
115
+ },
116
+ });
117
+ ```
118
+
119
+ `inReplyTo` is the parent message's `Message-ID`. `references` lists the thread's ids, oldest first, ending with the parent; it defaults to `inReplyTo`. Mail clients use them to show the reply in the same conversation. An id that cannot be sent, such as one with a control character, is left out. If `references` cannot be sent, it falls back to `inReplyTo`. The email still sends. `headers` cannot set `In-Reply-To` or `References`.
120
+
91
121
  ## Attachments {#attachments}
92
122
 
93
123
  ```ts
@@ -195,7 +225,7 @@ The inbox keeps the most recent 100 messages through HMR and clears on a full se
195
225
 
196
226
  The dev inbox works in native Void apps, TanStack Start, and React Router. It is unavailable in SvelteKit, Nuxt, Analog, and Astro; sends from those apps return `BINDING_MISSING`. Use `createEmailTestHarness` from `void/email/testing` to capture sends in tests. If a configured inbox cannot be reached, `sendEmail` returns `UPSTREAM_ERROR` without sending.
197
227
 
198
- `sendInDev` is deprecated. During local development it skips the inbox and returns `BINDING_MISSING`, so it never delivers. Remove it, and deploy the app to test real delivery.
228
+ Remove the deprecated `sendInDev` option to use the local inbox. Deploy the app to test real delivery.
199
229
 
200
230
  ## Testing {#testing}
201
231