alchemy-effect 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +179 -0
  2. package/bin/alchemy-effect.js +15 -0
  3. package/bin/alchemy-effect.js.map +1 -0
  4. package/bin/alchemy-effect.ts +10 -0
  5. package/lib/app.d.ts +7 -2
  6. package/lib/app.d.ts.map +1 -1
  7. package/lib/app.js +1 -0
  8. package/lib/app.js.map +1 -1
  9. package/lib/apply.d.ts +57 -1
  10. package/lib/apply.d.ts.map +1 -1
  11. package/lib/apply.js +141 -55
  12. package/lib/apply.js.map +1 -1
  13. package/lib/aws/account.d.ts +18 -0
  14. package/lib/aws/account.d.ts.map +1 -0
  15. package/lib/aws/account.js +18 -0
  16. package/lib/aws/account.js.map +1 -0
  17. package/lib/aws/arn.d.ts +2 -0
  18. package/lib/aws/arn.d.ts.map +1 -0
  19. package/lib/aws/arn.js +1 -0
  20. package/lib/aws/arn.js.map +1 -0
  21. package/lib/aws/assets.d.ts +8 -0
  22. package/lib/aws/assets.d.ts.map +1 -0
  23. package/lib/aws/assets.js +4 -0
  24. package/lib/aws/assets.js.map +1 -0
  25. package/lib/aws/bundle.d.ts +4 -0
  26. package/lib/aws/bundle.d.ts.map +1 -0
  27. package/lib/aws/bundle.js +4 -0
  28. package/lib/aws/bundle.js.map +1 -0
  29. package/lib/aws/client.d.ts +8 -0
  30. package/lib/aws/client.d.ts.map +1 -0
  31. package/lib/aws/client.js +28 -0
  32. package/lib/aws/client.js.map +1 -0
  33. package/lib/aws/credentials.d.ts +146 -0
  34. package/lib/aws/credentials.d.ts.map +1 -0
  35. package/lib/aws/credentials.js +170 -0
  36. package/lib/aws/credentials.js.map +1 -0
  37. package/lib/aws/dynamodb/attribute-value.d.ts +20 -0
  38. package/lib/aws/dynamodb/attribute-value.d.ts.map +1 -0
  39. package/lib/aws/dynamodb/attribute-value.js +217 -0
  40. package/lib/aws/dynamodb/attribute-value.js.map +1 -0
  41. package/lib/aws/dynamodb/client.d.ts +12 -0
  42. package/lib/aws/dynamodb/client.d.ts.map +1 -0
  43. package/lib/aws/dynamodb/client.js +11 -0
  44. package/lib/aws/dynamodb/client.js.map +1 -0
  45. package/lib/aws/dynamodb/expr.d.ts +41 -0
  46. package/lib/aws/dynamodb/expr.d.ts.map +1 -0
  47. package/lib/aws/dynamodb/expr.js +1 -0
  48. package/lib/aws/dynamodb/expr.js.map +1 -0
  49. package/lib/aws/dynamodb/index.d.ts +9 -0
  50. package/lib/aws/dynamodb/index.d.ts.map +1 -0
  51. package/lib/aws/dynamodb/index.js +10 -0
  52. package/lib/aws/dynamodb/index.js.map +1 -0
  53. package/lib/aws/dynamodb/projection.d.ts +25 -0
  54. package/lib/aws/dynamodb/projection.d.ts.map +1 -0
  55. package/lib/aws/dynamodb/projection.js +1 -0
  56. package/lib/aws/dynamodb/projection.js.map +1 -0
  57. package/lib/aws/dynamodb/secondary-index.d.ts +25 -0
  58. package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -0
  59. package/lib/aws/dynamodb/secondary-index.js +4 -0
  60. package/lib/aws/dynamodb/secondary-index.js.map +1 -0
  61. package/lib/aws/dynamodb/table.d.ts +56 -0
  62. package/lib/aws/dynamodb/table.d.ts.map +1 -0
  63. package/lib/aws/dynamodb/table.get-item.d.ts +55 -0
  64. package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -0
  65. package/lib/aws/dynamodb/table.get-item.js +75 -0
  66. package/lib/aws/dynamodb/table.get-item.js.map +1 -0
  67. package/lib/aws/dynamodb/table.js +4 -0
  68. package/lib/aws/dynamodb/table.js.map +1 -0
  69. package/lib/aws/dynamodb/table.provider.d.ts +8 -0
  70. package/lib/aws/dynamodb/table.provider.d.ts.map +1 -0
  71. package/lib/aws/dynamodb/table.provider.js +199 -0
  72. package/lib/aws/dynamodb/table.provider.js.map +1 -0
  73. package/lib/aws/ec2/client.d.ts +12 -0
  74. package/lib/aws/ec2/client.d.ts.map +1 -0
  75. package/lib/aws/ec2/client.js +11 -0
  76. package/lib/aws/ec2/client.js.map +1 -0
  77. package/lib/aws/ec2/index.d.ts +4 -0
  78. package/lib/aws/ec2/index.d.ts.map +1 -0
  79. package/lib/aws/ec2/index.js +4 -0
  80. package/lib/aws/ec2/index.js.map +1 -0
  81. package/lib/aws/ec2/vpc.d.ts +131 -0
  82. package/lib/aws/ec2/vpc.d.ts.map +1 -0
  83. package/lib/aws/ec2/vpc.js +3 -0
  84. package/lib/aws/ec2/vpc.js.map +1 -0
  85. package/lib/aws/ec2/vpc.provider.d.ts +7 -0
  86. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -0
  87. package/lib/aws/ec2/vpc.provider.js +198 -0
  88. package/lib/aws/ec2/vpc.provider.js.map +1 -0
  89. package/lib/aws/iam.d.ts +23 -0
  90. package/lib/aws/iam.d.ts.map +1 -0
  91. package/lib/aws/iam.js +7 -0
  92. package/lib/aws/iam.js.map +1 -0
  93. package/lib/aws/index.d.ts +32 -0
  94. package/lib/aws/index.d.ts.map +1 -0
  95. package/lib/aws/index.js +23 -0
  96. package/lib/aws/index.js.map +1 -0
  97. package/lib/aws/lambda/client.d.ts +8 -0
  98. package/lib/aws/lambda/client.d.ts.map +1 -0
  99. package/lib/aws/lambda/client.js +7 -0
  100. package/lib/aws/lambda/client.js.map +1 -0
  101. package/lib/aws/lambda/consume.d.ts +17 -0
  102. package/lib/aws/lambda/consume.d.ts.map +1 -0
  103. package/lib/aws/lambda/consume.js +30 -0
  104. package/lib/aws/lambda/consume.js.map +1 -0
  105. package/lib/aws/lambda/function.d.ts +41 -0
  106. package/lib/aws/lambda/function.d.ts.map +1 -0
  107. package/lib/aws/lambda/function.handler.d.ts +7 -0
  108. package/lib/aws/lambda/function.handler.d.ts.map +1 -0
  109. package/lib/aws/lambda/function.handler.js +8 -0
  110. package/lib/aws/lambda/function.handler.js.map +1 -0
  111. package/lib/aws/lambda/function.invoke.d.ts +10 -0
  112. package/lib/aws/lambda/function.invoke.d.ts.map +1 -0
  113. package/lib/aws/lambda/function.invoke.js +31 -0
  114. package/lib/aws/lambda/function.invoke.js.map +1 -0
  115. package/lib/aws/lambda/function.js +3 -0
  116. package/lib/aws/lambda/function.js.map +1 -0
  117. package/lib/aws/lambda/function.provider.d.ts +9 -0
  118. package/lib/aws/lambda/function.provider.d.ts.map +1 -0
  119. package/lib/aws/lambda/function.provider.js +465 -0
  120. package/lib/aws/lambda/function.provider.js.map +1 -0
  121. package/lib/aws/lambda/index.d.ts +8 -0
  122. package/lib/aws/lambda/index.d.ts.map +1 -0
  123. package/lib/aws/lambda/index.js +9 -0
  124. package/lib/aws/lambda/index.js.map +1 -0
  125. package/lib/aws/lambda/serve.d.ts +14 -0
  126. package/lib/aws/lambda/serve.d.ts.map +1 -0
  127. package/lib/aws/lambda/serve.js +7 -0
  128. package/lib/aws/lambda/serve.js.map +1 -0
  129. package/lib/aws/parse-ini.d.ts +4 -0
  130. package/lib/aws/parse-ini.d.ts.map +1 -0
  131. package/lib/aws/parse-ini.js +67 -0
  132. package/lib/aws/parse-ini.js.map +1 -0
  133. package/lib/aws/profile.d.ts +6 -0
  134. package/lib/aws/profile.d.ts.map +1 -0
  135. package/lib/aws/profile.js +4 -0
  136. package/lib/aws/profile.js.map +1 -0
  137. package/lib/aws/region.d.ts +19 -0
  138. package/lib/aws/region.d.ts.map +1 -0
  139. package/lib/aws/region.js +21 -0
  140. package/lib/aws/region.js.map +1 -0
  141. package/lib/aws/s3.d.ts +8 -0
  142. package/lib/aws/s3.d.ts.map +1 -0
  143. package/lib/aws/s3.js +7 -0
  144. package/lib/aws/s3.js.map +1 -0
  145. package/lib/aws/sqs/client.d.ts +12 -0
  146. package/lib/aws/sqs/client.d.ts.map +1 -0
  147. package/lib/aws/sqs/client.js +11 -0
  148. package/lib/aws/sqs/client.js.map +1 -0
  149. package/lib/aws/sqs/index.d.ts +7 -0
  150. package/lib/aws/sqs/index.d.ts.map +1 -0
  151. package/lib/aws/sqs/index.js +7 -0
  152. package/lib/aws/sqs/index.js.map +1 -0
  153. package/lib/aws/sqs/queue.consume.d.ts +12 -0
  154. package/lib/aws/sqs/queue.consume.d.ts.map +1 -0
  155. package/lib/aws/sqs/queue.consume.js +3 -0
  156. package/lib/aws/sqs/queue.consume.js.map +1 -0
  157. package/lib/aws/sqs/queue.d.ts +79 -0
  158. package/lib/aws/sqs/queue.d.ts.map +1 -0
  159. package/lib/aws/sqs/queue.event-source.d.ts +20 -0
  160. package/lib/aws/sqs/queue.event-source.d.ts.map +1 -0
  161. package/lib/aws/sqs/queue.event-source.js +148 -0
  162. package/lib/aws/sqs/queue.event-source.js.map +1 -0
  163. package/lib/aws/sqs/queue.js +3 -0
  164. package/lib/aws/sqs/queue.js.map +1 -0
  165. package/lib/aws/sqs/queue.provider.d.ts +7 -0
  166. package/lib/aws/sqs/queue.provider.d.ts.map +1 -0
  167. package/lib/aws/sqs/queue.provider.js +79 -0
  168. package/lib/aws/sqs/queue.provider.js.map +1 -0
  169. package/lib/aws/sqs/queue.send-message.d.ts +11 -0
  170. package/lib/aws/sqs/queue.send-message.d.ts.map +1 -0
  171. package/lib/aws/sqs/queue.send-message.js +32 -0
  172. package/lib/aws/sqs/queue.send-message.js.map +1 -0
  173. package/lib/aws/sts.d.ts +8 -0
  174. package/lib/aws/sts.d.ts.map +1 -0
  175. package/lib/aws/sts.js +7 -0
  176. package/lib/aws/sts.js.map +1 -0
  177. package/lib/aws/zip.d.ts +3 -0
  178. package/lib/aws/zip.d.ts.map +1 -0
  179. package/lib/aws/zip.js +12 -0
  180. package/lib/aws/zip.js.map +1 -0
  181. package/lib/binding.d.ts +70 -22
  182. package/lib/binding.d.ts.map +1 -1
  183. package/lib/binding.js.map +1 -1
  184. package/lib/capability.d.ts +38 -0
  185. package/lib/capability.d.ts.map +1 -1
  186. package/lib/cli/approve.d.ts +4 -0
  187. package/lib/cli/approve.d.ts.map +1 -0
  188. package/lib/cli/approve.js +18 -0
  189. package/lib/cli/approve.js.map +1 -0
  190. package/lib/cli/clack.d.ts +14 -0
  191. package/lib/cli/clack.d.ts.map +1 -0
  192. package/lib/cli/clack.js +12 -0
  193. package/lib/cli/clack.js.map +1 -0
  194. package/lib/cli/components/ApprovePlan.d.ts +8 -0
  195. package/lib/cli/components/ApprovePlan.d.ts.map +1 -0
  196. package/lib/cli/components/ApprovePlan.js +30 -0
  197. package/lib/cli/components/ApprovePlan.js.map +1 -0
  198. package/lib/cli/components/Plan.d.ts +7 -0
  199. package/lib/cli/components/Plan.d.ts.map +1 -0
  200. package/lib/cli/components/Plan.js +100 -0
  201. package/lib/cli/components/Plan.js.map +1 -0
  202. package/lib/cli/components/PlanProgress.d.ts +9 -0
  203. package/lib/cli/components/PlanProgress.d.ts.map +1 -0
  204. package/lib/cli/components/PlanProgress.js +166 -0
  205. package/lib/cli/components/PlanProgress.js.map +1 -0
  206. package/lib/cli/index.d.ts +449 -0
  207. package/lib/cli/index.d.ts.map +1 -0
  208. package/lib/cli/index.js +39912 -0
  209. package/lib/cli/index.js.map +1 -0
  210. package/lib/cli/main.d.ts +2 -0
  211. package/lib/cli/main.d.ts.map +1 -0
  212. package/lib/cli/main.js +1 -0
  213. package/lib/cli/main.js.map +1 -0
  214. package/lib/cli/plan.d.ts +13 -0
  215. package/lib/cli/plan.d.ts.map +1 -0
  216. package/lib/cli/plan.js +1 -0
  217. package/lib/cli/plan.js.map +1 -0
  218. package/lib/cli/progress.d.ts +7 -0
  219. package/lib/cli/progress.d.ts.map +1 -0
  220. package/lib/cli/progress.js +30 -0
  221. package/lib/cli/progress.js.map +1 -0
  222. package/lib/cli/spinner.d.ts +2 -0
  223. package/lib/cli/spinner.d.ts.map +1 -0
  224. package/lib/cli/spinner.js +13 -0
  225. package/lib/cli/spinner.js.map +1 -0
  226. package/lib/cloudflare/api.d.ts +36 -0
  227. package/lib/cloudflare/api.d.ts.map +1 -0
  228. package/lib/cloudflare/api.js +99 -0
  229. package/lib/cloudflare/api.js.map +1 -0
  230. package/lib/cloudflare/context.d.ts +27 -0
  231. package/lib/cloudflare/context.d.ts.map +1 -0
  232. package/lib/cloudflare/context.js +24 -0
  233. package/lib/cloudflare/context.js.map +1 -0
  234. package/lib/cloudflare/index.d.ts +6 -0
  235. package/lib/cloudflare/index.d.ts.map +1 -0
  236. package/lib/cloudflare/index.js +5 -0
  237. package/lib/cloudflare/index.js.map +1 -0
  238. package/lib/cloudflare/kv/index.d.ts +4 -0
  239. package/lib/cloudflare/kv/index.d.ts.map +1 -0
  240. package/lib/cloudflare/kv/index.js +4 -0
  241. package/lib/cloudflare/kv/index.js.map +1 -0
  242. package/lib/cloudflare/kv/namespace.binding.d.ts +8 -0
  243. package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -0
  244. package/lib/cloudflare/kv/namespace.binding.js +15 -0
  245. package/lib/cloudflare/kv/namespace.binding.js.map +1 -0
  246. package/lib/cloudflare/kv/namespace.client.d.ts +11 -0
  247. package/lib/cloudflare/kv/namespace.client.d.ts.map +1 -0
  248. package/lib/cloudflare/kv/namespace.client.js +31 -0
  249. package/lib/cloudflare/kv/namespace.client.js.map +1 -0
  250. package/lib/cloudflare/kv/namespace.d.ts +23 -0
  251. package/lib/cloudflare/kv/namespace.d.ts.map +1 -0
  252. package/lib/cloudflare/kv/namespace.js +3 -0
  253. package/lib/cloudflare/kv/namespace.js.map +1 -0
  254. package/lib/cloudflare/kv/namespace.provider.d.ts +5 -0
  255. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -0
  256. package/lib/cloudflare/kv/namespace.provider.js +80 -0
  257. package/lib/cloudflare/kv/namespace.provider.js.map +1 -0
  258. package/lib/cloudflare/live.d.ts +11 -0
  259. package/lib/cloudflare/live.d.ts.map +1 -0
  260. package/lib/cloudflare/live.js +18 -0
  261. package/lib/cloudflare/live.js.map +1 -0
  262. package/lib/cloudflare/r2/bucket.binding.d.ts +8 -0
  263. package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -0
  264. package/lib/cloudflare/r2/bucket.binding.js +18 -0
  265. package/lib/cloudflare/r2/bucket.binding.js.map +1 -0
  266. package/lib/cloudflare/r2/bucket.client.d.ts +8 -0
  267. package/lib/cloudflare/r2/bucket.client.d.ts.map +1 -0
  268. package/lib/cloudflare/r2/bucket.client.js +9 -0
  269. package/lib/cloudflare/r2/bucket.client.js.map +1 -0
  270. package/lib/cloudflare/r2/bucket.d.ts +32 -0
  271. package/lib/cloudflare/r2/bucket.d.ts.map +1 -0
  272. package/lib/cloudflare/r2/bucket.del.d.ts +4 -0
  273. package/lib/cloudflare/r2/bucket.del.d.ts.map +1 -0
  274. package/lib/cloudflare/r2/bucket.del.js +7 -0
  275. package/lib/cloudflare/r2/bucket.del.js.map +1 -0
  276. package/lib/cloudflare/r2/bucket.get.d.ts +5 -0
  277. package/lib/cloudflare/r2/bucket.get.d.ts.map +1 -0
  278. package/lib/cloudflare/r2/bucket.get.js +7 -0
  279. package/lib/cloudflare/r2/bucket.get.js.map +1 -0
  280. package/lib/cloudflare/r2/bucket.head.d.ts +4 -0
  281. package/lib/cloudflare/r2/bucket.head.d.ts.map +1 -0
  282. package/lib/cloudflare/r2/bucket.head.js +7 -0
  283. package/lib/cloudflare/r2/bucket.head.js.map +1 -0
  284. package/lib/cloudflare/r2/bucket.js +3 -0
  285. package/lib/cloudflare/r2/bucket.js.map +1 -0
  286. package/lib/cloudflare/r2/bucket.list.d.ts +5 -0
  287. package/lib/cloudflare/r2/bucket.list.d.ts.map +1 -0
  288. package/lib/cloudflare/r2/bucket.list.js +7 -0
  289. package/lib/cloudflare/r2/bucket.list.js.map +1 -0
  290. package/lib/cloudflare/r2/bucket.multipart.d.ts +19 -0
  291. package/lib/cloudflare/r2/bucket.multipart.d.ts.map +1 -0
  292. package/lib/cloudflare/r2/bucket.multipart.js +25 -0
  293. package/lib/cloudflare/r2/bucket.multipart.js.map +1 -0
  294. package/lib/cloudflare/r2/bucket.provider.d.ts +5 -0
  295. package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -0
  296. package/lib/cloudflare/r2/bucket.provider.js +66 -0
  297. package/lib/cloudflare/r2/bucket.provider.js.map +1 -0
  298. package/lib/cloudflare/r2/bucket.put.d.ts +6 -0
  299. package/lib/cloudflare/r2/bucket.put.d.ts.map +1 -0
  300. package/lib/cloudflare/r2/bucket.put.js +8 -0
  301. package/lib/cloudflare/r2/bucket.put.js.map +1 -0
  302. package/lib/cloudflare/r2/index.d.ts +10 -0
  303. package/lib/cloudflare/r2/index.d.ts.map +1 -0
  304. package/lib/cloudflare/r2/index.js +10 -0
  305. package/lib/cloudflare/r2/index.js.map +1 -0
  306. package/lib/cloudflare/stream.d.ts +10 -0
  307. package/lib/cloudflare/stream.d.ts.map +1 -0
  308. package/lib/cloudflare/stream.js +16 -0
  309. package/lib/cloudflare/stream.js.map +1 -0
  310. package/lib/cloudflare/worker/assets.fetch.d.ts +8 -0
  311. package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -0
  312. package/lib/cloudflare/worker/assets.fetch.js +11 -0
  313. package/lib/cloudflare/worker/assets.fetch.js.map +1 -0
  314. package/lib/cloudflare/worker/assets.provider.d.ts +66 -0
  315. package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -0
  316. package/lib/cloudflare/worker/assets.provider.js +145 -0
  317. package/lib/cloudflare/worker/assets.provider.js.map +1 -0
  318. package/lib/cloudflare/worker/index.d.ts +6 -0
  319. package/lib/cloudflare/worker/index.d.ts.map +1 -0
  320. package/lib/cloudflare/worker/index.js +5 -0
  321. package/lib/cloudflare/worker/index.js.map +1 -0
  322. package/lib/cloudflare/worker/worker.d.ts +67 -0
  323. package/lib/cloudflare/worker/worker.d.ts.map +1 -0
  324. package/lib/cloudflare/worker/worker.handler.d.ts +11 -0
  325. package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -0
  326. package/lib/cloudflare/worker/worker.handler.js +15 -0
  327. package/lib/cloudflare/worker/worker.handler.js.map +1 -0
  328. package/lib/cloudflare/worker/worker.js +4 -0
  329. package/lib/cloudflare/worker/worker.js.map +1 -0
  330. package/lib/cloudflare/worker/worker.provider.d.ts +10 -0
  331. package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -0
  332. package/lib/cloudflare/worker/worker.provider.js +193 -0
  333. package/lib/cloudflare/worker/worker.provider.js.map +1 -0
  334. package/lib/cloudflare/worker/worker.serve.d.ts +39 -0
  335. package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -0
  336. package/lib/cloudflare/worker/worker.serve.js +4 -0
  337. package/lib/cloudflare/worker/worker.serve.js.map +1 -0
  338. package/lib/destroy.d.ts +1 -3
  339. package/lib/destroy.d.ts.map +1 -1
  340. package/lib/destroy.js +5 -0
  341. package/lib/destroy.js.map +1 -1
  342. package/lib/dot-alchemy.d.ts +3 -2
  343. package/lib/dot-alchemy.d.ts.map +1 -1
  344. package/lib/dot-alchemy.js +3 -2
  345. package/lib/dot-alchemy.js.map +1 -1
  346. package/lib/esbuild.d.ts +28 -0
  347. package/lib/esbuild.d.ts.map +1 -0
  348. package/lib/esbuild.js +63 -0
  349. package/lib/esbuild.js.map +1 -0
  350. package/lib/index.d.ts +1 -0
  351. package/lib/index.d.ts.map +1 -1
  352. package/lib/index.js +4 -0
  353. package/lib/index.js.map +1 -1
  354. package/lib/plan.d.ts +19 -8
  355. package/lib/plan.d.ts.map +1 -1
  356. package/lib/plan.js +144 -72
  357. package/lib/plan.js.map +1 -1
  358. package/lib/policy.d.ts +19 -1
  359. package/lib/policy.d.ts.map +1 -1
  360. package/lib/policy.js +10 -1
  361. package/lib/policy.js.map +1 -1
  362. package/lib/provider.d.ts +2 -2
  363. package/lib/provider.d.ts.map +1 -1
  364. package/lib/resource.d.ts +2 -10
  365. package/lib/resource.d.ts.map +1 -1
  366. package/lib/resource.js +1 -0
  367. package/lib/resource.js.map +1 -1
  368. package/lib/runtime.d.ts +1 -1
  369. package/lib/runtime.d.ts.map +1 -1
  370. package/lib/schema.d.ts +37 -0
  371. package/lib/schema.d.ts.map +1 -0
  372. package/lib/schema.js +61 -0
  373. package/lib/schema.js.map +1 -0
  374. package/lib/sha256.d.ts +5 -0
  375. package/lib/sha256.d.ts.map +1 -0
  376. package/lib/sha256.js +16 -0
  377. package/lib/sha256.js.map +1 -0
  378. package/lib/state.d.ts +3 -2
  379. package/lib/state.d.ts.map +1 -1
  380. package/lib/state.js +3 -2
  381. package/lib/state.js.map +1 -1
  382. package/lib/tags.d.ts +17 -0
  383. package/lib/tags.d.ts.map +1 -0
  384. package/lib/tags.js +22 -0
  385. package/lib/tags.js.map +1 -0
  386. package/lib/test.d.ts +14 -0
  387. package/lib/test.d.ts.map +1 -0
  388. package/lib/test.js +28 -0
  389. package/lib/test.js.map +1 -0
  390. package/lib/tsconfig.test.tsbuildinfo +1 -0
  391. package/lib/type.d.ts +3 -0
  392. package/lib/type.d.ts.map +1 -0
  393. package/lib/type.js +3 -0
  394. package/lib/type.js.map +1 -0
  395. package/package.json +115 -3
  396. package/src/app.ts +8 -7
  397. package/src/apply.ts +251 -93
  398. package/src/aws/account.ts +37 -0
  399. package/src/aws/arn.ts +1 -0
  400. package/src/aws/assets.ts +8 -0
  401. package/src/aws/bundle.ts +5 -0
  402. package/src/aws/client.ts +47 -0
  403. package/src/aws/credentials.ts +409 -0
  404. package/src/aws/dynamodb/attribute-value.ts +240 -0
  405. package/src/aws/dynamodb/client.ts +20 -0
  406. package/src/aws/dynamodb/expr.ts +90 -0
  407. package/src/aws/dynamodb/index.ts +12 -0
  408. package/src/aws/dynamodb/projection.ts +159 -0
  409. package/src/aws/dynamodb/secondary-index.ts +45 -0
  410. package/src/aws/dynamodb/table.get-item.ts +177 -0
  411. package/src/aws/dynamodb/table.provider.ts +280 -0
  412. package/src/aws/dynamodb/table.ts +156 -0
  413. package/src/aws/ec2/client.ts +20 -0
  414. package/src/aws/ec2/index.ts +3 -0
  415. package/src/aws/ec2/vpc.provider.ts +285 -0
  416. package/src/aws/ec2/vpc.ts +152 -0
  417. package/src/aws/iam.ts +30 -0
  418. package/src/aws/index.ts +54 -0
  419. package/src/aws/lambda/client.ts +14 -0
  420. package/src/aws/lambda/consume.ts +63 -0
  421. package/src/aws/lambda/function.handler.ts +30 -0
  422. package/src/aws/lambda/function.invoke.ts +40 -0
  423. package/src/aws/lambda/function.provider.ts +655 -0
  424. package/src/aws/lambda/function.ts +45 -0
  425. package/src/aws/lambda/index.ts +9 -0
  426. package/src/aws/lambda/serve.ts +29 -0
  427. package/src/aws/parse-ini.ts +80 -0
  428. package/src/aws/profile.ts +6 -0
  429. package/src/aws/region.ts +37 -0
  430. package/src/aws/s3.ts +10 -0
  431. package/src/aws/sqs/client.ts +20 -0
  432. package/src/aws/sqs/index.ts +6 -0
  433. package/src/aws/sqs/queue.consume.ts +13 -0
  434. package/src/aws/sqs/queue.event-source.ts +253 -0
  435. package/src/aws/sqs/queue.provider.ts +94 -0
  436. package/src/aws/sqs/queue.send-message.ts +51 -0
  437. package/src/aws/sqs/queue.ts +86 -0
  438. package/src/aws/sts.ts +13 -0
  439. package/src/aws/zip.ts +17 -0
  440. package/src/binding.ts +121 -25
  441. package/src/capability.ts +44 -0
  442. package/src/cli/approve.tsx +30 -0
  443. package/src/cli/clack.ts +22 -0
  444. package/src/cli/components/ApprovePlan.tsx +44 -0
  445. package/src/cli/components/Plan.tsx +154 -0
  446. package/src/cli/components/PlanProgress.tsx +206 -0
  447. package/src/cli/index.ts +6 -0
  448. package/src/cli/main.ts +0 -0
  449. package/src/cli/plan.ts +16 -0
  450. package/src/cli/progress.tsx +46 -0
  451. package/src/cli/spinner.ts +14 -0
  452. package/src/cloudflare/api.ts +152 -0
  453. package/src/cloudflare/context.ts +49 -0
  454. package/src/cloudflare/index.ts +6 -0
  455. package/src/cloudflare/kv/index.ts +3 -0
  456. package/src/cloudflare/kv/namespace.binding.ts +25 -0
  457. package/src/cloudflare/kv/namespace.client.ts +70 -0
  458. package/src/cloudflare/kv/namespace.provider.ts +99 -0
  459. package/src/cloudflare/kv/namespace.ts +29 -0
  460. package/src/cloudflare/live.ts +38 -0
  461. package/src/cloudflare/r2/bucket.binding.ts +27 -0
  462. package/src/cloudflare/r2/bucket.client.ts +22 -0
  463. package/src/cloudflare/r2/bucket.del.ts +11 -0
  464. package/src/cloudflare/r2/bucket.get.ts +13 -0
  465. package/src/cloudflare/r2/bucket.head.ts +11 -0
  466. package/src/cloudflare/r2/bucket.list.ts +12 -0
  467. package/src/cloudflare/r2/bucket.multipart.ts +55 -0
  468. package/src/cloudflare/r2/bucket.provider.ts +83 -0
  469. package/src/cloudflare/r2/bucket.put.ts +17 -0
  470. package/src/cloudflare/r2/bucket.ts +38 -0
  471. package/src/cloudflare/r2/index.ts +9 -0
  472. package/src/cloudflare/stream.ts +21 -0
  473. package/src/cloudflare/worker/assets.fetch.ts +27 -0
  474. package/src/cloudflare/worker/assets.provider.ts +249 -0
  475. package/src/cloudflare/worker/index.ts +6 -0
  476. package/src/cloudflare/worker/worker.handler.ts +39 -0
  477. package/src/cloudflare/worker/worker.provider.ts +246 -0
  478. package/src/cloudflare/worker/worker.serve.ts +19 -0
  479. package/src/cloudflare/worker/worker.ts +76 -0
  480. package/src/destroy.ts +6 -3
  481. package/src/dot-alchemy.ts +3 -2
  482. package/src/esbuild.ts +98 -0
  483. package/src/index.ts +5 -0
  484. package/src/plan.ts +233 -120
  485. package/src/policy.ts +55 -2
  486. package/src/provider.ts +2 -2
  487. package/src/resource.ts +3 -2
  488. package/src/runtime.ts +1 -1
  489. package/src/schema.ts +102 -0
  490. package/src/sha256.ts +23 -0
  491. package/src/state.ts +3 -2
  492. package/src/tags.ts +38 -0
  493. package/src/test.ts +71 -0
  494. package/src/type.ts +2 -0
package/src/esbuild.ts ADDED
@@ -0,0 +1,98 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Data from "effect/Data";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Queue from "effect/Queue";
6
+ import type * as Scope from "effect/Scope";
7
+ import type esbuild from "esbuild";
8
+
9
+ export class ESBuild extends Context.Tag("ESBuild")<
10
+ ESBuild,
11
+ {
12
+ readonly build: <T extends esbuild.BuildOptions>(
13
+ options: esbuild.SameShape<esbuild.BuildOptions, T>,
14
+ ) => Effect.Effect<esbuild.BuildResult<T>, ESBuildError>;
15
+ readonly context: <T extends esbuild.BuildOptions>(
16
+ options: esbuild.SameShape<esbuild.BuildOptions, T>,
17
+ ) => Effect.Effect<
18
+ {
19
+ queue: Queue.Queue<esbuild.BuildResult<T>>;
20
+ rebuild: () => Effect.Effect<
21
+ esbuild.BuildResult<T>,
22
+ ESBuildError,
23
+ never
24
+ >;
25
+ },
26
+ ESBuildError,
27
+ Scope.Scope
28
+ >;
29
+ }
30
+ >() {}
31
+
32
+ export const layer = () =>
33
+ Layer.effect(
34
+ ESBuild,
35
+ Effect.gen(function* () {
36
+ const esbuild = yield* Effect.promise(() => import("esbuild"));
37
+ return ESBuild.of({
38
+ build: Effect.fnUntraced(function* (options) {
39
+ return yield* Effect.tryPromise({
40
+ try: () => esbuild.build(options),
41
+ catch: ESBuildError.map,
42
+ });
43
+ }),
44
+ context: Effect.fnUntraced(function* (options) {
45
+ const queue = yield* Queue.unbounded<esbuild.BuildResult>();
46
+ const context = yield* Effect.tryPromise({
47
+ try: async () =>
48
+ esbuild.context({
49
+ ...options,
50
+ plugins: [
51
+ ...(options.plugins ?? []),
52
+ {
53
+ name: "queue",
54
+ setup: (build) => {
55
+ build.onEnd((result) => {
56
+ Queue.unsafeOffer(queue, result as esbuild.BuildResult);
57
+ });
58
+ },
59
+ },
60
+ ],
61
+ }),
62
+ catch: ESBuildError.map,
63
+ });
64
+ yield* Effect.addFinalizer(() =>
65
+ Effect.promise(() => context.dispose()),
66
+ );
67
+ yield* Effect.tryPromise({
68
+ try: () => context.watch(),
69
+ catch: ESBuildError.map,
70
+ });
71
+ return {
72
+ queue,
73
+ rebuild: Effect.fnUntraced(function* () {
74
+ return yield* Effect.tryPromise({
75
+ try: (): Promise<esbuild.BuildResult> => context.rebuild(),
76
+ catch: ESBuildError.map,
77
+ });
78
+ }),
79
+ };
80
+ }),
81
+ });
82
+ }),
83
+ );
84
+
85
+ export class ESBuildError extends Data.TaggedError("ESBuildError")<{
86
+ message: string;
87
+ errors: esbuild.Message[];
88
+ messages: esbuild.Message[];
89
+ }> {
90
+ static map(error: unknown): ESBuildError {
91
+ const cause = error as esbuild.BuildFailure;
92
+ return new ESBuildError({
93
+ message: cause.message,
94
+ errors: cause.errors,
95
+ messages: cause.warnings,
96
+ });
97
+ }
98
+ }
package/src/index.ts CHANGED
@@ -14,4 +14,9 @@ export * from "./provider.ts";
14
14
  export * from "./resource.ts";
15
15
  export * from "./runtime.ts";
16
16
  export * from "./service.ts";
17
+ export * from "./type.ts";
18
+
19
+ // export * as AWS from "./aws/index.ts";
20
+ // export * as CLI from "./cli/index.ts";
21
+ // export * as Cloudflare from "./cloudflare/index.ts";
17
22
  export * as State from "./state.ts";
package/src/plan.ts CHANGED
@@ -1,13 +1,19 @@
1
+ import * as Context from "effect/Context";
1
2
  import * as Data from "effect/Data";
2
3
  import * as Effect from "effect/Effect";
3
- import type { AnyBinding } from "./binding.ts";
4
+ import { omit } from "effect/Struct";
5
+ import type {
6
+ AnyBinding,
7
+ BindingDiffProps,
8
+ BindingService,
9
+ } from "./binding.ts";
4
10
  import type { Capability } from "./capability.ts";
5
11
  import type { Phase } from "./phase.ts";
6
12
  import type { Instance } from "./policy.ts";
7
- import { type ProviderService } from "./provider.ts";
13
+ import { type Diff, type ProviderService } from "./provider.ts";
8
14
  import type { Resource, ResourceTags } from "./resource.ts";
9
- import { isService, type Service } from "./service.ts";
10
- import { State, type ResourceState } from "./state.ts";
15
+ import { isService, type IService, type Service } from "./service.ts";
16
+ import { State, StateStoreError, type ResourceState } from "./state.ts";
11
17
 
12
18
  export type PlanError = never;
13
19
 
@@ -26,23 +32,34 @@ export const isBindNode = (node: any): node is BindNode => {
26
32
  */
27
33
  export type BindNode<B extends AnyBinding = AnyBinding> =
28
34
  | Attach<B>
35
+ | Reattach<B>
29
36
  | Detach<B>
30
37
  | NoopBind<B>;
31
38
 
32
39
  export type Attach<B extends AnyBinding = AnyBinding> = {
33
40
  action: "attach";
34
41
  binding: B;
35
- olds?: BindNode;
42
+ olds: BindNode | undefined;
43
+ attr: B["attr"] | undefined;
44
+ };
45
+
46
+ export type Reattach<B extends AnyBinding = AnyBinding> = {
47
+ action: "reattach";
48
+ binding: B;
49
+ olds: BindNode;
50
+ attr: B["attr"];
36
51
  };
37
52
 
38
53
  export type Detach<B extends AnyBinding = AnyBinding> = {
39
54
  action: "detach";
40
55
  binding: B;
56
+ attr: B["attr"] | undefined;
41
57
  };
42
58
 
43
59
  export type NoopBind<B extends AnyBinding = AnyBinding> = {
44
60
  action: "noop";
45
61
  binding: B;
62
+ attr: B["attr"];
46
63
  };
47
64
 
48
65
  export const isCRUD = (node: any): node is CRUD => {
@@ -144,19 +161,19 @@ export type Plan = {
144
161
 
145
162
  export const plan = <
146
163
  const Phase extends "update" | "destroy",
147
- const Services extends Service[],
164
+ const Resources extends (Service | Resource)[],
148
165
  >({
149
166
  phase,
150
- services,
167
+ resources,
151
168
  }: {
152
169
  phase: Phase;
153
- services: Services;
170
+ resources: Resources;
154
171
  }) => {
172
+ type Services = Extract<Resources[number], IService>[];
155
173
  type ServiceIDs = Services[number]["id"];
156
174
  type ServiceHosts = {
157
175
  [ID in ServiceIDs]: Extract<Services[number], Service<Extract<ID, string>>>;
158
176
  };
159
-
160
177
  type UpstreamTags = {
161
178
  [ID in ServiceIDs]: ServiceHosts[ID]["props"]["bindings"]["tags"][number];
162
179
  }[ServiceIDs];
@@ -166,12 +183,17 @@ export const plan = <
166
183
  Resource
167
184
  >;
168
185
  }[ServiceIDs];
169
- type Resources = {
186
+ type ExplicitResources = Resources[number];
187
+ type ResourceGraph = {
170
188
  [ID in ServiceIDs]: Apply<Extract<Instance<ServiceHosts[ID]>, Resource>>;
171
189
  } & {
172
190
  [ID in UpstreamResources["id"]]: Apply<
173
191
  Extract<UpstreamResources, { id: ID }>
174
192
  >;
193
+ } & {
194
+ [ID in ExplicitResources["id"]]: Apply<
195
+ Extract<ExplicitResources, { id: ID }>
196
+ >;
175
197
  };
176
198
 
177
199
  return Effect.gen(function* () {
@@ -190,21 +212,10 @@ export const plan = <
190
212
  bindings: BindNode[];
191
213
  } => !!resource?.bindings,
192
214
  )
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
- // }),
215
+ .flatMap((resource) =>
216
+ resource.bindings.flatMap(({ binding }) => [
217
+ [binding.capability.resource.id, binding.capability.resource],
218
+ ]),
208
219
  )
209
220
  .reduce(
210
221
  (acc, [id, resourceId]) => ({
@@ -214,16 +225,18 @@ export const plan = <
214
225
  {} as Record<string, string[]>,
215
226
  );
216
227
 
217
- const resources =
228
+ const resourceGraph =
218
229
  phase === "update"
219
230
  ? (Object.fromEntries(
220
231
  (yield* Effect.all(
221
- services
222
- .flatMap((service) => [
223
- ...service.props.bindings.capabilities.map(
224
- (cap: Capability) => cap.resource as Resource,
225
- ),
226
- service,
232
+ resources
233
+ .flatMap((resource) => [
234
+ ...(isService(resource)
235
+ ? resource.props.bindings.capabilities.map(
236
+ (cap: Capability) => cap.resource as Resource,
237
+ )
238
+ : []),
239
+ resource,
227
240
  ])
228
241
  .filter(
229
242
  (node, i, arr) =>
@@ -240,16 +253,22 @@ export const plan = <
240
253
  const oldState = yield* state.get(id);
241
254
  const provider = yield* resource.provider.tag;
242
255
 
243
- const bindings = diffBindings(
244
- oldState,
245
- isService(node)
246
- ? (
256
+ const bindings = isService(node)
257
+ ? yield* diffBindings({
258
+ oldState,
259
+ bindings: (
247
260
  node.props.bindings as unknown as {
248
261
  bindings: AnyBinding[];
249
262
  }
250
- ).bindings
251
- : [],
252
- );
263
+ ).bindings,
264
+ target: {
265
+ id: node.id,
266
+ props: node.props,
267
+ oldAttr: oldState?.output,
268
+ oldProps: oldState?.props,
269
+ },
270
+ })
271
+ : []; // TODO(sam): return undefined instead of empty array
253
272
 
254
273
  if (
255
274
  oldState === undefined ||
@@ -264,47 +283,42 @@ export const plan = <
264
283
  // phantom
265
284
  attributes: undefined!,
266
285
  });
267
- } else if (provider.diff) {
268
- const diff = yield* provider.diff({
269
- id,
286
+ }
287
+
288
+ const diff = provider.diff
289
+ ? yield* provider.diff({
290
+ id,
291
+ olds: oldState.props,
292
+ news,
293
+ output: oldState.output,
294
+ })
295
+ : undefined;
296
+
297
+ if (!diff && arePropsChanged(oldState, resource.props)) {
298
+ return Node<Update<Resource>>({
299
+ action: "update",
270
300
  olds: oldState.props,
271
301
  news,
272
302
  output: oldState.output,
303
+ provider,
304
+ resource,
305
+ bindings,
306
+ // phantom
307
+ attributes: undefined!,
273
308
  });
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
- });
306
- }
307
- } else if (compare(oldState, resource.props)) {
309
+ } else if (diff?.action === "replace") {
310
+ return Node<Replace<Resource>>({
311
+ action: "replace",
312
+ olds: oldState.props,
313
+ news,
314
+ output: oldState.output,
315
+ provider,
316
+ resource,
317
+ bindings,
318
+ // phantom
319
+ attributes: undefined!,
320
+ });
321
+ } else if (diff?.action === "update") {
308
322
  return Node<Update<Resource>>({
309
323
  action: "update",
310
324
  olds: oldState.props,
@@ -335,7 +349,7 @@ export const plan = <
335
349
  (yield* Effect.all(
336
350
  (yield* state.list()).map(
337
351
  Effect.fn(function* (id) {
338
- if (id in resources) {
352
+ if (id in resourceGraph) {
339
353
  return;
340
354
  }
341
355
  const oldState = yield* state.get(id);
@@ -376,7 +390,9 @@ export const plan = <
376
390
  );
377
391
 
378
392
  for (const [resourceId, deletion] of Object.entries(deletions)) {
379
- const dependencies = deletion.downstream.filter((d) => d in resources);
393
+ const dependencies = deletion.downstream.filter(
394
+ (d) => d in resourceGraph,
395
+ );
380
396
  if (dependencies.length > 0) {
381
397
  return yield* Effect.fail(
382
398
  new DeleteResourceHasDownstreamDependencies({
@@ -390,17 +406,17 @@ export const plan = <
390
406
 
391
407
  return {
392
408
  phase,
393
- resources,
409
+ resources: resourceGraph,
394
410
  deletions,
395
411
  } satisfies Plan as Plan;
396
412
  }) as Effect.Effect<
397
413
  {
398
414
  phase: Phase;
399
415
  resources: {
400
- [ID in keyof Resources]: Resources[ID];
416
+ [ID in keyof ResourceGraph]: ResourceGraph[ID];
401
417
  };
402
418
  deletions: {
403
- [id in Exclude<string, keyof Resources>]?: Delete<Resource>;
419
+ [id in Exclude<string, keyof ResourceGraph>]?: Delete<Resource>;
404
420
  };
405
421
  },
406
422
  never,
@@ -416,55 +432,152 @@ class DeleteResourceHasDownstreamDependencies extends Data.TaggedError(
416
432
  dependencies: string[];
417
433
  }> {}
418
434
 
419
- const compare = <R extends Resource>(
420
- oldState: ResourceState | undefined,
421
- newState: R["props"],
422
- ) => JSON.stringify(oldState?.props) === JSON.stringify(newState);
423
-
424
- const diffBindings = (
435
+ const arePropsChanged = <R extends Resource>(
425
436
  oldState: ResourceState | undefined,
426
- bindings: AnyBinding[],
437
+ newProps: R["props"],
427
438
  ) => {
428
- const actions: BindNode[] = [];
439
+ return (
440
+ JSON.stringify(omit(oldState?.props ?? {}, "bindings")) !==
441
+ JSON.stringify(omit((newProps ?? {}) as any, "bindings"))
442
+ );
443
+ };
444
+
445
+ const diffBindings = Effect.fn(function* ({
446
+ oldState,
447
+ bindings,
448
+ target,
449
+ }: {
450
+ oldState: ResourceState | undefined;
451
+ bindings: AnyBinding[];
452
+ target: BindingDiffProps["target"];
453
+ }) {
454
+ // const actions: BindNode[] = [];
429
455
  const oldBindings = oldState?.bindings;
430
456
  const oldSids = new Set(
431
457
  oldBindings?.map(({ binding }) => binding.capability.sid),
432
458
  );
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
459
 
438
- const oldBinding = oldBindings?.find(
439
- ({ binding }) => binding.capability.sid === sid,
440
- );
441
- if (!oldBinding) {
442
- actions.push({
443
- action: "attach",
444
- binding,
460
+ const diffBinding: (
461
+ binding: AnyBinding,
462
+ ) => Effect.Effect<BindNode, StateStoreError, State> = Effect.fn(
463
+ function* (binding) {
464
+ const cap = binding.capability;
465
+ const sid = cap.sid ?? `${cap.action}:${cap.resource.ID}`;
466
+ // Find potential oldBinding for this sid
467
+ const oldBinding = oldBindings?.find(
468
+ ({ binding }) => binding.capability.sid === sid,
469
+ );
470
+ if (!oldBinding) {
471
+ return {
472
+ action: "attach",
473
+ binding,
474
+ attr: undefined,
475
+ olds: undefined,
476
+ } satisfies Attach<AnyBinding>;
477
+ }
478
+
479
+ const diff = yield* isBindingDiff({
480
+ target,
481
+ oldBinding,
482
+ newBinding: binding,
445
483
  });
446
- } else if (isBindingDiff(oldBinding, binding)) {
447
- actions.push({
448
- action: "attach",
484
+ // if (diff === false) {
485
+ // } else if (diff === true) {
486
+ // return {
487
+ // action: "attach",
488
+ // binding,
489
+ // olds: oldBinding,
490
+ // } satisfies Attach<AnyBinding>;
491
+ // }
492
+ if (diff.action === "replace") {
493
+ return yield* Effect.die(
494
+ new Error("Replace binding not yet supported"),
495
+ );
496
+ // TODO(sam): implement support for replacing bindings
497
+ // return {
498
+ // action: "replace",
499
+ // binding,
500
+ // olds: oldBinding,
501
+ // };
502
+ } else if (diff?.action === "update") {
503
+ return {
504
+ action: "reattach",
505
+ binding,
506
+ olds: oldBinding,
507
+ attr: oldBinding.attr,
508
+ } satisfies Reattach<AnyBinding>;
509
+ }
510
+ return {
511
+ action: "noop",
449
512
  binding,
450
- olds: oldBinding,
451
- });
452
- }
513
+ attr: oldBinding.attr,
514
+ } satisfies NoopBind<AnyBinding>;
515
+ },
516
+ );
517
+
518
+ return (yield* Effect.all(bindings.map(diffBinding))).filter(
519
+ (action): action is BindNode => action !== null,
520
+ );
521
+ });
522
+
523
+ const isBindingDiff = Effect.fn(function* ({
524
+ target,
525
+ oldBinding: { binding: oldBinding },
526
+ newBinding,
527
+ }: {
528
+ // TODO(sam): support binding to other Resources
529
+ target: BindingDiffProps["target"];
530
+ oldBinding: BindNode;
531
+ newBinding: AnyBinding;
532
+ }) {
533
+ const oldCap = oldBinding.capability;
534
+ const newCap = newBinding.capability;
535
+ if (
536
+ // if the binding provider has changed
537
+ oldBinding.tag !== newBinding.tag ||
538
+ // if it points to a totally different resource, we should replace
539
+ oldCap?.resource?.id !== newCap?.resource?.id ||
540
+ // if it is a different action
541
+ oldCap.action !== newCap.action
542
+ ) {
543
+ // then we must replace (we need to detach and attach with different bindings or to different resources)
544
+ return {
545
+ action: "replace",
546
+ } satisfies Diff;
453
547
  }
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
548
 
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;
549
+ const binding = newBinding as AnyBinding & {
550
+ // smuggled property (because it interacts poorly with inference)
551
+ Tag: Context.Tag<never, BindingService>;
552
+ };
553
+ const provider = yield* binding.Tag;
554
+ if (provider.diff) {
555
+ const state = yield* State;
556
+ const oldState = yield* state.get(oldCap.resource.id);
557
+ const diff = yield* provider.diff({
558
+ source: {
559
+ id: oldCap.resource.id,
560
+ props: newCap.resource.props,
561
+ oldProps: oldState?.props,
562
+ oldAttr: oldState?.output,
563
+ },
564
+ props: newBinding.props,
565
+ attr: oldBinding.attr,
566
+ target,
567
+ });
568
+
569
+ if (diff?.action === "update" || diff?.action === "replace") {
570
+ return diff;
571
+ }
572
+ }
573
+ return {
574
+ action:
575
+ oldBinding.capability.action !== newBinding.capability.action ||
576
+ oldBinding.capability?.resource?.id !==
577
+ newBinding.capability?.resource?.id
578
+ ? "update"
579
+ : "noop",
580
+ } as const;
581
+ });
469
582
  // TODO(sam): compare props
470
583
  // oldBinding.props !== newBinding.props;
package/src/policy.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as Context from "effect/Context";
2
2
  import * as Effect from "effect/Effect";
3
+ import * as S from "effect/Schema";
3
4
  import { type AnyBinding, type Bind } from "./binding.ts";
4
5
  import type { Capability } from "./capability.ts";
5
6
  import type { Runtime } from "./runtime.ts";
@@ -26,7 +27,11 @@ export interface Policy<
26
27
  /** Add more Capabilities to a Policy */
27
28
  and<B extends AnyBinding[]>(
28
29
  ...bindings: B
29
- ): Policy<F, B[number]["capability"] | Capabilities, Tags>;
30
+ ): Policy<
31
+ F,
32
+ B[number]["capability"] | Capabilities,
33
+ BindingTags<B[number]> | Exclude<Tags, unknown>
34
+ >;
30
35
  }
31
36
 
32
37
  export type $<T> = Instance<T>;
@@ -46,7 +51,7 @@ export function Policy<B extends AnyBinding[]>(
46
51
  >;
47
52
  export function Policy(...bindings: AnyBinding[]): any {
48
53
  return {
49
- runtime: bindings[0]["runtime"],
54
+ runtime: bindings[0]?.["runtime"],
50
55
  capabilities: bindings.map((b) => b.capability),
51
56
  tags: bindings.map((b) => Context.Tag(b.tag as any)()),
52
57
  bindings,
@@ -57,6 +62,54 @@ export function Policy(...bindings: AnyBinding[]): any {
57
62
  };
58
63
  }
59
64
 
65
+ export namespace Policy {
66
+ export interface AnyOf<in out T> {
67
+ readonly anyOf: T[];
68
+ }
69
+ type Generalize<T> = T extends S.Schema<infer U> ? U : T;
70
+
71
+ export const anyOf = <const T>(...anyOf: T[]): AnyOf<Generalize<T>> => ({
72
+ anyOf: anyOf as Generalize<T>[],
73
+ });
74
+
75
+ export const join = <
76
+ const Strings extends readonly string[],
77
+ const Delimiter extends string,
78
+ >(
79
+ strings: Strings,
80
+ delimiter: Delimiter,
81
+ ) => strings.join(delimiter) as Join<Strings, Delimiter>;
82
+
83
+ type ___ = Join<string[], ",">;
84
+ type Join<
85
+ T extends readonly string[],
86
+ Delimiter extends string,
87
+ > = T extends readonly [infer First extends string]
88
+ ? First
89
+ : T extends readonly [
90
+ infer First extends string,
91
+ ...infer Rest extends readonly string[],
92
+ ]
93
+ ? `${First}${Delimiter}${Join<Rest, Delimiter>}`
94
+ : T extends string[]
95
+ ? string
96
+ : "";
97
+
98
+ export type Constraint<T> = Pick<
99
+ T,
100
+ {
101
+ [k in keyof T]: T[k] extends never
102
+ ? never
103
+ : T[k] extends AnyOf<never>
104
+ ? never
105
+ : k;
106
+ }[keyof T]
107
+ >;
108
+
109
+ // TODO(sam): one day we might infer policies using a compiler plugin, this is a placeholder
110
+ export const infer = <T>(): T => undefined!;
111
+ }
112
+
60
113
  /** declare a Policy requiring Capabilities in some context */
61
114
  export const declare = <S extends Capability>() =>
62
115
  Effect.gen(function* () {}) as Effect.Effect<void, never, S>;