alchemy-effect 0.1.0 → 0.3.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 (590) hide show
  1. package/bin/alchemy-effect.js +55038 -8
  2. package/bin/alchemy-effect.js.map +1 -1
  3. package/bin/alchemy-effect.ts +266 -10
  4. package/lib/$.d.ts +5 -0
  5. package/lib/$.d.ts.map +1 -0
  6. package/lib/$.js +9 -0
  7. package/lib/$.js.map +1 -0
  8. package/lib/app.d.ts +7 -15
  9. package/lib/app.d.ts.map +1 -1
  10. package/lib/app.js +1 -20
  11. package/lib/app.js.map +1 -1
  12. package/lib/apply.d.ts +15 -19
  13. package/lib/apply.d.ts.map +1 -1
  14. package/lib/apply.js +173 -82
  15. package/lib/apply.js.map +1 -1
  16. package/lib/assert-never.d.ts +12 -0
  17. package/lib/assert-never.d.ts.map +1 -0
  18. package/lib/assert-never.js +11 -0
  19. package/lib/assert-never.js.map +1 -0
  20. package/lib/aws/account.d.ts +13 -3
  21. package/lib/aws/account.d.ts.map +1 -1
  22. package/lib/aws/account.js +19 -4
  23. package/lib/aws/account.js.map +1 -1
  24. package/lib/aws/arn.d.ts +1 -5
  25. package/lib/aws/arn.d.ts.map +1 -1
  26. package/lib/aws/client.d.ts.map +1 -1
  27. package/lib/aws/client.js +8 -1
  28. package/lib/aws/client.js.map +1 -1
  29. package/lib/aws/config.d.ts +15 -0
  30. package/lib/aws/config.d.ts.map +1 -0
  31. package/lib/aws/config.js +1 -0
  32. package/lib/aws/config.js.map +1 -0
  33. package/lib/aws/credentials.d.ts +11 -1
  34. package/lib/aws/credentials.d.ts.map +1 -1
  35. package/lib/aws/credentials.js +73 -47
  36. package/lib/aws/credentials.js.map +1 -1
  37. package/lib/aws/dynamodb/attribute-value.d.ts +20 -0
  38. package/lib/aws/dynamodb/attribute-value.d.ts.map +1 -0
  39. package/lib/aws/dynamodb/attribute-value.js +217 -0
  40. package/lib/aws/dynamodb/attribute-value.js.map +1 -0
  41. package/lib/aws/dynamodb/client.d.ts +12 -0
  42. package/lib/aws/dynamodb/client.d.ts.map +1 -0
  43. package/lib/aws/{sqs/queue.client.js → dynamodb/client.js} +6 -6
  44. package/lib/aws/dynamodb/client.js.map +1 -0
  45. package/lib/aws/dynamodb/expr.d.ts +41 -0
  46. package/lib/aws/dynamodb/expr.d.ts.map +1 -0
  47. package/lib/aws/dynamodb/expr.js +1 -0
  48. package/lib/aws/dynamodb/expr.js.map +1 -0
  49. package/lib/aws/dynamodb/index.d.ts +10 -0
  50. package/lib/aws/dynamodb/index.d.ts.map +1 -0
  51. package/lib/aws/dynamodb/index.js +9 -0
  52. package/lib/aws/dynamodb/index.js.map +1 -0
  53. package/lib/aws/dynamodb/projection.d.ts +25 -0
  54. package/lib/aws/dynamodb/projection.d.ts.map +1 -0
  55. package/lib/aws/dynamodb/projection.js +1 -0
  56. package/lib/aws/dynamodb/projection.js.map +1 -0
  57. package/lib/aws/dynamodb/secondary-index.d.ts +26 -0
  58. package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -0
  59. package/lib/aws/dynamodb/secondary-index.js +4 -0
  60. package/lib/aws/dynamodb/secondary-index.js.map +1 -0
  61. package/lib/aws/dynamodb/table.d.ts +59 -0
  62. package/lib/aws/dynamodb/table.d.ts.map +1 -0
  63. package/lib/aws/dynamodb/table.get-item.d.ts +57 -0
  64. package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -0
  65. package/lib/aws/dynamodb/table.get-item.js +77 -0
  66. package/lib/aws/dynamodb/table.get-item.js.map +1 -0
  67. package/lib/aws/dynamodb/table.js +4 -0
  68. package/lib/aws/dynamodb/table.js.map +1 -0
  69. package/lib/aws/dynamodb/table.provider.d.ts +7 -0
  70. package/lib/aws/dynamodb/table.provider.d.ts.map +1 -0
  71. package/lib/aws/dynamodb/table.provider.js +187 -0
  72. package/lib/aws/dynamodb/table.provider.js.map +1 -0
  73. package/lib/aws/ec2/client.d.ts +12 -0
  74. package/lib/aws/ec2/client.d.ts.map +1 -0
  75. package/lib/aws/ec2/client.js +11 -0
  76. package/lib/aws/ec2/client.js.map +1 -0
  77. package/lib/aws/ec2/index.d.ts +7 -0
  78. package/lib/aws/ec2/index.d.ts.map +1 -0
  79. package/lib/aws/ec2/index.js +7 -0
  80. package/lib/aws/ec2/index.js.map +1 -0
  81. package/lib/aws/ec2/subnet.d.ts +175 -0
  82. package/lib/aws/ec2/subnet.d.ts.map +1 -0
  83. package/lib/aws/ec2/subnet.js +4 -0
  84. package/lib/aws/ec2/subnet.js.map +1 -0
  85. package/lib/aws/ec2/subnet.provider.d.ts +4 -0
  86. package/lib/aws/ec2/subnet.provider.d.ts.map +1 -0
  87. package/lib/aws/ec2/subnet.provider.js +250 -0
  88. package/lib/aws/ec2/subnet.provider.js.map +1 -0
  89. package/lib/aws/ec2/vpc.d.ts +135 -0
  90. package/lib/aws/ec2/vpc.d.ts.map +1 -0
  91. package/lib/aws/ec2/vpc.js +4 -0
  92. package/lib/aws/ec2/vpc.js.map +1 -0
  93. package/lib/aws/ec2/vpc.provider.d.ts +6 -0
  94. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -0
  95. package/lib/aws/ec2/vpc.provider.js +183 -0
  96. package/lib/aws/ec2/vpc.provider.js.map +1 -0
  97. package/lib/aws/index.d.ts +23 -16
  98. package/lib/aws/index.d.ts.map +1 -1
  99. package/lib/aws/index.js +10 -18
  100. package/lib/aws/index.js.map +1 -1
  101. package/lib/aws/lambda/client.d.ts +8 -0
  102. package/lib/aws/lambda/client.d.ts.map +1 -0
  103. package/lib/aws/lambda/client.js +7 -0
  104. package/lib/aws/lambda/client.js.map +1 -0
  105. package/lib/aws/lambda/consume.d.ts +10 -11
  106. package/lib/aws/lambda/consume.d.ts.map +1 -1
  107. package/lib/aws/lambda/consume.js +3 -3
  108. package/lib/aws/lambda/consume.js.map +1 -1
  109. package/lib/aws/lambda/function.d.ts +18 -15
  110. package/lib/aws/lambda/function.d.ts.map +1 -1
  111. package/lib/aws/lambda/function.handler.d.ts +1 -1
  112. package/lib/aws/lambda/function.handler.d.ts.map +1 -1
  113. package/lib/aws/lambda/function.handler.js.map +1 -1
  114. package/lib/aws/lambda/function.invoke.d.ts +7 -5
  115. package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
  116. package/lib/aws/lambda/function.invoke.js +5 -3
  117. package/lib/aws/lambda/function.invoke.js.map +1 -1
  118. package/lib/aws/lambda/function.js +1 -1
  119. package/lib/aws/lambda/function.js.map +1 -1
  120. package/lib/aws/lambda/function.provider.d.ts +6 -5
  121. package/lib/aws/lambda/function.provider.d.ts.map +1 -1
  122. package/lib/aws/lambda/function.provider.js +150 -58
  123. package/lib/aws/lambda/function.provider.js.map +1 -1
  124. package/lib/aws/lambda/index.d.ts +2 -2
  125. package/lib/aws/lambda/index.d.ts.map +1 -1
  126. package/lib/aws/lambda/index.js +2 -1
  127. package/lib/aws/lambda/index.js.map +1 -1
  128. package/lib/aws/lambda/serve.d.ts +2 -4
  129. package/lib/aws/lambda/serve.d.ts.map +1 -1
  130. package/lib/aws/lambda/serve.js.map +1 -1
  131. package/lib/aws/profile.d.ts +2 -2
  132. package/lib/aws/profile.d.ts.map +1 -1
  133. package/lib/aws/profile.js +1 -1
  134. package/lib/aws/profile.js.map +1 -1
  135. package/lib/aws/region.d.ts +14 -1
  136. package/lib/aws/region.d.ts.map +1 -1
  137. package/lib/aws/region.js +26 -1
  138. package/lib/aws/region.js.map +1 -1
  139. package/lib/aws/sqs/client.d.ts +12 -0
  140. package/lib/aws/sqs/client.d.ts.map +1 -0
  141. package/lib/aws/sqs/client.js +11 -0
  142. package/lib/aws/sqs/client.js.map +1 -0
  143. package/lib/aws/sqs/index.d.ts +3 -1
  144. package/lib/aws/sqs/index.d.ts.map +1 -1
  145. package/lib/aws/sqs/index.js +3 -1
  146. package/lib/aws/sqs/index.js.map +1 -1
  147. package/lib/aws/sqs/queue.consume.d.ts +1 -10
  148. package/lib/aws/sqs/queue.consume.d.ts.map +1 -1
  149. package/lib/aws/sqs/queue.consume.js +0 -19
  150. package/lib/aws/sqs/queue.consume.js.map +1 -1
  151. package/lib/aws/sqs/queue.d.ts +6 -12
  152. package/lib/aws/sqs/queue.d.ts.map +1 -1
  153. package/lib/aws/sqs/queue.event-source.d.ts +22 -0
  154. package/lib/aws/sqs/queue.event-source.d.ts.map +1 -0
  155. package/lib/aws/sqs/queue.event-source.js +130 -0
  156. package/lib/aws/sqs/queue.event-source.js.map +1 -0
  157. package/lib/aws/sqs/queue.js +1 -1
  158. package/lib/aws/sqs/queue.js.map +1 -1
  159. package/lib/aws/sqs/queue.provider.d.ts +5 -4
  160. package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
  161. package/lib/aws/sqs/queue.provider.js +6 -6
  162. package/lib/aws/sqs/queue.provider.js.map +1 -1
  163. package/lib/aws/sqs/queue.send-message.d.ts +8 -6
  164. package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
  165. package/lib/aws/sqs/queue.send-message.js +6 -4
  166. package/lib/aws/sqs/queue.send-message.js.map +1 -1
  167. package/lib/binding.d.ts +74 -26
  168. package/lib/binding.d.ts.map +1 -1
  169. package/lib/binding.js.map +1 -1
  170. package/lib/capability.d.ts +38 -0
  171. package/lib/capability.d.ts.map +1 -1
  172. package/lib/cli/components/ApprovePlan.d.ts +2 -2
  173. package/lib/cli/components/ApprovePlan.d.ts.map +1 -1
  174. package/lib/cli/components/ApprovePlan.js.map +1 -1
  175. package/lib/cli/components/Plan.d.ts +2 -2
  176. package/lib/cli/components/Plan.d.ts.map +1 -1
  177. package/lib/cli/components/Plan.js +3 -1
  178. package/lib/cli/components/Plan.js.map +1 -1
  179. package/lib/cli/components/PlanProgress.d.ts +8 -4
  180. package/lib/cli/components/PlanProgress.d.ts.map +1 -1
  181. package/lib/cli/components/PlanProgress.js +11 -1
  182. package/lib/cli/components/PlanProgress.js.map +1 -1
  183. package/lib/cli/index.d.ts +342 -213
  184. package/lib/cli/index.d.ts.map +1 -1
  185. package/lib/cli/index.js +26047 -11403
  186. package/lib/cli/index.js.map +1 -1
  187. package/lib/cli/ink-service.d.ts +4 -0
  188. package/lib/cli/ink-service.d.ts.map +1 -0
  189. package/lib/cli/ink-service.js +43 -0
  190. package/lib/cli/ink-service.js.map +1 -0
  191. package/lib/cli/service.d.ts +21 -0
  192. package/lib/cli/service.d.ts.map +1 -0
  193. package/lib/cli/service.js +5 -0
  194. package/lib/cli/service.js.map +1 -0
  195. package/lib/cloudflare/account.d.ts +10 -0
  196. package/lib/cloudflare/account.d.ts.map +1 -0
  197. package/lib/cloudflare/account.js +24 -0
  198. package/lib/cloudflare/account.js.map +1 -0
  199. package/lib/cloudflare/api.d.ts +31 -19
  200. package/lib/cloudflare/api.d.ts.map +1 -1
  201. package/lib/cloudflare/api.js +95 -29
  202. package/lib/cloudflare/api.js.map +1 -1
  203. package/lib/cloudflare/config.d.ts +9 -0
  204. package/lib/cloudflare/config.d.ts.map +1 -0
  205. package/lib/cloudflare/config.js +1 -0
  206. package/lib/cloudflare/config.js.map +1 -0
  207. package/lib/cloudflare/context.d.ts +27 -0
  208. package/lib/cloudflare/context.d.ts.map +1 -0
  209. package/lib/cloudflare/context.js +24 -0
  210. package/lib/cloudflare/context.js.map +1 -0
  211. package/lib/cloudflare/index.d.ts +7 -4
  212. package/lib/cloudflare/index.d.ts.map +1 -1
  213. package/lib/cloudflare/index.js +7 -4
  214. package/lib/cloudflare/index.js.map +1 -1
  215. package/lib/cloudflare/kv/index.d.ts +4 -0
  216. package/lib/cloudflare/kv/index.d.ts.map +1 -0
  217. package/lib/cloudflare/kv/index.js +4 -0
  218. package/lib/cloudflare/kv/index.js.map +1 -0
  219. package/lib/cloudflare/kv/namespace.binding.d.ts +10 -0
  220. package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -0
  221. package/lib/cloudflare/kv/namespace.binding.js +15 -0
  222. package/lib/cloudflare/kv/namespace.binding.js.map +1 -0
  223. package/lib/cloudflare/kv/namespace.client.d.ts +11 -0
  224. package/lib/cloudflare/kv/namespace.client.d.ts.map +1 -0
  225. package/lib/cloudflare/kv/namespace.client.js +31 -0
  226. package/lib/cloudflare/kv/namespace.client.js.map +1 -0
  227. package/lib/cloudflare/kv/namespace.d.ts +24 -0
  228. package/lib/cloudflare/kv/namespace.d.ts.map +1 -0
  229. package/lib/cloudflare/kv/namespace.js +3 -0
  230. package/lib/cloudflare/kv/namespace.js.map +1 -0
  231. package/lib/cloudflare/kv/namespace.provider.d.ts +6 -0
  232. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -0
  233. package/lib/cloudflare/kv/namespace.provider.js +81 -0
  234. package/lib/cloudflare/kv/namespace.provider.js.map +1 -0
  235. package/lib/cloudflare/live.d.ts +11 -0
  236. package/lib/cloudflare/live.d.ts.map +1 -0
  237. package/lib/cloudflare/live.js +15 -0
  238. package/lib/cloudflare/live.js.map +1 -0
  239. package/lib/cloudflare/r2/bucket.binding.d.ts +10 -0
  240. package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -0
  241. package/lib/cloudflare/r2/bucket.binding.js +18 -0
  242. package/lib/cloudflare/r2/bucket.binding.js.map +1 -0
  243. package/lib/cloudflare/r2/bucket.client.d.ts +8 -0
  244. package/lib/cloudflare/r2/bucket.client.d.ts.map +1 -0
  245. package/lib/cloudflare/r2/bucket.client.js +9 -0
  246. package/lib/cloudflare/r2/bucket.client.js.map +1 -0
  247. package/lib/cloudflare/r2/bucket.d.ts +33 -0
  248. package/lib/cloudflare/r2/bucket.d.ts.map +1 -0
  249. package/lib/cloudflare/r2/bucket.del.d.ts +4 -0
  250. package/lib/cloudflare/r2/bucket.del.d.ts.map +1 -0
  251. package/lib/cloudflare/r2/bucket.del.js +7 -0
  252. package/lib/cloudflare/r2/bucket.del.js.map +1 -0
  253. package/lib/cloudflare/r2/bucket.get.d.ts +5 -0
  254. package/lib/cloudflare/r2/bucket.get.d.ts.map +1 -0
  255. package/lib/cloudflare/r2/bucket.get.js +7 -0
  256. package/lib/cloudflare/r2/bucket.get.js.map +1 -0
  257. package/lib/cloudflare/r2/bucket.head.d.ts +4 -0
  258. package/lib/cloudflare/r2/bucket.head.d.ts.map +1 -0
  259. package/lib/cloudflare/r2/bucket.head.js +7 -0
  260. package/lib/cloudflare/r2/bucket.head.js.map +1 -0
  261. package/lib/cloudflare/r2/bucket.js +3 -0
  262. package/lib/cloudflare/r2/bucket.js.map +1 -0
  263. package/lib/cloudflare/r2/bucket.list.d.ts +5 -0
  264. package/lib/cloudflare/r2/bucket.list.d.ts.map +1 -0
  265. package/lib/cloudflare/r2/bucket.list.js +7 -0
  266. package/lib/cloudflare/r2/bucket.list.js.map +1 -0
  267. package/lib/cloudflare/r2/bucket.multipart.d.ts +19 -0
  268. package/lib/cloudflare/r2/bucket.multipart.d.ts.map +1 -0
  269. package/lib/cloudflare/r2/bucket.multipart.js +25 -0
  270. package/lib/cloudflare/r2/bucket.multipart.js.map +1 -0
  271. package/lib/cloudflare/r2/bucket.provider.d.ts +6 -0
  272. package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -0
  273. package/lib/cloudflare/r2/bucket.provider.js +67 -0
  274. package/lib/cloudflare/r2/bucket.provider.js.map +1 -0
  275. package/lib/cloudflare/r2/bucket.put.d.ts +6 -0
  276. package/lib/cloudflare/r2/bucket.put.d.ts.map +1 -0
  277. package/lib/cloudflare/r2/bucket.put.js +8 -0
  278. package/lib/cloudflare/r2/bucket.put.js.map +1 -0
  279. package/lib/cloudflare/r2/index.d.ts +10 -0
  280. package/lib/cloudflare/r2/index.d.ts.map +1 -0
  281. package/lib/cloudflare/r2/index.js +10 -0
  282. package/lib/cloudflare/r2/index.js.map +1 -0
  283. package/lib/cloudflare/stream.d.ts +10 -0
  284. package/lib/cloudflare/stream.d.ts.map +1 -0
  285. package/lib/cloudflare/stream.js +16 -0
  286. package/lib/cloudflare/stream.js.map +1 -0
  287. package/lib/cloudflare/worker/assets.fetch.d.ts +9 -0
  288. package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -0
  289. package/lib/cloudflare/worker/assets.fetch.js +12 -0
  290. package/lib/cloudflare/worker/assets.fetch.js.map +1 -0
  291. package/lib/cloudflare/worker/assets.provider.d.ts +66 -0
  292. package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -0
  293. package/lib/cloudflare/worker/assets.provider.js +145 -0
  294. package/lib/cloudflare/worker/assets.provider.js.map +1 -0
  295. package/lib/cloudflare/worker/index.d.ts +5 -0
  296. package/lib/cloudflare/worker/index.d.ts.map +1 -0
  297. package/lib/cloudflare/worker/index.js +5 -0
  298. package/lib/cloudflare/worker/index.js.map +1 -0
  299. package/lib/cloudflare/worker/worker.d.ts +66 -0
  300. package/lib/cloudflare/worker/worker.d.ts.map +1 -0
  301. package/lib/cloudflare/worker/worker.handler.d.ts +11 -0
  302. package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -0
  303. package/lib/cloudflare/worker/worker.handler.js +15 -0
  304. package/lib/cloudflare/worker/worker.handler.js.map +1 -0
  305. package/lib/cloudflare/worker/worker.js +4 -0
  306. package/lib/cloudflare/worker/worker.js.map +1 -0
  307. package/lib/cloudflare/worker/worker.provider.d.ts +11 -0
  308. package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -0
  309. package/lib/cloudflare/worker/worker.provider.js +194 -0
  310. package/lib/cloudflare/worker/worker.provider.js.map +1 -0
  311. package/lib/cloudflare/worker/worker.serve.d.ts +39 -0
  312. package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -0
  313. package/lib/cloudflare/worker/worker.serve.js +4 -0
  314. package/lib/cloudflare/worker/worker.serve.js.map +1 -0
  315. package/lib/data.d.ts +3 -0
  316. package/lib/data.d.ts.map +1 -0
  317. package/lib/data.js +8 -0
  318. package/lib/data.js.map +1 -0
  319. package/lib/destroy.d.ts +1 -3
  320. package/lib/destroy.d.ts.map +1 -1
  321. package/lib/destroy.js +2 -0
  322. package/lib/destroy.js.map +1 -1
  323. package/lib/diff.d.ts +16 -0
  324. package/lib/diff.d.ts.map +1 -0
  325. package/lib/diff.js +9 -0
  326. package/lib/diff.js.map +1 -0
  327. package/lib/dot-alchemy.d.ts +3 -2
  328. package/lib/dot-alchemy.d.ts.map +1 -1
  329. package/lib/dot-alchemy.js +3 -2
  330. package/lib/dot-alchemy.js.map +1 -1
  331. package/lib/env.d.ts +5 -0
  332. package/lib/env.d.ts.map +1 -1
  333. package/lib/env.js +15 -29
  334. package/lib/env.js.map +1 -1
  335. package/lib/esbuild.d.ts +28 -0
  336. package/lib/esbuild.d.ts.map +1 -0
  337. package/lib/esbuild.js +63 -0
  338. package/lib/esbuild.js.map +1 -0
  339. package/lib/exports.d.ts +9 -0
  340. package/lib/exports.d.ts.map +1 -0
  341. package/lib/exports.js +13 -0
  342. package/lib/exports.js.map +1 -0
  343. package/lib/index.d.ts +11 -5
  344. package/lib/index.d.ts.map +1 -1
  345. package/lib/index.js +11 -5
  346. package/lib/index.js.map +1 -1
  347. package/lib/input.d.ts +32 -0
  348. package/lib/input.d.ts.map +1 -0
  349. package/lib/input.js +1 -0
  350. package/lib/input.js.map +1 -0
  351. package/lib/output.d.ts +143 -0
  352. package/lib/output.d.ts.map +1 -0
  353. package/lib/output.js +269 -0
  354. package/lib/output.js.map +1 -0
  355. package/lib/plan.d.ts +59 -29
  356. package/lib/plan.d.ts.map +1 -1
  357. package/lib/plan.js +347 -169
  358. package/lib/plan.js.map +1 -1
  359. package/lib/policy.d.ts +22 -5
  360. package/lib/policy.d.ts.map +1 -1
  361. package/lib/policy.js +10 -2
  362. package/lib/policy.js.map +1 -1
  363. package/lib/provider.d.ts +16 -18
  364. package/lib/provider.d.ts.map +1 -1
  365. package/lib/ref.d.ts +14 -0
  366. package/lib/ref.d.ts.map +1 -0
  367. package/lib/ref.js +21 -0
  368. package/lib/ref.js.map +1 -0
  369. package/lib/resource.d.ts +13 -16
  370. package/lib/resource.d.ts.map +1 -1
  371. package/lib/resource.js +1 -0
  372. package/lib/resource.js.map +1 -1
  373. package/lib/runtime.d.ts +8 -7
  374. package/lib/runtime.d.ts.map +1 -1
  375. package/lib/runtime.js.map +1 -1
  376. package/lib/schema.d.ts +37 -0
  377. package/lib/schema.d.ts.map +1 -0
  378. package/lib/schema.js +61 -0
  379. package/lib/schema.js.map +1 -0
  380. package/lib/service.d.ts +9 -6
  381. package/lib/service.d.ts.map +1 -1
  382. package/lib/service.js.map +1 -1
  383. package/lib/sha256.d.ts +5 -0
  384. package/lib/sha256.d.ts.map +1 -0
  385. package/lib/sha256.js +16 -0
  386. package/lib/sha256.js.map +1 -0
  387. package/lib/stack.d.ts +60 -0
  388. package/lib/stack.d.ts.map +1 -0
  389. package/lib/stack.js +11 -0
  390. package/lib/stack.js.map +1 -0
  391. package/lib/stage.d.ts +39 -0
  392. package/lib/stage.d.ts.map +1 -0
  393. package/lib/stage.js +32 -0
  394. package/lib/stage.js.map +1 -0
  395. package/lib/state.d.ts +53 -11
  396. package/lib/state.d.ts.map +1 -1
  397. package/lib/state.js +33 -31
  398. package/lib/state.js.map +1 -1
  399. package/lib/tags.d.ts +17 -0
  400. package/lib/tags.d.ts.map +1 -0
  401. package/lib/tags.js +22 -0
  402. package/lib/tags.js.map +1 -0
  403. package/lib/test.d.ts +35 -0
  404. package/lib/test.d.ts.map +1 -0
  405. package/lib/test.js +68 -0
  406. package/lib/test.js.map +1 -0
  407. package/lib/tsconfig.test.tsbuildinfo +1 -0
  408. package/lib/type.d.ts +6 -0
  409. package/lib/type.d.ts.map +1 -0
  410. package/lib/type.js +3 -0
  411. package/lib/type.js.map +1 -0
  412. package/lib/unknown.d.ts +4 -0
  413. package/lib/unknown.d.ts.map +1 -0
  414. package/lib/unknown.js +4 -0
  415. package/lib/unknown.js.map +1 -0
  416. package/lib/user.d.ts +3 -0
  417. package/lib/user.d.ts.map +1 -0
  418. package/lib/user.js +3 -0
  419. package/lib/user.js.map +1 -0
  420. package/lib/util.d.ts +6 -0
  421. package/lib/util.d.ts.map +1 -0
  422. package/lib/util.js +9 -0
  423. package/lib/util.js.map +1 -0
  424. package/package.json +58 -7
  425. package/src/$.ts +17 -0
  426. package/src/app.ts +9 -37
  427. package/src/apply.ts +435 -289
  428. package/src/assert-never.ts +18 -0
  429. package/src/aws/account.ts +29 -7
  430. package/src/aws/arn.ts +1 -7
  431. package/src/aws/client.ts +14 -1
  432. package/src/aws/config.ts +16 -0
  433. package/src/aws/credentials.ts +213 -177
  434. package/src/aws/dynamodb/attribute-value.ts +240 -0
  435. package/src/aws/{sqs/queue.client.ts → dynamodb/client.ts} +9 -9
  436. package/src/aws/dynamodb/expr.ts +90 -0
  437. package/src/aws/dynamodb/index.ts +12 -0
  438. package/src/aws/dynamodb/projection.ts +159 -0
  439. package/src/aws/dynamodb/secondary-index.ts +45 -0
  440. package/src/aws/dynamodb/table.get-item.ts +173 -0
  441. package/src/aws/dynamodb/table.provider.ts +276 -0
  442. package/src/aws/dynamodb/table.ts +101 -0
  443. package/src/aws/ec2/client.ts +20 -0
  444. package/src/aws/ec2/index.ts +7 -0
  445. package/src/aws/ec2/subnet.provider.ts +358 -0
  446. package/src/aws/ec2/subnet.ts +213 -0
  447. package/src/aws/ec2/vpc.provider.ts +269 -0
  448. package/src/aws/ec2/vpc.ts +163 -0
  449. package/src/aws/index.ts +50 -45
  450. package/src/aws/lambda/client.ts +14 -0
  451. package/src/aws/lambda/consume.ts +8 -8
  452. package/src/aws/lambda/function.handler.ts +1 -1
  453. package/src/aws/lambda/function.invoke.ts +8 -4
  454. package/src/aws/lambda/function.provider.ts +208 -109
  455. package/src/aws/lambda/function.ts +21 -12
  456. package/src/aws/lambda/index.ts +3 -4
  457. package/src/aws/lambda/serve.ts +1 -1
  458. package/src/aws/profile.ts +1 -4
  459. package/src/aws/region.ts +43 -2
  460. package/src/aws/sqs/client.ts +20 -0
  461. package/src/aws/sqs/index.ts +4 -1
  462. package/src/aws/sqs/queue.consume.ts +1 -34
  463. package/src/aws/sqs/queue.event-source.ts +227 -0
  464. package/src/aws/sqs/queue.provider.ts +14 -7
  465. package/src/aws/sqs/queue.send-message.ts +7 -10
  466. package/src/aws/sqs/queue.ts +9 -4
  467. package/src/binding.ts +130 -34
  468. package/src/capability.ts +44 -0
  469. package/src/cli/components/ApprovePlan.tsx +2 -2
  470. package/src/cli/components/Plan.tsx +6 -3
  471. package/src/cli/components/PlanProgress.tsx +32 -14
  472. package/src/cli/index.ts +2 -6
  473. package/src/cli/ink-service.tsx +61 -0
  474. package/src/cli/service.ts +23 -0
  475. package/src/cloudflare/account.ts +37 -0
  476. package/src/cloudflare/api.ts +147 -63
  477. package/src/cloudflare/config.ts +7 -0
  478. package/src/cloudflare/context.ts +49 -0
  479. package/src/cloudflare/index.ts +8 -4
  480. package/src/cloudflare/kv/index.ts +3 -0
  481. package/src/cloudflare/kv/namespace.binding.ts +27 -0
  482. package/src/cloudflare/kv/namespace.client.ts +70 -0
  483. package/src/cloudflare/kv/namespace.provider.ts +100 -0
  484. package/src/cloudflare/kv/namespace.ts +30 -0
  485. package/src/cloudflare/live.ts +32 -0
  486. package/src/cloudflare/r2/bucket.binding.ts +29 -0
  487. package/src/cloudflare/r2/bucket.client.ts +22 -0
  488. package/src/cloudflare/r2/bucket.del.ts +11 -0
  489. package/src/cloudflare/r2/bucket.get.ts +13 -0
  490. package/src/cloudflare/r2/bucket.head.ts +11 -0
  491. package/src/cloudflare/r2/bucket.list.ts +12 -0
  492. package/src/cloudflare/r2/bucket.multipart.ts +55 -0
  493. package/src/cloudflare/r2/bucket.provider.ts +84 -0
  494. package/src/cloudflare/r2/bucket.put.ts +17 -0
  495. package/src/cloudflare/r2/bucket.ts +44 -0
  496. package/src/cloudflare/r2/index.ts +9 -0
  497. package/src/cloudflare/stream.ts +21 -0
  498. package/src/cloudflare/worker/assets.fetch.ts +29 -0
  499. package/src/cloudflare/worker/assets.provider.ts +249 -0
  500. package/src/cloudflare/worker/index.ts +4 -0
  501. package/src/cloudflare/worker/worker.handler.ts +39 -0
  502. package/src/cloudflare/worker/worker.provider.ts +249 -0
  503. package/src/cloudflare/worker/worker.serve.ts +22 -0
  504. package/src/cloudflare/worker/worker.ts +77 -0
  505. package/src/data.ts +18 -0
  506. package/src/destroy.ts +2 -3
  507. package/src/diff.ts +30 -0
  508. package/src/dot-alchemy.ts +3 -2
  509. package/src/env.ts +20 -32
  510. package/src/esbuild.ts +98 -0
  511. package/src/exports.ts +21 -0
  512. package/src/index.ts +12 -6
  513. package/src/input.ts +81 -0
  514. package/src/output.ts +518 -0
  515. package/src/plan.ts +544 -243
  516. package/src/policy.ts +58 -7
  517. package/src/provider.ts +27 -25
  518. package/src/ref.ts +48 -0
  519. package/src/resource.ts +23 -8
  520. package/src/runtime.ts +16 -9
  521. package/src/schema.ts +102 -0
  522. package/src/service.ts +11 -7
  523. package/src/sha256.ts +23 -0
  524. package/src/stack.ts +116 -0
  525. package/src/stage.ts +85 -0
  526. package/src/state.ts +141 -62
  527. package/src/tags.ts +38 -0
  528. package/src/test.ts +172 -0
  529. package/src/type.ts +6 -0
  530. package/src/unknown.ts +6 -0
  531. package/src/user.ts +4 -0
  532. package/src/util.ts +21 -0
  533. package/lib/approve.d.ts +0 -15
  534. package/lib/approve.d.ts.map +0 -1
  535. package/lib/approve.js +0 -7
  536. package/lib/approve.js.map +0 -1
  537. package/lib/aws/lambda/function.client.d.ts +0 -8
  538. package/lib/aws/lambda/function.client.d.ts.map +0 -1
  539. package/lib/aws/lambda/function.client.js +0 -7
  540. package/lib/aws/lambda/function.client.js.map +0 -1
  541. package/lib/aws/sqs/queue.client.d.ts +0 -12
  542. package/lib/aws/sqs/queue.client.d.ts.map +0 -1
  543. package/lib/aws/sqs/queue.client.js.map +0 -1
  544. package/lib/cli/approve.d.ts +0 -4
  545. package/lib/cli/approve.d.ts.map +0 -1
  546. package/lib/cli/approve.js +0 -18
  547. package/lib/cli/approve.js.map +0 -1
  548. package/lib/cli/clack.d.ts +0 -14
  549. package/lib/cli/clack.d.ts.map +0 -1
  550. package/lib/cli/clack.js +0 -12
  551. package/lib/cli/clack.js.map +0 -1
  552. package/lib/cli/main.d.ts +0 -2
  553. package/lib/cli/main.d.ts.map +0 -1
  554. package/lib/cli/main.js +0 -1
  555. package/lib/cli/main.js.map +0 -1
  556. package/lib/cli/plan.d.ts +0 -13
  557. package/lib/cli/plan.d.ts.map +0 -1
  558. package/lib/cli/plan.js +0 -1
  559. package/lib/cli/plan.js.map +0 -1
  560. package/lib/cli/progress.d.ts +0 -7
  561. package/lib/cli/progress.d.ts.map +0 -1
  562. package/lib/cli/progress.js +0 -29
  563. package/lib/cli/progress.js.map +0 -1
  564. package/lib/cli/spinner.d.ts +0 -2
  565. package/lib/cli/spinner.d.ts.map +0 -1
  566. package/lib/cli/spinner.js +0 -13
  567. package/lib/cli/spinner.js.map +0 -1
  568. package/lib/cloudflare/kv.d.ts +0 -29
  569. package/lib/cloudflare/kv.d.ts.map +0 -1
  570. package/lib/cloudflare/kv.js +0 -3
  571. package/lib/cloudflare/kv.js.map +0 -1
  572. package/lib/cloudflare/kv.provider.d.ts +0 -4
  573. package/lib/cloudflare/kv.provider.d.ts.map +0 -1
  574. package/lib/cloudflare/kv.provider.js +0 -39
  575. package/lib/cloudflare/kv.provider.js.map +0 -1
  576. package/lib/cloudflare/worker.d.ts +0 -33
  577. package/lib/cloudflare/worker.d.ts.map +0 -1
  578. package/lib/cloudflare/worker.js +0 -4
  579. package/lib/cloudflare/worker.js.map +0 -1
  580. package/src/approve.ts +0 -13
  581. package/src/aws/lambda/function.client.ts +0 -14
  582. package/src/cli/approve.tsx +0 -30
  583. package/src/cli/clack.ts +0 -22
  584. package/src/cli/main.ts +0 -0
  585. package/src/cli/plan.ts +0 -16
  586. package/src/cli/progress.tsx +0 -45
  587. package/src/cli/spinner.ts +0 -14
  588. package/src/cloudflare/kv.provider.ts +0 -51
  589. package/src/cloudflare/kv.ts +0 -20
  590. package/src/cloudflare/worker.ts +0 -34
@@ -5,27 +5,30 @@ import { FileSystem } from "@effect/platform";
5
5
  import * as Effect from "effect/Effect";
6
6
  import * as Schedule from "effect/Schedule";
7
7
 
8
- import { App, DotAlchemy } from "alchemy-effect";
9
-
10
8
  import type {
9
+ CreateFunctionRequest,
11
10
  CreateFunctionUrlConfigRequest,
12
11
  UpdateFunctionUrlConfigRequest,
13
12
  } from "itty-aws/lambda";
14
- import { AccountID } from "../account.ts";
13
+ import { App } from "../../app.ts";
14
+ import { DotAlchemy } from "../../dot-alchemy.ts";
15
+ import type { ProviderService } from "../../provider.ts";
16
+ import { createTagger, createTagsList, hasTags } from "../../tags.ts";
15
17
  import * as IAM from "../iam.ts";
16
- import { Region } from "../region.ts";
17
18
  import { zipCode } from "../zip.ts";
18
- import { FunctionClient } from "./function.client.ts";
19
+ import { LambdaClient } from "./client.ts";
19
20
  import { Function, type FunctionAttr, type FunctionProps } from "./function.ts";
21
+ import { Account } from "../account.ts";
22
+ import { Region } from "../region.ts";
20
23
 
21
24
  export const functionProvider = () =>
22
25
  Function.provider.effect(
23
26
  Effect.gen(function* () {
24
- const lambda = yield* FunctionClient;
27
+ const lambda = yield* LambdaClient;
25
28
  const iam = yield* IAM.IAMClient;
26
- const accountId = yield* AccountID;
27
- const region = yield* Region;
28
29
  const app = yield* App;
30
+ const accountId = yield* Account;
31
+ const region = yield* Region;
29
32
  const dotAlchemy = yield* DotAlchemy;
30
33
  const fs = yield* FileSystem.FileSystem;
31
34
 
@@ -38,6 +41,19 @@ export const functionProvider = () =>
38
41
  const createPolicyName = (id: string) =>
39
42
  `${app.name}-${app.stage}-${id}-${region}`;
40
43
 
44
+ const createPhysicalNames = (id: string) => {
45
+ const roleName = createRoleName(id);
46
+ const policyName = createPolicyName(id);
47
+ const functionName = createFunctionName(id);
48
+ return {
49
+ roleName,
50
+ policyName,
51
+ functionName,
52
+ roleArn: `arn:aws:iam::${accountId}:role/${roleName}`,
53
+ functionArn: `arn:aws:lambda:${region}:${accountId}:function:${functionName}`,
54
+ };
55
+ };
56
+
41
57
  const attachBindings = Effect.fn(function* ({
42
58
  roleName,
43
59
  policyName,
@@ -51,15 +67,15 @@ export const functionProvider = () =>
51
67
  functionName: string;
52
68
  bindings: Function["binding"][];
53
69
  }) {
54
- const env = bindings.reduce(
55
- (acc, binding) => ({ ...acc, ...binding?.env }),
56
- {},
57
- );
58
- const policyStatements = bindings.flatMap((binding) =>
59
- binding?.policyStatements?.map((stmt: IAM.PolicyStatement) => ({
60
- ...stmt,
61
- Sid: stmt.Sid?.replace(/[^A-Za-z0-9]+/gi, ""),
62
- })),
70
+ const env = bindings
71
+ .map((binding) => binding?.env)
72
+ .reduce((acc, env) => ({ ...acc, ...env }), {});
73
+ const policyStatements = bindings.flatMap(
74
+ (binding) =>
75
+ binding?.policyStatements?.map((stmt: IAM.PolicyStatement) => ({
76
+ ...stmt,
77
+ Sid: stmt.Sid?.replace(/[^A-Za-z0-9]+/gi, ""),
78
+ })) ?? [],
63
79
  );
64
80
 
65
81
  if (policyStatements.length > 0) {
@@ -83,13 +99,14 @@ export const functionProvider = () =>
83
99
  return env;
84
100
  });
85
101
 
86
- const createRole = Effect.fn(function* ({
102
+ const createRoleIfNotExists = Effect.fn(function* ({
87
103
  id,
88
104
  roleName,
89
105
  }: {
90
106
  id: string;
91
107
  roleName: string;
92
108
  }) {
109
+ yield* Effect.logDebug(`creating role ${id}`);
93
110
  const role = yield* iam
94
111
  .createRole({
95
112
  RoleName: roleName,
@@ -105,7 +122,7 @@ export const functionProvider = () =>
105
122
  },
106
123
  ],
107
124
  }),
108
- Tags: createTagsList(id),
125
+ Tags: createTagsList(tagged(id)),
109
126
  })
110
127
  .pipe(
111
128
  Effect.catchTag("EntityAlreadyExistsException", () =>
@@ -115,7 +132,7 @@ export const functionProvider = () =>
115
132
  })
116
133
  .pipe(
117
134
  Effect.filterOrFail(
118
- (role) => validateTagList(tagged(id), role.Role?.Tags),
135
+ (role) => hasTags(tagged(id), role.Role?.Tags),
119
136
  () =>
120
137
  new Error(
121
138
  `Role ${roleName} exists but has incorrect tags`,
@@ -125,18 +142,25 @@ export const functionProvider = () =>
125
142
  ),
126
143
  );
127
144
 
128
- yield* iam.attachRolePolicy({
129
- RoleName: roleName,
130
- PolicyArn:
131
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
132
- });
145
+ yield* Effect.logDebug(`attaching policy ${id}`);
146
+ yield* iam
147
+ .attachRolePolicy({
148
+ RoleName: roleName,
149
+ PolicyArn:
150
+ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
151
+ })
152
+ .pipe(Effect.tapError(Effect.logDebug), Effect.tap(Effect.logDebug));
133
153
 
154
+ yield* Effect.logDebug(`attached policy ${id}`);
134
155
  return role;
135
156
  });
136
157
 
137
158
  const bundleCode = Effect.fn(function* (
138
159
  id: string,
139
- props: FunctionProps,
160
+ props: {
161
+ main: string;
162
+ handler?: string;
163
+ },
140
164
  ) {
141
165
  const handler = props.handler ?? "default";
142
166
  let file = path.relative(process.cwd(), props.main);
@@ -151,7 +175,7 @@ export const functionProvider = () =>
151
175
  );
152
176
  yield* bundle({
153
177
  // entryPoints: [props.main],
154
- // we use a virtual entry point so that
178
+ // we use a virtual entry point so that we can pluck out the user's handler closure and only its dependencies (not the whole module)
155
179
  stdin: {
156
180
  contents: `import { ${handler} as handler } from "${file}";\nexport default handler;`,
157
181
  resolveDir: process.cwd(),
@@ -168,6 +192,7 @@ export const functionProvider = () =>
168
192
  outfile,
169
193
  minify: true,
170
194
  external: ["@aws-sdk/*", "@smithy/*"],
195
+ logLevel: "error",
171
196
  });
172
197
  const code = yield* fs
173
198
  .readFile(outfile)
@@ -178,40 +203,12 @@ export const functionProvider = () =>
178
203
  };
179
204
  });
180
205
 
181
- const hashCode = (code: Uint8Array<ArrayBufferLike>) =>
206
+ const hashCode = (code: string | Uint8Array<ArrayBufferLike>) =>
182
207
  Effect.sync(() =>
183
208
  crypto.createHash("sha256").update(code).digest("hex"),
184
209
  );
185
210
 
186
- const validateTagList = (
187
- expectedTags: Record<string, string>,
188
- tags: { Key: string; Value: string }[] | undefined,
189
- ) => {
190
- return Object.entries(expectedTags).every(([key, value]) =>
191
- tags?.some((tag) => tag.Key === key && tag.Value === value),
192
- );
193
- };
194
-
195
- const validateTags = (
196
- expectedTags: Record<string, string>,
197
- tags: Record<string, string> | undefined,
198
- ) => {
199
- return Object.entries(expectedTags).every(
200
- ([key, value]) => tags?.[key] === value,
201
- );
202
- };
203
-
204
- const createTagsList = (id: string) =>
205
- Object.entries(tagged(id)).map(([Key, Value]) => ({
206
- Key,
207
- Value,
208
- }));
209
-
210
- const tagged = (id: string) => ({
211
- "alchemy::app": app.name,
212
- "alchemy::stage": app.stage,
213
- "alchemy::id": id,
214
- });
211
+ const tagged = yield* createTagger();
215
212
 
216
213
  const createOrUpdateFunction = Effect.fn(function* ({
217
214
  id,
@@ -222,54 +219,115 @@ export const functionProvider = () =>
222
219
  functionName,
223
220
  }: {
224
221
  id: string;
225
- news: FunctionProps;
222
+ news: FunctionProps<any>;
226
223
  roleArn: string;
227
- code: Uint8Array<ArrayBufferLike>;
228
- env: Record<string, string>;
224
+ code: string | Uint8Array<ArrayBufferLike>;
225
+ env: Record<string, string> | undefined;
229
226
  functionName: string;
230
227
  }) {
231
- yield* lambda
232
- .createFunction({
228
+ yield* Effect.logDebug(`creating function ${id}`);
229
+ const createFunctionRequest: CreateFunctionRequest = {
230
+ FunctionName: functionName,
231
+ Handler: `index.${news.handler ?? "default"}`,
232
+ Role: roleArn,
233
+ Code: {
234
+ // TODO(sam): upload to assets
235
+ ZipFile: yield* zipCode(code),
236
+ },
237
+ Runtime: news.runtime ?? "nodejs22.x",
238
+ Environment: env
239
+ ? {
240
+ Variables: env,
241
+ }
242
+ : undefined,
243
+ Tags: tagged(id),
244
+ };
245
+
246
+ const getAndUpdate = lambda
247
+ .getFunction({
233
248
  FunctionName: functionName,
234
- Handler: `index.${news.handler ?? "default"}`,
235
- Role: roleArn,
236
- Code: {
237
- // TODO(sam): upload to assets
238
- ZipFile: yield* zipCode(code),
239
- },
240
- Runtime: "nodejs22.x",
241
- Environment: {
242
- Variables: env,
243
- },
244
- Tags: tagged(id),
245
249
  })
246
250
  .pipe(
247
- Effect.retry({
248
- while: (e) =>
249
- e.name === "InvalidParameterValueException" &&
250
- e.message?.includes("cannot be assumed by Lambda"),
251
- schedule: Schedule.exponential(10),
252
- }),
253
- Effect.catchTag("ResourceConflictException", () =>
254
- lambda
255
- .getFunction({
256
- FunctionName: functionName,
257
- })
258
- .pipe(
259
- Effect.flatMap((f) =>
260
- // if it exists and contains these tags, we will assume it was created by alchemy
261
- // but state was lost, so if it exists, let's adopt it
262
- validateTags(tagged(id), f.Tags)
263
- ? Effect.succeed(f.Configuration!)
264
- : Effect.fail(
265
- new Error(
266
- "Function tags do not match expected values",
267
- ),
268
- ),
269
- ),
270
- ),
251
+ Effect.filterOrFail(
252
+ // if it exists and contains these tags, we will assume it was created by alchemy
253
+ // but state was lost, so if it exists, let's adopt it
254
+ (f) => hasTags(tagged(id), f.Tags),
255
+ () =>
256
+ // TODO(sam): add custom
257
+ new Error("Function tags do not match expected values"),
258
+ ),
259
+ Effect.flatMap(() =>
260
+ Effect.gen(function* () {
261
+ yield* Effect.logDebug(`updating function code ${id}`);
262
+ yield* lambda
263
+ .updateFunctionCode({
264
+ FunctionName: createFunctionRequest.FunctionName,
265
+ Architectures: createFunctionRequest.Architectures,
266
+ ZipFile: createFunctionRequest.Code.ZipFile,
267
+ // TODO(sam): support uploading via S3
268
+ })
269
+ .pipe(
270
+ Effect.retry({
271
+ while: (e) =>
272
+ e._tag === "ResourceConflictException" ||
273
+ (e._tag === "InvalidParameterValueException" &&
274
+ e.message?.includes(
275
+ "The role defined for the function cannot be assumed by Lambda.",
276
+ )),
277
+ schedule: Schedule.exponential(100),
278
+ }),
279
+ );
280
+ yield* Effect.logDebug(`updated function code ${id}`);
281
+ yield* lambda
282
+ .updateFunctionConfiguration({
283
+ FunctionName: createFunctionRequest.FunctionName,
284
+ DeadLetterConfig: createFunctionRequest.DeadLetterConfig,
285
+ Description: createFunctionRequest.Description,
286
+ Environment: createFunctionRequest.Environment,
287
+ EphemeralStorage: createFunctionRequest.EphemeralStorage,
288
+ FileSystemConfigs: createFunctionRequest.FileSystemConfigs,
289
+ Handler: createFunctionRequest.Handler,
290
+ ImageConfig: createFunctionRequest.ImageConfig,
291
+ KMSKeyArn: createFunctionRequest.KMSKeyArn,
292
+ Layers: createFunctionRequest.Layers,
293
+ LoggingConfig: createFunctionRequest.LoggingConfig,
294
+ MemorySize: createFunctionRequest.MemorySize,
295
+ // RevisionId: "???"
296
+ Role: createFunctionRequest.Role,
297
+ Runtime: createFunctionRequest.Runtime,
298
+ SnapStart: createFunctionRequest.SnapStart,
299
+ Timeout: createFunctionRequest.Timeout,
300
+ TracingConfig: createFunctionRequest.TracingConfig,
301
+ VpcConfig: createFunctionRequest.VpcConfig,
302
+ })
303
+ .pipe(
304
+ Effect.retry({
305
+ while: (e) =>
306
+ e._tag === "ResourceConflictException" ||
307
+ (e._tag === "InvalidParameterValueException" &&
308
+ e.message?.includes(
309
+ "The role defined for the function cannot be assumed by Lambda.",
310
+ )),
311
+ schedule: Schedule.exponential(100),
312
+ }),
313
+ );
314
+ yield* Effect.logDebug(`updated function configuration ${id}`);
315
+ }),
271
316
  ),
272
317
  );
318
+
319
+ yield* lambda.createFunction(createFunctionRequest).pipe(
320
+ Effect.tapError(Effect.logDebug),
321
+ Effect.retry({
322
+ while: (e) =>
323
+ e._tag === "InvalidParameterValueException" &&
324
+ e.message?.includes("cannot be assumed by Lambda"),
325
+ schedule: Schedule.exponential(10),
326
+ }),
327
+ Effect.catchTags({
328
+ ResourceConflictException: () => getAndUpdate,
329
+ }),
330
+ );
273
331
  });
274
332
 
275
333
  const createOrUpdateFunctionUrl = Effect.fn(function* ({
@@ -283,6 +341,7 @@ export const functionProvider = () =>
283
341
  }) {
284
342
  // TODO(sam): support AWS_IAM
285
343
  const authType = "NONE";
344
+ yield* Effect.logDebug(`creating function url config ${functionName}`);
286
345
  if (url) {
287
346
  const config = {
288
347
  FunctionName: functionName,
@@ -329,8 +388,12 @@ export const functionProvider = () =>
329
388
  )
330
389
  : Effect.void,
331
390
  ]);
391
+ yield* Effect.logDebug(`created function url config ${functionName}`);
332
392
  return FunctionUrl;
333
393
  } else if (oldUrl) {
394
+ yield* Effect.logDebug(
395
+ `deleting function url config ${functionName}`,
396
+ );
334
397
  yield* Effect.all([
335
398
  lambda
336
399
  .deleteFunctionUrlConfig({
@@ -348,6 +411,7 @@ export const functionProvider = () =>
348
411
  Effect.catchTag("ResourceNotFoundException", () => Effect.void),
349
412
  ),
350
413
  ]);
414
+ yield* Effect.logDebug(`deleted function url config ${functionName}`);
351
415
  }
352
416
  return undefined;
353
417
  });
@@ -362,9 +426,9 @@ export const functionProvider = () =>
362
426
  }`;
363
427
 
364
428
  return {
365
- // type: "AWS.Lambda.Function",
366
429
  read: Effect.fn(function* ({ id, output }) {
367
430
  if (output) {
431
+ yield* Effect.logDebug(`reading function ${id}`);
368
432
  // example: refresh the function URL from the API
369
433
  return {
370
434
  ...output,
@@ -374,6 +438,12 @@ export const functionProvider = () =>
374
438
  })
375
439
  .pipe(
376
440
  Effect.map((f) => f.FunctionUrl),
441
+ Effect.retry({
442
+ // error: ResourceConflictException: The operation cannot be performed at this time.
443
+ // An update is in progress for resource: arn:aws:lambda:us-west-2:084828582823:function:my-app-dev-Consumer-us-west-2
444
+ while: (e) => e.name === "ResourceConflictException",
445
+ schedule: Schedule.exponential(100),
446
+ }),
377
447
  Effect.catchTag("ResourceNotFoundException", () =>
378
448
  Effect.succeed(undefined),
379
449
  ),
@@ -384,22 +454,51 @@ export const functionProvider = () =>
384
454
  }),
385
455
  diff: Effect.fn(function* ({ id, olds, news, output }) {
386
456
  if (
387
- output.functionName !==
388
- (news.functionName ?? createFunctionName(id))
389
- ) {
390
457
  // function name changed
391
- return { action: "replace" };
392
- }
393
- if (olds.url !== news.url) {
458
+ output.functionName !==
459
+ (news.functionName ?? createFunctionName(id)) ||
394
460
  // url changed
461
+ olds.url !== news.url
462
+ ) {
395
463
  return { action: "replace" };
396
464
  }
397
- const { hash } = yield* bundleCode(id, news);
398
- if (output.code.hash !== hash) {
465
+ if (
466
+ output.code.hash !==
467
+ (yield* bundleCode(id, {
468
+ main: news.main,
469
+ handler: news.handler,
470
+ })).hash
471
+ ) {
399
472
  // code changed
400
473
  return { action: "update" };
401
474
  }
402
- return { action: "noop" };
475
+ }),
476
+ precreate: Effect.fn(function* ({ id, news }) {
477
+ const { roleName, functionName, roleArn } = createPhysicalNames(id);
478
+
479
+ const role = yield* createRoleIfNotExists({ id, roleName });
480
+
481
+ // mock code
482
+ const code = "export default () => {}";
483
+ yield* createOrUpdateFunction({
484
+ id,
485
+ news,
486
+ roleArn: role.Role.Arn,
487
+ code,
488
+ functionName,
489
+ env: {},
490
+ });
491
+
492
+ return {
493
+ functionArn: `arn:aws:lambda:${region}:${accountId}:function:${functionName}`,
494
+ functionName,
495
+ functionUrl: undefined,
496
+ roleName: createRoleName(id),
497
+ code: {
498
+ hash: yield* hashCode(code),
499
+ },
500
+ roleArn,
501
+ } satisfies FunctionAttr<FunctionProps>;
403
502
  }),
404
503
  create: Effect.fn(function* ({ id, news, bindings, session }) {
405
504
  const roleName = createRoleName(id);
@@ -408,7 +507,7 @@ export const functionProvider = () =>
408
507
  const functionName = news.functionName ?? createFunctionName(id);
409
508
  const functionArn = `arn:aws:lambda:${region}:${accountId}:function:${functionName}`;
410
509
 
411
- const role = yield* createRole({ id, roleName });
510
+ const role = yield* createRoleIfNotExists({ id, roleName });
412
511
 
413
512
  const env = yield* attachBindings({
414
513
  roleName,
@@ -558,6 +657,6 @@ export const functionProvider = () =>
558
657
  .pipe(Effect.catchTag("NoSuchEntityException", () => Effect.void));
559
658
  return null as any;
560
659
  }),
561
- };
660
+ } satisfies ProviderService<Function>;
562
661
  }),
563
662
  );
@@ -1,18 +1,24 @@
1
- import { Policy, Runtime, type Capability } from "alchemy-effect";
1
+ import type { Capability } from "../../capability.ts";
2
+ import { Runtime, type RuntimeProps } from "../../runtime.ts";
2
3
  import type * as IAM from "../iam.ts";
3
4
 
4
5
  export type { Context } from "aws-lambda";
5
6
 
6
- export interface FunctionProps<Req = any> {
7
+ export interface FunctionProps<Req = unknown>
8
+ extends RuntimeProps<Function, Req> {
7
9
  functionName?: string;
8
10
  functionArn?: string;
9
11
  main: string;
10
12
  handler?: string;
11
13
  memory?: number;
12
- runtime?: "nodejs20x" | "nodejs22x";
14
+ runtime?: "nodejs20.x" | "nodejs22.x";
13
15
  architecture?: "x86_64" | "arm64";
14
16
  url?: boolean;
15
- bindings: Policy<Function, Extract<Req, Capability>>;
17
+ }
18
+ export declare namespace FunctionProps {
19
+ export type Simplified<Req> = FunctionProps<
20
+ Capability.Simplify<Extract<Req, Capability>>
21
+ >;
16
22
  }
17
23
 
18
24
  export type FunctionAttr<Props extends FunctionProps = FunctionProps> = {
@@ -26,14 +32,17 @@ export type FunctionAttr<Props extends FunctionProps = FunctionProps> = {
26
32
  };
27
33
  };
28
34
 
29
- export interface Function extends Runtime<"AWS.Lambda.Function"> {
30
- props: FunctionProps;
31
- attr: FunctionAttr<Extract<this["props"], FunctionProps>>;
32
- binding: {
33
- env: {
34
- [key: string]: string;
35
- };
36
- policyStatements: IAM.PolicyStatement[];
35
+ export interface FunctionBinding {
36
+ env?: {
37
+ [key: string]: string;
37
38
  };
39
+ policyStatements?: IAM.PolicyStatement[];
40
+ }
41
+
42
+ export interface Function extends Runtime<"AWS.Lambda.Function"> {
43
+ props: FunctionProps<any>;
44
+ attr: FunctionAttr<Extract<this["props"], FunctionProps<any>>>;
45
+ binding: FunctionBinding;
46
+ base: Function;
38
47
  }
39
48
  export const Function = Runtime("AWS.Lambda.Function")<Function>();
@@ -1,12 +1,11 @@
1
- export * from "./function.client.ts";
1
+ export * from "./client.ts";
2
2
  export * from "./function.handler.ts";
3
3
  export * from "./function.invoke.ts";
4
4
  export * from "./function.provider.ts";
5
5
  export * from "./function.ts";
6
6
  export * from "./serve.ts";
7
-
8
7
  export * from "./consume.ts";
9
8
 
10
- export type * as Alchemy from "../index.ts";
11
-
12
9
  // export type * as lambda from "aws-lambda";
10
+
11
+ import "../config.ts";
@@ -22,7 +22,7 @@ export const serve =
22
22
  ) => Effect.Effect<FunctionURLResult, never, Req>;
23
23
  },
24
24
  ) =>
25
- <const Props extends Lambda.FunctionProps<Req>>(props: Props) =>
25
+ <const Props extends Lambda.FunctionProps.Simplified<Req>>(props: Props) =>
26
26
  Lambda.Function(id, { handle: fetch })({
27
27
  ...props,
28
28
  url: true,
@@ -1,6 +1,3 @@
1
1
  import * as Context from "effect/Context";
2
2
 
3
- export class AwsProfile extends Context.Tag("AWS::Profile")<
4
- AwsProfile,
5
- string
6
- >() {}
3
+ export class Profile extends Context.Tag("AWS::Profile")<Profile, string>() {}
package/src/aws/region.ts CHANGED
@@ -1,9 +1,15 @@
1
+ import * as Config from "effect/Config";
2
+ import * as Option from "effect/Option";
1
3
  import * as Context from "effect/Context";
2
4
  import * as Data from "effect/Data";
3
5
  import * as Effect from "effect/Effect";
4
6
  import * as Layer from "effect/Layer";
7
+ import { App } from "../app.ts";
8
+ import { loadProfile } from "./credentials.ts";
5
9
 
6
- export class Region extends Context.Tag("AWS::Region")<Region, string>() {}
10
+ export class Region extends Context.Tag("AWS::Region")<Region, RegionID>() {}
11
+
12
+ export type RegionID = string;
7
13
 
8
14
  export const of = (region: string) => Layer.succeed(Region, region);
9
15
 
@@ -17,11 +23,16 @@ export class EnvironmentVariableNotSet extends Data.TaggedError(
17
23
  variable: string;
18
24
  }> {}
19
25
 
26
+ export const AWS_REGION = Config.string("AWS_REGION");
27
+
28
+ const tryGetAWSRegion = () =>
29
+ Config.option(AWS_REGION).pipe(Effect.map(Option.getOrUndefined));
30
+
20
31
  export const fromEnv = () =>
21
32
  Layer.effect(
22
33
  Region,
23
34
  Effect.gen(function* () {
24
- const region = process.env.AWS_REGION;
35
+ const region = yield* tryGetAWSRegion();
25
36
  if (!region) {
26
37
  return yield* Effect.fail(
27
38
  new EnvironmentVariableNotSet({
@@ -33,3 +44,33 @@ export const fromEnv = () =>
33
44
  return region;
34
45
  }),
35
46
  );
47
+
48
+ export class AWSStageConfigRegionMissing extends Data.TaggedError(
49
+ "AWSStageConfigMissing",
50
+ )<{
51
+ message: string;
52
+ stage: string;
53
+ }> {}
54
+
55
+ export const fromStageConfig = () =>
56
+ Layer.effect(
57
+ Region,
58
+ Effect.gen(function* () {
59
+ const app = yield* App;
60
+ if (app.config.aws?.region) {
61
+ return app.config.aws.region;
62
+ } else if (app.config.aws?.profile) {
63
+ const profile = yield* loadProfile(app.config.aws.profile);
64
+ if (profile.region) {
65
+ return profile.region;
66
+ }
67
+ }
68
+ const region = yield* tryGetAWSRegion();
69
+ if (region) {
70
+ return region;
71
+ }
72
+ return yield* Effect.dieMessage(
73
+ "No AWS region found in stage config, SSO profile, or environment variable",
74
+ );
75
+ }),
76
+ );
@@ -0,0 +1,20 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Layer from "effect/Layer";
3
+
4
+ import { SQS } from "itty-aws/sqs";
5
+ import { createAWSServiceClientLayer } from "../client.ts";
6
+ import * as Credentials from "../credentials.ts";
7
+ import * as Region from "../region.ts";
8
+
9
+ export class SQSClient extends Context.Tag("AWS.SQS.Client")<
10
+ SQSClient,
11
+ SQS
12
+ >() {}
13
+
14
+ export const client = createAWSServiceClientLayer<typeof SQSClient, SQS>(
15
+ SQSClient,
16
+ SQS,
17
+ );
18
+
19
+ export const clientFromEnv = () =>
20
+ Layer.provide(client(), Layer.merge(Credentials.fromEnv(), Region.fromEnv()));
@@ -1,5 +1,8 @@
1
- export * from "./queue.client.ts";
1
+ export * from "./client.ts";
2
2
  export * from "./queue.consume.ts";
3
+ export * from "./queue.event-source.ts";
3
4
  export * from "./queue.provider.ts";
4
5
  export * from "./queue.send-message.ts";
5
6
  export * from "./queue.ts";
7
+
8
+ import "../config.ts";