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
package/src/Apply.ts CHANGED
@@ -88,70 +88,68 @@ export const apply = <P extends Plan>(
88
88
  Output.InvalidReferenceError | Output.MissingSourceError | StateStoreError,
89
89
  Cli | State | Stack | Stage
90
90
  > =>
91
- ensureArtifactStore(
92
- Effect.gen(function* () {
93
- const cli = yield* Cli;
94
- const session = yield* cli.startApplySession(plan);
95
- const state = yield* State;
96
- const stack = yield* Stack;
97
- const stage = yield* Stage;
98
- const stackName = stack.name;
99
-
100
- const tracker: Record<string, ResourceTracker> = {};
101
- const terminalStatuses = new Map<
102
- string,
103
- {
104
- id: string;
105
- type: string;
106
- status: Extract<ApplyStatus, "created" | "updated">;
107
- }
108
- >();
109
-
110
- yield* executePlan(
111
- plan,
112
- tracker,
113
- terminalStatuses,
114
- session,
115
- state,
116
- stackName,
117
- stage,
118
- );
91
+ Effect.gen(function* () {
92
+ const cli = yield* Cli;
93
+ const session = yield* cli.startApplySession(plan);
94
+ const state = yield* State;
95
+ const stack = yield* Stack;
96
+ const stage = yield* Stage;
97
+ const stackName = stack.name;
98
+
99
+ const tracker: Record<string, ResourceTracker> = {};
100
+ const terminalStatuses = new Map<
101
+ string,
102
+ {
103
+ id: string;
104
+ type: string;
105
+ status: Extract<ApplyStatus, "created" | "updated">;
106
+ }
107
+ >();
108
+
109
+ yield* executePlan(
110
+ plan,
111
+ tracker,
112
+ terminalStatuses,
113
+ session,
114
+ state,
115
+ stackName,
116
+ stage,
117
+ );
119
118
 
120
- // TODO(sam): support roll back to previous state if errors occur during expansion
121
- // -> RISK: some UPDATEs may not be reversible (i.e. trigger replacements)
122
- // TODO(sam): should pivot be done separately? E.g shift traffic?
119
+ // TODO(sam): support roll back to previous state if errors occur during expansion
120
+ // -> RISK: some UPDATEs may not be reversible (i.e. trigger replacements)
121
+ // TODO(sam): should pivot be done separately? E.g shift traffic?
123
122
 
124
- yield* collectGarbage(plan, session);
123
+ yield* collectGarbage(plan, session);
125
124
 
126
- yield* converge(
127
- plan,
128
- tracker,
129
- terminalStatuses,
130
- session,
131
- state,
132
- stackName,
133
- stage,
134
- );
125
+ yield* converge(
126
+ plan,
127
+ tracker,
128
+ terminalStatuses,
129
+ session,
130
+ state,
131
+ stackName,
132
+ stage,
133
+ );
135
134
 
136
- yield* Effect.forEach(
137
- Array.from(terminalStatuses.values()),
138
- ({ id, type, status }) =>
139
- session.emit({ kind: "status-change", id, type, status }),
140
- { concurrency: "unbounded" },
141
- );
135
+ yield* Effect.forEach(
136
+ Array.from(terminalStatuses.values()),
137
+ ({ id, type, status }) =>
138
+ session.emit({ kind: "status-change", id, type, status }),
139
+ { concurrency: "unbounded" },
140
+ );
142
141
 
143
- yield* session.done();
142
+ yield* session.done();
144
143
 
145
- if (!plan.output) {
146
- return undefined;
147
- }
144
+ if (!plan.output) {
145
+ return undefined;
146
+ }
148
147
 
149
- const outputs = Object.fromEntries(
150
- Object.entries(tracker).map(([fqn, t]) => [fqn, t.output]),
151
- );
152
- return yield* Output.evaluate(plan.output, outputs);
153
- }),
154
- );
148
+ const outputs = Object.fromEntries(
149
+ Object.entries(tracker).map(([fqn, t]) => [fqn, t.output]),
150
+ );
151
+ return yield* Output.evaluate(plan.output, outputs);
152
+ }).pipe(ensureArtifactStore);
155
153
 
156
154
  // ── Phase 1: concurrent initial execution ──────────────────────────────────
157
155
  //
@@ -1,4 +1,6 @@
1
- import type * as Effect from "effect/Effect";
1
+ import * as Context from "effect/Context";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
2
4
  import * as Schema from "effect/Schema";
3
5
 
4
6
  export class AuthError extends Schema.TaggedErrorClass<AuthError>()(
@@ -9,25 +11,203 @@ export class AuthError extends Schema.TaggedErrorClass<AuthError>()(
9
11
  },
10
12
  ) {}
11
13
 
12
- export interface AuthProvider<Config extends { method: string }, Credentials> {
13
- readonly name: string;
14
+ export class AuthProviders extends Context.Service<
15
+ AuthProviders,
16
+ {
17
+ [providerName: string]: AuthProvider;
18
+ }
19
+ >()("AuthProviders") {}
14
20
 
15
- configure(profileName: string): Effect.Effect<Config, AuthError>;
21
+ /**
22
+ * Context passed to {@link AuthProviderImpl.configure}.
23
+ */
24
+ export interface ConfigureContext {
25
+ /**
26
+ * `true` when running in a CI/CD environment (resolved from the `CI`
27
+ * env/config). Providers MUST NOT prompt interactively when `ci` is true;
28
+ * they should pick a non-interactive default (typically
29
+ * `{ method: "env" }`) so unattended runs work.
30
+ */
31
+ readonly ci: boolean;
32
+ }
33
+
34
+ export interface AuthProviderImpl<
35
+ Config extends { method: string } = any,
36
+ Credentials = any,
37
+ ConfigureReq = any,
38
+ LoginReq = any,
39
+ LogoutReq = any,
40
+ PrettyPrintReq = any,
41
+ ReadReq = any,
42
+ > {
43
+ configure(
44
+ profileName: string,
45
+ ctx: ConfigureContext,
46
+ ): Effect.Effect<Config, AuthError, ConfigureReq>;
16
47
 
17
48
  login(
18
49
  profileName: string,
19
50
  config: Config,
20
- ): Effect.Effect<void, AuthError, never>;
51
+ ): Effect.Effect<void, AuthError, LoginReq>;
21
52
 
22
53
  logout(
23
54
  profileName: string,
24
55
  config: Config,
25
- ): Effect.Effect<void, AuthError, never>;
56
+ ): Effect.Effect<void, AuthError, LogoutReq>;
26
57
 
27
- prettyPrint(profileName: string, config: Config): Effect.Effect<void>;
58
+ prettyPrint(
59
+ profileName: string,
60
+ config: Config,
61
+ ): Effect.Effect<void, AuthError, PrettyPrintReq>;
28
62
 
29
63
  read(
30
64
  profileName: string,
31
65
  config: Config,
32
- ): Effect.Effect<Credentials, AuthError, never>;
66
+ ): Effect.Effect<Credentials, AuthError, ReadReq>;
33
67
  }
68
+
69
+ export interface AuthProvider<
70
+ Config extends { method: string } = any,
71
+ Credentials = any,
72
+ > extends AuthProviderImpl<
73
+ Config,
74
+ Credentials,
75
+ never,
76
+ never,
77
+ never,
78
+ never,
79
+ never
80
+ > {
81
+ readonly kind: "AuthProvider";
82
+ readonly name: string;
83
+ }
84
+
85
+ export const AuthProvider =
86
+ <Config extends { method: string }, Credentials>() =>
87
+ <
88
+ ImplReq = never,
89
+ ConfigureReq = never,
90
+ LoginReq = never,
91
+ LogoutReq = never,
92
+ PrettyPrintReq = never,
93
+ ReadReq = never,
94
+ >(
95
+ name: string,
96
+ impl:
97
+ | AuthProviderImpl<
98
+ Config,
99
+ Credentials,
100
+ ConfigureReq,
101
+ LoginReq,
102
+ LogoutReq,
103
+ PrettyPrintReq,
104
+ ReadReq
105
+ >
106
+ | Effect.Effect<
107
+ AuthProviderImpl<
108
+ Config,
109
+ Credentials,
110
+ ConfigureReq,
111
+ LoginReq,
112
+ LogoutReq,
113
+ PrettyPrintReq,
114
+ ReadReq
115
+ >,
116
+ never,
117
+ ImplReq
118
+ >,
119
+ ) =>
120
+ Effect.gen(function* () {
121
+ const ctx = yield* Effect.context();
122
+ const providers = yield* AuthProviders;
123
+ const service = yield* Effect.isEffect(impl)
124
+ ? impl
125
+ : Effect.succeed(impl);
126
+ return yield* Effect.sync(
127
+ () =>
128
+ (providers[name] = {
129
+ kind: "AuthProvider",
130
+ name,
131
+ ...Object.fromEntries(
132
+ Object.entries(service).map(([name, fn]) => [
133
+ name,
134
+ (...args: Parameters<typeof fn>) =>
135
+ fn(...args).pipe(Effect.provideContext(ctx)),
136
+ ]),
137
+ ),
138
+ } as AuthProvider<Config, Credentials>),
139
+ );
140
+ });
141
+
142
+ /**
143
+ * Build a Layer that registers an AuthProvider into the {@link AuthProviders}
144
+ * registry when its parent layer is built. Use this from a provider's
145
+ * top-level `providers()` Layer so that `alchemy login` can discover the
146
+ * provider via the registry without forcing credential resolution.
147
+ */
148
+ export const AuthProviderLayer =
149
+ <Config extends { method: string }, Credentials>() =>
150
+ <
151
+ ImplReq = never,
152
+ ConfigureReq = never,
153
+ LoginReq = never,
154
+ LogoutReq = never,
155
+ PrettyPrintReq = never,
156
+ ReadReq = never,
157
+ >(
158
+ name: string,
159
+ impl:
160
+ | AuthProviderImpl<
161
+ Config,
162
+ Credentials,
163
+ ConfigureReq,
164
+ LoginReq,
165
+ LogoutReq,
166
+ PrettyPrintReq,
167
+ ReadReq
168
+ >
169
+ | Effect.Effect<
170
+ AuthProviderImpl<
171
+ Config,
172
+ Credentials,
173
+ ConfigureReq,
174
+ LoginReq,
175
+ LogoutReq,
176
+ PrettyPrintReq,
177
+ ReadReq
178
+ >,
179
+ never,
180
+ ImplReq
181
+ >,
182
+ ) =>
183
+ Layer.effectDiscard(
184
+ AuthProvider<Config, Credentials>()<
185
+ ImplReq,
186
+ ConfigureReq,
187
+ LoginReq,
188
+ LogoutReq,
189
+ PrettyPrintReq,
190
+ ReadReq
191
+ >(name, impl),
192
+ );
193
+
194
+ /**
195
+ * Look up a registered {@link AuthProvider} by name. Fails with
196
+ * {@link AuthError} if the provider hasn't been registered (typically because
197
+ * its layer hasn't been built).
198
+ */
199
+ export const getAuthProvider = <
200
+ Config extends { method: string } = any,
201
+ Credentials = any,
202
+ >(
203
+ name: string,
204
+ ): Effect.Effect<AuthProvider<Config, Credentials>, AuthError, AuthProviders> =>
205
+ Effect.flatMap(AuthProviders.asEffect(), (registry) =>
206
+ registry[name] == null
207
+ ? Effect.fail(
208
+ new AuthError({
209
+ message: `AuthProvider '${name}' is not registered. Make sure its layer has been built.`,
210
+ }),
211
+ )
212
+ : Effect.succeed(registry[name] as AuthProvider<Config, Credentials>),
213
+ );
@@ -1,72 +1,135 @@
1
+ import * as Config from "effect/Config";
2
+ import * as ConfigProvider from "effect/ConfigProvider";
3
+ import * as Context from "effect/Context";
1
4
  import * as Effect from "effect/Effect";
2
5
  import * as FileSystem from "effect/FileSystem";
3
- import type { PlatformError } from "effect/PlatformError";
4
6
  import os from "node:os";
5
7
  import path from "pathe";
8
+ import type { AuthProvider, ConfigureContext } from "./AuthProvider.ts";
6
9
 
7
10
  export const rootDir = path.join(os.homedir(), ".alchemy");
8
11
  export const configFilePath = path.join(rootDir, "profiles.json");
9
12
 
10
- export const CONFIG_VERSION = 2;
13
+ /**
14
+ * Config key consulted by the various `fromAuthProvider` /
15
+ * `fromEnvironment` layers to pick which named profile in
16
+ * `~/.alchemy/profiles.json` to use. Defaults to `"default"`.
17
+ */
18
+ export const ALCHEMY_PROFILE = Config.string("ALCHEMY_PROFILE").pipe(
19
+ Config.withDefault("default"),
20
+ );
11
21
 
12
- export interface AlchemyProfiles {
13
- version: typeof CONFIG_VERSION;
14
- profiles: Record<string, AlchemyProfile>;
15
- }
22
+ export const CONFIG_VERSION = 0;
23
+
24
+ export class AlchemyConfig extends Context.Service<
25
+ AlchemyConfig,
26
+ {
27
+ version: typeof CONFIG_VERSION;
28
+ profiles: {
29
+ [profileName: string]: AlchemyProfile;
30
+ };
31
+ }
32
+ >()("Alchemy::Profiles") {}
16
33
 
17
- export type AlchemyProfile = Record<string, { method: string }>;
34
+ export interface AlchemyProfile {
35
+ [providerName: string]: {
36
+ /**
37
+ * The method used to login to the provider. Different providers may use different methods, but common ones are:
38
+ * - oauth: OAuth authentication
39
+ * - api-key: API key authentication
40
+ * - username-password: Username and password authentication
41
+ * - token: Token authentication
42
+ * - certificate: Certificate authentication
43
+ * - ssh: SSH authentication
44
+ * - other: Other authentication methods
45
+ */
46
+ method: string;
47
+ };
48
+ }
18
49
 
19
- const emptyConfig = (): AlchemyProfiles => ({
50
+ const emptyConfig = (): AlchemyConfig["Service"] => ({
20
51
  version: CONFIG_VERSION,
21
52
  profiles: {},
22
53
  });
23
54
 
24
- export const readConfig: Effect.Effect<
25
- AlchemyProfiles,
26
- never,
27
- FileSystem.FileSystem
28
- > = Effect.gen(function* () {
29
- const fs = yield* FileSystem.FileSystem;
30
- const data = yield* fs
31
- .readFileString(configFilePath)
32
- .pipe(Effect.orElseSucceed(() => undefined));
33
- if (data === undefined) return emptyConfig();
34
- try {
35
- const parsed = JSON.parse(data);
36
- if (parsed?.version !== CONFIG_VERSION) {
37
- return emptyConfig();
38
- }
39
- return parsed as AlchemyProfiles;
40
- } catch {
41
- return emptyConfig();
42
- }
43
- });
55
+ export const readConfig = FileSystem.FileSystem.asEffect().pipe(
56
+ Effect.flatMap((fs) => fs.readFileString(configFilePath)),
57
+ Effect.flatMap((data) =>
58
+ Effect.try({
59
+ try: () => {
60
+ const parsed = JSON.parse(data);
61
+ if (parsed?.version !== CONFIG_VERSION) {
62
+ // TODO(sam): this is destructive, should we maintain a chain of migrations from 0 to current?
63
+ return emptyConfig();
64
+ }
65
+ return parsed as AlchemyConfig["Service"];
66
+ },
67
+ catch: emptyConfig,
68
+ }),
69
+ ),
70
+ Effect.orElseSucceed(emptyConfig),
71
+ );
72
+
73
+ export const writeConfig = (config: AlchemyConfig["Service"]) =>
74
+ FileSystem.FileSystem.asEffect().pipe(
75
+ Effect.tap((fs) =>
76
+ fs.makeDirectory(path.dirname(configFilePath), { recursive: true }),
77
+ ),
78
+ Effect.flatMap((fs) =>
79
+ fs.writeFileString(configFilePath, JSON.stringify(config, null, 2)),
80
+ ),
81
+ );
82
+
83
+ export const getProfile = (name: string) =>
84
+ readConfig.pipe(Effect.map((config) => config.profiles[name]));
44
85
 
45
- export const writeConfig = (
46
- config: AlchemyProfiles,
47
- ): Effect.Effect<void, PlatformError, FileSystem.FileSystem> =>
48
- Effect.gen(function* () {
49
- const fs = yield* FileSystem.FileSystem;
50
- yield* fs.makeDirectory(path.dirname(configFilePath), {
51
- recursive: true,
52
- });
53
- yield* fs.writeFileString(configFilePath, JSON.stringify(config, null, 2));
54
- });
86
+ export const setProfile = (name: string, profile: AlchemyProfile) =>
87
+ readConfig.pipe(
88
+ Effect.tap((config) =>
89
+ Effect.sync(() => (config.profiles[name] = profile)),
90
+ ),
91
+ Effect.flatMap(writeConfig),
92
+ );
55
93
 
56
- export const getProfile = (
57
- name: string,
58
- ): Effect.Effect<AlchemyProfile | undefined, never, FileSystem.FileSystem> =>
59
- Effect.gen(function* () {
60
- const config = yield* readConfig;
61
- return config.profiles[name];
62
- });
94
+ /**
95
+ * Returns a `ConfigProvider` that overrides `ALCHEMY_PROFILE` with the
96
+ * given `profile` (when explicitly passed via the CLI `--profile` flag),
97
+ * falling through to `base` for everything else.
98
+ *
99
+ * Use this to let the CLI's `--profile <name>` win over `$ALCHEMY_PROFILE`
100
+ * without disturbing other config lookups.
101
+ */
102
+ export const withProfileOverride = (
103
+ base: ConfigProvider.ConfigProvider,
104
+ profile: string | undefined,
105
+ ): ConfigProvider.ConfigProvider => {
106
+ if (profile === undefined) return base;
107
+ const overrides: Record<string, string> = { ALCHEMY_PROFILE: profile };
108
+ const overrideProvider = ConfigProvider.make((path) =>
109
+ Effect.succeed(
110
+ path.length === 1 && typeof path[0] === "string" && path[0] in overrides
111
+ ? ConfigProvider.makeValue(overrides[path[0]]!)
112
+ : undefined,
113
+ ),
114
+ );
115
+ return ConfigProvider.orElse(base)(overrideProvider);
116
+ };
63
117
 
64
- export const setProfile = (
65
- name: string,
66
- profile: AlchemyProfile,
67
- ): Effect.Effect<void, PlatformError, FileSystem.FileSystem> =>
68
- Effect.gen(function* () {
69
- const config = yield* readConfig;
70
- config.profiles[name] = profile;
71
- yield* writeConfig(config);
72
- });
118
+ /**
119
+ * Load the stored config for the given AuthProvider in `profileName`.
120
+ * If absent, run the provider's `configure` step (passing through `ctx` so
121
+ * providers can pick a CI-friendly default) and persist the resulting config
122
+ * under the provider's name.
123
+ */
124
+ export const loadOrConfigure = <Config extends { method: string }>(
125
+ auth: AuthProvider<Config>,
126
+ profileName: string,
127
+ ctx: ConfigureContext,
128
+ ) =>
129
+ Effect.flatMap(getProfile(profileName), (existing) =>
130
+ existing?.[auth.name]
131
+ ? Effect.succeed(existing?.[auth.name])
132
+ : Effect.tap(auth.configure(profileName, ctx), (config) =>
133
+ setProfile(profileName, { ...existing, [auth.name]: config }),
134
+ ),
135
+ );
package/src/Auth/index.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from "./AuthProvider.ts";
2
- export type { AlchemyProfile, AlchemyProfiles } from "./Profile.ts";
2
+ export type * from "./Profile.ts";