alchemy-effect 0.0.0 → 0.2.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 (494) hide show
  1. package/README.md +179 -0
  2. package/bin/alchemy-effect.js +15 -0
  3. package/bin/alchemy-effect.js.map +1 -0
  4. package/bin/alchemy-effect.ts +10 -0
  5. package/lib/app.d.ts +7 -2
  6. package/lib/app.d.ts.map +1 -1
  7. package/lib/app.js +1 -0
  8. package/lib/app.js.map +1 -1
  9. package/lib/apply.d.ts +57 -1
  10. package/lib/apply.d.ts.map +1 -1
  11. package/lib/apply.js +141 -55
  12. package/lib/apply.js.map +1 -1
  13. package/lib/aws/account.d.ts +18 -0
  14. package/lib/aws/account.d.ts.map +1 -0
  15. package/lib/aws/account.js +18 -0
  16. package/lib/aws/account.js.map +1 -0
  17. package/lib/aws/arn.d.ts +2 -0
  18. package/lib/aws/arn.d.ts.map +1 -0
  19. package/lib/aws/arn.js +1 -0
  20. package/lib/aws/arn.js.map +1 -0
  21. package/lib/aws/assets.d.ts +8 -0
  22. package/lib/aws/assets.d.ts.map +1 -0
  23. package/lib/aws/assets.js +4 -0
  24. package/lib/aws/assets.js.map +1 -0
  25. package/lib/aws/bundle.d.ts +4 -0
  26. package/lib/aws/bundle.d.ts.map +1 -0
  27. package/lib/aws/bundle.js +4 -0
  28. package/lib/aws/bundle.js.map +1 -0
  29. package/lib/aws/client.d.ts +8 -0
  30. package/lib/aws/client.d.ts.map +1 -0
  31. package/lib/aws/client.js +28 -0
  32. package/lib/aws/client.js.map +1 -0
  33. package/lib/aws/credentials.d.ts +146 -0
  34. package/lib/aws/credentials.d.ts.map +1 -0
  35. package/lib/aws/credentials.js +170 -0
  36. package/lib/aws/credentials.js.map +1 -0
  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/dynamodb/client.js +11 -0
  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 +9 -0
  50. package/lib/aws/dynamodb/index.d.ts.map +1 -0
  51. package/lib/aws/dynamodb/index.js +10 -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 +25 -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 +56 -0
  62. package/lib/aws/dynamodb/table.d.ts.map +1 -0
  63. package/lib/aws/dynamodb/table.get-item.d.ts +55 -0
  64. package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -0
  65. package/lib/aws/dynamodb/table.get-item.js +75 -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 +8 -0
  70. package/lib/aws/dynamodb/table.provider.d.ts.map +1 -0
  71. package/lib/aws/dynamodb/table.provider.js +199 -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 +4 -0
  78. package/lib/aws/ec2/index.d.ts.map +1 -0
  79. package/lib/aws/ec2/index.js +4 -0
  80. package/lib/aws/ec2/index.js.map +1 -0
  81. package/lib/aws/ec2/vpc.d.ts +131 -0
  82. package/lib/aws/ec2/vpc.d.ts.map +1 -0
  83. package/lib/aws/ec2/vpc.js +3 -0
  84. package/lib/aws/ec2/vpc.js.map +1 -0
  85. package/lib/aws/ec2/vpc.provider.d.ts +7 -0
  86. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -0
  87. package/lib/aws/ec2/vpc.provider.js +198 -0
  88. package/lib/aws/ec2/vpc.provider.js.map +1 -0
  89. package/lib/aws/iam.d.ts +23 -0
  90. package/lib/aws/iam.d.ts.map +1 -0
  91. package/lib/aws/iam.js +7 -0
  92. package/lib/aws/iam.js.map +1 -0
  93. package/lib/aws/index.d.ts +32 -0
  94. package/lib/aws/index.d.ts.map +1 -0
  95. package/lib/aws/index.js +23 -0
  96. package/lib/aws/index.js.map +1 -0
  97. package/lib/aws/lambda/client.d.ts +8 -0
  98. package/lib/aws/lambda/client.d.ts.map +1 -0
  99. package/lib/aws/lambda/client.js +7 -0
  100. package/lib/aws/lambda/client.js.map +1 -0
  101. package/lib/aws/lambda/consume.d.ts +17 -0
  102. package/lib/aws/lambda/consume.d.ts.map +1 -0
  103. package/lib/aws/lambda/consume.js +30 -0
  104. package/lib/aws/lambda/consume.js.map +1 -0
  105. package/lib/aws/lambda/function.d.ts +41 -0
  106. package/lib/aws/lambda/function.d.ts.map +1 -0
  107. package/lib/aws/lambda/function.handler.d.ts +7 -0
  108. package/lib/aws/lambda/function.handler.d.ts.map +1 -0
  109. package/lib/aws/lambda/function.handler.js +8 -0
  110. package/lib/aws/lambda/function.handler.js.map +1 -0
  111. package/lib/aws/lambda/function.invoke.d.ts +10 -0
  112. package/lib/aws/lambda/function.invoke.d.ts.map +1 -0
  113. package/lib/aws/lambda/function.invoke.js +31 -0
  114. package/lib/aws/lambda/function.invoke.js.map +1 -0
  115. package/lib/aws/lambda/function.js +3 -0
  116. package/lib/aws/lambda/function.js.map +1 -0
  117. package/lib/aws/lambda/function.provider.d.ts +9 -0
  118. package/lib/aws/lambda/function.provider.d.ts.map +1 -0
  119. package/lib/aws/lambda/function.provider.js +465 -0
  120. package/lib/aws/lambda/function.provider.js.map +1 -0
  121. package/lib/aws/lambda/index.d.ts +8 -0
  122. package/lib/aws/lambda/index.d.ts.map +1 -0
  123. package/lib/aws/lambda/index.js +9 -0
  124. package/lib/aws/lambda/index.js.map +1 -0
  125. package/lib/aws/lambda/serve.d.ts +14 -0
  126. package/lib/aws/lambda/serve.d.ts.map +1 -0
  127. package/lib/aws/lambda/serve.js +7 -0
  128. package/lib/aws/lambda/serve.js.map +1 -0
  129. package/lib/aws/parse-ini.d.ts +4 -0
  130. package/lib/aws/parse-ini.d.ts.map +1 -0
  131. package/lib/aws/parse-ini.js +67 -0
  132. package/lib/aws/parse-ini.js.map +1 -0
  133. package/lib/aws/profile.d.ts +6 -0
  134. package/lib/aws/profile.d.ts.map +1 -0
  135. package/lib/aws/profile.js +4 -0
  136. package/lib/aws/profile.js.map +1 -0
  137. package/lib/aws/region.d.ts +19 -0
  138. package/lib/aws/region.d.ts.map +1 -0
  139. package/lib/aws/region.js +21 -0
  140. package/lib/aws/region.js.map +1 -0
  141. package/lib/aws/s3.d.ts +8 -0
  142. package/lib/aws/s3.d.ts.map +1 -0
  143. package/lib/aws/s3.js +7 -0
  144. package/lib/aws/s3.js.map +1 -0
  145. package/lib/aws/sqs/client.d.ts +12 -0
  146. package/lib/aws/sqs/client.d.ts.map +1 -0
  147. package/lib/aws/sqs/client.js +11 -0
  148. package/lib/aws/sqs/client.js.map +1 -0
  149. package/lib/aws/sqs/index.d.ts +7 -0
  150. package/lib/aws/sqs/index.d.ts.map +1 -0
  151. package/lib/aws/sqs/index.js +7 -0
  152. package/lib/aws/sqs/index.js.map +1 -0
  153. package/lib/aws/sqs/queue.consume.d.ts +12 -0
  154. package/lib/aws/sqs/queue.consume.d.ts.map +1 -0
  155. package/lib/aws/sqs/queue.consume.js +3 -0
  156. package/lib/aws/sqs/queue.consume.js.map +1 -0
  157. package/lib/aws/sqs/queue.d.ts +79 -0
  158. package/lib/aws/sqs/queue.d.ts.map +1 -0
  159. package/lib/aws/sqs/queue.event-source.d.ts +20 -0
  160. package/lib/aws/sqs/queue.event-source.d.ts.map +1 -0
  161. package/lib/aws/sqs/queue.event-source.js +148 -0
  162. package/lib/aws/sqs/queue.event-source.js.map +1 -0
  163. package/lib/aws/sqs/queue.js +3 -0
  164. package/lib/aws/sqs/queue.js.map +1 -0
  165. package/lib/aws/sqs/queue.provider.d.ts +7 -0
  166. package/lib/aws/sqs/queue.provider.d.ts.map +1 -0
  167. package/lib/aws/sqs/queue.provider.js +79 -0
  168. package/lib/aws/sqs/queue.provider.js.map +1 -0
  169. package/lib/aws/sqs/queue.send-message.d.ts +11 -0
  170. package/lib/aws/sqs/queue.send-message.d.ts.map +1 -0
  171. package/lib/aws/sqs/queue.send-message.js +32 -0
  172. package/lib/aws/sqs/queue.send-message.js.map +1 -0
  173. package/lib/aws/sts.d.ts +8 -0
  174. package/lib/aws/sts.d.ts.map +1 -0
  175. package/lib/aws/sts.js +7 -0
  176. package/lib/aws/sts.js.map +1 -0
  177. package/lib/aws/zip.d.ts +3 -0
  178. package/lib/aws/zip.d.ts.map +1 -0
  179. package/lib/aws/zip.js +12 -0
  180. package/lib/aws/zip.js.map +1 -0
  181. package/lib/binding.d.ts +70 -22
  182. package/lib/binding.d.ts.map +1 -1
  183. package/lib/binding.js.map +1 -1
  184. package/lib/capability.d.ts +38 -0
  185. package/lib/capability.d.ts.map +1 -1
  186. package/lib/cli/approve.d.ts +4 -0
  187. package/lib/cli/approve.d.ts.map +1 -0
  188. package/lib/cli/approve.js +18 -0
  189. package/lib/cli/approve.js.map +1 -0
  190. package/lib/cli/clack.d.ts +14 -0
  191. package/lib/cli/clack.d.ts.map +1 -0
  192. package/lib/cli/clack.js +12 -0
  193. package/lib/cli/clack.js.map +1 -0
  194. package/lib/cli/components/ApprovePlan.d.ts +8 -0
  195. package/lib/cli/components/ApprovePlan.d.ts.map +1 -0
  196. package/lib/cli/components/ApprovePlan.js +30 -0
  197. package/lib/cli/components/ApprovePlan.js.map +1 -0
  198. package/lib/cli/components/Plan.d.ts +7 -0
  199. package/lib/cli/components/Plan.d.ts.map +1 -0
  200. package/lib/cli/components/Plan.js +100 -0
  201. package/lib/cli/components/Plan.js.map +1 -0
  202. package/lib/cli/components/PlanProgress.d.ts +9 -0
  203. package/lib/cli/components/PlanProgress.d.ts.map +1 -0
  204. package/lib/cli/components/PlanProgress.js +166 -0
  205. package/lib/cli/components/PlanProgress.js.map +1 -0
  206. package/lib/cli/index.d.ts +449 -0
  207. package/lib/cli/index.d.ts.map +1 -0
  208. package/lib/cli/index.js +39912 -0
  209. package/lib/cli/index.js.map +1 -0
  210. package/lib/cli/main.d.ts +2 -0
  211. package/lib/cli/main.d.ts.map +1 -0
  212. package/lib/cli/main.js +1 -0
  213. package/lib/cli/main.js.map +1 -0
  214. package/lib/cli/plan.d.ts +13 -0
  215. package/lib/cli/plan.d.ts.map +1 -0
  216. package/lib/cli/plan.js +1 -0
  217. package/lib/cli/plan.js.map +1 -0
  218. package/lib/cli/progress.d.ts +7 -0
  219. package/lib/cli/progress.d.ts.map +1 -0
  220. package/lib/cli/progress.js +30 -0
  221. package/lib/cli/progress.js.map +1 -0
  222. package/lib/cli/spinner.d.ts +2 -0
  223. package/lib/cli/spinner.d.ts.map +1 -0
  224. package/lib/cli/spinner.js +13 -0
  225. package/lib/cli/spinner.js.map +1 -0
  226. package/lib/cloudflare/api.d.ts +36 -0
  227. package/lib/cloudflare/api.d.ts.map +1 -0
  228. package/lib/cloudflare/api.js +99 -0
  229. package/lib/cloudflare/api.js.map +1 -0
  230. package/lib/cloudflare/context.d.ts +27 -0
  231. package/lib/cloudflare/context.d.ts.map +1 -0
  232. package/lib/cloudflare/context.js +24 -0
  233. package/lib/cloudflare/context.js.map +1 -0
  234. package/lib/cloudflare/index.d.ts +6 -0
  235. package/lib/cloudflare/index.d.ts.map +1 -0
  236. package/lib/cloudflare/index.js +5 -0
  237. package/lib/cloudflare/index.js.map +1 -0
  238. package/lib/cloudflare/kv/index.d.ts +4 -0
  239. package/lib/cloudflare/kv/index.d.ts.map +1 -0
  240. package/lib/cloudflare/kv/index.js +4 -0
  241. package/lib/cloudflare/kv/index.js.map +1 -0
  242. package/lib/cloudflare/kv/namespace.binding.d.ts +8 -0
  243. package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -0
  244. package/lib/cloudflare/kv/namespace.binding.js +15 -0
  245. package/lib/cloudflare/kv/namespace.binding.js.map +1 -0
  246. package/lib/cloudflare/kv/namespace.client.d.ts +11 -0
  247. package/lib/cloudflare/kv/namespace.client.d.ts.map +1 -0
  248. package/lib/cloudflare/kv/namespace.client.js +31 -0
  249. package/lib/cloudflare/kv/namespace.client.js.map +1 -0
  250. package/lib/cloudflare/kv/namespace.d.ts +23 -0
  251. package/lib/cloudflare/kv/namespace.d.ts.map +1 -0
  252. package/lib/cloudflare/kv/namespace.js +3 -0
  253. package/lib/cloudflare/kv/namespace.js.map +1 -0
  254. package/lib/cloudflare/kv/namespace.provider.d.ts +5 -0
  255. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -0
  256. package/lib/cloudflare/kv/namespace.provider.js +80 -0
  257. package/lib/cloudflare/kv/namespace.provider.js.map +1 -0
  258. package/lib/cloudflare/live.d.ts +11 -0
  259. package/lib/cloudflare/live.d.ts.map +1 -0
  260. package/lib/cloudflare/live.js +18 -0
  261. package/lib/cloudflare/live.js.map +1 -0
  262. package/lib/cloudflare/r2/bucket.binding.d.ts +8 -0
  263. package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -0
  264. package/lib/cloudflare/r2/bucket.binding.js +18 -0
  265. package/lib/cloudflare/r2/bucket.binding.js.map +1 -0
  266. package/lib/cloudflare/r2/bucket.client.d.ts +8 -0
  267. package/lib/cloudflare/r2/bucket.client.d.ts.map +1 -0
  268. package/lib/cloudflare/r2/bucket.client.js +9 -0
  269. package/lib/cloudflare/r2/bucket.client.js.map +1 -0
  270. package/lib/cloudflare/r2/bucket.d.ts +32 -0
  271. package/lib/cloudflare/r2/bucket.d.ts.map +1 -0
  272. package/lib/cloudflare/r2/bucket.del.d.ts +4 -0
  273. package/lib/cloudflare/r2/bucket.del.d.ts.map +1 -0
  274. package/lib/cloudflare/r2/bucket.del.js +7 -0
  275. package/lib/cloudflare/r2/bucket.del.js.map +1 -0
  276. package/lib/cloudflare/r2/bucket.get.d.ts +5 -0
  277. package/lib/cloudflare/r2/bucket.get.d.ts.map +1 -0
  278. package/lib/cloudflare/r2/bucket.get.js +7 -0
  279. package/lib/cloudflare/r2/bucket.get.js.map +1 -0
  280. package/lib/cloudflare/r2/bucket.head.d.ts +4 -0
  281. package/lib/cloudflare/r2/bucket.head.d.ts.map +1 -0
  282. package/lib/cloudflare/r2/bucket.head.js +7 -0
  283. package/lib/cloudflare/r2/bucket.head.js.map +1 -0
  284. package/lib/cloudflare/r2/bucket.js +3 -0
  285. package/lib/cloudflare/r2/bucket.js.map +1 -0
  286. package/lib/cloudflare/r2/bucket.list.d.ts +5 -0
  287. package/lib/cloudflare/r2/bucket.list.d.ts.map +1 -0
  288. package/lib/cloudflare/r2/bucket.list.js +7 -0
  289. package/lib/cloudflare/r2/bucket.list.js.map +1 -0
  290. package/lib/cloudflare/r2/bucket.multipart.d.ts +19 -0
  291. package/lib/cloudflare/r2/bucket.multipart.d.ts.map +1 -0
  292. package/lib/cloudflare/r2/bucket.multipart.js +25 -0
  293. package/lib/cloudflare/r2/bucket.multipart.js.map +1 -0
  294. package/lib/cloudflare/r2/bucket.provider.d.ts +5 -0
  295. package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -0
  296. package/lib/cloudflare/r2/bucket.provider.js +66 -0
  297. package/lib/cloudflare/r2/bucket.provider.js.map +1 -0
  298. package/lib/cloudflare/r2/bucket.put.d.ts +6 -0
  299. package/lib/cloudflare/r2/bucket.put.d.ts.map +1 -0
  300. package/lib/cloudflare/r2/bucket.put.js +8 -0
  301. package/lib/cloudflare/r2/bucket.put.js.map +1 -0
  302. package/lib/cloudflare/r2/index.d.ts +10 -0
  303. package/lib/cloudflare/r2/index.d.ts.map +1 -0
  304. package/lib/cloudflare/r2/index.js +10 -0
  305. package/lib/cloudflare/r2/index.js.map +1 -0
  306. package/lib/cloudflare/stream.d.ts +10 -0
  307. package/lib/cloudflare/stream.d.ts.map +1 -0
  308. package/lib/cloudflare/stream.js +16 -0
  309. package/lib/cloudflare/stream.js.map +1 -0
  310. package/lib/cloudflare/worker/assets.fetch.d.ts +8 -0
  311. package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -0
  312. package/lib/cloudflare/worker/assets.fetch.js +11 -0
  313. package/lib/cloudflare/worker/assets.fetch.js.map +1 -0
  314. package/lib/cloudflare/worker/assets.provider.d.ts +66 -0
  315. package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -0
  316. package/lib/cloudflare/worker/assets.provider.js +145 -0
  317. package/lib/cloudflare/worker/assets.provider.js.map +1 -0
  318. package/lib/cloudflare/worker/index.d.ts +6 -0
  319. package/lib/cloudflare/worker/index.d.ts.map +1 -0
  320. package/lib/cloudflare/worker/index.js +5 -0
  321. package/lib/cloudflare/worker/index.js.map +1 -0
  322. package/lib/cloudflare/worker/worker.d.ts +67 -0
  323. package/lib/cloudflare/worker/worker.d.ts.map +1 -0
  324. package/lib/cloudflare/worker/worker.handler.d.ts +11 -0
  325. package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -0
  326. package/lib/cloudflare/worker/worker.handler.js +15 -0
  327. package/lib/cloudflare/worker/worker.handler.js.map +1 -0
  328. package/lib/cloudflare/worker/worker.js +4 -0
  329. package/lib/cloudflare/worker/worker.js.map +1 -0
  330. package/lib/cloudflare/worker/worker.provider.d.ts +10 -0
  331. package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -0
  332. package/lib/cloudflare/worker/worker.provider.js +193 -0
  333. package/lib/cloudflare/worker/worker.provider.js.map +1 -0
  334. package/lib/cloudflare/worker/worker.serve.d.ts +39 -0
  335. package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -0
  336. package/lib/cloudflare/worker/worker.serve.js +4 -0
  337. package/lib/cloudflare/worker/worker.serve.js.map +1 -0
  338. package/lib/destroy.d.ts +1 -3
  339. package/lib/destroy.d.ts.map +1 -1
  340. package/lib/destroy.js +5 -0
  341. package/lib/destroy.js.map +1 -1
  342. package/lib/dot-alchemy.d.ts +3 -2
  343. package/lib/dot-alchemy.d.ts.map +1 -1
  344. package/lib/dot-alchemy.js +3 -2
  345. package/lib/dot-alchemy.js.map +1 -1
  346. package/lib/esbuild.d.ts +28 -0
  347. package/lib/esbuild.d.ts.map +1 -0
  348. package/lib/esbuild.js +63 -0
  349. package/lib/esbuild.js.map +1 -0
  350. package/lib/index.d.ts +1 -0
  351. package/lib/index.d.ts.map +1 -1
  352. package/lib/index.js +4 -0
  353. package/lib/index.js.map +1 -1
  354. package/lib/plan.d.ts +19 -8
  355. package/lib/plan.d.ts.map +1 -1
  356. package/lib/plan.js +144 -72
  357. package/lib/plan.js.map +1 -1
  358. package/lib/policy.d.ts +19 -1
  359. package/lib/policy.d.ts.map +1 -1
  360. package/lib/policy.js +10 -1
  361. package/lib/policy.js.map +1 -1
  362. package/lib/provider.d.ts +2 -2
  363. package/lib/provider.d.ts.map +1 -1
  364. package/lib/resource.d.ts +2 -10
  365. package/lib/resource.d.ts.map +1 -1
  366. package/lib/resource.js +1 -0
  367. package/lib/resource.js.map +1 -1
  368. package/lib/runtime.d.ts +1 -1
  369. package/lib/runtime.d.ts.map +1 -1
  370. package/lib/schema.d.ts +37 -0
  371. package/lib/schema.d.ts.map +1 -0
  372. package/lib/schema.js +61 -0
  373. package/lib/schema.js.map +1 -0
  374. package/lib/sha256.d.ts +5 -0
  375. package/lib/sha256.d.ts.map +1 -0
  376. package/lib/sha256.js +16 -0
  377. package/lib/sha256.js.map +1 -0
  378. package/lib/state.d.ts +3 -2
  379. package/lib/state.d.ts.map +1 -1
  380. package/lib/state.js +3 -2
  381. package/lib/state.js.map +1 -1
  382. package/lib/tags.d.ts +17 -0
  383. package/lib/tags.d.ts.map +1 -0
  384. package/lib/tags.js +22 -0
  385. package/lib/tags.js.map +1 -0
  386. package/lib/test.d.ts +14 -0
  387. package/lib/test.d.ts.map +1 -0
  388. package/lib/test.js +28 -0
  389. package/lib/test.js.map +1 -0
  390. package/lib/tsconfig.test.tsbuildinfo +1 -0
  391. package/lib/type.d.ts +3 -0
  392. package/lib/type.d.ts.map +1 -0
  393. package/lib/type.js +3 -0
  394. package/lib/type.js.map +1 -0
  395. package/package.json +115 -3
  396. package/src/app.ts +8 -7
  397. package/src/apply.ts +251 -93
  398. package/src/aws/account.ts +37 -0
  399. package/src/aws/arn.ts +1 -0
  400. package/src/aws/assets.ts +8 -0
  401. package/src/aws/bundle.ts +5 -0
  402. package/src/aws/client.ts +47 -0
  403. package/src/aws/credentials.ts +409 -0
  404. package/src/aws/dynamodb/attribute-value.ts +240 -0
  405. package/src/aws/dynamodb/client.ts +20 -0
  406. package/src/aws/dynamodb/expr.ts +90 -0
  407. package/src/aws/dynamodb/index.ts +12 -0
  408. package/src/aws/dynamodb/projection.ts +159 -0
  409. package/src/aws/dynamodb/secondary-index.ts +45 -0
  410. package/src/aws/dynamodb/table.get-item.ts +177 -0
  411. package/src/aws/dynamodb/table.provider.ts +280 -0
  412. package/src/aws/dynamodb/table.ts +156 -0
  413. package/src/aws/ec2/client.ts +20 -0
  414. package/src/aws/ec2/index.ts +3 -0
  415. package/src/aws/ec2/vpc.provider.ts +285 -0
  416. package/src/aws/ec2/vpc.ts +152 -0
  417. package/src/aws/iam.ts +30 -0
  418. package/src/aws/index.ts +54 -0
  419. package/src/aws/lambda/client.ts +14 -0
  420. package/src/aws/lambda/consume.ts +63 -0
  421. package/src/aws/lambda/function.handler.ts +30 -0
  422. package/src/aws/lambda/function.invoke.ts +40 -0
  423. package/src/aws/lambda/function.provider.ts +655 -0
  424. package/src/aws/lambda/function.ts +45 -0
  425. package/src/aws/lambda/index.ts +9 -0
  426. package/src/aws/lambda/serve.ts +29 -0
  427. package/src/aws/parse-ini.ts +80 -0
  428. package/src/aws/profile.ts +6 -0
  429. package/src/aws/region.ts +37 -0
  430. package/src/aws/s3.ts +10 -0
  431. package/src/aws/sqs/client.ts +20 -0
  432. package/src/aws/sqs/index.ts +6 -0
  433. package/src/aws/sqs/queue.consume.ts +13 -0
  434. package/src/aws/sqs/queue.event-source.ts +253 -0
  435. package/src/aws/sqs/queue.provider.ts +94 -0
  436. package/src/aws/sqs/queue.send-message.ts +51 -0
  437. package/src/aws/sqs/queue.ts +86 -0
  438. package/src/aws/sts.ts +13 -0
  439. package/src/aws/zip.ts +17 -0
  440. package/src/binding.ts +121 -25
  441. package/src/capability.ts +44 -0
  442. package/src/cli/approve.tsx +30 -0
  443. package/src/cli/clack.ts +22 -0
  444. package/src/cli/components/ApprovePlan.tsx +44 -0
  445. package/src/cli/components/Plan.tsx +154 -0
  446. package/src/cli/components/PlanProgress.tsx +206 -0
  447. package/src/cli/index.ts +6 -0
  448. package/src/cli/main.ts +0 -0
  449. package/src/cli/plan.ts +16 -0
  450. package/src/cli/progress.tsx +46 -0
  451. package/src/cli/spinner.ts +14 -0
  452. package/src/cloudflare/api.ts +152 -0
  453. package/src/cloudflare/context.ts +49 -0
  454. package/src/cloudflare/index.ts +6 -0
  455. package/src/cloudflare/kv/index.ts +3 -0
  456. package/src/cloudflare/kv/namespace.binding.ts +25 -0
  457. package/src/cloudflare/kv/namespace.client.ts +70 -0
  458. package/src/cloudflare/kv/namespace.provider.ts +99 -0
  459. package/src/cloudflare/kv/namespace.ts +29 -0
  460. package/src/cloudflare/live.ts +38 -0
  461. package/src/cloudflare/r2/bucket.binding.ts +27 -0
  462. package/src/cloudflare/r2/bucket.client.ts +22 -0
  463. package/src/cloudflare/r2/bucket.del.ts +11 -0
  464. package/src/cloudflare/r2/bucket.get.ts +13 -0
  465. package/src/cloudflare/r2/bucket.head.ts +11 -0
  466. package/src/cloudflare/r2/bucket.list.ts +12 -0
  467. package/src/cloudflare/r2/bucket.multipart.ts +55 -0
  468. package/src/cloudflare/r2/bucket.provider.ts +83 -0
  469. package/src/cloudflare/r2/bucket.put.ts +17 -0
  470. package/src/cloudflare/r2/bucket.ts +38 -0
  471. package/src/cloudflare/r2/index.ts +9 -0
  472. package/src/cloudflare/stream.ts +21 -0
  473. package/src/cloudflare/worker/assets.fetch.ts +27 -0
  474. package/src/cloudflare/worker/assets.provider.ts +249 -0
  475. package/src/cloudflare/worker/index.ts +6 -0
  476. package/src/cloudflare/worker/worker.handler.ts +39 -0
  477. package/src/cloudflare/worker/worker.provider.ts +246 -0
  478. package/src/cloudflare/worker/worker.serve.ts +19 -0
  479. package/src/cloudflare/worker/worker.ts +76 -0
  480. package/src/destroy.ts +6 -3
  481. package/src/dot-alchemy.ts +3 -2
  482. package/src/esbuild.ts +98 -0
  483. package/src/index.ts +5 -0
  484. package/src/plan.ts +233 -120
  485. package/src/policy.ts +55 -2
  486. package/src/provider.ts +2 -2
  487. package/src/resource.ts +3 -2
  488. package/src/runtime.ts +1 -1
  489. package/src/schema.ts +102 -0
  490. package/src/sha256.ts +23 -0
  491. package/src/state.ts +3 -2
  492. package/src/tags.ts +38 -0
  493. package/src/test.ts +71 -0
  494. package/src/type.ts +2 -0
@@ -0,0 +1,285 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schedule from "effect/Schedule";
3
+
4
+ import { App, type ProviderService } from "alchemy-effect";
5
+ import type { ScopedPlanStatusSession } from "../../apply.ts";
6
+ import { createTagger, createTagsList } from "../../tags.ts";
7
+ import { Account } from "../account.ts";
8
+ import { Region } from "../region.ts";
9
+ import { EC2Client } from "./client.ts";
10
+ import { Vpc, type VpcAttrs, type VpcProps } from "./vpc.ts";
11
+
12
+ import type { EC2 } from "itty-aws/ec2";
13
+
14
+ export const vpcProvider = () =>
15
+ Vpc.provider.effect(
16
+ Effect.gen(function* () {
17
+ const ec2 = yield* EC2Client;
18
+ const app = yield* App;
19
+ const region = yield* Region;
20
+ const accountId = yield* Account;
21
+ const tagged = yield* createTagger();
22
+
23
+ return {
24
+ diff: Effect.fn(function* ({ id, news, olds }) {
25
+ // 1. CIDR block changes
26
+ if (olds.cidrBlock !== news.cidrBlock) {
27
+ return { action: "replace" } as const;
28
+ }
29
+
30
+ // 2. Instance tenancy changes
31
+ if (olds.instanceTenancy !== news.instanceTenancy) {
32
+ return { action: "replace" } as const;
33
+ }
34
+
35
+ // 3. IPAM pool changes
36
+ if (olds.ipv4IpamPoolId !== news.ipv4IpamPoolId) {
37
+ return { action: "replace" } as const;
38
+ }
39
+
40
+ if (olds.ipv6IpamPoolId !== news.ipv6IpamPoolId) {
41
+ return { action: "replace" } as const;
42
+ }
43
+
44
+ // 4. IPv6 CIDR block changes
45
+ if (olds.ipv6CidrBlock !== news.ipv6CidrBlock) {
46
+ return { action: "replace" } as const;
47
+ }
48
+
49
+ // 5. IPv6 pool changes
50
+ if (olds.ipv6Pool !== news.ipv6Pool) {
51
+ return { action: "replace" } as const;
52
+ }
53
+ }),
54
+
55
+ create: Effect.fn(function* ({ id, news, session }) {
56
+ // 1. Prepare tags
57
+ const alchemyTags = tagged(id);
58
+ const userTags = news.tags ?? {};
59
+ const allTags = { ...alchemyTags, ...userTags };
60
+
61
+ // 2. Call CreateVpc
62
+ const createResult = yield* ec2.createVpc({
63
+ // TODO(sam): add all properties
64
+ AmazonProvidedIpv6CidrBlock: news.amazonProvidedIpv6CidrBlock,
65
+ InstanceTenancy: news.instanceTenancy,
66
+ CidrBlock: news.cidrBlock,
67
+ Ipv4IpamPoolId: news.ipv4IpamPoolId,
68
+ Ipv4NetmaskLength: news.ipv4NetmaskLength,
69
+ Ipv6Pool: news.ipv6Pool,
70
+ Ipv6CidrBlock: news.ipv6CidrBlock,
71
+ Ipv6IpamPoolId: news.ipv6IpamPoolId,
72
+ Ipv6NetmaskLength: news.ipv6NetmaskLength,
73
+ Ipv6CidrBlockNetworkBorderGroup:
74
+ news.ipv6CidrBlockNetworkBorderGroup,
75
+ TagSpecifications: [
76
+ {
77
+ ResourceType: "vpc",
78
+ Tags: createTagsList(allTags),
79
+ },
80
+ ],
81
+ DryRun: false,
82
+ });
83
+
84
+ const vpcId = createResult.Vpc!.VpcId!;
85
+ yield* session.note(`VPC created: ${vpcId}`);
86
+
87
+ // 3. Modify DNS attributes if specified (separate API calls)
88
+ yield* ec2.modifyVpcAttribute({
89
+ VpcId: vpcId,
90
+ EnableDnsSupport: { Value: news.enableDnsSupport ?? true },
91
+ });
92
+
93
+ if (news.enableDnsHostnames !== undefined) {
94
+ yield* ec2.modifyVpcAttribute({
95
+ VpcId: vpcId,
96
+ EnableDnsHostnames: { Value: news.enableDnsHostnames },
97
+ });
98
+ }
99
+
100
+ // 4. Wait for VPC to be available
101
+ const vpc = yield* waitForVpcAvailable(ec2, vpcId, session);
102
+
103
+ // 6. Return attributes
104
+ return {
105
+ vpcId,
106
+ vpcArn:
107
+ `arn:aws:ec2:${region}:${accountId}:vpc/${vpcId}` as VpcAttrs<VpcProps>["vpcArn"],
108
+ cidrBlock: vpc.CidrBlock!,
109
+ dhcpOptionsId: vpc.DhcpOptionsId!,
110
+ state: vpc.State!,
111
+ isDefault: vpc.IsDefault ?? false,
112
+ ownerId: vpc.OwnerId,
113
+ cidrBlockAssociationSet: vpc.CidrBlockAssociationSet?.map(
114
+ (assoc) => ({
115
+ associationId: assoc.AssociationId!,
116
+ cidrBlock: assoc.CidrBlock!,
117
+ cidrBlockState: {
118
+ state: assoc.CidrBlockState!.State!,
119
+ statusMessage: assoc.CidrBlockState!.StatusMessage,
120
+ },
121
+ }),
122
+ ),
123
+ ipv6CidrBlockAssociationSet: vpc.Ipv6CidrBlockAssociationSet?.map(
124
+ (assoc) => ({
125
+ associationId: assoc.AssociationId!,
126
+ ipv6CidrBlock: assoc.Ipv6CidrBlock!,
127
+ ipv6CidrBlockState: {
128
+ state: assoc.Ipv6CidrBlockState!.State!,
129
+ statusMessage: assoc.Ipv6CidrBlockState!.StatusMessage,
130
+ },
131
+ networkBorderGroup: assoc.NetworkBorderGroup,
132
+ ipv6Pool: assoc.Ipv6Pool,
133
+ }),
134
+ ),
135
+ } satisfies VpcAttrs<VpcProps>;
136
+ }),
137
+
138
+ update: Effect.fn(function* ({ news, olds, output, session }) {
139
+ const vpcId = output.vpcId;
140
+
141
+ // Only DNS and metrics settings can be updated
142
+ // Everything else requires replacement (handled by diff)
143
+
144
+ if (news.enableDnsSupport !== olds.enableDnsSupport) {
145
+ yield* ec2.modifyVpcAttribute({
146
+ VpcId: vpcId,
147
+ EnableDnsSupport: { Value: news.enableDnsSupport ?? true },
148
+ });
149
+ yield* session.note("Updated DNS support");
150
+ }
151
+
152
+ if (news.enableDnsHostnames !== olds.enableDnsHostnames) {
153
+ yield* ec2.modifyVpcAttribute({
154
+ VpcId: vpcId,
155
+ EnableDnsHostnames: { Value: news.enableDnsHostnames ?? false },
156
+ });
157
+ yield* session.note("Updated DNS hostnames");
158
+ }
159
+
160
+ // Note: Tag updates would go here if we support user tag changes
161
+
162
+ return output; // VPC attributes don't change from these updates
163
+ }),
164
+
165
+ delete: Effect.fn(function* ({ output, session }) {
166
+ const vpcId = output.vpcId;
167
+
168
+ yield* session.note(`Deleting VPC: ${vpcId}`);
169
+
170
+ // 1. Attempt to delete VPC
171
+ yield* ec2
172
+ .deleteVpc({
173
+ VpcId: vpcId,
174
+ DryRun: false,
175
+ })
176
+ .pipe(
177
+ Effect.tapError(Effect.logDebug),
178
+ Effect.catchTag("InvalidVpcID.NotFound", () => Effect.void),
179
+ // Retry on dependency violations (resources still being deleted)
180
+ Effect.retry({
181
+ while: (e) => {
182
+ // DependencyViolation means there are still dependent resources
183
+ // This can happen if subnets/IGW are being deleted concurrently
184
+ return (
185
+ e._tag === "ValidationError" &&
186
+ e.message?.includes("DependencyViolation")
187
+ );
188
+ },
189
+ schedule: Schedule.exponential(1000, 1.5).pipe(
190
+ Schedule.intersect(Schedule.recurs(10)), // Try up to 10 times
191
+ Schedule.tapOutput(([, attempt]) =>
192
+ session.note(
193
+ `Waiting for dependencies to clear... (attempt ${attempt + 1})`,
194
+ ),
195
+ ),
196
+ ),
197
+ }),
198
+ );
199
+
200
+ // 2. Wait for VPC to be fully deleted
201
+ yield* waitForVpcDeleted(ec2, vpcId, session);
202
+
203
+ yield* session.note(`VPC ${vpcId} deleted successfully`);
204
+ }),
205
+ } satisfies ProviderService<Vpc>;
206
+ }),
207
+ );
208
+
209
+ /**
210
+ * Wait for VPC to be in available state
211
+ */
212
+ const waitForVpcAvailable = (
213
+ ec2: EC2,
214
+ vpcId: string,
215
+ session?: ScopedPlanStatusSession,
216
+ ) =>
217
+ Effect.retry(
218
+ Effect.gen(function* () {
219
+ const result = yield* ec2
220
+ .describeVpcs({ VpcIds: [vpcId] })
221
+ .pipe(
222
+ Effect.catchTag("InvalidVpcID.NotFound", () =>
223
+ Effect.succeed({ Vpcs: [] }),
224
+ ),
225
+ );
226
+ const vpc = result.Vpcs![0];
227
+
228
+ if (vpc.State === "available") {
229
+ return vpc;
230
+ }
231
+
232
+ // Still pending, fail to trigger retry
233
+ return yield* Effect.fail(new Error("VPC not yet available"));
234
+ }),
235
+ {
236
+ schedule: Schedule.fixed(2000).pipe(
237
+ // Check every 2 seconds
238
+ Schedule.intersect(Schedule.recurs(30)), // Max 60 seconds
239
+ Schedule.tapOutput(([, attempt]) =>
240
+ session
241
+ ? session.note(
242
+ `Waiting for VPC to be available... (${(attempt + 1) * 2}s)`,
243
+ )
244
+ : Effect.void,
245
+ ),
246
+ ),
247
+ },
248
+ );
249
+
250
+ /**
251
+ * Wait for VPC to be deleted
252
+ */
253
+ const waitForVpcDeleted = (
254
+ ec2: EC2,
255
+ vpcId: string,
256
+ session: ScopedPlanStatusSession,
257
+ ) =>
258
+ Effect.gen(function* () {
259
+ yield* Effect.retry(
260
+ Effect.gen(function* () {
261
+ const result = yield* ec2.describeVpcs({ VpcIds: [vpcId] }).pipe(
262
+ Effect.tapError(Effect.logDebug),
263
+ Effect.catchTag("InvalidVpcID.NotFound", () =>
264
+ Effect.succeed({ Vpcs: [] }),
265
+ ),
266
+ );
267
+
268
+ if (!result.Vpcs || result.Vpcs.length === 0) {
269
+ return; // Successfully deleted
270
+ }
271
+
272
+ // Still exists, fail to trigger retry
273
+ return yield* Effect.fail(new Error("VPC still exists"));
274
+ }),
275
+ {
276
+ schedule: Schedule.fixed(2000).pipe(
277
+ // Check every 2 seconds
278
+ Schedule.intersect(Schedule.recurs(15)), // Max 30 seconds
279
+ Schedule.tapOutput(([, attempt]) =>
280
+ session.note(`Waiting for VPC deletion... (${(attempt + 1) * 2}s)`),
281
+ ),
282
+ ),
283
+ },
284
+ );
285
+ });
@@ -0,0 +1,152 @@
1
+ import type * as EC2 from "itty-aws/ec2";
2
+ import { Resource } from "../../resource.ts";
3
+ import type { AccountID } from "../account.ts";
4
+ import type { RegionID } from "../region.ts";
5
+
6
+ export const Vpc = Resource<{
7
+ <const ID extends string, const Props extends VpcProps>(
8
+ id: ID,
9
+ props: Props,
10
+ ): Vpc<ID, Props>;
11
+ }>("AWS.EC2.VPC");
12
+
13
+ export interface Vpc<
14
+ ID extends string = string,
15
+ Props extends VpcProps = VpcProps,
16
+ > extends Resource<"AWS.EC2.VPC", ID, Props, VpcAttrs<Props>> {}
17
+
18
+ export interface VpcProps {
19
+ /**
20
+ * The IPv4 network range for the VPC, in CIDR notation.
21
+ * Required unless using IPAM.
22
+ * @example "10.0.0.0/16"
23
+ */
24
+ cidrBlock?: string;
25
+
26
+ /**
27
+ * The ID of an IPv4 IPAM pool you want to use for allocating this VPC's CIDR.
28
+ */
29
+ ipv4IpamPoolId?: string;
30
+
31
+ /**
32
+ * The netmask length of the IPv4 CIDR you want to allocate to this VPC from an IPAM pool.
33
+ */
34
+ ipv4NetmaskLength?: number;
35
+
36
+ /**
37
+ * The ID of an IPv6 IPAM pool which will be used to allocate this VPC an IPv6 CIDR.
38
+ */
39
+ ipv6IpamPoolId?: string;
40
+
41
+ /**
42
+ * The netmask length of the IPv6 CIDR you want to allocate to this VPC from an IPAM pool.
43
+ */
44
+ ipv6NetmaskLength?: number;
45
+
46
+ /**
47
+ * Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC.
48
+ */
49
+ ipv6CidrBlock?: string;
50
+
51
+ /**
52
+ * The ID of an IPv6 address pool from which to allocate the IPv6 CIDR block.
53
+ */
54
+ ipv6Pool?: string;
55
+
56
+ /**
57
+ * The Availability Zone or Local Zone Group name for the IPv6 CIDR block.
58
+ */
59
+ ipv6CidrBlockNetworkBorderGroup?: string;
60
+
61
+ /**
62
+ * The tenancy options for instances launched into the VPC.
63
+ * @default "default"
64
+ */
65
+ instanceTenancy?: EC2.Tenancy;
66
+
67
+ /**
68
+ * Whether DNS resolution is supported for the VPC.
69
+ * @default true
70
+ */
71
+ enableDnsSupport?: boolean;
72
+
73
+ /**
74
+ * Whether instances launched in the VPC get DNS hostnames.
75
+ * @default true
76
+ */
77
+ enableDnsHostnames?: boolean;
78
+
79
+ /**
80
+ * Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC.
81
+ */
82
+ amazonProvidedIpv6CidrBlock?: boolean;
83
+
84
+ /**
85
+ * Tags to assign to the VPC.
86
+ * These will be merged with alchemy auto-tags (alchemy::app, alchemy::stage, alchemy::id).
87
+ */
88
+ tags?: Record<string, string>;
89
+ }
90
+
91
+ export interface VpcAttrs<Props extends VpcProps> {
92
+ /**
93
+ * The ID of the VPC.
94
+ */
95
+ vpcId: string;
96
+
97
+ /**
98
+ * The Amazon Resource Name (ARN) of the VPC.
99
+ */
100
+ vpcArn: `arn:aws:ec2:${RegionID}:${AccountID}:vpc/${this["vpcId"]}`;
101
+
102
+ /**
103
+ * The primary IPv4 CIDR block for the VPC.
104
+ */
105
+ cidrBlock: string;
106
+
107
+ /**
108
+ * The ID of the set of DHCP options associated with the VPC.
109
+ */
110
+ dhcpOptionsId: string;
111
+
112
+ /**
113
+ * The current state of the VPC.
114
+ */
115
+ state: EC2.VpcState;
116
+
117
+ /**
118
+ * Whether the VPC is the default VPC.
119
+ */
120
+ isDefault: boolean;
121
+
122
+ /**
123
+ * The ID of the AWS account that owns the VPC.
124
+ */
125
+ ownerId?: string;
126
+
127
+ /**
128
+ * Information about the IPv4 CIDR blocks associated with the VPC.
129
+ */
130
+ cidrBlockAssociationSet?: Array<{
131
+ associationId: string;
132
+ cidrBlock: string;
133
+ cidrBlockState: {
134
+ state: EC2.VpcCidrBlockStateCode;
135
+ statusMessage?: string;
136
+ };
137
+ }>;
138
+
139
+ /**
140
+ * Information about the IPv6 CIDR blocks associated with the VPC.
141
+ */
142
+ ipv6CidrBlockAssociationSet?: Array<{
143
+ associationId: string;
144
+ ipv6CidrBlock: string;
145
+ ipv6CidrBlockState: {
146
+ state: EC2.VpcCidrBlockStateCode;
147
+ statusMessage?: string;
148
+ };
149
+ networkBorderGroup?: string;
150
+ ipv6Pool?: string;
151
+ }>;
152
+ }
package/src/aws/iam.ts ADDED
@@ -0,0 +1,30 @@
1
+ import * as Context from "effect/Context";
2
+ import { IAM } from "itty-aws/iam";
3
+ import { createAWSServiceClientLayer } from "./client.ts";
4
+
5
+ export class IAMClient extends Context.Tag("AWS::IAM::Client")<
6
+ IAMClient,
7
+ IAM
8
+ >() {}
9
+
10
+ export const client = createAWSServiceClientLayer<typeof IAMClient, IAM>(
11
+ IAMClient,
12
+ IAM,
13
+ );
14
+
15
+ export interface PolicyDocument {
16
+ Version: "2012-10-17";
17
+ Statement: PolicyStatement[];
18
+ }
19
+
20
+ export interface PolicyStatement {
21
+ Effect: "Allow" | "Deny";
22
+ Sid?: string;
23
+ Action: string[];
24
+ Resource: string | string[];
25
+ Condition?: Record<string, Record<string, string | string[]>>;
26
+ Principal?: Record<string, string | string[]>;
27
+ NotPrincipal?: Record<string, string | string[]>;
28
+ NotAction?: string[];
29
+ NotResource?: string[];
30
+ }
@@ -0,0 +1,54 @@
1
+ import * as Layer from "effect/Layer";
2
+ import * as ESBuild from "../esbuild.ts";
3
+ import * as Account from "./account.ts";
4
+ import * as Credentials from "./credentials.ts";
5
+ import * as DynamoDB from "./dynamodb/index.ts";
6
+ import * as EC2 from "./ec2/index.ts";
7
+ import * as IAM from "./iam.ts";
8
+ import * as Lambda from "./lambda/index.ts";
9
+ import * as Region from "./region.ts";
10
+ import * as S3 from "./s3.ts";
11
+ import * as SQS from "./sqs/index.ts";
12
+ import * as STS from "./sts.ts";
13
+ // TODO(sam): should this be named?
14
+ export * from "./profile.ts";
15
+
16
+ export const providers = Layer.mergeAll(
17
+ Layer.provide(
18
+ Layer.provideMerge(Lambda.functionProvider(), ESBuild.layer()),
19
+ Lambda.client(),
20
+ ),
21
+ Layer.provide(SQS.queueProvider(), SQS.client()),
22
+ Layer.provide(DynamoDB.tableProvider(), DynamoDB.client()),
23
+ Layer.provide(EC2.vpcProvider(), EC2.client()),
24
+ );
25
+
26
+ export const bindings = Layer.mergeAll(
27
+ //
28
+ SQS.sendMessageFromLambdaFunction(),
29
+ SQS.queueEventSourceProvider(),
30
+ DynamoDB.getItemFromLambdaFunction(),
31
+ );
32
+
33
+ export const clients = Layer.mergeAll(
34
+ STS.client(),
35
+ IAM.client(),
36
+ S3.client(),
37
+ SQS.client(),
38
+ Lambda.client(),
39
+ DynamoDB.client(),
40
+ EC2.client(),
41
+ );
42
+
43
+ export const defaultProviders = providers.pipe(
44
+ Layer.provideMerge(bindings),
45
+ Layer.provideMerge(Account.fromIdentity()),
46
+ Layer.provideMerge(clients),
47
+ );
48
+
49
+ export const live = defaultProviders.pipe(
50
+ Layer.provide(Region.fromEnv()),
51
+ Layer.provide(Credentials.fromSSO()),
52
+ );
53
+
54
+ export default live;
@@ -0,0 +1,14 @@
1
+ import * as Context from "effect/Context";
2
+
3
+ import { Lambda } from "itty-aws/lambda";
4
+ import { createAWSServiceClientLayer } from "../client.ts";
5
+
6
+ export class LambdaClient extends Context.Tag("AWS.Lambda.Client")<
7
+ LambdaClient,
8
+ Lambda
9
+ >() {}
10
+
11
+ export const client = createAWSServiceClientLayer<typeof LambdaClient, Lambda>(
12
+ LambdaClient,
13
+ Lambda,
14
+ );
@@ -0,0 +1,63 @@
1
+ import type { From } from "alchemy-effect";
2
+ import { declare } from "alchemy-effect";
3
+ import type {
4
+ Context as LambdaContext,
5
+ SQSBatchResponse,
6
+ SQSEvent,
7
+ } from "aws-lambda";
8
+ import * as Effect from "effect/Effect";
9
+ import * as S from "effect/Schema";
10
+ import * as SQS from "../sqs/index.ts";
11
+ import * as Lambda from "./function.ts";
12
+
13
+ export const consume =
14
+ <Q extends SQS.Queue, ID extends string, Req>(
15
+ id: ID,
16
+ {
17
+ queue,
18
+ handle,
19
+ }: {
20
+ queue: Q;
21
+ handle: (
22
+ event: SQS.QueueEvent<Q["props"]["schema"]["Type"]>,
23
+ context: LambdaContext,
24
+ ) => Effect.Effect<SQSBatchResponse | void, never, Req>;
25
+ },
26
+ ) =>
27
+ <const Props extends Lambda.FunctionProps<Req>>({
28
+ bindings,
29
+ ...props
30
+ }: Props) =>
31
+ Lambda.Function(id, {
32
+ handle: Effect.fn(function* (event: SQSEvent, context: LambdaContext) {
33
+ yield* declare<SQS.Consume<From<Q>>>();
34
+ const records = yield* Effect.all(
35
+ event.Records.map(
36
+ Effect.fn(function* (record) {
37
+ return {
38
+ ...record,
39
+ body: yield* S.validate(queue.props.schema)(record.body).pipe(
40
+ Effect.catchAll(() => Effect.void),
41
+ ),
42
+ };
43
+ }),
44
+ ),
45
+ );
46
+ const response = yield* handle(
47
+ {
48
+ Records: records.filter((record) => record.body !== undefined),
49
+ },
50
+ context,
51
+ );
52
+ return {
53
+ batchItemFailures: [
54
+ ...(response?.batchItemFailures ?? []),
55
+ ...records
56
+ .filter((record) => record.body === undefined)
57
+ .map((failed) => ({
58
+ itemIdentifier: failed.messageId,
59
+ })),
60
+ ],
61
+ } satisfies SQSBatchResponse;
62
+ }),
63
+ })({ ...props, bindings: bindings.and(SQS.QueueEventSource(queue)) });
@@ -0,0 +1,30 @@
1
+ import type { Capability } from "alchemy-effect";
2
+ import type { Context as LambdaContext } from "aws-lambda";
3
+ import * as Effect from "effect/Effect";
4
+
5
+ type Handler = (
6
+ event: any,
7
+ context: LambdaContext,
8
+ ) => Effect.Effect<any, any, never>;
9
+
10
+ type HandlerEffect<Req = Capability> = Effect.Effect<Handler, any, Req>;
11
+
12
+ const memo = Symbol.for("alchemy::memo");
13
+
14
+ // TODO(sam): is there a better way to lazily evaluate the Effect and cache the result?
15
+ const resolveHandler = async (
16
+ effect: HandlerEffect & {
17
+ [memo]?: Handler;
18
+ },
19
+ ) =>
20
+ (effect[memo] ??= await Effect.runPromise(
21
+ // safe to cast away the Capability requirements since they are phantoms
22
+ effect as HandlerEffect<never>,
23
+ ));
24
+
25
+ export const toHandler =
26
+ <H extends Handler>(effect: Effect.Effect<H, any, Capability>) =>
27
+ async (event: any, context: LambdaContext) =>
28
+ Effect.runPromise(
29
+ (await resolveHandler(effect))(event, context),
30
+ ) as Promise<Effect.Effect.Success<ReturnType<H>>>;
@@ -0,0 +1,40 @@
1
+ import * as Effect from "effect/Effect";
2
+
3
+ import { $, Binding, type Capability, declare, toEnvKey } from "alchemy-effect";
4
+ import { LambdaClient } from "./client.ts";
5
+ import { Function } from "./function.ts";
6
+
7
+ export interface InvokeFunction<Resource = unknown>
8
+ extends Capability<"AWS.Lambda.InvokeFunction", Resource> {}
9
+
10
+ export const InvokeFunction = Binding<
11
+ <F extends Function>(func: F) => Binding<Function, InvokeFunction<$<F>>>
12
+ >(Function, "AWS.Lambda.InvokeFunction");
13
+
14
+ export const invoke = <F extends Function>(func: F, input: any) =>
15
+ Effect.gen(function* () {
16
+ const lambda = yield* LambdaClient;
17
+ const functionArn = process.env[`${func.id}-functionArn`]!;
18
+ yield* declare<InvokeFunction<F>>();
19
+ return yield* lambda.invoke({
20
+ FunctionName: functionArn,
21
+ InvocationType: "RequestResponse",
22
+ Payload: JSON.stringify(input),
23
+ });
24
+ });
25
+
26
+ export const invokeFunctionFromLambda = InvokeFunction.provider.succeed({
27
+ attach: ({ source: func }) => ({
28
+ env: {
29
+ [toEnvKey(func.id, "FUNCTION_ARN")]: func.attr.functionArn,
30
+ },
31
+ policyStatements: [
32
+ {
33
+ Sid: "AWS.Lambda.InvokeFunction",
34
+ Effect: "Allow",
35
+ Action: ["lambda:InvokeFunction"],
36
+ Resource: [func.attr.functionArn],
37
+ },
38
+ ],
39
+ }),
40
+ });