alchemy 0.25.0 → 0.26.1

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 (499) hide show
  1. package/README.md +7 -0
  2. package/lib/ai/astro-file.d.ts.map +1 -1
  3. package/lib/ai/astro-file.js +2 -1
  4. package/lib/ai/astro-file.js.map +1 -1
  5. package/lib/ai/client.d.ts.map +1 -1
  6. package/lib/ai/client.js +3 -2
  7. package/lib/ai/client.js.map +1 -1
  8. package/lib/alchemy.d.ts +7 -0
  9. package/lib/alchemy.d.ts.map +1 -1
  10. package/lib/alchemy.js +19 -3
  11. package/lib/alchemy.js.map +1 -1
  12. package/lib/apply.d.ts.map +1 -1
  13. package/lib/apply.js +63 -5
  14. package/lib/apply.js.map +1 -1
  15. package/lib/aws/control/client.js +4 -3
  16. package/lib/aws/control/client.js.map +1 -1
  17. package/lib/aws/control/properties.d.ts +6 -0
  18. package/lib/aws/control/properties.d.ts.map +1 -1
  19. package/lib/aws/control/properties.js +48 -0
  20. package/lib/aws/control/properties.js.map +1 -1
  21. package/lib/aws/control/resource.d.ts.map +1 -1
  22. package/lib/aws/control/resource.js +3 -2
  23. package/lib/aws/control/resource.js.map +1 -1
  24. package/lib/aws/control/types.d.ts +3969 -4862
  25. package/lib/aws/control/types.d.ts.map +1 -1
  26. package/lib/aws/control/types.js.map +1 -1
  27. package/lib/aws/function.d.ts.map +1 -1
  28. package/lib/aws/function.js +9 -8
  29. package/lib/aws/function.js.map +1 -1
  30. package/lib/aws/oidc/oidc-provider.d.ts.map +1 -1
  31. package/lib/aws/oidc/oidc-provider.js +3 -2
  32. package/lib/aws/oidc/oidc-provider.js.map +1 -1
  33. package/lib/aws/queue.d.ts.map +1 -1
  34. package/lib/aws/queue.js +3 -2
  35. package/lib/aws/queue.js.map +1 -1
  36. package/lib/aws/role.d.ts.map +1 -1
  37. package/lib/aws/role.js +3 -1
  38. package/lib/aws/role.js.map +1 -1
  39. package/lib/aws/ssm-parameter.d.ts.map +1 -1
  40. package/lib/aws/ssm-parameter.js +2 -1
  41. package/lib/aws/ssm-parameter.js.map +1 -1
  42. package/lib/cloudflare/account-api-token.d.ts.map +1 -1
  43. package/lib/cloudflare/account-api-token.js +3 -2
  44. package/lib/cloudflare/account-api-token.js.map +1 -1
  45. package/lib/cloudflare/ai-gateway.d.ts.map +1 -1
  46. package/lib/cloudflare/ai-gateway.js +4 -3
  47. package/lib/cloudflare/ai-gateway.js.map +1 -1
  48. package/lib/cloudflare/api-error.d.ts +0 -9
  49. package/lib/cloudflare/api-error.d.ts.map +1 -1
  50. package/lib/cloudflare/api-error.js +24 -0
  51. package/lib/cloudflare/api-error.js.map +1 -1
  52. package/lib/cloudflare/api.d.ts.map +1 -1
  53. package/lib/cloudflare/api.js +5 -4
  54. package/lib/cloudflare/api.js.map +1 -1
  55. package/lib/cloudflare/assets.d.ts.map +1 -1
  56. package/lib/cloudflare/assets.js +26 -6
  57. package/lib/cloudflare/assets.js.map +1 -1
  58. package/lib/cloudflare/astro.d.ts +63 -0
  59. package/lib/cloudflare/astro.d.ts.map +1 -0
  60. package/lib/cloudflare/astro.js +133 -0
  61. package/lib/cloudflare/astro.js.map +1 -0
  62. package/lib/cloudflare/auth.d.ts.map +1 -1
  63. package/lib/cloudflare/auth.js +3 -2
  64. package/lib/cloudflare/auth.js.map +1 -1
  65. package/lib/cloudflare/bindings.d.ts +24 -2
  66. package/lib/cloudflare/bindings.d.ts.map +1 -1
  67. package/lib/cloudflare/bindings.js.map +1 -1
  68. package/lib/cloudflare/bound.d.ts +10 -1
  69. package/lib/cloudflare/bound.d.ts.map +1 -1
  70. package/lib/cloudflare/bucket.d.ts.map +1 -1
  71. package/lib/cloudflare/bucket.js +12 -8
  72. package/lib/cloudflare/bucket.js.map +1 -1
  73. package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
  74. package/lib/cloudflare/bundle/bundle-worker.js +2 -1
  75. package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
  76. package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts.map +1 -1
  77. package/lib/cloudflare/bundle/nodejs-compat-mode.js +2 -1
  78. package/lib/cloudflare/bundle/nodejs-compat-mode.js.map +1 -1
  79. package/lib/cloudflare/custom-domain.d.ts.map +1 -1
  80. package/lib/cloudflare/custom-domain.js +10 -9
  81. package/lib/cloudflare/custom-domain.js.map +1 -1
  82. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  83. package/lib/cloudflare/d1-database.js +11 -10
  84. package/lib/cloudflare/d1-database.js.map +1 -1
  85. package/lib/cloudflare/d1-export.d.ts.map +1 -1
  86. package/lib/cloudflare/d1-export.js +2 -1
  87. package/lib/cloudflare/d1-export.js.map +1 -1
  88. package/lib/cloudflare/d1-import.d.ts.map +1 -1
  89. package/lib/cloudflare/d1-import.js +2 -1
  90. package/lib/cloudflare/d1-import.js.map +1 -1
  91. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  92. package/lib/cloudflare/d1-migrations.js +2 -1
  93. package/lib/cloudflare/d1-migrations.js.map +1 -1
  94. package/lib/cloudflare/dispatch-namespace.d.ts +94 -0
  95. package/lib/cloudflare/dispatch-namespace.d.ts.map +1 -0
  96. package/lib/cloudflare/dispatch-namespace.js +143 -0
  97. package/lib/cloudflare/dispatch-namespace.js.map +1 -0
  98. package/lib/cloudflare/dns-records.d.ts.map +1 -1
  99. package/lib/cloudflare/dns-records.js +5 -4
  100. package/lib/cloudflare/dns-records.js.map +1 -1
  101. package/lib/cloudflare/do-state-store/worker.d.ts.map +1 -1
  102. package/lib/cloudflare/do-state-store/worker.js +4 -0
  103. package/lib/cloudflare/do-state-store/worker.js.map +1 -1
  104. package/lib/cloudflare/email-address.d.ts +79 -0
  105. package/lib/cloudflare/email-address.d.ts.map +1 -0
  106. package/lib/cloudflare/email-address.js +112 -0
  107. package/lib/cloudflare/email-address.js.map +1 -0
  108. package/lib/cloudflare/email-catch-all.d.ts +123 -0
  109. package/lib/cloudflare/email-catch-all.d.ts.map +1 -0
  110. package/lib/cloudflare/email-catch-all.js +124 -0
  111. package/lib/cloudflare/email-catch-all.js.map +1 -0
  112. package/lib/cloudflare/email-routing.d.ts +89 -0
  113. package/lib/cloudflare/email-routing.d.ts.map +1 -0
  114. package/lib/cloudflare/email-routing.js +120 -0
  115. package/lib/cloudflare/email-routing.js.map +1 -0
  116. package/lib/cloudflare/email-rule.d.ts +196 -0
  117. package/lib/cloudflare/email-rule.d.ts.map +1 -0
  118. package/lib/cloudflare/email-rule.js +153 -0
  119. package/lib/cloudflare/email-rule.js.map +1 -0
  120. package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
  121. package/lib/cloudflare/hyperdrive.js +5 -4
  122. package/lib/cloudflare/hyperdrive.js.map +1 -1
  123. package/lib/cloudflare/images.d.ts +60 -0
  124. package/lib/cloudflare/images.d.ts.map +1 -0
  125. package/lib/cloudflare/images.js +60 -0
  126. package/lib/cloudflare/images.js.map +1 -0
  127. package/lib/cloudflare/index.d.ts +10 -0
  128. package/lib/cloudflare/index.d.ts.map +1 -1
  129. package/lib/cloudflare/index.js +10 -0
  130. package/lib/cloudflare/index.js.map +1 -1
  131. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  132. package/lib/cloudflare/kv-namespace.js +2 -1
  133. package/lib/cloudflare/kv-namespace.js.map +1 -1
  134. package/lib/cloudflare/pipeline.d.ts +7 -0
  135. package/lib/cloudflare/pipeline.d.ts.map +1 -1
  136. package/lib/cloudflare/pipeline.js +28 -2
  137. package/lib/cloudflare/pipeline.js.map +1 -1
  138. package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
  139. package/lib/cloudflare/queue-consumer.js +2 -1
  140. package/lib/cloudflare/queue-consumer.js.map +1 -1
  141. package/lib/cloudflare/queue.d.ts.map +1 -1
  142. package/lib/cloudflare/queue.js +0 -8
  143. package/lib/cloudflare/queue.js.map +1 -1
  144. package/lib/cloudflare/route.d.ts +26 -1
  145. package/lib/cloudflare/route.d.ts.map +1 -1
  146. package/lib/cloudflare/route.js +84 -16
  147. package/lib/cloudflare/route.js.map +1 -1
  148. package/lib/cloudflare/secret.d.ts +137 -0
  149. package/lib/cloudflare/secret.d.ts.map +1 -0
  150. package/lib/cloudflare/secret.js +122 -0
  151. package/lib/cloudflare/secret.js.map +1 -0
  152. package/lib/cloudflare/secrets-store.d.ts +145 -0
  153. package/lib/cloudflare/secrets-store.d.ts.map +1 -0
  154. package/lib/cloudflare/secrets-store.js +213 -0
  155. package/lib/cloudflare/secrets-store.js.map +1 -0
  156. package/lib/cloudflare/sveltekit.d.ts +49 -0
  157. package/lib/cloudflare/sveltekit.d.ts.map +1 -0
  158. package/lib/cloudflare/sveltekit.js +56 -0
  159. package/lib/cloudflare/sveltekit.js.map +1 -0
  160. package/lib/cloudflare/user.d.ts.map +1 -1
  161. package/lib/cloudflare/user.js +2 -1
  162. package/lib/cloudflare/user.js.map +1 -1
  163. package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
  164. package/lib/cloudflare/vectorize-index.js +6 -5
  165. package/lib/cloudflare/vectorize-index.js.map +1 -1
  166. package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
  167. package/lib/cloudflare/vectorize-metadata-index.js +2 -1
  168. package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
  169. package/lib/cloudflare/website.d.ts.map +1 -1
  170. package/lib/cloudflare/website.js +7 -2
  171. package/lib/cloudflare/website.js.map +1 -1
  172. package/lib/cloudflare/worker-assets.d.ts +18 -0
  173. package/lib/cloudflare/worker-assets.d.ts.map +1 -1
  174. package/lib/cloudflare/worker-assets.js +61 -67
  175. package/lib/cloudflare/worker-assets.js.map +1 -1
  176. package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
  177. package/lib/cloudflare/worker-metadata.js +23 -1
  178. package/lib/cloudflare/worker-metadata.js.map +1 -1
  179. package/lib/cloudflare/worker.d.ts +43 -2
  180. package/lib/cloudflare/worker.d.ts.map +1 -1
  181. package/lib/cloudflare/worker.js +50 -11
  182. package/lib/cloudflare/worker.js.map +1 -1
  183. package/lib/cloudflare/wrangler.json.d.ts +21 -0
  184. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  185. package/lib/cloudflare/wrangler.json.js +33 -0
  186. package/lib/cloudflare/wrangler.json.js.map +1 -1
  187. package/lib/cloudflare/zone.d.ts.map +1 -1
  188. package/lib/cloudflare/zone.js +4 -3
  189. package/lib/cloudflare/zone.js.map +1 -1
  190. package/lib/destroy.d.ts.map +1 -1
  191. package/lib/destroy.js +30 -13
  192. package/lib/destroy.js.map +1 -1
  193. package/lib/dns/godaddy.d.ts.map +1 -1
  194. package/lib/dns/godaddy.js +3 -2
  195. package/lib/dns/godaddy.js.map +1 -1
  196. package/lib/dns/import-dns.d.ts.map +1 -1
  197. package/lib/dns/import-dns.js +2 -1
  198. package/lib/dns/import-dns.js.map +1 -1
  199. package/lib/esbuild/bundle.d.ts +1 -1
  200. package/lib/esbuild/bundle.d.ts.map +1 -1
  201. package/lib/esbuild/bundle.js +2 -1
  202. package/lib/esbuild/bundle.js.map +1 -1
  203. package/lib/fs/copy-file.d.ts.map +1 -1
  204. package/lib/fs/copy-file.js +2 -1
  205. package/lib/fs/copy-file.js.map +1 -1
  206. package/lib/fs/file.d.ts.map +1 -1
  207. package/lib/fs/file.js +2 -1
  208. package/lib/fs/file.js.map +1 -1
  209. package/lib/github/client.d.ts.map +1 -1
  210. package/lib/github/client.js +11 -10
  211. package/lib/github/client.js.map +1 -1
  212. package/lib/github/repository-environment.d.ts.map +1 -1
  213. package/lib/github/repository-environment.js +5 -4
  214. package/lib/github/repository-environment.js.map +1 -1
  215. package/lib/github/secret.d.ts.map +1 -1
  216. package/lib/github/secret.js +7 -6
  217. package/lib/github/secret.js.map +1 -1
  218. package/lib/index.d.ts +2 -1
  219. package/lib/index.d.ts.map +1 -1
  220. package/lib/index.js +1 -0
  221. package/lib/index.js.map +1 -1
  222. package/lib/neon/project.d.ts.map +1 -1
  223. package/lib/neon/project.js +3 -2
  224. package/lib/neon/project.js.map +1 -1
  225. package/lib/planetscale/api.d.ts +53 -0
  226. package/lib/planetscale/api.d.ts.map +1 -0
  227. package/lib/planetscale/api.js +84 -0
  228. package/lib/planetscale/api.js.map +1 -0
  229. package/lib/planetscale/branch.d.ts +129 -0
  230. package/lib/planetscale/branch.d.ts.map +1 -0
  231. package/lib/planetscale/branch.js +161 -0
  232. package/lib/planetscale/branch.js.map +1 -0
  233. package/lib/planetscale/database.d.ts +143 -0
  234. package/lib/planetscale/database.d.ts.map +1 -0
  235. package/lib/planetscale/database.js +184 -0
  236. package/lib/planetscale/database.js.map +1 -0
  237. package/lib/planetscale/index.d.ts +5 -0
  238. package/lib/planetscale/index.d.ts.map +1 -0
  239. package/lib/planetscale/index.js +5 -0
  240. package/lib/planetscale/index.js.map +1 -0
  241. package/lib/planetscale/utils.d.ts +15 -0
  242. package/lib/planetscale/utils.d.ts.map +1 -0
  243. package/lib/planetscale/utils.js +95 -0
  244. package/lib/planetscale/utils.js.map +1 -0
  245. package/lib/resource.js +7 -1
  246. package/lib/resource.js.map +1 -1
  247. package/lib/runtime/plugin.d.ts.map +1 -1
  248. package/lib/runtime/plugin.js +2 -1
  249. package/lib/runtime/plugin.js.map +1 -1
  250. package/lib/scope.d.ts +13 -2
  251. package/lib/scope.d.ts.map +1 -1
  252. package/lib/scope.js +53 -10
  253. package/lib/scope.js.map +1 -1
  254. package/lib/sentry/client-key.d.ts.map +1 -1
  255. package/lib/sentry/client-key.js +5 -4
  256. package/lib/sentry/client-key.js.map +1 -1
  257. package/lib/sentry/project.d.ts.map +1 -1
  258. package/lib/sentry/project.js +5 -4
  259. package/lib/sentry/project.js.map +1 -1
  260. package/lib/sentry/team.d.ts.map +1 -1
  261. package/lib/sentry/team.js +5 -4
  262. package/lib/sentry/team.js.map +1 -1
  263. package/lib/stripe/card.d.ts.map +1 -1
  264. package/lib/stripe/card.js +2 -1
  265. package/lib/stripe/card.js.map +1 -1
  266. package/lib/stripe/client.d.ts.map +1 -1
  267. package/lib/stripe/client.js +3 -2
  268. package/lib/stripe/client.js.map +1 -1
  269. package/lib/stripe/coupon.d.ts.map +1 -1
  270. package/lib/stripe/coupon.js +2 -1
  271. package/lib/stripe/coupon.js.map +1 -1
  272. package/lib/stripe/customer.d.ts.map +1 -1
  273. package/lib/stripe/customer.js +2 -1
  274. package/lib/stripe/customer.js.map +1 -1
  275. package/lib/stripe/entitlements-feature.d.ts.map +1 -1
  276. package/lib/stripe/entitlements-feature.js +2 -1
  277. package/lib/stripe/entitlements-feature.js.map +1 -1
  278. package/lib/stripe/file.d.ts.map +1 -1
  279. package/lib/stripe/file.js +2 -1
  280. package/lib/stripe/file.js.map +1 -1
  281. package/lib/stripe/meter.d.ts.map +1 -1
  282. package/lib/stripe/meter.js +4 -2
  283. package/lib/stripe/meter.js.map +1 -1
  284. package/lib/stripe/portal-configuration.d.ts.map +1 -1
  285. package/lib/stripe/portal-configuration.js +2 -1
  286. package/lib/stripe/portal-configuration.js.map +1 -1
  287. package/lib/stripe/price.d.ts.map +1 -1
  288. package/lib/stripe/price.js +2 -1
  289. package/lib/stripe/price.js.map +1 -1
  290. package/lib/stripe/product-feature.d.ts.map +1 -1
  291. package/lib/stripe/product-feature.js +2 -1
  292. package/lib/stripe/product-feature.js.map +1 -1
  293. package/lib/stripe/product.d.ts.map +1 -1
  294. package/lib/stripe/product.js +2 -1
  295. package/lib/stripe/product.js.map +1 -1
  296. package/lib/stripe/promotion-code.d.ts.map +1 -1
  297. package/lib/stripe/promotion-code.js +2 -1
  298. package/lib/stripe/promotion-code.js.map +1 -1
  299. package/lib/stripe/shipping-rate.d.ts.map +1 -1
  300. package/lib/stripe/shipping-rate.js +2 -1
  301. package/lib/stripe/shipping-rate.js.map +1 -1
  302. package/lib/stripe/tax-rate.d.ts.map +1 -1
  303. package/lib/stripe/tax-rate.js +2 -1
  304. package/lib/stripe/tax-rate.js.map +1 -1
  305. package/lib/stripe/webhook.d.ts.map +1 -1
  306. package/lib/stripe/webhook.js +3 -2
  307. package/lib/stripe/webhook.js.map +1 -1
  308. package/lib/test/bun.d.ts.map +1 -1
  309. package/lib/test/bun.js +6 -1
  310. package/lib/test/bun.js.map +1 -1
  311. package/lib/test/prune.js +7 -1
  312. package/lib/test/prune.js.map +1 -1
  313. package/lib/test/vitest.d.ts.map +1 -1
  314. package/lib/test/vitest.js +10 -3
  315. package/lib/test/vitest.js.map +1 -1
  316. package/lib/upstash/redis.d.ts.map +1 -1
  317. package/lib/upstash/redis.js +2 -1
  318. package/lib/upstash/redis.js.map +1 -1
  319. package/lib/util/async-queue.d.ts +35 -0
  320. package/lib/util/async-queue.d.ts.map +1 -0
  321. package/lib/util/async-queue.js +87 -0
  322. package/lib/util/async-queue.js.map +1 -0
  323. package/lib/util/cli.d.ts +37 -0
  324. package/lib/util/cli.d.ts.map +1 -0
  325. package/lib/util/cli.js +90 -0
  326. package/lib/util/cli.js.map +1 -0
  327. package/lib/util/ignore-matcher.d.ts +94 -0
  328. package/lib/util/ignore-matcher.d.ts.map +1 -0
  329. package/lib/util/ignore-matcher.js +616 -0
  330. package/lib/util/ignore-matcher.js.map +1 -0
  331. package/lib/util/logger.d.ts +3 -0
  332. package/lib/util/logger.d.ts.map +1 -0
  333. package/lib/util/logger.js +15 -0
  334. package/lib/util/logger.js.map +1 -0
  335. package/lib/util/retry.d.ts.map +1 -1
  336. package/lib/util/retry.js +0 -1
  337. package/lib/util/retry.js.map +1 -1
  338. package/lib/util/safe-fetch.d.ts.map +1 -1
  339. package/lib/util/safe-fetch.js +2 -1
  340. package/lib/util/safe-fetch.js.map +1 -1
  341. package/lib/util/telemetry/client.d.ts +32 -0
  342. package/lib/util/telemetry/client.d.ts.map +1 -0
  343. package/lib/util/telemetry/client.js +94 -0
  344. package/lib/util/telemetry/client.js.map +1 -0
  345. package/lib/util/telemetry/constants.d.ts +4 -0
  346. package/lib/util/telemetry/constants.d.ts.map +1 -0
  347. package/lib/util/telemetry/constants.js +8 -0
  348. package/lib/util/telemetry/constants.js.map +1 -0
  349. package/lib/util/telemetry/context.d.ts +15 -0
  350. package/lib/util/telemetry/context.d.ts.map +1 -0
  351. package/lib/util/telemetry/context.js +128 -0
  352. package/lib/util/telemetry/context.js.map +1 -0
  353. package/lib/util/telemetry/index.d.ts +3 -0
  354. package/lib/util/telemetry/index.d.ts.map +1 -0
  355. package/lib/util/telemetry/index.js +3 -0
  356. package/lib/util/telemetry/index.js.map +1 -0
  357. package/lib/util/telemetry/types.d.ts +59 -0
  358. package/lib/util/telemetry/types.d.ts.map +1 -0
  359. package/lib/util/telemetry/types.js +1 -0
  360. package/lib/util/telemetry/types.js.map +1 -0
  361. package/lib/util/xdg-paths.d.ts +9 -0
  362. package/lib/util/xdg-paths.d.ts.map +1 -0
  363. package/lib/util/xdg-paths.js +41 -0
  364. package/lib/util/xdg-paths.js.map +1 -0
  365. package/lib/vercel/project.d.ts.map +1 -1
  366. package/lib/vercel/project.js +2 -1
  367. package/lib/vercel/project.js.map +1 -1
  368. package/lib/web/astro.d.ts.map +1 -1
  369. package/lib/web/astro.js +2 -1
  370. package/lib/web/astro.js.map +1 -1
  371. package/lib/web/shadcn.d.ts.map +1 -1
  372. package/lib/web/shadcn.js +2 -1
  373. package/lib/web/shadcn.js.map +1 -1
  374. package/lib/web/vite.d.ts.map +1 -1
  375. package/lib/web/vite.js +3 -2
  376. package/lib/web/vite.js.map +1 -1
  377. package/lib/web/vitepress/dependencies.d.ts.map +1 -1
  378. package/lib/web/vitepress/dependencies.js +2 -1
  379. package/lib/web/vitepress/dependencies.js.map +1 -1
  380. package/lib/web/vitepress/vitepress.d.ts.map +1 -1
  381. package/lib/web/vitepress/vitepress.js +2 -1
  382. package/lib/web/vitepress/vitepress.js.map +1 -1
  383. package/package.json +6 -4
  384. package/src/ai/astro-file.ts +2 -1
  385. package/src/ai/client.ts +3 -2
  386. package/src/alchemy.ts +28 -3
  387. package/src/apply.ts +66 -5
  388. package/src/aws/control/client.ts +4 -4
  389. package/src/aws/control/properties.ts +48 -0
  390. package/src/aws/control/resource.ts +3 -2
  391. package/src/aws/control/types.ts +3988 -6301
  392. package/src/aws/function.ts +9 -8
  393. package/src/aws/oidc/oidc-provider.ts +3 -2
  394. package/src/aws/queue.ts +3 -2
  395. package/src/aws/role.ts +3 -1
  396. package/src/aws/ssm-parameter.ts +2 -1
  397. package/src/cloudflare/account-api-token.ts +3 -2
  398. package/src/cloudflare/ai-gateway.ts +4 -3
  399. package/src/cloudflare/api-error.ts +36 -0
  400. package/src/cloudflare/api.ts +9 -4
  401. package/src/cloudflare/assets.ts +30 -6
  402. package/src/cloudflare/astro.ts +176 -0
  403. package/src/cloudflare/auth.ts +3 -2
  404. package/src/cloudflare/bindings.ts +29 -0
  405. package/src/cloudflare/bound.ts +38 -21
  406. package/src/cloudflare/bucket.ts +15 -8
  407. package/src/cloudflare/bundle/bundle-worker.ts +2 -1
  408. package/src/cloudflare/bundle/nodejs-compat-mode.ts +2 -1
  409. package/src/cloudflare/custom-domain.ts +10 -9
  410. package/src/cloudflare/d1-database.ts +11 -10
  411. package/src/cloudflare/d1-export.ts +2 -1
  412. package/src/cloudflare/d1-import.ts +2 -1
  413. package/src/cloudflare/d1-migrations.ts +2 -1
  414. package/src/cloudflare/dispatch-namespace.ts +281 -0
  415. package/src/cloudflare/dns-records.ts +5 -4
  416. package/src/cloudflare/do-state-store/worker.ts +4 -0
  417. package/src/cloudflare/email-address.ts +203 -0
  418. package/src/cloudflare/email-catch-all.ts +248 -0
  419. package/src/cloudflare/email-routing.ts +230 -0
  420. package/src/cloudflare/email-rule.ts +322 -0
  421. package/src/cloudflare/hyperdrive.ts +5 -4
  422. package/src/cloudflare/images.ts +59 -0
  423. package/src/cloudflare/index.ts +10 -0
  424. package/src/cloudflare/kv-namespace.ts +2 -1
  425. package/src/cloudflare/pipeline.ts +38 -2
  426. package/src/cloudflare/queue-consumer.ts +2 -1
  427. package/src/cloudflare/queue.ts +0 -12
  428. package/src/cloudflare/route.ts +118 -18
  429. package/src/cloudflare/secret.ts +253 -0
  430. package/src/cloudflare/secrets-store.ts +420 -0
  431. package/src/cloudflare/sveltekit.ts +72 -0
  432. package/src/cloudflare/user.ts +2 -1
  433. package/src/cloudflare/vectorize-index.ts +6 -5
  434. package/src/cloudflare/vectorize-metadata-index.ts +2 -1
  435. package/src/cloudflare/website.ts +76 -66
  436. package/src/cloudflare/worker-assets.ts +95 -89
  437. package/src/cloudflare/worker-metadata.ts +20 -1
  438. package/src/cloudflare/worker.ts +116 -18
  439. package/src/cloudflare/wrangler.json.ts +63 -0
  440. package/src/cloudflare/zone.ts +4 -3
  441. package/src/destroy.ts +35 -17
  442. package/src/dns/godaddy.ts +3 -2
  443. package/src/dns/import-dns.ts +2 -1
  444. package/src/esbuild/bundle.ts +2 -1
  445. package/src/fs/copy-file.ts +2 -1
  446. package/src/fs/file.ts +3 -1
  447. package/src/github/client.ts +11 -10
  448. package/src/github/repository-environment.ts +5 -4
  449. package/src/github/secret.ts +7 -6
  450. package/src/index.ts +2 -1
  451. package/src/neon/project.ts +3 -2
  452. package/src/planetscale/api.ts +115 -0
  453. package/src/planetscale/branch.ts +352 -0
  454. package/src/planetscale/database.ts +394 -0
  455. package/src/planetscale/index.ts +4 -0
  456. package/src/planetscale/utils.ts +189 -0
  457. package/src/resource.ts +7 -1
  458. package/src/runtime/plugin.ts +2 -1
  459. package/src/scope.ts +64 -13
  460. package/src/sentry/client-key.ts +5 -4
  461. package/src/sentry/project.ts +5 -4
  462. package/src/sentry/team.ts +5 -4
  463. package/src/stripe/card.ts +2 -1
  464. package/src/stripe/client.ts +3 -2
  465. package/src/stripe/coupon.ts +2 -1
  466. package/src/stripe/customer.ts +2 -1
  467. package/src/stripe/entitlements-feature.ts +2 -1
  468. package/src/stripe/file.ts +2 -1
  469. package/src/stripe/meter.ts +4 -2
  470. package/src/stripe/portal-configuration.ts +2 -1
  471. package/src/stripe/price.ts +2 -1
  472. package/src/stripe/product-feature.ts +2 -1
  473. package/src/stripe/product.ts +2 -1
  474. package/src/stripe/promotion-code.ts +2 -1
  475. package/src/stripe/shipping-rate.ts +2 -1
  476. package/src/stripe/tax-rate.ts +2 -1
  477. package/src/stripe/webhook.ts +3 -2
  478. package/src/test/bun.ts +6 -1
  479. package/src/test/prune.ts +7 -1
  480. package/src/test/vitest.ts +14 -3
  481. package/src/upstash/redis.ts +2 -1
  482. package/src/util/async-queue.ts +97 -0
  483. package/src/util/cli.tsx +221 -0
  484. package/src/util/ignore-matcher.ts +873 -0
  485. package/src/util/logger.ts +17 -0
  486. package/src/util/retry.ts +0 -1
  487. package/src/util/safe-fetch.ts +2 -1
  488. package/src/util/telemetry/client.ts +127 -0
  489. package/src/util/telemetry/constants.ts +13 -0
  490. package/src/util/telemetry/context.ts +154 -0
  491. package/src/util/telemetry/index.ts +2 -0
  492. package/src/util/telemetry/types.ts +83 -0
  493. package/src/util/xdg-paths.ts +48 -0
  494. package/src/vercel/project.ts +2 -1
  495. package/src/web/astro.ts +2 -1
  496. package/src/web/shadcn.ts +2 -1
  497. package/src/web/vite.ts +3 -2
  498. package/src/web/vitepress/dependencies.ts +2 -1
  499. package/src/web/vitepress/vitepress.ts +2 -1
@@ -8,10 +8,13 @@ import type { Binding, Json, Self } from "./bindings.ts";
8
8
  import type { BrowserRendering } from "./browser-rendering.ts";
9
9
  import type { R2BucketResource as _R2Bucket } from "./bucket.ts";
10
10
  import type { D1DatabaseResource } from "./d1-database.ts";
11
+ import type { DispatchNamespaceResource } from "./dispatch-namespace.ts";
11
12
  import type { DurableObjectNamespace as _DurableObjectNamespace } from "./durable-object-namespace.ts";
12
13
  import type { HyperdriveResource as _Hyperdrive } from "./hyperdrive.ts";
14
+ import type { Images as _Images } from "./images.ts";
13
15
  import type { PipelineResource as _Pipeline } from "./pipeline.ts";
14
16
  import type { QueueResource as _Queue } from "./queue.ts";
17
+ import type { SecretsStore as _SecretsStore } from "./secrets-store.ts";
15
18
  import type { VectorizeIndexResource as _VectorizeIndex } from "./vectorize-index.ts";
16
19
  import type { VersionMetadata as _VersionMetadata } from "./version-metadata.ts";
17
20
  import type { Worker as _Worker, WorkerRef } from "./worker.ts";
@@ -48,24 +51,38 @@ export type Bound<T extends Binding> = T extends _DurableObjectNamespace<
48
51
  ? Workflow<P>
49
52
  : T extends D1DatabaseResource
50
53
  ? D1Database
51
- : T extends _VectorizeIndex
52
- ? VectorizeIndex
53
- : T extends _Queue<infer Body>
54
- ? Queue<Body>
55
- : T extends _AnalyticsEngineDataset
56
- ? AnalyticsEngineDataset
57
- : T extends _Pipeline<infer R>
58
- ? Pipeline<R>
59
- : T extends string
60
- ? string
61
- : T extends BrowserRendering
62
- ? Fetcher
63
- : T extends _Ai<infer M>
64
- ? Ai<M>
65
- : T extends _VersionMetadata
66
- ? WorkerVersionMetadata
67
- : T extends Self
68
- ? Service
69
- : T extends Json<infer T>
70
- ? T
71
- : Service;
54
+ : T extends DispatchNamespaceResource
55
+ ? { get(name: string): Fetcher }
56
+ : T extends _VectorizeIndex
57
+ ? VectorizeIndex
58
+ : T extends _Queue<infer Body>
59
+ ? Queue<Body>
60
+ : T extends _SecretsStore<infer S>
61
+ ? SecretsStoreBinding<S>
62
+ : T extends _AnalyticsEngineDataset
63
+ ? AnalyticsEngineDataset
64
+ : T extends _Pipeline<infer R>
65
+ ? Pipeline<R>
66
+ : T extends string
67
+ ? string
68
+ : T extends BrowserRendering
69
+ ? Fetcher
70
+ : T extends _Ai<infer M>
71
+ ? Ai<M>
72
+ : T extends _Images
73
+ ? ImagesBinding
74
+ : T extends _VersionMetadata
75
+ ? WorkerVersionMetadata
76
+ : T extends Self
77
+ ? Service
78
+ : T extends Json<infer T>
79
+ ? T
80
+ : Service;
81
+
82
+ interface SecretsStoreBinding<
83
+ S extends Record<string, Secret> | undefined = undefined,
84
+ > {
85
+ get(
86
+ key: (S extends Record<string, any> ? keyof S : never) | (string & {}),
87
+ ): Promise<string>;
88
+ }
@@ -3,6 +3,7 @@ import type { Context } from "../context.ts";
3
3
  import { Resource, ResourceKind } from "../resource.ts";
4
4
  import { bind } from "../runtime/bind.ts";
5
5
  import type { Secret } from "../secret.ts";
6
+ import { logger } from "../util/logger.ts";
6
7
  import { CloudflareApiError, handleApiError } from "./api-error.ts";
7
8
  import { type CloudflareApi, createCloudflareApi } from "./api.ts";
8
9
  import type { Bound } from "./bound.ts";
@@ -195,7 +196,7 @@ const R2BucketResource = Resource(
195
196
  if (this.phase === "delete") {
196
197
  if (props.delete !== false) {
197
198
  if (props.empty) {
198
- console.log("Emptying R2 bucket:", bucketName);
199
+ logger.log("Emptying R2 bucket:", bucketName);
199
200
  const r2Client = await createR2Client({
200
201
  ...props,
201
202
  accountId: api.accountId,
@@ -227,6 +228,12 @@ const R2BucketResource = Resource(
227
228
  }
228
229
  }
229
230
 
231
+ if (this.phase === "update" && bucketName !== this.output.name) {
232
+ throw new Error(
233
+ `Cannot update R2Bucket name after creation. Bucket name is immutable. Before: ${this.output.name}, After: ${bucketName}`,
234
+ );
235
+ }
236
+
230
237
  await updatePublicAccess(
231
238
  api,
232
239
  bucketName,
@@ -497,7 +504,7 @@ export async function emptyBucket(
497
504
 
498
505
  try {
499
506
  do {
500
- console.log(`Listing objects in bucket ${bucketName}`);
507
+ logger.log(`Listing objects in bucket ${bucketName}`);
501
508
  // List objects in the bucket
502
509
  const { objects, continuationToken: nextToken } = await listObjects(
503
510
  r2,
@@ -508,7 +515,7 @@ export async function emptyBucket(
508
515
 
509
516
  continuationToken = nextToken;
510
517
 
511
- console.log(`Found ${objects.length} objects in bucket ${bucketName}`);
518
+ logger.log(`Found ${objects.length} objects in bucket ${bucketName}`);
512
519
 
513
520
  // Delete objects in batches
514
521
  if (objects.length > 0) {
@@ -527,7 +534,7 @@ export async function emptyBucket(
527
534
  `https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}?delete`,
528
535
  );
529
536
 
530
- console.log(
537
+ logger.log(
531
538
  `Deleting ${batch.length} objects from bucket ${bucketName}`,
532
539
  );
533
540
 
@@ -554,7 +561,7 @@ export async function emptyBucket(
554
561
  }
555
562
  } while (continuationToken);
556
563
 
557
- console.log(
564
+ logger.log(
558
565
  `Successfully emptied bucket ${bucketName}, deleted ${totalDeleted} objects total`,
559
566
  );
560
567
  } catch (error) {
@@ -562,7 +569,7 @@ export async function emptyBucket(
562
569
  // the bucket was not found
563
570
  return;
564
571
  }
565
- console.error(`Failed to empty bucket ${bucketName}:`, error);
572
+ logger.error(`Failed to empty bucket ${bucketName}:`, error);
566
573
  throw error;
567
574
  }
568
575
  }
@@ -647,9 +654,9 @@ export async function setCorsConfiguration(
647
654
  );
648
655
  }
649
656
 
650
- console.log(`Successfully set CORS configuration for bucket ${bucketName}`);
657
+ logger.log(`Successfully set CORS configuration for bucket ${bucketName}`);
651
658
  } catch (error) {
652
- console.error(
659
+ logger.error(
653
660
  `Failed to set CORS configuration for bucket ${bucketName}:`,
654
661
  error,
655
662
  );
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { Bundle } from "../../esbuild/bundle.ts";
4
+ import { logger } from "../../util/logger.ts";
4
5
  import type { Bindings } from "../bindings.ts";
5
6
  import type { WorkerProps } from "../worker.ts";
6
7
  import { createAliasPlugin } from "./alias-plugin.ts";
@@ -124,7 +125,7 @@ export async function bundleWorkerScript<B extends Bindings>(
124
125
  rewriteNodeCompatBuildFailure(e.errors, nodeJsCompatMode);
125
126
  throw e;
126
127
  }
127
- console.error("Error reading bundle:", e);
128
+ logger.error("Error reading bundle:", e);
128
129
  throw new Error("Error reading bundle");
129
130
  }
130
131
  }
@@ -1,4 +1,5 @@
1
1
  import type { NodeJSCompatMode } from "miniflare";
2
+ import { logger } from "../../util/logger.ts";
2
3
 
3
4
  /**
4
5
  * Computes and validates the Node.js compatibility mode we are running.
@@ -40,7 +41,7 @@ export async function getNodeJSCompatMode(
40
41
  }
41
42
 
42
43
  if (props?.noBundle && hasNodejsCompatV2Flag) {
43
- console.warn(
44
+ logger.warn(
44
45
  "`nodejs_compat_v2` compatibility flag and `--no-bundle` can't be used together. If you want to polyfill Node.js built-ins and disable Wrangler's bundling, please polyfill as part of your own bundling process.",
45
46
  );
46
47
  }
@@ -1,5 +1,6 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource } from "../resource.ts";
3
+ import { logger } from "../util/logger.ts";
3
4
  import { handleApiError } from "./api-error.ts";
4
5
  import {
5
6
  createCloudflareApi,
@@ -127,20 +128,20 @@ async function deleteCustomDomain(
127
128
  const domainIdToDelete = context.output?.id;
128
129
 
129
130
  if (!domainIdToDelete) {
130
- console.warn(
131
+ logger.warn(
131
132
  `Cannot delete CustomDomain ${logicalId} (${domainHostname}): Missing domain ID in state. Assuming already deleted.`,
132
133
  );
133
134
  return; // Exit early if no ID
134
135
  }
135
136
 
136
- console.log(
137
+ logger.log(
137
138
  `Deleting CustomDomain binding ${domainIdToDelete} for ${domainHostname}`,
138
139
  );
139
140
  const response = await api.delete(
140
141
  `/accounts/${api.accountId}/workers/domains/${domainIdToDelete}`,
141
142
  );
142
143
 
143
- console.log(
144
+ logger.log(
144
145
  `Delete result for ${domainIdToDelete} (${domainHostname}):`,
145
146
  response.status,
146
147
  response.statusText,
@@ -172,7 +173,7 @@ async function ensureCustomDomain(
172
173
  const domainHostname = props.name;
173
174
 
174
175
  // Check if domain binding already exists for this account
175
- console.log(`Checking existing domain bindings for account ${api.accountId}`);
176
+ logger.log(`Checking existing domain bindings for account ${api.accountId}`);
176
177
  const listResponse = await api.get(
177
178
  `/accounts/${api.accountId}/workers/domains`,
178
179
  );
@@ -210,7 +211,7 @@ async function ensureCustomDomain(
210
211
  let currentDomainId = existingBinding?.id;
211
212
  const bindingExists = !!existingBinding;
212
213
 
213
- console.log(
214
+ logger.log(
214
215
  `Domain binding status for ${domainHostname} (Zone: ${props.zoneId}):`,
215
216
  bindingExists
216
217
  ? `Found (ID: ${currentDomainId}, Worker: ${existingBinding.service}, Env: ${existingBinding.environment})`
@@ -230,7 +231,7 @@ async function ensureCustomDomain(
230
231
  // Cloudflare's PUT /accounts/{account_id}/workers/domains acts as an upsert
231
232
  if (!bindingExists || needsUpdate) {
232
233
  operationPerformed = bindingExists ? "update" : "create";
233
- console.log(
234
+ logger.log(
234
235
  `${operationPerformed === "update" ? "Updating" : "Creating"} domain binding: ${domainHostname} (Zone: ${props.zoneId}) → ${props.workerName}:${environment}`,
235
236
  );
236
237
 
@@ -272,11 +273,11 @@ async function ensureCustomDomain(
272
273
 
273
274
  resultantBinding = putResult.result;
274
275
  currentDomainId = resultantBinding.id; // Update ID from the PUT response
275
- console.log(
276
+ logger.log(
276
277
  `Successfully ${operationPerformed}d binding, new ID: ${currentDomainId}`,
277
278
  );
278
279
  } else {
279
- console.log(
280
+ logger.log(
280
281
  `Domain binding already exists and is up to date: ${domainHostname} (ID: ${currentDomainId}) → ${props.workerName}:${environment}`,
281
282
  );
282
283
  }
@@ -284,7 +285,7 @@ async function ensureCustomDomain(
284
285
  // Ensure we have the final binding details
285
286
  if (!resultantBinding || !currentDomainId) {
286
287
  // This case should ideally not happen if API calls succeed
287
- console.error("Error: Could not determine final domain binding state.", {
288
+ logger.error("Error: Could not determine final domain binding state.", {
288
289
  existingBinding,
289
290
  resultantBinding,
290
291
  currentDomainId,
@@ -1,6 +1,7 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource, ResourceKind } from "../resource.ts";
3
3
  import { bind, type Bound } from "../runtime/bind.ts";
4
+ import { logger } from "../util/logger.ts";
4
5
  import { CloudflareApiError, handleApiError } from "./api-error.ts";
5
6
  import {
6
7
  createCloudflareApi,
@@ -240,10 +241,10 @@ const D1DatabaseResource = Resource(
240
241
  const databaseName = props.name ?? id;
241
242
 
242
243
  if (this.phase === "delete") {
243
- console.log("Deleting D1 database:", databaseName);
244
+ logger.log("Deleting D1 database:", databaseName);
244
245
  if (props.delete !== false) {
245
246
  // Delete D1 database
246
- console.log("Deleting D1 database:", databaseName);
247
+ logger.log("Deleting D1 database:", databaseName);
247
248
  await deleteDatabase(api, this.output?.id);
248
249
  }
249
250
 
@@ -253,7 +254,7 @@ const D1DatabaseResource = Resource(
253
254
  let dbData: CloudflareD1Response;
254
255
 
255
256
  if (this.phase === "create") {
256
- console.log("Creating D1 database:", databaseName);
257
+ logger.log("Creating D1 database:", databaseName);
257
258
  try {
258
259
  dbData = await createDatabase(api, databaseName, props);
259
260
 
@@ -273,7 +274,7 @@ const D1DatabaseResource = Resource(
273
274
  error instanceof CloudflareApiError &&
274
275
  error.message.includes("already exists")
275
276
  ) {
276
- console.log(`Database ${databaseName} already exists, adopting it`);
277
+ logger.log(`Database ${databaseName} already exists, adopting it`);
277
278
  // Find the existing database by name
278
279
  const databases = await listDatabases(api, databaseName);
279
280
  const existingDb = databases.find((db) => db.name === databaseName);
@@ -289,7 +290,7 @@ const D1DatabaseResource = Resource(
289
290
 
290
291
  // Update the database with the provided properties
291
292
  if (props.readReplication) {
292
- console.log(
293
+ logger.log(
293
294
  `Updating adopted database ${databaseName} with new properties`,
294
295
  );
295
296
  dbData = await updateDatabase(api, existingDb.id, props);
@@ -311,12 +312,12 @@ const D1DatabaseResource = Resource(
311
312
  `Cannot update primaryLocationHint from '${this.output.primaryLocationHint}' to '${props.primaryLocationHint}' after database creation.`,
312
313
  );
313
314
  }
314
- console.log("Updating D1 database:", databaseName);
315
+ logger.log("Updating D1 database:", databaseName);
315
316
  // Update the database with new properties
316
317
  dbData = await updateDatabase(api, this.output.id, props);
317
318
  } else {
318
319
  // If no ID exists, fall back to creating a new database
319
- console.log(
320
+ logger.log(
320
321
  "No existing database ID found, creating new D1 database:",
321
322
  databaseName,
322
323
  );
@@ -342,7 +343,7 @@ const D1DatabaseResource = Resource(
342
343
  api,
343
344
  });
344
345
  } catch (migrationErr) {
345
- console.error("Failed to apply D1 migrations:", migrationErr);
346
+ logger.error("Failed to apply D1 migrations:", migrationErr);
346
347
  throw migrationErr;
347
348
  }
348
349
  }
@@ -443,7 +444,7 @@ export async function deleteDatabase(
443
444
  databaseId?: string,
444
445
  ): Promise<void> {
445
446
  if (!databaseId) {
446
- console.log("No database ID provided, skipping delete");
447
+ logger.log("No database ID provided, skipping delete");
447
448
  return;
448
449
  }
449
450
 
@@ -580,7 +581,7 @@ async function cloneDb(
580
581
  }
581
582
 
582
583
  // Perform the cloning
583
- console.log(`Cloning data from database ${sourceId} to ${targetDbId}`);
584
+ logger.log(`Cloning data from database ${sourceId} to ${targetDbId}`);
584
585
  await cloneD1Database(api, {
585
586
  sourceDatabaseId: sourceId,
586
587
  targetDatabaseId: targetDbId,
@@ -1,3 +1,4 @@
1
+ import { logger } from "../util/logger.ts";
1
2
  import type { CloudflareApi } from "./api.ts"; // Ensure CloudflareApi is exported if not already
2
3
 
3
4
  /**
@@ -153,7 +154,7 @@ export async function exportD1Database(
153
154
  // Log messages for visibility
154
155
  if (data.messages && data.messages.length > 0) {
155
156
  for (const message of data.messages) {
156
- console.log(`D1 Export: ${message}`);
157
+ logger.log(`D1 Export: ${message}`);
157
158
  }
158
159
  }
159
160
 
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { logger } from "../util/logger.ts";
2
3
  import type { CloudflareApi } from "./api.ts";
3
4
 
4
5
  /**
@@ -386,7 +387,7 @@ async function pollImportStatus(
386
387
  // Log messages for visibility
387
388
  if (data.messages && data.messages.length > 0) {
388
389
  for (const message of data.messages) {
389
- console.log(`D1 Import: ${message}`);
390
+ logger.log(`D1 Import: ${message}`);
390
391
  }
391
392
  }
392
393
 
@@ -1,5 +1,6 @@
1
1
  import * as fs from "node:fs/promises";
2
2
  import * as path from "node:path";
3
+ import { logger } from "../util/logger.ts";
3
4
  import { handleApiError } from "./api-error.ts";
4
5
  import type { CloudflareApi } from "./api.ts";
5
6
 
@@ -132,6 +133,6 @@ export async function applyMigrations(
132
133
  const insertSQL = `INSERT INTO ${options.migrationsTable} (id, applied_at) VALUES ('${migrationId.replace("'", "''")}', datetime('now'));`;
133
134
  await executeD1SQL(options, insertSQL);
134
135
 
135
- console.log(`Applied migration: ${migrationId}`);
136
+ logger.log(`Applied migration: ${migrationId}`);
136
137
  }
137
138
  }
@@ -0,0 +1,281 @@
1
+ import type { Context } from "../context.ts";
2
+ import { Resource, ResourceKind } from "../resource.ts";
3
+ import { bind } from "../runtime/bind.ts";
4
+ import { logger } from "../util/logger.ts";
5
+ import { CloudflareApiError, handleApiError } from "./api-error.ts";
6
+ import {
7
+ createCloudflareApi,
8
+ type CloudflareApi,
9
+ type CloudflareApiOptions,
10
+ } from "./api.ts";
11
+
12
+ /**
13
+ * Properties for creating or updating a Dispatch Namespace
14
+ */
15
+ export interface DispatchNamespaceProps extends CloudflareApiOptions {
16
+ /**
17
+ * Name of the namespace
18
+ */
19
+ namespace?: string;
20
+
21
+ /**
22
+ * Whether to adopt an existing namespace with the same name if it exists
23
+ * If true and a namespace with the same name exists, it will be adopted rather than creating a new one
24
+ *
25
+ * @default false
26
+ */
27
+ adopt?: boolean;
28
+
29
+ /**
30
+ * Whether to delete the namespace.
31
+ * If set to false, the namespace will remain but the resource will be removed from state
32
+ *
33
+ * @default true
34
+ */
35
+ delete?: boolean;
36
+ }
37
+
38
+ export function isDispatchNamespace(
39
+ resource: Resource,
40
+ ): resource is DispatchNamespaceResource {
41
+ return resource[ResourceKind] === "cloudflare::DispatchNamespace";
42
+ }
43
+
44
+ /**
45
+ * Output returned after Dispatch Namespace creation/update
46
+ */
47
+ export interface DispatchNamespaceResource
48
+ extends Resource<"cloudflare::DispatchNamespace">,
49
+ Omit<DispatchNamespaceProps, "delete"> {
50
+ type: "dispatch_namespace";
51
+ /**
52
+ * The name of the namespace
53
+ */
54
+ namespace: string;
55
+
56
+ /**
57
+ * The namespace name from Cloudflare API
58
+ */
59
+ namespaceName: string;
60
+
61
+ /**
62
+ * The namespace ID from Cloudflare API
63
+ */
64
+ namespaceId: string;
65
+
66
+ /**
67
+ * Time at which the namespace was created
68
+ */
69
+ createdAt: number;
70
+
71
+ /**
72
+ * Time at which the namespace was last modified
73
+ */
74
+ modifiedAt: number;
75
+ }
76
+
77
+ export type DispatchNamespace = DispatchNamespaceResource & {
78
+ get(name: string): Fetcher;
79
+ };
80
+
81
+ /**
82
+ * A Cloudflare Dispatch Namespace enables routing worker requests to different scripts based on patterns.
83
+ *
84
+ * @see https://developers.cloudflare.com/workers/configuration/routing/dispatch-namespace/
85
+ *
86
+ * @example
87
+ * // Create a basic dispatch namespace
88
+ * const myNamespace = await DispatchNamespace("my-namespace", {
89
+ * namespace: "my-namespace"
90
+ * });
91
+ *
92
+ * @example
93
+ * // Create dispatch namespace with default name from id
94
+ * const dispatchNS = await DispatchNamespace("api-dispatch");
95
+ *
96
+ * @example
97
+ * // Adopt an existing namespace if it already exists instead of failing
98
+ * const existingNamespace = await DispatchNamespace("existing-ns", {
99
+ * namespace: "existing-namespace",
100
+ * adopt: true
101
+ * });
102
+ *
103
+ * @example
104
+ * // When removing from Alchemy state, keep the namespace in Cloudflare
105
+ * const preservedNamespace = await DispatchNamespace("preserve-ns", {
106
+ * namespace: "preserved-namespace",
107
+ * delete: false
108
+ * });
109
+ */
110
+
111
+ export async function DispatchNamespace(
112
+ name: string,
113
+ props: DispatchNamespaceProps = {},
114
+ ): Promise<DispatchNamespace> {
115
+ const dispatchNamespace = await _DispatchNamespace(name, props);
116
+ const binding = await bind(dispatchNamespace);
117
+ return {
118
+ ...dispatchNamespace,
119
+ // Add runtime methods that dispatch namespaces have
120
+ get: binding.get,
121
+ };
122
+ }
123
+
124
+ const _DispatchNamespace = Resource(
125
+ "cloudflare::DispatchNamespace",
126
+ async function (
127
+ this: Context<DispatchNamespaceResource>,
128
+ id: string,
129
+ props: DispatchNamespaceProps,
130
+ ): Promise<DispatchNamespaceResource> {
131
+ // Create Cloudflare API client with automatic account discovery
132
+ const api = await createCloudflareApi(props);
133
+
134
+ const namespace = props.namespace ?? id;
135
+
136
+ if (this.phase === "delete") {
137
+ // For delete operations, we need to check if the namespace exists in the output
138
+ const namespaceName = this.output?.namespace;
139
+ if (namespaceName && props.delete !== false) {
140
+ await deleteDispatchNamespace(api, namespaceName);
141
+ }
142
+
143
+ // Return minimal output for deleted state
144
+ return this.destroy();
145
+ }
146
+
147
+ // For create or update operations
148
+ let createdAt =
149
+ this.phase === "update"
150
+ ? this.output?.createdAt || Date.now()
151
+ : Date.now();
152
+
153
+ if (this.phase === "update") {
154
+ // Check that the namespace name hasn't changed
155
+ if (this.output?.namespace && this.output.namespace !== namespace) {
156
+ throw new Error(
157
+ `Cannot update dispatch namespace name after creation. Namespace name is immutable. Before: ${this.output.namespace}, After: ${namespace}`,
158
+ );
159
+ }
160
+ // For updates, just refresh metadata
161
+ } else {
162
+ try {
163
+ // Try to create the dispatch namespace
164
+ await createDispatchNamespace(api, {
165
+ ...props,
166
+ namespace,
167
+ });
168
+ createdAt = Date.now();
169
+ } catch (error) {
170
+ // Check if this is a "namespace already exists" error and adopt is enabled
171
+ if (
172
+ props.adopt &&
173
+ error instanceof CloudflareApiError &&
174
+ error.status === 400 &&
175
+ (error.message.includes("already exists") ||
176
+ error.message.includes("Ensure it does not already exist"))
177
+ ) {
178
+ logger.log(
179
+ `Dispatch namespace '${namespace}' already exists, adopting it`,
180
+ );
181
+ // Get the namespace to retrieve ID and validate it exists
182
+ const existingNamespace = await getDispatchNamespace(api, namespace);
183
+ if (!existingNamespace) {
184
+ throw new Error(
185
+ `Failed to find existing dispatch namespace '${namespace}'`,
186
+ );
187
+ }
188
+ } else {
189
+ // Re-throw the error if adopt is false or it's not a "namespace already exists" error
190
+ throw error;
191
+ }
192
+ }
193
+ }
194
+
195
+ // Get the namespace information after creation/adoption
196
+ const namespaceInfo = await getDispatchNamespace(api, namespace);
197
+ if (!namespaceInfo) {
198
+ throw new Error(`Failed to get namespace information for '${namespace}'`);
199
+ }
200
+
201
+ return this({
202
+ type: "dispatch_namespace",
203
+ namespace,
204
+ namespaceName: namespaceInfo.namespaceName,
205
+ namespaceId: namespaceInfo.namespaceId,
206
+ createdAt: createdAt,
207
+ modifiedAt: Date.now(),
208
+ });
209
+ },
210
+ );
211
+
212
+ export async function createDispatchNamespace(
213
+ api: CloudflareApi,
214
+ props: DispatchNamespaceProps & {
215
+ namespace: string;
216
+ },
217
+ ): Promise<void> {
218
+ const createResponse = await api.post(
219
+ `/accounts/${api.accountId}/workers/dispatch/namespaces`,
220
+ {
221
+ name: props.namespace,
222
+ },
223
+ );
224
+
225
+ if (!createResponse.ok) {
226
+ await handleApiError(
227
+ createResponse,
228
+ "create",
229
+ "dispatch_namespace",
230
+ props.namespace,
231
+ );
232
+ }
233
+ }
234
+
235
+ export async function getDispatchNamespace(
236
+ api: CloudflareApi,
237
+ namespace: string,
238
+ ): Promise<{ namespaceName: string; namespaceId: string } | undefined> {
239
+ const getResponse = await api.get(
240
+ `/accounts/${api.accountId}/workers/dispatch/namespaces/${namespace}`,
241
+ );
242
+
243
+ if (getResponse.status === 404) {
244
+ return undefined;
245
+ }
246
+
247
+ if (!getResponse.ok) {
248
+ await handleApiError(getResponse, "get", "dispatch_namespace", namespace);
249
+ }
250
+
251
+ const result = (await getResponse.json()) as {
252
+ result: {
253
+ namespace_name: string;
254
+ namespace_id: string;
255
+ };
256
+ };
257
+
258
+ return {
259
+ namespaceName: result.result.namespace_name,
260
+ namespaceId: result.result.namespace_id,
261
+ };
262
+ }
263
+
264
+ export async function deleteDispatchNamespace(
265
+ api: CloudflareApi,
266
+ namespace: string,
267
+ ) {
268
+ // Delete dispatch namespace
269
+ const deleteResponse = await api.delete(
270
+ `/accounts/${api.accountId}/workers/dispatch/namespaces/${namespace}`,
271
+ );
272
+
273
+ if (!deleteResponse.ok && deleteResponse.status !== 404) {
274
+ await handleApiError(
275
+ deleteResponse,
276
+ "delete",
277
+ "dispatch_namespace",
278
+ namespace,
279
+ );
280
+ }
281
+ }