void 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/AGENTS_TEMPLATE.md +1 -1
  2. package/README.md +5 -1
  3. package/dist/{account-cmd-CjyxcGkM.mjs → account-cmd-vJhh5lrb.mjs} +5 -5
  4. package/dist/{scan-ClYmX3sa.mjs → application-analysis-BVsVqc11.mjs} +135 -18
  5. package/dist/application-routing-B7QEjqSR.mjs +27 -0
  6. package/dist/{auth-DLNN0D3Z.mjs → auth-CQkSDS50.mjs} +26 -96
  7. package/dist/auth-DX3JURcX.mjs +2 -0
  8. package/dist/{auth-link-BLO4ptzo.mjs → auth-link-D75t9wO2.mjs} +5 -5
  9. package/dist/{auth-router-ZUg9MF_U.mjs → auth-router-ClfhL1J7.mjs} +7 -7
  10. package/dist/{better-auth-shared-rsBGBvWJ.mjs → better-auth-shared-hy6RPh9W.mjs} +13 -2
  11. package/dist/{build-cmd-BxR5FROK.mjs → build-cmd-zMi1iFnS.mjs} +21 -9
  12. package/dist/{cache-D0sWhgKI.mjs → cache-ZtQmyxVV.mjs} +5 -5
  13. package/dist/{cancel-deploy-D4NUqFbi.mjs → cancel-deploy-Box0kkEV.mjs} +5 -5
  14. package/dist/{cf-access-P0iZnu0q.mjs → cf-access-BGe5sWXF.mjs} +4 -48
  15. package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
  16. package/dist/{cf-build-output-BJ6yGEIS.mjs → cf-build-output-BPqOT964.mjs} +2 -1
  17. package/dist/cf-build-output-_0HNWysu.mjs +2 -0
  18. package/dist/cli/cli.mjs +89 -461
  19. package/dist/cli/{cf-compat.mjs → cloudflare-operation-process.mjs} +454 -424
  20. package/dist/cli/env-schema-probe.d.mts +2 -1
  21. package/dist/cli/env-schema-probe.mjs +4 -4
  22. package/dist/client-B9UBI03V.mjs +2 -0
  23. package/dist/{client-BTZ3XkrB.mjs → client-DKAsFA4X.mjs} +161 -24
  24. package/dist/{cloudflare-auth-DQkqoMYa.mjs → cloudflare-auth-Qdc7tw8F.mjs} +41 -38
  25. package/dist/{cloudflare-cmd-BKlfGHAy.mjs → cloudflare-cmd-CmY8dGkd.mjs} +6 -6
  26. package/dist/cloudflare-config-Bktvwtpf.mjs +182 -0
  27. package/dist/{cloudflare-connect-Ctmrw579.mjs → cloudflare-connect-IiR3ZieC.mjs} +4 -4
  28. package/dist/{cloudflare-operations-BT6OWFBk.mjs → cloudflare-operations-BCdXSsmo.mjs} +1 -1
  29. package/dist/{cloudflare-operations-B9tzgjmf.mjs → cloudflare-operations-DzH-A966.mjs} +116 -172
  30. package/dist/{preset-UHj9ARyP.mjs → cloudflare-process-B-wekeR6.mjs} +93 -6
  31. package/dist/{config-VavjpDnp.d.mts → config-BMHb8RCj.d.mts} +1 -0
  32. package/dist/config-C_XRIPx2.mjs +89 -0
  33. package/dist/config-entry.d.mts +1 -1
  34. package/dist/{connect-Dg-WkW-C.mjs → connect-B-usTnlF.mjs} +9 -9
  35. package/dist/{create-project-l9J7pbtm.mjs → create-project-CYOOAYcn.mjs} +12 -12
  36. package/dist/{create-project-DdoqwFLF.mjs → create-project-FWbf5Olo.mjs} +1 -1
  37. package/dist/{db-gp2sCXyN.mjs → db-Ck2eZ2iB.mjs} +26 -26
  38. package/dist/{delete-TTedbH6B.mjs → delete-sK56qtzZ.mjs} +5 -5
  39. package/dist/{deploy-CH-o2CaZ.mjs → deploy-gCVaiJbS.mjs} +984 -616
  40. package/dist/{deploy-B19L2Bra.mjs → deploy-irP5q0-x.mjs} +1 -1
  41. package/dist/{domain-JRF59P_r.mjs → domain-DFfQE8jg.mjs} +6 -6
  42. package/dist/{email-Bo6G9LOZ.mjs → email-CdnhUHvJ.mjs} +15 -30
  43. package/dist/{env-BYOrWQnv.mjs → env-DmGdHi5i.mjs} +8 -8
  44. package/dist/{env-public-BxU_0yTL.d.mts → env-public-BX_r8HR6.d.mts} +1 -1
  45. package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
  46. package/dist/{env-validation-BB4GkLxn.mjs → env-validation-C_8tPdhs.mjs} +20 -73
  47. package/dist/{env-validation-BXge7uyK.mjs → env-validation-zZOCcQVZ.mjs} +1 -1
  48. package/dist/{fetch-CXDChK7B.mjs → fetch-BIZJh7vR.mjs} +2 -2
  49. package/dist/{fetch-stream-AOByI7Ki.mjs → fetch-stream-IvCYKyQL.mjs} +24 -4
  50. package/dist/{gen-sCtlCOdA.mjs → gen-CshAkukR.mjs} +4 -4
  51. package/dist/gen-DvQTWzDU.mjs +2 -0
  52. package/dist/{github-cmd-0-7PexDq.mjs → github-cmd-DftuEvIt.mjs} +13 -13
  53. package/dist/{handler-HEcZsaij.d.mts → handler-CZ4nAylQ.d.mts} +1 -1
  54. package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
  55. package/dist/{help-GKtwl07I.mjs → help-Dotbf6iz.mjs} +236 -750
  56. package/dist/help-mabuIV98.mjs +2 -0
  57. package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
  58. package/dist/index.d.mts +1 -1
  59. package/dist/index.mjs +299 -1517
  60. package/dist/info-B97bTX9N.mjs +113 -0
  61. package/dist/{init-FZx3Elvz.mjs → init-BTQEZZGJ.mjs} +61 -27
  62. package/dist/limits-Bq5LG8Id.d.mts +27 -0
  63. package/dist/limits-Cjuk2VPm.mjs +68 -0
  64. package/dist/{link-BrQfb_CU.mjs → link-B46sYH0K.mjs} +6 -6
  65. package/dist/{list-D44jmIAM.mjs → list-BnPrIsU_.mjs} +6 -6
  66. package/dist/{live-CKJlvlNp.d.mts → live-Chw1eIMv.d.mts} +1 -1
  67. package/dist/{local-d1-Bg9OzEEO.mjs → local-d1-2CMnpuW_.mjs} +2 -2
  68. package/dist/log-vqY3pqwI.mjs +29 -0
  69. package/dist/{login-CAsAsQ-_.mjs → login-BuiMyUrx.mjs} +8 -8
  70. package/dist/login-DIy9Sb-U.mjs +2 -0
  71. package/dist/{logs-BjKvFnVM.mjs → logs-CZG9d-ic.mjs} +10 -11
  72. package/dist/migrate-BCiJ8w0f.mjs +2 -0
  73. package/dist/{migrate-BPITvDJN.mjs → migrate-q4_njtaW.mjs} +4 -3
  74. package/dist/{node-Dt7z256D.mjs → node-BkyRWRx8.mjs} +1 -1
  75. package/dist/operator-args-B3BTmSoi.mjs +697 -0
  76. package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-7erYc6Lt.mjs} +2 -2
  77. package/dist/{operator-client-DUwumHpQ.mjs → operator-client-CpHjTd0t.mjs} +3 -3
  78. package/dist/{operator-cmd-BK5CCiT9.mjs → operator-cmd-DGqPJUD3.mjs} +70 -24
  79. package/dist/{output-Dm_A4Tbv.mjs → output-CbM85T4k.mjs} +18 -10
  80. package/dist/pages/client.d.mts +34 -2
  81. package/dist/pages/client.mjs +59 -3
  82. package/dist/pages/index.d.mts +1 -1
  83. package/dist/pages/index.mjs +2 -2
  84. package/dist/pages/islands-plugin.mjs +1 -1
  85. package/dist/pages/protocol.d.mts +2 -2
  86. package/dist/pages/protocol.mjs +2 -308
  87. package/dist/{parse-filename-DioPHiR9.mjs → parse-filename-CUbj-1MP.mjs} +35 -1
  88. package/dist/plan-D1Q5rf-r.mjs +2 -0
  89. package/dist/plan-NPpwZ_kc.mjs +58 -0
  90. package/dist/platform-args-3k8X9-H_.mjs +514 -0
  91. package/dist/platform-args-DdnM6WIf.mjs +2 -0
  92. package/dist/{platform-auth-config-BlN8xTdD.mjs → platform-auth-config-DDrxUy4m.mjs} +6 -6
  93. package/dist/{platform-auth-protection-7d5aV2Jg.mjs → platform-auth-protection-BLadnnct.mjs} +8 -8
  94. package/dist/{platform-auth-recovery-Dxij8ZbR.mjs → platform-auth-recovery-CmCzX2Fl.mjs} +6 -6
  95. package/dist/{platform-cmd-B3hwKrFK.mjs → platform-cmd-DMDEc9uS.mjs} +29 -8
  96. package/dist/{platform-cmd-E0FuL212.mjs → platform-cmd-pMTRhvYs.mjs} +1 -1
  97. package/dist/{platform-domain-D6Xcy9ZX.mjs → platform-domain-Di6EYrQl.mjs} +5 -5
  98. package/dist/{platform-lifecycle-k0E0xoxx.mjs → platform-lifecycle-BBoNzojY.mjs} +1541 -572
  99. package/dist/{platform-lifecycle-DMh_qrry.mjs → platform-lifecycle-BFdSi9Qt.mjs} +1 -1
  100. package/dist/{platform-management-Brz_BDiT.mjs → platform-management-CWOQOWXm.mjs} +10 -7
  101. package/dist/{platform-management-DOtss0BN.mjs → platform-management-DG47jys8.mjs} +1 -1
  102. package/dist/platform-plans-config-Vl9BP3H4.mjs +359 -0
  103. package/dist/{platform-recovery-BvtcXON5.mjs → platform-recovery-BJnQJEtQ.mjs} +4 -4
  104. package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-DkPPXfp_.mjs} +2 -2
  105. package/dist/{plugin-inference-BMfKRSqE.mjs → plugin-inference-CXWnn79A.mjs} +174 -64
  106. package/dist/{prepare-C-6YZyyg.mjs → prepare-CBLT3CHH.mjs} +3 -3
  107. package/dist/prepare-CnjcTV2s.mjs +2 -0
  108. package/dist/{prepare-CRhJbVrG.mjs → prepare-DnaKBi--.mjs} +5 -21
  109. package/dist/{project-C0Fqu05O.mjs → project-DKG5Ra8p.mjs} +15 -82
  110. package/dist/project-DsblYifa.mjs +2 -0
  111. package/dist/{project-cmd-BZLCqOqw.mjs → project-cmd-DxnXstAq.mjs} +19 -19
  112. package/dist/{project-team-BvgM0WoX.mjs → project-team-BmHcaALJ.mjs} +5 -5
  113. package/dist/{project-token-l5DqK6Az.mjs → project-token-GionZlBI.mjs} +5 -5
  114. package/dist/{project-zero-trust-v6Mvpp8y.mjs → project-zero-trust-JLCjVQA7.mjs} +5 -5
  115. package/dist/prompts-2TGE6oXx.mjs +2 -0
  116. package/dist/prompts-BNUoTiaf.mjs +2044 -0
  117. package/dist/{protocol-BBa6cstI.d.mts → protocol-CjF_iI9X.d.mts} +2 -2
  118. package/dist/protocol-U7bfjHmA.mjs +331 -0
  119. package/dist/{provision-Fr9pRqce.mjs → provision-CVku1JFU.mjs} +1 -1
  120. package/dist/{provision-C4IGqkBf.mjs → provision-CaoxO_U7.mjs} +90 -199
  121. package/dist/{requests-DN-BbNiM.mjs → requests-BOjIVAeF.mjs} +5 -5
  122. package/dist/resource-name-C7LVpcRm.mjs +11 -0
  123. package/dist/{rollback-D7rzSaZM.mjs → rollback-CwR3pLj3.mjs} +6 -6
  124. package/dist/route-url-CG7U-cRN.mjs +15 -0
  125. package/dist/{runner-B8wXwWlo.mjs → runner-CXA9Fh8h.mjs} +1 -1
  126. package/dist/{runner-p-dMs2UN.mjs → runner-Ol0TNjk6.mjs} +2 -2
  127. package/dist/runtime/ai.d.mts +12 -8
  128. package/dist/runtime/ai.mjs +87 -22
  129. package/dist/runtime/better-auth-mysql.mjs +1 -1
  130. package/dist/runtime/better-auth-pg.mjs +1 -1
  131. package/dist/runtime/better-auth.mjs +1 -1
  132. package/dist/runtime/client-react.mjs +2 -2
  133. package/dist/runtime/client-solid.mjs +2 -2
  134. package/dist/runtime/client-svelte.mjs +2 -2
  135. package/dist/runtime/client-vue.mjs +2 -2
  136. package/dist/runtime/client.mjs +2 -2
  137. package/dist/runtime/durable.d.mts +3 -1
  138. package/dist/runtime/durable.mjs +4 -1
  139. package/dist/runtime/email/testing.mjs +2 -2
  140. package/dist/runtime/email.mjs +1 -1
  141. package/dist/runtime/env-public.d.mts +1 -1
  142. package/dist/runtime/fetch-stream.mjs +1 -1
  143. package/dist/runtime/fetch.mjs +1 -1
  144. package/dist/runtime/handler.d.mts +1 -1
  145. package/dist/runtime/kv.mjs +0 -1
  146. package/dist/runtime/limits.d.mts +2 -0
  147. package/dist/runtime/limits.mjs +2 -0
  148. package/dist/runtime/live-client.d.mts +1 -1
  149. package/dist/runtime/live-server.mjs +25 -16
  150. package/dist/runtime/live.d.mts +1 -1
  151. package/dist/runtime/migration-handler.mjs +62 -42
  152. package/dist/runtime/remote/index.mjs +2 -2
  153. package/dist/runtime/route-url.d.mts +4 -0
  154. package/dist/runtime/route-url.mjs +2 -0
  155. package/dist/runtime/routing.d.mts +180 -0
  156. package/dist/runtime/routing.mjs +1082 -0
  157. package/dist/runtime/sandbox-container.d.mts +1 -1
  158. package/dist/runtime/sandbox-container.mjs +1 -1
  159. package/dist/runtime/sandbox.d.mts +3 -3
  160. package/dist/runtime/sandbox.mjs +75 -45
  161. package/dist/runtime/sse.mjs +1 -1
  162. package/dist/runtime/validator.d.mts +1 -1
  163. package/dist/runtime/ws-server.d.mts +4 -2
  164. package/dist/runtime/ws-server.mjs +27 -2
  165. package/dist/runtime/ws.d.mts +2 -2
  166. package/dist/runtime/ws.mjs +8 -6
  167. package/dist/{sandbox-qpNBT8a3.d.mts → sandbox-XZAqzFlG.d.mts} +11 -8
  168. package/dist/{sandbox-container-DdNEBfCc.d.mts → sandbox-container-Bo0eiFKz.d.mts} +2 -1
  169. package/dist/{sandbox-container-4fdqLnyb.mjs → sandbox-container-C6ItmVuN.mjs} +4 -2
  170. package/dist/{scan-4tfN-PSn.mjs → scan-C7okrLyM.mjs} +4 -35
  171. package/dist/{secret-BOtOl_cb.mjs → secret-ByWJWBUG.mjs} +7 -7
  172. package/dist/{skills-D1II1Juz.mjs → skills-C1PlclPt.mjs} +1 -1
  173. package/dist/{sse-BaC1jXko.mjs → sse-CQNaDFFV.mjs} +6 -3
  174. package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-klFCfcor.mjs} +40 -32
  175. package/dist/validate-Dq_L3s0S.mjs +2 -0
  176. package/dist/{validate-CIUwFpjB.mjs → validate-ctOrgiS3.mjs} +2 -1
  177. package/dist/{wrangler-DQF1vKyf.mjs → wrangler-7K-bW_DL.mjs} +8 -239
  178. package/dist/{ws-BoY7vQML.d.mts → ws-CL1w7GXU.d.mts} +13 -2
  179. package/package.json +16 -10
  180. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +34 -157
  181. package/skills/void/SKILL.md +55 -135
  182. package/skills/void/docs/guide/ai.md +94 -84
  183. package/skills/void/docs/guide/app-types.md +3 -32
  184. package/skills/void/docs/guide/auth.md +12 -116
  185. package/skills/void/docs/guide/database/d1.md +9 -54
  186. package/skills/void/docs/guide/database/mysql.md +1 -1
  187. package/skills/void/docs/guide/database/postgresql.md +5 -26
  188. package/skills/void/docs/guide/database.md +23 -75
  189. package/skills/void/docs/guide/deployment.md +48 -112
  190. package/skills/void/docs/guide/durable-state.md +43 -18
  191. package/skills/void/docs/guide/edge/headers.md +4 -48
  192. package/skills/void/docs/guide/edge/prerendering.md +5 -20
  193. package/skills/void/docs/guide/edge/redirects.md +11 -64
  194. package/skills/void/docs/guide/edge/revalidation.md +5 -18
  195. package/skills/void/docs/guide/edge/rewrites.md +56 -284
  196. package/skills/void/docs/guide/edge/static-assets.md +22 -72
  197. package/skills/void/docs/guide/email/domains.md +116 -0
  198. package/skills/void/docs/guide/email/receiving.md +139 -0
  199. package/skills/void/docs/guide/email/sending.md +231 -0
  200. package/skills/void/docs/guide/email.md +13 -619
  201. package/skills/void/docs/guide/env-migration.md +11 -11
  202. package/skills/void/docs/guide/env-vars.md +9 -29
  203. package/skills/void/docs/guide/index.md +0 -15
  204. package/skills/void/docs/guide/jobs.md +3 -18
  205. package/skills/void/docs/guide/kv.md +5 -11
  206. package/skills/void/docs/guide/live.md +5 -56
  207. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +78 -125
  208. package/skills/void/docs/guide/pages-routing/head.md +10 -10
  209. package/skills/void/docs/guide/pages-routing/islands.md +6 -36
  210. package/skills/void/docs/guide/pages-routing/layouts.md +6 -128
  211. package/skills/void/docs/guide/pages-routing/loaders.md +3 -19
  212. package/skills/void/docs/guide/pages-routing/markdown.md +13 -171
  213. package/skills/void/docs/guide/pages-routing/overview.md +7 -17
  214. package/skills/void/docs/guide/pages-routing/view-transitions.md +1 -1
  215. package/skills/void/docs/guide/platform/administration/access.md +1 -4
  216. package/skills/void/docs/guide/platform/administration/email.md +35 -8
  217. package/skills/void/docs/guide/platform/administration/operations.md +26 -4
  218. package/skills/void/docs/guide/platform/administration/plans.md +126 -0
  219. package/skills/void/docs/guide/platform/administration/projects.md +5 -2
  220. package/skills/void/docs/guide/platform/administration/zero-trust.md +49 -160
  221. package/skills/void/docs/guide/platform/development/runtime.md +3 -13
  222. package/skills/void/docs/guide/platform/development/schema-ci.md +0 -58
  223. package/skills/void/docs/guide/platform/installation/ci.md +1 -1
  224. package/skills/void/docs/guide/platform/installation/credentials.md +15 -6
  225. package/skills/void/docs/guide/platform/installation/domains.md +35 -2
  226. package/skills/void/docs/guide/platform/installation/first-deployment.md +4 -2
  227. package/skills/void/docs/guide/platform/installation/maintenance.md +15 -1
  228. package/skills/void/docs/guide/platform/installation/prerequisites.md +24 -18
  229. package/skills/void/docs/guide/platform/installation/setup.md +88 -14
  230. package/skills/void/docs/guide/platform-administration.md +1 -0
  231. package/skills/void/docs/guide/queues.md +7 -9
  232. package/skills/void/docs/guide/quickstart.md +38 -37
  233. package/skills/void/docs/guide/remote-dev.md +5 -10
  234. package/skills/void/docs/guide/sandboxes.md +29 -21
  235. package/skills/void/docs/guide/server-routing.md +9 -72
  236. package/skills/void/docs/guide/sse.md +4 -18
  237. package/skills/void/docs/guide/ssg.md +3 -15
  238. package/skills/void/docs/guide/ssr.md +14 -62
  239. package/skills/void/docs/guide/storage.md +9 -4
  240. package/skills/void/docs/guide/type-safety.md +3 -14
  241. package/skills/void/docs/guide/typed-fetch.md +3 -7
  242. package/skills/void/docs/guide/websockets.md +68 -40
  243. package/skills/void/docs/integrations/agents.md +3 -3
  244. package/skills/void/docs/integrations/cloudflare.md +85 -316
  245. package/skills/void/docs/integrations/frameworks/analog.md +5 -64
  246. package/skills/void/docs/integrations/frameworks/astro.md +4 -73
  247. package/skills/void/docs/integrations/frameworks/nuxt.md +5 -62
  248. package/skills/void/docs/integrations/frameworks/overview.md +11 -54
  249. package/skills/void/docs/integrations/frameworks/react-router.md +5 -60
  250. package/skills/void/docs/integrations/frameworks/sveltekit.md +6 -65
  251. package/skills/void/docs/integrations/frameworks/tanstack-start.md +4 -62
  252. package/skills/void/docs/integrations/nodejs-bun-deno.md +5 -69
  253. package/skills/void/docs/reference/api/auth.md +156 -0
  254. package/skills/void/docs/reference/api/client.md +87 -0
  255. package/skills/void/docs/reference/api/database.md +95 -0
  256. package/skills/void/docs/reference/api/durable.md +46 -0
  257. package/skills/void/docs/reference/api/env.md +50 -0
  258. package/skills/void/docs/reference/api/handlers.md +254 -0
  259. package/skills/void/docs/reference/api/pages.md +241 -0
  260. package/skills/void/docs/reference/api/plugin.md +39 -0
  261. package/skills/void/docs/reference/api/resources.md +109 -0
  262. package/skills/void/docs/reference/api/rewrites.md +76 -0
  263. package/skills/void/docs/reference/api/types.md +92 -0
  264. package/skills/void/docs/reference/api.md +56 -1218
  265. package/skills/void/docs/reference/cli/auth.md +89 -0
  266. package/skills/void/docs/reference/cli/database.md +128 -0
  267. package/skills/void/docs/reference/cli/deploy.md +105 -0
  268. package/skills/void/docs/reference/cli/domains.md +41 -0
  269. package/skills/void/docs/reference/cli/email.md +129 -0
  270. package/skills/void/docs/reference/cli/generate.md +116 -0
  271. package/skills/void/docs/reference/cli/github.md +189 -0
  272. package/skills/void/docs/reference/cli/platform-config.md +92 -0
  273. package/skills/void/docs/reference/cli/platform-email.md +81 -0
  274. package/skills/void/docs/reference/cli/platform-installation.md +142 -0
  275. package/skills/void/docs/reference/cli/platform-operations.md +90 -0
  276. package/skills/void/docs/reference/cli/platform-users.md +89 -0
  277. package/skills/void/docs/reference/cli/platform-zero-trust.md +59 -0
  278. package/skills/void/docs/reference/cli/platform.md +70 -0
  279. package/skills/void/docs/reference/cli/project.md +214 -0
  280. package/skills/void/docs/reference/cli/secrets.md +76 -0
  281. package/skills/void/docs/reference/cli/setup.md +70 -0
  282. package/skills/void/docs/reference/cli.md +32 -1682
  283. package/skills/void/docs/reference/config.md +12 -18
  284. package/skills/void/docs/reference/resource-inference.md +3 -58
  285. package/skills/void/docs/reference/structure.md +14 -41
  286. package/dist/auth-CZuiVsFh.mjs +0 -2
  287. package/dist/canonical-json-DuDiiUsQ.mjs +0 -13
  288. package/dist/client-Czz8o5jP.mjs +0 -2
  289. package/dist/dist-BuDuKZJv.mjs +0 -2
  290. package/dist/dist-CTBk70IR.mjs +0 -1310
  291. package/dist/gen-CNJ62MM7.mjs +0 -2
  292. package/dist/help-CmZzxUba.mjs +0 -2
  293. package/dist/log-ChfPKsVd.mjs +0 -26
  294. package/dist/login-CGcRKEoi.mjs +0 -2
  295. package/dist/migrate-CYfbKkXh.mjs +0 -2
  296. package/dist/plan-BEZ8VJW0.mjs +0 -256
  297. package/dist/plan-DpuOr14e.mjs +0 -2
  298. package/dist/prepare-Bm3iq-u4.mjs +0 -2
  299. package/dist/project-BuUwfj6f.mjs +0 -2
  300. package/dist/validate-EKmJWxmy.mjs +0 -2
  301. /package/dist/cli/{cf-compat.d.mts → cloudflare-operation-process.d.mts} +0 -0
@@ -2,14 +2,12 @@
2
2
  import { n as __toESM } from "../rolldown-runtime-DXIUcv95.mjs";
3
3
  import { a as join, n as dirname, u as resolve } from "../dist-BVqXeR_h.mjs";
4
4
  import { t as require_picocolors } from "../picocolors-BTps1_gs.mjs";
5
- import { t as prepareCfBuildOutput } from "../cf-build-output-BJ6yGEIS.mjs";
6
5
  import { copyFileSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7
6
  import { fileURLToPath } from "node:url";
8
7
  import { tmpdir } from "node:os";
9
8
  import { spawn, spawnSync } from "node:child_process";
10
9
  import { parse } from "jsonc-parser";
11
10
  import { stripVTControlCharacters } from "node:util";
12
- import { readBuildOutput } from "@cloudflare/build-output-utils";
13
11
  import { EnvHttpProxyAgent, fetch as fetch$1 } from "undici";
14
12
  import { getCloudflareAuthUseKeyringFromEnv } from "@cloudflare/workers-auth";
15
13
  import { createCfAuth, createCfProfileStore, readUserPreferences, setKeyringPreference } from "@cloudflare/workers-auth/cf";
@@ -62,18 +60,26 @@ function cloudflareDeviceCode(output) {
62
60
  const plain = stripVTControlCharacters(output);
63
61
  return /and enter the code:\s*([A-Za-z0-9-]+)\s/i.exec(plain)?.[1] ?? /[?&]user_code=([A-Za-z0-9-]+)\s/i.exec(plain)?.[1] ?? null;
64
62
  }
63
+ function cloudflareVerificationUrl(output) {
64
+ const plain = stripVTControlCharacters(output);
65
+ return /(?:Opening a link in your default browser:|Visit this link to authenticate:)\s*(https?:\/\/\S+)\s/i.exec(plain)?.[1] ?? /please visit:\s*(https?:\/\/\S+)\s/i.exec(plain)?.[1] ?? null;
66
+ }
67
+ function printCloudflareLoginLink(url) {
68
+ console.log(`Open this link if your browser did not open: ${url}`);
69
+ }
65
70
  function printCloudflareLoginPrompt(code) {
66
71
  console.log(code ? `Opening Cloudflare login in your browser. Confirm the code ${import_picocolors.default.blue(code)} in your browser. Press Ctrl+C to cancel.` : "Opening Cloudflare login in your browser. Confirm the code shown in your browser. Press Ctrl+C to cancel.");
67
72
  }
68
73
  //#endregion
69
- //#region src/cli/cf-compat.ts
70
- /**
71
- * Private transport for the existing Void Cloudflare command seams. The
72
- * orchestrators still use their established argument/result contracts; this
73
- * process translates them to the pinned cf CLI. It never invokes Wrangler.
74
- */
74
+ //#region src/cli/cloudflare-operation-process.ts
75
75
  const cf = join(dirname(fileURLToPath(import.meta.resolve("cf/package.json"))), "bin", "cf");
76
- const args = process.argv.slice(2);
76
+ const operation = (() => {
77
+ try {
78
+ return JSON.parse(process.argv[2] ?? "null");
79
+ } catch {
80
+ return null;
81
+ }
82
+ })();
77
83
  process.env.CLOUDFLARE_AUTH_USE_KEYRING ??= "true";
78
84
  function cfEnvironment() {
79
85
  const env = {
@@ -92,14 +98,23 @@ function cfEnvironment() {
92
98
  ]) if (!env[canonical] && env[alias]) env[canonical] = env[alias];
93
99
  return env;
94
100
  }
95
- function result(status, stdout = "", stderr = "") {
101
+ function result(status, stdout = "", stderr = "", data) {
102
+ const code = /\[(?:code:\s*)?(\d{4,})\]/.exec(stderr);
103
+ const errorCode = code ? Number(code[1]) : void 0;
96
104
  return {
97
105
  status,
98
106
  stdout,
99
- stderr
107
+ stderr,
108
+ ...data !== void 0 ? { data } : {},
109
+ ...errorCode ? { errorCode } : {},
110
+ ...[
111
+ 10006,
112
+ 10007,
113
+ 10090
114
+ ].includes(errorCode ?? 0) ? { failure: "not-found" } : {}
100
115
  };
101
116
  }
102
- function runCf(command, cwd = process.cwd()) {
117
+ function runCf(command, cwd = process.cwd(), bounds) {
103
118
  const env = cfEnvironment();
104
119
  env.CF_QUIET = "1";
105
120
  const child = spawnSync(process.execPath, [cf, ...command], {
@@ -108,7 +123,8 @@ function runCf(command, cwd = process.cwd()) {
108
123
  encoding: "utf8",
109
124
  shell: false,
110
125
  windowsHide: true,
111
- maxBuffer: 33554432,
126
+ maxBuffer: bounds?.maxOutputBytes ?? 33554432,
127
+ ...bounds ? { timeout: bounds.timeoutMs } : {},
112
128
  stdio: [
113
129
  "ignore",
114
130
  "pipe",
@@ -120,7 +136,14 @@ function runCf(command, cwd = process.cwd()) {
120
136
  child.error?.message || "",
121
137
  child.signal ? `Cloudflare CLI terminated by ${child.signal}.` : ""
122
138
  ].filter(Boolean).join("\n").replace(/\[(\d{4,})\]/g, "[code: $1]");
123
- return result(child.status ?? 1, child.stdout ?? "", stderr);
139
+ if (child.signal || child.error || child.status === null) return {
140
+ status: 1,
141
+ stdout: "",
142
+ stderr,
143
+ signal: child.signal,
144
+ error: child.error?.message ?? (child.signal ? void 0 : "Cloudflare CLI did not report an exit status.")
145
+ };
146
+ return result(child.status, child.stdout ?? "", stderr);
124
147
  }
125
148
  function runInteractiveCf(command) {
126
149
  return new Promise((resolve) => {
@@ -144,6 +167,7 @@ function runInteractiveCf(command) {
144
167
  });
145
168
  let output = "";
146
169
  let announced = false;
170
+ let announcedLink = false;
147
171
  let settled = false;
148
172
  const finish = (value) => {
149
173
  if (!settled) {
@@ -160,6 +184,13 @@ function runInteractiveCf(command) {
160
184
  printCloudflareLoginPrompt(code);
161
185
  }
162
186
  }
187
+ if (!announcedLink) {
188
+ const url = cloudflareVerificationUrl(output);
189
+ if (url) {
190
+ announcedLink = true;
191
+ printCloudflareLoginLink(url);
192
+ }
193
+ }
163
194
  };
164
195
  child.stdout.on("data", collect);
165
196
  child.stderr.on("data", collect);
@@ -177,7 +208,10 @@ async function withBuildOutput(raw, sourceMain, action) {
177
208
  try {
178
209
  const main = "index.js";
179
210
  if (sourceMain) copyFileSync(sourceMain, join(scratch, main));
180
- else writeFileSync(join(scratch, main), "export default { fetch() { return new Response(\"\"); } };\n");
211
+ else {
212
+ const { VOID_SECRET_DRAFT_SOURCE } = await import("@void/deploy-cloudflare");
213
+ writeFileSync(join(scratch, main), VOID_SECRET_DRAFT_SOURCE);
214
+ }
181
215
  writeFileSync(join(scratch, "wrangler.json"), JSON.stringify({
182
216
  ...raw,
183
217
  main,
@@ -185,6 +219,7 @@ async function withBuildOutput(raw, sourceMain, action) {
185
219
  }), { mode: 384 });
186
220
  const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? raw.account_id;
187
221
  if (typeof accountId !== "string" || !accountId) throw new Error("Cloudflare account is not pinned for Worker deployment.");
222
+ const { prepareCfBuildOutput } = await import("../cf-build-output-_0HNWysu.mjs");
188
223
  const output = await prepareCfBuildOutput(scratch, accountId);
189
224
  if (!output) throw new Error("Could not prepare the Cloudflare Worker build output.");
190
225
  try {
@@ -207,12 +242,8 @@ function object(value) {
207
242
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Cloudflare returned an unexpected response.");
208
243
  return value;
209
244
  }
210
- function field(name) {
211
- const index = args.indexOf(name);
212
- return index >= 0 ? args[index + 1] : void 0;
213
- }
214
245
  function configPath() {
215
- return field("-c") ?? field("--config");
246
+ return "configPath" in operation ? operation.configPath : void 0;
216
247
  }
217
248
  function config() {
218
249
  const path = configPath();
@@ -220,7 +251,7 @@ function config() {
220
251
  return object(parse(readFileSync(path, "utf8")));
221
252
  }
222
253
  function workerName() {
223
- const name = field("--name") ?? config().name;
254
+ const name = ("workerName" in operation ? operation.workerName : void 0) ?? config().name;
224
255
  if (typeof name !== "string" || !name) throw new Error("Cloudflare Worker name is missing from the generated config.");
225
256
  return name;
226
257
  }
@@ -336,6 +367,7 @@ async function clearWorkerCustomDomains(worker) {
336
367
  }
337
368
  }
338
369
  async function assertExistingProvisionableResources(directory, account) {
370
+ const { readBuildOutput } = await import("@cloudflare/build-output-utils");
339
371
  const bindings = (await readBuildOutput(directory)).workers.default.config.env ?? {};
340
372
  const queueNames = /* @__PURE__ */ new Set();
341
373
  const accountPath = `/accounts/${encodeURIComponent(account)}`;
@@ -415,7 +447,7 @@ async function sessionCredential() {
415
447
  } : null;
416
448
  }
417
449
  async function auth() {
418
- if (args[0] === "login") {
450
+ if (operation.type === "auth.login") {
419
451
  const loggedIn = await runInteractiveCf([
420
452
  "auth",
421
453
  "login",
@@ -424,26 +456,24 @@ async function auth() {
424
456
  if (loggedIn.status === 0) persistCfKeyringPreference(process.cwd());
425
457
  return loggedIn;
426
458
  }
427
- if (args[0] === "logout") return runCf(["auth", "logout"]);
428
- if (args[0] === "whoami") {
459
+ if (operation.type === "auth.logout") return runCf(["auth", "logout"]);
460
+ if (operation.type === "auth.whoami") {
429
461
  const called = runCf(["auth", "whoami"]);
430
462
  if (called.status !== 0) return called;
431
463
  const identity = object(parsedJson(called.stdout));
432
- if (identity.authenticated !== true || identity.tokenValid !== true) return result(1, JSON.stringify({ loggedIn: false }), "Cloudflare authentication is required.");
464
+ if (identity.authenticated !== true || identity.tokenValid !== true) return result(1, "", "Cloudflare authentication is required.", { loggedIn: false });
433
465
  if (String(identity.authSource).startsWith("OAuth token from ")) persistCfKeyringPreference(process.cwd());
434
- return result(0, JSON.stringify({
466
+ return result(0, "", called.stderr, {
435
467
  loggedIn: true,
436
468
  accounts: identity.accounts,
437
469
  email: identity.email,
438
470
  tokenPermissions: identity.scopes,
439
471
  authType: process.env.CLOUDFLARE_API_KEY || process.env.CF_API_KEY ? "Global API Key" : String(identity.authSource).startsWith("OAuth token") ? "OAuth Token" : "API Token"
440
- }), called.stderr);
441
- }
442
- if (args[0] === "auth" && args[1] === "token") {
443
- const credential = await sessionCredential();
444
- return credential ? result(0, `${JSON.stringify(credential)}\n`) : result(1, "", "Cloudflare session has no OAuth bearer.");
472
+ });
445
473
  }
446
- return result(1, "", "Unsupported Cloudflare authentication operation.");
474
+ if (operation.type !== "auth.token") throw new Error("Unsupported Cloudflare authentication operation.");
475
+ const credential = await sessionCredential();
476
+ return credential ? result(0, "", "", credential) : result(1, "", "Cloudflare session has no OAuth bearer.");
447
477
  }
448
478
  function listAllResourcePages(command, extraFlags = []) {
449
479
  const pageSize = 100;
@@ -484,152 +514,158 @@ async function readAllQueues() {
484
514
  throw new Error("Cloudflare Queue list exceeded the supported page limit.");
485
515
  }
486
516
  async function resources() {
487
- const [group, verb, third] = args;
488
- if (group === "d1" && verb === "execute" && third) {
489
- const database = d1Database(third);
490
- const sql = field("--command");
491
- if (!sql) throw new Error("D1 SQL command is missing.");
492
- return runCf([
517
+ switch (operation.type) {
518
+ case "d1.execute": return runCf([
493
519
  "d1",
494
520
  "query",
495
- database.id,
521
+ d1Database(operation.database).id,
496
522
  "--sql",
497
- sql
523
+ operation.sql
498
524
  ]);
499
- }
500
- if (group === "d1" && verb === "migrations" && (third === "list" || third === "apply")) {
501
- const token = args[3];
502
- if (!token) throw new Error("D1 migration target is missing.");
503
- const database = d1Database(token);
504
- const called = runCf([
505
- "d1",
506
- "migrations",
507
- third,
508
- database.id,
509
- "--dir",
510
- database.dir,
511
- ...database.pattern ? ["--pattern", database.pattern] : [],
512
- "--table",
513
- database.table
514
- ]);
515
- if (called.status !== 0 || third !== "list") return called;
516
- const pending = parsedJson(called.stdout);
517
- if (!Array.isArray(pending)) throw new Error("D1 migration list was malformed.");
518
- return result(0, pending.length ? `Migrations to be applied:\n${pending.map((item) => object(item).Name).join("\n")}\n` : "No migrations to apply!\n");
519
- }
520
- if (group === "containers" && verb === "list") return runCf([
521
- "containers",
522
- "applications",
523
- "list"
524
- ]);
525
- if (group === "d1" && verb === "list") return listAllResourcePages(["d1", "list"]);
526
- if (group === "d1" && verb === "info" && third) {
527
- const listed = listAllResourcePages(["d1", "list"]);
528
- if (listed.status !== 0) return listed;
529
- const value = parsedJson(listed.stdout);
530
- if (!Array.isArray(value)) throw new Error("D1 list was malformed.");
531
- const selected = value.find((item) => object(item).name === third) ?? null;
532
- return selected === null ? result(1, "", `D1 database ${JSON.stringify(third)} does not exist.`) : result(0, `${JSON.stringify(selected)}\n`);
533
- }
534
- if (group === "d1" && verb === "create" && third) {
535
- const created = runCf([
536
- "d1",
537
- "create",
538
- "--name",
539
- third
525
+ case "d1.migrations.list":
526
+ case "d1.migrations.apply": {
527
+ const database = d1Database(operation.database);
528
+ const verb = operation.type === "d1.migrations.list" ? "list" : "apply";
529
+ const called = runCf([
530
+ "d1",
531
+ "migrations",
532
+ verb,
533
+ database.id,
534
+ "--dir",
535
+ database.dir,
536
+ ...database.pattern ? ["--pattern", database.pattern] : [],
537
+ "--table",
538
+ database.table
539
+ ]);
540
+ if (called.status !== 0 || verb !== "list") return called;
541
+ const pending = parsedJson(called.stdout);
542
+ if (!Array.isArray(pending) || pending.some((item) => typeof object(item).Name !== "string")) throw new Error("D1 migration list was malformed.");
543
+ return result(0, "", called.stderr, { pending: pending.map((item) => object(item).Name) });
544
+ }
545
+ case "containers.list": return runCf([
546
+ "containers",
547
+ "applications",
548
+ "list"
540
549
  ]);
541
- if (created.status !== 0) return created;
542
- const database = object(parsedJson(created.stdout));
543
- if (typeof database.uuid !== "string") throw new Error("D1 creation returned no database ID.");
544
- updateBinding("d1_databases", field("--binding") ?? "", {
545
- database_name: third,
546
- database_id: database.uuid
547
- });
548
- return created;
549
- }
550
- if (group === "kv" && verb === "namespace" && third === "list") return listAllResourcePages([
551
- "kv",
552
- "namespaces",
553
- "list"
554
- ], [
555
- "--order",
556
- "id",
557
- "--direction",
558
- "asc"
559
- ]);
560
- if (group === "kv" && verb === "namespace" && third === "create" && args[3]) {
561
- const created = runCf([
550
+ case "d1.list": return listAllResourcePages(["d1", "list"]);
551
+ case "d1.info": {
552
+ const listed = listAllResourcePages(["d1", "list"]);
553
+ if (listed.status !== 0) return listed;
554
+ const list = parsedJson(listed.stdout);
555
+ if (!Array.isArray(list)) throw new Error("D1 list was malformed.");
556
+ const value = list.find((item) => object(item).name === operation.name);
557
+ return value === void 0 ? {
558
+ ...result(1, "", "D1 database does not exist."),
559
+ failure: "not-found"
560
+ } : result(0, "", "", value);
561
+ }
562
+ case "d1.create": {
563
+ const created = runCf([
564
+ "d1",
565
+ "create",
566
+ "--name",
567
+ operation.name
568
+ ]);
569
+ if (created.status !== 0) return created;
570
+ const database = object(parsedJson(created.stdout));
571
+ if (typeof database.uuid !== "string") throw new Error("D1 creation returned no database ID.");
572
+ updateBinding("d1_databases", operation.binding, {
573
+ database_name: operation.name,
574
+ database_id: database.uuid
575
+ });
576
+ return created;
577
+ }
578
+ case "kv.namespace.list": return listAllResourcePages([
562
579
  "kv",
563
580
  "namespaces",
564
- "create",
565
- "--title",
566
- args[3]
581
+ "list"
582
+ ], [
583
+ "--order",
584
+ "id",
585
+ "--direction",
586
+ "asc"
567
587
  ]);
568
- if (created.status !== 0) return created;
569
- const namespace = object(parsedJson(created.stdout));
570
- if (typeof namespace.id !== "string") throw new Error("KV creation returned no namespace ID.");
571
- updateBinding("kv_namespaces", field("--binding") ?? "", { id: namespace.id });
572
- return created;
573
- }
574
- if (group === "r2" && verb === "bucket" && third === "info" && args[3]) {
575
- const read = runCf([
588
+ case "kv.namespace.create": {
589
+ const created = runCf([
590
+ "kv",
591
+ "namespaces",
592
+ "create",
593
+ "--title",
594
+ operation.name
595
+ ]);
596
+ if (created.status !== 0) return created;
597
+ const namespace = object(parsedJson(created.stdout));
598
+ if (typeof namespace.id !== "string") throw new Error("KV creation returned no namespace ID.");
599
+ updateBinding("kv_namespaces", operation.binding, { id: namespace.id });
600
+ return created;
601
+ }
602
+ case "r2.bucket.info": return runCf([
576
603
  "r2",
577
604
  "buckets",
578
605
  "get",
579
- args[3]
606
+ operation.name
580
607
  ]);
581
- return read.status !== 0 && /\[code:\s*10006\]/.test(read.stderr) ? result(1, "", "[code: 10006] The specified bucket does not exist.") : read;
582
- }
583
- if (group === "r2" && verb === "bucket" && third === "create" && args[3]) {
584
- const created = runCf([
585
- "r2",
586
- "buckets",
587
- "create",
588
- "--name",
589
- args[3]
590
- ]);
591
- if (created.status === 0) updateBinding("r2_buckets", field("--binding") ?? "", { bucket_name: args[3] });
592
- return created;
593
- }
594
- if (group === "hyperdrive" && verb === "create" && third) {
595
- const connection = args.find((part) => part.startsWith("--connection-string="))?.slice(20);
596
- if (!connection) throw new Error("Hyperdrive connection string is missing.");
597
- const url = new URL(connection);
598
- const created = await withSecretFile(JSON.stringify({
599
- name: third,
600
- origin: {
601
- host: url.hostname,
602
- port: Number(url.port || (url.protocol.startsWith("mysql") ? 3306 : 5432)),
603
- database: decodeURIComponent(url.pathname.replace(/^\//, "")),
604
- scheme: url.protocol.replace(":", ""),
605
- user: decodeURIComponent(url.username),
606
- password: decodeURIComponent(url.password)
607
- }
608
- }), (path) => runCf([
609
- "hyperdrive",
610
- "create",
611
- "--body",
612
- `@${path}`
613
- ]));
614
- if (created.status !== 0) return result(created.status, "", "Hyperdrive creation failed.");
615
- const hyperdrive = object(parsedJson(created.stdout));
616
- if (typeof hyperdrive.id !== "string") throw new Error("Hyperdrive creation returned no ID.");
617
- updateBinding("hyperdrive", field("--binding") ?? "", { id: hyperdrive.id });
618
- return result(0, `${JSON.stringify({
619
- id: hyperdrive.id,
620
- name: third
621
- })}\n`);
622
- }
623
- if (group === "queues" && (verb === "info" || verb === "create") && third) {
624
- if (verb === "create") return runCf([
608
+ case "r2.bucket.create": {
609
+ const created = runCf([
610
+ "r2",
611
+ "buckets",
612
+ "create",
613
+ "--name",
614
+ operation.name
615
+ ]);
616
+ if (created.status === 0) updateBinding("r2_buckets", operation.binding, { bucket_name: operation.name });
617
+ return created;
618
+ }
619
+ case "hyperdrive.create": {
620
+ const url = new URL(readFileSync(0, "utf8"));
621
+ const name = operation.name;
622
+ const created = await withSecretFile(JSON.stringify({
623
+ name,
624
+ origin: {
625
+ host: url.hostname,
626
+ port: Number(url.port || (url.protocol.startsWith("mysql") ? 3306 : 5432)),
627
+ database: decodeURIComponent(url.pathname.replace(/^\//, "")),
628
+ scheme: url.protocol.replace(":", ""),
629
+ user: decodeURIComponent(url.username),
630
+ password: decodeURIComponent(url.password)
631
+ }
632
+ }), (path) => runCf([
633
+ "hyperdrive",
634
+ "create",
635
+ "--body",
636
+ "@" + path
637
+ ]));
638
+ if (created.status !== 0) return {
639
+ ...created,
640
+ stdout: "",
641
+ stderr: "Hyperdrive creation failed."
642
+ };
643
+ const hyperdrive = object(parsedJson(created.stdout));
644
+ if (typeof hyperdrive.id !== "string") throw new Error("Hyperdrive creation returned no ID.");
645
+ updateBinding("hyperdrive", operation.binding, { id: hyperdrive.id });
646
+ return result(0, "", "", {
647
+ id: hyperdrive.id,
648
+ name
649
+ });
650
+ }
651
+ case "queues.create": return runCf([
625
652
  "queues",
626
653
  "create",
627
654
  "--queue-name",
628
- third
655
+ operation.name
629
656
  ]);
630
- return (await readAllQueues()).find((item) => item.queue_name === third) ? result(0, `Queue Name: ${third}\n`) : result(1, "", `Queue "${third}" does not exist`);
657
+ case "queues.info": {
658
+ const queue = (await readAllQueues()).find((item) => item.queue_name === operation.name);
659
+ return queue ? result(0, "", "", {
660
+ id: queue.queue_id,
661
+ name: queue.queue_name
662
+ }) : {
663
+ ...result(1, "", "Cloudflare Queue does not exist."),
664
+ failure: "not-found"
665
+ };
666
+ }
667
+ default: throw new Error("Unsupported Cloudflare resource operation.");
631
668
  }
632
- return result(1, "", `Unsupported Cloudflare resource operation: ${group} ${verb}.`);
633
669
  }
634
670
  function emailZone(domain) {
635
671
  const labels = domain.split(".");
@@ -643,103 +679,67 @@ function emailZone(domain) {
643
679
  candidate
644
680
  ]);
645
681
  if (read.status === 0) return candidate;
646
- if (!/Zone not found:/.test(read.stderr)) throw new Error("Cloudflare could not resolve the Email zone.");
682
+ if (read.signal || read.error || !/Zone not found:/.test(read.stderr)) throw new Error("Cloudflare could not resolve the Email zone.");
647
683
  }
648
684
  throw new Error(`Cloudflare Email zone for ${domain} was not found.`);
649
685
  }
650
686
  function email() {
651
- const [group, product, operation, candidate] = args;
652
- if (group !== "email" || !candidate) return result(1, "", "Unsupported Cloudflare email operation.");
653
- if (product === "routing" && operation === "settings") {
654
- const read = runCf([
687
+ if (!("domain" in operation)) throw new Error("Cloudflare Email domain is missing.");
688
+ const domain = operation.domain;
689
+ switch (operation.type) {
690
+ case "email.routing.settings": {
691
+ const read = runCf([
692
+ "email-routing",
693
+ "settings",
694
+ "get",
695
+ "--zone",
696
+ domain
697
+ ]);
698
+ return read.status !== 0 && !read.signal && !read.error && /Zone not found:/.test(read.stderr) ? result(0, "", "", null) : read;
699
+ }
700
+ case "email.routing.enable": return runCf([
655
701
  "email-routing",
656
- "settings",
657
- "get",
702
+ "enable",
658
703
  "--zone",
659
- candidate
704
+ domain,
705
+ "--name",
706
+ domain
660
707
  ]);
661
- if (read.status !== 0) return /Zone not found:/.test(read.stderr) ? result(1, "", `Could not find a zone for \`${candidate}\`.`) : read;
662
- const settings = object(parsedJson(read.stdout));
663
- if (typeof settings.tag !== "string" || typeof settings.name !== "string") throw new Error("Email Routing settings were incomplete.");
664
- return result(0, `Email Routing for ${settings.name}:\n Enabled: ${settings.enabled === true}\n Status: ${settings.status}\n Tag: ${settings.tag}\n`);
665
- }
666
- if (product === "routing" && operation === "enable") return runCf([
667
- "email-routing",
668
- "enable",
669
- "--zone",
670
- candidate,
671
- "--name",
672
- candidate
673
- ]);
674
- if (product === "routing" && operation === "rules" && args[3] === "list" && args[4]) {
675
- const zone = args[4];
676
- const lines = [];
677
- for (let page = 1; page <= 100; page++) {
708
+ case "email.routing.rules.list": return listAllResourcePages([
709
+ "email-routing",
710
+ "rules",
711
+ "list-account"
712
+ ], ["--zone", domain]);
713
+ case "email.sending.settings": {
678
714
  const listed = runCf([
679
- "email-routing",
680
- "rules",
681
- "list-account",
715
+ "email-sending",
716
+ "subdomains",
717
+ "list",
682
718
  "--zone",
683
- zone,
684
- "--page",
685
- String(page),
686
- "--per-page",
687
- "100"
719
+ emailZone(domain)
688
720
  ]);
689
721
  if (listed.status !== 0) return listed;
690
- const items = parsedJson(listed.stdout);
691
- if (!Array.isArray(items)) throw new Error("Email Routing rules were malformed.");
692
- for (const entry of items.map(object)) {
693
- const actions = Array.isArray(entry.actions) ? entry.actions.map((action) => {
694
- const item = object(action);
695
- return item.type === "worker" ? `worker:${item.value}` : item.type === "forward" && Array.isArray(item.value) ? `forward:${item.value.join(",")}` : String(item.type);
696
- }) : [];
697
- const matchers = Array.isArray(entry.matchers) ? entry.matchers.map(object) : [];
698
- if (matchers.some((item) => item.type === "all")) lines.push(`Catch-all rule: ${entry.enabled === true ? "enabled" : "disabled"}, action: ${actions.join(", ")}`);
699
- else {
700
- if (typeof entry.id !== "string") throw new Error("Email Routing rule ID was missing.");
701
- const recipients = matchers.filter((item) => item.type === "literal" || item.type === "to").map((item) => `to:${item.value}`);
702
- lines.push(`Rule: ${entry.id}\n Name: ${entry.name || "(none)"}\n Enabled: ${entry.enabled === true}\n Matchers: ${recipients.join(", ")}\n Actions: ${actions.join(", ")}\n Priority: ${entry.priority ?? 0}`);
703
- }
704
- }
705
- if (items.length < 100) return result(0, lines.length ? `${lines.join("\n")}\n` : "No routing rules found.\n");
722
+ const values = parsedJson(listed.stdout);
723
+ if (!Array.isArray(values)) throw new Error("Email Sending subdomains were malformed.");
724
+ return result(0, "", "", values.map(object).find((item) => item.name === domain) ?? null);
706
725
  }
707
- throw new Error("Email Routing rules exceeded the supported page limit.");
708
- }
709
- if (product === "sending" && operation === "settings") {
710
- const listed = runCf([
726
+ case "email.sending.enable": return runCf([
711
727
  "email-sending",
712
728
  "subdomains",
713
- "list",
729
+ "create",
714
730
  "--zone",
715
- emailZone(candidate)
731
+ emailZone(domain),
732
+ "--name",
733
+ domain
716
734
  ]);
717
- if (listed.status !== 0) return listed;
718
- const values = parsedJson(listed.stdout);
719
- if (!Array.isArray(values)) throw new Error("Email Sending subdomains were malformed.");
720
- const match = values.map(object).find((item) => item.name === candidate);
721
- if (!match) return result(1, "", `No sending subdomain found for \`${candidate}\`.`);
722
- const tag = match.tag ?? match.id;
723
- if (typeof tag !== "string") throw new Error("Email Sending subdomain ID was missing.");
724
- return result(0, `Email Sending for ${candidate}:\n Enabled: ${match.enabled === true}\n Tag: ${tag}\n`);
735
+ default: throw new Error("Unsupported Cloudflare Email operation.");
725
736
  }
726
- if (product === "sending" && operation === "enable") return runCf([
727
- "email-sending",
728
- "subdomains",
729
- "create",
730
- "--zone",
731
- emailZone(candidate),
732
- "--name",
733
- candidate
734
- ]);
735
- return result(1, "", `Unsupported Cloudflare email operation: ${product} ${operation}.`);
736
737
  }
737
738
  async function secrets() {
738
739
  const worker = workerName();
739
- const verb = args[1];
740
740
  const apply = async (action) => {
741
741
  const first = action();
742
- if (first.status === 0 || !/\[code:\s*10007\]/.test(first.stderr)) return first;
742
+ if (first.status === 0 || first.errorCode !== 10007) return first;
743
743
  const draft = await withBuildOutput({
744
744
  name: worker,
745
745
  account_id: process.env.CLOUDFLARE_ACCOUNT_ID ?? config().account_id,
@@ -754,148 +754,147 @@ async function secrets() {
754
754
  ], directory));
755
755
  return draft.status === 0 ? action() : draft;
756
756
  };
757
- if (verb === "list") {
758
- const listed = runCf([
757
+ switch (operation.type) {
758
+ case "secret.list": return runCf([
759
759
  "workers",
760
760
  "secrets",
761
761
  "list",
762
762
  "--worker",
763
763
  worker
764
764
  ]);
765
- if (listed.status !== 0 && /\[code:\s*(?:10007|10090)\]/.test(listed.stderr)) return result(1, "", `Worker "${worker}" not found. [code: 10007]`);
766
- return listed;
767
- }
768
- if (verb === "put" && args[2]) {
769
- const value = readFileSync(0, "utf8").replace(/\n$/, "");
770
- return await withSecretFile(JSON.stringify({
771
- name: args[2],
772
- text: value,
773
- type: "secret_text"
774
- }), (path) => apply(() => runCf([
775
- "workers",
776
- "secrets",
777
- "update",
778
- args[2],
779
- "--worker",
780
- worker,
781
- "--body",
782
- `@${path}`
783
- ])));
784
- }
785
- if (verb === "bulk") {
786
- const input = object(parsedJson(readFileSync(0, "utf8")));
787
- const patch = Object.fromEntries(Object.entries(input).map(([name, text]) => [name, {
788
- type: "secret_text",
789
- text
790
- }]));
791
- return await withSecretFile(JSON.stringify(patch), (path) => apply(() => runCf([
765
+ case "secret.put": {
766
+ const value = readFileSync(0, "utf8").replace(/\n$/, "");
767
+ const name = operation.name;
768
+ return withSecretFile(JSON.stringify({
769
+ name,
770
+ text: value,
771
+ type: "secret_text"
772
+ }), (path) => apply(() => runCf([
773
+ "workers",
774
+ "secrets",
775
+ "update",
776
+ name,
777
+ "--worker",
778
+ worker,
779
+ "--body",
780
+ "@" + path
781
+ ])));
782
+ }
783
+ case "secret.bulk": {
784
+ const values = object(parsedJson(readFileSync(0, "utf8")));
785
+ const patch = Object.fromEntries(Object.entries(values).map(([name, text]) => [name, {
786
+ type: "secret_text",
787
+ text
788
+ }]));
789
+ return withSecretFile(JSON.stringify(patch), (path) => apply(() => runCf([
790
+ "workers",
791
+ "secrets",
792
+ "bulk",
793
+ "--worker",
794
+ worker,
795
+ "--file",
796
+ path
797
+ ])));
798
+ }
799
+ case "secret.delete": return runCf([
792
800
  "workers",
793
801
  "secrets",
794
- "bulk",
802
+ "delete",
803
+ operation.name,
795
804
  "--worker",
796
805
  worker,
797
- "--file",
798
- path
799
- ])));
806
+ "--force"
807
+ ]);
808
+ default: throw new Error("Unsupported Cloudflare secret operation.");
800
809
  }
801
- if (verb === "delete" && args[2]) return runCf([
802
- "workers",
803
- "secrets",
804
- "delete",
805
- args[2],
806
- "--worker",
807
- worker,
808
- "--force"
809
- ]);
810
- return result(1, "", `Unsupported Cloudflare secret operation: ${verb}.`);
811
810
  }
812
811
  async function workerHistory() {
813
812
  const worker = workerName();
814
- const [group, verb, third] = args;
815
- if (group === "deployments" && (verb === "status" || verb === "list")) {
816
- const called = runCf([
817
- "workers",
818
- "deployments",
819
- "list",
820
- "--worker",
821
- worker
822
- ]);
823
- if (called.status !== 0) return called;
824
- const deployments = object(parsedJson(called.stdout)).deployments;
825
- if (!Array.isArray(deployments)) throw new Error("Worker deployments were malformed.");
826
- if (verb === "status") return deployments[0] ? result(0, `${JSON.stringify(deployments[0])}\n`) : result(1, "", "Worker has no active deployment.");
827
- return result(0, `${JSON.stringify(deployments)}\n`);
828
- }
829
- if (group === "versions" && verb === "list") return cleanJson([
830
- "workers",
831
- "versions",
832
- "list",
833
- "--worker-id",
834
- worker
835
- ], (value) => {
836
- if (!Array.isArray(value)) throw new Error("Worker versions were malformed.");
837
- return value.map((entry) => {
838
- const version = object(entry);
839
- return {
840
- ...version,
841
- metadata: { created_on: version.created_on }
842
- };
843
- });
844
- });
845
- if (group === "versions" && verb === "view" && third) {
846
- const called = runCf([
813
+ switch (operation.type) {
814
+ case "deployments.status":
815
+ case "deployments.list": {
816
+ const called = runCf([
817
+ "workers",
818
+ "deployments",
819
+ "list",
820
+ "--worker",
821
+ worker
822
+ ]);
823
+ if (called.status !== 0) return called;
824
+ const deployments = object(parsedJson(called.stdout)).deployments;
825
+ if (!Array.isArray(deployments)) throw new Error("Worker deployments were malformed.");
826
+ return operation.type === "deployments.list" ? result(0, "", called.stderr, deployments) : deployments[0] ? result(0, "", called.stderr, deployments[0]) : result(1, "", "Worker has no active deployment.");
827
+ }
828
+ case "versions.list": return cleanJson([
847
829
  "workers",
848
830
  "versions",
849
- "get",
850
- third,
831
+ "list",
851
832
  "--worker-id",
852
833
  worker
853
- ]);
854
- if (called.status !== 0) return called;
855
- const version = object(parsedJson(called.stdout));
856
- if (version.id !== third || !Array.isArray(version.bindings)) throw new Error("Worker version bindings were malformed.");
857
- const resources = await readVersionResources(worker, third);
858
- return result(0, `${JSON.stringify({
859
- ...version,
860
- resources
861
- })}\n`);
862
- }
863
- if (group === "versions" && verb === "deploy") {
864
- const firstFlag = args.findIndex((part, index) => index >= 2 && part.startsWith("-"));
865
- const versions = args.slice(2, firstFlag === -1 ? void 0 : firstFlag).map((part) => {
866
- const [version_id, fraction] = part.split("@");
867
- const percentage = Number(fraction);
868
- if (!/^[0-9a-f-]{36}$/i.test(version_id ?? "") || !Number.isFinite(percentage)) throw new Error("Cloudflare deployment version was malformed.");
869
- return {
870
- version_id,
871
- percentage
872
- };
834
+ ], (value) => {
835
+ if (!Array.isArray(value)) throw new Error("Worker versions were malformed.");
836
+ return value.map((entry) => {
837
+ const version = object(entry);
838
+ return {
839
+ ...version,
840
+ metadata: { created_on: version.created_on }
841
+ };
842
+ });
873
843
  });
874
- if (!versions.length || Math.abs(versions.reduce((sum, entry) => sum + entry.percentage, 0) - 100) > .001) throw new Error("Cloudflare deployment percentages must total 100.");
875
- const message = field("--message");
876
- return runCf([
877
- "workers",
878
- "deployments",
879
- "create",
880
- "--worker",
881
- worker,
882
- "--body",
883
- JSON.stringify({
884
- strategy: "percentage",
885
- versions,
886
- ...message ? { annotations: { "workers/message": message } } : {}
887
- })
888
- ]);
844
+ case "versions.view": {
845
+ const versionId = operation.versionId;
846
+ const called = runCf([
847
+ "workers",
848
+ "versions",
849
+ "get",
850
+ versionId,
851
+ "--worker-id",
852
+ worker,
853
+ ...operation.includeSource ? ["--include", "modules"] : []
854
+ ], process.cwd(), operation.includeSource ? {
855
+ timeoutMs: 3e4,
856
+ maxOutputBytes: 1048576
857
+ } : void 0);
858
+ if (called.status !== 0) return called;
859
+ const version = object(parsedJson(called.stdout));
860
+ if (version.id !== versionId || !Array.isArray(version.bindings)) throw new Error("Worker version bindings were malformed.");
861
+ if (operation.includeSource) return result(0, "", called.stderr, version);
862
+ const resources = await readVersionResources(worker, versionId);
863
+ return result(0, "", called.stderr, {
864
+ ...version,
865
+ resources
866
+ });
867
+ }
868
+ case "versions.deploy": {
869
+ const versions = operation.versions.map((value) => ({
870
+ version_id: value.versionId,
871
+ percentage: value.percentage
872
+ }));
873
+ if (!versions.length || versions.some((value) => !/^[-a-f\d]{36}$/i.test(value.version_id) || !Number.isFinite(value.percentage) || value.percentage < 0 || value.percentage > 100) || Math.abs(versions.reduce((sum, value) => sum + value.percentage, 0) - 100) > .001) throw new Error("Cloudflare deployment percentages must total 100.");
874
+ return runCf([
875
+ "workers",
876
+ "deployments",
877
+ "create",
878
+ "--worker",
879
+ worker,
880
+ "--body",
881
+ JSON.stringify({
882
+ strategy: "percentage",
883
+ versions,
884
+ ...operation.message ? { annotations: { "workers/message": operation.message } } : {}
885
+ })
886
+ ]);
887
+ }
888
+ default: throw new Error("Unsupported Cloudflare Worker history operation.");
889
889
  }
890
- return result(1, "", `Unsupported Cloudflare Worker history operation: ${group} ${verb}.`);
891
890
  }
892
891
  async function workerChanges() {
893
- if (args[0] === "queues" && args[1] === "consumer" && args[2] === "remove") {
894
- const queueName = args[3];
895
- const worker = args[4];
896
- if (!queueName || !worker) throw new Error("Queue consumer target is missing.");
897
- const queue = (await readAllQueues()).find((item) => item.queue_name === queueName);
898
- if (!queue || typeof queue.queue_id !== "string") return result(1, "", `Queue "${queueName}" does not exist`);
892
+ if (operation.type === "queues.consumer.remove") {
893
+ const queue = (await readAllQueues()).find((item) => item.queue_name === operation.queueName);
894
+ if (!queue || typeof queue.queue_id !== "string") return {
895
+ ...result(1, "", "Cloudflare Queue does not exist."),
896
+ failure: "not-found"
897
+ };
899
898
  const consumers = runCf([
900
899
  "queues",
901
900
  "consumers",
@@ -906,8 +905,17 @@ async function workerChanges() {
906
905
  if (consumers.status !== 0) return consumers;
907
906
  const members = parsedJson(consumers.stdout);
908
907
  if (!Array.isArray(members)) throw new Error("Queue consumer list was malformed.");
909
- for (const item of members.map(object).filter((entry) => entry.script === worker)) {
910
- if (typeof item.consumer_id !== "string") throw new Error("Queue consumer ID is missing.");
908
+ const matching = members.map(object).filter((entry) => {
909
+ const name = entry.script_name ?? entry.script;
910
+ if (entry.script_name !== void 0 && (typeof entry.script_name !== "string" || !entry.script_name) || entry.script !== void 0 && (typeof entry.script !== "string" || !entry.script) || entry.script_name !== void 0 && entry.script !== void 0 && entry.script_name !== entry.script || entry.type === "worker" && name === void 0) throw new Error("Queue consumer Worker identity is ambiguous.");
911
+ return name === operation.workerName;
912
+ });
913
+ if (matching.length > 1) throw new Error("Queue consumer Worker identity is ambiguous.");
914
+ for (const item of matching) {
915
+ if (typeof item.consumer_id !== "string" || !item.consumer_id || item.consumer_id.startsWith("-") || /\s/.test(item.consumer_id) || [...item.consumer_id].some((character) => {
916
+ const code = character.charCodeAt(0);
917
+ return code < 32 || code === 127;
918
+ }) || item.type !== void 0 && item.type !== "worker") throw new Error("Queue consumer ID or type is invalid.");
911
919
  const deleted = runCf([
912
920
  "queues",
913
921
  "consumers",
@@ -921,59 +929,62 @@ async function workerChanges() {
921
929
  }
922
930
  return result(0);
923
931
  }
924
- if (args[0] === "triggers" && args[1] === "deploy") {
925
- const raw = config();
926
- const name = workerName();
927
- if (raw.name !== name) throw new Error("Cloudflare trigger Worker name changed.");
928
- return await withBuildOutput(raw, null, (directory) => runCf([
929
- "workers",
930
- "triggers",
931
- "deploy",
932
- "--prebuilt",
933
- ...args.includes("--dry-run") ? ["--dry-run"] : []
934
- ], directory));
932
+ const raw = config();
933
+ const name = workerName();
934
+ if (raw.name !== name) throw new Error("Cloudflare Worker target changed.");
935
+ if (operation.type === "triggers.clear-crons" || operation.type === "triggers.clear-domains") {
936
+ if (raw.account_id !== void 0 && raw.account_id !== accountId()) throw new Error("Cloudflare trigger target changed.");
937
+ return operation.type === "triggers.clear-crons" ? clearWorkerCronSchedules(name) : clearWorkerCustomDomains(name);
935
938
  }
936
- if (args[0] === "triggers" && args[1] === "clear-crons") {
937
- const raw = config();
938
- const name = workerName();
939
- if (raw.name !== name || raw.account_id !== void 0 && raw.account_id !== accountId()) throw new Error("Cloudflare trigger target changed.");
940
- return await clearWorkerCronSchedules(name);
941
- }
942
- if (args[0] === "triggers" && args[1] === "clear-domains") {
943
- const raw = config();
944
- const name = workerName();
945
- if (raw.name !== name || raw.account_id !== void 0 && raw.account_id !== accountId()) throw new Error("Cloudflare trigger target changed.");
946
- return await clearWorkerCustomDomains(name);
947
- }
948
- if (args[0] === "versions" && args[1] === "upload" || args[0] === "deploy") {
949
- const raw = config();
939
+ if (operation.type === "triggers.deploy") return withBuildOutput(raw, null, (directory) => runCf([
940
+ "workers",
941
+ "triggers",
942
+ "deploy",
943
+ "--prebuilt"
944
+ ], directory));
945
+ if (operation.type === "versions.upload" || operation.type === "worker.deploy") {
950
946
  const path = configPath();
951
947
  if (typeof raw.main !== "string" || !raw.main || raw.no_bundle !== true) throw new Error("Cloudflare Worker upload requires a prebuilt platform Worker.");
952
948
  const source = resolve(dirname(path), raw.main);
953
- const message = field("--message");
954
- const secrets = field("--secrets-file");
955
- return await withBuildOutput(raw, source, (directory) => runCf([
956
- ...args[0] === "deploy" ? ["deploy"] : [
949
+ const request = operation;
950
+ const called = await withBuildOutput(raw, source, (directory) => runCf([
951
+ ...request.type === "worker.deploy" ? ["deploy"] : [
957
952
  "workers",
958
953
  "versions",
959
954
  "create"
960
955
  ],
961
956
  "--prebuilt",
962
- ...message ? ["--message", message] : [],
963
- ...secrets ? ["--secrets-file", secrets] : [],
964
- ...args.includes("--dry-run") ? ["--dry-run"] : []
957
+ ...request.message ? ["--message", request.message] : [],
958
+ ...request.secretsFilePath ? ["--secrets-file", request.secretsFilePath] : []
965
959
  ], directory));
960
+ if (called.status !== 0) return called;
961
+ let uploaded = {};
962
+ try {
963
+ uploaded = object(parsedJson(called.stdout));
964
+ } catch {}
965
+ const output = called.stdout;
966
+ const versionId = uploaded.version_id ?? uploaded.id ?? uploaded.versionId ?? output.match(/(?:Worker|Current) Version ID:\s*([0-9a-f]{8}-[0-9a-f-]{27})/i)?.[1];
967
+ if (typeof versionId !== "string" || !/^[0-9a-f]{8}-[0-9a-f-]{27}$/i.test(versionId)) throw new Error("Cloudflare did not return the uploaded Worker version ID.");
968
+ const previewUrl = typeof uploaded.preview_url === "string" ? uploaded.preview_url : output.match(/Version Preview(?: Alias)? URL:\s*(https:\/\/\S+)/i)?.[1];
969
+ const workersDevUrl = typeof uploaded.workers_dev_url === "string" ? uploaded.workers_dev_url : output.match(/(https:\/\/[a-z0-9.-]+\.workers\.dev(?:\/[^\s]*)?)/i)?.[1];
970
+ return result(0, "", called.stderr, {
971
+ versionId,
972
+ ...previewUrl ? { previewUrl } : {},
973
+ ...workersDevUrl ? { workersDevUrl } : {}
974
+ });
966
975
  }
967
- return result(1, "", `Unsupported Cloudflare Worker operation: ${args.slice(0, 2).join(" ")}.`);
976
+ throw new Error("Unsupported Cloudflare Worker operation.");
968
977
  }
969
978
  async function tail() {
970
- const worker = args[1];
971
- const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? config().account_id;
972
- if (!worker || typeof accountId !== "string" || !accountId || worker !== workerName()) throw new Error("Cloudflare tail target is not pinned.");
979
+ if (operation.type !== "tail") throw new Error("Cloudflare tail operation is required.");
980
+ const worker = workerName();
981
+ const raw = config();
982
+ const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? raw.account_id;
983
+ if (!worker || typeof accountId !== "string" || !accountId || worker !== raw.name) throw new Error("Cloudflare tail target is not pinned.");
973
984
  const filters = [];
974
- if (field("--search")) filters.push({ query: field("--search") });
975
- if (field("--version-id")) filters.push({ scriptVersion: field("--version-id") });
976
- if (field("--status") === "error") filters.push({ outcome: [
985
+ if (operation.search) filters.push({ query: operation.search });
986
+ if (operation.versionId) filters.push({ scriptVersion: operation.versionId });
987
+ if (operation.status === "error") filters.push({ outcome: [
977
988
  "exception",
978
989
  "exceededCpu",
979
990
  "exceededMemory",
@@ -1010,25 +1021,29 @@ async function tail() {
1010
1021
  if (stopped.signal.aborted) return result(0);
1011
1022
  await new Promise((resolve, reject) => {
1012
1023
  finish = resolve;
1024
+ let pendingMessages = Promise.resolve();
1013
1025
  socket = new WebSocket(tailUrl, "trace-v1");
1014
1026
  socket.addEventListener("open", () => {
1015
1027
  socket.send(JSON.stringify({ debug: false }));
1016
1028
  });
1017
1029
  socket.addEventListener("message", (event) => {
1018
- try {
1019
- const log = object(parsedJson(String(event.data)));
1030
+ pendingMessages = pendingMessages.then(async () => {
1031
+ const data = event.data;
1032
+ const text = typeof data === "string" ? data : data instanceof Blob ? await data.text() : data instanceof ArrayBuffer ? new TextDecoder().decode(data) : null;
1033
+ if (text === null) throw new Error("Unsupported Cloudflare tail frame.");
1034
+ const log = object(parsedJson(text));
1020
1035
  const detail = object(log.event ?? {});
1021
1036
  const request = object(detail.request ?? {});
1022
1037
  const prefix = typeof request.url === "string" ? `${request.method ?? "GET"} ${request.url}` : typeof detail.queue === "string" ? `Queue ${detail.queue}` : typeof detail.mailFrom === "string" ? `Email from ${detail.mailFrom}` : "Worker event";
1023
1038
  process.stdout.write(`${prefix} - ${log.outcome ?? "unknown"} @ ${new Date(Number(log.eventTimestamp)).toLocaleString()}\n`);
1024
1039
  if (Array.isArray(log.logs)) for (const line of log.logs.map(object)) process.stdout.write(` (${line.level ?? "log"}) ${Array.isArray(line.message) ? line.message.join(" ") : ""}\n`);
1025
1040
  if (Array.isArray(log.exceptions)) for (const exception of log.exceptions.map(object)) process.stderr.write(` ${exception.name ?? "Error"}: ${exception.message ?? ""}\n`);
1026
- } catch {
1041
+ }).catch(() => {
1027
1042
  process.stderr.write("Cloudflare returned a malformed tail event.\n");
1028
- }
1043
+ });
1029
1044
  });
1030
1045
  socket.addEventListener("error", () => reject(/* @__PURE__ */ new Error("Cloudflare Worker tail connection failed.")));
1031
- socket.addEventListener("close", () => resolve());
1046
+ socket.addEventListener("close", () => void pendingMessages.then(resolve));
1032
1047
  if (stopped.signal.aborted) resolve();
1033
1048
  });
1034
1049
  } catch (error) {
@@ -1048,34 +1063,49 @@ async function tail() {
1048
1063
  return result(0);
1049
1064
  }
1050
1065
  async function main() {
1051
- if ([
1052
- "whoami",
1053
- "login",
1054
- "logout",
1055
- "auth"
1056
- ].includes(args[0] ?? "")) return auth();
1057
- if (args[0] === "secret") return await secrets();
1058
- if (args[0] === "tail") return await tail();
1059
- if (args[0] === "email") return email();
1060
- if (args[0] === "deployments" || args[0] === "versions" && args[1] !== "upload") return await workerHistory();
1061
- if (args[0] === "triggers" || args[0] === "deploy" || args[0] === "versions" && args[1] === "upload" || args[0] === "queues" && args[1] === "consumer") return await workerChanges();
1062
- if ([
1063
- "d1",
1064
- "kv",
1065
- "r2",
1066
- "hyperdrive",
1067
- "queues",
1068
- "containers"
1069
- ].includes(args[0] ?? "")) return await resources();
1070
- return result(1, "", `Unsupported Cloudflare operation: ${args.slice(0, 2).join(" ")}.`);
1066
+ if (process.argv.length !== 3) throw new Error("Exactly one typed Cloudflare operation is required.");
1067
+ if (!operation || typeof operation !== "object" || typeof operation.type !== "string") throw new Error("Cloudflare operation is required.");
1068
+ if (operation.type.startsWith("auth.")) return auth();
1069
+ if (operation.type.startsWith("secret.")) return secrets();
1070
+ if (operation.type === "tail") return tail();
1071
+ if (operation.type.startsWith("email.")) return email();
1072
+ if (operation.type.startsWith("deployments.") || operation.type.startsWith("versions.") && operation.type !== "versions.upload") return workerHistory();
1073
+ if (operation.type.startsWith("triggers.") || operation.type === "worker.deploy" || operation.type === "versions.upload" || operation.type === "queues.consumer.remove") return workerChanges();
1074
+ return resources();
1071
1075
  }
1072
1076
  try {
1073
1077
  const output = await main();
1074
- if (output.stdout) process.stdout.write(output.stdout);
1078
+ if (operation.type !== "auth.login" && operation.type !== "tail") {
1079
+ let data = output.data;
1080
+ let humanOutput = "";
1081
+ if (data === void 0 && output.stdout.trim()) try {
1082
+ data = parsedJson(output.stdout);
1083
+ } catch {
1084
+ humanOutput = output.stdout;
1085
+ }
1086
+ process.stdout.write(JSON.stringify({
1087
+ operationResult: 1,
1088
+ ...output.signal ? { signal: output.signal } : {},
1089
+ ...output.error ? { error: output.error } : {},
1090
+ ...data !== void 0 ? { data } : {},
1091
+ ...output.errorCode !== void 0 ? { errorCode: output.errorCode } : {},
1092
+ ...output.failure ? { failure: output.failure } : {},
1093
+ ...output.stderr ? { errors: [{
1094
+ code: output.errorCode,
1095
+ message: output.stderr
1096
+ }] } : {},
1097
+ ...humanOutput ? { output: humanOutput } : {}
1098
+ }) + "\n");
1099
+ }
1075
1100
  if (output.stderr) process.stderr.write(output.stderr);
1076
1101
  process.exitCode = output.status;
1077
1102
  } catch (error) {
1078
- process.stderr.write(error instanceof Error ? error.message : "Cloudflare command failed.");
1103
+ const message = error instanceof Error ? error.message : "Cloudflare operation failed.";
1104
+ if (operation?.type !== "auth.login" && operation?.type !== "tail") process.stdout.write(JSON.stringify({
1105
+ operationResult: 1,
1106
+ errors: [{ message }]
1107
+ }) + "\n");
1108
+ process.stderr.write(message);
1079
1109
  process.exitCode = 1;
1080
1110
  }
1081
1111
  //#endregion