alchemy 0.16.10 → 0.17.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 (419) hide show
  1. package/lib/ai/astro-file.d.ts +1 -1
  2. package/lib/ai/astro-file.d.ts.map +1 -1
  3. package/lib/ai/astro-file.js +1 -1
  4. package/lib/ai/astro-file.js.map +1 -1
  5. package/lib/ai/client.js +2 -2
  6. package/lib/ai/client.js.map +1 -1
  7. package/lib/ai/css-file.d.ts +1 -1
  8. package/lib/ai/css-file.d.ts.map +1 -1
  9. package/lib/ai/css-file.js +1 -1
  10. package/lib/ai/css-file.js.map +1 -1
  11. package/lib/ai/data.d.ts +1 -1
  12. package/lib/ai/data.d.ts.map +1 -1
  13. package/lib/ai/data.js +1 -1
  14. package/lib/ai/data.js.map +1 -1
  15. package/lib/ai/html-file.d.ts +1 -1
  16. package/lib/ai/html-file.d.ts.map +1 -1
  17. package/lib/ai/html-file.js +1 -1
  18. package/lib/ai/html-file.js.map +1 -1
  19. package/lib/ai/json-file.d.ts +1 -1
  20. package/lib/ai/json-file.d.ts.map +1 -1
  21. package/lib/ai/json-file.js +1 -1
  22. package/lib/ai/json-file.js.map +1 -1
  23. package/lib/ai/typescript-file.d.ts +1 -1
  24. package/lib/ai/typescript-file.d.ts.map +1 -1
  25. package/lib/ai/typescript-file.js +1 -1
  26. package/lib/ai/typescript-file.js.map +1 -1
  27. package/lib/ai/vue-file.d.ts +1 -1
  28. package/lib/ai/vue-file.d.ts.map +1 -1
  29. package/lib/ai/vue-file.js +1 -1
  30. package/lib/ai/vue-file.js.map +1 -1
  31. package/lib/ai/yaml-file.d.ts +1 -1
  32. package/lib/ai/yaml-file.d.ts.map +1 -1
  33. package/lib/ai/yaml-file.js +2 -2
  34. package/lib/ai/yaml-file.js.map +1 -1
  35. package/lib/alchemy.d.ts +4 -0
  36. package/lib/alchemy.d.ts.map +1 -1
  37. package/lib/alchemy.js +14 -4
  38. package/lib/alchemy.js.map +1 -1
  39. package/lib/apply.d.ts +2 -0
  40. package/lib/apply.d.ts.map +1 -1
  41. package/lib/apply.js +17 -2
  42. package/lib/apply.js.map +1 -1
  43. package/lib/aws/bucket.d.ts +1 -1
  44. package/lib/aws/bucket.d.ts.map +1 -1
  45. package/lib/aws/bucket.js +1 -1
  46. package/lib/aws/bucket.js.map +1 -1
  47. package/lib/aws/function.d.ts +1 -1
  48. package/lib/aws/function.d.ts.map +1 -1
  49. package/lib/aws/function.js +2 -2
  50. package/lib/aws/function.js.map +1 -1
  51. package/lib/aws/oidc/oidc-provider.d.ts +1 -1
  52. package/lib/aws/oidc/oidc-provider.d.ts.map +1 -1
  53. package/lib/aws/oidc/oidc-provider.js +1 -1
  54. package/lib/aws/oidc/oidc-provider.js.map +1 -1
  55. package/lib/aws/policy-attachment.d.ts +1 -1
  56. package/lib/aws/policy-attachment.d.ts.map +1 -1
  57. package/lib/aws/policy-attachment.js +1 -1
  58. package/lib/aws/policy-attachment.js.map +1 -1
  59. package/lib/aws/policy.d.ts +1 -1
  60. package/lib/aws/policy.d.ts.map +1 -1
  61. package/lib/aws/policy.js +1 -1
  62. package/lib/aws/policy.js.map +1 -1
  63. package/lib/aws/queue.d.ts +1 -1
  64. package/lib/aws/queue.d.ts.map +1 -1
  65. package/lib/aws/queue.js +20 -25
  66. package/lib/aws/queue.js.map +1 -1
  67. package/lib/aws/role.d.ts +1 -1
  68. package/lib/aws/role.d.ts.map +1 -1
  69. package/lib/aws/role.js +1 -1
  70. package/lib/aws/role.js.map +1 -1
  71. package/lib/aws/ses.d.ts +1 -1
  72. package/lib/aws/ses.d.ts.map +1 -1
  73. package/lib/aws/ses.js +1 -1
  74. package/lib/aws/ses.js.map +1 -1
  75. package/lib/aws/table.d.ts +1 -1
  76. package/lib/aws/table.d.ts.map +1 -1
  77. package/lib/aws/table.js +1 -1
  78. package/lib/aws/table.js.map +1 -1
  79. package/lib/cloudflare/account-api-token.d.ts +1 -1
  80. package/lib/cloudflare/account-api-token.d.ts.map +1 -1
  81. package/lib/cloudflare/account-api-token.js +1 -1
  82. package/lib/cloudflare/account-api-token.js.map +1 -1
  83. package/lib/cloudflare/ai-gateway.d.ts +4 -3
  84. package/lib/cloudflare/ai-gateway.d.ts.map +1 -1
  85. package/lib/cloudflare/ai-gateway.js +13 -1
  86. package/lib/cloudflare/ai-gateway.js.map +1 -1
  87. package/lib/cloudflare/api-error.js +1 -1
  88. package/lib/cloudflare/api-error.js.map +1 -1
  89. package/lib/cloudflare/assets.js +2 -2
  90. package/lib/cloudflare/assets.js.map +1 -1
  91. package/lib/cloudflare/auth.js +1 -1
  92. package/lib/cloudflare/auth.js.map +1 -1
  93. package/lib/cloudflare/bindings.d.ts +17 -11
  94. package/lib/cloudflare/bindings.d.ts.map +1 -1
  95. package/lib/cloudflare/bindings.js +6 -0
  96. package/lib/cloudflare/bindings.js.map +1 -1
  97. package/lib/cloudflare/bound.d.ts +11 -10
  98. package/lib/cloudflare/bound.d.ts.map +1 -1
  99. package/lib/cloudflare/bucket.d.ts +6 -4
  100. package/lib/cloudflare/bucket.d.ts.map +1 -1
  101. package/lib/cloudflare/bucket.js +22 -2
  102. package/lib/cloudflare/bucket.js.map +1 -1
  103. package/lib/cloudflare/bundle/bundle-worker.d.ts +1 -0
  104. package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
  105. package/lib/cloudflare/bundle/bundle-worker.js +4 -2
  106. package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
  107. package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts +1 -1
  108. package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts.map +1 -1
  109. package/lib/cloudflare/bundle/nodejs-compat-mode.js +2 -2
  110. package/lib/cloudflare/bundle/nodejs-compat-mode.js.map +1 -1
  111. package/lib/cloudflare/bundle/nodejs-compat.js +1 -1
  112. package/lib/cloudflare/bundle/nodejs-compat.js.map +1 -1
  113. package/lib/cloudflare/custom-domain.js +1 -1
  114. package/lib/cloudflare/custom-domain.js.map +1 -1
  115. package/lib/cloudflare/d1-database.d.ts +4 -62
  116. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  117. package/lib/cloudflare/d1-database.js +27 -11
  118. package/lib/cloudflare/d1-database.js.map +1 -1
  119. package/lib/cloudflare/dns-records.d.ts +1 -1
  120. package/lib/cloudflare/dns-records.d.ts.map +1 -1
  121. package/lib/cloudflare/dns-records.js +2 -2
  122. package/lib/cloudflare/dns-records.js.map +1 -1
  123. package/lib/cloudflare/event-source.d.ts +3 -3
  124. package/lib/cloudflare/event-source.d.ts.map +1 -1
  125. package/lib/cloudflare/hyperdrive.d.ts +4 -3
  126. package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
  127. package/lib/cloudflare/hyperdrive.js +9 -1
  128. package/lib/cloudflare/hyperdrive.js.map +1 -1
  129. package/lib/cloudflare/kv-namespace.d.ts +9 -5
  130. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  131. package/lib/cloudflare/kv-namespace.js +26 -6
  132. package/lib/cloudflare/kv-namespace.js.map +1 -1
  133. package/lib/cloudflare/permission-groups.d.ts +1 -1
  134. package/lib/cloudflare/permission-groups.d.ts.map +1 -1
  135. package/lib/cloudflare/permission-groups.js +1 -1
  136. package/lib/cloudflare/permission-groups.js.map +1 -1
  137. package/lib/cloudflare/pipeline.d.ts +5 -3
  138. package/lib/cloudflare/pipeline.d.ts.map +1 -1
  139. package/lib/cloudflare/pipeline.js +16 -2
  140. package/lib/cloudflare/pipeline.js.map +1 -1
  141. package/lib/cloudflare/queue-consumer.d.ts +3 -3
  142. package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
  143. package/lib/cloudflare/queue-consumer.js +1 -1
  144. package/lib/cloudflare/queue-consumer.js.map +1 -1
  145. package/lib/cloudflare/queue.d.ts +34 -22
  146. package/lib/cloudflare/queue.d.ts.map +1 -1
  147. package/lib/cloudflare/queue.js +66 -4
  148. package/lib/cloudflare/queue.js.map +1 -1
  149. package/lib/cloudflare/route.d.ts +1 -1
  150. package/lib/cloudflare/route.d.ts.map +1 -1
  151. package/lib/cloudflare/route.js +1 -1
  152. package/lib/cloudflare/route.js.map +1 -1
  153. package/lib/cloudflare/types.js +1 -1
  154. package/lib/cloudflare/types.js.map +1 -1
  155. package/lib/cloudflare/vectorize-index.d.ts +6 -4
  156. package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
  157. package/lib/cloudflare/vectorize-index.js +20 -3
  158. package/lib/cloudflare/vectorize-index.js.map +1 -1
  159. package/lib/cloudflare/vectorize-metadata-index.d.ts +4 -3
  160. package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
  161. package/lib/cloudflare/vectorize-metadata-index.js +5 -2
  162. package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
  163. package/lib/cloudflare/website.d.ts.map +1 -1
  164. package/lib/cloudflare/website.js +1 -0
  165. package/lib/cloudflare/website.js.map +1 -1
  166. package/lib/cloudflare/worker-assets.d.ts +32 -0
  167. package/lib/cloudflare/worker-assets.d.ts.map +1 -0
  168. package/lib/cloudflare/worker-assets.js +143 -0
  169. package/lib/cloudflare/worker-assets.js.map +1 -0
  170. package/lib/cloudflare/worker-metadata.d.ts +31 -0
  171. package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
  172. package/lib/cloudflare/worker-metadata.js +248 -0
  173. package/lib/cloudflare/worker-metadata.js.map +1 -1
  174. package/lib/cloudflare/worker-stub.d.ts +40 -0
  175. package/lib/cloudflare/worker-stub.d.ts.map +1 -0
  176. package/lib/cloudflare/worker-stub.js +86 -0
  177. package/lib/cloudflare/worker-stub.js.map +1 -0
  178. package/lib/cloudflare/worker.d.ts +57 -28
  179. package/lib/cloudflare/worker.d.ts.map +1 -1
  180. package/lib/cloudflare/worker.js +203 -479
  181. package/lib/cloudflare/worker.js.map +1 -1
  182. package/lib/cloudflare/wrangler.json.d.ts +1 -1
  183. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  184. package/lib/cloudflare/wrangler.json.js +5 -2
  185. package/lib/cloudflare/wrangler.json.js.map +1 -1
  186. package/lib/cloudflare/zone.d.ts +1 -1
  187. package/lib/cloudflare/zone.d.ts.map +1 -1
  188. package/lib/cloudflare/zone.js +1 -1
  189. package/lib/cloudflare/zone.js.map +1 -1
  190. package/lib/destroy.d.ts +1 -4
  191. package/lib/destroy.d.ts.map +1 -1
  192. package/lib/destroy.js +10 -21
  193. package/lib/destroy.js.map +1 -1
  194. package/lib/dns/import-dns.d.ts +1 -1
  195. package/lib/dns/import-dns.d.ts.map +1 -1
  196. package/lib/dns/import-dns.js +1 -1
  197. package/lib/dns/import-dns.js.map +1 -1
  198. package/lib/encrypt.d.ts.map +1 -1
  199. package/lib/encrypt.js +2 -1
  200. package/lib/encrypt.js.map +1 -1
  201. package/lib/env.js +14 -8
  202. package/lib/env.js.map +1 -1
  203. package/lib/esbuild/bundle.d.ts +2 -2
  204. package/lib/esbuild/bundle.d.ts.map +1 -1
  205. package/lib/esbuild/bundle.js +3 -3
  206. package/lib/esbuild/bundle.js.map +1 -1
  207. package/lib/fs/copy-file.d.ts +1 -1
  208. package/lib/fs/copy-file.d.ts.map +1 -1
  209. package/lib/fs/copy-file.js +1 -1
  210. package/lib/fs/copy-file.js.map +1 -1
  211. package/lib/github/client.js +1 -1
  212. package/lib/github/client.js.map +1 -1
  213. package/lib/github/repository-environment.d.ts +1 -1
  214. package/lib/github/repository-environment.d.ts.map +1 -1
  215. package/lib/github/repository-environment.js +2 -2
  216. package/lib/github/repository-environment.js.map +1 -1
  217. package/lib/github/secret.d.ts +1 -1
  218. package/lib/github/secret.d.ts.map +1 -1
  219. package/lib/github/secret.js +1 -1
  220. package/lib/github/secret.js.map +1 -1
  221. package/lib/internal/docs/providers.d.ts +1 -1
  222. package/lib/internal/docs/providers.d.ts.map +1 -1
  223. package/lib/internal/docs/providers.js +3 -1
  224. package/lib/internal/docs/providers.js.map +1 -1
  225. package/lib/neon/api-error.js +2 -2
  226. package/lib/neon/api-error.js.map +1 -1
  227. package/lib/os/exec.js +1 -1
  228. package/lib/os/exec.js.map +1 -1
  229. package/lib/resource.d.ts +13 -11
  230. package/lib/resource.d.ts.map +1 -1
  231. package/lib/resource.js +10 -5
  232. package/lib/resource.js.map +1 -1
  233. package/lib/runtime/bind.d.ts +25 -0
  234. package/lib/runtime/bind.d.ts.map +1 -0
  235. package/lib/runtime/bind.js +76 -0
  236. package/lib/runtime/bind.js.map +1 -0
  237. package/lib/runtime/global.d.ts +8 -0
  238. package/lib/runtime/global.d.ts.map +1 -0
  239. package/lib/runtime/global.js +3 -0
  240. package/lib/runtime/global.js.map +1 -0
  241. package/lib/runtime/plugin.d.ts +35 -0
  242. package/lib/runtime/plugin.d.ts.map +1 -0
  243. package/lib/runtime/plugin.js +133 -0
  244. package/lib/runtime/plugin.js.map +1 -0
  245. package/lib/runtime/shims.d.ts +6 -0
  246. package/lib/runtime/shims.d.ts.map +1 -0
  247. package/lib/runtime/shims.js +27 -0
  248. package/lib/runtime/shims.js.map +1 -0
  249. package/lib/runtime/state.d.ts +5 -0
  250. package/lib/runtime/state.d.ts.map +1 -0
  251. package/lib/runtime/state.js +4 -0
  252. package/lib/runtime/state.js.map +1 -0
  253. package/lib/scope.d.ts +16 -2
  254. package/lib/scope.d.ts.map +1 -1
  255. package/lib/scope.js +56 -9
  256. package/lib/scope.js.map +1 -1
  257. package/lib/secret.d.ts +7 -2
  258. package/lib/secret.d.ts.map +1 -1
  259. package/lib/secret.js +19 -4
  260. package/lib/secret.js.map +1 -1
  261. package/lib/sentry/client-key.d.ts +1 -1
  262. package/lib/sentry/client-key.d.ts.map +1 -1
  263. package/lib/sentry/client-key.js +1 -1
  264. package/lib/sentry/client-key.js.map +1 -1
  265. package/lib/sentry/project.d.ts +1 -1
  266. package/lib/sentry/project.d.ts.map +1 -1
  267. package/lib/sentry/project.js +1 -1
  268. package/lib/sentry/project.js.map +1 -1
  269. package/lib/sentry/team.d.ts +1 -1
  270. package/lib/sentry/team.d.ts.map +1 -1
  271. package/lib/sentry/team.js +1 -1
  272. package/lib/sentry/team.js.map +1 -1
  273. package/lib/serde.d.ts +26 -1
  274. package/lib/serde.d.ts.map +1 -1
  275. package/lib/serde.js +53 -8
  276. package/lib/serde.js.map +1 -1
  277. package/lib/stripe/meter.d.ts +1 -1
  278. package/lib/stripe/meter.d.ts.map +1 -1
  279. package/lib/stripe/meter.js +1 -1
  280. package/lib/stripe/meter.js.map +1 -1
  281. package/lib/stripe/price.d.ts +1 -1
  282. package/lib/stripe/price.d.ts.map +1 -1
  283. package/lib/stripe/price.js +1 -1
  284. package/lib/stripe/price.js.map +1 -1
  285. package/lib/stripe/product.d.ts +1 -1
  286. package/lib/stripe/product.d.ts.map +1 -1
  287. package/lib/stripe/product.js +1 -1
  288. package/lib/stripe/product.js.map +1 -1
  289. package/lib/stripe/webhook.d.ts +1 -1
  290. package/lib/stripe/webhook.d.ts.map +1 -1
  291. package/lib/stripe/webhook.js +1 -1
  292. package/lib/stripe/webhook.js.map +1 -1
  293. package/lib/test/bun.js +1 -1
  294. package/lib/test/bun.js.map +1 -1
  295. package/lib/test/prune.js +1 -1
  296. package/lib/test/prune.js.map +1 -1
  297. package/lib/upstash/redis.d.ts +1 -1
  298. package/lib/upstash/redis.d.ts.map +1 -1
  299. package/lib/upstash/redis.js +1 -1
  300. package/lib/upstash/redis.js.map +1 -1
  301. package/lib/util/content-type.d.ts +1 -1
  302. package/lib/util/content-type.d.ts.map +1 -1
  303. package/lib/util/content-type.js +1 -2
  304. package/lib/util/content-type.js.map +1 -1
  305. package/lib/util/retry.d.ts.map +1 -1
  306. package/lib/util/retry.js +1 -0
  307. package/lib/util/retry.js.map +1 -1
  308. package/lib/vercel/project-domain.d.ts +1 -1
  309. package/lib/vercel/project-domain.d.ts.map +1 -1
  310. package/lib/vercel/project-domain.js +1 -1
  311. package/lib/vercel/project-domain.js.map +1 -1
  312. package/lib/vercel/project.js +1 -1
  313. package/lib/vercel/project.js.map +1 -1
  314. package/lib/web/shadcn-component.d.ts +1 -1
  315. package/lib/web/shadcn-component.d.ts.map +1 -1
  316. package/lib/web/shadcn-component.js +1 -1
  317. package/lib/web/shadcn-component.js.map +1 -1
  318. package/lib/web/shadcn.d.ts +1 -1
  319. package/lib/web/shadcn.d.ts.map +1 -1
  320. package/lib/web/shadcn.js +1 -1
  321. package/lib/web/shadcn.js.map +1 -1
  322. package/lib/web/vitepress/dependencies.d.ts +1 -1
  323. package/lib/web/vitepress/dependencies.d.ts.map +1 -1
  324. package/lib/web/vitepress/dependencies.js +1 -1
  325. package/lib/web/vitepress/dependencies.js.map +1 -1
  326. package/lib/web/vitepress/vitepress.js +1 -1
  327. package/lib/web/vitepress/vitepress.js.map +1 -1
  328. package/package.json +2 -1
  329. package/src/ai/astro-file.ts +1 -1
  330. package/src/ai/client.ts +2 -2
  331. package/src/ai/css-file.ts +1 -1
  332. package/src/ai/data.ts +1 -1
  333. package/src/ai/html-file.ts +1 -1
  334. package/src/ai/json-file.ts +1 -1
  335. package/src/ai/typescript-file.ts +1 -1
  336. package/src/ai/vue-file.ts +1 -1
  337. package/src/ai/yaml-file.ts +2 -2
  338. package/src/alchemy.ts +18 -4
  339. package/src/apply.ts +27 -2
  340. package/src/aws/bucket.ts +1 -1
  341. package/src/aws/function.ts +2 -2
  342. package/src/aws/oidc/oidc-provider.ts +1 -1
  343. package/src/aws/policy-attachment.ts +1 -1
  344. package/src/aws/policy.ts +1 -1
  345. package/src/aws/queue.ts +28 -29
  346. package/src/aws/role.ts +1 -1
  347. package/src/aws/ses.ts +1 -1
  348. package/src/aws/table.ts +1 -1
  349. package/src/cloudflare/account-api-token.ts +1 -1
  350. package/src/cloudflare/ai-gateway.ts +23 -4
  351. package/src/cloudflare/api-error.ts +1 -1
  352. package/src/cloudflare/assets.ts +2 -2
  353. package/src/cloudflare/auth.ts +1 -1
  354. package/src/cloudflare/bindings.ts +33 -18
  355. package/src/cloudflare/bound.ts +18 -17
  356. package/src/cloudflare/bucket.ts +52 -24
  357. package/src/cloudflare/bundle/bundle-worker.ts +5 -2
  358. package/src/cloudflare/bundle/nodejs-compat-mode.ts +3 -3
  359. package/src/cloudflare/bundle/nodejs-compat.ts +1 -1
  360. package/src/cloudflare/custom-domain.ts +1 -1
  361. package/src/cloudflare/d1-database.ts +40 -19
  362. package/src/cloudflare/dns-records.ts +2 -2
  363. package/src/cloudflare/event-source.ts +3 -3
  364. package/src/cloudflare/hyperdrive.ts +19 -4
  365. package/src/cloudflare/kv-namespace.ts +46 -15
  366. package/src/cloudflare/permission-groups.ts +1 -1
  367. package/src/cloudflare/pipeline.ts +29 -6
  368. package/src/cloudflare/queue-consumer.ts +3 -3
  369. package/src/cloudflare/queue.ts +124 -23
  370. package/src/cloudflare/route.ts +1 -1
  371. package/src/cloudflare/types.ts +1 -1
  372. package/src/cloudflare/vectorize-index.ts +36 -8
  373. package/src/cloudflare/vectorize-metadata-index.ts +10 -4
  374. package/src/cloudflare/website.ts +4 -3
  375. package/src/cloudflare/worker-assets.ts +237 -0
  376. package/src/cloudflare/worker-metadata.ts +287 -0
  377. package/src/cloudflare/worker-stub.ts +153 -0
  378. package/src/cloudflare/worker.ts +386 -592
  379. package/src/cloudflare/wrangler.json.ts +4 -2
  380. package/src/cloudflare/zone.ts +1 -1
  381. package/src/destroy.ts +12 -23
  382. package/src/dns/import-dns.ts +1 -1
  383. package/src/encrypt.ts +2 -2
  384. package/src/env.ts +15 -8
  385. package/src/esbuild/bundle.ts +4 -3
  386. package/src/fs/copy-file.ts +1 -1
  387. package/src/github/client.ts +1 -1
  388. package/src/github/repository-environment.ts +2 -2
  389. package/src/github/secret.ts +1 -1
  390. package/src/internal/docs/providers.ts +1 -1
  391. package/src/neon/api-error.ts +2 -2
  392. package/src/os/exec.ts +1 -1
  393. package/src/resource.ts +22 -31
  394. package/src/runtime/bind.ts +95 -0
  395. package/src/runtime/global.ts +10 -0
  396. package/src/runtime/plugin.ts +162 -0
  397. package/src/runtime/shims.js +34 -0
  398. package/src/runtime/state.ts +9 -0
  399. package/src/scope.ts +72 -11
  400. package/src/secret.ts +29 -4
  401. package/src/sentry/client-key.ts +1 -1
  402. package/src/sentry/project.ts +1 -1
  403. package/src/sentry/team.ts +1 -1
  404. package/src/serde.ts +126 -10
  405. package/src/stripe/meter.ts +1 -1
  406. package/src/stripe/price.ts +1 -1
  407. package/src/stripe/product.ts +1 -1
  408. package/src/stripe/webhook.ts +1 -1
  409. package/src/test/bun.ts +1 -1
  410. package/src/test/prune.ts +1 -1
  411. package/src/upstash/redis.ts +1 -1
  412. package/src/util/content-type.ts +2 -3
  413. package/src/util/retry.ts +1 -0
  414. package/src/vercel/project-domain.ts +1 -1
  415. package/src/vercel/project.ts +1 -1
  416. package/src/web/shadcn-component.ts +1 -1
  417. package/src/web/shadcn.ts +1 -1
  418. package/src/web/vitepress/dependencies.ts +1 -1
  419. package/src/web/vitepress/vitepress.ts +1 -1
@@ -1,124 +1,200 @@
1
- import * as crypto from "node:crypto";
2
- import * as fs from "node:fs/promises";
3
- import { Resource } from "../resource.js";
4
- import { getContentType } from "../util/content-type.js";
1
+ import path from "node:path";
2
+ import { InnerResourceScope, Resource, ResourceKind } from "../resource.js";
3
+ import { getBindKey, tryGetBinding } from "../runtime/bind.js";
4
+ import { isRuntime } from "../runtime/global.js";
5
+ import { bootstrapPlugin } from "../runtime/plugin.js";
6
+ import { Scope } from "../scope.js";
7
+ import { Secret, secret } from "../secret.js";
8
+ import { serializeScope } from "../serde.js";
5
9
  import { withExponentialBackoff } from "../util/retry.js";
6
10
  import { slugify } from "../util/slugify.js";
7
11
  import { CloudflareApiError, handleApiError } from "./api-error.js";
8
12
  import { createCloudflareApi, } from "./api.js";
9
- import { Self } from "./bindings.js";
13
+ import { Json } from "./bindings.js";
14
+ import { isBucket } from "./bucket.js";
10
15
  import { bundleWorkerScript } from "./bundle/bundle-worker.js";
11
- import { isQueueEventSource } from "./event-source.js";
16
+ import { isD1Database } from "./d1-database.js";
17
+ import { isQueueEventSource, } from "./event-source.js";
18
+ import { isKVNamespace } from "./kv-namespace.js";
19
+ import { isPipeline } from "./pipeline.js";
12
20
  import { QueueConsumer, deleteQueueConsumer, listQueueConsumers, } from "./queue-consumer.js";
13
21
  import { isQueue } from "./queue.js";
22
+ import { isVectorizeIndex } from "./vectorize-index.js";
23
+ import { uploadAssets } from "./worker-assets.js";
24
+ import { prepareWorkerMetadata, } from "./worker-metadata.js";
25
+ import { WorkerStub, isWorkerStub } from "./worker-stub.js";
14
26
  import { upsertWorkflow } from "./workflow.js";
15
- /**
16
- * A Cloudflare Worker is a serverless function that can be deployed to the Cloudflare network.
17
- *
18
- * @example
19
- * // Create a basic HTTP handler worker with custom domain routing
20
- * // and workers.dev URL:
21
- * const api = await Worker("api", {
22
- * name: "api-worker",
23
- * entrypoint: "./src/api.ts",
24
- * routes: ["api.example.com/*"],
25
- * url: true
26
- * });
27
- *
28
- * await Route("route", {
29
- * zoneId: zone.zoneId,
30
- * worker: api,
31
- * pattern: "api.example.com/*",
32
- * });
33
- *
34
- * @example
35
- * // Create a real-time chat worker using Durable Objects
36
- * // for state management:
37
- * const chatRooms = new DurableObjectNamespace("chat-rooms");
38
- * const userStore = new DurableObjectNamespace("user-store");
39
- *
40
- * const chat = await Worker("chat", {
41
- * name: "chat-worker",
42
- * entrypoint: "./src/chat.ts",
43
- * bindings: {
44
- * ROOMS: chatRooms,
45
- * USERS: userStore
46
- * },
47
- * });
48
- *
49
- * @example
50
- * // Create a worker with KV namespace for caching and data storage:
51
- * const cache = await KVNamespace("cache-store");
52
- * const settings = await KVNamespace("user-settings");
53
- *
54
- * const cacheWorker = await Worker("cache", {
55
- * name: "cache-worker",
56
- * entrypoint: "./src/cache.ts",
57
- * bindings: {
58
- * CACHE: cache,
59
- * SETTINGS: settings
60
- * }
61
- * });
62
- *
63
- * @example
64
- * // Create a worker with R2 bucket for object storage:
65
- * const uploads = await R2Bucket("uploads", {
66
- * name: "user-uploads"
67
- * });
68
- * const assets = await R2Bucket("assets", {
69
- * name: "static-assets",
70
- * allowPublicAccess: true
71
- * });
72
- *
73
- * const storageWorker = await Worker("storage", {
74
- * name: "storage-worker",
75
- * entrypoint: "./src/storage.ts",
76
- * bindings: {
77
- * UPLOADS: uploads,
78
- * ASSETS: assets
79
- * }
80
- * });
81
- *
82
- * @example
83
- * // Create a worker with static assets:
84
- * const staticAssets = await Assets("static", {
85
- * path: "./src/assets"
86
- * });
87
- *
88
- * const frontendWorker = await Worker("frontend", {
89
- * name: "frontend-worker",
90
- * entrypoint: "./src/worker.ts",
91
- * bindings: {
92
- * ASSETS: staticAssets
93
- * }
94
- * });
95
- *
96
- * @example
97
- * // Create a worker with scheduled cron triggers:
98
- * const cronWorker = await Worker("scheduled-tasks", {
99
- * name: "cron-worker",
100
- * entrypoint: "./src/scheduled.ts",
101
- * crons: ['* 15 * * *', '0 0 * * *', '0 12 * * MON']
102
- * })
103
- *
104
- * @see
105
- * https://developers.cloudflare.com/workers/
106
- */
107
- export const Worker = Resource("cloudflare::Worker", {
27
+ export function isWorker(resource) {
28
+ return resource[ResourceKind] === "cloudflare::Worker";
29
+ }
30
+ export function Worker(...args) {
31
+ const [id, meta, props] = args.length === 2 ? [args[0], undefined, args[1]] : args;
32
+ if (("fetch" in props && props.fetch) || ("queue" in props && props.queue)) {
33
+ const scope = Scope.current;
34
+ const workerName = props.name ?? id;
35
+ // we need to make sure the worker exists
36
+ const stub = WorkerStub(`${id}/stub`, {
37
+ name: workerName,
38
+ accountId: props.accountId,
39
+ apiKey: props.apiKey,
40
+ apiToken: props.apiToken,
41
+ baseUrl: props.baseUrl,
42
+ email: props.email,
43
+ });
44
+ async function collectResources(scope) {
45
+ if (!scope) {
46
+ return [];
47
+ }
48
+ return (await Promise.all(Array.from(scope.resources.values()).map(async (resource) => [
49
+ (await resource),
50
+ ...(await collectResources(await resource[InnerResourceScope])),
51
+ ]))).flat();
52
+ }
53
+ const deferred = scope.defer(async () => {
54
+ const autoBindings = {};
55
+ for (const resource of await collectResources(Scope.root)) {
56
+ if (isQueue(resource) ||
57
+ isWorkerStub(resource) ||
58
+ isWorker(resource) ||
59
+ isD1Database(resource) ||
60
+ isBucket(resource) ||
61
+ isPipeline(resource) ||
62
+ isVectorizeIndex(resource) ||
63
+ isKVNamespace(resource)) {
64
+ // TODO(sam): make this generic/pluggable
65
+ autoBindings[getBindKey(resource)] = resource;
66
+ }
67
+ }
68
+ // TODO(sam): prune to only needed secrets
69
+ for (const secret of Secret.all()) {
70
+ autoBindings[secret.name] = secret;
71
+ }
72
+ const bindings = {
73
+ ...props.bindings,
74
+ __ALCHEMY_WORKER_NAME__: workerName,
75
+ __ALCHEMY_SERIALIZED_SCOPE__: Json(await serializeScope(scope)),
76
+ ALCHEMY_STAGE: scope.stage,
77
+ ALCHEMY_PASSWORD: secret(scope.password),
78
+ // TODO(sam): prune un-needed bindings
79
+ ...autoBindings,
80
+ };
81
+ return _Worker(id, {
82
+ ...props,
83
+ url: true,
84
+ compatibilityFlags: [
85
+ "nodejs_compat",
86
+ ...(props.compatibilityFlags ?? []),
87
+ ],
88
+ entrypoint: meta.filename,
89
+ name: workerName,
90
+ // adopt because the stub guarnatees that the worker exists
91
+ adopt: true,
92
+ bindings,
93
+ bundle: {
94
+ ...props.bundle,
95
+ plugins: [bootstrapPlugin],
96
+ external: [
97
+ // for alchemy
98
+ "libsodium*",
99
+ "@swc/*",
100
+ "esbuild",
101
+ // TODO(sam): this is for fetch, why is it a package?
102
+ "undici",
103
+ // TODO(sam): no idea where this came from, feels dangerous to externalize it
104
+ "ws",
105
+ "miniflare",
106
+ ],
107
+ banner: {
108
+ js: "var __ALCHEMY_RUNTIME__ = true;",
109
+ },
110
+ inject: [
111
+ ...(props.bundle?.inject ?? []),
112
+ path.resolve(import.meta.dirname, "..", "runtime", "shims.js"),
113
+ ],
114
+ },
115
+ });
116
+ });
117
+ // defer construction of this worker until the app is about to finaloze
118
+ // this ensures that the Worker's dependencies are instantiated before we bundle
119
+ // it is then safe to bundle and import the Worker to detect which resources need to be auto-bound
120
+ const promise = Promise.all([deferred, stub]).then(([worker]) => worker);
121
+ if (isRuntime) {
122
+ if (props.fetch) {
123
+ promise.fetch = async (request, env, ctx) => {
124
+ try {
125
+ return await props.fetch(request, env, ctx);
126
+ }
127
+ catch (err) {
128
+ return new Response(err.message + err.stack, {
129
+ status: 500,
130
+ });
131
+ }
132
+ };
133
+ }
134
+ if (props.queue) {
135
+ promise.queue = async (batch, env, ctx) => {
136
+ return await props.queue(batch, env, ctx);
137
+ };
138
+ }
139
+ }
140
+ else {
141
+ promise.fetch = async (request, init) => {
142
+ const worker = await promise;
143
+ if (!worker.url) {
144
+ throw new Error("Worker URL is not available in runtime");
145
+ }
146
+ if (request instanceof Request) {
147
+ const origin = new URL(worker.url);
148
+ const incoming = request.url.startsWith("/")
149
+ ? new URL(`${worker.url}${request.url}`)
150
+ : new URL(request.url);
151
+ console.log(incoming);
152
+ const proxyURL = new URL(`${incoming.pathname}${incoming.search}${incoming.hash}`, origin);
153
+ const headers = new Headers(request.headers);
154
+ headers.set("host", origin.host);
155
+ try {
156
+ return await fetch(new Request(proxyURL, {
157
+ method: request.method,
158
+ body: request.body,
159
+ headers,
160
+ // TODO(sam): do we need this? GPT added it ...
161
+ // redirect: "manual",
162
+ }));
163
+ }
164
+ catch (err) {
165
+ return new Response(err.message ?? "proxy error", { status: 500 });
166
+ }
167
+ }
168
+ else {
169
+ if (typeof request === "string" && request.startsWith("/")) {
170
+ request = new URL(`${worker.url}${request}`);
171
+ }
172
+ return await fetch(request, init);
173
+ }
174
+ };
175
+ }
176
+ return promise;
177
+ }
178
+ return _Worker(id, props).then(async (worker) => {
179
+ const binding = await tryGetBinding(worker);
180
+ if (binding) {
181
+ worker.fetch = (request) => binding.fetch(request);
182
+ worker.connect = (address, options) => binding.connect(address, options);
183
+ }
184
+ return worker;
185
+ });
186
+ }
187
+ export const _Worker = Resource("cloudflare::Worker", {
108
188
  alwaysUpdate: true,
109
189
  }, async function (id, props) {
110
- // Validate input - we need either script, entryPoint, or bundle
111
- if (!props.script && !props.entrypoint) {
112
- throw new Error("One of script or entryPoint must be provided");
113
- }
114
190
  // Create Cloudflare API client with automatic account discovery
115
191
  const api = await createCloudflareApi(props);
116
192
  // Use the provided name
117
193
  const workerName = props.name ?? id;
118
- const oldBindings = await this.get("bindings");
119
194
  const compatibilityDate = props.compatibilityDate ?? "2025-04-20";
120
195
  const compatibilityFlags = props.compatibilityFlags ?? [];
121
196
  const uploadWorkerScript = async (props) => {
197
+ const oldBindings = await this.get("bindings");
122
198
  // Get the script content - either from props.script, or by bundling
123
199
  const scriptContent = props.script ??
124
200
  (await bundleWorkerScript({
@@ -158,6 +234,8 @@ export const Worker = Resource("cloudflare::Worker", {
158
234
  workerName,
159
235
  }, assetUploadResult);
160
236
  await putWorker(api, workerName, scriptContent, scriptMetadata);
237
+ // TODO: it is less than ideal that this can fail, resulting in state problem
238
+ await this.set("bindings", props.bindings);
161
239
  for (const workflow of workflowsBindings) {
162
240
  await upsertWorkflow(api, {
163
241
  workflowName: workflow.workflowName,
@@ -181,8 +259,6 @@ export const Worker = Resource("cloudflare::Worker", {
181
259
  }
182
260
  throw new Error(`Unsupported event source type: ${eventSource}`);
183
261
  }) ?? []);
184
- // TODO: it is less than ideal that this can fail, resulting in state problem
185
- await this.set("bindings", props.bindings);
186
262
  // Handle worker URL if requested
187
263
  const workerUrl = await configureURL(this, api, workerName, props.url ?? false);
188
264
  // Get current timestamp
@@ -194,16 +270,19 @@ export const Worker = Resource("cloudflare::Worker", {
194
270
  await handleApiError(res, "updating cron triggers", "worker", workerName);
195
271
  }
196
272
  }
197
- return { scriptMetadata, workerUrl, now };
273
+ return { scriptContent, scriptMetadata, workerUrl, now };
198
274
  };
199
275
  if (this.phase === "delete") {
200
- if (Object.values(props.bindings ?? {}).some((binding) => binding === Self)) {
201
- // remove the Self bindings or else we can't remove (LOL)
202
- await uploadWorkerScript({
203
- ...props,
204
- bindings: Object.fromEntries(Object.entries(props.bindings ?? {}).filter(([_, binding]) => binding !== Self)),
205
- });
206
- }
276
+ // Delete any queue consumers attached to this worker first
277
+ await deleteQueueConsumers(this, api, workerName);
278
+ await uploadWorkerScript({
279
+ ...props,
280
+ entrypoint: undefined,
281
+ script: props.format === "cjs"
282
+ ? "addEventListener('fetch', event => { event.respondWith(new Response('hello world')); });"
283
+ : "export default { fetch(request) { return new Response('hello world'); } }",
284
+ bindings: {},
285
+ });
207
286
  await withExponentialBackoff(() => deleteWorker(this, api, {
208
287
  ...props,
209
288
  workerName,
@@ -213,6 +292,10 @@ export const Worker = Resource("cloudflare::Worker", {
213
292
  err.status === 503, 10, 100);
214
293
  return this.destroy();
215
294
  }
295
+ // Validate input - we need either script, entryPoint, or bundle
296
+ if (!props.script && !props.entrypoint) {
297
+ throw new Error("One of script or entrypoint must be provided");
298
+ }
216
299
  if (this.phase === "create") {
217
300
  if (!props.adopt) {
218
301
  await assertWorkerDoesNotExist(this, api, workerName);
@@ -244,10 +327,8 @@ export const Worker = Resource("cloudflare::Worker", {
244
327
  Env: undefined,
245
328
  });
246
329
  });
247
- async function deleteWorker(ctx, api, props) {
330
+ export async function deleteWorker(ctx, api, props) {
248
331
  const workerName = props.workerName;
249
- // Delete any queue consumers attached to this worker first
250
- await deleteQueueConsumers(ctx, api, workerName);
251
332
  // Delete worker
252
333
  const deleteResponse = await api.delete(`/accounts/${api.accountId}/workers/scripts/${workerName}`);
253
334
  // Check for success (2xx status code)
@@ -268,7 +349,7 @@ async function deleteWorker(ctx, api, props) {
268
349
  // Return minimal output for deleted state
269
350
  return;
270
351
  }
271
- async function putWorker(api, workerName, scriptContent, scriptMetadata) {
352
+ export async function putWorker(api, workerName, scriptContent, scriptMetadata) {
272
353
  return withExponentialBackoff(async () => {
273
354
  const scriptName = scriptMetadata.main_module ?? scriptMetadata.body_part;
274
355
  // Create FormData for the upload
@@ -296,261 +377,7 @@ async function putWorker(api, workerName, scriptContent, scriptMetadata) {
296
377
  return formData;
297
378
  }, (err) => err.status === 404 || err.status === 500 || err.status === 503, 10, 100);
298
379
  }
299
- /**
300
- * Creates asset configuration object from provided config or defaults
301
- */
302
- function createAssetConfig(config) {
303
- const assetConfig = {
304
- html_handling: "auto-trailing-slash",
305
- };
306
- if (config) {
307
- if (config._headers !== undefined) {
308
- assetConfig._headers = config._headers;
309
- }
310
- if (config._redirects !== undefined) {
311
- assetConfig._redirects = config._redirects;
312
- }
313
- if (config.html_handling !== undefined) {
314
- assetConfig.html_handling = config.html_handling;
315
- }
316
- if (config.not_found_handling !== undefined) {
317
- assetConfig.not_found_handling = config.not_found_handling;
318
- }
319
- if (config.run_worker_first !== undefined) {
320
- assetConfig.run_worker_first = config.run_worker_first;
321
- }
322
- if (config.serve_directly !== undefined) {
323
- assetConfig.serve_directly = config.serve_directly;
324
- }
325
- }
326
- return assetConfig;
327
- }
328
- async function prepareWorkerMetadata(ctx, oldBindings, props, assetUploadResult) {
329
- // Prepare metadata with bindings
330
- const meta = {
331
- compatibility_date: props.compatibilityDate,
332
- compatibility_flags: props.compatibilityFlags,
333
- bindings: [],
334
- observability: {
335
- enabled: props.observability?.enabled !== false,
336
- },
337
- // TODO(sam): base64 encode instead? 0 collision risk vs readability.
338
- tags: [`alchemy:id:${slugify(ctx.fqn)}`],
339
- migrations: {
340
- new_classes: props.migrations?.new_classes ?? [],
341
- deleted_classes: props.migrations?.deleted_classes ?? [],
342
- renamed_classes: props.migrations?.renamed_classes ?? [],
343
- transferred_classes: props.migrations?.transferred_classes ?? [],
344
- new_sqlite_classes: props.migrations?.new_sqlite_classes ?? [],
345
- },
346
- };
347
- // If we have asset upload results, add them to the metadata
348
- if (assetUploadResult) {
349
- meta.assets = {
350
- jwt: assetUploadResult.completionToken,
351
- };
352
- // Initialize config from assetUploadResult if it exists
353
- if (assetUploadResult.assetConfig) {
354
- meta.assets.config = {
355
- ...assetUploadResult.assetConfig,
356
- };
357
- }
358
- // If there's no config from assetUploadResult but we have props.assets,
359
- // we need to create the config ourselves (this handles the case when no assets were uploaded)
360
- if (!meta.assets.config && props.assets) {
361
- meta.assets.config = createAssetConfig(props.assets);
362
- }
363
- }
364
- const bindings = (props.bindings ?? {});
365
- // Convert bindings to the format expected by the API
366
- for (const [bindingName, binding] of Object.entries(bindings)) {
367
- // Create a copy of the binding to avoid modifying the original
368
- if (typeof binding === "string") {
369
- meta.bindings.push({
370
- type: "plain_text",
371
- name: bindingName,
372
- text: binding,
373
- });
374
- }
375
- else if (binding === Self) {
376
- meta.bindings.push({
377
- type: "service",
378
- name: bindingName,
379
- service: props.workerName,
380
- });
381
- }
382
- else if (binding.type === "d1") {
383
- meta.bindings.push({
384
- type: "d1",
385
- name: bindingName,
386
- id: binding.id,
387
- });
388
- }
389
- else if (binding.type === "kv_namespace") {
390
- meta.bindings.push({
391
- type: "kv_namespace",
392
- name: bindingName,
393
- namespace_id: "namespaceId" in binding ? binding.namespaceId : binding.id,
394
- });
395
- }
396
- else if (binding.type === "service") {
397
- meta.bindings.push({
398
- type: "service",
399
- name: bindingName,
400
- service: binding.name,
401
- });
402
- }
403
- else if (binding.type === "durable_object_namespace") {
404
- meta.bindings.push({
405
- type: "durable_object_namespace",
406
- name: bindingName,
407
- class_name: binding.className,
408
- script_name: binding.scriptName,
409
- environment: binding.environment,
410
- namespace_id: binding.namespaceId,
411
- });
412
- configureClassMigration(binding, binding.id, binding.className);
413
- }
414
- else if (binding.type === "r2_bucket") {
415
- meta.bindings.push({
416
- type: "r2_bucket",
417
- name: bindingName,
418
- bucket_name: binding.name,
419
- });
420
- }
421
- else if (binding.type === "assets") {
422
- meta.bindings.push({
423
- type: "assets",
424
- name: bindingName,
425
- });
426
- }
427
- else if (binding.type === "secret") {
428
- meta.bindings.push({
429
- type: "secret_text",
430
- name: bindingName,
431
- text: binding.unencrypted,
432
- });
433
- }
434
- else if (binding.type === "workflow") {
435
- meta.bindings.push({
436
- type: "workflow",
437
- name: bindingName,
438
- workflow_name: binding.workflowName,
439
- class_name: binding.className,
440
- // this should be set if the Workflow is in another script ...
441
- // script_name: ??,
442
- });
443
- // it's unclear whether this is needed, but it works both ways
444
- // configureClassMigration(binding, binding.id, binding.className);
445
- }
446
- else if (binding.type === "queue") {
447
- meta.bindings.push({
448
- type: "queue",
449
- name: bindingName,
450
- queue_name: binding.name,
451
- });
452
- }
453
- else if (binding.type === "pipeline") {
454
- meta.bindings.push({
455
- type: "pipelines",
456
- name: bindingName,
457
- pipeline: binding.name,
458
- });
459
- }
460
- else if (binding.type === "vectorize") {
461
- meta.bindings.push({
462
- type: "vectorize",
463
- name: bindingName,
464
- index_name: binding.name,
465
- });
466
- }
467
- else if (binding.type === "ai_gateway") {
468
- // AI Gateway binding - just needs the name property
469
- meta.bindings.push({
470
- type: "ai",
471
- name: bindingName,
472
- });
473
- }
474
- else if (binding.type === "hyperdrive") {
475
- // Hyperdrive binding
476
- meta.bindings.push({
477
- type: "hyperdrive",
478
- name: bindingName,
479
- id: binding.hyperdriveId,
480
- });
481
- }
482
- else if (binding.type === "browser") {
483
- meta.bindings.push({
484
- type: "browser",
485
- name: bindingName,
486
- });
487
- }
488
- else if (binding.type === "ai") {
489
- meta.bindings.push({
490
- type: "ai",
491
- name: bindingName,
492
- });
493
- }
494
- else if (binding.type === "analytics_engine") {
495
- meta.bindings.push({
496
- type: "analytics_engine",
497
- name: bindingName,
498
- dataset: binding.dataset,
499
- });
500
- }
501
- else {
502
- // @ts-expect-error - we should never reach here
503
- throw new Error(`Unsupported binding type: ${binding.type}`);
504
- }
505
- }
506
- function configureClassMigration(binding, stableId, className) {
507
- const oldBinding = Object.values(oldBindings ?? {})
508
- ?.filter((b) => typeof b === "object" &&
509
- (b.type === "durable_object_namespace" || b.type === "workflow"))
510
- ?.find((b) => b.id === stableId);
511
- if (!oldBinding) {
512
- if (binding.type === "durable_object_namespace" && binding.sqlite) {
513
- meta.migrations.new_sqlite_classes.push(className);
514
- }
515
- else {
516
- meta.migrations.new_classes.push(className);
517
- }
518
- }
519
- else if (oldBinding.className !== className) {
520
- meta.migrations.renamed_classes.push({
521
- from: oldBinding.className,
522
- to: className,
523
- });
524
- }
525
- }
526
- // Convert env variables to plain_text bindings
527
- // TODO(sam): remove Worker.env in favor of always bindings
528
- if (props.env) {
529
- for (const [key, value] of Object.entries(props.env)) {
530
- meta.bindings.push({
531
- name: key,
532
- type: "plain_text",
533
- text: value,
534
- });
535
- }
536
- }
537
- // Determine if we're using ESM or service worker format
538
- const isEsModule = props.format !== "cjs"; // Default to ESM unless CJS is specified
539
- const scriptName = isEsModule ? "worker.js" : "script";
540
- if (isEsModule) {
541
- // For ES modules format
542
- meta.main_module = scriptName;
543
- }
544
- else {
545
- // For service worker format (CJS)
546
- meta.body_part = scriptName;
547
- }
548
- if (process.env.DEBUG) {
549
- console.log(meta);
550
- }
551
- return meta;
552
- }
553
- async function assertWorkerDoesNotExist(ctx, api, workerName) {
380
+ export async function assertWorkerDoesNotExist(ctx, api, workerName) {
554
381
  const response = await api.get(`/accounts/${api.accountId}/workers/scripts/${workerName}`);
555
382
  if (response.status === 404) {
556
383
  return true;
@@ -567,7 +394,7 @@ async function assertWorkerDoesNotExist(ctx, api, workerName) {
567
394
  }
568
395
  throw new Error(`Error checking if worker exists: ${response.status} ${response.statusText} ${await response.text()}`);
569
396
  }
570
- async function configureURL(ctx, api, workerName, url) {
397
+ export async function configureURL(ctx, api, workerName, url) {
571
398
  let workerUrl;
572
399
  if (url) {
573
400
  // Enable the workers.dev subdomain for this worker
@@ -602,7 +429,7 @@ async function configureURL(ctx, api, workerName, url) {
602
429
  }
603
430
  return workerUrl;
604
431
  }
605
- async function getWorkerScriptMetadata(api, workerName) {
432
+ export async function getWorkerScriptMetadata(api, workerName) {
606
433
  const response = await api.get(`/accounts/${api.accountId}/workers/services/${workerName}`);
607
434
  if (response.status === 404) {
608
435
  return undefined;
@@ -612,7 +439,7 @@ async function getWorkerScriptMetadata(api, workerName) {
612
439
  }
613
440
  return (await response.json()).result;
614
441
  }
615
- async function getWorkerBindings(api, workerName, environment = "production") {
442
+ export async function _getWorkerBindings(api, workerName, environment = "production") {
616
443
  const response = await api.get(`/accounts/${api.accountId}/workers/services/${workerName}/environments/${environment}/bindings`, {
617
444
  headers: {
618
445
  Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
@@ -628,109 +455,6 @@ async function getWorkerBindings(api, workerName, environment = "production") {
628
455
  const data = await response.json();
629
456
  return data.result;
630
457
  }
631
- /**
632
- * Uploads assets to Cloudflare and returns a completion token
633
- *
634
- * @param api CloudflareApi instance
635
- * @param workerName Name of the worker
636
- * @param assets Assets resource containing files to upload
637
- * @param assetConfig Configuration for the assets
638
- * @returns Completion token for the assets upload
639
- */
640
- async function uploadAssets(api, workerName, assets, assetConfig) {
641
- // Process the assets configuration once at the beginning
642
- const processedConfig = createAssetConfig(assetConfig);
643
- // Generate the file manifest
644
- const fileMetadata = {};
645
- // Process each file in the assets
646
- for (const file of assets.files) {
647
- const { hash, size } = await calculateFileMetadata(file.filePath);
648
- // Use the relative path as the key, ensuring it starts with a slash
649
- const key = file.path.startsWith("/") ? file.path : `/${file.path}`;
650
- fileMetadata[key] = { hash, size };
651
- }
652
- // Start the upload session
653
- const uploadSessionUrl = `/accounts/${api.accountId}/workers/scripts/${workerName}/assets-upload-session`;
654
- const uploadSessionResponse = await api.post(uploadSessionUrl, JSON.stringify({ manifest: fileMetadata }), {
655
- headers: { "Content-Type": "application/json" },
656
- });
657
- if (!uploadSessionResponse.ok) {
658
- throw new Error(`Failed to start assets upload session: ${uploadSessionResponse.status} ${uploadSessionResponse.statusText}`);
659
- }
660
- const sessionData = (await uploadSessionResponse.json());
661
- // If there are no buckets, assets are already uploaded or empty
662
- if (!sessionData.result.buckets || sessionData.result.buckets.length === 0) {
663
- return {
664
- completionToken: sessionData.result.jwt,
665
- assetConfig: processedConfig,
666
- };
667
- }
668
- // Upload the files in batches as specified by the API
669
- let completionToken = sessionData.result.jwt;
670
- const buckets = sessionData.result.buckets;
671
- // Process each bucket of files
672
- for (const bucket of buckets) {
673
- const formData = new FormData();
674
- let totalBytes = 0;
675
- // Add each file in the bucket to the form
676
- for (const fileHash of bucket) {
677
- // Find the file with this hash
678
- const file = assets.files.find((f) => {
679
- const filePath = f.path.startsWith("/") ? f.path : `/${f.path}`;
680
- return fileMetadata[filePath]?.hash === fileHash;
681
- });
682
- if (!file) {
683
- throw new Error(`Could not find file with hash ${fileHash}`);
684
- }
685
- // Read the file content
686
- const fileContent = await fs.readFile(file.filePath);
687
- // Convert to base64 as required by the API when using base64=true
688
- const base64Content = fileContent.toString("base64");
689
- // Add the file to the form with the hash as the key and set the correct content type
690
- const blob = new Blob([base64Content], {
691
- type: getContentType(file.filePath),
692
- });
693
- totalBytes += blob.size;
694
- formData.append(fileHash, blob, fileHash);
695
- }
696
- // Upload this batch of files
697
- const uploadResponse = await api.post(`/accounts/${api.accountId}/workers/assets/upload?base64=true`, formData, {
698
- headers: {
699
- Authorization: `Bearer ${completionToken}`,
700
- "Content-Type": "multipart/form-data",
701
- },
702
- });
703
- if (!uploadResponse.ok) {
704
- throw new Error(`Failed to upload asset files: ${uploadResponse.status} ${uploadResponse.statusText}`);
705
- }
706
- const uploadData = (await uploadResponse.json());
707
- // Update the completion token for the next batch
708
- if (uploadData.result.jwt) {
709
- completionToken = uploadData.result.jwt;
710
- }
711
- }
712
- // Return the final completion token with asset configuration
713
- return {
714
- completionToken,
715
- assetConfig: processedConfig,
716
- };
717
- }
718
- /**
719
- * Calculate the SHA-256 hash and size of a file
720
- *
721
- * @param filePath Path to the file
722
- * @returns Hash (first 32 chars of SHA-256) and size of the file
723
- */
724
- async function calculateFileMetadata(filePath) {
725
- const hash = crypto.createHash("sha256");
726
- const fileContent = await fs.readFile(filePath);
727
- hash.update(fileContent);
728
- const fileHash = hash.digest("hex").substring(0, 32); // First 32 chars of hash
729
- return {
730
- hash: fileHash,
731
- size: fileContent.length,
732
- };
733
- }
734
458
  /**
735
459
  * Lists and deletes all queue consumers for a specific worker
736
460
  * @param ctx Worker context containing eventSources