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
package/src/state.ts CHANGED
@@ -5,7 +5,6 @@ import * as Context from "effect/Context";
5
5
  import * as Data from "effect/Data";
6
6
  import * as Effect from "effect/Effect";
7
7
  import * as Layer from "effect/Layer";
8
- import { App } from "./app.ts";
9
8
  import type { BindNode } from "./plan.ts";
10
9
  import { isResource } from "./resource.ts";
11
10
 
@@ -53,40 +52,147 @@ import { isResource } from "./resource.ts";
53
52
 
54
53
  // Scrap the "key-value" store on State/Scope
55
54
 
56
- export type ResourceStatus =
57
- | "creating"
58
- | "created"
59
- | "updating"
60
- | "updated"
61
- | "deleting"
62
- | "deleted";
63
-
64
- export type ResourceState = {
65
- type: string;
66
- id: string;
55
+ export type Props = Record<string, any>;
56
+ export type Attr = Record<string, any>;
57
+
58
+ export type ResourceStatus = ResourceState["status"];
59
+
60
+ interface BaseResourceState {
61
+ resourceType: string;
62
+ /** Logical ID of the Resource (stable across creates, updates, deletes and replaces) */
63
+ logicalId: string;
64
+ /** A unique randomly generated token used to seed ID generation (only changes when replaced) */
65
+ instanceId: string;
66
+ /** The version of the provider that was used to create/update the resource. */
67
+ providerVersion: number;
68
+ /** Current status of the logical Resource */
67
69
  status: ResourceStatus;
68
- props: any;
69
- output: any;
70
+ /** List of logical IDs of resources that depend on this resource */
71
+ downstream: string[];
72
+ /** List of Bindings attached to this Resource */
70
73
  bindings?: BindNode[];
71
- };
74
+ /** Desired state (input props) of this Resource */
75
+ props?: Props;
76
+ /** The output attributes of this Resource (if it has been created) */
77
+ attr?: Attr;
78
+ }
79
+
80
+ export interface CreatingResourceState extends BaseResourceState {
81
+ status: "creating";
82
+ /** The new resource properties that are being (or have been) applied. */
83
+ props: Props;
84
+ }
85
+
86
+ export interface CreatedResourceState extends BaseResourceState {
87
+ status: "created";
88
+ /** The new resource properties that have been applied. */
89
+ props: Props;
90
+ /** The output attributes of the created resource */
91
+ attr: Attr;
92
+ }
93
+
94
+ export interface UpdatingReourceState extends BaseResourceState {
95
+ status: "updating";
96
+ /** The new resource properties that are being (or have been) applied. */
97
+ props: Props;
98
+ old: {
99
+ /** The old resource properties that have been successfully applied. */
100
+ props: Props;
101
+ /** The old output properties that have been successfully applied. */
102
+ attr: Attr;
103
+ // TODO(sam): do I need to track the old downstream edges?
104
+ // downstream: string[];
105
+ };
106
+ }
107
+
108
+ export interface UpdatedResourceState extends BaseResourceState {
109
+ status: "updated";
110
+ /** The new resource properties that are being (or have been) applied. */
111
+ props: Props;
112
+ /** The output attributes of the created resource */
113
+ attr: Attr;
114
+ }
115
+
116
+ export interface DeletingResourceState extends BaseResourceState {
117
+ status: "deleting";
118
+ /** Attributes of the resource being deleted */
119
+ attr: Attr | undefined;
120
+ }
121
+
122
+ export interface ReplacingResourceState extends BaseResourceState {
123
+ status: "replacing";
124
+ /** Desired properties of the new resource (the replacement) */
125
+ props: Props;
126
+ /** Reference to the state of the old resource (the one being replaced) */
127
+ old:
128
+ | CreatedResourceState
129
+ | UpdatedResourceState
130
+ | CreatingResourceState
131
+ | UpdatingReourceState
132
+ | DeletingResourceState;
133
+ /** Whether the resource should be deleted before or after replacements */
134
+ deleteFirst: boolean;
135
+ }
136
+
137
+ export interface ReplacedResourceState extends BaseResourceState {
138
+ status: "replaced";
139
+ /** Desired properties of the new resource (the replacement) */
140
+ props: Props;
141
+ /** Output attributes of the new resource (the replacement) */
142
+ attr: Attr;
143
+ /** Reference to the state of the old resource (the one being replaced) */
144
+ old:
145
+ | CreatingResourceState
146
+ | CreatedResourceState
147
+ | UpdatingReourceState
148
+ | UpdatedResourceState
149
+ | DeletingResourceState;
150
+ /** Whether the resource should be deleted before or after replacements */
151
+ deleteFirst: boolean;
152
+ // .. will (finally) transition to `CreatedResourceState` after finalizing
153
+ }
154
+
155
+ export type ResourceState =
156
+ | CreatingResourceState
157
+ | CreatedResourceState
158
+ | UpdatingReourceState
159
+ | UpdatedResourceState
160
+ | DeletingResourceState
161
+ | ReplacingResourceState
162
+ | ReplacedResourceState;
72
163
 
73
164
  export class StateStoreError extends Data.TaggedError("StateStoreError")<{
74
165
  message: string;
75
166
  }> {}
76
167
 
77
168
  export interface StateService {
78
- listApps(): Effect.Effect<string[], StateStoreError, never>;
79
- listStages(appName?: string): Effect.Effect<string[], StateStoreError, never>;
169
+ listStacks(): Effect.Effect<string[], StateStoreError, never>;
170
+ listStages(stack: string): Effect.Effect<string[], StateStoreError, never>;
80
171
  // stub
81
- get(
82
- id: string,
83
- ): Effect.Effect<ResourceState | undefined, StateStoreError, never>;
84
- set<V extends ResourceState>(
85
- id: string,
86
- value: V,
87
- ): Effect.Effect<V, StateStoreError, never>;
88
- delete(id: string): Effect.Effect<void, StateStoreError, never>;
89
- list(): Effect.Effect<string[], StateStoreError, never>;
172
+ get(request: {
173
+ stack: string;
174
+ stage: string;
175
+ resourceId: string;
176
+ }): Effect.Effect<ResourceState | undefined, StateStoreError, never>;
177
+ getReplacedResources(request: {
178
+ stack: string;
179
+ stage: string;
180
+ }): Effect.Effect<ReplacedResourceState[], StateStoreError, never>;
181
+ set<V extends ResourceState>(request: {
182
+ stack: string;
183
+ stage: string;
184
+ resourceId: string;
185
+ value: V;
186
+ }): Effect.Effect<V, StateStoreError, never>;
187
+ delete(request: {
188
+ stack: string;
189
+ stage: string;
190
+ resourceId: string;
191
+ }): Effect.Effect<void, StateStoreError, never>;
192
+ list(request: {
193
+ stack: string;
194
+ stage: string;
195
+ }): Effect.Effect<string[], StateStoreError, never>;
90
196
  }
91
197
 
92
198
  export class State extends Context.Tag("AWS::Lambda::State")<
@@ -98,13 +204,10 @@ export class State extends Context.Tag("AWS::Lambda::State")<
98
204
  export const localFs = Layer.effect(
99
205
  State,
100
206
  Effect.gen(function* () {
101
- const app = yield* App;
102
207
  const fs = yield* FileSystem.FileSystem;
103
208
  const path = yield* Path.Path;
104
209
  const dotAlchemy = path.join(process.cwd(), ".alchemy");
105
210
  const stateDir = path.join(dotAlchemy, "state");
106
- const appDir = path.join(stateDir, app.name);
107
- const stageDir = path.join(appDir, app.stage);
108
211
 
109
212
  const fail = (err: PlatformError) =>
110
213
  Effect.fail(
@@ -121,77 +224,167 @@ export const localFs = Layer.effect(
121
224
  Effect.catchTag("BadArgument", (e) => fail(e)),
122
225
  );
123
226
 
124
- const resourceFile = (id: string) => path.join(stageDir, `${id}.json`);
227
+ const stage = ({ stack, stage }: { stack: string; stage: string }) =>
228
+ path.join(stateDir, stack, stage);
229
+
230
+ const resource = ({
231
+ stack,
232
+ stage,
233
+ resourceId,
234
+ }: {
235
+ stack: string;
236
+ stage: string;
237
+ resourceId: string;
238
+ }) => path.join(stateDir, stack, stage, `${resourceId}.json`);
125
239
 
126
- yield* fs.makeDirectory(stageDir, { recursive: true });
240
+ const ensure = yield* Effect.cachedFunction((dir: string) =>
241
+ fs.makeDirectory(dir, { recursive: true }),
242
+ );
127
243
 
128
- return {
129
- listApps: () =>
244
+ const state: StateService = {
245
+ listStacks: () =>
130
246
  fs.readDirectory(stateDir).pipe(
131
247
  recover,
132
248
  Effect.map((files) => files ?? []),
133
249
  ),
134
- listStages: (appName: string = app.name) =>
135
- fs.readDirectory(path.join(stateDir, appName)).pipe(
250
+ listStages: (stack: string) =>
251
+ fs.readDirectory(path.join(stateDir, stack)).pipe(
136
252
  recover,
137
253
  Effect.map((files) => files ?? []),
138
254
  ),
139
- get: (id) =>
140
- fs.readFile(resourceFile(id)).pipe(
255
+ get: (request) =>
256
+ fs.readFile(resource(request)).pipe(
141
257
  Effect.map((file) => JSON.parse(file.toString())),
142
258
  recover,
143
259
  ),
144
- set: <V extends ResourceState>(id: string, value: V) =>
145
- fs
146
- .writeFileString(
147
- resourceFile(id),
148
- JSON.stringify(
149
- value,
150
- (k, v) => {
151
- if (isResource(v)) {
152
- return {
153
- id: v.id,
154
- type: v.type,
155
- props: v.props,
156
- attr: v.attr,
157
- };
158
- }
159
- return v;
160
- },
161
- 2,
260
+ getReplacedResources: Effect.fnUntraced(function* (request) {
261
+ return (yield* Effect.all(
262
+ (yield* state.list(request)).map((resourceId) =>
263
+ state.get({
264
+ stack: request.stack,
265
+ stage: request.stage,
266
+ resourceId,
267
+ }),
268
+ ),
269
+ )).filter((r) => r?.status === "replaced");
270
+ }),
271
+ set: (request) =>
272
+ ensure(stage(request)).pipe(
273
+ Effect.flatMap(() =>
274
+ fs.writeFileString(
275
+ resource(request),
276
+ JSON.stringify(
277
+ request.value,
278
+ (k, v) => {
279
+ if (isResource(v)) {
280
+ return {
281
+ id: v.id,
282
+ type: v.type,
283
+ props: v.props,
284
+ attr: v.attr,
285
+ };
286
+ }
287
+ return v;
288
+ },
289
+ 2,
290
+ ),
162
291
  ),
163
- )
164
- .pipe(
165
- recover,
166
- Effect.map(() => value),
167
292
  ),
168
- delete: (id) => fs.remove(resourceFile(id)).pipe(recover),
169
- list: () =>
170
- fs.readDirectory(stageDir).pipe(
293
+ recover,
294
+ Effect.map(() => request.value),
295
+ ),
296
+ delete: (request) => fs.remove(resource(request)).pipe(recover),
297
+ list: (request) =>
298
+ fs.readDirectory(stage(request)).pipe(
171
299
  recover,
172
300
  Effect.map(
173
301
  (files) => files?.map((file) => file.replace(/\.json$/, "")) ?? [],
174
302
  ),
175
303
  ),
176
304
  };
305
+ return state;
177
306
  }),
178
307
  );
179
308
 
180
- export const inMemory = () => {
181
- const state = new Map<string, any>();
182
- return Layer.succeed(State, {
183
- listApps: () => Effect.succeed([]),
309
+ type StackId = string;
310
+ type StageId = string;
311
+ type ResourceId = string;
312
+
313
+ export const inMemory = (
314
+ initialState: Record<
315
+ StackId,
316
+ Record<StageId, Record<ResourceId, ResourceState>>
317
+ > = {},
318
+ ) =>
319
+ Layer.succeed(State, inMemoryService(initialState)) as Layer.Layer<
320
+ State,
321
+ never,
322
+ never
323
+ >;
324
+
325
+ export const inMemoryService = (
326
+ initialState: Record<
327
+ StackId,
328
+ Record<StageId, Record<ResourceId, ResourceState>>
329
+ > = {},
330
+ ) => {
331
+ const state = initialState;
332
+ return {
333
+ listStacks: () => Effect.succeed(Array.from(Object.keys(state))),
184
334
  // oxlint-disable-next-line require-yield
185
- listStages: (_appName?: string) => Effect.succeed([]),
186
- get: (id: string) => Effect.succeed(state.get(id)),
187
- set: <V>(id: string, value: V) => {
188
- state.set(id, value);
335
+ listStages: (stack: string) =>
336
+ Effect.succeed(
337
+ Array.from(stack in state ? Object.keys(state[stack]) : []),
338
+ ),
339
+ get: ({
340
+ stack,
341
+ stage,
342
+ resourceId,
343
+ }: {
344
+ stack: string;
345
+ stage: string;
346
+ resourceId: string;
347
+ }) => Effect.succeed(state[stack]?.[stage]?.[resourceId]),
348
+ getReplacedResources: ({
349
+ stack,
350
+ stage,
351
+ }: {
352
+ stack: string;
353
+ stage: string;
354
+ }) =>
355
+ Effect.succeed(
356
+ Array.from(Object.values(state[stack]?.[stage] ?? {}) ?? []).filter(
357
+ (s) => s.status === "replaced",
358
+ ),
359
+ ),
360
+ set: <V extends ResourceState>({
361
+ stack,
362
+ stage,
363
+ resourceId,
364
+ value,
365
+ }: {
366
+ stack: string;
367
+ stage: string;
368
+ resourceId: string;
369
+ value: V;
370
+ }) => {
371
+ const stackState = (state[stack] ??= {});
372
+ const stageState = (stackState[stage] ??= {});
373
+ stageState[resourceId] = value;
189
374
  return Effect.succeed(value);
190
375
  },
191
- delete: (id: string) => {
192
- state.delete(id);
193
- return Effect.succeed(undefined);
194
- },
195
- list: () => Effect.succeed(Array.from(state.keys())),
196
- });
376
+ delete: ({
377
+ stack,
378
+ stage,
379
+ resourceId,
380
+ }: {
381
+ stack: string;
382
+ stage: string;
383
+ resourceId: string;
384
+ }) => Effect.succeed(delete state[stack]?.[stage]?.[resourceId]),
385
+ list: ({ stack, stage }: { stack: string; stage: string }) =>
386
+ Effect.succeed(
387
+ Array.from(Object.keys(state[stack]?.[stage] ?? {}) ?? []),
388
+ ),
389
+ } satisfies StateService;
197
390
  };
package/src/tags.ts CHANGED
@@ -36,3 +36,34 @@ export const createTagger = Effect.fn(function* () {
36
36
  "alchemy::id": id,
37
37
  });
38
38
  });
39
+
40
+ export const diffTags = (
41
+ oldTags: Record<string, string>,
42
+ newTags: Record<string, string>,
43
+ ) => {
44
+ const removed: string[] = [];
45
+ const updated: { Key: string; Value: string }[] = [];
46
+ const added: { Key: string; Value: string }[] = [];
47
+ for (const key in oldTags) {
48
+ if (!(key in newTags)) {
49
+ removed.push(key);
50
+ } else if (oldTags[key] !== newTags[key]) {
51
+ updated.push({ Key: key, Value: newTags[key] });
52
+ }
53
+ }
54
+ for (const key in newTags) {
55
+ if (!(key in oldTags)) {
56
+ added.push({ Key: key, Value: newTags[key] });
57
+ } else if (oldTags[key] !== newTags[key]) {
58
+ updated.push({ Key: key, Value: newTags[key] });
59
+ }
60
+ }
61
+ return {
62
+ added,
63
+ removed,
64
+ updated,
65
+ upsert: [...added, ...updated].filter(
66
+ (tag, index, self) => self.findIndex((t) => t.Key === tag.Key) === index,
67
+ ),
68
+ };
69
+ };
package/src/test.ts CHANGED
@@ -1,17 +1,42 @@
1
1
  import { FetchHttpClient, FileSystem, HttpClient } from "@effect/platform";
2
2
  import { NodeContext } from "@effect/platform-node";
3
- import type * as Path from "@effect/platform/Path";
4
- import { it } from "@effect/vitest";
5
- import { LogLevel } from "effect";
3
+ import * as Path from "@effect/platform/Path";
4
+ import * as PlatformConfigProvider from "@effect/platform/PlatformConfigProvider";
5
+ import { expect, it } from "@effect/vitest";
6
+ import { ConfigProvider, LogLevel } from "effect";
6
7
  import * as Effect from "effect/Effect";
7
8
  import * as Layer from "effect/Layer";
8
9
  import * as Logger from "effect/Logger";
9
10
  import * as Scope from "effect/Scope";
10
11
  import * as App from "./app.ts";
11
- import { PlanStatusReporter } from "./apply.ts";
12
+ import { CLI } from "./cli/service.ts";
12
13
  import { DotAlchemy, dotAlchemy } from "./dot-alchemy.ts";
14
+ import type { Resource } from "./resource.ts";
13
15
  import * as State from "./state.ts";
14
16
 
17
+ declare module "@effect/vitest" {
18
+ interface ExpectStatic {
19
+ emptyObject(): any;
20
+ propExpr(identifier: string, src: Resource): any;
21
+ }
22
+ }
23
+
24
+ expect.emptyObject = () =>
25
+ expect.toSatisfy(
26
+ (deletions) => Object.keys(deletions).length === 0,
27
+ "empty object",
28
+ );
29
+
30
+ expect.propExpr = (identifier: string, src: Resource) =>
31
+ expect.objectContaining({
32
+ kind: "PropExpr",
33
+ identifier,
34
+ expr: expect.objectContaining({
35
+ kind: "ResourceExpr",
36
+ src,
37
+ }),
38
+ });
39
+
15
40
  type Provided =
16
41
  | Scope.Scope
17
42
  | App.App
@@ -21,11 +46,34 @@ type Provided =
21
46
  | FileSystem.FileSystem
22
47
  | Path.Path;
23
48
 
49
+ export function test(
50
+ name: string,
51
+ options: {
52
+ timeout?: number;
53
+ state?: Layer.Layer<State.State, never, App.App>;
54
+ },
55
+ testCase: Effect.Effect<void, any, Provided>,
56
+ ): void;
57
+
24
58
  export function test(
25
59
  name: string,
26
60
  testCase: Effect.Effect<void, any, Provided>,
27
- timeout: number = 120_000,
61
+ ): void;
62
+
63
+ export function test(
64
+ name: string,
65
+ ...args:
66
+ | [
67
+ {
68
+ timeout?: number;
69
+ state?: Layer.Layer<State.State, never, App.App>;
70
+ },
71
+ Effect.Effect<void, any, Provided>,
72
+ ]
73
+ | [Effect.Effect<void, any, Provided>]
28
74
  ) {
75
+ const [options = {}, testCase] =
76
+ args.length === 1 ? [undefined, args[0]] : args;
29
77
  const platform = Layer.mergeAll(
30
78
  NodeContext.layer,
31
79
  FetchHttpClient.layer,
@@ -33,9 +81,18 @@ export function test(
33
81
  );
34
82
 
35
83
  const alchemy = Layer.provideMerge(
36
- Layer.mergeAll(State.localFs, report),
84
+ Layer.mergeAll(options.state ?? State.localFs, testCLI),
37
85
  Layer.mergeAll(
38
- App.make({ name: name.replaceAll(/[^a-zA-Z0-9_]/g, "-"), stage: "test" }),
86
+ App.make({
87
+ name: name.replaceAll(/[^a-zA-Z0-9_]/g, "-"),
88
+ stage: "test",
89
+ config: {
90
+ adopt: true,
91
+ aws: {
92
+ profile: "default",
93
+ },
94
+ },
95
+ }),
39
96
  dotAlchemy,
40
97
  ),
41
98
  );
@@ -43,29 +100,73 @@ export function test(
43
100
  return it.scopedLive(
44
101
  name,
45
102
  () =>
46
- testCase.pipe(
103
+ Effect.gen(function* () {
104
+ const configProvider = ConfigProvider.orElse(
105
+ yield* PlatformConfigProvider.fromDotEnv(".env"),
106
+ ConfigProvider.fromEnv,
107
+ );
108
+ return yield* testCase.pipe(Effect.withConfigProvider(configProvider));
109
+ }).pipe(
47
110
  Effect.provide(Layer.provideMerge(alchemy, platform)),
48
111
  Logger.withMinimumLogLevel(
49
112
  process.env.DEBUG ? LogLevel.Debug : LogLevel.Info,
50
113
  ),
114
+ Effect.provide(NodeContext.layer),
115
+ Effect.provide(NodeContext.layer),
51
116
  ),
52
- timeout,
117
+ options.timeout,
53
118
  );
54
119
  }
55
120
 
56
- export const report = Layer.succeed(
57
- PlanStatusReporter,
58
- PlanStatusReporter.of({
59
- start: Effect.fn(function* (plan) {
60
- return {
121
+ export namespace test {
122
+ export const state = (resources: Record<string, State.ResourceState> = {}) =>
123
+ Layer.effect(
124
+ State.State,
125
+ Effect.gen(function* () {
126
+ const app = yield* App.App;
127
+ return State.inMemoryService({
128
+ [app.name]: {
129
+ [app.stage]: resources,
130
+ },
131
+ });
132
+ }),
133
+ );
134
+
135
+ export const defaultState = (
136
+ resources: Record<string, State.ResourceState> = {},
137
+ other?: {
138
+ [stack: string]: {
139
+ [stage: string]: {
140
+ [resourceId: string]: State.ResourceState;
141
+ };
142
+ };
143
+ },
144
+ ) =>
145
+ Layer.succeed(
146
+ State.State,
147
+ State.inMemoryService({
148
+ ["test-app"]: {
149
+ ["test-stage"]: resources,
150
+ },
151
+ ...other,
152
+ }),
153
+ );
154
+ }
155
+
156
+ export const testCLI = Layer.succeed(
157
+ CLI,
158
+ CLI.of({
159
+ approvePlan: () => Effect.succeed(true),
160
+ displayPlan: () => Effect.void,
161
+ startApplySession: () =>
162
+ Effect.succeed({
61
163
  done: () => Effect.void,
62
164
  emit: (event) =>
63
165
  Effect.log(
64
166
  event.kind === "status-change"
65
167
  ? `${event.status} ${event.id}(${event.type})`
66
- : event.message,
168
+ : `${event.id}: ${event.message}`,
67
169
  ),
68
- };
69
- }),
170
+ }),
70
171
  }),
71
172
  );
package/src/todo.ts ADDED
@@ -0,0 +1,4 @@
1
+ import * as Effect from "effect/Effect";
2
+
3
+ export const todo = (message?: string) =>
4
+ Effect.dieMessage(message ?? `Not implemented`);
package/src/type.ts CHANGED
@@ -1,2 +1,6 @@
1
1
  export type type<T> = new () => T;
2
2
  export const type = class {} as new <T>() => T;
3
+
4
+ export declare namespace type {
5
+ export type of<T extends type<any>> = InstanceType<T>;
6
+ }
package/src/unknown.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { type Output, isOutput } from "./output.ts";
2
+ import type { Input } from "./input.ts";
3
+
4
+ // @ts-expect-error - we want to allow any value to be checked for unknown
5
+ export const isUnknown = <V>(value: V): value is Output<Input.Resolve<V>> =>
6
+ isOutput(value);
package/src/user.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { env } from "./env.ts";
2
+
3
+ export type USER = typeof USER;
4
+ export const USER = env.USER ?? env.USERNAME ?? "unknown";
package/src/util.ts ADDED
@@ -0,0 +1,21 @@
1
+ import * as Effect from "effect/Effect";
2
+
3
+ export type IsAny<T> = 0 extends 1 & T ? true : false;
4
+
5
+ export type UnionToIntersection<U> = (
6
+ U extends any ? (k: U) => void : never
7
+ ) extends (k: infer I) => void
8
+ ? I
9
+ : never;
10
+
11
+ export const assertDefined = <T>(value: T | undefined, message: string): T => {
12
+ if (!value) {
13
+ throw new Error(message);
14
+ }
15
+ return value;
16
+ };
17
+
18
+ export const asEffect = <T, Err = never, Req = never>(
19
+ effect: T | Effect.Effect<T, Err, Req>,
20
+ ): Effect.Effect<T, Err, Req> =>
21
+ Effect.isEffect(effect) ? effect : Effect.succeed(effect);