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
package/src/plan.ts CHANGED
@@ -1,13 +1,22 @@
1
+ import * as Context from "effect/Context";
2
+ import { App } from "./app.ts";
1
3
  import * as Data from "effect/Data";
2
4
  import * as Effect from "effect/Effect";
3
- import type { AnyBinding } from "./binding.ts";
5
+ import { omit } from "effect/Struct";
6
+ import type {
7
+ AnyBinding,
8
+ BindingDiffProps,
9
+ BindingService,
10
+ } from "./binding.ts";
4
11
  import type { Capability } from "./capability.ts";
5
- import type { Phase } from "./phase.ts";
12
+ import type { Diff } from "./diff.ts";
13
+ import * as Output from "./output.ts";
6
14
  import type { Instance } from "./policy.ts";
15
+ import type { Provider } from "./provider.ts";
7
16
  import { type ProviderService } from "./provider.ts";
8
- import type { Resource, ResourceTags } from "./resource.ts";
9
- import { isService, type Service } from "./service.ts";
10
- import { State, type ResourceState } from "./state.ts";
17
+ import type { AnyResource, Resource, ResourceTags } from "./resource.ts";
18
+ import { isService, type IService, type Service } from "./service.ts";
19
+ import { State, StateStoreError, type ResourceState } from "./state.ts";
11
20
 
12
21
  export type PlanError = never;
13
22
 
@@ -26,23 +35,34 @@ export const isBindNode = (node: any): node is BindNode => {
26
35
  */
27
36
  export type BindNode<B extends AnyBinding = AnyBinding> =
28
37
  | Attach<B>
38
+ | Reattach<B>
29
39
  | Detach<B>
30
40
  | NoopBind<B>;
31
41
 
32
42
  export type Attach<B extends AnyBinding = AnyBinding> = {
33
43
  action: "attach";
34
44
  binding: B;
35
- olds?: BindNode;
45
+ olds: BindNode | undefined;
46
+ attr: B["attr"] | undefined;
47
+ };
48
+
49
+ export type Reattach<B extends AnyBinding = AnyBinding> = {
50
+ action: "reattach";
51
+ binding: B;
52
+ olds: BindNode;
53
+ attr: B["attr"];
36
54
  };
37
55
 
38
56
  export type Detach<B extends AnyBinding = AnyBinding> = {
39
57
  action: "detach";
40
58
  binding: B;
59
+ attr: B["attr"] | undefined;
41
60
  };
42
61
 
43
62
  export type NoopBind<B extends AnyBinding = AnyBinding> = {
44
63
  action: "noop";
45
64
  binding: B;
65
+ attr: B["attr"];
46
66
  };
47
67
 
48
68
  export const isCRUD = (node: any): node is CRUD => {
@@ -59,14 +79,14 @@ export const isCRUD = (node: any): node is CRUD => {
59
79
  /**
60
80
  * A node in the plan that represents a resource CRUD operation.
61
81
  */
62
- export type CRUD<R extends Resource = Resource> =
82
+ export type CRUD<R extends Resource = AnyResource> =
63
83
  | Create<R>
64
84
  | Update<R>
65
85
  | Delete<R>
66
86
  | Replace<R>
67
87
  | NoopUpdate<R>;
68
88
 
69
- export type Apply<R extends Resource = Resource> =
89
+ export type Apply<R extends Resource = AnyResource> =
70
90
  | Create<R>
71
91
  | Update<R>
72
92
  | Replace<R>
@@ -82,104 +102,170 @@ const Node = <T extends Apply>(node: T) => ({
82
102
  },
83
103
  });
84
104
 
85
- export type Create<R extends Resource> = {
105
+ export type Create<R extends Resource = AnyResource> = {
86
106
  action: "create";
87
107
  resource: R;
88
108
  news: any;
89
- provider: ProviderService;
109
+ provider: ProviderService<R>;
90
110
  attributes: R["attr"];
91
111
  bindings: BindNode[];
92
112
  };
93
113
 
94
- export type Update<R extends Resource> = {
114
+ export type Update<R extends Resource = AnyResource> = {
95
115
  action: "update";
96
116
  resource: R;
97
117
  olds: any;
98
118
  news: any;
99
119
  output: any;
100
- provider: ProviderService;
120
+ provider: ProviderService<R>;
101
121
  attributes: R["attr"];
102
122
  bindings: BindNode[];
103
123
  };
104
124
 
105
- export type Delete<R extends Resource> = {
125
+ export type Delete<R extends Resource = AnyResource> = {
106
126
  action: "delete";
107
127
  resource: R;
108
128
  olds: any;
109
129
  output: any;
110
- provider: ProviderService;
130
+ provider: ProviderService<R>;
111
131
  bindings: BindNode[];
112
132
  attributes: R["attr"];
113
133
  downstream: string[];
114
134
  };
115
135
 
116
- export type NoopUpdate<R extends Resource> = {
136
+ export type NoopUpdate<R extends Resource = AnyResource> = {
117
137
  action: "noop";
118
138
  resource: R;
119
139
  attributes: R["attr"];
120
140
  bindings: BindNode[];
121
141
  };
122
142
 
123
- export type Replace<R extends Resource> = {
143
+ export type Replace<R extends Resource = AnyResource> = {
124
144
  action: "replace";
125
145
  resource: R;
126
146
  olds: any;
127
147
  news: any;
128
148
  output: any;
129
- provider: ProviderService;
149
+ provider: ProviderService<R>;
130
150
  bindings: BindNode[];
131
151
  attributes: R["attr"];
132
152
  deleteFirst?: boolean;
133
153
  };
134
154
 
135
- export type Plan = {
136
- phase: Phase;
155
+ export type ResourceGraph<Resources extends Service | Resource> = ToGraph<
156
+ TraverseResources<Resources>
157
+ >;
158
+
159
+ export type TraverseResources<Resources extends Service | Resource> =
160
+ | Resources
161
+ | BoundResources<Resources>
162
+ | TransitiveResources<Resources>;
163
+
164
+ type ToGraph<Resources extends Service | Resource> = {
165
+ [ID in Resources["id"]]: Apply<Extract<Resources, { id: ID }>>;
166
+ };
167
+
168
+ export type BoundResources<Resources extends Service | Resource> = NeverUnknown<
169
+ Extract<
170
+ Resources,
171
+ IService
172
+ >["props"]["bindings"]["capabilities"][number]["resource"]
173
+ >;
174
+
175
+ // finds transitive dependencies at most two levels deep
176
+ // TODO(sam): figure out an efficient way to do arbitrary depth
177
+ export type TransitiveResources<
178
+ Resources extends Service | Resource,
179
+ Found extends Service | Resource = never,
180
+ > = Extract<
181
+ | Found
182
+ | {
183
+ [prop in keyof Resources["props"]]: IsAny<
184
+ Resources["props"][prop]
185
+ > extends true
186
+ ? Found
187
+ : Resources["props"][prop] extends { kind: "alchemy/Policy" }
188
+ ? Found
189
+ : Resources["props"][prop] extends Output.Output<any, infer Src, any>
190
+ ? Src extends Found
191
+ ? Found
192
+ : TransitiveResources<Src, Src | Found>
193
+ : {
194
+ [p in keyof Resources["props"][prop]]: IsAny<
195
+ Resources["props"][prop][p]
196
+ > extends true
197
+ ? Found
198
+ : Resources["props"][prop][p] extends Output.Output<
199
+ any,
200
+ infer Src,
201
+ any
202
+ >
203
+ ? Src extends Found
204
+ ? Found
205
+ : TransitiveResources<Src, Src | Found>
206
+ : Found;
207
+ }[keyof Resources["props"][prop]];
208
+ }[keyof Resources["props"]],
209
+ Service | Resource
210
+ >;
211
+
212
+ export type Providers<Resources extends Service | Resource> =
213
+ | ResourceProviders<Resources>
214
+ | BindingTags<Resources>;
215
+
216
+ export type ResourceProviders<Res extends Service | Resource> = Res extends any
217
+ ? Provider<Extract<Res["base"], Service | Resource>>
218
+ : never;
219
+
220
+ export type BindingTags<Resources extends Service | Resource> = NeverUnknown<
221
+ Extract<Resources, Service>["props"]["bindings"]["tags"][number]
222
+ >;
223
+
224
+ type NeverUnknown<T> = unknown extends T ? never : T;
225
+
226
+ type IsAny<T> = 0 extends 1 & T ? true : false;
227
+
228
+ export type DerivePlan<Resources extends Service | Resource> = {
137
229
  resources: {
138
- [id in string]: CRUD;
230
+ [ID in keyof ResourceGraph<Resources>]: ResourceGraph<Resources>[ID];
139
231
  };
140
232
  deletions: {
141
- [id in string]?: Delete<Resource>;
233
+ [ID in string]: Delete<AnyResource>;
142
234
  };
143
235
  };
144
236
 
145
- export const plan = <
146
- const Phase extends "update" | "destroy",
147
- const Services extends Service[],
148
- >({
149
- phase,
150
- services,
151
- }: {
152
- phase: Phase;
153
- services: Services;
154
- }) => {
155
- type ServiceIDs = Services[number]["id"];
156
- type ServiceHosts = {
157
- [ID in ServiceIDs]: Extract<Services[number], Service<Extract<ID, string>>>;
237
+ export type IPlan = {
238
+ resources: {
239
+ [id in string]: CRUD<any>;
158
240
  };
159
-
160
- type UpstreamTags = {
161
- [ID in ServiceIDs]: ServiceHosts[ID]["props"]["bindings"]["tags"][number];
162
- }[ServiceIDs];
163
- type UpstreamResources = {
164
- [ID in ServiceIDs]: Extract<
165
- ServiceHosts[ID]["props"]["bindings"]["capabilities"][number]["resource"],
166
- Resource
167
- >;
168
- }[ServiceIDs];
169
- type Resources = {
170
- [ID in ServiceIDs]: Apply<Extract<Instance<ServiceHosts[ID]>, Resource>>;
171
- } & {
172
- [ID in UpstreamResources["id"]]: Apply<
173
- Extract<UpstreamResources, { id: ID }>
174
- >;
241
+ deletions: {
242
+ [id in string]?: Delete<Resource>;
175
243
  };
244
+ };
245
+
246
+ export type Plan<Resources extends Service | Resource> = Effect.Effect<
247
+ DerivePlan<Resources>,
248
+ never,
249
+ Providers<Resources> | State
250
+ >;
176
251
 
177
- return Effect.gen(function* () {
252
+ export const plan = <const Resources extends (Service | Resource)[]>(
253
+ ...resources: Resources
254
+ ): Plan<Instance<Resources[number]>> =>
255
+ Effect.gen(function* () {
178
256
  const state = yield* State;
179
257
 
180
- const resourceIds = yield* state.list();
258
+ // TODO(sam): rename terminology to Stack
259
+ const app = yield* App;
260
+
261
+ const resourceIds = yield* state.list({
262
+ stack: app.name,
263
+ stage: app.stage,
264
+ });
181
265
  const resourcesState = yield* Effect.all(
182
- resourceIds.map((id) => state.get(id)),
266
+ resourceIds.map((id) =>
267
+ state.get({ stack: app.name, stage: app.stage, resourceId: id }),
268
+ ),
183
269
  );
184
270
  // map of resource ID -> its downstream dependencies (resources that depend on it)
185
271
  const downstream = resourcesState
@@ -190,21 +276,10 @@ export const plan = <
190
276
  bindings: BindNode[];
191
277
  } => !!resource?.bindings,
192
278
  )
193
- .flatMap(
194
- (resource) =>
195
- resource.bindings.flatMap(({ binding }) => [
196
- [binding.capability.resource.id, binding.capability.resource],
197
- ]),
198
- // resource.bindings.flatMap(({ binding }) => {
199
- // const capability: Capability = binding.capability;
200
- // const resource = capability.resource;
201
- // if (!resource) {
202
- // return [];
203
- // }
204
- // return [
205
- // [binding.capability.resource.id, binding.capability.resource],
206
- // ];
207
- // }),
279
+ .flatMap((resource) =>
280
+ resource.bindings.flatMap(({ binding }) => [
281
+ [binding.capability.resource.id, binding.capability.resource],
282
+ ]),
208
283
  )
209
284
  .reduce(
210
285
  (acc, [id, resourceId]) => ({
@@ -214,131 +289,273 @@ export const plan = <
214
289
  {} as Record<string, string[]>,
215
290
  );
216
291
 
217
- const resources =
218
- phase === "update"
219
- ? (Object.fromEntries(
220
- (yield* Effect.all(
221
- services
222
- .flatMap((service) => [
223
- ...service.props.bindings.capabilities.map(
224
- (cap: Capability) => cap.resource as Resource,
225
- ),
226
- service,
227
- ])
228
- .filter(
229
- (node, i, arr) =>
230
- arr.findIndex((n) => n.id === node.id) === i,
292
+ type ResolveEffect<T> = Effect.Effect<T, ResolveErr, ResolveReq>;
293
+ type ResolveErr = StateStoreError;
294
+ type ResolveReq =
295
+ | Context.TagClass<
296
+ Provider<Resource<string, string, any, any>>,
297
+ string,
298
+ ProviderService<Resource<string, string, any, any>>
299
+ >
300
+ | State;
301
+
302
+ const resolvedResources: Record<
303
+ string,
304
+ ResolveEffect<{
305
+ [attr in string]: any;
306
+ }>
307
+ > = {};
308
+
309
+ const resolveResource = (
310
+ resourceExpr: Output.ResourceExpr<any, any, any>,
311
+ ) =>
312
+ Effect.gen(function* () {
313
+ return yield* (resolvedResources[resourceExpr.src.id] ??=
314
+ yield* Effect.cached(
315
+ Effect.gen(function* () {
316
+ const resource = resourceExpr.src as Resource & {
317
+ provider: ResourceTags<Resource<string, string, any, any>>;
318
+ };
319
+ const provider = yield* resource.provider.tag;
320
+ const props = yield* resolveInput(resource.props);
321
+ const oldState = yield* state.get({
322
+ stack: app.name,
323
+ stage: app.stage,
324
+ resourceId: resource.id,
325
+ });
326
+
327
+ if (!oldState) {
328
+ return resourceExpr;
329
+ }
330
+
331
+ const diff = yield* provider.diff
332
+ ? provider.diff({
333
+ id: resource.id,
334
+ olds: oldState.props,
335
+ news: props,
336
+ output: oldState.output,
337
+ })
338
+ : Effect.succeed(undefined);
339
+
340
+ if (diff == null) {
341
+ if (arePropsChanged(oldState, props)) {
342
+ // the props have changed but the provider did not provide any hints as to what is stable
343
+ // so we must assume everything has changed
344
+ return resourceExpr;
345
+ }
346
+ } else if (diff.action === "update") {
347
+ const output = oldState?.output;
348
+ if (diff.stables) {
349
+ return new Output.ResourceExpr(
350
+ resourceExpr.src,
351
+ Object.fromEntries(
352
+ diff.stables.map((stable) => [stable, output?.[stable]]),
353
+ ),
354
+ );
355
+ } else {
356
+ // if there are no stable properties, treat every property as changed
357
+ return resourceExpr;
358
+ }
359
+ } else if (diff.action === "replace") {
360
+ }
361
+ return oldState?.output;
362
+ }),
363
+ ));
364
+ });
365
+
366
+ const resolveInput = (input: any): ResolveEffect<any> =>
367
+ Effect.gen(function* () {
368
+ if (!input) {
369
+ return input;
370
+ } else if (Output.isExpr(input)) {
371
+ return yield* resolveOutput(input);
372
+ } else if (Array.isArray(input)) {
373
+ return yield* Effect.all(input.map(resolveInput));
374
+ } else if (typeof input === "object") {
375
+ return Object.fromEntries(
376
+ yield* Effect.all(
377
+ Object.entries(input).map(([key, value]) =>
378
+ resolveInput(value).pipe(Effect.map((value) => [key, value])),
379
+ ),
380
+ ),
381
+ );
382
+ }
383
+ return input;
384
+ });
385
+
386
+ const resolveOutput = (expr: Output.Expr<any>): ResolveEffect<any> =>
387
+ Effect.gen(function* () {
388
+ if (Output.isResourceExpr(expr)) {
389
+ return yield* resolveResource(expr);
390
+ } else if (Output.isPropExpr(expr)) {
391
+ const upstream = yield* resolveOutput(expr.expr);
392
+ return upstream?.[expr.identifier];
393
+ } else if (Output.isApplyExpr(expr)) {
394
+ const upstream = yield* resolveOutput(expr.expr);
395
+ return Output.isOutput(upstream) ? expr : expr.f(upstream);
396
+ } else if (Output.isEffectExpr(expr)) {
397
+ const upstream = yield* resolveOutput(expr.expr);
398
+ return Output.isOutput(upstream) ? expr : yield* expr.f(upstream);
399
+ } else if (Output.isAllExpr(expr)) {
400
+ return yield* Effect.all(expr.outs.map(resolveOutput));
401
+ }
402
+ return yield* Effect.die(new Error("Not implemented yet"));
403
+ });
404
+
405
+ const resolveUpstream = (
406
+ value: any,
407
+ ): {
408
+ [ID in string]: Resource;
409
+ } => {
410
+ if (Output.isExpr(value)) {
411
+ return Output.upstream(value);
412
+ } else if (Array.isArray(value)) {
413
+ return Object.assign({}, ...value.map(resolveUpstream));
414
+ } else if (
415
+ value &&
416
+ (typeof value === "object" || typeof value === "function")
417
+ ) {
418
+ return Object.assign(
419
+ {},
420
+ ...Object.values(value).map((value) => resolveUpstream(value)),
421
+ );
422
+ }
423
+ return {};
424
+ };
425
+
426
+ const resourceGraph = Object.fromEntries(
427
+ (yield* Effect.all(
428
+ resources
429
+ .flatMap((resource) => [
430
+ ...(isService(resource)
431
+ ? resource.props.bindings.capabilities.map(
432
+ (cap: Capability) => cap.resource as Resource,
231
433
  )
232
- .map(
233
- Effect.fn(function* (node) {
234
- const id = node.id;
235
- const resource = node as Resource & {
236
- provider: ResourceTags<Resource>;
237
- };
238
- const news = resource.props;
239
-
240
- const oldState = yield* state.get(id);
241
- const provider = yield* resource.provider.tag;
242
-
243
- const bindings = diffBindings(
244
- oldState,
245
- isService(node)
246
- ? (
247
- node.props.bindings as unknown as {
248
- bindings: AnyBinding[];
249
- }
250
- ).bindings
251
- : [],
252
- );
253
-
254
- if (
255
- oldState === undefined ||
256
- oldState.status === "creating"
257
- ) {
258
- return Node<Create<Resource>>({
259
- action: "create",
260
- news,
261
- provider,
262
- resource,
263
- bindings,
264
- // phantom
265
- attributes: undefined!,
266
- });
267
- } else if (provider.diff) {
268
- const diff = yield* provider.diff({
269
- id,
270
- olds: oldState.props,
271
- news,
272
- output: oldState.output,
273
- });
274
- if (diff.action === "noop") {
275
- return Node<NoopUpdate<Resource>>({
276
- action: "noop",
277
- resource,
278
- bindings,
279
- // phantom
280
- attributes: undefined!,
281
- });
282
- } else if (diff.action === "replace") {
283
- return Node<Replace<Resource>>({
284
- action: "replace",
285
- olds: oldState.props,
286
- news,
287
- output: oldState.output,
288
- provider,
289
- resource,
290
- bindings,
291
- // phantom
292
- attributes: undefined!,
293
- });
294
- } else {
295
- return Node<Update<Resource>>({
296
- action: "update",
297
- olds: oldState.props,
298
- news,
299
- output: oldState.output,
300
- provider,
301
- resource,
302
- bindings,
303
- // phantom
304
- attributes: undefined!,
305
- });
434
+ : []),
435
+ ...Object.values(resolveUpstream(resource.props)),
436
+ resource,
437
+ ])
438
+ .filter(
439
+ (node, i, arr) => arr.findIndex((n) => n.id === node.id) === i,
440
+ )
441
+ .map(
442
+ Effect.fn(function* (node) {
443
+ const id = node.id;
444
+ const resource = node as Resource & {
445
+ provider: ResourceTags<Resource<string, string, any, any>>;
446
+ };
447
+ const news = yield* resolveInput(resource.props);
448
+
449
+ const oldState = yield* state.get({
450
+ stack: app.name,
451
+ stage: app.stage,
452
+ resourceId: id,
453
+ });
454
+ const provider = yield* resource.provider.tag;
455
+
456
+ const bindings = isService(node)
457
+ ? yield* diffBindings({
458
+ oldState,
459
+ bindings: (
460
+ node.props.bindings as unknown as {
461
+ bindings: AnyBinding[];
306
462
  }
307
- } else if (compare(oldState, resource.props)) {
308
- return Node<Update<Resource>>({
309
- action: "update",
310
- olds: oldState.props,
311
- news,
312
- output: oldState.output,
313
- provider,
314
- resource,
315
- bindings,
316
- // phantom
317
- attributes: undefined!,
318
- });
319
- } else {
320
- return Node<NoopUpdate<Resource>>({
321
- action: "noop",
322
- resource,
323
- bindings,
324
- // phantom
325
- attributes: undefined!,
326
- });
327
- }
328
- }),
329
- ),
330
- )).map((update) => [update.resource.id, update]),
331
- ) as Plan["resources"])
332
- : ({} as Plan["resources"]);
463
+ ).bindings,
464
+ target: {
465
+ id: node.id,
466
+ props: node.props,
467
+ oldAttr: oldState?.output,
468
+ oldProps: oldState?.props,
469
+ },
470
+ })
471
+ : []; // TODO(sam): return undefined instead of empty array
472
+
473
+ if (oldState === undefined || oldState.status === "creating") {
474
+ return Node<Create<Resource>>({
475
+ action: "create",
476
+ news,
477
+ provider,
478
+ resource,
479
+ bindings,
480
+ // phantom
481
+ attributes: undefined!,
482
+ });
483
+ }
484
+
485
+ const diff = provider.diff
486
+ ? yield* (() => {
487
+ const diff = provider.diff({
488
+ id,
489
+ olds: oldState.props,
490
+ news,
491
+ output: oldState.output,
492
+ });
493
+ return Effect.isEffect(diff) ? diff : Effect.succeed(diff);
494
+ })()
495
+ : undefined;
496
+
497
+ if (!diff && arePropsChanged(oldState, news)) {
498
+ return Node<Update<Resource>>({
499
+ action: "update",
500
+ olds: oldState.props,
501
+ news,
502
+ output: oldState.output,
503
+ provider,
504
+ resource,
505
+ bindings,
506
+ // phantom
507
+ attributes: undefined!,
508
+ });
509
+ } else if (diff?.action === "replace") {
510
+ return Node<Replace<Resource>>({
511
+ action: "replace",
512
+ olds: oldState.props,
513
+ news,
514
+ output: oldState.output,
515
+ provider,
516
+ resource,
517
+ bindings,
518
+ // phantom
519
+ attributes: undefined!,
520
+ });
521
+ } else if (diff?.action === "update") {
522
+ return Node<Update<Resource>>({
523
+ action: "update",
524
+ olds: oldState.props,
525
+ news,
526
+ output: oldState.output,
527
+ provider,
528
+ resource,
529
+ bindings,
530
+ // phantom
531
+ attributes: undefined!,
532
+ });
533
+ } else {
534
+ return Node<NoopUpdate<Resource>>({
535
+ action: "noop",
536
+ resource,
537
+ bindings,
538
+ // phantom
539
+ attributes: undefined!,
540
+ });
541
+ }
542
+ }),
543
+ ),
544
+ )).map((update) => [update.resource.id, update]),
545
+ ) as IPlan["resources"];
333
546
 
334
547
  const deletions = Object.fromEntries(
335
548
  (yield* Effect.all(
336
- (yield* state.list()).map(
549
+ (yield* state.list({ stack: app.name, stage: app.stage })).map(
337
550
  Effect.fn(function* (id) {
338
- if (id in resources) {
551
+ if (id in resourceGraph) {
339
552
  return;
340
553
  }
341
- const oldState = yield* state.get(id);
554
+ const oldState = yield* state.get({
555
+ stack: app.name,
556
+ stage: app.stage,
557
+ resourceId: id,
558
+ });
342
559
  const context = yield* Effect.context<never>();
343
560
  if (oldState) {
344
561
  const provider: ProviderService = context.unsafeMap.get(
@@ -361,7 +578,6 @@ export const plan = <
361
578
  bindings: [],
362
579
  resource: {
363
580
  id: id,
364
- parent: undefined,
365
581
  type: oldState.type,
366
582
  attr: oldState.output,
367
583
  props: oldState.props,
@@ -376,7 +592,9 @@ export const plan = <
376
592
  );
377
593
 
378
594
  for (const [resourceId, deletion] of Object.entries(deletions)) {
379
- const dependencies = deletion.downstream.filter((d) => d in resources);
595
+ const dependencies = deletion.downstream.filter(
596
+ (d) => d in resourceGraph,
597
+ );
380
598
  if (dependencies.length > 0) {
381
599
  return yield* Effect.fail(
382
600
  new DeleteResourceHasDownstreamDependencies({
@@ -389,24 +607,10 @@ export const plan = <
389
607
  }
390
608
 
391
609
  return {
392
- phase,
393
- resources,
610
+ resources: resourceGraph,
394
611
  deletions,
395
- } satisfies Plan as Plan;
396
- }) as Effect.Effect<
397
- {
398
- phase: Phase;
399
- resources: {
400
- [ID in keyof Resources]: Resources[ID];
401
- };
402
- deletions: {
403
- [id in Exclude<string, keyof Resources>]?: Delete<Resource>;
404
- };
405
- },
406
- never,
407
- UpstreamTags | State
408
- >;
409
- };
612
+ } satisfies IPlan as IPlan;
613
+ }) as any;
410
614
 
411
615
  class DeleteResourceHasDownstreamDependencies extends Data.TaggedError(
412
616
  "DeleteResourceHasDownstreamDependencies",
@@ -416,55 +620,152 @@ class DeleteResourceHasDownstreamDependencies extends Data.TaggedError(
416
620
  dependencies: string[];
417
621
  }> {}
418
622
 
419
- const compare = <R extends Resource>(
623
+ const arePropsChanged = <R extends Resource>(
420
624
  oldState: ResourceState | undefined,
421
- newState: R["props"],
422
- ) => JSON.stringify(oldState?.props) === JSON.stringify(newState);
423
-
424
- const diffBindings = (
425
- oldState: ResourceState | undefined,
426
- bindings: AnyBinding[],
625
+ newProps: R["props"],
427
626
  ) => {
428
- const actions: BindNode[] = [];
627
+ return (
628
+ JSON.stringify(omit(oldState?.props ?? {}, "bindings")) !==
629
+ JSON.stringify(omit((newProps ?? {}) as any, "bindings"))
630
+ );
631
+ };
632
+
633
+ const diffBindings = Effect.fn(function* ({
634
+ oldState,
635
+ bindings,
636
+ target,
637
+ }: {
638
+ oldState: ResourceState | undefined;
639
+ bindings: AnyBinding[];
640
+ target: BindingDiffProps["target"];
641
+ }) {
642
+ // const actions: BindNode[] = [];
429
643
  const oldBindings = oldState?.bindings;
430
644
  const oldSids = new Set(
431
645
  oldBindings?.map(({ binding }) => binding.capability.sid),
432
646
  );
433
- for (const binding of bindings) {
434
- const cap = binding.capability;
435
- const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
436
- oldSids.delete(sid);
437
647
 
438
- const oldBinding = oldBindings?.find(
439
- ({ binding }) => binding.capability.sid === sid,
440
- );
441
- if (!oldBinding) {
442
- actions.push({
443
- action: "attach",
444
- binding,
648
+ const diffBinding: (
649
+ binding: AnyBinding,
650
+ ) => Effect.Effect<BindNode, StateStoreError, State> = Effect.fn(
651
+ function* (binding) {
652
+ const cap = binding.capability;
653
+ const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
654
+ // Find potential oldBinding for this sid
655
+ const oldBinding = oldBindings?.find(
656
+ ({ binding }) => binding.capability.sid === sid,
657
+ );
658
+ if (!oldBinding) {
659
+ return {
660
+ action: "attach",
661
+ binding,
662
+ attr: undefined,
663
+ olds: undefined,
664
+ } satisfies Attach<AnyBinding>;
665
+ }
666
+
667
+ const diff = yield* isBindingDiff({
668
+ target,
669
+ oldBinding,
670
+ newBinding: binding,
445
671
  });
446
- } else if (isBindingDiff(oldBinding, binding)) {
447
- actions.push({
448
- action: "attach",
672
+ // if (diff === false) {
673
+ // } else if (diff === true) {
674
+ // return {
675
+ // action: "attach",
676
+ // binding,
677
+ // olds: oldBinding,
678
+ // } satisfies Attach<AnyBinding>;
679
+ // }
680
+ if (diff.action === "replace") {
681
+ return yield* Effect.die(
682
+ new Error("Replace binding not yet supported"),
683
+ );
684
+ // TODO(sam): implement support for replacing bindings
685
+ // return {
686
+ // action: "replace",
687
+ // binding,
688
+ // olds: oldBinding,
689
+ // };
690
+ } else if (diff?.action === "update") {
691
+ return {
692
+ action: "reattach",
693
+ binding,
694
+ olds: oldBinding,
695
+ attr: oldBinding.attr,
696
+ } satisfies Reattach<AnyBinding>;
697
+ }
698
+ return {
699
+ action: "noop",
449
700
  binding,
450
- olds: oldBinding,
451
- });
452
- }
701
+ attr: oldBinding.attr,
702
+ } satisfies NoopBind<AnyBinding>;
703
+ },
704
+ );
705
+
706
+ return (yield* Effect.all(bindings.map(diffBinding))).filter(
707
+ (action): action is BindNode => action !== null,
708
+ );
709
+ });
710
+
711
+ const isBindingDiff = Effect.fn(function* ({
712
+ target,
713
+ oldBinding: { binding: oldBinding },
714
+ newBinding,
715
+ }: {
716
+ // TODO(sam): support binding to other Resources
717
+ target: BindingDiffProps["target"];
718
+ oldBinding: BindNode;
719
+ newBinding: AnyBinding;
720
+ }) {
721
+ const oldCap = oldBinding.capability;
722
+ const newCap = newBinding.capability;
723
+ if (
724
+ // if the binding provider has changed
725
+ oldBinding.tag !== newBinding.tag ||
726
+ // if it points to a totally different resource, we should replace
727
+ oldCap?.resource?.id !== newCap?.resource?.id ||
728
+ // if it is a different action
729
+ oldCap.action !== newCap.action
730
+ ) {
731
+ // then we must replace (we need to detach and attach with different bindings or to different resources)
732
+ return {
733
+ action: "replace",
734
+ } satisfies Diff;
453
735
  }
454
- // for (const sid of oldSids) {
455
- // actions.push({
456
- // action: "detach",
457
- // cap: oldBindings?.find((binding) => binding.sid === sid)!,
458
- // });
459
- // }
460
- return actions;
461
- };
462
736
 
463
- const isBindingDiff = (
464
- { binding: oldBinding }: BindNode,
465
- newBinding: AnyBinding,
466
- ) =>
467
- oldBinding.capability.action !== newBinding.capability.action ||
468
- oldBinding.capability?.resource?.id !== newBinding.capability?.resource?.id;
737
+ const binding = newBinding as AnyBinding & {
738
+ // smuggled property (because it interacts poorly with inference)
739
+ Tag: Context.Tag<never, BindingService>;
740
+ };
741
+ const provider = yield* binding.Tag;
742
+ if (provider.diff) {
743
+ const state = yield* State;
744
+ const oldState = yield* state.get(oldCap.resource.id);
745
+ const diff = yield* provider.diff({
746
+ source: {
747
+ id: oldCap.resource.id,
748
+ props: newCap.resource.props,
749
+ oldProps: oldState?.props,
750
+ oldAttr: oldState?.output,
751
+ },
752
+ props: newBinding.props,
753
+ attr: oldBinding.attr,
754
+ target,
755
+ });
756
+
757
+ if (diff?.action === "update" || diff?.action === "replace") {
758
+ return diff;
759
+ }
760
+ }
761
+ return {
762
+ action:
763
+ oldBinding.capability.action !== newBinding.capability.action ||
764
+ oldBinding.capability?.resource?.id !==
765
+ newBinding.capability?.resource?.id
766
+ ? "update"
767
+ : "noop",
768
+ } as const;
769
+ });
469
770
  // TODO(sam): compare props
470
771
  // oldBinding.props !== newBinding.props;