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/output.ts ADDED
@@ -0,0 +1,542 @@
1
+ import { pipe } from "effect";
2
+ import * as Data from "effect/Data";
3
+ import * as Effect from "effect/Effect";
4
+ import * as App from "./app.ts";
5
+ import { isPrimitive } from "./data.ts";
6
+ import type { From } from "./policy.ts";
7
+ import { getRefMetadata, isRef, ref as stageRef, type Ref } from "./ref.ts";
8
+ import type { AnyResource, Resource } from "./resource.ts";
9
+ import * as State from "./state.ts";
10
+ import type { IsAny, UnionToIntersection } from "./util.ts";
11
+
12
+ // a special symbol only used at runtime to probe the Output proxy
13
+ const ExprSymbol = Symbol.for("alchemy/Expr");
14
+
15
+ export const isOutput = (value: any): value is Output<any> =>
16
+ value &&
17
+ (typeof value === "object" || typeof value === "function") &&
18
+ ExprSymbol in value;
19
+
20
+ export const of = <R extends Resource>(
21
+ resource: Ref<R> | R,
22
+ ): Output.Of<R["attr"], From<R>> => {
23
+ if (isRef(resource)) {
24
+ const metadata = getRefMetadata(resource);
25
+ return new RefExpr(
26
+ metadata.stack,
27
+ metadata.stage,
28
+ metadata.resourceId,
29
+ ) as any;
30
+ }
31
+ return new ResourceExpr(resource) as any;
32
+ };
33
+
34
+ export const ref = <R extends Resource<string, string, any, any>>(
35
+ resourceId: R["id"],
36
+ options?: {
37
+ stage?: string;
38
+ stack?: string;
39
+ },
40
+ ) => of(stageRef({ resourceId, ...options }));
41
+
42
+ export interface Output<A = any, Src extends Resource = any, Req = any> {
43
+ readonly kind: string;
44
+ readonly src: Src;
45
+ readonly req: Req;
46
+ apply<B>(fn: (value: A) => B): Output.Of<B, Src, Req>;
47
+ effect<B, Req2>(
48
+ // Outputs are not allowed to fail, so we use never for the error type
49
+ fn: (value: A) => Effect.Effect<B, never, Req2>,
50
+ ): Output.Of<B, Src, Req | Req2>;
51
+ }
52
+
53
+ export declare namespace Output {
54
+ // TODO(sam): doesn't support disjunct unions very well
55
+ export type Of<A, Src extends Resource = any, Req = never> = [
56
+ Extract<A, object>,
57
+ ] extends [never]
58
+ ? Output<A, Src, Req>
59
+ : [Extract<A, any[]>] extends [never]
60
+ ? Object<
61
+ {
62
+ [attr in keyof A]: A[attr];
63
+ },
64
+ Src,
65
+ Req
66
+ >
67
+ : Array<Extract<A, any[]>, Src, Req>;
68
+ }
69
+
70
+ export type Object<A, Src extends Resource, Req = any> = Output<A, Src, Req> & {
71
+ [Prop in keyof Exclude<A, undefined>]-?: Output.Of<
72
+ Exclude<A, undefined>[Prop] | Extract<A, undefined>,
73
+ Src,
74
+ Req
75
+ >;
76
+ };
77
+
78
+ export type Array<A extends any[], Src extends Resource, Req = any> = Output<
79
+ A,
80
+ Src,
81
+ Req
82
+ > & {
83
+ [i in Extract<keyof A, number>]: Output.Of<A[i], Src, Req>;
84
+ };
85
+
86
+ export const isExpr = (value: any): value is Expr<any> =>
87
+ value &&
88
+ (typeof value === "object" || typeof value === "function") &&
89
+ ExprSymbol in value;
90
+
91
+ export type Expr<A = any, Src extends AnyResource = AnyResource, Req = any> =
92
+ | AllExpr<Expr<A, Src, Req>[]>
93
+ | ApplyExpr<any, A, Src, Req>
94
+ | EffectExpr<any, A, Src, Req>
95
+ | LiteralExpr<A>
96
+ | PropExpr<A, keyof A, Src, Req>
97
+ | ResourceExpr<A, Src, Req>
98
+ | RefExpr<A>;
99
+
100
+ const proxy = (self: any): any => {
101
+ const proxy = new Proxy(
102
+ Object.assign(() => {}, self),
103
+ {
104
+ has: (_, prop) => (prop === ExprSymbol ? true : prop in self),
105
+ get: (_, prop) =>
106
+ prop === Symbol.toPrimitive
107
+ ? (hint: string) => (hint === "string" ? self.toString() : self)
108
+ : prop === ExprSymbol
109
+ ? self
110
+ : isResourceExpr(self) && self.stables && prop in self.stables
111
+ ? self.stables[prop as keyof typeof self.stables]
112
+ : prop === "apply"
113
+ ? self[prop]
114
+ : prop in self
115
+ ? typeof self[prop as keyof typeof self] === "function" &&
116
+ !("kind" in self)
117
+ ? new PropExpr(proxy, prop as never)
118
+ : self[prop as keyof typeof self]
119
+ : new PropExpr(proxy, prop as never),
120
+ apply: (_, thisArg, args) => {
121
+ if (isPropExpr(self)) {
122
+ if (self.identifier === "apply") {
123
+ return new ApplyExpr(self.expr, args[0]);
124
+ } else if (self.identifier === "effect") {
125
+ return new EffectExpr(self.expr, args[0]);
126
+ }
127
+ }
128
+ return undefined;
129
+ },
130
+ },
131
+ );
132
+ return proxy;
133
+ };
134
+
135
+ export abstract class BaseExpr<A = any, Src extends Resource = any, Req = any>
136
+ implements Output<A, Src, Req>
137
+ {
138
+ declare readonly kind: any;
139
+ declare readonly src: Src;
140
+ declare readonly req: Req;
141
+ // we use a kind tag instead of instanceof to protect ourselves from duplicate alchemy-effect module imports
142
+ constructor() {}
143
+ public apply<B>(fn: (value: A) => B): Output.Of<B, Src> {
144
+ return new ApplyExpr(this as Expr<A, Src, Req>, fn) as any;
145
+ }
146
+ public effect<B, Req2>(
147
+ fn: (value: A) => Effect.Effect<B, never, Req2>,
148
+ ): Output.Of<B, Src, Req | Req2> {
149
+ return new EffectExpr(this as any, fn) as any;
150
+ }
151
+ public pipe(...fns: any[]): any {
152
+ // @ts-expect-error
153
+ return pipe(this, ...fns);
154
+ }
155
+ toString(): string {
156
+ return JSON.stringify(this, null, 2);
157
+ }
158
+ }
159
+
160
+ export const isResourceExpr = <
161
+ Value = any,
162
+ Src extends AnyResource = AnyResource,
163
+ Req = any,
164
+ >(
165
+ node: Expr<Value, Src, Req> | any,
166
+ ): node is ResourceExpr<Value, Src, Req> => node?.kind === "ResourceExpr";
167
+
168
+ export class ResourceExpr<
169
+ Value,
170
+ Src extends AnyResource,
171
+ Req = never,
172
+ > extends BaseExpr<Value, Src, Req> {
173
+ readonly kind = "ResourceExpr";
174
+ constructor(
175
+ public readonly src: Src,
176
+ readonly stables?: Record<string, any>,
177
+ ) {
178
+ super();
179
+ return proxy(this);
180
+ }
181
+ }
182
+
183
+ export const isPropExpr = <
184
+ A = any,
185
+ Prop extends keyof A = keyof A,
186
+ Src extends AnyResource = AnyResource,
187
+ Req = any,
188
+ >(
189
+ node: any,
190
+ ): node is PropExpr<A, Prop, Src, Req> => node?.kind === "PropExpr";
191
+
192
+ export class PropExpr<
193
+ A = any,
194
+ Id extends keyof A = keyof A,
195
+ Src extends AnyResource = AnyResource,
196
+ Req = any,
197
+ > extends BaseExpr<A[Id], Src, Req> {
198
+ readonly kind = "PropExpr";
199
+ constructor(
200
+ public readonly expr: Expr<A, Src, Req>,
201
+ public readonly identifier: Id,
202
+ ) {
203
+ super();
204
+ return proxy(this);
205
+ }
206
+ }
207
+
208
+ export const literal = <A>(value: A) => new LiteralExpr(value);
209
+
210
+ export const isLiteralExpr = <A = any>(node: any): node is LiteralExpr<A> =>
211
+ node?.kind === "LiteralExpr";
212
+
213
+ export class LiteralExpr<A> extends BaseExpr<A, never> {
214
+ readonly kind = "LiteralExpr";
215
+ constructor(public readonly value: A) {
216
+ super();
217
+ return proxy(this);
218
+ }
219
+ }
220
+
221
+ //Output.ApplyExpr<any, any, AnyResource, any>
222
+ export const isApplyExpr = <
223
+ In = any,
224
+ Out = any,
225
+ Src extends AnyResource = AnyResource,
226
+ Req = any,
227
+ >(
228
+ node: Output<Out, Src, Req>,
229
+ ): node is ApplyExpr<In, Out, Src, Req> => node?.kind === "ApplyExpr";
230
+
231
+ export class ApplyExpr<
232
+ A,
233
+ B,
234
+ Src extends AnyResource,
235
+ Req = never,
236
+ > extends BaseExpr<B, Src, Req> {
237
+ readonly kind = "ApplyExpr";
238
+ constructor(
239
+ public readonly expr: Expr<A, Src, Req>,
240
+ public readonly f: (value: A) => B,
241
+ ) {
242
+ super();
243
+ return proxy(this);
244
+ }
245
+ }
246
+
247
+ export const isEffectExpr = <
248
+ In = any,
249
+ Out = any,
250
+ Src extends AnyResource = AnyResource,
251
+ Req = any,
252
+ Req2 = any,
253
+ >(
254
+ node: any,
255
+ ): node is EffectExpr<In, Out, Src, Req, Req2> => node?.kind === "EffectExpr";
256
+
257
+ export class EffectExpr<
258
+ A,
259
+ B,
260
+ Src extends AnyResource,
261
+ Req = never,
262
+ Req2 = never,
263
+ > extends BaseExpr<B, Src, Req> {
264
+ readonly kind = "EffectExpr";
265
+ constructor(
266
+ public readonly expr: Expr<A, Src, Req>,
267
+ public readonly f: (value: A) => Effect.Effect<B, never, Req2>,
268
+ ) {
269
+ super();
270
+ return proxy(this);
271
+ }
272
+ }
273
+
274
+ export const isAllExpr = <Outs extends Expr[] = Expr[]>(
275
+ node: any,
276
+ ): node is AllExpr<Outs> => node?.kind === "AllExpr";
277
+
278
+ export class AllExpr<Outs extends Expr[]> extends BaseExpr<Outs> {
279
+ readonly kind = "AllExpr";
280
+ constructor(public readonly outs: Outs) {
281
+ super();
282
+ return proxy(this);
283
+ }
284
+ }
285
+
286
+ export const isRefExpr = <A = any>(node: any): node is RefExpr<A> =>
287
+ node?.kind === "RefExpr";
288
+
289
+ export class RefExpr<A> extends BaseExpr<A, never, never> {
290
+ readonly kind = "RefExpr";
291
+ constructor(
292
+ public readonly stack: string | undefined,
293
+ public readonly stage: string | undefined,
294
+ public readonly resourceId: string,
295
+ ) {
296
+ super();
297
+ return proxy(this);
298
+ }
299
+ }
300
+
301
+ export class MissingSourceError extends Data.TaggedError("MissingSourceError")<{
302
+ message: string;
303
+ srcId: string;
304
+ }> {}
305
+
306
+ export class InvalidReferenceError extends Data.TaggedError(
307
+ "InvalidReferenceError",
308
+ )<{
309
+ message: string;
310
+ stack: string;
311
+ stage: string;
312
+ resourceId: string;
313
+ }> {}
314
+
315
+ export const evaluate: <A, Upstream extends AnyResource, Req>(
316
+ expr: Output<A, Upstream, Req>,
317
+ upstream: {
318
+ [Id in Upstream["id"]]: Extract<Upstream, { id: Id }>["attr"];
319
+ },
320
+ ) => Effect.Effect<
321
+ A,
322
+ InvalidReferenceError | MissingSourceError,
323
+ State.State
324
+ > = (expr, upstream) =>
325
+ Effect.gen(function* () {
326
+ if (isResourceExpr(expr)) {
327
+ const srcId = expr.src.id;
328
+ const src = upstream[srcId as keyof typeof upstream];
329
+ if (!src) {
330
+ // type-safety should prevent this but let the caller decide how to handle it
331
+ return yield* Effect.fail(
332
+ new MissingSourceError({
333
+ message: `Source ${srcId} not found`,
334
+ srcId,
335
+ }),
336
+ );
337
+ }
338
+ return src;
339
+ } else if (isLiteralExpr(expr)) {
340
+ return expr.value;
341
+ } else if (isApplyExpr(expr)) {
342
+ return expr.f(yield* evaluate(expr.expr, upstream));
343
+ } else if (isEffectExpr(expr)) {
344
+ // TODO(sam): the same effect shoudl be memoized so that it's not run multiple times
345
+ return yield* expr.f(yield* evaluate(expr.expr, upstream));
346
+ } else if (isAllExpr(expr)) {
347
+ return yield* Effect.all(expr.outs.map((out) => evaluate(out, upstream)));
348
+ } else if (isPropExpr(expr)) {
349
+ return (yield* evaluate(expr.expr, upstream))?.[expr.identifier];
350
+ } else if (isRefExpr(expr)) {
351
+ const state = yield* State.State;
352
+ const app = yield* App.App;
353
+ const stack = expr.stack ?? app.name;
354
+ const stage = expr.stage ?? app.stage;
355
+ const resource = yield* state.get({
356
+ stack,
357
+ stage,
358
+ resourceId: expr.resourceId,
359
+ });
360
+ if (!resource) {
361
+ return yield* Effect.fail(
362
+ new InvalidReferenceError({
363
+ message: `Reference to '${expr.resourceId}' in stack '${stack}' and stage '${stage}' not found. Have you deployed '${stage}' or '${stack}'?`,
364
+ stack,
365
+ stage,
366
+ resourceId: expr.resourceId,
367
+ }),
368
+ );
369
+ }
370
+ return resource.attr;
371
+ } else if (Array.isArray(expr)) {
372
+ return yield* Effect.all(expr.map((item) => evaluate(item, upstream)));
373
+ } else if (typeof expr === "object" && expr !== null) {
374
+ return Object.fromEntries(
375
+ yield* Effect.all(
376
+ Object.entries(expr).map(([key, value]) =>
377
+ evaluate(value, upstream).pipe(Effect.map((value) => [key, value])),
378
+ ),
379
+ ),
380
+ );
381
+ }
382
+ return expr;
383
+ }) as Effect.Effect<any>;
384
+
385
+ export type Upstream<O extends Output<any, any, any>> =
386
+ O extends Output<infer _V, infer Up, infer _Req>
387
+ ? {
388
+ [Id in Up["id"]]: Extract<Up, { id: Id }>;
389
+ }
390
+ : never;
391
+
392
+ export const hasOutputs = (value: any): value is Output<any, any, any> =>
393
+ Object.keys(upstreamAny(value)).length > 0;
394
+
395
+ export const upstreamAny = (
396
+ value: any,
397
+ ): {
398
+ [ID in string]: Resource;
399
+ } => {
400
+ if (isExpr(value)) {
401
+ return upstream(value);
402
+ } else if (Array.isArray(value)) {
403
+ return Object.assign({}, ...value.map(resolveUpstream));
404
+ } else if (
405
+ value &&
406
+ (typeof value === "object" || typeof value === "function")
407
+ ) {
408
+ return Object.assign(
409
+ {},
410
+ ...Object.values(value).map((value) => resolveUpstream(value)),
411
+ );
412
+ }
413
+ return {};
414
+ };
415
+
416
+ export const upstream = <E extends Output<any, AnyResource, any>>(
417
+ expr: E,
418
+ ): {
419
+ [Id in keyof Upstream<E>]: Upstream<E>[Id];
420
+ } => _upstream(expr);
421
+
422
+ const _upstream = (expr: any): any => {
423
+ if (isResourceExpr(expr)) {
424
+ return {
425
+ [expr.src.id]: expr.src,
426
+ };
427
+ } else if (isPropExpr(expr)) {
428
+ return upstream(expr.expr);
429
+ } else if (isAllExpr(expr)) {
430
+ return Object.assign({}, ...expr.outs.map((out) => upstream(out)));
431
+ } else if (isEffectExpr(expr) || isApplyExpr(expr)) {
432
+ return upstream(expr.expr);
433
+ } else if (Array.isArray(expr)) {
434
+ return expr.map(_upstream).reduce(toObject, {});
435
+ } else if (typeof expr === "object" && expr !== null) {
436
+ return Object.values(expr)
437
+ .map((v) => _upstream(v))
438
+ .reduce(toObject, {});
439
+ }
440
+ return {};
441
+ };
442
+
443
+ const toObject = <A, B>(acc: B, v: A) => ({
444
+ ...acc,
445
+ ...v,
446
+ });
447
+
448
+ export type ResolveUpstream<A> = unknown extends A
449
+ ? { [id: string]: Resource }
450
+ : A extends undefined | null | boolean | number | string | symbol | bigint
451
+ ? {}
452
+ : IsAny<A> extends true
453
+ ? {}
454
+ : A extends Output<any, infer Upstream, any>
455
+ ? {
456
+ [Id in Upstream["id"]]: Extract<Upstream, { id: Id }>;
457
+ }
458
+ : A extends readonly any[] | any[]
459
+ ? ResolveUpstream<A[number]>
460
+ : A extends Record<string, any>
461
+ ? {
462
+ [Id in keyof UnionToIntersection<
463
+ ResolveUpstream<A[keyof A]>
464
+ >]: UnionToIntersection<ResolveUpstream<A[keyof A]>>[Id];
465
+ }
466
+ : {};
467
+
468
+ export const resolveUpstream = <const A>(value: A): ResolveUpstream<A> => {
469
+ if (isPrimitive(value)) {
470
+ return {} as any;
471
+ } else if (isOutput(value)) {
472
+ return upstream(value) as any;
473
+ } else if (Array.isArray(value)) {
474
+ return Object.fromEntries(
475
+ value.map((v) => resolveUpstream(v)).flatMap(Object.entries),
476
+ ) as any;
477
+ } else if (typeof value === "object" || typeof value === "function") {
478
+ return Object.fromEntries(
479
+ Object.values(value as any)
480
+ .map(resolveUpstream)
481
+ .flatMap(Object.entries),
482
+ ) as any;
483
+ }
484
+ return {} as any;
485
+ };
486
+
487
+ export const interpolate = <Args extends any[]>(
488
+ template: TemplateStringsArray,
489
+ ...args: Args
490
+ ): All<Args> extends Output<any, infer Src, infer Req>
491
+ ? Output<string, Src, Req>
492
+ : never =>
493
+ all(...args.map((arg) => (isOutput(arg) ? arg : literal(arg)))).apply(
494
+ (args) =>
495
+ template
496
+ .map((str, i) => str + (args[i] == null ? "" : String(args[i])))
497
+ .join(""),
498
+ ) as any;
499
+
500
+ export const all = <Outs extends (Output | Expr)[]>(...outs: Outs) =>
501
+ new AllExpr(outs as any) as unknown as All<Outs>;
502
+
503
+ export type All<Outs extends (Output | Expr)[]> = number extends Outs["length"]
504
+ ? [Outs[number]] extends [
505
+ | Output<infer V, infer Src, infer Req>
506
+ | Expr<infer V, infer Src, infer Req>,
507
+ ]
508
+ ? Output<V, Src, Req>
509
+ : never
510
+ : Tuple<Outs>;
511
+
512
+ export type Tuple<
513
+ Outs extends (Output | Expr)[],
514
+ Values extends any[] = [],
515
+ Src extends Resource = never,
516
+ Req = never,
517
+ > = Outs extends [infer H, ...infer Tail extends (Output | Expr)[]]
518
+ ? H extends Output<infer V, infer Src2, infer Req2>
519
+ ? Tuple<Tail, [...Values, V], Src | Src2, Req | Req2>
520
+ : never
521
+ : Output<Values, Src, Req>;
522
+
523
+ export const filter = <Outs extends any[]>(...outs: Outs) =>
524
+ outs.filter(isOutput) as unknown as Filter<Outs>;
525
+
526
+ export type Filter<Outs extends any[]> = number extends Outs["length"]
527
+ ? Output<
528
+ Extract<Outs[number], Output>["value"],
529
+ Extract<Outs[number], Output>["src"],
530
+ Extract<Outs[number], Output>["req"]
531
+ >
532
+ : FilterTuple<Outs>;
533
+
534
+ export type FilterTuple<
535
+ Outs extends (Output | Expr)[],
536
+ Values extends any[] = [],
537
+ Src extends Resource = never,
538
+ > = Outs extends [infer H, ...infer Tail extends (Output | Expr)[]]
539
+ ? H extends Output<infer V, infer Src2>
540
+ ? FilterTuple<Tail, [...Values, V], Src | Src2>
541
+ : FilterTuple<Tail, Values, Src>
542
+ : Output<Values, Src>;
@@ -1,7 +1,62 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import { App } from "./app.ts";
3
3
 
4
- export const physicalName = Effect.fn(function* (id: string) {
4
+ export const physicalName = Effect.fn(function* ({
5
+ id,
6
+ instanceId,
7
+ // 16 base32 characters = 80 bits of entropy = 4 × 10⁻⁷
8
+ suffixLength = 16,
9
+ }: {
10
+ id: string;
11
+ /** Hex-encoded instance ID (16 random bytes) */
12
+ instanceId: string;
13
+ suffixLength?: number;
14
+ }) {
5
15
  const app = yield* App;
6
- return `${app.name}-${id}-${app.stage}`;
16
+ return `${app.name}-${id}-${app.stage}-${base32(Buffer.from(instanceId, "hex")).slice(0, suffixLength)}`;
7
17
  });
18
+
19
+ // Base32 is ideal for physical names because it's denser than hex (5 bits per char vs 4)
20
+ // and compatible with DNS/S3 (as opposed to base64 which contains uppercase letters and symbols).
21
+
22
+ // base32.ts
23
+ // Concise, fast RFC 4648 Base32 encoder (no padding), lowercase output.
24
+ // Charset: a-z2-7 (DNS/S3 friendly)
25
+ const ALPH = "abcdefghijklmnopqrstuvwxyz234567";
26
+
27
+ /**
28
+ * Encode bytes into RFC4648 Base32 (no padding), lowercase.
29
+ *
30
+ * Performance notes:
31
+ * - O(n) single pass, no big-int
32
+ * - Avoids per-byte string concatenation by using a char array
33
+ */
34
+ export function base32(bytes: Uint8Array): string {
35
+ const n = bytes.length;
36
+ if (n === 0) return "";
37
+
38
+ // Base32 length without padding: ceil(n*8/5)
39
+ const outLen = ((n * 8 + 4) / 5) | 0;
40
+ const out = Array.from<string>({ length: outLen });
41
+
42
+ let buffer = 0;
43
+ let bits = 0;
44
+ let o = 0;
45
+
46
+ for (let i = 0; i < n; i++) {
47
+ buffer = (buffer << 8) | bytes[i];
48
+ bits += 8;
49
+
50
+ while (bits >= 5) {
51
+ out[o++] = ALPH[(buffer >>> (bits - 5)) & 31];
52
+ bits -= 5;
53
+ }
54
+ }
55
+
56
+ if (bits > 0) {
57
+ out[o++] = ALPH[(buffer << (5 - bits)) & 31];
58
+ }
59
+
60
+ // outLen computed as exact ceiling; o should match, but slice defensively.
61
+ return o === outLen ? out.join("") : out.slice(0, o).join("");
62
+ }