alchemy 2.0.0-beta.10 → 2.0.0-beta.13

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 (420) hide show
  1. package/bin/alchemy.js +1122 -450
  2. package/bin/alchemy.js.map +1 -1
  3. package/bin/alchemy.sh +15 -0
  4. package/bin/alchemy.ts +22 -727
  5. package/bin/commands/_shared.ts +237 -0
  6. package/bin/commands/bootstrap.ts +117 -0
  7. package/bin/commands/deploy.ts +144 -0
  8. package/bin/commands/login.ts +93 -0
  9. package/bin/commands/logs.ts +157 -0
  10. package/bin/commands/tail.ts +138 -0
  11. package/lib/AWS/AuthProvider.d.ts +7 -71
  12. package/lib/AWS/AuthProvider.d.ts.map +1 -1
  13. package/lib/AWS/AuthProvider.js +27 -22
  14. package/lib/AWS/AuthProvider.js.map +1 -1
  15. package/lib/AWS/AutoScaling/LaunchTemplate.d.ts +3 -3
  16. package/lib/AWS/AutoScaling/LaunchTemplate.d.ts.map +1 -1
  17. package/lib/AWS/AutoScaling/LaunchTemplate.js +2 -2
  18. package/lib/AWS/AutoScaling/LaunchTemplate.js.map +1 -1
  19. package/lib/AWS/Bootstrap.d.ts +2 -1
  20. package/lib/AWS/Bootstrap.d.ts.map +1 -1
  21. package/lib/AWS/Bootstrap.js +27 -29
  22. package/lib/AWS/Bootstrap.js.map +1 -1
  23. package/lib/AWS/CloudWatch/Alarm.d.ts +2 -2
  24. package/lib/AWS/CloudWatch/Alarm.d.ts.map +1 -1
  25. package/lib/AWS/CloudWatch/Alarm.js +2 -2
  26. package/lib/AWS/CloudWatch/Alarm.js.map +1 -1
  27. package/lib/AWS/CloudWatch/AlarmMuteRule.d.ts +2 -2
  28. package/lib/AWS/CloudWatch/AlarmMuteRule.d.ts.map +1 -1
  29. package/lib/AWS/CloudWatch/AlarmMuteRule.js +2 -2
  30. package/lib/AWS/CloudWatch/AlarmMuteRule.js.map +1 -1
  31. package/lib/AWS/CloudWatch/CompositeAlarm.d.ts +2 -2
  32. package/lib/AWS/CloudWatch/CompositeAlarm.d.ts.map +1 -1
  33. package/lib/AWS/CloudWatch/CompositeAlarm.js +2 -2
  34. package/lib/AWS/CloudWatch/CompositeAlarm.js.map +1 -1
  35. package/lib/AWS/CloudWatch/Dashboard.d.ts +2 -2
  36. package/lib/AWS/CloudWatch/Dashboard.d.ts.map +1 -1
  37. package/lib/AWS/CloudWatch/Dashboard.js +2 -2
  38. package/lib/AWS/CloudWatch/Dashboard.js.map +1 -1
  39. package/lib/AWS/CloudWatch/InsightRule.d.ts +2 -2
  40. package/lib/AWS/CloudWatch/InsightRule.d.ts.map +1 -1
  41. package/lib/AWS/CloudWatch/InsightRule.js +2 -2
  42. package/lib/AWS/CloudWatch/InsightRule.js.map +1 -1
  43. package/lib/AWS/CloudWatch/MetricStream.d.ts +2 -2
  44. package/lib/AWS/CloudWatch/MetricStream.d.ts.map +1 -1
  45. package/lib/AWS/CloudWatch/MetricStream.js +2 -2
  46. package/lib/AWS/CloudWatch/MetricStream.js.map +1 -1
  47. package/lib/AWS/Credentials.d.ts +5 -10
  48. package/lib/AWS/Credentials.d.ts.map +1 -1
  49. package/lib/AWS/Credentials.js +6 -30
  50. package/lib/AWS/Credentials.js.map +1 -1
  51. package/lib/AWS/DynamoDB/Table.d.ts +1 -1
  52. package/lib/AWS/DynamoDB/Table.d.ts.map +1 -1
  53. package/lib/AWS/EC2/EIP.d.ts +3 -3
  54. package/lib/AWS/EC2/EIP.d.ts.map +1 -1
  55. package/lib/AWS/EC2/EIP.js +2 -2
  56. package/lib/AWS/EC2/EIP.js.map +1 -1
  57. package/lib/AWS/EC2/EgressOnlyInternetGateway.d.ts +3 -3
  58. package/lib/AWS/EC2/EgressOnlyInternetGateway.d.ts.map +1 -1
  59. package/lib/AWS/EC2/EgressOnlyInternetGateway.js +2 -2
  60. package/lib/AWS/EC2/EgressOnlyInternetGateway.js.map +1 -1
  61. package/lib/AWS/EC2/Instance.d.ts +3 -3
  62. package/lib/AWS/EC2/Instance.d.ts.map +1 -1
  63. package/lib/AWS/EC2/Instance.js +2 -2
  64. package/lib/AWS/EC2/Instance.js.map +1 -1
  65. package/lib/AWS/EC2/InternetGateway.d.ts +3 -3
  66. package/lib/AWS/EC2/InternetGateway.d.ts.map +1 -1
  67. package/lib/AWS/EC2/InternetGateway.js +2 -2
  68. package/lib/AWS/EC2/InternetGateway.js.map +1 -1
  69. package/lib/AWS/EC2/NatGateway.d.ts +3 -3
  70. package/lib/AWS/EC2/NatGateway.d.ts.map +1 -1
  71. package/lib/AWS/EC2/NatGateway.js +2 -2
  72. package/lib/AWS/EC2/NatGateway.js.map +1 -1
  73. package/lib/AWS/EC2/Network.d.ts +1 -1
  74. package/lib/AWS/EC2/NetworkAcl.d.ts +3 -3
  75. package/lib/AWS/EC2/NetworkAcl.d.ts.map +1 -1
  76. package/lib/AWS/EC2/NetworkAcl.js +2 -2
  77. package/lib/AWS/EC2/NetworkAcl.js.map +1 -1
  78. package/lib/AWS/EC2/RouteTable.d.ts +3 -3
  79. package/lib/AWS/EC2/RouteTable.d.ts.map +1 -1
  80. package/lib/AWS/EC2/RouteTable.js +2 -2
  81. package/lib/AWS/EC2/RouteTable.js.map +1 -1
  82. package/lib/AWS/EC2/SecurityGroup.d.ts +3 -3
  83. package/lib/AWS/EC2/SecurityGroup.d.ts.map +1 -1
  84. package/lib/AWS/EC2/SecurityGroup.js +2 -2
  85. package/lib/AWS/EC2/SecurityGroup.js.map +1 -1
  86. package/lib/AWS/EC2/Subnet.d.ts +1 -1
  87. package/lib/AWS/EC2/Subnet.d.ts.map +1 -1
  88. package/lib/AWS/EC2/Vpc.d.ts +3 -3
  89. package/lib/AWS/EC2/Vpc.d.ts.map +1 -1
  90. package/lib/AWS/EC2/Vpc.js +2 -2
  91. package/lib/AWS/EC2/Vpc.js.map +1 -1
  92. package/lib/AWS/EC2/VpcEndpoint.d.ts +3 -3
  93. package/lib/AWS/EC2/VpcEndpoint.d.ts.map +1 -1
  94. package/lib/AWS/EC2/VpcEndpoint.js +2 -2
  95. package/lib/AWS/EC2/VpcEndpoint.js.map +1 -1
  96. package/lib/AWS/ECR/Repository.d.ts +1 -1
  97. package/lib/AWS/ECR/Repository.d.ts.map +1 -1
  98. package/lib/AWS/ECR/Repository.js +0 -1
  99. package/lib/AWS/ECR/Repository.js.map +1 -1
  100. package/lib/AWS/ECS/Cluster.d.ts +2 -2
  101. package/lib/AWS/ECS/Cluster.d.ts.map +1 -1
  102. package/lib/AWS/ECS/Cluster.js +2 -2
  103. package/lib/AWS/ECS/Cluster.js.map +1 -1
  104. package/lib/AWS/ECS/Service.d.ts +1 -1
  105. package/lib/AWS/ECS/Service.d.ts.map +1 -1
  106. package/lib/AWS/ECS/Task.d.ts +2 -2
  107. package/lib/AWS/ECS/Task.d.ts.map +1 -1
  108. package/lib/AWS/ECS/Task.js +2 -2
  109. package/lib/AWS/ECS/Task.js.map +1 -1
  110. package/lib/AWS/EKS/Cluster.d.ts +1 -1
  111. package/lib/AWS/EKS/Cluster.d.ts.map +1 -1
  112. package/lib/AWS/ELBv2/Listener.d.ts +1 -1
  113. package/lib/AWS/ELBv2/Listener.d.ts.map +1 -1
  114. package/lib/AWS/ELBv2/LoadBalancer.d.ts +1 -1
  115. package/lib/AWS/ELBv2/LoadBalancer.d.ts.map +1 -1
  116. package/lib/AWS/ELBv2/TargetGroup.d.ts +1 -1
  117. package/lib/AWS/ELBv2/TargetGroup.d.ts.map +1 -1
  118. package/lib/AWS/Endpoint.d.ts +7 -2
  119. package/lib/AWS/Endpoint.d.ts.map +1 -1
  120. package/lib/AWS/Endpoint.js +7 -2
  121. package/lib/AWS/Endpoint.js.map +1 -1
  122. package/lib/AWS/Environment.d.ts +68 -0
  123. package/lib/AWS/Environment.d.ts.map +1 -0
  124. package/lib/AWS/Environment.js +53 -0
  125. package/lib/AWS/Environment.js.map +1 -0
  126. package/lib/AWS/EventBridge/EventBus.d.ts +2 -2
  127. package/lib/AWS/EventBridge/EventBus.d.ts.map +1 -1
  128. package/lib/AWS/EventBridge/EventBus.js +2 -2
  129. package/lib/AWS/EventBridge/EventBus.js.map +1 -1
  130. package/lib/AWS/EventBridge/ListRules.d.ts +2 -2
  131. package/lib/AWS/EventBridge/ListRules.d.ts.map +1 -1
  132. package/lib/AWS/EventBridge/ListRules.js +2 -2
  133. package/lib/AWS/EventBridge/ListRules.js.map +1 -1
  134. package/lib/AWS/EventBridge/PutEvents.d.ts +2 -2
  135. package/lib/AWS/EventBridge/PutEvents.d.ts.map +1 -1
  136. package/lib/AWS/EventBridge/PutEvents.js +2 -2
  137. package/lib/AWS/EventBridge/PutEvents.js.map +1 -1
  138. package/lib/AWS/EventBridge/Rule.d.ts +2 -2
  139. package/lib/AWS/EventBridge/Rule.d.ts.map +1 -1
  140. package/lib/AWS/EventBridge/Rule.js +2 -2
  141. package/lib/AWS/EventBridge/Rule.js.map +1 -1
  142. package/lib/AWS/IAM/OpenIDConnectProvider.d.ts +2 -2
  143. package/lib/AWS/IAM/OpenIDConnectProvider.d.ts.map +1 -1
  144. package/lib/AWS/IAM/OpenIDConnectProvider.js +2 -2
  145. package/lib/AWS/IAM/OpenIDConnectProvider.js.map +1 -1
  146. package/lib/AWS/IAM/Policy.d.ts +3 -3
  147. package/lib/AWS/IAM/Policy.d.ts.map +1 -1
  148. package/lib/AWS/IAM/Policy.js +2 -2
  149. package/lib/AWS/IAM/Policy.js.map +1 -1
  150. package/lib/AWS/IAM/Role.d.ts +3 -3
  151. package/lib/AWS/IAM/Role.d.ts.map +1 -1
  152. package/lib/AWS/IAM/Role.js +3 -3
  153. package/lib/AWS/IAM/Role.js.map +1 -1
  154. package/lib/AWS/Kinesis/Stream.d.ts +2 -2
  155. package/lib/AWS/Kinesis/Stream.d.ts.map +1 -1
  156. package/lib/AWS/Kinesis/Stream.js +2 -2
  157. package/lib/AWS/Kinesis/Stream.js.map +1 -1
  158. package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
  159. package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
  160. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
  161. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
  162. package/lib/AWS/Lambda/EventSourceMapping.d.ts +2 -2
  163. package/lib/AWS/Lambda/EventSourceMapping.d.ts.map +1 -1
  164. package/lib/AWS/Lambda/EventSourceMapping.js +2 -2
  165. package/lib/AWS/Lambda/EventSourceMapping.js.map +1 -1
  166. package/lib/AWS/Lambda/Function.d.ts +2 -2
  167. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  168. package/lib/AWS/Lambda/Function.js +2 -2
  169. package/lib/AWS/Lambda/Function.js.map +1 -1
  170. package/lib/AWS/Lambda/Permission.d.ts +1 -1
  171. package/lib/AWS/Lambda/Permission.js +1 -1
  172. package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
  173. package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
  174. package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
  175. package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
  176. package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
  177. package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
  178. package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
  179. package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
  180. package/lib/AWS/Logs/LogGroup.d.ts +3 -3
  181. package/lib/AWS/Logs/LogGroup.d.ts.map +1 -1
  182. package/lib/AWS/Logs/LogGroup.js +2 -2
  183. package/lib/AWS/Logs/LogGroup.js.map +1 -1
  184. package/lib/AWS/Providers.d.ts +1 -2
  185. package/lib/AWS/Providers.d.ts.map +1 -1
  186. package/lib/AWS/Providers.js +3 -3
  187. package/lib/AWS/Providers.js.map +1 -1
  188. package/lib/AWS/Region.d.ts +6 -22
  189. package/lib/AWS/Region.d.ts.map +1 -1
  190. package/lib/AWS/Region.js +6 -39
  191. package/lib/AWS/Region.js.map +1 -1
  192. package/lib/AWS/S3/Bucket.d.ts +2 -2
  193. package/lib/AWS/S3/Bucket.d.ts.map +1 -1
  194. package/lib/AWS/S3/Bucket.js +2 -2
  195. package/lib/AWS/S3/Bucket.js.map +1 -1
  196. package/lib/AWS/SNS/Topic.d.ts +1 -1
  197. package/lib/AWS/SNS/Topic.d.ts.map +1 -1
  198. package/lib/AWS/SQS/Queue.d.ts +3 -3
  199. package/lib/AWS/SQS/Queue.d.ts.map +1 -1
  200. package/lib/AWS/SQS/Queue.js +2 -2
  201. package/lib/AWS/SQS/Queue.js.map +1 -1
  202. package/lib/AWS/index.d.ts +1 -3
  203. package/lib/AWS/index.d.ts.map +1 -1
  204. package/lib/AWS/index.js +1 -3
  205. package/lib/AWS/index.js.map +1 -1
  206. package/lib/Apply.d.ts.map +1 -1
  207. package/lib/Apply.js +2 -2
  208. package/lib/Apply.js.map +1 -1
  209. package/lib/Auth/AuthProvider.d.ts +51 -7
  210. package/lib/Auth/AuthProvider.d.ts.map +1 -1
  211. package/lib/Auth/AuthProvider.js +37 -0
  212. package/lib/Auth/AuthProvider.js.map +1 -1
  213. package/lib/Auth/Profile.d.ts +71 -10
  214. package/lib/Auth/Profile.d.ts.map +1 -1
  215. package/lib/Auth/Profile.js +47 -30
  216. package/lib/Auth/Profile.js.map +1 -1
  217. package/lib/Auth/index.d.ts +1 -1
  218. package/lib/Auth/index.d.ts.map +1 -1
  219. package/lib/Cloudflare/Auth/AuthProvider.d.ts +14 -31
  220. package/lib/Cloudflare/Auth/AuthProvider.d.ts.map +1 -1
  221. package/lib/Cloudflare/Auth/AuthProvider.js +59 -38
  222. package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
  223. package/lib/Cloudflare/CloudflareEnvironment.d.ts +11 -0
  224. package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -0
  225. package/lib/Cloudflare/CloudflareEnvironment.js +26 -0
  226. package/lib/Cloudflare/CloudflareEnvironment.js.map +1 -0
  227. package/lib/Cloudflare/Container/ContainerApplication.d.ts +70 -42
  228. package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
  229. package/lib/Cloudflare/Container/ContainerApplication.js +49 -24
  230. package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
  231. package/lib/Cloudflare/Credentials.d.ts +11 -0
  232. package/lib/Cloudflare/Credentials.d.ts.map +1 -0
  233. package/lib/Cloudflare/Credentials.js +34 -0
  234. package/lib/Cloudflare/Credentials.js.map +1 -0
  235. package/lib/Cloudflare/D1/D1Database.d.ts +2 -2
  236. package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
  237. package/lib/Cloudflare/D1/D1Database.js +2 -2
  238. package/lib/Cloudflare/D1/D1Database.js.map +1 -1
  239. package/lib/Cloudflare/KV/KVNamespace.d.ts +2 -2
  240. package/lib/Cloudflare/KV/KVNamespace.d.ts.map +1 -1
  241. package/lib/Cloudflare/KV/KVNamespace.js +2 -2
  242. package/lib/Cloudflare/KV/KVNamespace.js.map +1 -1
  243. package/lib/Cloudflare/Providers.d.ts +2 -3
  244. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  245. package/lib/Cloudflare/Providers.js +12 -4
  246. package/lib/Cloudflare/Providers.js.map +1 -1
  247. package/lib/Cloudflare/Queue/Queue.d.ts +52 -0
  248. package/lib/Cloudflare/Queue/Queue.d.ts.map +1 -0
  249. package/lib/Cloudflare/Queue/Queue.js +136 -0
  250. package/lib/Cloudflare/Queue/Queue.js.map +1 -0
  251. package/lib/Cloudflare/Queue/QueueBinding.d.ts +35 -0
  252. package/lib/Cloudflare/Queue/QueueBinding.d.ts.map +1 -0
  253. package/lib/Cloudflare/Queue/QueueBinding.js +51 -0
  254. package/lib/Cloudflare/Queue/QueueBinding.js.map +1 -0
  255. package/lib/Cloudflare/Queue/QueueConsumer.d.ts +86 -0
  256. package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -0
  257. package/lib/Cloudflare/Queue/QueueConsumer.js +138 -0
  258. package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -0
  259. package/lib/Cloudflare/Queue/index.d.ts +4 -0
  260. package/lib/Cloudflare/Queue/index.d.ts.map +1 -0
  261. package/lib/Cloudflare/Queue/index.js +4 -0
  262. package/lib/Cloudflare/Queue/index.js.map +1 -0
  263. package/lib/Cloudflare/R2/R2Bucket.d.ts +2 -2
  264. package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
  265. package/lib/Cloudflare/R2/R2Bucket.js +2 -2
  266. package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
  267. package/lib/Cloudflare/SecretsStore/Secret.d.ts +74 -0
  268. package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -0
  269. package/lib/Cloudflare/SecretsStore/Secret.js +161 -0
  270. package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -0
  271. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts +42 -0
  272. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts.map +1 -0
  273. package/lib/Cloudflare/SecretsStore/SecretBinding.js +49 -0
  274. package/lib/Cloudflare/SecretsStore/SecretBinding.js.map +1 -0
  275. package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts +37 -0
  276. package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts.map +1 -0
  277. package/lib/Cloudflare/SecretsStore/SecretsStore.js +88 -0
  278. package/lib/Cloudflare/SecretsStore/SecretsStore.js.map +1 -0
  279. package/lib/Cloudflare/SecretsStore/index.d.ts +4 -0
  280. package/lib/Cloudflare/SecretsStore/index.d.ts.map +1 -0
  281. package/lib/Cloudflare/SecretsStore/index.js +4 -0
  282. package/lib/Cloudflare/SecretsStore/index.js.map +1 -0
  283. package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
  284. package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
  285. package/lib/Cloudflare/Workers/Worker.d.ts +5 -3
  286. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  287. package/lib/Cloudflare/Workers/Worker.js +61 -7
  288. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  289. package/lib/Cloudflare/Workers/Workflow.d.ts +10 -4
  290. package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
  291. package/lib/Cloudflare/Workers/Workflow.js +3 -3
  292. package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
  293. package/lib/Cloudflare/index.d.ts +3 -1
  294. package/lib/Cloudflare/index.d.ts.map +1 -1
  295. package/lib/Cloudflare/index.js +3 -1
  296. package/lib/Cloudflare/index.js.map +1 -1
  297. package/lib/Stack.d.ts +3 -2
  298. package/lib/Stack.d.ts.map +1 -1
  299. package/lib/Stack.js +10 -7
  300. package/lib/Stack.js.map +1 -1
  301. package/lib/State/LocalState.d.ts.map +1 -1
  302. package/lib/State/LocalState.js +40 -12
  303. package/lib/State/LocalState.js.map +1 -1
  304. package/lib/Test/Bun.d.ts.map +1 -1
  305. package/lib/Test/Bun.js +3 -2
  306. package/lib/Test/Bun.js.map +1 -1
  307. package/lib/Test/Vitest.d.ts +3 -1
  308. package/lib/Test/Vitest.d.ts.map +1 -1
  309. package/lib/Test/Vitest.js +19 -16
  310. package/lib/Test/Vitest.js.map +1 -1
  311. package/lib/Util/PlatformServices.d.ts +14 -3
  312. package/lib/Util/PlatformServices.d.ts.map +1 -1
  313. package/lib/Util/PlatformServices.js +21 -3
  314. package/lib/Util/PlatformServices.js.map +1 -1
  315. package/package.json +5 -5
  316. package/src/AWS/AuthProvider.ts +67 -67
  317. package/src/AWS/AutoScaling/LaunchTemplate.ts +3 -3
  318. package/src/AWS/Bootstrap.ts +32 -37
  319. package/src/AWS/CloudWatch/Alarm.ts +2 -2
  320. package/src/AWS/CloudWatch/AlarmMuteRule.ts +2 -2
  321. package/src/AWS/CloudWatch/CompositeAlarm.ts +2 -2
  322. package/src/AWS/CloudWatch/Dashboard.ts +2 -2
  323. package/src/AWS/CloudWatch/InsightRule.ts +2 -2
  324. package/src/AWS/CloudWatch/MetricStream.ts +2 -2
  325. package/src/AWS/Credentials.ts +9 -44
  326. package/src/AWS/DynamoDB/Table.ts +1 -1
  327. package/src/AWS/EC2/EIP.ts +3 -3
  328. package/src/AWS/EC2/EgressOnlyInternetGateway.ts +3 -3
  329. package/src/AWS/EC2/Instance.ts +3 -3
  330. package/src/AWS/EC2/InternetGateway.ts +3 -3
  331. package/src/AWS/EC2/NatGateway.ts +3 -3
  332. package/src/AWS/EC2/NetworkAcl.ts +3 -3
  333. package/src/AWS/EC2/RouteTable.ts +3 -3
  334. package/src/AWS/EC2/SecurityGroup.ts +3 -3
  335. package/src/AWS/EC2/Subnet.ts +1 -1
  336. package/src/AWS/EC2/Vpc.ts +3 -3
  337. package/src/AWS/EC2/VpcEndpoint.ts +3 -3
  338. package/src/AWS/ECR/Repository.ts +1 -1
  339. package/src/AWS/ECS/Cluster.ts +2 -2
  340. package/src/AWS/ECS/Service.ts +1 -1
  341. package/src/AWS/ECS/Task.ts +2 -2
  342. package/src/AWS/EKS/Cluster.ts +1 -1
  343. package/src/AWS/ELBv2/Listener.ts +1 -1
  344. package/src/AWS/ELBv2/LoadBalancer.ts +1 -1
  345. package/src/AWS/ELBv2/TargetGroup.ts +1 -1
  346. package/src/AWS/Endpoint.ts +12 -8
  347. package/src/AWS/Environment.ts +123 -0
  348. package/src/AWS/EventBridge/EventBus.ts +2 -2
  349. package/src/AWS/EventBridge/ListRules.ts +2 -2
  350. package/src/AWS/EventBridge/PutEvents.ts +2 -2
  351. package/src/AWS/EventBridge/Rule.ts +2 -2
  352. package/src/AWS/IAM/OpenIDConnectProvider.ts +2 -2
  353. package/src/AWS/IAM/Policy.ts +3 -3
  354. package/src/AWS/IAM/Role.ts +4 -4
  355. package/src/AWS/Kinesis/Stream.ts +2 -2
  356. package/src/AWS/Lambda/EventSourceMapping.ts +2 -2
  357. package/src/AWS/Lambda/Function.ts +2 -2
  358. package/src/AWS/Lambda/Permission.ts +1 -1
  359. package/src/AWS/Logs/LogGroup.ts +3 -3
  360. package/src/AWS/Providers.ts +7 -7
  361. package/src/AWS/Region.ts +9 -66
  362. package/src/AWS/S3/Bucket.ts +2 -2
  363. package/src/AWS/SNS/Topic.ts +1 -1
  364. package/src/AWS/SQS/Queue.ts +3 -3
  365. package/src/AWS/index.ts +1 -3
  366. package/src/Apply.ts +55 -57
  367. package/src/Auth/AuthProvider.ts +188 -8
  368. package/src/Auth/Profile.ts +117 -54
  369. package/src/Auth/index.ts +1 -1
  370. package/src/Cloudflare/Auth/AuthProvider.ts +127 -98
  371. package/src/Cloudflare/CloudflareEnvironment.ts +49 -0
  372. package/src/Cloudflare/Container/ContainerApplication.ts +172 -94
  373. package/src/Cloudflare/Credentials.ts +75 -0
  374. package/src/Cloudflare/D1/D1Database.ts +2 -2
  375. package/src/Cloudflare/KV/KVNamespace.ts +2 -2
  376. package/src/Cloudflare/Providers.ts +20 -10
  377. package/src/Cloudflare/Queue/Queue.ts +174 -0
  378. package/src/Cloudflare/Queue/QueueBinding.ts +110 -0
  379. package/src/Cloudflare/Queue/QueueConsumer.ts +219 -0
  380. package/src/Cloudflare/Queue/index.ts +3 -0
  381. package/src/Cloudflare/R2/R2Bucket.ts +2 -2
  382. package/src/Cloudflare/SecretsStore/Secret.ts +229 -0
  383. package/src/Cloudflare/SecretsStore/SecretBinding.ts +107 -0
  384. package/src/Cloudflare/SecretsStore/SecretsStore.ts +106 -0
  385. package/src/Cloudflare/SecretsStore/index.ts +3 -0
  386. package/src/Cloudflare/Workers/InferEnv.ts +5 -3
  387. package/src/Cloudflare/Workers/Worker.ts +63 -7
  388. package/src/Cloudflare/Workers/Workflow.ts +19 -9
  389. package/src/Cloudflare/index.ts +3 -1
  390. package/src/Stack.ts +40 -29
  391. package/src/State/LocalState.ts +43 -16
  392. package/src/Test/Bun.ts +3 -0
  393. package/src/Test/Vitest.ts +31 -23
  394. package/src/Util/PlatformServices.ts +54 -13
  395. package/bin/process-manager.ts +0 -10
  396. package/lib/AWS/Account.d.ts +0 -26
  397. package/lib/AWS/Account.d.ts.map +0 -1
  398. package/lib/AWS/Account.js +0 -32
  399. package/lib/AWS/Account.js.map +0 -1
  400. package/lib/AWS/Profile.d.ts +0 -6
  401. package/lib/AWS/Profile.d.ts.map +0 -1
  402. package/lib/AWS/Profile.js +0 -4
  403. package/lib/AWS/Profile.js.map +0 -1
  404. package/lib/AWS/StageConfig.d.ts +0 -25
  405. package/lib/AWS/StageConfig.d.ts.map +0 -1
  406. package/lib/AWS/StageConfig.js +0 -23
  407. package/lib/AWS/StageConfig.js.map +0 -1
  408. package/lib/Cloudflare/Account.d.ts +0 -10
  409. package/lib/Cloudflare/Account.d.ts.map +0 -1
  410. package/lib/Cloudflare/Account.js +0 -24
  411. package/lib/Cloudflare/Account.js.map +0 -1
  412. package/lib/Cloudflare/StageConfig.d.ts +0 -8
  413. package/lib/Cloudflare/StageConfig.d.ts.map +0 -1
  414. package/lib/Cloudflare/StageConfig.js +0 -4
  415. package/lib/Cloudflare/StageConfig.js.map +0 -1
  416. package/src/AWS/Account.ts +0 -56
  417. package/src/AWS/Profile.ts +0 -5
  418. package/src/AWS/StageConfig.ts +0 -44
  419. package/src/Cloudflare/Account.ts +0 -38
  420. package/src/Cloudflare/StageConfig.ts +0 -8
@@ -0,0 +1,237 @@
1
+ import * as Cause from "effect/Cause";
2
+ import * as Config from "effect/Config";
3
+ import * as Console from "effect/Console";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Option from "effect/Option";
6
+ import * as Path from "effect/Path";
7
+ import * as S from "effect/Schema";
8
+ import * as Argument from "effect/unstable/cli/Argument";
9
+ import * as CliError from "effect/unstable/cli/CliError";
10
+ import * as Flag from "effect/unstable/cli/Flag";
11
+
12
+ import { AuthError } from "../../src/Auth/AuthProvider.ts";
13
+ import type * as Stack from "../../src/Stack.ts";
14
+ import { PromptCancelled } from "../../src/Util/Clank.ts";
15
+
16
+ export const USER = Config.string("USER").pipe(
17
+ Config.orElse(() => Config.string("USERNAME")),
18
+ Config.withDefault("unknown"),
19
+ );
20
+
21
+ export const STAGE = Config.string("stage").pipe(
22
+ Config.option,
23
+ (a) => a.asEffect(),
24
+ Effect.map(Option.getOrUndefined),
25
+ );
26
+
27
+ /**
28
+ * `true` if `e` is a {@link PromptCancelled}, or an {@link AuthError} whose
29
+ * `cause` chain bottoms out in one. Schema-tagged errors don't always
30
+ * survive `instanceof` across module boundaries, so we also accept any
31
+ * object whose `_tag` matches.
32
+ */
33
+ const isPromptCancellation = (e: unknown): boolean => {
34
+ for (let cur: unknown = e, i = 0; cur != null && i < 16; i++) {
35
+ if (cur instanceof PromptCancelled) return true;
36
+ if (
37
+ typeof cur === "object" &&
38
+ (cur as { _tag?: unknown })._tag === "PromptCancelled"
39
+ ) {
40
+ return true;
41
+ }
42
+ if (
43
+ cur instanceof AuthError ||
44
+ (typeof cur === "object" &&
45
+ (cur as { _tag?: unknown })._tag === "AuthError")
46
+ ) {
47
+ cur = (cur as { cause?: unknown }).cause;
48
+ continue;
49
+ }
50
+ return false;
51
+ }
52
+ return false;
53
+ };
54
+
55
+ /**
56
+ * Catches user cancellations (Ctrl+C inside a prompt, surfaced as
57
+ * {@link PromptCancelled} or wrapped in an {@link AuthError}) and exits
58
+ * the CLI cleanly with a friendly message instead of dumping a stack
59
+ * trace.
60
+ */
61
+ export const handleCancellation = <A, E, R>(self: Effect.Effect<A, E, R>) =>
62
+ self.pipe(
63
+ Effect.catchCause((cause) => {
64
+ const cancelled = cause.reasons.some((r) => {
65
+ if (Cause.isFailReason(r)) return isPromptCancellation(r.error);
66
+ if (Cause.isDieReason(r)) return isPromptCancellation(r.defect);
67
+ return false;
68
+ });
69
+ return cancelled
70
+ ? Console.log("\nCancelled.")
71
+ : (Effect.failCause(cause) as Effect.Effect<never, E, never>);
72
+ }),
73
+ // A bare fiber interrupt (Ctrl+C while not inside a prompt) shouldn't
74
+ // dump a stack trace either.
75
+ Effect.onInterrupt(() => Console.log("\nInterrupted.")),
76
+ );
77
+
78
+ export const stage = Flag.string("stage").pipe(
79
+ Flag.withSchema(S.String.check(S.isPattern(/^[a-z0-9]+([-_a-z0-9]+)*$/gi))),
80
+ Flag.withDescription("Stage to deploy to, defaults to dev_${USER}"),
81
+ Flag.optional,
82
+ Flag.map(Option.getOrUndefined),
83
+ Flag.mapEffect(
84
+ Effect.fn(function* (stage) {
85
+ if (stage) {
86
+ return stage;
87
+ }
88
+ return yield* STAGE.pipe(
89
+ Effect.catch(() =>
90
+ Effect.fail(
91
+ new CliError.MissingOption({
92
+ option: "stage",
93
+ }),
94
+ ),
95
+ ),
96
+ Effect.flatMap((s) =>
97
+ s === undefined
98
+ ? USER.asEffect().pipe(
99
+ Effect.map((user) => `dev_${user}`),
100
+ Effect.catch(() => Effect.succeed("unknown")),
101
+ )
102
+ : Effect.succeed(s),
103
+ ),
104
+ );
105
+ }),
106
+ ),
107
+ );
108
+
109
+ export const envFile = Flag.file("env-file").pipe(
110
+ Flag.optional,
111
+ Flag.withDescription(
112
+ "File to load environment variables from, defaults to .env",
113
+ ),
114
+ );
115
+
116
+ export const dryRun = Flag.boolean("dry-run").pipe(
117
+ Flag.withDescription("Dry run the deployment, do not actually deploy"),
118
+ Flag.withDefault(false),
119
+ );
120
+
121
+ export const yes = Flag.boolean("yes").pipe(
122
+ Flag.withDescription("Yes to all prompts"),
123
+ Flag.withDefault(false),
124
+ );
125
+
126
+ export const force = Flag.boolean("force").pipe(
127
+ Flag.withDescription(
128
+ "Force updates for resources that would otherwise no-op",
129
+ ),
130
+ Flag.withDefault(false),
131
+ );
132
+
133
+ export const main = Argument.file("main", {
134
+ mustExist: true,
135
+ }).pipe(
136
+ Argument.withDescription("Main file to deploy, defaults to alchemy.run.ts"),
137
+ Argument.withDefault("alchemy.run.ts"),
138
+ );
139
+
140
+ export const profile = Flag.string("profile").pipe(
141
+ Flag.withDescription(
142
+ "Auth profile to use (~/.alchemy/profiles.json). Defaults to 'default' or $ALCHEMY_PROFILE.",
143
+ ),
144
+ Flag.optional,
145
+ Flag.map(Option.getOrElse(() => "default")),
146
+ );
147
+
148
+ export const resourceFilter = Flag.string("filter").pipe(
149
+ Flag.withDescription(
150
+ "Comma-separated logical resource IDs (e.g. Api,Sandbox). Only those resources are included.",
151
+ ),
152
+ Flag.optional,
153
+ Flag.map(Option.getOrUndefined),
154
+ );
155
+
156
+ export const TAIL_COLORS = [
157
+ "\x1b[36m", // cyan
158
+ "\x1b[35m", // magenta
159
+ "\x1b[33m", // yellow
160
+ "\x1b[32m", // green
161
+ "\x1b[34m", // blue
162
+ "\x1b[91m", // bright red
163
+ "\x1b[96m", // bright cyan
164
+ "\x1b[95m", // bright magenta
165
+ "\x1b[93m", // bright yellow
166
+ "\x1b[92m", // bright green
167
+ ];
168
+ export const TAIL_RESET = "\x1b[0m";
169
+
170
+ export const formatLocalTimestamp = (date: Date): string => {
171
+ const y = date.getFullYear();
172
+ const mo = String(date.getMonth() + 1).padStart(2, "0");
173
+ const d = String(date.getDate()).padStart(2, "0");
174
+ const h = String(date.getHours()).padStart(2, "0");
175
+ const mi = String(date.getMinutes()).padStart(2, "0");
176
+ const s = String(date.getSeconds()).padStart(2, "0");
177
+ const ms = String(date.getMilliseconds()).padStart(3, "0");
178
+ const tz =
179
+ new Intl.DateTimeFormat("en-US", { timeZoneName: "short" })
180
+ .formatToParts(date)
181
+ .find((p) => p.type === "timeZoneName")?.value ?? "";
182
+ return `${y}-${mo}-${d} ${h}:${mi}:${s}.${ms} ${tz}`;
183
+ };
184
+
185
+ export const parseResourceFilter = (
186
+ filter: string | undefined,
187
+ ): ReadonlySet<string> | undefined => {
188
+ if (filter === undefined) return undefined;
189
+ const ids = filter
190
+ .split(",")
191
+ .map((s) => s.trim())
192
+ .filter((s) => s.length > 0);
193
+ if (ids.length === 0) return undefined;
194
+ return new Set(ids);
195
+ };
196
+
197
+ export const parseSince = (value: string): Date => {
198
+ const match = value.match(/^(\d+)([smhd])$/);
199
+ if (match) {
200
+ const num = parseInt(match[1]!, 10);
201
+ const unit = match[2]!;
202
+ const ms =
203
+ unit === "s"
204
+ ? num * 1000
205
+ : unit === "m"
206
+ ? num * 60_000
207
+ : unit === "h"
208
+ ? num * 3_600_000
209
+ : num * 86_400_000;
210
+ return new Date(Date.now() - ms);
211
+ }
212
+ const parsed = new Date(value);
213
+ if (isNaN(parsed.getTime())) {
214
+ throw new Error(
215
+ `Invalid --since value: '${value}'. Use a duration (e.g. '1h', '30m') or ISO date.`,
216
+ );
217
+ }
218
+ return parsed;
219
+ };
220
+
221
+ export const importStack = Effect.fn(function* (main: string) {
222
+ const path = yield* Path.Path;
223
+ const module = yield* Effect.promise(
224
+ () => import(path.resolve(process.cwd(), main)),
225
+ );
226
+ const stackEffect = module.default as ReturnType<
227
+ ReturnType<typeof Stack.make>
228
+ >;
229
+ if (!Effect.isEffect(stackEffect)) {
230
+ return yield* Effect.die(
231
+ new Error(
232
+ `Main file '${main}' must export a default stack definition (export default Alchemy.Stack({...}))`,
233
+ ),
234
+ );
235
+ }
236
+ return stackEffect;
237
+ });
@@ -0,0 +1,117 @@
1
+ import * as Auth from "@distilled.cloud/aws/Auth";
2
+ import * as ConfigProvider from "effect/ConfigProvider";
3
+ import * as Console from "effect/Console";
4
+ import * as Effect from "effect/Effect";
5
+ import type { FileSystem } from "effect/FileSystem";
6
+ import * as Layer from "effect/Layer";
7
+ import * as Logger from "effect/Logger";
8
+ import * as Option from "effect/Option";
9
+ import { Path } from "effect/Path";
10
+ import * as Command from "effect/unstable/cli/Command";
11
+ import * as Flag from "effect/unstable/cli/Flag";
12
+ import type { HttpClient } from "effect/unstable/http/HttpClient";
13
+
14
+ import {
15
+ bootstrap as bootstrapAws,
16
+ destroyBootstrap as destroyBootstrapAws,
17
+ } from "../../src/AWS/Bootstrap.ts";
18
+ import * as AWSCredentials from "../../src/AWS/Credentials.ts";
19
+ import * as AWSEnvironment from "../../src/AWS/Environment.ts";
20
+ import * as AWSRegion from "../../src/AWS/Region.ts";
21
+ import { loadConfigProvider } from "../../src/Util/ConfigProvider.ts";
22
+ import { fileLogger } from "../../src/Util/FileLogger.ts";
23
+
24
+ import { envFile } from "./_shared.ts";
25
+
26
+ const awsProfile = Flag.string("profile").pipe(
27
+ Flag.withDescription("AWS profile to use for credentials"),
28
+ Flag.optional,
29
+ Flag.map(Option.getOrElse(() => "default")),
30
+ );
31
+
32
+ const awsRegion = Flag.string("region").pipe(
33
+ Flag.withDescription(
34
+ "AWS region to bootstrap (defaults to AWS_REGION env var)",
35
+ ),
36
+ Flag.optional,
37
+ Flag.map(Option.getOrUndefined),
38
+ );
39
+
40
+ const bootstrapDestroy = Flag.boolean("destroy").pipe(
41
+ Flag.withDescription("Destroy all bootstrap buckets in the selected region"),
42
+ Flag.withDefault(false),
43
+ );
44
+
45
+ export const bootstrapCommand = Command.make(
46
+ "bootstrap",
47
+ {
48
+ envFile,
49
+ profile: awsProfile,
50
+ region: awsRegion,
51
+ destroy: bootstrapDestroy,
52
+ },
53
+ Effect.fnUntraced(function* ({ envFile, profile, region, destroy }) {
54
+ const logger = Logger.layer([fileLogger("bootstrap.txt")]);
55
+
56
+ return yield* Effect.gen(function* () {
57
+ const ssoProfile = yield* Auth.loadProfile(profile);
58
+ if (!ssoProfile.sso_account_id) {
59
+ return yield* Effect.die(
60
+ `AWS SSO profile '${profile}' is missing sso_account_id`,
61
+ );
62
+ }
63
+
64
+ // Build a single AWSEnvironment, then derive Region/Credentials from
65
+ // it so resource providers downstream see a consistent view. The
66
+ // credentials Effect captures FileSystem/Path/HttpClient via the
67
+ // ambient context; AWSEnvironment expects R=never, so we provide it
68
+ // here.
69
+ const ambient = yield* Effect.context<FileSystem | Path | HttpClient>();
70
+ const environment = AWSEnvironment.makeEnvironment({
71
+ accountId: ssoProfile.sso_account_id,
72
+ region: region ?? ssoProfile.region ?? "us-east-1",
73
+ credentials: Auth.loadProfileCredentials(profile).pipe(
74
+ Effect.provide(ambient),
75
+ ),
76
+ profile,
77
+ });
78
+
79
+ const awsLayers = Layer.provideMerge(
80
+ Layer.mergeAll(
81
+ AWSRegion.fromEnvironment,
82
+ AWSCredentials.fromEnvironment,
83
+ ),
84
+ environment,
85
+ );
86
+
87
+ return yield* Effect.gen(function* () {
88
+ const provider = yield* loadConfigProvider(envFile);
89
+ const bootstrapLayer = Layer.provide(
90
+ awsLayers,
91
+ Layer.succeed(ConfigProvider.ConfigProvider, provider),
92
+ );
93
+ if (destroy) {
94
+ yield* destroyBootstrapAws().pipe(
95
+ Effect.tap((result) =>
96
+ result.destroyed === 0
97
+ ? Console.log("✓ No bootstrap buckets found to destroy")
98
+ : Console.log(
99
+ `✓ Destroyed ${result.destroyed} bootstrap bucket(s): ${result.bucketNames.join(", ")}`,
100
+ ),
101
+ ),
102
+ Effect.provide(bootstrapLayer),
103
+ );
104
+ return;
105
+ }
106
+ yield* bootstrapAws().pipe(
107
+ Effect.tap(({ bucketName, created }) =>
108
+ created
109
+ ? Console.log(`✓ Created assets bucket: ${bucketName}`)
110
+ : Console.log(`✓ Assets bucket already exists: ${bucketName}`),
111
+ ),
112
+ Effect.provide(bootstrapLayer),
113
+ );
114
+ });
115
+ }).pipe(Effect.provide(logger));
116
+ }),
117
+ );
@@ -0,0 +1,144 @@
1
+ import * as ConfigProvider from "effect/ConfigProvider";
2
+ import * as Console from "effect/Console";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Logger from "effect/Logger";
6
+ import * as Option from "effect/Option";
7
+ import * as Command from "effect/unstable/cli/Command";
8
+
9
+ import { apply } from "../../src/Apply.ts";
10
+ import { ArtifactStore, createArtifactStore } from "../../src/Artifacts.ts";
11
+ import { AuthProviders } from "../../src/Auth/AuthProvider.ts";
12
+ import { withProfileOverride } from "../../src/Auth/Profile.ts";
13
+ import * as CLI from "../../src/Cli/index.ts";
14
+ import * as Plan from "../../src/Plan.ts";
15
+ import { Stage } from "../../src/Stage.ts";
16
+ import * as State from "../../src/State/index.ts";
17
+ import { loadConfigProvider } from "../../src/Util/ConfigProvider.ts";
18
+ import { fileLogger } from "../../src/Util/FileLogger.ts";
19
+
20
+ import {
21
+ dryRun as dryRunFlag,
22
+ envFile,
23
+ force,
24
+ importStack,
25
+ main,
26
+ profile,
27
+ stage,
28
+ yes,
29
+ } from "./_shared.ts";
30
+
31
+ const execStack = Effect.fn(function* ({
32
+ main,
33
+ stage,
34
+ envFile,
35
+ profile,
36
+ dryRun = false,
37
+ force = false,
38
+ yes = false,
39
+ destroy = false,
40
+ }: {
41
+ main: string;
42
+ stage: string;
43
+ envFile: Option.Option<string>;
44
+ profile: string;
45
+ dryRun?: boolean;
46
+ force?: boolean;
47
+ yes?: boolean;
48
+ destroy?: boolean;
49
+ }) {
50
+ const stackEffect = yield* importStack(main);
51
+
52
+ const services = Layer.mergeAll(
53
+ Layer.succeed(ArtifactStore, createArtifactStore()),
54
+ Layer.succeed(AuthProviders, {}),
55
+ ConfigProvider.layer(
56
+ withProfileOverride(yield* loadConfigProvider(envFile), profile),
57
+ ),
58
+ CLI.inkCLI(),
59
+ Logger.layer([fileLogger("out")]),
60
+ Layer.succeed(Stage, stage),
61
+ State.LocalState,
62
+ );
63
+
64
+ yield* Effect.gen(function* () {
65
+ const cli = yield* CLI.Cli;
66
+ const stack = yield* stackEffect;
67
+
68
+ yield* Effect.gen(function* () {
69
+ const updatePlan = yield* Plan.make(
70
+ destroy
71
+ ? {
72
+ ...stack,
73
+ // zero these out (destroy will treat all as orphans)
74
+ // TODO(sam): probably better to have Plan.destroy and Plan.update
75
+ resources: {},
76
+ bindings: {},
77
+ output: {},
78
+ }
79
+ : stack,
80
+ { force },
81
+ );
82
+ if (dryRun) {
83
+ yield* cli.displayPlan(updatePlan);
84
+ } else {
85
+ if (!yes) {
86
+ const approved = yield* cli.approvePlan(updatePlan);
87
+ if (!approved) {
88
+ return;
89
+ }
90
+ }
91
+ const outputs = yield* apply(updatePlan);
92
+
93
+ yield* Console.log(outputs);
94
+ }
95
+ }).pipe(Effect.provide(stack.services));
96
+ }).pipe(Effect.provide(services));
97
+ });
98
+
99
+ export const deployCommand = Command.make(
100
+ "deploy",
101
+ {
102
+ dryRun: dryRunFlag,
103
+ force,
104
+ main,
105
+ envFile,
106
+ stage,
107
+ yes,
108
+ profile,
109
+ },
110
+ execStack,
111
+ );
112
+
113
+ export const destroyCommand = Command.make(
114
+ "destroy",
115
+ {
116
+ dryRun: dryRunFlag,
117
+ main,
118
+ envFile,
119
+ stage,
120
+ yes,
121
+ profile,
122
+ },
123
+ (args) =>
124
+ execStack({
125
+ ...args,
126
+ destroy: true,
127
+ }),
128
+ );
129
+
130
+ export const planCommand = Command.make(
131
+ "plan",
132
+ {
133
+ main,
134
+ envFile,
135
+ stage,
136
+ profile,
137
+ },
138
+ (args) =>
139
+ execStack({
140
+ ...args,
141
+ // plan is the same as deploy with dryRun always set to true
142
+ dryRun: true,
143
+ }),
144
+ );
@@ -0,0 +1,93 @@
1
+ import * as Config from "effect/Config";
2
+ import * as ConfigProvider from "effect/ConfigProvider";
3
+ import * as Console from "effect/Console";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import * as Logger from "effect/Logger";
7
+ import { Command, Flag } from "effect/unstable/cli";
8
+
9
+ import { AuthProviders } from "../../src/Auth/AuthProvider.ts";
10
+ import {
11
+ getProfile,
12
+ setProfile,
13
+ withProfileOverride,
14
+ } from "../../src/Auth/Profile.ts";
15
+ import { Stage } from "../../src/Stage.ts";
16
+ import * as State from "../../src/State/index.ts";
17
+ import { loadConfigProvider } from "../../src/Util/ConfigProvider.ts";
18
+ import { fileLogger } from "../../src/Util/FileLogger.ts";
19
+
20
+ import { envFile, importStack, main, profile, stage } from "./_shared.ts";
21
+
22
+ const loginConfigure = Flag.boolean("configure").pipe(
23
+ Flag.withDescription(
24
+ "Run the provider's interactive configure step before logging in",
25
+ ),
26
+ Flag.withDefault(false),
27
+ );
28
+
29
+ export const loginCommand = Command.make(
30
+ "login",
31
+ {
32
+ main,
33
+ envFile,
34
+ stage,
35
+ profile,
36
+ configure: loginConfigure,
37
+ },
38
+ Effect.fnUntraced(function* ({ main, stage, envFile, profile, configure }) {
39
+ const stackEffect = yield* importStack(main);
40
+
41
+ const authProviders: AuthProviders["Service"] = {};
42
+
43
+ const services = Layer.mergeAll(
44
+ Layer.succeed(AuthProviders, authProviders),
45
+ ConfigProvider.layer(
46
+ withProfileOverride(yield* loadConfigProvider(envFile), profile),
47
+ ),
48
+ Logger.layer([fileLogger("out")]),
49
+ Layer.succeed(Stage, stage),
50
+ State.LocalState,
51
+ );
52
+
53
+ yield* Effect.gen(function* () {
54
+ // Build the stack — this triggers each provider's AuthProviderLayer,
55
+ // which registers itself into the shared `authProviders` registry.
56
+ yield* stackEffect;
57
+
58
+ const ci = yield* Config.boolean("CI").pipe(Config.withDefault(false));
59
+ const providers = Object.values(authProviders);
60
+
61
+ if (providers.length === 0) {
62
+ yield* Console.log(
63
+ "No AuthProviders registered. Make sure the stack's providers() layer includes AuthProviderLayer entries.",
64
+ );
65
+ return;
66
+ }
67
+
68
+ yield* Effect.forEach(
69
+ providers,
70
+ (provider) =>
71
+ Effect.gen(function* () {
72
+ const existing = yield* getProfile(profile);
73
+ const stored = existing?.[provider.name];
74
+
75
+ let cfg: { method: string };
76
+ if (configure || stored == null) {
77
+ cfg = yield* provider.configure(profile, { ci });
78
+ yield* setProfile(profile, {
79
+ ...existing,
80
+ [provider.name]: cfg,
81
+ });
82
+ } else {
83
+ cfg = stored;
84
+ }
85
+
86
+ yield* provider.login(profile, cfg);
87
+ yield* provider.prettyPrint(profile, cfg);
88
+ }),
89
+ { discard: true },
90
+ );
91
+ }).pipe(Effect.provide(services));
92
+ }),
93
+ );