void 1.1.0 → 1.1.12

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 (246) hide show
  1. package/dist/{account-cmd-BTcUzv9L.mjs → account-cmd-Cj6sCMTk.mjs} +4 -4
  2. package/dist/{application-analysis-AB_YYWgH.mjs → application-analysis-D7nNmNJb.mjs} +6 -6
  3. package/dist/{application-routing-L7V-TFhZ.mjs → application-routing-CZH66gXn.mjs} +1 -1
  4. package/dist/{auth-link-DUJuvRx5.mjs → auth-link-Dj7lAC_K.mjs} +4 -4
  5. package/dist/{auth-migrations-Cgs0k6lS.mjs → auth-migrations-BO27GDNr.mjs} +38 -2
  6. package/dist/{auth-router-CIxiMG7i.mjs → auth-router-CNsMOFCa.mjs} +5 -4
  7. package/dist/{better-auth-shared-B74NJIus.d.mts → better-auth-shared-Bv18bB-l.d.mts} +2 -0
  8. package/dist/{better-auth-shared-CMXlZG7W.mjs → better-auth-shared-D-6z0q0f.mjs} +28 -1
  9. package/dist/{build-cmd-BkIv25PA.mjs → build-cmd-ByhegwRC.mjs} +2 -2
  10. package/dist/{cache-Ctzfig-W.mjs → cache-CEFb5ban.mjs} +2 -2
  11. package/dist/{cancel-deploy-CD9o-SsC.mjs → cancel-deploy-CaARY26n.mjs} +2 -2
  12. package/dist/{cf-build-output-Bc8i3dzE.mjs → cf-build-output-ChEKWan2.mjs} +71 -7
  13. package/dist/cf-build-output-Dcmxa-Zm.mjs +1 -0
  14. package/dist/{cf-user-agent-ChjQp2MU.mjs → cf-command-values-b8OqDoo9.mjs} +5 -16
  15. package/dist/cf-user-agent-BkEHPDLA.mjs +16 -0
  16. package/dist/cli/cli.mjs +180 -57
  17. package/dist/cli/cloudflare-operation-process.mjs +46 -9
  18. package/dist/cli/env-schema-probe.mjs +3 -3
  19. package/dist/{client-DM9Kcf4e.mjs → client-BdzxubTS.mjs} +58 -13
  20. package/dist/client-DAnfyMe9.mjs +1 -0
  21. package/dist/{cloudflare-auth-CqFBDo52.mjs → cloudflare-auth-DSvBc1Gu.mjs} +1 -1
  22. package/dist/{cloudflare-cmd-BIAF_BIY.mjs → cloudflare-cmd-D_2-Q-_i.mjs} +4 -4
  23. package/dist/{cloudflare-config-DV60XFFK.mjs → cloudflare-config-rdFOys4X.mjs} +2 -2
  24. package/dist/{cloudflare-connect-WjwnVOJA.mjs → cloudflare-connect-BN-k2kD-.mjs} +2 -2
  25. package/dist/{cloudflare-operations-CrSUFRzJ.mjs → cloudflare-operations-BFLCpUCV.mjs} +1 -1
  26. package/dist/{cloudflare-operations-B42EZeJy.mjs → cloudflare-operations-D5PLrOqD.mjs} +18 -8
  27. package/dist/{cloudflare-process-CeDWJRhj.mjs → cloudflare-process-CZJ4viYl.mjs} +2 -2
  28. package/dist/collect-BWhkgtAn.mjs +1 -0
  29. package/dist/{collect-xjffdCdk.mjs → collect-Dew86qce.mjs} +4 -3
  30. package/dist/{config-D0GY5ItR.mjs → config-CyUJzi3q.mjs} +1 -1
  31. package/dist/{config-Bx_1SpnO.mjs → config-D26zcdKy.mjs} +2 -2
  32. package/dist/{config-BEm9vRvS.mjs → config-DC5llZaI.mjs} +2 -2
  33. package/dist/{config-QrJWu0IX.mjs → config-DYJV8aEH.mjs} +1 -1
  34. package/dist/{connect-CKtk-EZe.mjs → connect-C4_m2moF.mjs} +5 -5
  35. package/dist/{create-project-B-ewF_Af.mjs → create-project-CvuYDD-l.mjs} +1 -1
  36. package/dist/{create-project-yInGo72M.mjs → create-project-D8jQTwVQ.mjs} +2 -2
  37. package/dist/database-provider.d.mts +6 -0
  38. package/dist/{db-7I_gfdVq.mjs → db-BsiOAa0A.mjs} +306 -111
  39. package/dist/{db-types-Bb4WBWIs.mjs → db-types-NGxPwnlt.mjs} +1 -1
  40. package/dist/{delete-Cy-M1u-r.mjs → delete-CAma7nFi.mjs} +2 -2
  41. package/dist/{deploy-BYYlnsiy.mjs → deploy-D1gIPiAq.mjs} +148 -64
  42. package/dist/deploy-Dc0XsCQj.mjs +2 -0
  43. package/dist/{deploy-managed-static-Ca4TFdmx.mjs → deploy-managed-static-B9KVxY3X.mjs} +80 -34
  44. package/dist/{deploy-transport-DWlWBe6M.mjs → deploy-transport-B3mtEi_q.mjs} +2 -2
  45. package/dist/deploy.d.mts +22 -1
  46. package/dist/deploy.mjs +49 -8
  47. package/dist/discover-D4TPKo57.mjs +1 -0
  48. package/dist/{discover-D2PGT63u.mjs → discover-LaV0tbIu.mjs} +1 -1
  49. package/dist/{dispatch-DrTTk8Xg.mjs → dispatch-BAbbn3jg.mjs} +6 -6
  50. package/dist/{domain-CZGxPv9u.mjs → domain-BAdwm-QS.mjs} +3 -3
  51. package/dist/{drizzle-CF84FOVM.mjs → drizzle-BQfyvQKX.mjs} +13 -2
  52. package/dist/{email-DzyNVuoU.mjs → email-MwjA7kaL.mjs} +11 -12
  53. package/dist/{email-cloudflare-DfG6UEMm.mjs → email-cloudflare-etpKiITL.mjs} +7 -10
  54. package/dist/{entry-ehmBvs5w.mjs → entry-B_0IhV64.mjs} +1 -1
  55. package/dist/{env-Nx3yf50r.mjs → env-B163-G1s.mjs} +5 -5
  56. package/dist/{env-types-DS2_y4X8.mjs → env-types-GRchm5dw.mjs} +1 -1
  57. package/dist/{env-validation-BT7z-qpQ.mjs → env-validation-CuGfWRJd.mjs} +1 -1
  58. package/dist/{env-validation-DYxjz_Wo.mjs → env-validation-D_KyMdab.mjs} +2 -2
  59. package/dist/{fetch-BPCYVi3H.d.mts → fetch-CUX0tB78.d.mts} +16 -3
  60. package/dist/fetch-CtESUYWd.mjs +26 -0
  61. package/dist/{fetch-error-Dj3crt0e.mjs → fetch-error-Bw0n-IY-.mjs} +1 -1
  62. package/dist/{fetch-stream-PGgz4uGz.mjs → fetch-stream-BspOeTAI.mjs} +1 -1
  63. package/dist/{fetch-stream-obvZ7fvO.d.mts → fetch-stream-DfkAzZf-.d.mts} +1 -1
  64. package/dist/{gen-CufHEf42.mjs → gen-CYN3wiov.mjs} +26 -20
  65. package/dist/gen-Cf-RBVg4.mjs +1 -0
  66. package/dist/{generate-Dat0UTry.mjs → generate-B1m4Cm4n.mjs} +1 -1
  67. package/dist/{generate-ClI89brV.mjs → generate-DkEb9rL-.mjs} +1 -1
  68. package/dist/{github-cmd-FU8EjFyU.mjs → github-cmd-C8QsnJQs.mjs} +2 -2
  69. package/dist/{handler-_PqY82xe.d.mts → handler-D5K_yP6T.d.mts} +1 -1
  70. package/dist/{headers-Di1FsD3e.mjs → headers-Bi4bOAwp.mjs} +1 -1
  71. package/dist/{help-BT2hovNI.mjs → help-B2sFwn9b.mjs} +60 -15
  72. package/dist/help-w-xlx_kq.mjs +1 -0
  73. package/dist/{inbound-brj2-TM5.d.mts → inbound-Da7XsjH3.d.mts} +6 -12
  74. package/dist/index.d.mts +1 -1
  75. package/dist/index.mjs +139 -126
  76. package/dist/{info-l249eUdH.mjs → info-Bxunp14X.mjs} +4 -4
  77. package/dist/{init-D0A6M64Q.mjs → init-DGFQMnbk.mjs} +51 -28
  78. package/dist/{link-WMoJFf4i.mjs → link-CwrfpjIM.mjs} +3 -3
  79. package/dist/{list-CQ2EQEHL.mjs → list-hKoW5z-b.mjs} +3 -3
  80. package/dist/{live-DJONVlQK.d.mts → live-JheIDZKc.d.mts} +1 -1
  81. package/dist/{local-d1-BxvQYEFi.mjs → local-d1-CpaPbd_L.mjs} +5 -5
  82. package/dist/login-08mBwZfI.mjs +1 -0
  83. package/dist/{login-C2T1oVG-.mjs → login-f2eu2TQh.mjs} +3 -3
  84. package/dist/{logs-DnC1d7xB.mjs → logs-CEWqD-_B.mjs} +3 -3
  85. package/dist/{migrate-BDIprOYd.mjs → migrate-DYfdWBXt.mjs} +5 -5
  86. package/dist/migrate-Di-4EuoE.mjs +1 -0
  87. package/dist/{neon-n74ta1Pr.mjs → neon-DTZr7Bu7.mjs} +0 -1
  88. package/dist/nitro.mjs +3 -3
  89. package/dist/{node-cPadMgUO.mjs → node-uN8_zxJr.mjs} +15 -9
  90. package/dist/operator-cmd-Bv20yLu2.mjs +1 -0
  91. package/dist/{operator-cmd-DHieWtFp.mjs → operator-cmd-DCr_QGMH.mjs} +4 -4
  92. package/dist/{output-Ba6ZbrzY.mjs → output-CKguMgr7.mjs} +13 -1
  93. package/dist/pages/client.d.mts +2 -2
  94. package/dist/pages/client.mjs +18 -5
  95. package/dist/pages/index.d.mts +2 -2
  96. package/dist/pages/index.mjs +5 -5
  97. package/dist/pages/islands-plugin.d.mts +44 -6
  98. package/dist/pages/islands-plugin.mjs +99 -28
  99. package/dist/pages/protocol.d.mts +2 -2
  100. package/dist/pages/protocol.mjs +1 -1
  101. package/dist/pages/serialize.d.mts +2 -2
  102. package/dist/pages/serialize.mjs +1 -1
  103. package/dist/{platform-args-CaCL_1Ch.mjs → platform-args-B7ke06up.mjs} +1 -4
  104. package/dist/platform-args-B_LrqEZB.mjs +1 -0
  105. package/dist/{platform-auth-config-Z16-I8nT.mjs → platform-auth-config-qGvEuns3.mjs} +5 -5
  106. package/dist/{platform-auth-protection-BXwZiJSF.mjs → platform-auth-protection-CyLcD6ot.mjs} +3 -3
  107. package/dist/{platform-auth-recovery-CXjfqyOv.mjs → platform-auth-recovery-B2LKI8V2.mjs} +3 -3
  108. package/dist/{platform-cmd-PT4YwMLM.mjs → platform-cmd-B2ec5eFg.mjs} +1 -1
  109. package/dist/{platform-cmd-DaAOiWTl.mjs → platform-cmd-CX7phm7V.mjs} +6 -6
  110. package/dist/{platform-domain-CxpvUeo0.mjs → platform-domain-DDNK2y-4.mjs} +3 -3
  111. package/dist/{platform-lifecycle-DBiS0cJd.mjs → platform-lifecycle-3CR98Tg2.mjs} +399 -40
  112. package/dist/{platform-lifecycle-u9pMOvxC.mjs → platform-lifecycle-CWc5gr6c.mjs} +1 -1
  113. package/dist/{platform-management-DvBS83rC.mjs → platform-management-DAE6g2QU.mjs} +1 -1
  114. package/dist/{platform-management-DhEFdQAf.mjs → platform-management-o3LCCeE4.mjs} +40 -4
  115. package/dist/{platform-plans-config-BWn1S2Rv.mjs → platform-plans-config-CBMZxCep.mjs} +1 -1
  116. package/dist/{platform-recovery-BUGOB4RC.mjs → platform-recovery-Dmsg7lWA.mjs} +2 -2
  117. package/dist/{platform-setup-YvN9VQXV.mjs → platform-setup-hFbnWAVQ.mjs} +1 -1
  118. package/dist/{plugin-inference-DsARdQKE.mjs → plugin-inference-Bekzjuqw.mjs} +2 -2
  119. package/dist/{prepare-DEB5SeVJ.mjs → prepare-DepAGBcV.mjs} +9 -9
  120. package/dist/prepare-EVEbQ9n2.mjs +1 -0
  121. package/dist/{prepare-PQCgsny0.mjs → prepare-HKo7Rh5V.mjs} +2 -2
  122. package/dist/{project-cmd-DVatD8Ev.mjs → project-cmd-8ylYGx-O.mjs} +18 -18
  123. package/dist/{project-paths-DMvEeSau.mjs → project-paths-DGu_QZ_Q.mjs} +1 -1
  124. package/dist/{project-team-DJrWEAG1.mjs → project-team-Bvpl78we.mjs} +2 -2
  125. package/dist/{project-token-CBgLBuL6.mjs → project-token-QWHoJH2t.mjs} +2 -2
  126. package/dist/{project-tsconfig-bveqhlYA.mjs → project-tsconfig-Itv1f4WC.mjs} +1 -1
  127. package/dist/{project-zero-trust-92gLtZ25.mjs → project-zero-trust-8tJ-RFvu.mjs} +2 -2
  128. package/dist/{protocol-4H7V_3Os.d.mts → protocol-Ssc_LhHj.d.mts} +2 -2
  129. package/dist/{protocol-RNP0u7UY.mjs → protocol-bAUUkx70.mjs} +1 -1
  130. package/dist/{providers-BXuhmuub.mjs → providers-BUHwJlmM.mjs} +10 -1
  131. package/dist/provision-BgXFDv0d.mjs +1 -0
  132. package/dist/{provision-BnSSkiED.mjs → provision-DZKYCEJg.mjs} +66 -66
  133. package/dist/r2-conditions-B8xUgJRc.mjs +61 -0
  134. package/dist/{requests-7W1Pygt2.mjs → requests-Vk5Zyhcy.mjs} +2 -2
  135. package/dist/{rollback-BcASVnwP.mjs → rollback-CH4yMQys.mjs} +9 -8
  136. package/dist/{runner-CabsQ-iM.mjs → runner-3uGC-oLF.mjs} +9 -7
  137. package/dist/{runner-So9mYfcm.mjs → runner-WCdfeI0q.mjs} +1 -1
  138. package/dist/{runner-mysql-BhRaONkO.mjs → runner-mysql-BWmbk5IE.mjs} +1 -1
  139. package/dist/{runner-mysql-DWwE8jKi.mjs → runner-mysql-BcHnLUuM.mjs} +1 -1
  140. package/dist/{runner-pg-_Xncr3H5.mjs → runner-pg-Cgp-cr_p.mjs} +1 -1
  141. package/dist/{runner-pg-BRemq_GX.mjs → runner-pg-Cr3qrqi4.mjs} +1 -1
  142. package/dist/runtime/ai.d.mts +4 -0
  143. package/dist/runtime/ai.mjs +2 -37
  144. package/dist/runtime/better-auth-mysql.d.mts +1 -1
  145. package/dist/runtime/better-auth-mysql.mjs +2 -2
  146. package/dist/runtime/better-auth-pg.d.mts +1 -1
  147. package/dist/runtime/better-auth-pg.mjs +2 -2
  148. package/dist/runtime/better-auth.d.mts +1 -1
  149. package/dist/runtime/better-auth.mjs +2 -2
  150. package/dist/runtime/client-react.d.mts +2 -2
  151. package/dist/runtime/client-react.mjs +3 -3
  152. package/dist/runtime/client-solid.d.mts +2 -2
  153. package/dist/runtime/client-solid.mjs +3 -3
  154. package/dist/runtime/client-svelte.d.mts +2 -2
  155. package/dist/runtime/client-svelte.mjs +3 -3
  156. package/dist/runtime/client-vue.d.mts +2 -2
  157. package/dist/runtime/client-vue.mjs +3 -3
  158. package/dist/runtime/client.d.mts +2 -2
  159. package/dist/runtime/client.mjs +3 -3
  160. package/dist/runtime/email/testing.d.mts +1 -1
  161. package/dist/runtime/email.d.mts +2 -3
  162. package/dist/runtime/email.mjs +2 -3
  163. package/dist/runtime/fetch-server.d.mts +8 -0
  164. package/dist/runtime/fetch-server.mjs +30 -0
  165. package/dist/runtime/fetch-stream.d.mts +2 -2
  166. package/dist/runtime/fetch-stream.mjs +2 -2
  167. package/dist/runtime/fetch.d.mts +2 -2
  168. package/dist/runtime/fetch.mjs +3 -3
  169. package/dist/runtime/handler.d.mts +1 -1
  170. package/dist/runtime/live-client.d.mts +1 -1
  171. package/dist/runtime/live.d.mts +1 -1
  172. package/dist/runtime/migration-handler-mysql.mjs +4 -4
  173. package/dist/runtime/migration-handler-pg.mjs +9 -1
  174. package/dist/runtime/remote/binding-handler.mjs +25 -25
  175. package/dist/runtime/remote/index.d.mts +3 -0
  176. package/dist/runtime/remote/index.mjs +86 -23
  177. package/dist/runtime/routing.d.mts +2 -2
  178. package/dist/runtime/routing.mjs +1 -1
  179. package/dist/runtime/sse-client.d.mts +4 -0
  180. package/dist/runtime/validator.d.mts +1 -1
  181. package/dist/runtime/ws-server.d.mts +2 -2
  182. package/dist/runtime/ws.d.mts +1 -1
  183. package/dist/{scan-C0BMdmEd.mjs → scan-D2-FcLHs.mjs} +13 -5
  184. package/dist/{secret-bg73f1Ge.mjs → secret-wr6Sn4Xa.mjs} +4 -4
  185. package/dist/serialize-DtR8Vwa_.d.mts +18 -0
  186. package/dist/serialize-YHvlcG3Q.mjs +31 -0
  187. package/dist/{subcommand-prompt-Bm3ZlYgA.mjs → subcommand-prompt-CNZc4XUd.mjs} +1 -1
  188. package/dist/{types-BAp5AEBU.d.mts → types-7AIz0OZu.d.mts} +1 -1
  189. package/dist/{validate-CheZGRE7.mjs → validate-CnZPMq4q.mjs} +22 -17
  190. package/dist/validate-D7Wn8PUX.mjs +1 -0
  191. package/dist/{version-metadata-DIrqEHQo.mjs → version-metadata-B1Bm2wSq.mjs} +1 -1
  192. package/dist/{wrangler-BYs07Rxy.mjs → wrangler-C9XSzrju.mjs} +3 -3
  193. package/dist/wrangler-DAdxHEzh.mjs +1 -0
  194. package/dist/{wrapper-CwhpNWtH.mjs → wrapper-DGsYwNi6.mjs} +6 -4
  195. package/dist/{ws-aKVYB-fA.d.mts → ws-nnFnAyQb.d.mts} +6 -1
  196. package/docs/guide/auth.md +1 -1
  197. package/docs/guide/database/d1.md +2 -2
  198. package/docs/guide/database/mysql.md +1 -1
  199. package/docs/guide/deployment.md +2 -0
  200. package/docs/guide/edge/headers.md +10 -2
  201. package/docs/guide/edge/revalidation.md +2 -0
  202. package/docs/guide/email/receiving.md +1 -1
  203. package/docs/guide/email/sending.md +3 -3
  204. package/docs/guide/pages-routing/islands.md +2 -2
  205. package/docs/guide/pages-routing/markdown.md +3 -1
  206. package/docs/guide/platform/administration/connected-apps.md +18 -2
  207. package/docs/guide/platform/administration/email.md +7 -1
  208. package/docs/guide/platform/installation/ci.md +2 -0
  209. package/docs/guide/platform/installation/credentials.md +23 -5
  210. package/docs/guide/platform/installation/maintenance.md +32 -2
  211. package/docs/guide/platform/installation/setup.md +1 -1
  212. package/docs/guide/remote-dev.md +2 -0
  213. package/docs/guide/typed-fetch.md +1 -1
  214. package/docs/guide/websockets.md +2 -2
  215. package/docs/index.md +78 -22
  216. package/docs/integrations/cloudflare.md +1 -1
  217. package/docs/integrations/frameworks/tanstack-start.md +25 -0
  218. package/docs/reference/api/deploy.md +35 -3
  219. package/docs/reference/api/pages.md +7 -5
  220. package/docs/reference/api.md +2 -0
  221. package/docs/reference/cli/database.md +22 -5
  222. package/docs/reference/cli/deploy.md +12 -10
  223. package/docs/reference/cli/email.md +1 -1
  224. package/docs/reference/cli/generate.md +1 -1
  225. package/docs/reference/cli/platform-installation.md +4 -2
  226. package/docs/reference/cli/project.md +8 -4
  227. package/docs/reference/cli.md +2 -1
  228. package/docs/reference/config.md +12 -2
  229. package/package.json +8 -7
  230. package/dist/cf-build-output-BU3hqdHu.mjs +0 -1
  231. package/dist/client-B60PwCC4.mjs +0 -1
  232. package/dist/collect-Cae8A7Zr.mjs +0 -1
  233. package/dist/deploy-9lgfhrXS.mjs +0 -2
  234. package/dist/discover-ClzFSwns.mjs +0 -1
  235. package/dist/fetch-sAcwjzLO.mjs +0 -18
  236. package/dist/gen-sXyp5DFO.mjs +0 -1
  237. package/dist/help-i2YGGnTH.mjs +0 -1
  238. package/dist/login-XD844Xs-.mjs +0 -1
  239. package/dist/migrate-BRwU-blY.mjs +0 -1
  240. package/dist/operator-cmd-D6gnZsnK.mjs +0 -1
  241. package/dist/platform-args-B0HeTh0C.mjs +0 -1
  242. package/dist/prepare-CYT6tAzD.mjs +0 -1
  243. package/dist/r2-conditions-D1Wk8i7b.mjs +0 -30
  244. package/dist/serialize-BtQyaYoC.mjs +0 -20
  245. package/dist/serialize-CfSwWfF2.d.mts +0 -10
  246. package/dist/validate-BQFdf0Pi.mjs +0 -1
@@ -1,8 +1,8 @@
1
1
  import { a as join, c as resolve$2, n as dirname, o as normalize, t as basename } from "./dist-ipQi0Q8y.mjs";
2
2
  import { i as voidWarn, r as voidLog } from "./log-vqY3pqwI.mjs";
3
- import { _ as persistMaterializedWranglerConfig, j as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, y as readProvisionedBindingEntry } from "./wrangler-BYs07Rxy.mjs";
3
+ import { _ as persistMaterializedWranglerConfig, j as writeProvisionedWranglerConfig, s as assertNoDuplicateMembers, y as readProvisionedBindingEntry } from "./wrangler-C9XSzrju.mjs";
4
4
  import { n as scanWranglerDotenvKeys } from "./dotenv-CNazY3-w.mjs";
5
- import { l as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-CeDWJRhj.mjs";
5
+ import { l as resolveCloudflareOperationArgv, n as decodeCloudflareOperationResult, r as encodeCloudflareOperation } from "./cloudflare-process-CZJ4viYl.mjs";
6
6
  import { createRequire } from "node:module";
7
7
  import { closeSync, existsSync, fsyncSync, lstatSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, unlinkSync, writeSync } from "node:fs";
8
8
  import { isRecord } from "@void/deploy-core";
@@ -102,9 +102,8 @@ const TRANSPORT_REDIRECT_ENV_VARS = [
102
102
  "CLOUDFLARE_ENV"
103
103
  ];
104
104
  /**
105
- * Wrangler session-output sinks. When set, wrangler writes the raw argv to disk, which can
106
- * include a Hyperdrive password. They are scrubbed from the child env and rejected in project
107
- * dotenv, which wrangler reloads before writing.
105
+ * Session-output file variables. Provisioning keeps operation output off disk, so they are
106
+ * scrubbed from the child env and rejected in project dotenv. Secrets travel over stdin.
108
107
  */
109
108
  const OUTPUT_FILE_ENV_VARS = ["WRANGLER_OUTPUT_FILE_PATH", "WRANGLER_OUTPUT_FILE_DIRECTORY"];
110
109
  /**
@@ -140,7 +139,7 @@ function resolveComplianceRegion(env, configRegion) {
140
139
  if (envRegion !== void 0 && configRegion !== void 0 && envRegion !== configRegion) throw new Error(`provision: the Cloudflare compliance region is set to conflicting values — the CLOUDFLARE_COMPLIANCE_REGION environment variable is ${JSON.stringify(envRegion)} but the wrangler config "compliance_region" is ${JSON.stringify(configRegion)}. wrangler refuses to run with a mismatched compliance region; reconcile them (remove one, or set them equal) and retry.`);
141
140
  return envRegion ?? configRegion ?? "public";
142
141
  }
143
- /** Dotenv files wrangler loads for `--env=<env>`; provisioning always passes an empty env. */
142
+ /** Project dotenv files the fence scans for `env`; provisioning selects no named env (`''`). */
144
143
  function defaultWranglerEnvFiles(env) {
145
144
  return [
146
145
  ".env",
@@ -151,8 +150,8 @@ function defaultWranglerEnvFiles(env) {
151
150
  }
152
151
  /**
153
152
  * Fail when a project dotenv file sets a transport-redirect or session-output variable.
154
- * Wrangler reloads these files on every command, which would move its authenticated transport
155
- * away from the pinned base. Values exported in the shell are honored instead.
153
+ * Cloudflare tooling reads these files from the project, which would move its authenticated
154
+ * transport away from the pinned base. Values exported in the shell are honored instead.
156
155
  */
157
156
  function assertNoTransportRedirectInProjectDotenv(root, platform = process.platform) {
158
157
  const dotenvCaseInsensitive = platform === "win32";
@@ -169,9 +168,9 @@ function assertNoTransportRedirectInProjectDotenv(root, platform = process.platf
169
168
  const lowerKeys = caseInsensitive ? new Set([...keys].map((key) => key.toLowerCase())) : void 0;
170
169
  const declares = (name) => lowerKeys !== void 0 ? lowerKeys.has(name.toLowerCase()) : keys.has(name);
171
170
  const offenders = TRANSPORT_REDIRECT_ENV_VARS.filter(declares);
172
- if (offenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${offenders.join(", ")}, which wrangler reloads on every command and would redirect its authenticated Cloudflare API transport (and credentials) to a different endpoint/account than this provision is pinned to (the Hyperdrive existence check would then run against a DIFFERENT endpoint, risking cross-environment writes or duplicate resources). Remove ${offenders.join(", ")} from "${file}" and, if you truly need a non-default endpoint, export it in your shell/CI environment instead — that pin IS honored for both wrangler and the existence check.`);
171
+ if (offenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${offenders.join(", ")}, which Cloudflare tooling reads from project files and would redirect its authenticated Cloudflare API transport (and credentials) to a different endpoint/account than this provision is pinned to (the Hyperdrive existence check would then run against a DIFFERENT endpoint, risking cross-environment writes or duplicate resources). Remove ${offenders.join(", ")} from "${file}" and, if you truly need a non-default endpoint, export it in your shell/CI environment instead — that pin IS honored for both the Cloudflare operations and the existence check.`);
173
172
  const outputOffenders = OUTPUT_FILE_ENV_VARS.filter(declares);
174
- if (outputOffenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${outputOffenders.join(", ")}, which wrangler reloads on every command and which makes wrangler persist its session diagnostics — including the verbatim command line, where a Hyperdrive connection string's password would appear — to that output file. Remove ${outputOffenders.join(", ")} from "${file}" (set it in your shell only for non-provisioning wrangler commands if you need session output).`);
173
+ if (outputOffenders.length > 0) throw new Error(`provision: refusing to provision — the project file "${file}" sets ${outputOffenders.join(", ")}. Void does not allow Cloudflare session output files during provisioning. Remove ${outputOffenders.join(", ")} from "${file}".`);
175
174
  }
176
175
  }
177
176
  /**
@@ -245,7 +244,7 @@ var WranglerQuarantineError = class extends Error {
245
244
  pid;
246
245
  constructor(pid, detail) {
247
246
  const pidLabel = pid !== void 0 ? ` (pid ${pid})` : "";
248
- super(`provision: the spawned wrangler could not be confirmed terminated${pidLabel} — ${detail}. It may still be running and creating resources, so the cross-process provision lock is intentionally RETAINED (not released) and its owner is recorded in a quarantine sidecar ("<wrangler config>.void-provision.lock.quarantine.json") that blocks concurrent provisions. Recovery: verify the process${pidLabel} is dead (e.g. \`kill -0 <pid>\`; terminate it if not) — the NEXT provision then confirms the recorded group is gone and clears the quarantine automatically. To clear it manually instead, remove the sidecar and the "<wrangler config>.void-provision.lock.lock" directory, then re-run.`);
247
+ super(`provision: the spawned Cloudflare operation process could not be confirmed terminated${pidLabel} — ${detail}. It may still be running and creating resources, so the cross-process provision lock is intentionally RETAINED (not released) and its owner is recorded in a quarantine sidecar ("<Cloudflare config>.void-provision.lock.quarantine.json") that blocks concurrent provisions. Recovery: verify the process${pidLabel} is dead (e.g. \`kill -0 <pid>\`; terminate it if not) — the NEXT provision then confirms the recorded group is gone and clears the quarantine automatically. To clear it manually instead, remove the sidecar and the "<Cloudflare config>.void-provision.lock.lock" directory, then re-run.`);
249
248
  this.name = "WranglerQuarantineError";
250
249
  this.pid = pid;
251
250
  }
@@ -253,7 +252,7 @@ var WranglerQuarantineError = class extends Error {
253
252
  let activeProvisionSlot;
254
253
  function acquireProcessProvisionSlot() {
255
254
  if (activeProvisionSlot !== void 0) throw new Error("provision: a provision is already active in this process — run provisions sequentially. provisionCloudflareResources supports at most one concurrent provision per process; concurrent provisions across PROCESSES are serialized by the on-disk provision lock instead.");
256
- if (retentionWatchdog !== void 0) throw new Error(`provision: a previous provision in this process is still retaining its lock — an unconfirmed wrangler child${retentionWatchdog.info.pid !== void 0 ? ` (pid ${retentionWatchdog.info.pid})` : ""} could not be quarantined durably yet. No new provision may start until that retention resolves (the child is confirmed dead, or the quarantine metadata persists durably).`);
255
+ if (retentionWatchdog !== void 0) throw new Error(`provision: a previous provision in this process is still retaining its lock — an unconfirmed Cloudflare operation process${retentionWatchdog.info.pid !== void 0 ? ` (pid ${retentionWatchdog.info.pid})` : ""} could not be quarantined durably yet. No new provision may start until that retention resolves (the child is confirmed dead, or the quarantine metadata persists durably).`);
257
256
  const token = Symbol("void-provision-slot");
258
257
  activeProvisionSlot = token;
259
258
  return () => {
@@ -307,7 +306,7 @@ function deregisterRunner(registrant) {
307
306
  function coordinatorHandleSignal(signal) {
308
307
  if (activeTeardown !== void 0) return;
309
308
  if (retentionWatchdog !== void 0 && activeRegistrations.size === 0) {
310
- process.stderr.write(`provision: ignoring ${signal} — a provision lock is retained while an unconfirmed wrangler child may live and its quarantine metadata is not yet durable. The process exits once the child is confirmed dead or the metadata persists.\n`);
309
+ process.stderr.write(`provision: ignoring ${signal} — a provision lock is retained while an unconfirmed Cloudflare operation process may live and its quarantine metadata is not yet durable. The process exits once the child is confirmed dead or the metadata persists.\n`);
311
310
  return;
312
311
  }
313
312
  const teardown = {
@@ -350,14 +349,14 @@ function coordinatorTearDownRegistrant(teardown, registration) {
350
349
  if (lockQuarantine !== void 0) try {
351
350
  lockQuarantine({
352
351
  pid: registrant.pid(),
353
- reason: `the spawned wrangler could not be confirmed terminated after a forwarded ${teardown.signal} — ${detail}`
352
+ reason: `the spawned Cloudflare operation process could not be confirmed terminated after a forwarded ${teardown.signal} — ${detail}`
354
353
  });
355
354
  } catch (failure) {
356
355
  teardown.persistFailed = true;
357
356
  process.stderr.write(`provision: ${failure.message}\n`);
358
357
  }
359
358
  const pid = registrant.pid();
360
- process.stderr.write(`provision: warning — the wrangler child process group${typeof pid === "number" ? ` (pid ${pid})` : ""} could not be confirmed terminated after ${teardown.signal} (${detail}). It may still be running; the provision lock is retained (quarantined) — verify the process is dead before re-running provision.\n`);
359
+ process.stderr.write(`provision: warning — the Cloudflare operation process group${typeof pid === "number" ? ` (pid ${pid})` : ""} could not be confirmed terminated after ${teardown.signal} (${detail}). It may still be running; the provision lock is retained (quarantined) — verify the process is dead before re-running provision.\n`);
361
360
  registrant.quarantine(detail);
362
361
  complete();
363
362
  };
@@ -381,7 +380,7 @@ function finishCoordinatorTeardown(teardown) {
381
380
  if (teardown.persistFailed || retentionWatchdog !== void 0) {
382
381
  activeTeardown = void 0;
383
382
  installCoordinatorListeners();
384
- process.stderr.write(`provision: NOT re-raising ${teardown.signal} — a provision lock's quarantine metadata could not be persisted, so the lock is intentionally still held by this process to keep it from being stolen while the unconfirmed wrangler child may live.\n`);
383
+ process.stderr.write(`provision: NOT re-raising ${teardown.signal} — a provision lock's quarantine metadata could not be persisted, so the lock is intentionally still held by this process to keep it from being stolen while the unconfirmed Cloudflare operation process may live.\n`);
385
384
  return;
386
385
  }
387
386
  if (reRaisedOnce) return;
@@ -403,7 +402,7 @@ function retainQuarantinedLock(lock, info) {
403
402
  }
404
403
  function armRetentionWatchdog(lock, info) {
405
404
  if (retentionWatchdog !== void 0) return;
406
- process.stderr.write(`provision: warning — quarantine metadata for the unconfirmed wrangler child${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} could not be persisted, so the provision lock "${lock.lockTargetPath}.lock" is RETAINED by this process, which stays alive until the child is confirmed dead or the metadata persists durably.\n`);
405
+ process.stderr.write(`provision: warning — quarantine metadata for the unconfirmed Cloudflare operation process${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} could not be persisted, so the provision lock "${lock.lockTargetPath}.lock" is RETAINED by this process, which stays alive until the child is confirmed dead or the metadata persists durably.\n`);
407
406
  installCoordinatorListeners();
408
407
  let attempt = 0;
409
408
  const resolveWatchdog = () => {
@@ -456,12 +455,13 @@ function createDefaultRunWrangler(root, options) {
456
455
  const teardownDeadlineMs = options?.signalTeardownDeadlineMs ?? confirmGraceMs + SIGNAL_TEARDOWN_DEADLINE_MARGIN_MS;
457
456
  return (args, opts) => new Promise((resolvePromise, rejectPromise) => {
458
457
  const parallelWorkerUpload = options?.parallelWorkerUpload === true && args.type === "versions.upload";
458
+ const interactive = (args.type === "versions.upload" || args.type === "worker.deploy") && args.interactive === true;
459
459
  if (activeTeardown !== void 0) {
460
- rejectPromise(/* @__PURE__ */ new Error(`provision: refusing to spawn wrangler — a fatal ${activeTeardown.signal} is being handled and this process is terminating; no new wrangler work may start.`));
460
+ rejectPromise(/* @__PURE__ */ new Error(`provision: refusing to spawn a Cloudflare operation process — a fatal ${activeTeardown.signal} is being handled and this process is terminating; no new Cloudflare operation may start.`));
461
461
  return;
462
462
  }
463
463
  if (!canRegisterRunner(parallelWorkerUpload)) {
464
- rejectPromise(/* @__PURE__ */ new Error("provision: refusing to spawn wrangler — another wrangler child is already active in this process (only two immutable Worker uploads may overlap; all other Cloudflare commands and provisions remain sequential)."));
464
+ rejectPromise(/* @__PURE__ */ new Error("provision: refusing to spawn a Cloudflare operation process — another one is already active in this process (only two immutable Worker uploads may overlap; all other Cloudflare commands and provisions remain sequential)."));
465
465
  return;
466
466
  }
467
467
  const child = spawn(command, [...prefix, ...encodeCloudflareOperation(args)], {
@@ -475,7 +475,7 @@ function createDefaultRunWrangler(root, options) {
475
475
  }),
476
476
  ...opts.suppressLogs ? { WRANGLER_WRITE_LOGS: "false" } : {}
477
477
  },
478
- stdio: [
478
+ stdio: interactive ? "inherit" : [
479
479
  opts.input === void 0 ? "ignore" : "pipe",
480
480
  "pipe",
481
481
  "pipe"
@@ -548,7 +548,7 @@ function createDefaultRunWrangler(root, options) {
548
548
  };
549
549
  const timeoutStderr = (extra) => [
550
550
  stderr,
551
- `provision: wrangler exceeded the ${timeoutMs}ms command timeout`,
551
+ `provision: the Cloudflare operation process exceeded the ${timeoutMs}ms command timeout`,
552
552
  extra
553
553
  ].filter(Boolean).join("\n");
554
554
  const deregisterSelf = () => deregisterRunner(registrant);
@@ -557,7 +557,7 @@ function createDefaultRunWrangler(root, options) {
557
557
  settled = true;
558
558
  clearTimeout(commandTimer);
559
559
  deregisterSelf();
560
- resolvePromise(decodeCloudflareOperationResult(result));
560
+ resolvePromise(interactive ? result : decodeCloudflareOperationResult(result));
561
561
  };
562
562
  const quarantine = (detail) => {
563
563
  if (settled) return;
@@ -652,7 +652,7 @@ function createDefaultRunWrangler(root, options) {
652
652
  if (outcome === "gone") groupGone = true;
653
653
  confirmThenSettle(() => normalizeRunWranglerResult({
654
654
  stdout,
655
- stderr: [stderr, `provision: the spawned wrangler child emitted an error after spawn: ${error.message}`].filter(Boolean).join("\n"),
655
+ stderr: [stderr, `provision: the spawned Cloudflare operation process emitted an error after spawn: ${error.message}`].filter(Boolean).join("\n"),
656
656
  status: null,
657
657
  signal: "SIGKILL"
658
658
  }), `a post-spawn child error (${error.message}; the group was SIGKILLed)`);
@@ -697,8 +697,8 @@ function createDefaultRunWrangler(root, options) {
697
697
  function normalizeRunWranglerResult(result) {
698
698
  const stdout = result.stdout ?? "";
699
699
  const notes = [];
700
- if (result.signal != null) notes.push(`provision: wrangler was terminated by signal ${result.signal}`);
701
- if (result.error != null) notes.push(`provision: wrangler could not be spawned: ${result.error.message}`);
700
+ if (result.signal != null) notes.push(`provision: the Cloudflare operation process was terminated by signal ${result.signal}`);
701
+ if (result.error != null) notes.push(`provision: the Cloudflare operation process could not be spawned: ${result.error.message}`);
702
702
  const status = typeof result.status !== "number" || result.signal != null || result.error != null ? typeof result.status === "number" && result.status !== 0 ? result.status : 1 : result.status;
703
703
  const baseStderr = result.stderr ?? "";
704
704
  return {
@@ -903,7 +903,7 @@ function assertQuarantineClearedOrClear(lockTarget, onBeforeClear) {
903
903
  }
904
904
  if (!confirmedDead) {
905
905
  const who = pid !== void 0 || pgid !== void 0 ? `process group ${String(pgid ?? pid)}` : "an unrecorded process";
906
- throw new Error(`provision: refusing to provision — a previous provision QUARANTINED this config's lock because a spawned wrangler child could not be confirmed terminated (${who}${quarantinedAt ? `, quarantined at ${quarantinedAt}` : ""}${reason ? `; reason: ${reason}` : ""}). It may still be creating resources. Verify the process is dead (e.g. \`kill -0 ${String(pid ?? "<pid>")}\`; terminate it if not) and re-run — the quarantine then clears automatically. If you are CERTAIN the recorded process is unrelated (pid reuse) or gone, remove "${sidecarPath}" and the "${lockTarget}.lock" directory manually, then retry.`);
906
+ throw new Error(`provision: refusing to provision — a previous provision QUARANTINED this config's lock because a spawned Cloudflare operation process could not be confirmed terminated (${who}${quarantinedAt ? `, quarantined at ${quarantinedAt}` : ""}${reason ? `; reason: ${reason}` : ""}). It may still be creating resources. Verify the process is dead (e.g. \`kill -0 ${String(pid ?? "<pid>")}\`; terminate it if not) and re-run — the quarantine then clears automatically. If you are CERTAIN the recorded process is unrelated (pid reuse) or gone, remove "${sidecarPath}" and the "${lockTarget}.lock" directory manually, then retry.`);
907
907
  }
908
908
  const inspectedGeneration = typeof recorded?.generation === "string" ? recorded.generation : void 0;
909
909
  onBeforeClear?.();
@@ -1090,7 +1090,7 @@ async function acquireProvisionLock(configPath, lockOptions) {
1090
1090
  try {
1091
1091
  writeQuarantineSidecar(quarantineSidecarPath(lockTarget), info, lockOptions?.dirDurability);
1092
1092
  } catch (error) {
1093
- throw new Error(`provision: could not persist quarantine metadata to "${quarantineSidecarPath(lockTarget)}" (${error.message}). The cross-process provision lock "${lockTarget}.lock" is intentionally STILL HELD by this process (tracked, heartbeat running) so it cannot go stale and be stolen while the unconfirmed wrangler child${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} may still be running. Manual recovery: verify the process is dead${info.pid !== void 0 ? ` (e.g. \`kill -0 ${info.pid}\`)` : ""} and terminate it if not; the lock is freed when this process exits — remove the "${lockTarget}.lock" directory if it persists, then re-run.`);
1093
+ throw new Error(`provision: could not persist quarantine metadata to "${quarantineSidecarPath(lockTarget)}" (${error.message}). The cross-process provision lock "${lockTarget}.lock" is intentionally STILL HELD by this process (tracked, heartbeat running) so it cannot go stale and be stolen while the unconfirmed Cloudflare operation process${info.pid !== void 0 ? ` (pid ${info.pid})` : ""} may still be running. Manual recovery: verify the process is dead${info.pid !== void 0 ? ` (e.g. \`kill -0 ${info.pid}\`)` : ""} and terminate it if not; the lock is freed when this process exits — remove the "${lockTarget}.lock" directory if it persists, then re-run.`);
1094
1094
  }
1095
1095
  releasePromise = Promise.resolve();
1096
1096
  const locks = loadProperLockfileInternals()?.getLocks?.();
@@ -1125,7 +1125,7 @@ function readRootConfig(configPath) {
1125
1125
  }
1126
1126
  /** Throw unless a discovery call exited cleanly, so a failed list never means "absent". */
1127
1127
  function assertDiscoverySucceeded(result, label) {
1128
- if (!isCleanSuccess(result)) throw new Error(`provision: "${label}" failed (exit ${String(result.status)}): ${result.stderr || result.stdout || "no output"}. Cannot verify existing resources; refusing to create a possible duplicate.`);
1128
+ if (!isCleanSuccess(result)) throw new Error(`provision: ${label} failed (exit ${String(result.status)}): ${result.stderr || result.stdout || "no output"}. Cannot verify existing resources; refusing to create a possible duplicate.`);
1129
1129
  }
1130
1130
  /**
1131
1131
  * Reject the whole list if any member lacks a non-empty name or a valid id. A malformed member
@@ -1134,12 +1134,12 @@ function assertDiscoverySucceeded(result, label) {
1134
1134
  function validateResourceList(list, spec) {
1135
1135
  const validated = [];
1136
1136
  for (const member of list) {
1137
- if (!isRecord(member)) throw new Error(`provision: "${spec.command}" returned a malformed ${spec.resource} entry (not an object). Cannot verify existing resources; refusing to create a possible duplicate.`);
1137
+ if (!isRecord(member)) throw new Error(`provision: ${spec.command} returned a malformed ${spec.resource} entry (not an object). Cannot verify existing resources; refusing to create a possible duplicate.`);
1138
1138
  const rawName = member[spec.nameField];
1139
1139
  const nameValid = typeof rawName === "string" && rawName.length > 0;
1140
1140
  const idValid = spec.hasValidId(member);
1141
- if (nameValid && !idValid) throw new Error(`provision: "${spec.command}" returned a ${spec.resource} ${spec.nameLabel} ${JSON.stringify(rawName)} with no valid id (${spec.idRule}). Cannot verify existing resources; refusing to create a possible duplicate.`);
1142
- if (!nameValid) throw new Error(`provision: "${spec.command}" returned a malformed ${spec.resource} entry with no valid ${spec.nameField}. Cannot verify existing resources; refusing to create a possible duplicate.`);
1141
+ if (nameValid && !idValid) throw new Error(`provision: ${spec.command} returned a ${spec.resource} ${spec.nameLabel} ${JSON.stringify(rawName)} with no valid id (${spec.idRule}). Cannot verify existing resources; refusing to create a possible duplicate.`);
1142
+ if (!nameValid) throw new Error(`provision: ${spec.command} returned a malformed ${spec.resource} entry with no valid ${spec.nameField}. Cannot verify existing resources; refusing to create a possible duplicate.`);
1143
1143
  validated.push(member);
1144
1144
  }
1145
1145
  return validated;
@@ -1200,13 +1200,13 @@ function assertD1MigrationsDirApplied(result, binding, configPath) {
1200
1200
  }
1201
1201
  /**
1202
1202
  * After a create reports success, re-read the config and require a real id, plus the exact
1203
- * name where the name is the identity. A killed child can still report exit 0.
1203
+ * name where the name is the identity. A success status alone is not trusted.
1204
1204
  */
1205
1205
  function assertCreateWroteRealId(configPath, spec, binding, name) {
1206
1206
  const entry = readBindingEntry(configPath, spec.field, binding);
1207
1207
  const idOk = !!entry && spec.idValidator(entry[spec.idField]);
1208
1208
  const nameOk = spec.nameField === void 0 || !!entry && entry[spec.nameField] === name;
1209
- if (!idOk || !nameOk) throw new Error(`provision: "${spec.command} ${name}" reported success but "${configPath}" does not hold the expected ${spec.resource} for binding ${JSON.stringify(binding)} afterward (need a real ${spec.idField}${spec.nameField ? ` and ${spec.nameField} === ${JSON.stringify(name)}` : ""}). The create may have been interrupted or written a different resource — wrangler's launcher can mask a signal-killed child as exit 0. Refusing to record a wrong/unprovisioned resource; inspect the account/config and retry.`);
1209
+ if (!idOk || !nameOk) throw new Error(`provision: ${spec.command} ${name} reported success but "${configPath}" does not hold the expected ${spec.resource} for binding ${JSON.stringify(binding)} afterward (need a real ${spec.idField}${spec.nameField ? ` and ${spec.nameField} === ${JSON.stringify(name)}` : ""}). The create may have been interrupted or written a different resource. Refusing to record a wrong/unprovisioned resource; inspect the account/config and retry.`);
1210
1210
  }
1211
1211
  /** True when `value` contains an ASCII control character (0x00–0x1F or 0x7F). */
1212
1212
  function hasControlChar(value) {
@@ -1216,9 +1216,9 @@ function hasControlChar(value) {
1216
1216
  }
1217
1217
  return false;
1218
1218
  }
1219
- /** The universal option-injection guard for ANY wrangler ARGV positional. */
1219
+ /** The universal option-injection guard for ANY Cloudflare operation ARGV positional. */
1220
1220
  function assertNoOptionInjection(kind, name) {
1221
- if (typeof name !== "string" || name.length === 0 || name.startsWith("-") || hasControlChar(name)) throw new Error(`provision: refusing to pass an unsafe ${kind} name ${JSON.stringify(name)} to wrangler. A name may not be empty, begin with "-" (it would be parsed as a CLI flag), or contain control characters. Rename the resource and retry.`);
1221
+ if (typeof name !== "string" || name.length === 0 || name.startsWith("-") || hasControlChar(name)) throw new Error(`provision: refusing to pass an unsafe ${kind} name ${JSON.stringify(name)} to a Cloudflare operation. A name may not be empty, begin with "-" (it would be parsed as a CLI flag), or contain control characters. Rename the resource and retry.`);
1222
1222
  }
1223
1223
  /** Per-resource Cloudflare naming grammar. KV titles may contain spaces and mixed case. */
1224
1224
  const RESOURCE_NAME_GRAMMARS = {
@@ -1252,7 +1252,7 @@ const RESOURCE_NAME_GRAMMARS = {
1252
1252
  function assertValidResourceName(kind, name) {
1253
1253
  assertNoOptionInjection(RESOURCE_NAME_GRAMMARS[kind].label, name);
1254
1254
  const grammar = RESOURCE_NAME_GRAMMARS[kind];
1255
- if (!grammar.re.test(name)) throw new Error(`provision: refusing to pass an invalid ${grammar.label} name ${JSON.stringify(name)} to wrangler. A ${grammar.label} name must ${grammar.rule}. Rename the resource and retry.`);
1255
+ if (!grammar.re.test(name)) throw new Error(`provision: refusing to pass an invalid ${grammar.label} name ${JSON.stringify(name)} to a Cloudflare operation. A ${grammar.label} name must ${grammar.rule}. Rename the resource and retry.`);
1256
1256
  }
1257
1257
  /** Redactor that replaces the exact connection string and masks any URL userinfo password. */
1258
1258
  function createSecretRedactor(connectionString) {
@@ -1306,7 +1306,7 @@ async function provisionWithProcessSlot(root, rootWranglerPath, desired, opts) {
1306
1306
  reason: typeof bodyError.message === "string" ? bodyError.message : String(bodyError)
1307
1307
  });
1308
1308
  } catch (quarantineError) {
1309
- throw new AggregateError([bodyError, quarantineError], `provision failed with an unconfirmed wrangler child AND its quarantine metadata could not be persisted — the cross-process provision lock is intentionally still held by this process (not released, not stealable) while the child may live. Primary error: ${bodyError instanceof Error ? bodyError.message : String(bodyError)}; quarantine error: ${quarantineError instanceof Error ? quarantineError.message : String(quarantineError)}.`, { cause: bodyError });
1309
+ throw new AggregateError([bodyError, quarantineError], `provision failed with an unconfirmed Cloudflare operation process AND its quarantine metadata could not be persisted — the cross-process provision lock is intentionally still held by this process (not released, not stealable) while the child may live. Primary error: ${bodyError instanceof Error ? bodyError.message : String(bodyError)}; quarantine error: ${quarantineError instanceof Error ? quarantineError.message : String(quarantineError)}.`, { cause: bodyError });
1310
1310
  }
1311
1311
  throw bodyError;
1312
1312
  }
@@ -1359,19 +1359,19 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
1359
1359
  type: "d1.list",
1360
1360
  configPath
1361
1361
  }, {});
1362
- assertDiscoverySucceeded(listResult, "wrangler d1 list");
1362
+ assertDiscoverySucceeded(listResult, "Cloudflare d1 list");
1363
1363
  const rawList = listResult.data;
1364
- if (!Array.isArray(rawList)) throw new Error(`provision: "wrangler d1 list --json" did not return a JSON array; cannot verify whether D1 database ${JSON.stringify(name)} exists. Refusing to create a possible duplicate.`);
1364
+ if (!Array.isArray(rawList)) throw new Error(`provision: Cloudflare d1 list did not return a JSON array; cannot verify whether D1 database ${JSON.stringify(name)} exists. Refusing to create a possible duplicate.`);
1365
1365
  const claimants = validateResourceList(rawList, {
1366
1366
  resource: "D1 database",
1367
- command: "wrangler d1 list",
1367
+ command: "Cloudflare d1 list",
1368
1368
  hasValidId: (member) => reconcileD1IdAliases(member).kind === "id",
1369
1369
  idRule: "its uuid/database_id aliases must be present, well-formed D1 UUIDs agreeing on one id",
1370
1370
  nameField: "name",
1371
1371
  nameLabel: "named"
1372
1372
  }).map((db) => normalizeD1(db, name)).filter((m) => m.kind !== "other");
1373
- if (claimants.length > 1) throw new Error(`provision: "wrangler d1 list" returned ${claimants.length} D1 databases named ${JSON.stringify(name)}. D1 database names are account-unique, so this is ambiguous; cannot pick one to adopt and refusing to create a possible duplicate. Inspect the account and retry.`);
1374
- if (claimants.length === 1 && claimants[0].kind === "claimed-but-invalid") throw new Error(`provision: "wrangler d1 list" returned a D1 database named ${JSON.stringify(name)} with an ambiguous or empty id (conflicting/blank uuid/database_id, or conflicting name aliases). Cannot adopt it, and refusing to create a possible duplicate; inspect the account and retry.`);
1373
+ if (claimants.length > 1) throw new Error(`provision: Cloudflare d1 list returned ${claimants.length} D1 databases named ${JSON.stringify(name)}. D1 database names are account-unique, so this is ambiguous; cannot pick one to adopt and refusing to create a possible duplicate. Inspect the account and retry.`);
1374
+ if (claimants.length === 1 && claimants[0].kind === "claimed-but-invalid") throw new Error(`provision: Cloudflare d1 list returned a D1 database named ${JSON.stringify(name)} with an ambiguous or empty id (conflicting/blank uuid/database_id, or conflicting name aliases). Cannot adopt it, and refusing to create a possible duplicate; inspect the account and retry.`);
1375
1375
  const existing = claimants.length === 1 && claimants[0].kind === "match" ? claimants[0] : void 0;
1376
1376
  if (existing) {
1377
1377
  log.info(`adopted existing D1 database ${name} (${existing.id})`);
@@ -1407,7 +1407,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
1407
1407
  idValidator: isRealD1Id,
1408
1408
  nameField: "database_name",
1409
1409
  resource: "D1 database",
1410
- command: "wrangler d1 create"
1410
+ command: "Cloudflare d1 create"
1411
1411
  }, binding, name);
1412
1412
  persistCreatedConfig();
1413
1413
  assertD1MigrationsDirApplied(write({ d1MigrationsDir: {
@@ -1426,9 +1426,9 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
1426
1426
  name,
1427
1427
  configPath
1428
1428
  }, {});
1429
- assertDiscoverySucceeded(infoResult, `wrangler d1 info ${name}`);
1429
+ assertDiscoverySucceeded(infoResult, `Cloudflare d1 info ${name}`);
1430
1430
  const info = normalizeD1(isRecord(infoResult.data) ? infoResult.data : void 0, name);
1431
- if (info.kind !== "match") throw new Error(`provision: "wrangler d1 create ${name}" reported the database already exists, but "wrangler d1 info ${name} --json" did not return a database with a matching name and an unambiguous id. Refusing to adopt an unverified database.`);
1431
+ if (info.kind !== "match") throw new Error(`provision: Cloudflare d1 create ${name} reported the database already exists, but Cloudflare d1 info ${name} did not return a database with a matching name and an unambiguous id. Refusing to adopt an unverified database.`);
1432
1432
  log.info(`adopted existing D1 database ${name} (${info.id})`);
1433
1433
  assertD1MigrationsDirApplied(write({
1434
1434
  d1: {
@@ -1448,7 +1448,7 @@ async function reconcileD1(desired, configPath, runWrangler, write, persistCreat
1448
1448
  action: "adopted",
1449
1449
  id: info.id
1450
1450
  });
1451
- } else throw new Error(`provision: "wrangler d1 create ${name}" failed: ${created.stderr || created.stdout}`);
1451
+ } else throw new Error(`provision: Cloudflare d1 create ${name} failed: ${created.stderr || created.stdout}`);
1452
1452
  }
1453
1453
  }
1454
1454
  const databaseId = readBindingEntry(configPath, "d1_databases", binding)?.database_id;
@@ -1491,12 +1491,12 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
1491
1491
  type: "kv.namespace.list",
1492
1492
  configPath
1493
1493
  }, {});
1494
- assertDiscoverySucceeded(listResult, "wrangler kv namespace list");
1494
+ assertDiscoverySucceeded(listResult, "Cloudflare kv namespace list");
1495
1495
  const rawList = listResult.data;
1496
- if (!Array.isArray(rawList)) throw new Error(`provision: "wrangler kv namespace list" did not return a JSON array; cannot verify whether KV namespace ${JSON.stringify(title)} exists. Refusing to create a possible duplicate.`);
1496
+ if (!Array.isArray(rawList)) throw new Error(`provision: Cloudflare kv namespace list did not return a JSON array; cannot verify whether KV namespace ${JSON.stringify(title)} exists. Refusing to create a possible duplicate.`);
1497
1497
  const matches = validateResourceList(rawList, {
1498
1498
  resource: "KV namespace",
1499
- command: "wrangler kv namespace list",
1499
+ command: "Cloudflare kv namespace list",
1500
1500
  hasValidId: (member) => isRealKvId(member.id),
1501
1501
  idRule: "its id is missing or not a well-formed 32-hex namespace id",
1502
1502
  nameField: "title",
@@ -1524,13 +1524,13 @@ async function reconcileKv(desired, configPath, runWrangler, write, persistCreat
1524
1524
  binding,
1525
1525
  configPath
1526
1526
  });
1527
- if (!isCleanSuccess(created)) throw new Error(`provision: "wrangler kv namespace create ${title}" failed: ${created.stderr || created.stdout}`);
1527
+ if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare kv namespace create ${title} failed: ${created.stderr || created.stdout}`);
1528
1528
  assertCreateWroteRealId(configPath, {
1529
1529
  field: "kv_namespaces",
1530
1530
  idField: "id",
1531
1531
  idValidator: isRealKvId,
1532
1532
  resource: "KV namespace",
1533
- command: "wrangler kv namespace create"
1533
+ command: "Cloudflare kv namespace create"
1534
1534
  }, binding, title);
1535
1535
  persistCreatedConfig();
1536
1536
  resources.push({
@@ -1563,7 +1563,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
1563
1563
  }, {});
1564
1564
  if (isCleanSuccess(info)) {
1565
1565
  const payload = info.data;
1566
- if (!isRecord(payload) || payload.name !== bucketName) throw new Error(`provision: "wrangler r2 bucket info ${bucketName} --json" exited 0 but did not identify the requested bucket (expected name ${JSON.stringify(bucketName)}). Refusing to adopt an unverified bucket. Output: ${info.stdout || info.stderr}`);
1566
+ if (!isRecord(payload) || payload.name !== bucketName) throw new Error(`provision: Cloudflare r2 bucket info ${bucketName} exited 0 but did not identify the requested bucket (expected name ${JSON.stringify(bucketName)}). Refusing to adopt an unverified bucket. Output: ${info.stdout || info.stderr}`);
1567
1567
  log.info(`adopted existing R2 bucket ${bucketName}`);
1568
1568
  write({ r2: {
1569
1569
  binding,
@@ -1582,14 +1582,14 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
1582
1582
  binding,
1583
1583
  configPath
1584
1584
  });
1585
- if (!isCleanSuccess(created)) throw new Error(`provision: "wrangler r2 bucket create ${bucketName}" failed: ${created.stderr || created.stdout}`);
1585
+ if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare r2 bucket create ${bucketName} failed: ${created.stderr || created.stdout}`);
1586
1586
  assertCreateWroteRealId(configPath, {
1587
1587
  field: "r2_buckets",
1588
1588
  idField: "bucket_name",
1589
1589
  idValidator: isValidR2BucketNameFormat,
1590
1590
  nameField: "bucket_name",
1591
1591
  resource: "R2 bucket",
1592
- command: "wrangler r2 bucket create"
1592
+ command: "Cloudflare r2 bucket create"
1593
1593
  }, binding, bucketName);
1594
1594
  if (bucketName === R2_BUCKET_NAME_PLACEHOLDER) {
1595
1595
  const verify = await runWrangler({
@@ -1597,7 +1597,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
1597
1597
  name: bucketName,
1598
1598
  configPath
1599
1599
  }, {});
1600
- if (!isCleanSuccess(verify) || !isRecord(verify.data) || verify.data.name !== bucketName) throw new Error(`provision: "wrangler r2 bucket create ${bucketName}" reported success but a follow-up "wrangler r2 bucket info ${bucketName}" did not confirm the bucket exists. The create may have been interrupted — wrangler's launcher can mask a signal-killed child as exit 0, and the config entry is indistinguishable from the local-dev placeholder for this name. Refusing to record an unprovisioned bucket; inspect the account and retry.`);
1600
+ if (!isCleanSuccess(verify) || !isRecord(verify.data) || verify.data.name !== bucketName) throw new Error(`provision: Cloudflare r2 bucket create ${bucketName} reported success but a follow-up Cloudflare r2 bucket info ${bucketName} did not confirm the bucket exists. The create may have been interrupted, and the config entry is indistinguishable from the local-dev placeholder for this name. Refusing to record an unprovisioned bucket; inspect the account and retry.`);
1601
1601
  }
1602
1602
  persistCreatedConfig();
1603
1603
  resources.push({
@@ -1606,7 +1606,7 @@ async function reconcileR2(desired, configPath, runWrangler, write, persistCreat
1606
1606
  name: bucketName,
1607
1607
  action: "created"
1608
1608
  });
1609
- } else throw new Error(`provision: "wrangler r2 bucket info ${bucketName}" failed: ${info.stderr || info.stdout}. Cannot determine whether the bucket exists; refusing to create a possible duplicate.`);
1609
+ } else throw new Error(`provision: Cloudflare r2 bucket info ${bucketName} failed: ${info.stderr || info.stdout}. Cannot determine whether the bucket exists; refusing to create a possible duplicate.`);
1610
1610
  }
1611
1611
  }
1612
1612
  }
@@ -1663,7 +1663,7 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
1663
1663
  action: "skipped",
1664
1664
  reason
1665
1665
  });
1666
- } else if (existenceUnknown) throw new Error(`provision: cannot verify whether Hyperdrive config ${JSON.stringify(name)} already exists (no existence check available — provide an accountId + API token, or inject a listHyperdriveConfigs seam). "wrangler hyperdrive create" silently duplicates a same-named config, so provisioning refuses to create it blindly.`);
1666
+ } else if (existenceUnknown) throw new Error(`provision: could not check whether Hyperdrive config ${JSON.stringify(name)} already exists (see the warning above). A create would duplicate a config with the same name, so Void did not create it. Check that CLOUDFLARE_API_TOKEN can read Hyperdrive configs, then retry.`);
1667
1667
  else {
1668
1668
  const created = await runWrangler({
1669
1669
  type: "hyperdrive.create",
@@ -1671,13 +1671,13 @@ async function reconcileHyperdrive(desired, configPath, runWrangler, write, pers
1671
1671
  binding,
1672
1672
  configPath
1673
1673
  }, { input: connectionString });
1674
- if (!isCleanSuccess(created)) throw new Error(`provision: "wrangler hyperdrive create ${name}" failed: ${created.stderr || created.stdout}`);
1674
+ if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare hyperdrive create ${name} failed: ${created.stderr || created.stdout}`);
1675
1675
  assertCreateWroteRealId(configPath, {
1676
1676
  field: "hyperdrive",
1677
1677
  idField: "id",
1678
1678
  idValidator: isRealHyperdriveId,
1679
1679
  resource: "Hyperdrive config",
1680
- command: "wrangler hyperdrive create"
1680
+ command: "Cloudflare hyperdrive create"
1681
1681
  }, binding, name);
1682
1682
  persistCreatedConfig();
1683
1683
  resources.push({
@@ -1705,18 +1705,18 @@ async function reconcileQueues(desired, configPath, runWrangler, resources) {
1705
1705
  });
1706
1706
  continue;
1707
1707
  }
1708
- if (!isConfirmedAbsent(info, "queue")) throw new Error(`provision: "wrangler queues info ${name}" failed or did not confirm the queue exists: ${info.stderr || info.stdout || "no output"}`);
1708
+ if (!isConfirmedAbsent(info, "queue")) throw new Error(`provision: Cloudflare queues info ${name} failed or did not confirm the queue exists: ${info.stderr || info.stdout || "no output"}`);
1709
1709
  const created = await runWrangler({
1710
1710
  type: "queues.create",
1711
1711
  name,
1712
1712
  configPath
1713
1713
  });
1714
- if (!isCleanSuccess(created)) throw new Error(`provision: "wrangler queues create ${name}" failed: ${created.stderr || created.stdout}`);
1714
+ if (!isCleanSuccess(created)) throw new Error(`provision: Cloudflare queues create ${name} failed: ${created.stderr || created.stdout}`);
1715
1715
  if (!queueInfoConfirmsExists(await runWrangler({
1716
1716
  type: "queues.info",
1717
1717
  name,
1718
1718
  configPath
1719
- }), name)) throw new Error(`provision: "wrangler queues create ${name}" reported success but "wrangler queues info ${name}" did not confirm the queue exists afterward. The create may have been interrupted — wrangler's launcher can mask a signal-killed child as exit 0. Refusing to record an unprovisioned queue; inspect the account and retry.`);
1719
+ }), name)) throw new Error(`provision: Cloudflare queues create ${name} reported success but Cloudflare queues info ${name} did not confirm the queue exists afterward. The create may have been interrupted. Refusing to record an unprovisioned queue; inspect the account and retry.`);
1720
1720
  resources.push({
1721
1721
  kind: "queue",
1722
1722
  name,
@@ -1750,14 +1750,14 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
1750
1750
  const write = (patch) => writeProvisionedWranglerConfig(root, patch, { configPath });
1751
1751
  const persistCreatedConfig = () => persistMaterializedWranglerConfig(configPath);
1752
1752
  const hasRemoteWork = !!desired.d1 || desired.kvNamespaces.length > 0 || !!desired.r2 || !!desired.hyperdrive || desired.queues.length > 0;
1753
- if (hasRemoteWork && !effectiveAccountId) throw new Error("provision: no Cloudflare account is resolvable — set \"account_id\" in your root wrangler config or export CLOUDFLARE_ACCOUNT_ID before deploying. Refusing to provision resources without a pinned account (wrangler would otherwise fall back to an ambient/interactive account that is never persisted, so a later retry could rebind them elsewhere).");
1753
+ if (hasRemoteWork && !effectiveAccountId) throw new Error("provision: no Cloudflare account is resolvable. Set `cloudflare.account_id` in void.config.ts or export CLOUDFLARE_ACCOUNT_ID, then rerun `void deploy`. Void does not provision resources without a pinned account.");
1754
1754
  if (hasRemoteWork) assertNoTransportRedirectInProjectDotenv(root);
1755
1755
  if (desired.hyperdrive && !opts?.listHyperdriveConfigs) {
1756
1756
  const { binding, name, connectionString } = desired.hyperdrive;
1757
1757
  const entry = readBindingEntry(configPath, "hyperdrive", binding);
1758
1758
  if (!(entry !== void 0 && isRealHyperdriveId(entry.id)) && !resolveHyperdriveApiToken(opts?.apiToken)) {
1759
- if (connectionString) throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} is not in "${configPath}" yet, and creating it needs a Cloudflare API token. wrangler exposes no machine-readable Hyperdrive list, so Void checks the account over the Cloudflare REST API, which a Cloudflare browser OAuth cannot authenticate. Without that check a create would silently duplicate an existing same-named config, so nothing was provisioned. Either (a) export CLOUDFLARE_API_TOKEN with Hyperdrive edit permission and rerun, or (b) create the Hyperdrive config yourself (dashboard / "wrangler hyperdrive create") and add its id to the ${JSON.stringify(binding)} hyperdrive binding in "${configPath}" — deploying an already-provisioned Hyperdrive needs no token.`);
1760
- throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} is not in "${configPath}" yet, and there is no DATABASE_URL to create it from. Nothing was provisioned. Either (a) export DATABASE_URL with your PostgreSQL connection string and rerun (Void reads it from the shell — a value in .env/.env.local is NOT used here, so it never ships as a plaintext worker var), or (b) create the Hyperdrive config yourself (dashboard / "wrangler hyperdrive create") and add its id to the ${JSON.stringify(binding)} hyperdrive binding in "${configPath}" — deploying an already-provisioned Hyperdrive needs neither DATABASE_URL nor an API token.`);
1759
+ if (connectionString) throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} has no ID yet. Before Void creates one, it checks for an existing config with the Cloudflare API. That check needs an API token; a browser login cannot call it. Without the check, a create could duplicate an existing config with the same name, so nothing was provisioned. Either (a) export CLOUDFLARE_API_TOKEN with Hyperdrive edit permission and rerun, or (b) create the Hyperdrive config in the Cloudflare dashboard and add its ID to the ${JSON.stringify(binding)} entry in \`cloudflare.hyperdrive\` in void.config.ts. Deploying an already-provisioned Hyperdrive needs no token.`);
1760
+ throw new Error(`provision: Hyperdrive config ${JSON.stringify(name)} has no ID yet, and there is no DATABASE_URL to create it from. Nothing was provisioned. Either (a) export DATABASE_URL with your PostgreSQL connection string and rerun (Void reads it from the shell — a value in .env/.env.local is NOT used here, so it never ships as a plaintext worker var), or (b) create the Hyperdrive config in the Cloudflare dashboard and add its ID to the ${JSON.stringify(binding)} entry in \`cloudflare.hyperdrive\` in void.config.ts. Deploying an already-provisioned Hyperdrive needs neither DATABASE_URL nor an API token.`);
1761
1761
  }
1762
1762
  }
1763
1763
  let accountIdWritten = false;
@@ -1794,4 +1794,4 @@ async function provisionCloudflareResourcesLocked(root, configPath, desired, opt
1794
1794
  };
1795
1795
  }
1796
1796
  //#endregion
1797
- export { deleteEnvVarCaseAware as a, isRealKvId as c, resolvePinnedApiBaseUrl as d, createDefaultRunWrangler as i, provisionCloudflareResources as l, assertValidResourceName as n, isQueueConfirmedAbsent as o, checkCloudflareProvisionDrift as r, isRealD1Id as s, assertNoTransportRedirectInProjectDotenv as t, provisionEnv as u };
1797
+ export { provisionEnv as _, checkCloudflareProvisionDrift as a, enableD1ReadReplicationViaApi as c, isQueueConfirmedAbsent as d, isRealD1Id as f, provisionCloudflareResources as g, normalizeRunWranglerResult as h, assertValidResourceName as i, isAlreadyGoneKillError as l, isRealKvId as m, acquireProvisionLock as n, createDefaultRunWrangler as o, isRealHyperdriveId as p, assertNoTransportRedirectInProjectDotenv as r, deleteEnvVarCaseAware as s, WranglerQuarantineError as t, isQuarantineError as u, resolvePinnedApiBaseUrl as v, resolveProperLockfileKey as y };
@@ -0,0 +1,61 @@
1
+ //#region src/runtime/remote/r2-conditions.ts
2
+ /** URI-encoded JSON object metadata that the binding handler sends with a streamed `/r2/get` body. */
3
+ const R2_OBJECT_HEADER = "x-void-r2-object";
4
+ const HTTP_METADATA_FIELDS = /* @__PURE__ */ new Set([
5
+ "contentType",
6
+ "contentLanguage",
7
+ "contentDisposition",
8
+ "contentEncoding",
9
+ "cacheControl"
10
+ ]);
11
+ function serializeR2Conditional(value) {
12
+ if (value instanceof Headers) return Array.from(value.entries());
13
+ return {
14
+ ...value,
15
+ uploadedBefore: value.uploadedBefore?.toISOString(),
16
+ uploadedAfter: value.uploadedAfter?.toISOString()
17
+ };
18
+ }
19
+ function serializeR2HttpMetadata(value) {
20
+ if (value instanceof Headers) return Array.from(value.entries());
21
+ return {
22
+ ...value,
23
+ cacheExpiry: value.cacheExpiry?.toISOString()
24
+ };
25
+ }
26
+ function parseHeaderEntries(value, message) {
27
+ if (!value.every((pair) => Array.isArray(pair) && pair.length === 2 && pair.every((item) => typeof item === "string"))) throw new Error(message);
28
+ return new Headers(value);
29
+ }
30
+ function parseR2Conditional(value) {
31
+ if (Array.isArray(value)) return parseHeaderEntries(value, "Invalid R2 conditional headers");
32
+ if (!value || typeof value !== "object") throw new Error("Invalid R2 conditional options");
33
+ const result = {};
34
+ for (const [key, entry] of Object.entries(value)) if (key === "etagMatches" || key === "etagDoesNotMatch") {
35
+ if (typeof entry !== "string") throw new Error(`Invalid R2 condition: ${key}`);
36
+ result[key] = entry;
37
+ } else if (key === "uploadedBefore" || key === "uploadedAfter") {
38
+ if (typeof entry !== "string" || !Number.isFinite(Date.parse(entry))) throw new Error(`Invalid R2 condition: ${key}`);
39
+ result[key] = new Date(entry);
40
+ } else if (key === "secondsGranularity") {
41
+ if (typeof entry !== "boolean") throw new Error(`Invalid R2 condition: ${key}`);
42
+ result[key] = entry;
43
+ } else throw new Error(`Unsupported R2 condition: ${key}`);
44
+ return result;
45
+ }
46
+ /** Like native R2, unknown metadata fields are ignored. */
47
+ function parseR2HttpMetadata(value) {
48
+ if (Array.isArray(value)) return parseHeaderEntries(value, "Invalid R2 HTTP metadata headers");
49
+ if (!value || typeof value !== "object") throw new Error("Invalid R2 HTTP metadata");
50
+ const result = {};
51
+ for (const [key, entry] of Object.entries(value)) if (key === "cacheExpiry") {
52
+ if (typeof entry !== "string" || !Number.isFinite(Date.parse(entry))) throw new Error(`Invalid R2 HTTP metadata: ${key}`);
53
+ result[key] = new Date(entry);
54
+ } else if (HTTP_METADATA_FIELDS.has(key)) {
55
+ if (typeof entry !== "string") throw new Error(`Invalid R2 HTTP metadata: ${key}`);
56
+ result[key] = entry;
57
+ }
58
+ return result;
59
+ }
60
+ //#endregion
61
+ export { serializeR2HttpMetadata as a, serializeR2Conditional as i, parseR2Conditional as n, parseR2HttpMetadata as r, R2_OBJECT_HEADER as t };
@@ -1,8 +1,8 @@
1
1
  import { r as readProjectConfig } from "./project-rqDnVsJN.mjs";
2
2
  import { c as getToken } from "./auth-B6iOCjKI.mjs";
3
3
  import { H as outro, L as log } from "./dist-BVdsO7Py.mjs";
4
- import { f as import_picocolors, i as dim } from "./output-Ba6ZbrzY.mjs";
5
- import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
4
+ import { f as import_picocolors, i as dim } from "./output-CKguMgr7.mjs";
5
+ import { r as PlatformClient } from "./client-BdzxubTS.mjs";
6
6
  //#region src/cli/requests.ts
7
7
  async function runRequestsCommand(root, range, status) {
8
8
  console.log();
@@ -1,13 +1,13 @@
1
1
  import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
2
2
  import { c as getToken } from "./auth-B6iOCjKI.mjs";
3
3
  import { A as confirm, H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./dist-BVdsO7Py.mjs";
4
- import { c as formatRelativeTime, i as dim, m as printSuccess, o as formatCount, r as createSpinner } from "./output-Ba6ZbrzY.mjs";
5
- import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
4
+ import { c as formatRelativeTime, i as dim, m as printSuccess, o as formatCount, r as createSpinner } from "./output-CKguMgr7.mjs";
5
+ import { r as PlatformClient } from "./client-BdzxubTS.mjs";
6
6
  //#region src/cli/rollback.ts
7
- async function runRollbackCommand(root, deployId) {
7
+ async function runRollbackCommand(root, deployId, explicitPlatform) {
8
8
  console.log();
9
9
  const platform = readDeploymentPlatform(root);
10
- if (platform === "cloudflare") return runCloudflareRollback(root, deployId);
10
+ if (explicitPlatform === "cloudflare" || platform === "cloudflare") return runCloudflareRollback(root, deployId, platform !== "cloudflare");
11
11
  if (platform === "none") throw new Error("rollback: Deployment is disabled. Run `void init` to choose a platform.");
12
12
  const token = getToken(root);
13
13
  if (!token) {
@@ -73,8 +73,8 @@ async function runRollbackCommand(root, deployId) {
73
73
  process.exit(1);
74
74
  }
75
75
  }
76
- async function runCloudflareRollback(root, deployId) {
77
- const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-CrSUFRzJ.mjs");
76
+ async function runCloudflareRollback(root, deployId, restorePlatformFlag) {
77
+ const { activateCloudflareExistingVersion, readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BFLCpUCV.mjs");
78
78
  const context = resolveCloudflareOperationContext(root);
79
79
  const status = await readCloudflareWorkerStatus(context);
80
80
  const deployedVersionIds = new Set(status.deployedVersionIds);
@@ -116,7 +116,7 @@ async function runCloudflareRollback(root, deployId) {
116
116
  await confirmRollbackOrExit();
117
117
  } else {
118
118
  const targetSet = new Set(target.metadata.migrations);
119
- await confirmUnrevertedMigrations(current.metadata.migrations.filter((migration) => !targetSet.has(migration)), "version");
119
+ await confirmUnrevertedMigrations(current.metadata.migrations.filter((migration) => !targetSet.has(migration)), "version", restorePlatformFlag);
120
120
  }
121
121
  const spinner = createSpinner();
122
122
  spinner.start("Rolling back...");
@@ -139,11 +139,12 @@ async function confirmRollbackOrExit() {
139
139
  }
140
140
  }
141
141
  /** List migrations the rollback will not revert and ask before continuing. */
142
- async function confirmUnrevertedMigrations(migrationDiff, noun) {
142
+ async function confirmUnrevertedMigrations(migrationDiff, noun, restorePlatformFlag = false) {
143
143
  if (migrationDiff.length === 0) return;
144
144
  log.warn(`The current database has ${formatCount(migrationDiff.length, "migration")} applied after this ${noun}:`);
145
145
  for (const migration of migrationDiff) log.message(` ${dim("•")} ${migration}`);
146
146
  log.message(dim("Rolling back will NOT revert these migrations. The older code will run against the current schema."));
147
+ if (noun === "version") log.message(dim(`For D1, \`void db restore${restorePlatformFlag ? " --platform cloudflare" : ""} --bookmark <bookmark>\` undoes them with the restore point deploy printed before migrating. Restore points expire after 7 days on Workers Free and 30 days on Paid; undo older migrations with a new migration.`));
147
148
  await confirmRollbackOrExit();
148
149
  }
149
150
  //#endregion