void 0.27.0 → 1.0.3

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 (337) hide show
  1. package/README.md +3 -1
  2. package/dist/{account-cmd-l-FM7Ioq.mjs → account-cmd-BTcUzv9L.mjs} +6 -6
  3. package/dist/{agents-B_pX_HmQ.mjs → agents-CuNtT0D_.mjs} +5 -2
  4. package/dist/{application-analysis-DKy02UY0.mjs → application-analysis-AB_YYWgH.mjs} +118 -135
  5. package/dist/{application-routing-DQyUh_5S.mjs → application-routing-L7V-TFhZ.mjs} +1 -2
  6. package/dist/atomic-write-Dq6R0BPN.mjs +18 -0
  7. package/dist/{auth-Dn2vw-SG.mjs → auth-B6iOCjKI.mjs} +23 -56
  8. package/dist/auth-Cbqi1iVX.mjs +1 -0
  9. package/dist/{auth-link-vz9Z2kmG.mjs → auth-link-DUJuvRx5.mjs} +11 -11
  10. package/dist/{auth-migrations-BwHgeEsD.mjs → auth-migrations-Cgs0k6lS.mjs} +28 -5
  11. package/dist/{auth-router-DvsCUVw4.mjs → auth-router-CIxiMG7i.mjs} +5 -5
  12. package/dist/base64-DVrOndmI.mjs +16 -0
  13. package/dist/{better-auth-shared-CPvWD3nG.d.mts → better-auth-shared-B74NJIus.d.mts} +8 -13
  14. package/dist/{better-auth-shared-DPpj8zxc.mjs → better-auth-shared-CMXlZG7W.mjs} +56 -68
  15. package/dist/{build-cmd-D6we0VjO.mjs → build-cmd-BkIv25PA.mjs} +6 -6
  16. package/dist/{cache-CZRdzKx1.mjs → cache-Ctzfig-W.mjs} +6 -6
  17. package/dist/{cancel-deploy-CQ3NnMvf.mjs → cancel-deploy-CD9o-SsC.mjs} +5 -5
  18. package/dist/{cf-access-TWNzXltp.mjs → cf-access-BM9G0lhO.mjs} +4 -3
  19. package/dist/{cf-access-BcIBSKqG.mjs → cf-access-CWP4avfP.mjs} +3 -7
  20. package/dist/cf-build-output-BU3hqdHu.mjs +1 -0
  21. package/dist/{cf-build-output-DjvB_872.mjs → cf-build-output-Bc8i3dzE.mjs} +2 -2
  22. package/dist/cf-user-agent-ChjQp2MU.mjs +33 -0
  23. package/dist/cli/cli.mjs +199 -312
  24. package/dist/cli/cloudflare-operation-process.mjs +41 -15
  25. package/dist/cli/env-schema-probe.d.mts +7 -44
  26. package/dist/cli/env-schema-probe.mjs +14 -80
  27. package/dist/client-B60PwCC4.mjs +1 -0
  28. package/dist/{client-DlDJuY0s.mjs → client-DM9Kcf4e.mjs} +161 -415
  29. package/dist/{cloudflare-auth-CuxfF6OA.mjs → cloudflare-auth-CqFBDo52.mjs} +12 -39
  30. package/dist/{cloudflare-cmd-lHqNlJGW.mjs → cloudflare-cmd-BIAF_BIY.mjs} +7 -6
  31. package/dist/{cloudflare-config-BmhBv3HV.mjs → cloudflare-config-DV60XFFK.mjs} +16 -28
  32. package/dist/{cloudflare-connect-2G3rL2rP.mjs → cloudflare-connect-WjwnVOJA.mjs} +4 -4
  33. package/dist/{cloudflare-operations-CwI1bChl.mjs → cloudflare-operations-B42EZeJy.mjs} +26 -34
  34. package/dist/cloudflare-operations-CrSUFRzJ.mjs +1 -0
  35. package/dist/{cloudflare-process-2-TfIEzB.mjs → cloudflare-process-CeDWJRhj.mjs} +12 -7
  36. package/dist/collect-Cae8A7Zr.mjs +1 -0
  37. package/dist/{collect-DiTn9yr6.mjs → collect-xjffdCdk.mjs} +1 -1
  38. package/dist/{config-CSa15FvD.d.mts → config-7qoq2p9v.d.mts} +2 -2
  39. package/dist/{config-CLYAosnQ.mjs → config-BEm9vRvS.mjs} +11 -5
  40. package/dist/{config-DiowPT80.mjs → config-Bx_1SpnO.mjs} +87 -177
  41. package/dist/{config-DPByhVck.mjs → config-D0GY5ItR.mjs} +1 -1
  42. package/dist/config-QrJWu0IX.mjs +1 -0
  43. package/dist/config-entry.d.mts +1 -1
  44. package/dist/{connect-BfPBHHm-.mjs → connect-CKtk-EZe.mjs} +9 -9
  45. package/dist/create-project-B-ewF_Af.mjs +1 -0
  46. package/dist/{create-project-BdXEFKal.mjs → create-project-yInGo72M.mjs} +8 -8
  47. package/dist/database-provider.mjs +1 -2
  48. package/dist/{db-Xs80hcaA.mjs → db-7I_gfdVq.mjs} +177 -268
  49. package/dist/db-types-Bb4WBWIs.mjs +49 -0
  50. package/dist/{delete-d2vuou3j.mjs → delete-Cy-M1u-r.mjs} +6 -6
  51. package/dist/deploy-9lgfhrXS.mjs +2 -0
  52. package/dist/deploy-BYYlnsiy.mjs +6164 -0
  53. package/dist/deploy-managed-static-Ca4TFdmx.mjs +1595 -0
  54. package/dist/deploy-transport-DWlWBe6M.mjs +180 -0
  55. package/dist/deploy.d.mts +10 -0
  56. package/dist/deploy.mjs +82 -0
  57. package/dist/dev-inbox-Rd6j_8vM.mjs +217 -0
  58. package/dist/discover-ClzFSwns.mjs +1 -0
  59. package/dist/{discover-CkCYv9T_.mjs → discover-D2PGT63u.mjs} +2 -2
  60. package/dist/dispatch-DrTTk8Xg.mjs +431 -0
  61. package/dist/{dist-D3m88sjf.mjs → dist-BVdsO7Py.mjs} +5 -6
  62. package/dist/dist-CfgIkieS.mjs +1 -0
  63. package/dist/{dist-BVqXeR_h.mjs → dist-ipQi0Q8y.mjs} +2 -3
  64. package/dist/{domain-BsDUBAvt.mjs → domain-CZGxPv9u.mjs} +8 -23
  65. package/dist/{dotenv-BfU6eqFt.mjs → dotenv-CNazY3-w.mjs} +4 -16
  66. package/dist/edge.mjs +1 -2
  67. package/dist/{email-d_Aux1vM.mjs → email-BcjSyAL0.mjs} +4 -20
  68. package/dist/{email-_lGAHOhp.mjs → email-DzyNVuoU.mjs} +100 -192
  69. package/dist/email-cloudflare-DfG6UEMm.mjs +1096 -0
  70. package/dist/email-protocol-D9nTvhCp.mjs +82 -0
  71. package/dist/{entry-CMAkqBmU.mjs → entry-ehmBvs5w.mjs} +2 -2
  72. package/dist/{env-DMA3cXZt.mjs → env-0jrMQJI_.mjs} +6 -14
  73. package/dist/{env-BxocywBB.mjs → env-BJjULvL0.mjs} +2 -2
  74. package/dist/{env-C74QepDE.mjs → env-Nx3yf50r.mjs} +9 -9
  75. package/dist/{env-public-DR7ZM6d-.d.mts → env-public-CCdykygU.d.mts} +6 -23
  76. package/dist/{env-raw-jZpP5n47.mjs → env-raw-D74P4ebM.mjs} +15 -21
  77. package/dist/{env-types-CwXgeMgL.mjs → env-types-DS2_y4X8.mjs} +2 -2
  78. package/dist/env-validation-BT7z-qpQ.mjs +1 -0
  79. package/dist/env-validation-DYxjz_Wo.mjs +488 -0
  80. package/dist/{gen-DtkQhvQg.mjs → gen-CufHEf42.mjs} +132 -254
  81. package/dist/gen-sXyp5DFO.mjs +1 -0
  82. package/dist/generate-ClI89brV.mjs +1 -0
  83. package/dist/{generate-GDbL7sUr.mjs → generate-Dat0UTry.mjs} +38 -4
  84. package/dist/generated-wrangler-config-DeWj5F9Y.mjs +18 -0
  85. package/dist/{github-cmd-DaDdBbSS.mjs → github-cmd-FU8EjFyU.mjs} +28 -72
  86. package/dist/{handler-BHAn2fZJ.mjs → handler-BZ1t7-Rv.mjs} +2 -2
  87. package/dist/{handler-CNAwjRcW.d.mts → handler-_PqY82xe.d.mts} +1 -1
  88. package/dist/{headers-DlfR78Nu.mjs → headers-Di1FsD3e.mjs} +26 -81
  89. package/dist/{help-0bTe_lID.mjs → help-BT2hovNI.mjs} +26 -14
  90. package/dist/help-i2YGGnTH.mjs +1 -0
  91. package/dist/{inbound-PfQDLXc5.mjs → inbound-BuTfm11U.mjs} +71 -222
  92. package/dist/{inbound-CH5Mksyy.d.mts → inbound-brj2-TM5.d.mts} +19 -58
  93. package/dist/index.d.mts +2 -18
  94. package/dist/index.mjs +714 -762
  95. package/dist/{info-PYWwkWyt.mjs → info-l249eUdH.mjs} +5 -5
  96. package/dist/{init-DaBGmaXC.mjs → init-D0A6M64Q.mjs} +229 -392
  97. package/dist/isr-config-fZaJJ8t7.mjs +165 -0
  98. package/dist/{link-C6fjafep.mjs → link-WMoJFf4i.mjs} +9 -9
  99. package/dist/{list-BTFBlqKl.mjs → list-CQ2EQEHL.mjs} +7 -18
  100. package/dist/{live-CgQuTpqD.mjs → live-BcHoTDFe.mjs} +19 -17
  101. package/dist/{live-Du8jXwOW.d.mts → live-DJONVlQK.d.mts} +1 -1
  102. package/dist/load-user-env-DD5qveNU.mjs +49 -0
  103. package/dist/{local-d1-ga5O_idV.mjs → local-d1-BxvQYEFi.mjs} +6 -6
  104. package/dist/{login-GKcNUmtI.mjs → login-C2T1oVG-.mjs} +12 -12
  105. package/dist/login-XD844Xs-.mjs +1 -0
  106. package/dist/{logs-BiMSULmc.mjs → logs-DnC1d7xB.mjs} +6 -6
  107. package/dist/{migrate-NLsjBbuM.mjs → migrate-BDIprOYd.mjs} +70 -22
  108. package/dist/migrate-BRwU-blY.mjs +1 -0
  109. package/dist/migration-handler-Cg0Y4EPu.mjs +470 -0
  110. package/dist/{migration-handler-DM4clYj5.d.mts → migration-handler-CwlEQUoo.d.mts} +17 -26
  111. package/dist/{mime-DxCznlJq.mjs → mime-srOklVVv.mjs} +92 -395
  112. package/dist/mysql-migration-sql-BIS5vbNk.mjs +241 -0
  113. package/dist/nitro.d.mts +30 -0
  114. package/dist/nitro.mjs +88 -0
  115. package/dist/{node-DJicPvPj.mjs → node-cPadMgUO.mjs} +9 -25
  116. package/dist/{operator-args-DOBhIaIg.mjs → operator-args-UnE8Y2eK.mjs} +27 -26
  117. package/dist/{operator-auth-BEZ_u0Cz.mjs → operator-auth-Cr2zCc-J.mjs} +2 -2
  118. package/dist/{operator-client-DbDv4vtE.mjs → operator-client-C-ROjk1I.mjs} +4 -4
  119. package/dist/operator-cmd-D6gnZsnK.mjs +1 -0
  120. package/dist/{operator-cmd-BT4hgavL.mjs → operator-cmd-DHieWtFp.mjs} +8 -8
  121. package/dist/{output-C50ag2r3.mjs → output-Ba6ZbrzY.mjs} +37 -6
  122. package/dist/{package-json-DXfiT1jV.mjs → package-json-BjYqR-So.mjs} +1 -1
  123. package/dist/pages/client.d.mts +1 -1
  124. package/dist/pages/client.mjs +91 -5
  125. package/dist/pages/head.mjs +1 -2
  126. package/dist/pages/index.d.mts +1 -2
  127. package/dist/pages/index.mjs +6 -6
  128. package/dist/pages/islands-plugin.mjs +5 -83
  129. package/dist/pages/prefetch.mjs +1 -2
  130. package/dist/pages/protocol.d.mts +2 -2
  131. package/dist/pages/protocol.mjs +1 -1
  132. package/dist/pages/serialize.mjs +1 -2
  133. package/dist/plan-CKX_jWnD.mjs +1 -0
  134. package/dist/platform-args-B0HeTh0C.mjs +1 -0
  135. package/dist/{platform-args-DUeXY9Om.mjs → platform-args-CaCL_1Ch.mjs} +43 -60
  136. package/dist/{platform-auth-config-CkSx3usH.mjs → platform-auth-config-Z16-I8nT.mjs} +11 -12
  137. package/dist/{platform-auth-protection-BJimB_p9.mjs → platform-auth-protection-BXwZiJSF.mjs} +37 -27
  138. package/dist/{platform-auth-recovery-BU6izFAU.mjs → platform-auth-recovery-CXjfqyOv.mjs} +9 -10
  139. package/dist/{platform-cmd-BbY1dWiM.mjs → platform-cmd-DaAOiWTl.mjs} +16 -16
  140. package/dist/platform-cmd-PT4YwMLM.mjs +1 -0
  141. package/dist/{platform-discovery-DIYz8V63.mjs → platform-discovery-CHhNs8Nn.mjs} +1 -1
  142. package/dist/{platform-domain-CHVS6cV0.mjs → platform-domain-CxpvUeo0.mjs} +6 -6
  143. package/dist/{platform-lifecycle-DzCwqhFq.mjs → platform-lifecycle-DBiS0cJd.mjs} +1693 -2120
  144. package/dist/platform-lifecycle-u9pMOvxC.mjs +1 -0
  145. package/dist/{platform-management-CuuVDhyt.mjs → platform-management-DhEFdQAf.mjs} +696 -130
  146. package/dist/platform-management-DvBS83rC.mjs +1 -0
  147. package/dist/{platform-plans-config-CN-heS4q.mjs → platform-plans-config-BWn1S2Rv.mjs} +16 -12
  148. package/dist/{platform-recovery-CskSJgLh.mjs → platform-recovery-BUGOB4RC.mjs} +6 -9
  149. package/dist/{platform-registry-Cjv2Qf0r.mjs → platform-registry-B9mWX9LO.mjs} +13 -18
  150. package/dist/{platform-setup-BBxRxmFC.mjs → platform-setup-YvN9VQXV.mjs} +21 -28
  151. package/dist/{plugin-inference-BlQbOL0P.mjs → plugin-inference-DsARdQKE.mjs} +18 -33
  152. package/dist/prepare-CYT6tAzD.mjs +1 -0
  153. package/dist/{prepare-Do96654b.mjs → prepare-DEB5SeVJ.mjs} +12 -13
  154. package/dist/{prepare-Dq9hTIbo.mjs → prepare-PQCgsny0.mjs} +4 -4
  155. package/dist/{prerender-render-Ct20jftc.mjs → prerender-render-Bfsumdkv.mjs} +8 -2
  156. package/dist/prerender-render.d.mts +2 -0
  157. package/dist/prerender-render.mjs +1 -2
  158. package/dist/{project-cmd-DaoRrn-8.mjs → project-cmd-DVatD8Ev.mjs} +20 -20
  159. package/dist/{project-paths-GgcMozYz.mjs → project-paths-DMvEeSau.mjs} +9 -14
  160. package/dist/{project-BAm2aB6Q.mjs → project-rqDnVsJN.mjs} +8 -4
  161. package/dist/project-slug-6cyz8E7k.mjs +1 -0
  162. package/dist/{project-team-Q_lCA7Io.mjs → project-team-DJrWEAG1.mjs} +7 -7
  163. package/dist/{project-token-BArgK9o1.mjs → project-token-CBgLBuL6.mjs} +6 -6
  164. package/dist/{project-tsconfig-CVJhNMxs.mjs → project-tsconfig-bveqhlYA.mjs} +3 -5
  165. package/dist/project-zdB3fs9G.mjs +1 -0
  166. package/dist/{project-zero-trust-KO9Hu2Pq.mjs → project-zero-trust-92gLtZ25.mjs} +6 -6
  167. package/dist/{protocol-BPZaNqBo.d.mts → protocol-4H7V_3Os.d.mts} +1 -1
  168. package/dist/{protocol-CfaUwNs8.mjs → protocol-RNP0u7UY.mjs} +9 -3
  169. package/dist/{provision-BfaLiWbj.mjs → provision-BnSSkiED.mjs} +119 -866
  170. package/dist/{requests-C7Oeoh5u.mjs → requests-7W1Pygt2.mjs} +5 -5
  171. package/dist/resolve-project-PnhzMtY6.mjs +1 -0
  172. package/dist/resolve-project-WpwkCB_c.mjs +48 -0
  173. package/dist/{rollback-DVAtrLAl.mjs → rollback-BcASVnwP.mjs} +8 -18
  174. package/dist/{route-types-CbtsIeFn.mjs → route-types-BZi26DVS.mjs} +9 -91
  175. package/dist/routing-assets-VkrKIbxE.mjs +139 -0
  176. package/dist/{runner-DMBKSrRk.mjs → runner-CabsQ-iM.mjs} +22 -34
  177. package/dist/runner-So9mYfcm.mjs +1 -0
  178. package/dist/runner-mysql-BhRaONkO.mjs +146 -0
  179. package/dist/runner-mysql-DWwE8jKi.mjs +1 -0
  180. package/dist/{runner-pg-DV8p_zjA.mjs → runner-pg-BRemq_GX.mjs} +3 -3
  181. package/dist/runner-pg-_Xncr3H5.mjs +1 -0
  182. package/dist/runtime/ai.mjs +23 -25
  183. package/dist/runtime/auth-client-react.mjs +1 -2
  184. package/dist/runtime/auth-client-solid.mjs +1 -2
  185. package/dist/runtime/auth-client-svelte.mjs +1 -2
  186. package/dist/runtime/auth-client-vue.mjs +1 -2
  187. package/dist/runtime/auth-client.mjs +1 -2
  188. package/dist/runtime/auth.mjs +1 -2
  189. package/dist/runtime/better-auth-mysql.d.mts +2 -5
  190. package/dist/runtime/better-auth-mysql.mjs +9 -31
  191. package/dist/runtime/better-auth-pg.d.mts +2 -5
  192. package/dist/runtime/better-auth-pg.mjs +6 -32
  193. package/dist/runtime/better-auth.d.mts +2 -4
  194. package/dist/runtime/better-auth.mjs +9 -19
  195. package/dist/runtime/db.mjs +6 -2
  196. package/dist/runtime/durable.d.mts +18 -1
  197. package/dist/runtime/durable.mjs +26 -2
  198. package/dist/runtime/email/testing.d.mts +1 -1
  199. package/dist/runtime/email/testing.mjs +9 -23
  200. package/dist/runtime/email-protocol.d.mts +12 -0
  201. package/dist/runtime/email-protocol.mjs +1 -70
  202. package/dist/runtime/email.d.mts +1 -1
  203. package/dist/runtime/email.mjs +79 -221
  204. package/dist/runtime/env-public.d.mts +1 -1
  205. package/dist/runtime/env-public.mjs +12 -38
  206. package/dist/runtime/env.d.mts +1 -12
  207. package/dist/runtime/env.mjs +1 -2
  208. package/dist/runtime/handler.d.mts +1 -1
  209. package/dist/runtime/handler.mjs +1 -1
  210. package/dist/runtime/isr.mjs +1 -1
  211. package/dist/runtime/kv.mjs +1 -1
  212. package/dist/runtime/limits.mjs +1 -2
  213. package/dist/runtime/live-client.d.mts +3 -2
  214. package/dist/runtime/live-server.d.mts +2 -1
  215. package/dist/runtime/live-server.mjs +1 -16
  216. package/dist/runtime/live.d.mts +1 -1
  217. package/dist/runtime/live.mjs +1 -2
  218. package/dist/runtime/log.d.mts +2 -1
  219. package/dist/runtime/migration-handler-mysql.d.mts +2 -2
  220. package/dist/runtime/migration-handler-mysql.mjs +39 -8
  221. package/dist/runtime/migration-handler-pg.d.mts +2 -2
  222. package/dist/runtime/migration-handler-pg.mjs +1 -1
  223. package/dist/runtime/migration-handler.d.mts +2 -2
  224. package/dist/runtime/migration-handler.mjs +1 -470
  225. package/dist/runtime/queues.mjs +1 -1
  226. package/dist/runtime/remote/binding-handler.mjs +62 -62
  227. package/dist/runtime/remote/index.mjs +16 -77
  228. package/dist/runtime/response.mjs +1 -2
  229. package/dist/runtime/route-url.mjs +1 -2
  230. package/dist/runtime/routing.d.mts +3 -5
  231. package/dist/runtime/routing.mjs +82 -218
  232. package/dist/runtime/sandbox-container.d.mts +2 -2
  233. package/dist/runtime/sandbox-container.mjs +1 -2
  234. package/dist/runtime/sandbox.d.mts +2 -2
  235. package/dist/runtime/sandbox.mjs +13 -6
  236. package/dist/runtime/seed.d.mts +2 -1
  237. package/dist/runtime/sse.mjs +1 -2
  238. package/dist/runtime/storage.mjs +1 -1
  239. package/dist/runtime/validator.d.mts +1 -1
  240. package/dist/runtime/validator.mjs +1 -2
  241. package/dist/runtime/ws-server.d.mts +4 -4
  242. package/dist/runtime/ws-server.mjs +6 -28
  243. package/dist/runtime/ws.d.mts +1 -1
  244. package/dist/{sandbox-container-Bo0eiFKz.d.mts → sandbox-container-ChQRum-j.d.mts} +3 -1
  245. package/dist/{sandbox-container-C6ItmVuN.mjs → sandbox-container-a9LRUtii.mjs} +13 -2
  246. package/dist/{sandbox-C5LFoJMf.d.mts → sandbox-q3waMc2T.d.mts} +1 -1
  247. package/dist/{scan-C3uDzz6J.mjs → scan-C0BMdmEd.mjs} +84 -7
  248. package/dist/{secret-BvtB7IjY.mjs → secret-bg73f1Ge.mjs} +63 -81
  249. package/dist/{serialize-BPvnNQuA.mjs → serialize-BtQyaYoC.mjs} +10 -4
  250. package/dist/{skills-BgVMvQdy.mjs → skills-C_yRTg0g.mjs} +3 -3
  251. package/dist/{subcommand-prompt-BSlnD1fI.mjs → subcommand-prompt-Bm3ZlYgA.mjs} +39 -44
  252. package/dist/sveltekit.d.mts +2 -1
  253. package/dist/sveltekit.mjs +1 -1
  254. package/dist/validate-BQFdf0Pi.mjs +1 -0
  255. package/dist/{validate-C9qJArv7.mjs → validate-CheZGRE7.mjs} +4 -8
  256. package/dist/version-metadata-DIrqEHQo.mjs +73 -0
  257. package/dist/{wrangler-D9KTuqnv.mjs → wrangler-BYs07Rxy.mjs} +119 -378
  258. package/dist/wrapper-CwhpNWtH.mjs +663 -0
  259. package/dist/{ws-CChrrAU-.d.mts → ws-aKVYB-fA.d.mts} +1 -1
  260. package/dist/yarn-pnp-DLbEFMT0.mjs +92 -0
  261. package/docs/guide/ai.md +8 -2
  262. package/docs/guide/auth.md +2 -0
  263. package/docs/guide/database/mysql.md +14 -3
  264. package/docs/guide/database/postgresql.md +2 -0
  265. package/docs/guide/database.md +3 -5
  266. package/docs/guide/durable-state.md +32 -4
  267. package/docs/guide/platform/administration/access.md +4 -0
  268. package/docs/guide/platform/administration/connected-apps.md +55 -0
  269. package/docs/guide/platform/installation/credentials.md +21 -3
  270. package/docs/guide/platform/installation/domains.md +1 -1
  271. package/docs/guide/platform/installation/maintenance.md +38 -1
  272. package/docs/guide/platform/installation/prerequisites.md +6 -2
  273. package/docs/guide/platform/installation/setup.md +23 -1
  274. package/docs/guide/platform/installation/uninstall.md +6 -1
  275. package/docs/guide/quickstart.md +2 -0
  276. package/docs/guide/sandboxes.md +3 -1
  277. package/docs/guide/self-hosted-platform.md +1 -1
  278. package/docs/integrations/cloudflare.md +2 -2
  279. package/docs/integrations/frameworks/analog.md +3 -11
  280. package/docs/integrations/frameworks/nuxt.md +7 -10
  281. package/docs/integrations/nodejs-bun-deno.md +2 -0
  282. package/docs/reference/api/deploy.md +23 -0
  283. package/docs/reference/api/pages.md +2 -0
  284. package/docs/reference/api.md +3 -1
  285. package/docs/reference/cli/database.md +9 -3
  286. package/docs/reference/cli/platform-installation.md +19 -7
  287. package/docs/reference/cli/setup.md +2 -0
  288. package/docs/reference/config.md +2 -0
  289. package/package.json +39 -36
  290. package/sandbox.Dockerfile +1 -1
  291. package/skills/void/SKILL.md +2 -1
  292. package/dist/auth-LMJcNESe.mjs +0 -2
  293. package/dist/cf-build-output-H9a97vME.mjs +0 -2
  294. package/dist/cf-user-agent-lKblH3zU.mjs +0 -17
  295. package/dist/client-tso2OfcG.mjs +0 -2
  296. package/dist/cloudflare-operations-BlYLlowZ.mjs +0 -2
  297. package/dist/collect-DLyFDiKW.mjs +0 -2
  298. package/dist/config-5r-YpMC-.mjs +0 -2
  299. package/dist/config-B_ggY-IO.mjs +0 -89
  300. package/dist/config-BtSFvXZx.mjs +0 -2
  301. package/dist/config-write-AHGesphx.mjs +0 -61
  302. package/dist/create-project-qFDC45zg.mjs +0 -2
  303. package/dist/deploy-Bqe1PYBw.mjs +0 -10458
  304. package/dist/deploy-VsWsVQkw.mjs +0 -2
  305. package/dist/dev-inbox-CK-UuPob.mjs +0 -297
  306. package/dist/discover-EDUf6JJw.mjs +0 -2
  307. package/dist/dist-Bx1z6Eva.mjs +0 -2
  308. package/dist/dist-_UUlL6bg.mjs +0 -2
  309. package/dist/env-validation-CrVNjsPm.mjs +0 -2
  310. package/dist/env-validation-Dxdx_5wo.mjs +0 -951
  311. package/dist/gen-dA9hW7AV.mjs +0 -2
  312. package/dist/head-client-DzmJGN4C.mjs +0 -90
  313. package/dist/help-DfQYVfGY.mjs +0 -2
  314. package/dist/login-mx_ydhmp.mjs +0 -2
  315. package/dist/migrate-BHp07yJE.mjs +0 -2
  316. package/dist/operator-cmd-CwBB-1yb.mjs +0 -2
  317. package/dist/pages/head-client.d.mts +0 -13
  318. package/dist/pages/head-client.mjs +0 -2
  319. package/dist/plan-CH2G51je.mjs +0 -2
  320. package/dist/platform-args-D4E1PjVw.mjs +0 -2
  321. package/dist/platform-cmd-BbmJiq5O.mjs +0 -2
  322. package/dist/platform-lifecycle-ByAlpkhV.mjs +0 -2
  323. package/dist/platform-management-CBOT4BSM.mjs +0 -2
  324. package/dist/prepare-DRUV-g3X.mjs +0 -2
  325. package/dist/project-DedqCp59.mjs +0 -2
  326. package/dist/project-slug-DofjTFd-.mjs +0 -2
  327. package/dist/provision-Wu9ZBk9L.mjs +0 -2
  328. package/dist/resolve-project-BIeYs9Cw.mjs +0 -2
  329. package/dist/resolve-project-CP8rZs_p.mjs +0 -28
  330. package/dist/runner-9wjsSZx-.mjs +0 -2
  331. package/dist/runner-mysql-CEzKtmFb.mjs +0 -54
  332. package/dist/runner-mysql-CkFqZ6CE.mjs +0 -2
  333. package/dist/runner-pg-BGYRFdRp.mjs +0 -2
  334. package/dist/runtime/env-helpers.d.mts +0 -2
  335. package/dist/runtime/env-helpers.mjs +0 -2
  336. package/dist/validate-BJr9LfXy.mjs +0 -2
  337. package/dist/yarn-pnp-CUX_iTPA.mjs +0 -188
@@ -1,11 +1,11 @@
1
- import { a as join, n as dirname, o as normalize, t as basename } from "./dist-BVqXeR_h.mjs";
2
- import "./project-paths-GgcMozYz.mjs";
3
- import { m as readConfig } from "./config-DiowPT80.mjs";
4
- import { a as hasSandboxSqliteMigration, c as resolveSandboxConfig, i as assertSandboxNamespaceConfig, l as sandboxContainerConfig, r as SANDBOX_MIGRATION_TAG } from "./config-B_ggY-IO.mjs";
5
- import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-BmhBv3HV.mjs";
1
+ import { a as join, n as dirname, o as normalize, t as basename } from "./dist-ipQi0Q8y.mjs";
2
+ import "./project-paths-DMvEeSau.mjs";
3
+ import { d as readConfig } from "./config-Bx_1SpnO.mjs";
4
+ import { i as persistCloudflareConfig, r as materializeCloudflareConfig } from "./cloudflare-config-DV60XFFK.mjs";
6
5
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
7
6
  import { appendSqliteClassMigration, isRecord } from "@void/deploy-core";
8
7
  import { createHash } from "node:crypto";
8
+ import { isDeepStrictEqual } from "node:util";
9
9
  import { SyntaxKind, applyEdits, createScanner, findNodeAtLocation, modify, parse, parseTree } from "jsonc-parser";
10
10
  //#region src/cli/wrangler.ts
11
11
  const COMPAT_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
@@ -163,27 +163,14 @@ function resolveGeneratedName(base, used, kind) {
163
163
  }
164
164
  }
165
165
  /**
166
- * Read compatibility settings from `wrangler.jsonc`/`wrangler.json`,
167
- * `void.json`, and build output, with priority:
168
- * void.json > wrangler.jsonc > build output > latest known-good date.
169
- *
170
- * This function is read-only: when no explicit `compatibility_date` exists, it
171
- * returns the latest known-good date without writing it anywhere. Use
172
- * `ensureWranglerCompat()` when the caller is in a real dev/build/deploy
173
- * lifecycle and wants to persist the default in `void.json`.
174
- *
175
- * @param buildOutputDir - Optional path to the build output directory (e.g.
176
- * `dist/ssr`) which may contain a plugin-generated `wrangler.json` with the
177
- * correct compat settings for the built worker.
166
+ * Read compatibility settings with priority: Void config > project Wrangler config >
167
+ * `<buildOutputDir>/wrangler.json` > latest known-good date. Read-only; use
168
+ * `ensureWranglerCompat()` to pin the default date.
178
169
  */
179
170
  function readWranglerCompat(root, config, buildOutputDir) {
180
171
  return resolveWranglerCompat(readWranglerCompatFields(root, config, buildOutputDir));
181
172
  }
182
- /**
183
- * Read compatibility settings and ensure the default date is pinned in
184
- * `void.json` when no explicit date exists in void.json, wrangler config, or
185
- * build output.
186
- */
173
+ /** Like `readWranglerCompat()`, but pins the default date when no source sets one. */
187
174
  function ensureWranglerCompat(root, config, buildOutputDir) {
188
175
  const fields = readWranglerCompatFields(root, config, buildOutputDir);
189
176
  const defaultDate = fields.voidDate ?? fields.wranglerDate ?? fields.buildDate ? void 0 : ensureVoidCompatibilityDate(root, fields.voidConfig);
@@ -217,13 +204,10 @@ function readWranglerCompatFields(root, config, buildOutputDir) {
217
204
  }
218
205
  if (Array.isArray(buildParsed.compatibility_flags) && buildParsed.compatibility_flags.every((f) => typeof f === "string")) buildFlags = buildParsed.compatibility_flags;
219
206
  } catch {}
220
- const voidDate = voidConfig?.worker?.compatibility_date;
221
- const voidFlags = voidConfig?.worker?.compatibility_flags;
222
- if (voidDate !== void 0) validateCompatDate(voidDate, "void.json worker config");
223
207
  return {
224
208
  voidConfig,
225
- voidDate,
226
- voidFlags,
209
+ voidDate: voidConfig?.worker?.compatibility_date,
210
+ voidFlags: voidConfig?.worker?.compatibility_flags,
227
211
  wranglerDate,
228
212
  wranglerFlags,
229
213
  buildDate,
@@ -266,9 +250,8 @@ function ensureVoidCompatibilityDate(root, config) {
266
250
  return LATEST_KNOWN_COMPAT_DATE;
267
251
  }
268
252
  /**
269
- * Sync inferred/configured bindings into the project's wrangler.jsonc for local dev.
270
- * Only adds bindings that are missing — existing bindings are preserved.
271
- * Returns true if the file was modified.
253
+ * Add missing inferred bindings to the project Wrangler config for local dev; existing
254
+ * bindings are kept. Returns true if the file was written.
272
255
  */
273
256
  function syncWranglerBindings(root, bindings, options) {
274
257
  const { configPath, parsed, created } = readOrCreateProjectWranglerConfig(root);
@@ -357,67 +340,12 @@ function syncWranglerBindings(root, bindings, options) {
357
340
  modified = true;
358
341
  }
359
342
  }
360
- if (options?.durableObjects && options.durableObjects.length > 0) {
361
- const existingBindings = durableObjectBindingsOf(parsed);
362
- for (const module of options.durableObjects) {
363
- const conflict = existingBindings.find((binding) => binding.name === module.bindingName && binding.class_name !== module.className);
364
- if (conflict) throw new Error(`durable: binding '${module.bindingName}' is already configured for class '${conflict.class_name}', but durable-objects/ requires '${module.className}'.`);
365
- }
366
- const additions = options.durableObjects.filter((module) => !existingBindings.some((binding) => binding.name === module.bindingName)).map((module) => ({
367
- name: module.bindingName,
368
- class_name: module.className
369
- }));
370
- if (additions.length > 0) {
371
- parsed.durable_objects = { bindings: [...existingBindings, ...additions] };
372
- modified = true;
373
- }
374
- const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
375
- for (const module of options.durableObjects) {
376
- if (migrations.find((migration) => migration.tag === module.migrationTag && !migration.new_sqlite_classes?.includes(module.className))) throw new Error(`durable: migration tag '${module.migrationTag}' is already used by another Durable Object migration.`);
377
- if (!hasDurableObjectSqliteMigration(migrations, module.className)) {
378
- migrations.push({
379
- tag: module.migrationTag,
380
- new_sqlite_classes: [module.className]
381
- });
382
- modified = true;
383
- }
384
- }
385
- if (modified) parsed.migrations = migrations;
386
- }
387
- if (bindings.needsSandbox) {
388
- const sandbox = options?.sandbox ?? resolveSandboxConfig({ sandbox: true }, root);
389
- const bindingName = options?.bindingNames?.sandbox ?? sandbox?.binding ?? "SANDBOX";
390
- const className = sandbox.className;
391
- assertSandboxNamespaceConfig(parsed, sandbox);
392
- const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
393
- if (!existingDurableObjectBindings.some((binding) => binding.name === bindingName)) {
394
- parsed.durable_objects = { bindings: [...existingDurableObjectBindings, {
395
- name: bindingName,
396
- class_name: className
397
- }] };
398
- modified = true;
399
- }
400
- const existingContainers = parsed.containers ?? [];
401
- const containers = [...existingContainers.filter((container) => container.class_name !== className), sandboxContainerConfig(sandbox)];
402
- if (JSON.stringify(containers) !== JSON.stringify(existingContainers)) {
403
- parsed.containers = containers;
404
- modified = true;
405
- }
406
- const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
407
- if (!hasSandboxSqliteMigration(migrations, className)) {
408
- parsed.migrations = [...migrations, {
409
- tag: SANDBOX_MIGRATION_TAG,
410
- new_sqlite_classes: [className]
411
- }];
412
- modified = true;
413
- }
414
- }
415
343
  if (bindings.needsLive || options?.live) {
416
344
  const existingDurableObjectBindings = durableObjectBindingsOf(parsed);
417
345
  const liveConfig = typeof options?.live === "object" ? options.live : resolveLiveBindingConfig(root, {
418
346
  existingBindings: existingDurableObjectBindings,
419
347
  reservedBindings: options?.websockets?.map((route) => route.bindingName),
420
- reservedClasses: [...options?.websockets?.map((route) => route.className) ?? [], options?.sandbox?.className]
348
+ reservedClasses: options?.websockets?.map((route) => route.className)
421
349
  });
422
350
  if (!existingDurableObjectBindings.some((binding) => binding.name === liveConfig.bindingName)) {
423
351
  parsed.durable_objects = { bindings: [...existingDurableObjectBindings, {
@@ -438,20 +366,38 @@ function syncWranglerBindings(root, bindings, options) {
438
366
  if (created || modified) writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
439
367
  return created || modified;
440
368
  }
441
- const NO_INFERRED_BINDINGS = {
442
- needsD1: false,
443
- needsKV: false,
444
- needsR2: false,
445
- needsAuth: false,
446
- needsQueues: false,
447
- needsAI: false,
448
- needsSandbox: false,
449
- needsLive: false
450
- };
451
369
  /** Persist convention-derived Durable Object bindings and append-only migration history. */
452
370
  function syncWranglerDurableObjects(root, durableObjects) {
453
371
  if (durableObjects.length === 0) return false;
454
- return syncWranglerBindings(root, NO_INFERRED_BINDINGS, { durableObjects });
372
+ const { configPath, parsed, created } = readOrCreateProjectWranglerConfig(root);
373
+ let modified = false;
374
+ const existingBindings = durableObjectBindingsOf(parsed);
375
+ for (const module of durableObjects) {
376
+ const conflict = existingBindings.find((binding) => binding.name === module.bindingName && binding.class_name !== module.className);
377
+ if (conflict) throw new Error(`durable: binding '${module.bindingName}' is already configured for class '${conflict.class_name}', but durable-objects/ requires '${module.className}'.`);
378
+ }
379
+ const additions = durableObjects.filter((module) => !existingBindings.some((binding) => binding.name === module.bindingName)).map((module) => ({
380
+ name: module.bindingName,
381
+ class_name: module.className
382
+ }));
383
+ if (additions.length > 0) {
384
+ parsed.durable_objects = { bindings: [...existingBindings, ...additions] };
385
+ modified = true;
386
+ }
387
+ const migrations = Array.isArray(parsed.migrations) ? parsed.migrations : [];
388
+ for (const module of durableObjects) {
389
+ if (migrations.find((migration) => migration.tag === module.migrationTag && !migration.new_sqlite_classes?.includes(module.className))) throw new Error(`durable: migration tag '${module.migrationTag}' is already used by another Durable Object migration.`);
390
+ if (!hasDurableObjectSqliteMigration(migrations, module.className)) {
391
+ migrations.push({
392
+ tag: module.migrationTag,
393
+ new_sqlite_classes: [module.className]
394
+ });
395
+ modified = true;
396
+ }
397
+ }
398
+ if (modified) parsed.migrations = migrations;
399
+ if (created || modified) writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
400
+ return created || modified;
455
401
  }
456
402
  /** Persist WebSocket Durable Object bindings and SQLite migration history. */
457
403
  function syncWranglerWebSockets(root, websockets) {
@@ -459,10 +405,8 @@ function syncWranglerWebSockets(root, websockets) {
459
405
  return writeProvisionedWranglerConfig(root, { webSockets: websockets }).modified;
460
406
  }
461
407
  /**
462
- * Return registered WebSocket classes that no longer have a source route.
463
- * These classes must remain exported while their data-bearing bindings remain
464
- * in Wrangler configuration. Arbitrary user Durable Objects are excluded by
465
- * requiring provenance from Void's WebSocket migration tag.
408
+ * Registered WebSocket classes without a source route. They stay exported while their
409
+ * bindings remain; only classes created by Void's WebSocket migration tag count.
466
410
  */
467
411
  function readWranglerWebSocketTombstones(root, websockets) {
468
412
  const configPath = projectWranglerPaths(root).find((path) => existsSync(path));
@@ -474,23 +418,15 @@ function readWranglerWebSocketTombstones(root, websockets) {
474
418
  const bindings = parsed.durable_objects?.bindings;
475
419
  return [...new Set((Array.isArray(bindings) ? bindings : []).flatMap((binding) => typeof binding.class_name === "string" && historicalClasses.has(binding.class_name) && !currentClasses.has(binding.class_name) ? [binding.class_name] : []))].sort();
476
420
  }
477
- /**
478
- * Ensure a wrangler config has an explicit compatibility date.
479
- * Used when `worker.compatibility_date` is configured in void.json but the
480
- * active framework reads Cloudflare settings from wrangler.jsonc/json.
481
- */
421
+ /** Write the resolved compatibility date for frameworks that read the Wrangler config. */
482
422
  function ensureWranglerCompatibilityDate(root, compatibilityDate) {
483
- validateCompatDate(compatibilityDate, "void.json worker config");
484
423
  const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
485
424
  if (parsed.compatibility_date === compatibilityDate) return false;
486
425
  parsed.compatibility_date = compatibilityDate;
487
426
  writeProjectWranglerFile(configPath, JSON.stringify(parsed, null, 2) + "\n");
488
427
  return true;
489
428
  }
490
- /**
491
- * Ensure the `nodejs_als` compatibility flag exists in wrangler config.
492
- * Returns true if the config file was modified.
493
- */
429
+ /** Add the `nodejs_als` compatibility flag. Returns true if the file was written. */
494
430
  function ensureWranglerNodejsAlsFlag(root) {
495
431
  const { configPath, parsed } = readOrCreateProjectWranglerConfig(root);
496
432
  const compatibilityFlags = Array.isArray(parsed.compatibility_flags) ? parsed.compatibility_flags : [];
@@ -539,11 +475,8 @@ function writeManagedQueueProvenance(text, provenance) {
539
475
  return `${marker}${text.includes("\r\n") ? "\r\n" : "\n"}${text}`;
540
476
  }
541
477
  /**
542
- * Return explicitly Void-owned consumer names that may need remote cleanup.
543
- *
544
- * Current managed consumers are included for schema-1 upgrades; the activation layer subtracts
545
- * consumers still present in the desired config. Pending removals survive failed deploys so a
546
- * later retry can finish cleanup without inferring ownership from queue naming conventions.
478
+ * Void-owned consumer queues that may need remote cleanup: current managed consumers (the
479
+ * caller subtracts desired ones) and pending removals, which survive failed deploys.
547
480
  */
548
481
  function readWranglerManagedQueueCleanupCandidates(configPath) {
549
482
  if (!existsSync(configPath)) return [];
@@ -567,14 +500,8 @@ function acknowledgeWranglerManagedQueueRemovals(configPath, removedQueues) {
567
500
  if (finalText !== raw) writeProjectWranglerFile(configPath, finalText);
568
501
  }
569
502
  /**
570
- * Fill root Wrangler config fields required by generated/provisioned resources, including
571
- * append-only WebSocket Durable Object bindings and migrations, and Mode B email fields
572
- * (`send_email`, `addresses`, `vars`) that have no Wrangler command.
573
- *
574
- * Comment-preserving: uses `jsonc-parser` `modify()` + `applyEdits()` so
575
- * comments and unrelated content survive (unlike `syncWranglerBindings`, which
576
- * round-trips through `JSON.stringify` and strips comments). Every edit is an
577
- * idempotent upsert — running twice produces byte-identical output.
503
+ * Apply a {@link ProvisionedWranglerPatch} to the root Wrangler config. Edits keep comments
504
+ * and unrelated content, and a second run produces the same bytes.
578
505
  */
579
506
  function writeProvisionedWranglerConfig(root, patch, options) {
580
507
  const configPath = options?.configPath ?? discoverWranglerConfigPath(root);
@@ -676,7 +603,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
676
603
  if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — cannot adopt ${JSON.stringify(binding)} into "${field}" because that binding name is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this would make the config undeployable. Rename the conflicting binding and retry.`);
677
604
  if (matches.length === 1) {
678
605
  const { index, entry: existing } = matches[0];
679
- for (const [key, value] of Object.entries(properties)) if (!jsonEqual(existing[key], value)) set([
606
+ for (const [key, value] of Object.entries(properties)) if (!isDeepStrictEqual(existing[key], value)) set([
680
607
  field,
681
608
  index,
682
609
  key
@@ -753,7 +680,7 @@ function writeProvisionedWranglerConfig(root, patch, options) {
753
680
  const existing = currentList[index];
754
681
  for (const [key, value] of Object.entries(entry)) {
755
682
  if (value === void 0) continue;
756
- if (!jsonEqual(existing[key], value)) set([
683
+ if (!isDeepStrictEqual(existing[key], value)) set([
757
684
  "queues",
758
685
  section,
759
686
  index,
@@ -829,13 +756,13 @@ function writeProvisionedWranglerConfig(root, patch, options) {
829
756
  for (const [key, value] of Object.entries(patch.vars)) {
830
757
  const owner = owners.get(key);
831
758
  if (owner !== void 0) throw new Error(`deploy: cannot update "${configPath}" — cannot write var ${JSON.stringify(key)} because that binding name is already used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this would make the config undeployable. Rename the conflicting binding and retry.`);
832
- if (!jsonEqual(currentVars[key], value)) set(["vars", key], value);
759
+ if (!isDeepStrictEqual(currentVars[key], value)) set(["vars", key], value);
833
760
  }
834
761
  }
835
762
  if (patch.addresses !== void 0) {
836
763
  const currentAddresses = parseJsonc(text).addresses;
837
764
  if (patch.addresses === null) text = removeMember(text, ["addresses"], { formattingOptions });
838
- else if (!jsonEqual(currentAddresses, patch.addresses)) text = applyMemberEdit(text, ["addresses"], patch.addresses, { formattingOptions });
765
+ else if (!isDeepStrictEqual(currentAddresses, patch.addresses)) text = applyMemberEdit(text, ["addresses"], patch.addresses, { formattingOptions });
839
766
  }
840
767
  const droppedComment = findDroppedComment(extractCommentTokens(original), extractCommentTokens(text));
841
768
  if (droppedComment !== void 0) {
@@ -957,12 +884,7 @@ function parseCustomDomains(value, configPath) {
957
884
  }
958
885
  return domains;
959
886
  }
960
- /**
961
- * Extract the multiset of comment TOKENS (line + block) from JSONC source using
962
- * jsonc-parser's scanner — exact by construction, no regex. Each token is its
963
- * verbatim source slice, so a relocated comment keeps identical text (its
964
- * multiset entry is unchanged) while a dropped comment removes one.
965
- */
887
+ /** Every line and block comment in JSONC source, verbatim, in order. */
966
888
  function extractCommentTokens(text) {
967
889
  const scanner = createScanner(text, false);
968
890
  const tokens = [];
@@ -976,12 +898,7 @@ function extractCommentTokens(text) {
976
898
  }
977
899
  return tokens;
978
900
  }
979
- /**
980
- * Multiset-subset check: return the first comment token present in `before` but
981
- * missing (accounting for repeats) from `after`, or `undefined` when `after` is
982
- * a superset of `before`. The final gate uses this to prove no comment TEXT was
983
- * dropped by the edits.
984
- */
901
+ /** The first comment in `before` missing from `after`, counting repeats, if any. */
985
902
  function findDroppedComment(before, after) {
986
903
  const counts = /* @__PURE__ */ new Map();
987
904
  for (const token of after) counts.set(token, (counts.get(token) ?? 0) + 1);
@@ -991,10 +908,7 @@ function findDroppedComment(before, after) {
991
908
  counts.set(token, remaining - 1);
992
909
  }
993
910
  }
994
- /**
995
- * Detect indentation from an existing config so `jsonc-parser` formats inserted
996
- * content to match. Falls back to two-space indentation (the repo default).
997
- */
911
+ /** Match inserted content to the file's indentation; two spaces by default. */
998
912
  function detectFormattingOptions(text) {
999
913
  const match = text.match(/^([ \t]+)\S/m);
1000
914
  if (match) {
@@ -1015,27 +929,15 @@ function detectFormattingOptions(text) {
1015
929
  }
1016
930
  function parseJsonc(text) {
1017
931
  const errors = [];
1018
- const result = parse(text, errors, { allowTrailingComma: true });
932
+ const source = text.startsWith(UTF8_BOM) ? text.slice(1) : text;
933
+ const result = parse(source, errors, { allowTrailingComma: true });
1019
934
  if (errors.length > 0) throw new SyntaxError("Failed to parse JSONC");
1020
935
  return result;
1021
936
  }
1022
937
  /**
1023
- * `modify()` + `applyEdits()`, but when the edit APPENDS a new member after a
1024
- * sibling that carries a trailing inline comment, keep that comment attached to
1025
- * the sibling it documented.
1026
- *
1027
- * jsonc-parser's formatting `modify()` reflows the whole enclosing member/entry
1028
- * region and re-emits a trailing inline comment at the END of that region — so
1029
- * inserting `migrations_dir` after `"database_id": "id" // production db` (or
1030
- * appending a queue entry after `{ … } // jobs producer`) silently reassociates
1031
- * the comment onto the NEWLY inserted member. That violates the writer's
1032
- * comment-preservation contract. Here we detect that exact case, run the
1033
- * (comment-free) formatting edit on a stripped copy, then splice the comment
1034
- * back right after the sibling's separating comma so it stays put.
1035
- *
1036
- * Every other edit (value replacement, append after a comment-free sibling,
1037
- * first insertion into a missing container) falls through to the plain path, so
1038
- * behavior is byte-identical to before outside the trailing-comment case.
938
+ * `modify()` + `applyEdits()` that keeps a trailing inline comment on the sibling it
939
+ * documented. When a member is appended, `modify()` moves that comment after the new
940
+ * member, so edit a copy without it and splice it back after the sibling's comma.
1039
941
  */
1040
942
  function applyMemberEdit(text, path, value, options) {
1041
943
  const plain = () => applyEdits(text, modify(text, path, value, options));
@@ -1070,26 +972,15 @@ function applyMemberEdit(text, path, value, options) {
1070
972
  } catch {
1071
973
  return plainResult;
1072
974
  }
1073
- if (!jsonEqual(relocatedParsed, parseJsonc(plainResult))) return plainResult;
975
+ if (!isDeepStrictEqual(relocatedParsed, parseJsonc(plainResult))) return plainResult;
1074
976
  return relocated;
1075
977
  }
1076
978
  /**
1077
- * Remove one object member (the property at `path`), keeping every comment.
1078
- *
1079
- * jsonc-parser's `modify(text, path, undefined)` deletes from the END of the
1080
- * previous member to the end of the removed one — so the previous sibling's
1081
- * trailing comment, a full-line comment above the member, and the member's own
1082
- * trailing comment all vanish (measured on 4.x). The final comment gate would
1083
- * then refuse the write for the common `"name": "app", // worker` shape. Here
1084
- * the property node's exact source range is spliced out instead, plus ONE
1085
- * separating comma (the following one when present, else the preceding one so
1086
- * a strict `.json` file never gains a trailing comma) and the now-blank line it
1087
- * sat on. Comments are never inside those ranges, so they all stay put; a
1088
- * comment that was attached to the removed member is left orphaned on its line.
1089
- *
1090
- * Validate-before-return backstop: the spliced text must parse and equal the
1091
- * plain `modify()` result's data; otherwise the plain edit is returned and the
1092
- * final gate decides. An absent member is a no-op.
979
+ * Remove the object member at `path`, keeping every comment. `modify(…, undefined)` also
980
+ * deletes the comments between the previous member and this one, so splice out the
981
+ * property, one separating comma (the following one, else the preceding one, so strict
982
+ * JSON gains no trailing comma) and its blank line. Falls back to `modify()` when the
983
+ * result's data differs.
1093
984
  */
1094
985
  function removeMember(text, path, options) {
1095
986
  const root = parseTree(text, void 0, { allowTrailingComma: true });
@@ -1136,20 +1027,12 @@ function removeMember(text, path, options) {
1136
1027
  } catch {
1137
1028
  return plainResult;
1138
1029
  }
1139
- if (!jsonEqual(splicedParsed, parseJsonc(plainResult))) return plainResult;
1030
+ if (!isDeepStrictEqual(splicedParsed, parseJsonc(plainResult))) return plainResult;
1140
1031
  return spliced;
1141
1032
  }
1142
1033
  /**
1143
- * If a trailing inline comment sits on the same line right after `offset`,
1144
- * return its text and end offset. Only whitespace and an OPTIONAL single
1145
- * separator comma may sit between the sibling's value and the comment — so both
1146
- * `"id": "x" // c` and `"id": "x", // c` (a JSONC trailing comma, or the
1147
- * separator once a sibling follows) are recognized. A `//` line comment or a
1148
- * single-line `/* *\/` block comment counts; a newline or closing bracket first
1149
- * means there is no trailing comment (returns undefined). `offset` points just
1150
- * past the sibling's value, and the sibling is always its container's LAST
1151
- * member, so any comma here is a trailing/separator comma — never a boundary to
1152
- * an existing following member.
1034
+ * The `//` or single-line block comment on the same line after `offset` (just past the
1035
+ * last member's value), allowing one comma before it.
1153
1036
  */
1154
1037
  function readTrailingComment(text, offset) {
1155
1038
  let i = offset;
@@ -1178,12 +1061,7 @@ function readTrailingComment(text, offset) {
1178
1061
  };
1179
1062
  }
1180
1063
  }
1181
- /**
1182
- * Throw (without writing) if any object in the config declares the same member
1183
- * name twice. See the call site for why a duplicate makes property-level upserts
1184
- * silently ineffective. Walks the jsonc AST so nested objects (queue consumers,
1185
- * D1 entries, …) are covered, not just the top level.
1186
- */
1064
+ /** Throw if any object in the config, at any depth, declares the same key twice. */
1187
1065
  function assertNoDuplicateMembers(text, configPath) {
1188
1066
  const root = parseTree(text, void 0, { allowTrailingComma: true });
1189
1067
  if (!root) return;
@@ -1205,7 +1083,7 @@ function assertNoDuplicateMembers(text, configPath) {
1205
1083
  };
1206
1084
  walk(root);
1207
1085
  }
1208
- /** 1-based line/column for a byte offset — used in duplicate-key error messages. */
1086
+ /** 1-based line and column of an offset. */
1209
1087
  function offsetToLineColumn(text, offset) {
1210
1088
  let line = 1;
1211
1089
  let column = 1;
@@ -1243,19 +1121,9 @@ function validateDurableObjectMigrations(value, configPath) {
1243
1121
  return value;
1244
1122
  }
1245
1123
  /**
1246
- * wrangler's friendly label for each binding namespace. Mirrors
1247
- * `friendlyBindingNames` in `wrangler-dist/cli.js` — the map
1248
- * `validateBindingsHaveUniqueNames` iterates to gather every worker-wide binding
1249
- * name. Drives the owner name in the worker-wide producer-collision error.
1250
- *
1251
- * This is a 1:1 copy of wrangler's `friendlyBindingNames` EXCEPT `queues`, which
1252
- * is intentionally ABSENT: wrangler folds in `queues.producers`, but here producer
1253
- * identity is handled by the upsert's own binding-match logic (and consumers carry
1254
- * no binding), so including it would flag the very producer we are about to append
1255
- * as a self-collision. Every OTHER field wrangler enumerates is present (including
1256
- * `unsafe_hello_world`). `secrets.required` — which wrangler folds in separately
1257
- * under the label "Secret", not via this map — is handled in
1258
- * `collectWorkerBindingNames`.
1124
+ * Wrangler's `friendlyBindingNames`: the fields `validateBindingsHaveUniqueNames` reads, with
1125
+ * their labels. `queues` is left out because the producer upsert matches its own entries;
1126
+ * including it would make a producer collide with itself.
1259
1127
  */
1260
1128
  const FRIENDLY_BINDING_NAMES = {
1261
1129
  data_blobs: "Data Blob",
@@ -1297,15 +1165,7 @@ const FRIENDLY_BINDING_NAMES = {
1297
1165
  vpc_services: "VPC Service",
1298
1166
  vpc_networks: "VPC Network"
1299
1167
  };
1300
- /**
1301
- * Collect every binding NAME already used across the worker config, mapped to
1302
- * wrangler's friendly owner label (first writer wins on ties). Mirrors the exact
1303
- * name set `validateBindingsHaveUniqueNames` builds in `wrangler-dist/cli.js`:
1304
- * `getBindingNames(config[field])` for every `friendlyBindingNames` field, PLUS
1305
- * `config.secrets.required` under the label "Secret" — minus `queues` (see
1306
- * FRIENDLY_BINDING_NAMES for why). Used to fail closed before appending a queue
1307
- * producer whose binding collides with any other worker-wide binding.
1308
- */
1168
+ /** Every binding name in the config, mapped to its owner's label (first one wins). */
1309
1169
  function collectWorkerBindingNames(config) {
1310
1170
  const owners = /* @__PURE__ */ new Map();
1311
1171
  const claim = (name, friendly) => {
@@ -1316,26 +1176,18 @@ function collectWorkerBindingNames(config) {
1316
1176
  if (secrets && secrets.required !== void 0) {
1317
1177
  if (!Array.isArray(secrets.required)) throw new Error("deploy: cannot verify binding-name uniqueness — \"secrets.required\" must be an array of secret names. Fix the wrangler config and retry.");
1318
1178
  secrets.required.forEach((name, index) => {
1319
- if (typeof name !== "string" || name.length === 0) throw new Error(`deploy: cannot verify binding-name uniqueness — "secrets.required" contains a malformed entry at index ${index} (expected a non-empty string). Refusing to proceed on a partially-readable binding set (a dropped entry could hide a real collision). Fix the wrangler config and retry.`);
1179
+ if (typeof name !== "string" || name.length === 0) throw bindingSetError(`"secrets.required" contains a malformed entry at index ${index} (expected a non-empty string)`, "dropped entry");
1320
1180
  claim(name, "Secret");
1321
1181
  });
1322
1182
  }
1323
1183
  return owners;
1324
1184
  }
1325
- /** A shallow copy of `config` with one field omitted (never mutates the input). */
1185
+ /** A shallow copy of `config` without `field`. */
1326
1186
  function configWithoutField(config, field) {
1327
1187
  const { [field]: _omit, ...rest } = config;
1328
1188
  return rest;
1329
1189
  }
1330
- /**
1331
- * Add every `queues.producers[].binding` to an existing worker-binding owner map,
1332
- * under the friendly label "Queue" (first-writer-wins). The base
1333
- * `collectWorkerBindingNames` deliberately OMITS queues so the producer-append
1334
- * path does not flag the producer it is adding as a self-collision — but for the
1335
- * ADOPT path a producer binding sharing the adopted binding IS a real cross-type
1336
- * collision wrangler rejects at deploy, so the adopt guard layers producers on
1337
- * top of the reused collector.
1338
- */
1190
+ /** Add queue producer bindings (label "Queue"), which the base collector leaves out. */
1339
1191
  function addQueueProducerOwners(owners, config) {
1340
1192
  const queues = assertObjectContainer(config.queues, "queues");
1341
1193
  if (!queues || queues.producers === void 0) return;
@@ -1345,47 +1197,26 @@ function addQueueProducerOwners(owners, config) {
1345
1197
  }
1346
1198
  }
1347
1199
  /**
1348
- * The ONE strict `queues.producers` validator, shared by BOTH the adopt-guard's
1349
- * owner collection ({@link addQueueProducerOwners}) and the producer-upsert path (which
1350
- * otherwise clones the list and silently skips non-record members, committing a new
1351
- * producer beside a corrupt list). A non-array, or any member that is not a record with
1352
- * a non-empty string `binding`, THROWS (fail closed) rather than being dropped — a
1353
- * dropped/hidden producer could mask a real binding collision. Returns the validated
1354
- * producer records (each guaranteed to carry a non-empty string `binding`).
1200
+ * Validate `queues.producers`: every member needs a non-empty string `binding`. A skipped
1201
+ * member could hide a binding collision, so a malformed one throws.
1355
1202
  */
1356
1203
  function assertValidQueueProducers(producers) {
1357
1204
  if (producers === void 0) return [];
1358
1205
  if (!Array.isArray(producers)) throw new Error("deploy: cannot verify binding-name uniqueness — \"queues.producers\" must be an array. Fix the wrangler config and retry.");
1359
1206
  return producers.map((producer, index) => {
1360
- if (!isRecord(producer) || typeof producer.binding !== "string" || producer.binding.length === 0) throw new Error(`deploy: cannot verify binding-name uniqueness — "queues.producers" contains a malformed entry at index ${index} (missing a non-empty string "binding"). Refusing to proceed on a partially-readable binding set (a dropped producer could hide a real collision). Fix the wrangler config and retry.`);
1207
+ if (!isRecord(producer) || typeof producer.binding !== "string" || producer.binding.length === 0) throw bindingSetError(`"queues.producers" contains a malformed entry at index ${index} (missing a non-empty string "binding")`, "dropped producer");
1361
1208
  return producer;
1362
1209
  });
1363
1210
  }
1364
- /**
1365
- * Validate the OUTER shape of a wrangler container field that wrangler 4.131
1366
- * requires to be an OBJECT (`queues`, `secrets`). A PRESENT-but-non-object container
1367
- * (array/string/number/null) is malformed for wrangler AND would bypass the binding
1368
- * collectors, HIDING a real cross-type binding collision — so it THROWS (fail closed).
1369
- * An ABSENT container (undefined) returns undefined (a no-op, NOT an error).
1370
- * Returns the container as a record when present-and-object.
1371
- *
1372
- * NOTE: `null` is `typeof 'object'` but `isRecord(null)` is false, so `secrets: null` /
1373
- * `queues: null` (present but null) THROWS — correct (wrangler requires an object).
1374
- * Absent (`undefined`) is the only no-op.
1375
- */
1211
+ /** An object-valued container field (`queues`, `secrets`); any other present value throws. */
1376
1212
  function assertObjectContainer(value, field) {
1377
1213
  if (value === void 0) return;
1378
- if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object. Refusing to proceed on a partially-readable binding set (a wrong-shaped container could hide a real collision). Fix the wrangler config and retry.`);
1214
+ if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object`, "wrong-shaped container");
1379
1215
  return value;
1380
1216
  }
1381
1217
  /**
1382
- * The worker-wide OWNER of a binding name as the writer's adopt / `vars` guards see it:
1383
- * validates `field`'s own outer shape (throws on a malformed target, fail closed), then
1384
- * looks `name` up among every OTHER binding type — `queues.producers` included — and
1385
- * returns wrangler's friendly label for the owner, or `undefined` when the name is free
1386
- * (or held only by `field` itself). Lets a caller refuse a doomed write BEFORE side
1387
- * effects the write would otherwise follow (the Mode B email step). Reuses the ONE
1388
- * collector — never fork it.
1218
+ * The label of another binding type that already uses `name`, or undefined when only
1219
+ * `field` (or nothing) does. Lets a caller refuse a write before its side effects.
1389
1220
  */
1390
1221
  function findBindingNameOwner(config, field, name) {
1391
1222
  bindingNamesForField(field, config[field]);
@@ -1394,20 +1225,9 @@ function findBindingNameOwner(config, field, name) {
1394
1225
  return owners.get(name);
1395
1226
  }
1396
1227
  /**
1397
- * The STRICT canonical reader for a single provisioned binding entry in a wrangler
1398
- * config field (`d1_databases` / `kv_namespaces` / `r2_buckets` / `hyperdrive`). Replaces
1399
- * the provisioner's loose first-match `.find()` — which validated no outer shape,
1400
- * silently picked among duplicates, and bypassed the worker-wide collision check, so a
1401
- * duplicate/cross-type-collision config could be reported `reused` or pass a create
1402
- * postcondition though it is undeployable. Fails closed on:
1403
- * 1. a malformed TARGET field (reuses {@link bindingNamesForField}: a non-array outer
1404
- * shape, or any member without a non-empty string `binding`, throws);
1405
- * 2. MORE THAN ONE entry in the target field sharing `binding` (ambiguous identity —
1406
- * wrangler also rejects duplicate binding names);
1407
- * 3. a worker-wide CROSS-TYPE collision — `binding` is ALSO owned by any OTHER binding
1408
- * type (reuses the {@link collectWorkerBindingNames} collector, EXCLUDING the
1409
- * target field so the entry never self-collides, and INCLUDING `queues.producers`).
1410
- * Returns the single matching entry, or `undefined` when the binding is absent.
1228
+ * The one entry in `field` (`d1_databases`, `kv_namespaces`, …) with this binding, or
1229
+ * undefined. Throws on a malformed field, a duplicate entry, or a name another binding
1230
+ * type also uses.
1411
1231
  */
1412
1232
  function readProvisionedBindingEntry(config, field, binding, configPath) {
1413
1233
  bindingNamesForField(field, config[field]);
@@ -1420,12 +1240,7 @@ function readProvisionedBindingEntry(config, field, binding, configPath) {
1420
1240
  if (owner !== void 0) throw new Error(`provision: cannot read "${configPath}" — binding ${JSON.stringify(binding)} in "${field}" is also used by a ${owner} binding. Wrangler requires every binding name to be unique across the whole worker, so this config is undeployable. Rename the conflicting binding and retry.`);
1421
1241
  return matches[0];
1422
1242
  }
1423
- /**
1424
- * Explicit per-field shape metadata (see {@link BindingFieldShape}), transcribed
1425
- * from wrangler 4.131's config schema. Any `FRIENDLY_BINDING_NAMES` field absent here is
1426
- * a `namespace-array` (`[{ binding }]`) — the shape wrangler's `getBindingNames` reads
1427
- * via its `isNamespaceList` branch.
1428
- */
1243
+ /** Fields that are not a `namespace-array`. */
1429
1244
  const BINDING_FIELD_SHAPES = {
1430
1245
  vars: { kind: "key-map" },
1431
1246
  wasm_modules: { kind: "key-map" },
@@ -1480,32 +1295,16 @@ const BINDING_FIELD_SHAPES = {
1480
1295
  }
1481
1296
  };
1482
1297
  /**
1483
- * The ONE field-aware strict binding-name reader for a single config field. Routes
1484
- * each field to its KNOWN shape (see {@link BINDING_FIELD_SHAPES}) and FAILS CLOSED on
1485
- * any malformed/missing REQUIRED identity or wrong outer shape — never content-guessing.
1486
- * wrangler is lenient and would silently drop such a member, letting the worker-wide
1487
- * uniqueness guard miss (or invent) a collision.
1488
- *
1489
- * Exported so the deploy orchestrator's pass-through assert-set check reads a resource field's
1490
- * per-entry identity keys through the SAME wrangler-schema shapes (handling `send_email` /
1491
- * `ratelimits` name-keying and `logfwdr`'s nested `.bindings`, among others).
1298
+ * Binding names in one config field, read by the field's known shape. Throws on a wrong
1299
+ * shape or a missing required name, which Wrangler would drop silently.
1492
1300
  */
1493
1301
  function bindingNamesForField(field, value) {
1494
1302
  if (BINDING_FIELD_SHAPES[field]?.kind === "key-map") return keyMapBindingNames(field, value);
1495
1303
  return bindingEntriesForField(field, value).map((entry) => entry.name);
1496
1304
  }
1497
1305
  /**
1498
- * The entry-shaped sibling of {@link bindingNamesForField}: routes each field to its KNOWN
1499
- * shape and returns every binding's NAME **paired with its full config ENTRY object**, so a
1500
- * caller can compare not just WHICH bindings a field declares but the TARGET each one points
1501
- * at (a `services` binding's `service`, an `unsafe` binding's `type`, …). Same fail-closed
1502
- * philosophy as {@link bindingNamesForField} — a malformed/missing REQUIRED identity or wrong
1503
- * outer shape THROWS. {@link bindingNamesForField} is this reader's `.name` projection for every
1504
- * non-key-map field.
1505
- *
1506
- * Exported so the deploy orchestrator's pass-through assert-set check can pin a legitimately
1507
- * hand-declared binding's ENTRY pre-build and reject a build that KEEPS the name but REWRITES
1508
- * the target.
1306
+ * Like {@link bindingNamesForField}, but pairs each name with its config entry so a caller
1307
+ * can also compare what the binding points at.
1509
1308
  */
1510
1309
  function bindingEntriesForField(field, value) {
1511
1310
  const shape = BINDING_FIELD_SHAPES[field] ?? { kind: "namespace-array" };
@@ -1518,136 +1317,78 @@ function bindingEntriesForField(field, value) {
1518
1317
  case "whole-object": return [];
1519
1318
  }
1520
1319
  }
1521
- /**
1522
- * Entry-shaped reader for a KEY-MAP field. Key-map fields (vars/wasm_modules/text_blobs/
1523
- * data_blobs) carry no per-binding config ENTRY object — the binding name is the KEY and the
1524
- * VALUE is arbitrary content — and all four are excluded from the pass-through assert-set, so
1525
- * this branch is never reached in the normal flow. It THROWS the same wrong-shape message the
1526
- * name reader raises, so a FUTURE misclassification that routed a key-map field here fails
1527
- * CLOSED rather than silently reading no entries.
1528
- */
1320
+ /** Key-map fields have no entry objects; callers never route them here. */
1529
1321
  function keyMapBindingEntries(field) {
1530
- throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object mapping names to values. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1322
+ throw bindingSetError(`"${field}" must be an object mapping names to values`, "wrong-shaped field");
1531
1323
  }
1532
- /**
1533
- * Entry-shaped reader for a NAMESPACE-array field (`[{ binding }]`: kv_namespaces, d1_databases,
1534
- * r2_buckets, hyperdrive, services, vectorize, …). A PRESENT value that is not an array THROWS
1535
- * rather than being re-read as a key-map (which could under-collect and hide a real collision);
1536
- * every member is strictly validated for a non-empty string `.binding`.
1537
- */
1538
1324
  function namespaceArrayBindingEntries(field, value) {
1539
1325
  if (value === void 0) return [];
1540
- if (!Array.isArray(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an array of binding entries. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1326
+ if (!Array.isArray(value)) throw bindingSetError(`"${field}" must be an array of binding entries`, "wrong-shaped field");
1541
1327
  return strictBindingEntries(value, "binding", field);
1542
1328
  }
1543
1329
  /**
1544
- * Entry-shaped reader for a NAME-keyed array field (`send_email` / `ratelimits`: an array of
1545
- * `{ name }`). A PRESENT non-array THROWS; every member is strictly validated.
1546
- *
1547
- * Identity is the `.name` ONLY. Verified against wrangler 4.131's bundle +
1548
- * `config-schema.json`: NEITHER `send_email` NOR `ratelimits` has a `.binding` property in
1549
- * the schema, and on UPLOAD wrangler keys them by `.name`. An optional `.binding` that happens
1550
- * to sit on such an entry is NOT a binding identity wrangler recognizes, so unioning it would
1551
- * invent a PHANTOM collision (e.g. `send_email:[{name:"EMAIL_A",binding:"QUEUE_JOBS"}]` would
1552
- * falsely block a legitimate `QUEUE_JOBS` queue producer).
1330
+ * `send_email` and `ratelimits` are keyed by `.name` only. A `.binding` on such an entry is
1331
+ * not an identity Wrangler uses, so reading it would invent a collision.
1553
1332
  */
1554
1333
  function nameKeyedBindingEntries(field, value) {
1555
1334
  if (value === void 0) return [];
1556
- if (!Array.isArray(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an array of binding entries. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1335
+ if (!Array.isArray(value)) throw bindingSetError(`"${field}" must be an array of binding entries`, "wrong-shaped field");
1557
1336
  return strictBindingEntries(value, "name", field);
1558
1337
  }
1559
- /**
1560
- * Entry-shaped reader for a binding-LIST field (`{ bindings: [{ name }] }`: durable_objects /
1561
- * logfwdr / unsafe): the entry of each member is the member itself, keyed on `.name`. A wrong
1562
- * outer shape, or a missing `bindings` when required (durable_objects / logfwdr per schema),
1563
- * THROWS; a `bindings`-less `unsafe` (optional) contributes nothing.
1564
- */
1565
1338
  function bindingListEntries(field, value, bindingsRequired) {
1566
1339
  if (value === void 0) return [];
1567
- if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object with a "bindings" array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1340
+ if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object with a "bindings" array`, "wrong-shaped field");
1568
1341
  if (value.bindings === void 0) {
1569
- if (bindingsRequired) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" requires a "bindings" array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1342
+ if (bindingsRequired) throw bindingSetError(`"${field}" requires a "bindings" array`, "wrong-shaped field");
1570
1343
  return [];
1571
1344
  }
1572
- if (!Array.isArray(value.bindings)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}.bindings" must be an array. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1345
+ if (!Array.isArray(value.bindings)) throw bindingSetError(`"${field}.bindings" must be an array`, "wrong-shaped field");
1573
1346
  return strictBindingEntries(value.bindings, "name", `${field}.bindings`);
1574
1347
  }
1575
- /**
1576
- * Entry-shaped reader for a SINGLETON field (`{ binding }`: ai / browser / images / stream /
1577
- * media / websearch / version_metadata / assets): the entry is the singleton value itself. A
1578
- * PRESENT non-object THROWS; a present-but-malformed `binding` THROWS; a required-but-absent
1579
- * `binding` THROWS (never a fall-through that would mis-collect the object's OTHER keys); a
1580
- * binding-optional `assets` with no binding contributes nothing.
1581
- */
1582
1348
  function singletonBindingEntry(field, value, bindingRequired) {
1583
1349
  if (value === void 0) return [];
1584
- if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object with a "binding". Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1350
+ if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object with a "binding"`, "wrong-shaped field");
1585
1351
  if (typeof value.binding === "string" && value.binding.length > 0) return [{
1586
1352
  name: value.binding,
1587
1353
  entry: value
1588
1354
  }];
1589
- if (value.binding !== void 0) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" has a malformed "binding" (expected a non-empty string). Refusing to proceed on a partially-readable binding set (a dropped binding could hide a real collision). Fix the wrangler config and retry.`);
1590
- if (bindingRequired) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" requires a "binding" (a non-empty string). Refusing to proceed on a partially-readable binding set (a dropped binding could hide a real collision). Fix the wrangler config and retry.`);
1355
+ if (value.binding !== void 0) throw bindingSetError(`"${field}" has a malformed "binding" (expected a non-empty string)`, "dropped binding");
1356
+ if (bindingRequired) throw bindingSetError(`"${field}" requires a "binding" (a non-empty string)`, "dropped binding");
1591
1357
  return [];
1592
1358
  }
1593
- /**
1594
- * Read binding names from a KEY-MAP field (`vars`/`wasm_modules`/`text_blobs`/
1595
- * `data_blobs`): the object's KEYS are the binding names. Reads ONLY the keys — never
1596
- * the values — so a value that happens to look like a binding list (`{bindings:[…]}`)
1597
- * or a singleton (`{binding:'x'}`) is NOT misread. A PRESENT value that is not a
1598
- * plain object is the wrong outer shape and THROWS (fail closed). An explicitly
1599
- * `undefined`-valued key is not a real binding and is skipped.
1600
- */
1359
+ /** The keys of a key-map field are its binding names; the values are never read. */
1601
1360
  function keyMapBindingNames(field, value) {
1602
1361
  if (value === void 0) return [];
1603
- if (!isRecord(value)) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" must be an object mapping names to values. Refusing to proceed on a partially-readable binding set (a wrong-shaped field could hide a real collision). Fix the wrangler config and retry.`);
1362
+ if (!isRecord(value)) throw bindingSetError(`"${field}" must be an object mapping names to values`, "wrong-shaped field");
1604
1363
  return Object.keys(value).filter((key) => value[key] !== void 0);
1605
1364
  }
1606
1365
  /**
1607
- * Strictly read `keyField` (a non-empty string) from EVERY member of a binding-bearing array and
1608
- * return it PAIRED with the member's full entry object. THROWS (fail closed) on ANY malformed
1609
- * member — never silently drops one. Dropping a malformed member could convert a mixed-validity
1610
- * array (e.g. `[null, { binding: 'DB', id: '…' }]`) into an empty/partial binding set, so the
1611
- * worker-wide uniqueness guard would MISS the existing `DB` and commit a conflicting binding.
1366
+ * Read `keyField` from every member, paired with the member. A malformed member throws:
1367
+ * dropping it could hide an existing binding from the uniqueness check.
1612
1368
  */
1613
1369
  function strictBindingEntries(members, keyField, field) {
1614
1370
  return members.map((member, index) => {
1615
- if (!isRecord(member) || typeof member[keyField] !== "string" || member[keyField].length === 0) throw new Error(`deploy: cannot verify binding-name uniqueness — "${field}" contains a malformed entry at index ${index} (missing a non-empty string "${keyField}"). Refusing to proceed on a partially-readable binding set (a dropped entry could hide a real collision). Fix the wrangler config and retry.`);
1371
+ if (!isRecord(member) || typeof member[keyField] !== "string" || member[keyField].length === 0) throw bindingSetError(`"${field}" contains a malformed entry at index ${index} (missing a non-empty string "${keyField}")`, "dropped entry");
1616
1372
  return {
1617
1373
  name: member[keyField],
1618
1374
  entry: member
1619
1375
  };
1620
1376
  });
1621
1377
  }
1622
- /**
1623
- * True when a D1 `migrations_pattern` is valid under `dir` per wrangler's rule:
1624
- * the normalized pattern must start with `${normalized dir}/` (or the dir
1625
- * normalizes to "."). Mirrors wrangler's `resolveMigrationsConfig` /
1626
- * `stripDirPrefix`.
1627
- */
1378
+ /** A binding field that cannot be read completely; a missed name could hide a collision. */
1379
+ function bindingSetError(problem, hidden) {
1380
+ return /* @__PURE__ */ new Error(`deploy: cannot verify binding-name uniqueness — ${problem}. Refusing to proceed on a partially-readable binding set (a ${hidden} could hide a real collision). Fix the wrangler config and retry.`);
1381
+ }
1382
+ /** Wrangler's rule: the normalized pattern starts with `<dir>/`, unless the dir is ".". */
1628
1383
  function migrationsPatternMatchesDir(pattern, dir) {
1629
1384
  const normalizedDir = normalizeMigrationsPath(dir);
1630
1385
  if (normalizedDir === ".") return true;
1631
1386
  return normalizeMigrationsPath(pattern).startsWith(`${normalizedDir}/`);
1632
1387
  }
1633
- /**
1634
- * Mirror wrangler's `normalizeRelativePath`: forward-slash, posix-normalize, then
1635
- * drop a trailing slash. Keeps the migrations validity check byte-identical with
1636
- * wrangler's own.
1637
- */
1388
+ /** Wrangler's `normalizeRelativePath`: forward slashes, normalized, no trailing slash. */
1638
1389
  function normalizeMigrationsPath(p) {
1639
1390
  const normalized = normalize(p.replace(/\\/g, "/"));
1640
1391
  return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
1641
1392
  }
1642
- /** Order-insensitive structural equality — avoids rewriting an entry that only
1643
- * differs in key order (preserves the file's bytes/comments on that entry). */
1644
- function jsonEqual(a, b) {
1645
- return JSON.stringify(canonicalize(a)) === JSON.stringify(canonicalize(b));
1646
- }
1647
- function canonicalize(value) {
1648
- if (Array.isArray(value)) return value.map(canonicalize);
1649
- if (isRecord(value)) return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalize(value[key])]));
1650
- return value;
1651
- }
1652
1393
  //#endregion
1653
1394
  export { updateWranglerCustomDomain as A, readWranglerManagedQueueCleanupCandidates as C, syncWranglerBindings as D, resolveLiveBindingConfig as E, writeWranglerPublishedTrafficSnapshot as M, syncWranglerDurableObjects as O, 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, writeProvisionedWranglerConfig as j, syncWranglerWebSockets 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 };