alchemy-effect 0.2.0 → 0.4.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/bin/alchemy-effect.js +55354 -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 +4 -17
  9. package/lib/app.d.ts.map +1 -1
  10. package/lib/app.js +0 -20
  11. package/lib/app.js.map +1 -1
  12. package/lib/apply.d.ts +15 -75
  13. package/lib/apply.d.ts.map +1 -1
  14. package/lib/apply.js +439 -154
  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 +10 -1
  21. package/lib/aws/account.d.ts.map +1 -1
  22. package/lib/aws/account.js +18 -3
  23. package/lib/aws/account.js.map +1 -1
  24. package/lib/aws/client.d.ts.map +1 -1
  25. package/lib/aws/client.js +0 -1
  26. package/lib/aws/client.js.map +1 -1
  27. package/lib/aws/config.d.ts +15 -0
  28. package/lib/aws/config.d.ts.map +1 -0
  29. package/lib/aws/config.js +1 -0
  30. package/lib/aws/config.js.map +1 -0
  31. package/lib/aws/credentials.d.ts +10 -0
  32. package/lib/aws/credentials.d.ts.map +1 -1
  33. package/lib/aws/credentials.js +73 -47
  34. package/lib/aws/credentials.js.map +1 -1
  35. package/lib/aws/dynamodb/client.d.ts +1 -1
  36. package/lib/aws/dynamodb/client.d.ts.map +1 -1
  37. package/lib/aws/dynamodb/index.d.ts +2 -1
  38. package/lib/aws/dynamodb/index.d.ts.map +1 -1
  39. package/lib/aws/dynamodb/index.js +1 -2
  40. package/lib/aws/dynamodb/index.js.map +1 -1
  41. package/lib/aws/dynamodb/secondary-index.d.ts +5 -4
  42. package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -1
  43. package/lib/aws/dynamodb/table.d.ts +23 -20
  44. package/lib/aws/dynamodb/table.d.ts.map +1 -1
  45. package/lib/aws/dynamodb/table.get-item.d.ts +8 -6
  46. package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -1
  47. package/lib/aws/dynamodb/table.get-item.js +4 -2
  48. package/lib/aws/dynamodb/table.get-item.js.map +1 -1
  49. package/lib/aws/dynamodb/table.js.map +1 -1
  50. package/lib/aws/dynamodb/table.provider.d.ts +3 -4
  51. package/lib/aws/dynamodb/table.provider.d.ts.map +1 -1
  52. package/lib/aws/dynamodb/table.provider.js +18 -29
  53. package/lib/aws/dynamodb/table.provider.js.map +1 -1
  54. package/lib/aws/ec2/client.d.ts +1 -1
  55. package/lib/aws/ec2/client.d.ts.map +1 -1
  56. package/lib/aws/ec2/index.d.ts +11 -0
  57. package/lib/aws/ec2/index.d.ts.map +1 -1
  58. package/lib/aws/ec2/index.js +11 -0
  59. package/lib/aws/ec2/index.js.map +1 -1
  60. package/lib/aws/ec2/internet-gateway.d.ts +65 -0
  61. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -0
  62. package/lib/aws/ec2/internet-gateway.js +4 -0
  63. package/lib/aws/ec2/internet-gateway.js.map +1 -0
  64. package/lib/aws/ec2/internet-gateway.provider.d.ts +6 -0
  65. package/lib/aws/ec2/internet-gateway.provider.d.ts.map +1 -0
  66. package/lib/aws/ec2/internet-gateway.provider.js +193 -0
  67. package/lib/aws/ec2/internet-gateway.provider.js.map +1 -0
  68. package/lib/aws/ec2/route-table-association.d.ts +63 -0
  69. package/lib/aws/ec2/route-table-association.d.ts.map +1 -0
  70. package/lib/aws/ec2/route-table-association.js +4 -0
  71. package/lib/aws/ec2/route-table-association.js.map +1 -0
  72. package/lib/aws/ec2/route-table-association.provider.d.ts +4 -0
  73. package/lib/aws/ec2/route-table-association.provider.d.ts.map +1 -0
  74. package/lib/aws/ec2/route-table-association.provider.js +121 -0
  75. package/lib/aws/ec2/route-table-association.provider.js.map +1 -0
  76. package/lib/aws/ec2/route-table.d.ts +159 -0
  77. package/lib/aws/ec2/route-table.d.ts.map +1 -0
  78. package/lib/aws/ec2/route-table.js +4 -0
  79. package/lib/aws/ec2/route-table.js.map +1 -0
  80. package/lib/aws/ec2/route-table.provider.d.ts +6 -0
  81. package/lib/aws/ec2/route-table.provider.d.ts.map +1 -0
  82. package/lib/aws/ec2/route-table.provider.js +213 -0
  83. package/lib/aws/ec2/route-table.provider.js.map +1 -0
  84. package/lib/aws/ec2/route.d.ts +155 -0
  85. package/lib/aws/ec2/route.d.ts.map +1 -0
  86. package/lib/aws/ec2/route.js +3 -0
  87. package/lib/aws/ec2/route.js.map +1 -0
  88. package/lib/aws/ec2/route.provider.d.ts +4 -0
  89. package/lib/aws/ec2/route.provider.d.ts.map +1 -0
  90. package/lib/aws/ec2/route.provider.js +166 -0
  91. package/lib/aws/ec2/route.provider.js.map +1 -0
  92. package/lib/aws/ec2/subnet.d.ts +175 -0
  93. package/lib/aws/ec2/subnet.d.ts.map +1 -0
  94. package/lib/aws/ec2/subnet.js +4 -0
  95. package/lib/aws/ec2/subnet.js.map +1 -0
  96. package/lib/aws/ec2/subnet.provider.d.ts +4 -0
  97. package/lib/aws/ec2/subnet.provider.d.ts.map +1 -0
  98. package/lib/aws/ec2/subnet.provider.js +250 -0
  99. package/lib/aws/ec2/subnet.provider.js.map +1 -0
  100. package/lib/aws/ec2/vpc.d.ts +13 -8
  101. package/lib/aws/ec2/vpc.d.ts.map +1 -1
  102. package/lib/aws/ec2/vpc.js +1 -0
  103. package/lib/aws/ec2/vpc.js.map +1 -1
  104. package/lib/aws/ec2/vpc.provider.d.ts +1 -2
  105. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
  106. package/lib/aws/ec2/vpc.provider.js +45 -37
  107. package/lib/aws/ec2/vpc.provider.js.map +1 -1
  108. package/lib/aws/index.d.ts +15 -19
  109. package/lib/aws/index.d.ts.map +1 -1
  110. package/lib/aws/index.js +8 -10
  111. package/lib/aws/index.js.map +1 -1
  112. package/lib/aws/lambda/consume.d.ts +10 -11
  113. package/lib/aws/lambda/consume.d.ts.map +1 -1
  114. package/lib/aws/lambda/consume.js +3 -3
  115. package/lib/aws/lambda/consume.js.map +1 -1
  116. package/lib/aws/lambda/function.d.ts +7 -7
  117. package/lib/aws/lambda/function.d.ts.map +1 -1
  118. package/lib/aws/lambda/function.handler.d.ts +1 -1
  119. package/lib/aws/lambda/function.handler.d.ts.map +1 -1
  120. package/lib/aws/lambda/function.handler.js.map +1 -1
  121. package/lib/aws/lambda/function.invoke.d.ts +6 -4
  122. package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
  123. package/lib/aws/lambda/function.invoke.js +3 -1
  124. package/lib/aws/lambda/function.invoke.js.map +1 -1
  125. package/lib/aws/lambda/function.js +1 -1
  126. package/lib/aws/lambda/function.js.map +1 -1
  127. package/lib/aws/lambda/function.provider.d.ts +3 -2
  128. package/lib/aws/lambda/function.provider.d.ts.map +1 -1
  129. package/lib/aws/lambda/function.provider.js +28 -25
  130. package/lib/aws/lambda/function.provider.js.map +1 -1
  131. package/lib/aws/lambda/index.d.ts +1 -0
  132. package/lib/aws/lambda/index.d.ts.map +1 -1
  133. package/lib/aws/lambda/index.js +1 -0
  134. package/lib/aws/lambda/index.js.map +1 -1
  135. package/lib/aws/lambda/serve.d.ts +2 -4
  136. package/lib/aws/lambda/serve.d.ts.map +1 -1
  137. package/lib/aws/profile.d.ts +2 -2
  138. package/lib/aws/profile.d.ts.map +1 -1
  139. package/lib/aws/profile.js +1 -1
  140. package/lib/aws/profile.js.map +1 -1
  141. package/lib/aws/region.d.ts +14 -2
  142. package/lib/aws/region.d.ts.map +1 -1
  143. package/lib/aws/region.js +26 -1
  144. package/lib/aws/region.js.map +1 -1
  145. package/lib/aws/sqs/client.d.ts +1 -1
  146. package/lib/aws/sqs/client.d.ts.map +1 -1
  147. package/lib/aws/sqs/index.d.ts +1 -0
  148. package/lib/aws/sqs/index.d.ts.map +1 -1
  149. package/lib/aws/sqs/index.js +1 -0
  150. package/lib/aws/sqs/index.js.map +1 -1
  151. package/lib/aws/sqs/queue.consume.d.ts +1 -1
  152. package/lib/aws/sqs/queue.consume.d.ts.map +1 -1
  153. package/lib/aws/sqs/queue.consume.js +0 -1
  154. package/lib/aws/sqs/queue.consume.js.map +1 -1
  155. package/lib/aws/sqs/queue.d.ts +6 -4
  156. package/lib/aws/sqs/queue.d.ts.map +1 -1
  157. package/lib/aws/sqs/queue.event-source.d.ts +8 -6
  158. package/lib/aws/sqs/queue.event-source.d.ts.map +1 -1
  159. package/lib/aws/sqs/queue.event-source.js +26 -44
  160. package/lib/aws/sqs/queue.event-source.js.map +1 -1
  161. package/lib/aws/sqs/queue.js +1 -1
  162. package/lib/aws/sqs/queue.js.map +1 -1
  163. package/lib/aws/sqs/queue.provider.d.ts +2 -2
  164. package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
  165. package/lib/aws/sqs/queue.provider.js +2 -1
  166. package/lib/aws/sqs/queue.provider.js.map +1 -1
  167. package/lib/aws/sqs/queue.send-message.d.ts +7 -5
  168. package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
  169. package/lib/aws/sqs/queue.send-message.js +4 -2
  170. package/lib/aws/sqs/queue.send-message.js.map +1 -1
  171. package/lib/binding.d.ts +12 -12
  172. package/lib/binding.d.ts.map +1 -1
  173. package/lib/binding.js.map +1 -1
  174. package/lib/cli/components/ApprovePlan.d.ts +2 -2
  175. package/lib/cli/components/ApprovePlan.d.ts.map +1 -1
  176. package/lib/cli/components/ApprovePlan.js.map +1 -1
  177. package/lib/cli/components/Plan.d.ts +2 -2
  178. package/lib/cli/components/Plan.d.ts.map +1 -1
  179. package/lib/cli/components/Plan.js.map +1 -1
  180. package/lib/cli/components/PlanProgress.d.ts +8 -4
  181. package/lib/cli/components/PlanProgress.d.ts.map +1 -1
  182. package/lib/cli/components/PlanProgress.js +11 -1
  183. package/lib/cli/components/PlanProgress.js.map +1 -1
  184. package/lib/cli/index.d.ts +384 -264
  185. package/lib/cli/index.d.ts.map +1 -1
  186. package/lib/cli/index.js +57 -65
  187. package/lib/cli/index.js.map +1 -1
  188. package/lib/cli/ink-service.d.ts +4 -0
  189. package/lib/cli/ink-service.d.ts.map +1 -0
  190. package/lib/cli/ink-service.js +43 -0
  191. package/lib/cli/ink-service.js.map +1 -0
  192. package/lib/cli/service.d.ts +21 -0
  193. package/lib/cli/service.d.ts.map +1 -0
  194. package/lib/cli/service.js +5 -0
  195. package/lib/cli/service.js.map +1 -0
  196. package/lib/cloudflare/account.d.ts +10 -0
  197. package/lib/cloudflare/account.d.ts.map +1 -0
  198. package/lib/cloudflare/account.js +24 -0
  199. package/lib/cloudflare/account.js.map +1 -0
  200. package/lib/cloudflare/api.d.ts +7 -7
  201. package/lib/cloudflare/api.d.ts.map +1 -1
  202. package/lib/cloudflare/api.js +18 -17
  203. package/lib/cloudflare/api.js.map +1 -1
  204. package/lib/cloudflare/config.d.ts +9 -0
  205. package/lib/cloudflare/config.d.ts.map +1 -0
  206. package/lib/cloudflare/config.js +1 -0
  207. package/lib/cloudflare/config.js.map +1 -0
  208. package/lib/cloudflare/index.d.ts +3 -1
  209. package/lib/cloudflare/index.d.ts.map +1 -1
  210. package/lib/cloudflare/index.js +3 -0
  211. package/lib/cloudflare/index.js.map +1 -1
  212. package/lib/cloudflare/kv/namespace.binding.d.ts +5 -3
  213. package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -1
  214. package/lib/cloudflare/kv/namespace.binding.js +1 -1
  215. package/lib/cloudflare/kv/namespace.binding.js.map +1 -1
  216. package/lib/cloudflare/kv/namespace.client.d.ts +1 -1
  217. package/lib/cloudflare/kv/namespace.d.ts +3 -2
  218. package/lib/cloudflare/kv/namespace.d.ts.map +1 -1
  219. package/lib/cloudflare/kv/namespace.js.map +1 -1
  220. package/lib/cloudflare/kv/namespace.provider.d.ts +3 -2
  221. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
  222. package/lib/cloudflare/kv/namespace.provider.js +9 -7
  223. package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
  224. package/lib/cloudflare/live.d.ts +5 -5
  225. package/lib/cloudflare/live.d.ts.map +1 -1
  226. package/lib/cloudflare/live.js +5 -8
  227. package/lib/cloudflare/live.js.map +1 -1
  228. package/lib/cloudflare/r2/bucket.binding.d.ts +5 -3
  229. package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -1
  230. package/lib/cloudflare/r2/bucket.binding.js +1 -1
  231. package/lib/cloudflare/r2/bucket.binding.js.map +1 -1
  232. package/lib/cloudflare/r2/bucket.d.ts +3 -2
  233. package/lib/cloudflare/r2/bucket.d.ts.map +1 -1
  234. package/lib/cloudflare/r2/bucket.js.map +1 -1
  235. package/lib/cloudflare/r2/bucket.provider.d.ts +3 -2
  236. package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -1
  237. package/lib/cloudflare/r2/bucket.provider.js +14 -8
  238. package/lib/cloudflare/r2/bucket.provider.js.map +1 -1
  239. package/lib/cloudflare/worker/assets.fetch.d.ts +3 -2
  240. package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -1
  241. package/lib/cloudflare/worker/assets.fetch.js +2 -1
  242. package/lib/cloudflare/worker/assets.fetch.js.map +1 -1
  243. package/lib/cloudflare/worker/assets.provider.d.ts +1 -1
  244. package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -1
  245. package/lib/cloudflare/worker/index.d.ts +0 -1
  246. package/lib/cloudflare/worker/index.d.ts.map +1 -1
  247. package/lib/cloudflare/worker/worker.d.ts +5 -6
  248. package/lib/cloudflare/worker/worker.d.ts.map +1 -1
  249. package/lib/cloudflare/worker/worker.handler.d.ts +1 -1
  250. package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -1
  251. package/lib/cloudflare/worker/worker.handler.js.map +1 -1
  252. package/lib/cloudflare/worker/worker.js.map +1 -1
  253. package/lib/cloudflare/worker/worker.provider.d.ts +3 -2
  254. package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -1
  255. package/lib/cloudflare/worker/worker.provider.js +12 -7
  256. package/lib/cloudflare/worker/worker.provider.js.map +1 -1
  257. package/lib/cloudflare/worker/worker.serve.d.ts +7 -7
  258. package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -1
  259. package/lib/cloudflare/worker/worker.serve.js.map +1 -1
  260. package/lib/data.d.ts +3 -0
  261. package/lib/data.d.ts.map +1 -0
  262. package/lib/data.js +8 -0
  263. package/lib/data.js.map +1 -0
  264. package/lib/destroy.d.ts +1 -1
  265. package/lib/destroy.d.ts.map +1 -1
  266. package/lib/destroy.js +1 -4
  267. package/lib/destroy.js.map +1 -1
  268. package/lib/diff.d.ts +18 -0
  269. package/lib/diff.d.ts.map +1 -0
  270. package/lib/diff.js +22 -0
  271. package/lib/diff.js.map +1 -0
  272. package/lib/env.d.ts +5 -0
  273. package/lib/env.d.ts.map +1 -1
  274. package/lib/env.js +15 -29
  275. package/lib/env.js.map +1 -1
  276. package/lib/event.d.ts +1 -1
  277. package/lib/event.d.ts.map +1 -1
  278. package/lib/exports.d.ts +9 -0
  279. package/lib/exports.d.ts.map +1 -0
  280. package/lib/exports.js +13 -0
  281. package/lib/exports.js.map +1 -0
  282. package/lib/index.d.ts +10 -2
  283. package/lib/index.d.ts.map +1 -1
  284. package/lib/index.js +10 -5
  285. package/lib/index.js.map +1 -1
  286. package/lib/input.d.ts +32 -0
  287. package/lib/input.d.ts.map +1 -0
  288. package/lib/input.js +1 -0
  289. package/lib/input.js.map +1 -0
  290. package/lib/instance-id.d.ts +8 -0
  291. package/lib/instance-id.d.ts.map +1 -0
  292. package/lib/instance-id.js +12 -0
  293. package/lib/instance-id.js.map +1 -0
  294. package/lib/output.d.ts +145 -0
  295. package/lib/output.d.ts.map +1 -0
  296. package/lib/output.js +283 -0
  297. package/lib/output.js.map +1 -0
  298. package/lib/physical-name.d.ts +14 -1
  299. package/lib/physical-name.d.ts.map +1 -1
  300. package/lib/physical-name.js +41 -2
  301. package/lib/physical-name.js.map +1 -1
  302. package/lib/plan.d.ts +84 -58
  303. package/lib/plan.d.ts.map +1 -1
  304. package/lib/plan.js +504 -166
  305. package/lib/plan.js.map +1 -1
  306. package/lib/policy.d.ts +3 -4
  307. package/lib/policy.d.ts.map +1 -1
  308. package/lib/policy.js +0 -1
  309. package/lib/policy.js.map +1 -1
  310. package/lib/provider.d.ts +39 -24
  311. package/lib/provider.d.ts.map +1 -1
  312. package/lib/provider.js +9 -0
  313. package/lib/provider.js.map +1 -1
  314. package/lib/ref.d.ts +14 -0
  315. package/lib/ref.d.ts.map +1 -0
  316. package/lib/ref.js +21 -0
  317. package/lib/ref.js.map +1 -0
  318. package/lib/resource.d.ts +13 -8
  319. package/lib/resource.d.ts.map +1 -1
  320. package/lib/resource.js.map +1 -1
  321. package/lib/runtime.d.ts +7 -6
  322. package/lib/runtime.d.ts.map +1 -1
  323. package/lib/runtime.js.map +1 -1
  324. package/lib/service.d.ts +9 -6
  325. package/lib/service.d.ts.map +1 -1
  326. package/lib/service.js.map +1 -1
  327. package/lib/stack.d.ts +60 -0
  328. package/lib/stack.d.ts.map +1 -0
  329. package/lib/stack.js +11 -0
  330. package/lib/stack.js.map +1 -0
  331. package/lib/stage.d.ts +39 -0
  332. package/lib/stage.d.ts.map +1 -0
  333. package/lib/stage.js +32 -0
  334. package/lib/stage.js.map +1 -0
  335. package/lib/state.d.ts +135 -17
  336. package/lib/state.d.ts.map +1 -1
  337. package/lib/state.js +34 -30
  338. package/lib/state.js.map +1 -1
  339. package/lib/tags.d.ts +15 -0
  340. package/lib/tags.d.ts.map +1 -1
  341. package/lib/tags.js +27 -0
  342. package/lib/tags.js.map +1 -1
  343. package/lib/test.d.ts +25 -4
  344. package/lib/test.d.ts.map +1 -1
  345. package/lib/test.js +54 -14
  346. package/lib/test.js.map +1 -1
  347. package/lib/todo.d.ts +3 -0
  348. package/lib/todo.d.ts.map +1 -0
  349. package/lib/todo.js +3 -0
  350. package/lib/todo.js.map +1 -0
  351. package/lib/tsconfig.test.tsbuildinfo +1 -1
  352. package/lib/type.d.ts +3 -0
  353. package/lib/type.d.ts.map +1 -1
  354. package/lib/unknown.d.ts +4 -0
  355. package/lib/unknown.d.ts.map +1 -0
  356. package/lib/unknown.js +4 -0
  357. package/lib/unknown.js.map +1 -0
  358. package/lib/user.d.ts +3 -0
  359. package/lib/user.d.ts.map +1 -0
  360. package/lib/user.js +3 -0
  361. package/lib/user.js.map +1 -0
  362. package/lib/util.d.ts +6 -0
  363. package/lib/util.d.ts.map +1 -0
  364. package/lib/util.js +9 -0
  365. package/lib/util.js.map +1 -0
  366. package/package.json +18 -12
  367. package/src/$.ts +17 -0
  368. package/src/app.ts +3 -32
  369. package/src/apply.ts +824 -452
  370. package/src/assert-never.ts +18 -0
  371. package/src/aws/account.ts +23 -3
  372. package/src/aws/client.ts +0 -1
  373. package/src/aws/config.ts +16 -0
  374. package/src/aws/credentials.ts +212 -177
  375. package/src/aws/dynamodb/index.ts +3 -3
  376. package/src/aws/dynamodb/table.get-item.ts +5 -9
  377. package/src/aws/dynamodb/table.provider.ts +36 -39
  378. package/src/aws/dynamodb/table.ts +29 -84
  379. package/src/aws/ec2/index.ts +12 -0
  380. package/src/aws/ec2/internet-gateway.provider.ts +316 -0
  381. package/src/aws/ec2/internet-gateway.ts +79 -0
  382. package/src/aws/ec2/route-table-association.provider.ts +214 -0
  383. package/src/aws/ec2/route-table-association.ts +82 -0
  384. package/src/aws/ec2/route-table.provider.ts +306 -0
  385. package/src/aws/ec2/route-table.ts +175 -0
  386. package/src/aws/ec2/route.provider.ts +213 -0
  387. package/src/aws/ec2/route.ts +192 -0
  388. package/src/aws/ec2/subnet.provider.ts +358 -0
  389. package/src/aws/ec2/subnet.ts +213 -0
  390. package/src/aws/ec2/vpc.provider.ts +58 -50
  391. package/src/aws/ec2/vpc.ts +21 -8
  392. package/src/aws/index.ts +49 -40
  393. package/src/aws/lambda/consume.ts +8 -7
  394. package/src/aws/lambda/function.handler.ts +1 -1
  395. package/src/aws/lambda/function.invoke.ts +6 -2
  396. package/src/aws/lambda/function.provider.ts +41 -32
  397. package/src/aws/lambda/function.ts +7 -4
  398. package/src/aws/lambda/index.ts +2 -0
  399. package/src/aws/profile.ts +1 -4
  400. package/src/aws/region.ts +42 -3
  401. package/src/aws/sqs/index.ts +2 -0
  402. package/src/aws/sqs/queue.consume.ts +1 -1
  403. package/src/aws/sqs/queue.event-source.ts +29 -55
  404. package/src/aws/sqs/queue.provider.ts +10 -2
  405. package/src/aws/sqs/queue.send-message.ts +5 -8
  406. package/src/aws/sqs/queue.ts +9 -4
  407. package/src/binding.ts +19 -19
  408. package/src/cli/components/ApprovePlan.tsx +2 -2
  409. package/src/cli/components/Plan.tsx +3 -2
  410. package/src/cli/components/PlanProgress.tsx +32 -14
  411. package/src/cli/index.ts +2 -6
  412. package/src/cli/ink-service.tsx +61 -0
  413. package/src/cli/service.ts +23 -0
  414. package/src/cloudflare/account.ts +37 -0
  415. package/src/cloudflare/api.ts +33 -29
  416. package/src/cloudflare/config.ts +7 -0
  417. package/src/cloudflare/index.ts +3 -1
  418. package/src/cloudflare/kv/namespace.binding.ts +3 -1
  419. package/src/cloudflare/kv/namespace.provider.ts +10 -8
  420. package/src/cloudflare/kv/namespace.ts +3 -2
  421. package/src/cloudflare/live.ts +11 -17
  422. package/src/cloudflare/r2/bucket.binding.ts +3 -1
  423. package/src/cloudflare/r2/bucket.provider.ts +16 -9
  424. package/src/cloudflare/r2/bucket.ts +8 -2
  425. package/src/cloudflare/worker/assets.fetch.ts +3 -1
  426. package/src/cloudflare/worker/assets.provider.ts +1 -1
  427. package/src/cloudflare/worker/index.ts +0 -2
  428. package/src/cloudflare/worker/worker.handler.ts +1 -1
  429. package/src/cloudflare/worker/worker.provider.ts +21 -14
  430. package/src/cloudflare/worker/worker.serve.ts +5 -2
  431. package/src/cloudflare/worker/worker.ts +4 -3
  432. package/src/data.ts +18 -0
  433. package/src/destroy.ts +1 -5
  434. package/src/diff.ts +48 -0
  435. package/src/env.ts +20 -32
  436. package/src/event.ts +6 -0
  437. package/src/exports.ts +21 -0
  438. package/src/index.ts +10 -5
  439. package/src/input.ts +81 -0
  440. package/src/instance-id.ts +16 -0
  441. package/src/output.ts +542 -0
  442. package/src/physical-name.ts +57 -2
  443. package/src/plan.ts +757 -278
  444. package/src/policy.ts +3 -5
  445. package/src/provider.ts +70 -31
  446. package/src/ref.ts +48 -0
  447. package/src/resource.ts +70 -10
  448. package/src/runtime.ts +15 -8
  449. package/src/service.ts +11 -7
  450. package/src/stack.ts +116 -0
  451. package/src/stage.ts +85 -0
  452. package/src/state.ts +269 -76
  453. package/src/tags.ts +31 -0
  454. package/src/test.ts +118 -17
  455. package/src/todo.ts +4 -0
  456. package/src/type.ts +4 -0
  457. package/src/unknown.ts +6 -0
  458. package/src/user.ts +4 -0
  459. package/src/util.ts +21 -0
  460. package/lib/approve.d.ts +0 -15
  461. package/lib/approve.d.ts.map +0 -1
  462. package/lib/approve.js +0 -7
  463. package/lib/approve.js.map +0 -1
  464. package/lib/cli/approve.d.ts +0 -4
  465. package/lib/cli/approve.d.ts.map +0 -1
  466. package/lib/cli/approve.js +0 -18
  467. package/lib/cli/approve.js.map +0 -1
  468. package/lib/cli/clack.d.ts +0 -14
  469. package/lib/cli/clack.d.ts.map +0 -1
  470. package/lib/cli/clack.js +0 -12
  471. package/lib/cli/clack.js.map +0 -1
  472. package/lib/cli/main.d.ts +0 -2
  473. package/lib/cli/main.d.ts.map +0 -1
  474. package/lib/cli/main.js +0 -1
  475. package/lib/cli/main.js.map +0 -1
  476. package/lib/cli/plan.d.ts +0 -13
  477. package/lib/cli/plan.d.ts.map +0 -1
  478. package/lib/cli/plan.js +0 -1
  479. package/lib/cli/plan.js.map +0 -1
  480. package/lib/cli/progress.d.ts +0 -7
  481. package/lib/cli/progress.d.ts.map +0 -1
  482. package/lib/cli/progress.js +0 -30
  483. package/lib/cli/progress.js.map +0 -1
  484. package/lib/cli/spinner.d.ts +0 -2
  485. package/lib/cli/spinner.d.ts.map +0 -1
  486. package/lib/cli/spinner.js +0 -13
  487. package/lib/cli/spinner.js.map +0 -1
  488. package/src/approve.ts +0 -13
  489. package/src/cli/approve.tsx +0 -30
  490. package/src/cli/clack.ts +0 -22
  491. package/src/cli/main.ts +0 -0
  492. package/src/cli/plan.ts +0 -16
  493. package/src/cli/progress.tsx +0 -46
  494. package/src/cli/spinner.ts +0 -14
@@ -1,18 +1,18 @@
1
- import * as Data from "effect/Data";
2
1
  import * as Effect from "effect/Effect";
3
2
  import * as Layer from "effect/Layer";
4
3
  import * as Schedule from "effect/Schedule";
5
4
 
6
- import { App, type Provider, type ProviderService } from "alchemy-effect";
7
5
  import type { TimeToLiveSpecification } from "itty-aws/dynamodb";
6
+ import { App } from "../../app.ts";
7
+ import type { Input } from "../../input.ts";
8
+ import type { Provider, ProviderService } from "../../provider.ts";
8
9
  import { createTagger, hasTags } from "../../tags.ts";
9
- import { Account } from "../account.ts";
10
- import { Region } from "../region.ts";
11
10
  import { isScalarAttributeType, toAttributeType } from "./attribute-value.ts";
12
11
  import { DynamoDBClient } from "./client.ts";
13
12
  import {
14
13
  Table,
15
14
  type AnyTable,
15
+ type AttributesSchema,
16
16
  type TableAttrs,
17
17
  type TableProps,
18
18
  } from "./table.ts";
@@ -20,23 +20,22 @@ import {
20
20
  // we add an explict type to simplify the Layer type errors because the Table interface has a lot of type args
21
21
  export const tableProvider = (): Layer.Layer<
22
22
  Provider<AnyTable>,
23
- any,
24
- App | DynamoDBClient | Region | Account
23
+ never,
24
+ App | DynamoDBClient
25
25
  > =>
26
26
  Table.provider.effect(
27
- // @ts-expect-error
28
27
  Effect.gen(function* () {
29
28
  const dynamodb = yield* DynamoDBClient;
30
29
  const app = yield* App;
31
- const region = yield* Region;
32
- const accountId = yield* Account;
33
30
 
34
- const createTableName = (id: string, props: TableProps) =>
35
- props.tableName ?? `${app.name}-${id}-${app.stage}`;
31
+ const createTableName = (
32
+ id: string,
33
+ props: Input.ResolveProps<TableProps>,
34
+ ) => props.tableName ?? `${app.name}-${id}-${app.stage}`;
36
35
 
37
36
  const tagged = yield* createTagger();
38
37
 
39
- const toKeySchema = (props: TableProps) => [
38
+ const toKeySchema = (props: Input.ResolveProps<TableProps>) => [
40
39
  {
41
40
  AttributeName: props.partitionKey as string,
42
41
  KeyType: "HASH" as const,
@@ -51,8 +50,10 @@ export const tableProvider = (): Layer.Layer<
51
50
  : []),
52
51
  ];
53
52
 
54
- const toAttributeDefinitions = (props: TableProps) =>
55
- Object.entries(props.attributes)
53
+ const toAttributeDefinitions = (
54
+ attributes: AttributesSchema<any, any, any>,
55
+ ) =>
56
+ Object.entries(attributes)
56
57
  .flatMap(([name, schema]) => {
57
58
  const type = toAttributeType(schema);
58
59
  if (isScalarAttributeType(type)) {
@@ -69,9 +70,11 @@ export const tableProvider = (): Layer.Layer<
69
70
  })
70
71
  .sort((a, b) => a.AttributeName.localeCompare(b.AttributeName));
71
72
 
72
- const toAttributeDefinitionsMap = (props: TableProps) =>
73
+ const toAttributeDefinitionsMap = (
74
+ attributes: AttributesSchema<any, any, any>,
75
+ ) =>
73
76
  Object.fromEntries(
74
- toAttributeDefinitions(props).map(
77
+ toAttributeDefinitions(attributes).map(
75
78
  (def) => [def.AttributeName, def.AttributeType] as const,
76
79
  ),
77
80
  );
@@ -83,6 +86,7 @@ export const tableProvider = (): Layer.Layer<
83
86
  Effect.flatMap((r) =>
84
87
  dynamodb
85
88
  .listTagsOfResource({
89
+ // oxlint-disable-next-line no-non-null-asserted-optional-chain
86
90
  ResourceArn: r.Table?.TableArn!,
87
91
  })
88
92
  .pipe(
@@ -116,34 +120,27 @@ export const tableProvider = (): Layer.Layer<
116
120
  );
117
121
 
118
122
  return {
119
- diff: Effect.fn(function* ({ id, news, olds }) {
120
- const oldTableName = createTableName(id, olds);
121
- const newTableName = createTableName(id, news);
122
- if (oldTableName !== newTableName) {
123
- // TODO(sam): if the name is hard-coded, REPLACE is impossible - we need a suffix
124
- return { action: "replace" } as const;
125
- }
126
-
123
+ stables: ["tableName", "tableId", "tableArn"],
124
+ diff: Effect.fn(function* ({ news, olds }) {
127
125
  if (
126
+ // TODO(sam): if the name is hard-coded, REPLACE is impossible - we need a suffix
127
+ news.tableName !== olds.tableName ||
128
128
  olds.partitionKey !== news.partitionKey ||
129
129
  olds.sortKey !== news.sortKey
130
130
  ) {
131
131
  return { action: "replace" } as const;
132
132
  }
133
- const oldAttributeDefinitions = toAttributeDefinitionsMap(olds);
134
- const newAttributeDefinitions = toAttributeDefinitionsMap(news);
135
- for (const [name, type] of Object.entries(oldAttributeDefinitions)) {
133
+ const oldAttrs = toAttributeDefinitionsMap(olds.attributes);
134
+ const newAttrs = toAttributeDefinitionsMap(news.attributes);
135
+ for (const [name, type] of Object.entries(oldAttrs)) {
136
136
  // CloudFormation requires that editing an existing AttributeDefinition is a replace
137
- if (newAttributeDefinitions[name] !== type) {
137
+ if (newAttrs[name] !== type) {
138
138
  return { action: "replace" } as const;
139
139
  }
140
140
  }
141
-
142
141
  // TODO(sam):
143
142
  // Replacements:
144
143
  // 1. if you change ImportSourceSpecification
145
-
146
- return { action: "noop" } as const;
147
144
  }),
148
145
 
149
146
  create: Effect.fn(function* ({ id, news, session }) {
@@ -154,7 +151,7 @@ export const tableProvider = (): Layer.Layer<
154
151
  TableName: tableName,
155
152
  TableClass: news.tableClass,
156
153
  KeySchema: toKeySchema(news),
157
- AttributeDefinitions: toAttributeDefinitions(news),
154
+ AttributeDefinitions: toAttributeDefinitions(news.attributes),
158
155
  BillingMode: news.billingMode ?? "PAY_PER_REQUEST",
159
156
  SSESpecification: news.sseSpecification,
160
157
  WarmThroughput: news.warmThroughput,
@@ -194,17 +191,19 @@ export const tableProvider = (): Layer.Layer<
194
191
  return {
195
192
  tableName,
196
193
  tableId: response.TableId!,
197
- tableArn: response.TableArn! as TableAttrs<TableProps>["tableArn"],
194
+ tableArn: response.TableArn! as TableAttrs<
195
+ Input.Resolve<TableProps>
196
+ >["tableArn"],
198
197
  partitionKey: news.partitionKey,
199
198
  sortKey: news.sortKey,
200
- } satisfies TableAttrs<TableProps> as TableAttrs<any>;
199
+ } satisfies TableAttrs<Input.Resolve<TableProps>> as TableAttrs<any>;
201
200
  }),
202
201
 
203
202
  update: Effect.fn(function* ({ output, news, olds }) {
204
203
  yield* dynamodb.updateTable({
205
204
  TableName: output.tableName,
206
205
  TableClass: news.tableClass,
207
- AttributeDefinitions: toAttributeDefinitions(news),
206
+ AttributeDefinitions: toAttributeDefinitions(news.attributes),
208
207
  BillingMode: news.billingMode ?? "PAY_PER_REQUEST",
209
208
  SSESpecification: news.sseSpecification,
210
209
  WarmThroughput: news.warmThroughput,
@@ -255,12 +254,10 @@ export const tableProvider = (): Layer.Layer<
255
254
  e._tag === "ResourceInUseException" ||
256
255
  e._tag === "InternalServerError" ||
257
256
  e._tag === "TimeoutException",
258
- schedule: Schedule.fixed(100),
257
+ schedule: Schedule.exponential(100),
259
258
  }),
260
259
  );
261
260
 
262
- class TableStillExists extends Data.TaggedError("TableStillExists") {}
263
-
264
261
  while (true) {
265
262
  const table = yield* dynamodb
266
263
  .describeTable({
@@ -275,6 +272,6 @@ export const tableProvider = (): Layer.Layer<
275
272
  }
276
273
  }
277
274
  }),
278
- } satisfies ProviderService<Table<string, TableProps>>;
275
+ } satisfies ProviderService<Table<string, TableProps<unknown>>>;
279
276
  }),
280
277
  );
@@ -1,13 +1,13 @@
1
1
  import * as S from "effect/Schema";
2
+ import type { Input } from "../../input.ts";
2
3
  import { Resource } from "../../resource.ts";
3
4
  import type { type } from "../../type.ts";
4
5
  import type { AccountID } from "../account.ts";
5
6
  import type { RegionID } from "../region.ts";
6
-
7
7
  import type * as DynamoDB from "itty-aws/dynamodb";
8
8
 
9
9
  export interface TableProps<
10
- Items = any,
10
+ Items extends any = any,
11
11
  Attributes extends AttributesSchema<
12
12
  Items,
13
13
  PartitionKey,
@@ -15,42 +15,23 @@ export interface TableProps<
15
15
  > = AttributesSchema<Items, keyof Items, keyof Items | undefined>,
16
16
  PartitionKey extends keyof Items = keyof Items,
17
17
  SortKey extends keyof Items | undefined = keyof Items | undefined,
18
- BillingMode extends DynamoDB.BillingMode = DynamoDB.BillingMode,
19
- SSESpecification extends DynamoDB.SSESpecification | undefined =
20
- | DynamoDB.SSESpecification
21
- | undefined,
22
- TimeToLiveSpecification extends
23
- | DynamoDB.TimeToLiveSpecification
24
- | undefined = DynamoDB.TimeToLiveSpecification | undefined,
25
- WarmThroughput extends DynamoDB.WarmThroughput | undefined =
26
- | DynamoDB.WarmThroughput
27
- | undefined,
28
- OnDemandThroughput extends DynamoDB.OnDemandThroughput | undefined =
29
- | DynamoDB.OnDemandThroughput
30
- | undefined,
31
- ProvisionedThroughput extends DynamoDB.ProvisionedThroughput | undefined =
32
- | DynamoDB.ProvisionedThroughput
33
- | undefined,
34
- TableClass extends DynamoDB.TableClass | undefined =
35
- | DynamoDB.TableClass
36
- | undefined,
37
18
  > {
38
19
  items: type<Items>;
39
- tableName?: string;
40
20
  attributes: Attributes;
41
21
  partitionKey: PartitionKey;
42
22
  sortKey?: SortKey;
43
- billingMode?: BillingMode;
23
+ tableName?: string | undefined;
24
+ billingMode?: DynamoDB.BillingMode;
44
25
  deletionProtectionEnabled?: boolean;
45
- onDemandThroughput?: OnDemandThroughput;
46
- provisionedThroughput?: ProvisionedThroughput;
47
- sseSpecification?: SSESpecification;
48
- timeToLiveSpecification?: TimeToLiveSpecification;
49
- warmThroughput?: WarmThroughput;
50
- tableClass?: TableClass;
26
+ onDemandThroughput?: DynamoDB.OnDemandThroughput;
27
+ provisionedThroughput?: DynamoDB.ProvisionedThroughput;
28
+ sseSpecification?: DynamoDB.SSESpecification;
29
+ timeToLiveSpecification?: DynamoDB.TimeToLiveSpecification;
30
+ warmThroughput?: DynamoDB.WarmThroughput;
31
+ tableClass?: DynamoDB.TableClass;
51
32
  }
52
33
 
53
- export interface TableAttrs<Props extends TableProps> {
34
+ export interface TableAttrs<Props extends Input.Resolve<TableProps>> {
54
35
  tableName: Props["tableName"] extends string ? Props["tableName"] : string;
55
36
  tableId: string;
56
37
  tableArn: `arn:aws:dynamodb:${RegionID}:${AccountID}:table/${this["tableName"]}`;
@@ -86,71 +67,35 @@ export const Table = Resource<{
86
67
  >,
87
68
  const PartitionKey extends keyof Items,
88
69
  const SortKey extends keyof Items | undefined = undefined,
89
- const BillingMode extends DynamoDB.BillingMode = "PAY_PER_REQUEST",
90
- const SSESpecification extends
91
- | DynamoDB.SSESpecification
92
- | undefined = undefined,
93
- const TimeToLiveSpecification extends
94
- | DynamoDB.TimeToLiveSpecification
95
- | undefined = undefined,
96
- const WarmThroughput extends
97
- | DynamoDB.WarmThroughput
98
- | undefined = undefined,
99
- const OnDemandThroughput extends
100
- | DynamoDB.OnDemandThroughput
101
- | undefined = undefined,
102
- const ProvisionedThroughput extends
103
- | DynamoDB.ProvisionedThroughput
104
- | undefined = undefined,
105
- const TableClass extends DynamoDB.TableClass | undefined = undefined,
106
70
  >(
107
71
  id: ID,
108
- props: TableProps<
109
- Items,
110
- Attributes,
111
- PartitionKey,
112
- SortKey,
113
- BillingMode,
114
- SSESpecification,
115
- TimeToLiveSpecification,
116
- WarmThroughput,
117
- OnDemandThroughput,
118
- ProvisionedThroughput,
119
- TableClass
120
- >,
121
- ): Table<
122
- ID,
123
- TableProps<
124
- Items,
125
- Attributes,
126
- PartitionKey,
127
- SortKey,
128
- BillingMode,
129
- SSESpecification,
130
- TimeToLiveSpecification,
131
- WarmThroughput,
132
- OnDemandThroughput,
133
- ProvisionedThroughput,
134
- TableClass
135
- >
136
- >;
72
+ props: TableProps<Items, Attributes, PartitionKey, SortKey>,
73
+ ): Table<ID, TableProps<Items, Attributes, PartitionKey, SortKey>>;
137
74
  }>("AWS.DynamoDB.Table");
138
75
 
139
76
  export interface AnyTable extends Table<string, any> {}
140
77
 
141
78
  export interface Table<
142
79
  ID extends string = string,
143
- Props extends TableProps = TableProps,
144
- > extends Resource<"AWS.DynamoDB.Table", ID, Props, TableAttrs<Props>> {}
80
+ Props extends TableProps<any, any, any, any> = TableProps<any, any, any, any>,
81
+ > extends Resource<
82
+ "AWS.DynamoDB.Table",
83
+ ID,
84
+ Props,
85
+ TableAttrs<Input.Resolve<Props>>,
86
+ Table
87
+ > {}
145
88
 
146
89
  export declare namespace Table {
147
90
  export type PartitionKey<T extends Table> = T["props"]["partitionKey"];
148
91
  export type SortKey<T extends Table> = T["props"]["sortKey"];
92
+ export type Items<T extends Table> = T["props"]["items"];
149
93
  export type Key<T extends Table> = {
150
- [K in PartitionKey<T>]: T["props"]["attributes"][K];
151
- } & SortKey<T> extends infer S extends string
152
- ? {
153
- [K in S]: T["props"]["attributes"][K];
154
- }
155
- : {};
94
+ [K in PartitionKey<T>]: InstanceType<T["props"]["items"]>[K];
95
+ } & {
96
+ [K in Exclude<SortKey<T>, undefined>]: Exclude<
97
+ InstanceType<T["props"]["items"]>[K],
98
+ undefined
99
+ >;
100
+ };
156
101
  }
@@ -1,3 +1,15 @@
1
1
  export * from "./client.ts";
2
+ export * from "./internet-gateway.provider.ts";
3
+ export * from "./internet-gateway.ts";
4
+ export * from "./route-table-association.provider.ts";
5
+ export * from "./route-table-association.ts";
6
+ export * from "./route-table.provider.ts";
7
+ export * from "./route-table.ts";
8
+ export * from "./route.provider.ts";
9
+ export * from "./route.ts";
10
+ export * from "./subnet.provider.ts";
11
+ export * from "./subnet.ts";
2
12
  export * from "./vpc.provider.ts";
3
13
  export * from "./vpc.ts";
14
+
15
+ import "../config.ts";
@@ -0,0 +1,316 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Schedule from "effect/Schedule";
3
+
4
+ import type { EC2 } from "itty-aws/ec2";
5
+
6
+ import type { ScopedPlanStatusSession } from "../../cli/service.ts";
7
+ import type { ProviderService } from "../../provider.ts";
8
+ import { createTagger, createTagsList } from "../../tags.ts";
9
+ import { Account } from "../account.ts";
10
+ import { Region } from "../region.ts";
11
+ import { EC2Client } from "./client.ts";
12
+ import {
13
+ InternetGateway,
14
+ type InternetGatewayAttrs,
15
+ type InternetGatewayId,
16
+ type InternetGatewayProps,
17
+ } from "./internet-gateway.ts";
18
+
19
+ export const internetGatewayProvider = () =>
20
+ InternetGateway.provider.effect(
21
+ Effect.gen(function* () {
22
+ const ec2 = yield* EC2Client;
23
+ const region = yield* Region;
24
+ const accountId = yield* Account;
25
+ const tagged = yield* createTagger();
26
+
27
+ return {
28
+ stables: ["internetGatewayId", "internetGatewayArn", "ownerId"],
29
+ diff: Effect.fn(function* ({ news, olds }) {
30
+ // VPC attachment change can be handled via attach/detach (update)
31
+ // No properties require replacement
32
+ }),
33
+
34
+ create: Effect.fn(function* ({ id, news, session }) {
35
+ // 1. Prepare tags
36
+ const alchemyTags = tagged(id);
37
+ const userTags = news.tags ?? {};
38
+ const allTags = { ...alchemyTags, ...userTags };
39
+
40
+ // 2. Call CreateInternetGateway
41
+ const createResult = yield* ec2.createInternetGateway({
42
+ TagSpecifications: [
43
+ {
44
+ ResourceType: "internet-gateway",
45
+ Tags: createTagsList(allTags),
46
+ },
47
+ ],
48
+ DryRun: false,
49
+ });
50
+
51
+ const internetGatewayId = createResult.InternetGateway!
52
+ .InternetGatewayId! as InternetGatewayId;
53
+ yield* session.note(`Internet gateway created: ${internetGatewayId}`);
54
+
55
+ // 3. Attach to VPC if specified
56
+ if (news.vpcId) {
57
+ yield* ec2
58
+ .attachInternetGateway({
59
+ InternetGatewayId: internetGatewayId,
60
+ VpcId: news.vpcId,
61
+ })
62
+ .pipe(
63
+ Effect.retry({
64
+ // Retry if VPC is not yet available
65
+ while: (e) => e._tag === "InvalidVpcID.NotFound",
66
+ schedule: Schedule.exponential(100),
67
+ }),
68
+ );
69
+ yield* session.note(`Attached to VPC: ${news.vpcId}`);
70
+ }
71
+
72
+ // 4. Describe to get full details
73
+ const igw = yield* describeInternetGateway(
74
+ ec2,
75
+ internetGatewayId,
76
+ session,
77
+ );
78
+
79
+ // 5. Return attributes
80
+ return {
81
+ internetGatewayId,
82
+ internetGatewayArn:
83
+ `arn:aws:ec2:${region}:${accountId}:internet-gateway/${internetGatewayId}` as InternetGatewayAttrs<InternetGatewayProps>["internetGatewayArn"],
84
+ vpcId: news.vpcId,
85
+ ownerId: igw.OwnerId,
86
+ attachments: igw.Attachments?.map((a) => ({
87
+ state: a.State! as
88
+ | "attaching"
89
+ | "available"
90
+ | "detaching"
91
+ | "detached",
92
+ vpcId: a.VpcId!,
93
+ })),
94
+ } satisfies InternetGatewayAttrs<InternetGatewayProps>;
95
+ }),
96
+
97
+ update: Effect.fn(function* ({ news, olds, output, session }) {
98
+ const internetGatewayId = output.internetGatewayId;
99
+
100
+ // Handle VPC attachment changes
101
+ if (news.vpcId !== olds.vpcId) {
102
+ // Detach from old VPC if was attached
103
+ if (olds.vpcId) {
104
+ yield* ec2
105
+ .detachInternetGateway({
106
+ InternetGatewayId: internetGatewayId,
107
+ VpcId: olds.vpcId,
108
+ })
109
+ .pipe(
110
+ Effect.catchTag("Gateway.NotAttached", () => Effect.void),
111
+ );
112
+ yield* session.note(`Detached from VPC: ${olds.vpcId}`);
113
+ }
114
+
115
+ // Attach to new VPC if specified
116
+ if (news.vpcId) {
117
+ yield* ec2
118
+ .attachInternetGateway({
119
+ InternetGatewayId: internetGatewayId,
120
+ VpcId: news.vpcId,
121
+ })
122
+ .pipe(
123
+ Effect.retry({
124
+ while: (e) => e._tag === "InvalidVpcID.NotFound",
125
+ schedule: Schedule.exponential(100),
126
+ }),
127
+ );
128
+ yield* session.note(`Attached to VPC: ${news.vpcId}`);
129
+ }
130
+ }
131
+
132
+ // Handle tag updates
133
+ if (
134
+ JSON.stringify(news.tags ?? {}) !== JSON.stringify(olds.tags ?? {})
135
+ ) {
136
+ const alchemyTags = tagged(output.internetGatewayId);
137
+ const userTags = news.tags ?? {};
138
+ const allTags = { ...alchemyTags, ...userTags };
139
+
140
+ // Delete old tags that are no longer present
141
+ const oldTagKeys = Object.keys(olds.tags ?? {});
142
+ const newTagKeys = Object.keys(news.tags ?? {});
143
+ const tagsToDelete = oldTagKeys.filter(
144
+ (key) => !newTagKeys.includes(key),
145
+ );
146
+
147
+ if (tagsToDelete.length > 0) {
148
+ yield* ec2.deleteTags({
149
+ Resources: [internetGatewayId],
150
+ Tags: tagsToDelete.map((key) => ({ Key: key })),
151
+ });
152
+ }
153
+
154
+ // Create/update tags
155
+ yield* ec2.createTags({
156
+ Resources: [internetGatewayId],
157
+ Tags: createTagsList(allTags),
158
+ });
159
+
160
+ yield* session.note("Updated tags");
161
+ }
162
+
163
+ // Re-describe to get current state
164
+ const igw = yield* describeInternetGateway(
165
+ ec2,
166
+ internetGatewayId,
167
+ session,
168
+ );
169
+
170
+ return {
171
+ ...output,
172
+ vpcId: news.vpcId,
173
+ attachments: igw.Attachments?.map((a) => ({
174
+ state: a.State! as
175
+ | "attaching"
176
+ | "available"
177
+ | "detaching"
178
+ | "detached",
179
+ vpcId: a.VpcId!,
180
+ })),
181
+ };
182
+ }),
183
+
184
+ delete: Effect.fn(function* ({ output, session }) {
185
+ const internetGatewayId = output.internetGatewayId;
186
+
187
+ yield* session.note(
188
+ `Deleting internet gateway: ${internetGatewayId}`,
189
+ );
190
+
191
+ // 1. Detach from all VPCs first
192
+ if (output.attachments && output.attachments.length > 0) {
193
+ for (const attachment of output.attachments) {
194
+ yield* ec2
195
+ .detachInternetGateway({
196
+ InternetGatewayId: internetGatewayId,
197
+ VpcId: attachment.vpcId,
198
+ })
199
+ .pipe(
200
+ Effect.tapError(Effect.logDebug),
201
+ Effect.catchTag("Gateway.NotAttached", () => Effect.void),
202
+ Effect.catchTag(
203
+ "InvalidInternetGatewayID.NotFound",
204
+ () => Effect.void,
205
+ ),
206
+ );
207
+ yield* session.note(`Detached from VPC: ${attachment.vpcId}`);
208
+ }
209
+ }
210
+
211
+ // 2. Delete the internet gateway
212
+ yield* ec2
213
+ .deleteInternetGateway({
214
+ InternetGatewayId: internetGatewayId,
215
+ DryRun: false,
216
+ })
217
+ .pipe(
218
+ Effect.tapError(Effect.logDebug),
219
+ Effect.catchTag(
220
+ "InvalidInternetGatewayID.NotFound",
221
+ () => Effect.void,
222
+ ),
223
+ // Retry on dependency violations
224
+ Effect.retry({
225
+ while: (e) => {
226
+ return (
227
+ e._tag === "DependencyViolation" ||
228
+ (e._tag === "ValidationError" &&
229
+ e.message?.includes("DependencyViolation"))
230
+ );
231
+ },
232
+ schedule: Schedule.exponential(1000, 1.5).pipe(
233
+ Schedule.intersect(Schedule.recurs(10)),
234
+ Schedule.tapOutput(([, attempt]) =>
235
+ session.note(
236
+ `Waiting for dependencies to clear... (attempt ${attempt + 1})`,
237
+ ),
238
+ ),
239
+ ),
240
+ }),
241
+ );
242
+
243
+ // 3. Wait for internet gateway to be fully deleted
244
+ yield* waitForInternetGatewayDeleted(ec2, internetGatewayId, session);
245
+
246
+ yield* session.note(
247
+ `Internet gateway ${internetGatewayId} deleted successfully`,
248
+ );
249
+ }),
250
+ } satisfies ProviderService<InternetGateway>;
251
+ }),
252
+ );
253
+
254
+ /**
255
+ * Describe an internet gateway by ID
256
+ */
257
+ const describeInternetGateway = (
258
+ ec2: EC2,
259
+ internetGatewayId: string,
260
+ _session?: ScopedPlanStatusSession,
261
+ ) =>
262
+ Effect.gen(function* () {
263
+ const result = yield* ec2
264
+ .describeInternetGateways({ InternetGatewayIds: [internetGatewayId] })
265
+ .pipe(
266
+ Effect.catchTag("InvalidInternetGatewayID.NotFound", () =>
267
+ Effect.succeed({ InternetGateways: [] }),
268
+ ),
269
+ );
270
+
271
+ const igw = result.InternetGateways?.[0];
272
+ if (!igw) {
273
+ return yield* Effect.fail(new Error("Internet gateway not found"));
274
+ }
275
+ return igw;
276
+ });
277
+
278
+ /**
279
+ * Wait for internet gateway to be deleted
280
+ */
281
+ const waitForInternetGatewayDeleted = (
282
+ ec2: EC2,
283
+ internetGatewayId: string,
284
+ session: ScopedPlanStatusSession,
285
+ ) =>
286
+ Effect.gen(function* () {
287
+ yield* Effect.retry(
288
+ Effect.gen(function* () {
289
+ const result = yield* ec2
290
+ .describeInternetGateways({ InternetGatewayIds: [internetGatewayId] })
291
+ .pipe(
292
+ Effect.tapError(Effect.logDebug),
293
+ Effect.catchTag("InvalidInternetGatewayID.NotFound", () =>
294
+ Effect.succeed({ InternetGateways: [] }),
295
+ ),
296
+ );
297
+
298
+ if (!result.InternetGateways || result.InternetGateways.length === 0) {
299
+ return; // Successfully deleted
300
+ }
301
+
302
+ // Still exists, fail to trigger retry
303
+ return yield* Effect.fail(new Error("Internet gateway still exists"));
304
+ }),
305
+ {
306
+ schedule: Schedule.fixed(2000).pipe(
307
+ Schedule.intersect(Schedule.recurs(15)),
308
+ Schedule.tapOutput(([, attempt]) =>
309
+ session.note(
310
+ `Waiting for internet gateway deletion... (${(attempt + 1) * 2}s)`,
311
+ ),
312
+ ),
313
+ ),
314
+ },
315
+ );
316
+ });