alchemy 2.0.0-beta.34 → 2.0.0-beta.35

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 (356) hide show
  1. package/bin/cli.js +8 -7
  2. package/bin/exec.js +226 -52
  3. package/bin/exec.js.map +1 -1
  4. package/lib/AWS/AuthProvider.d.ts +7 -6
  5. package/lib/AWS/AuthProvider.d.ts.map +1 -1
  6. package/lib/AWS/AuthProvider.js +143 -134
  7. package/lib/AWS/AuthProvider.js.map +1 -1
  8. package/lib/AWS/Bootstrap.d.ts +2 -2
  9. package/lib/AWS/Bootstrap.d.ts.map +1 -1
  10. package/lib/AWS/EC2/hosted.d.ts +1 -1
  11. package/lib/AWS/Environment.d.ts +25 -3
  12. package/lib/AWS/Environment.d.ts.map +1 -1
  13. package/lib/AWS/Environment.js +47 -3
  14. package/lib/AWS/Environment.js.map +1 -1
  15. package/lib/AWS/IAM/OpenIDConnectProvider.d.ts +14 -6
  16. package/lib/AWS/IAM/OpenIDConnectProvider.d.ts.map +1 -1
  17. package/lib/AWS/IAM/OpenIDConnectProvider.js +6 -3
  18. package/lib/AWS/IAM/OpenIDConnectProvider.js.map +1 -1
  19. package/lib/AWS/IAM/Policy.d.ts +1 -1
  20. package/lib/AWS/IAM/Policy.d.ts.map +1 -1
  21. package/lib/AWS/IAM/Policy.js.map +1 -1
  22. package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
  23. package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
  24. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
  25. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
  26. package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
  27. package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
  28. package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
  29. package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
  30. package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
  31. package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
  32. package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
  33. package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
  34. package/lib/AWS/Providers.d.ts +1 -1
  35. package/lib/AWS/Providers.d.ts.map +1 -1
  36. package/lib/AWS/Providers.js +2 -1
  37. package/lib/AWS/Providers.js.map +1 -1
  38. package/lib/Auth/Credentials.d.ts +21 -6
  39. package/lib/Auth/Credentials.d.ts.map +1 -1
  40. package/lib/Auth/Credentials.js +30 -31
  41. package/lib/Auth/Credentials.js.map +1 -1
  42. package/lib/Auth/Profile.d.ts +31 -34
  43. package/lib/Auth/Profile.d.ts.map +1 -1
  44. package/lib/Auth/Profile.js +46 -31
  45. package/lib/Auth/Profile.js.map +1 -1
  46. package/lib/Axiom/AuthProvider.d.ts +2 -1
  47. package/lib/Axiom/AuthProvider.d.ts.map +1 -1
  48. package/lib/Axiom/AuthProvider.js +149 -143
  49. package/lib/Axiom/AuthProvider.js.map +1 -1
  50. package/lib/Axiom/Credentials.d.ts +2 -1
  51. package/lib/Axiom/Credentials.d.ts.map +1 -1
  52. package/lib/Axiom/Credentials.js +4 -4
  53. package/lib/Axiom/Credentials.js.map +1 -1
  54. package/lib/Axiom/Providers.d.ts +1 -1
  55. package/lib/Axiom/Providers.d.ts.map +1 -1
  56. package/lib/Axiom/Providers.js +3 -1
  57. package/lib/Axiom/Providers.js.map +1 -1
  58. package/lib/Cli/LoggingCli.d.ts.map +1 -1
  59. package/lib/Cli/LoggingCli.js +105 -7
  60. package/lib/Cli/LoggingCli.js.map +1 -1
  61. package/lib/Cli/checkVersion.d.ts +13 -0
  62. package/lib/Cli/checkVersion.d.ts.map +1 -0
  63. package/lib/Cli/checkVersion.js +47 -0
  64. package/lib/Cli/checkVersion.js.map +1 -0
  65. package/lib/Cli/commands/_shared.d.ts +2 -2
  66. package/lib/Cli/commands/_shared.d.ts.map +1 -1
  67. package/lib/Cli/commands/_shared.js +3 -3
  68. package/lib/Cli/commands/_shared.js.map +1 -1
  69. package/lib/Cli/commands/aws.d.ts +6 -0
  70. package/lib/Cli/commands/aws.d.ts.map +1 -0
  71. package/lib/Cli/commands/aws.js +63 -0
  72. package/lib/Cli/commands/aws.js.map +1 -0
  73. package/lib/Cli/commands/cloudflare.d.ts +17 -0
  74. package/lib/Cli/commands/cloudflare.d.ts.map +1 -0
  75. package/lib/Cli/commands/cloudflare.js +111 -0
  76. package/lib/Cli/commands/cloudflare.js.map +1 -0
  77. package/lib/Cli/commands/deploy.d.ts +6 -5
  78. package/lib/Cli/commands/deploy.d.ts.map +1 -1
  79. package/lib/Cli/commands/deploy.js +10 -10
  80. package/lib/Cli/commands/deploy.js.map +1 -1
  81. package/lib/Cli/commands/dev.d.ts.map +1 -1
  82. package/lib/Cli/commands/dev.js +16 -16
  83. package/lib/Cli/commands/dev.js.map +1 -1
  84. package/lib/Cli/commands/login.d.ts +2 -1
  85. package/lib/Cli/commands/login.d.ts.map +1 -1
  86. package/lib/Cli/commands/login.js +9 -8
  87. package/lib/Cli/commands/login.js.map +1 -1
  88. package/lib/Cli/commands/logs.d.ts +1 -1
  89. package/lib/Cli/commands/logs.d.ts.map +1 -1
  90. package/lib/Cli/commands/logs.js +7 -7
  91. package/lib/Cli/commands/logs.js.map +1 -1
  92. package/lib/Cli/commands/profile.d.ts +3 -1
  93. package/lib/Cli/commands/profile.d.ts.map +1 -1
  94. package/lib/Cli/commands/profile.js +14 -11
  95. package/lib/Cli/commands/profile.js.map +1 -1
  96. package/lib/Cli/commands/state.d.ts +1 -1
  97. package/lib/Cli/commands/state.d.ts.map +1 -1
  98. package/lib/Cli/commands/state.js +8 -8
  99. package/lib/Cli/commands/state.js.map +1 -1
  100. package/lib/Cli/commands/tail.d.ts +1 -1
  101. package/lib/Cli/commands/tail.d.ts.map +1 -1
  102. package/lib/Cli/commands/tail.js +7 -7
  103. package/lib/Cli/commands/tail.js.map +1 -1
  104. package/lib/Cli/exec.d.ts.map +1 -1
  105. package/lib/Cli/exec.js +5 -3
  106. package/lib/Cli/exec.js.map +1 -1
  107. package/lib/Cli/main.d.ts.map +1 -1
  108. package/lib/Cli/main.js +17 -5
  109. package/lib/Cli/main.js.map +1 -1
  110. package/lib/Cli/selectCli.d.ts +12 -0
  111. package/lib/Cli/selectCli.d.ts.map +1 -0
  112. package/lib/Cli/selectCli.js +32 -0
  113. package/lib/Cli/selectCli.js.map +1 -0
  114. package/lib/Cloudflare/Auth/AuthProvider.d.ts +2 -1
  115. package/lib/Cloudflare/Auth/AuthProvider.d.ts.map +1 -1
  116. package/lib/Cloudflare/Auth/AuthProvider.js +235 -214
  117. package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
  118. package/lib/Cloudflare/CloudflareEnvironment.d.ts +2 -1
  119. package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -1
  120. package/lib/Cloudflare/CloudflareEnvironment.js +3 -2
  121. package/lib/Cloudflare/CloudflareEnvironment.js.map +1 -1
  122. package/lib/Cloudflare/Credentials.d.ts +2 -1
  123. package/lib/Cloudflare/Credentials.d.ts.map +1 -1
  124. package/lib/Cloudflare/Credentials.js +4 -4
  125. package/lib/Cloudflare/Credentials.js.map +1 -1
  126. package/lib/Cloudflare/D1/D1Clone.d.ts +2 -1
  127. package/lib/Cloudflare/D1/D1Clone.d.ts.map +1 -1
  128. package/lib/Cloudflare/D1/D1Database.d.ts +2 -1
  129. package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
  130. package/lib/Cloudflare/D1/D1Import.d.ts +3 -1
  131. package/lib/Cloudflare/D1/D1Import.d.ts.map +1 -1
  132. package/lib/Cloudflare/Local/Sidecar.d.ts +11 -4
  133. package/lib/Cloudflare/Local/Sidecar.d.ts.map +1 -1
  134. package/lib/Cloudflare/Local/Sidecar.js +8 -6
  135. package/lib/Cloudflare/Local/Sidecar.js.map +1 -1
  136. package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +1 -1
  137. package/lib/Cloudflare/Local/SidecarHandlers.js +1 -5
  138. package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
  139. package/lib/Cloudflare/Local/SidecarServer.js +5 -2
  140. package/lib/Cloudflare/Local/SidecarServer.js.map +1 -1
  141. package/lib/Cloudflare/Logs.d.ts +5 -0
  142. package/lib/Cloudflare/Logs.d.ts.map +1 -1
  143. package/lib/Cloudflare/Logs.js +70 -1
  144. package/lib/Cloudflare/Logs.js.map +1 -1
  145. package/lib/Cloudflare/Providers.d.ts +1 -1
  146. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  147. package/lib/Cloudflare/Providers.js +4 -1
  148. package/lib/Cloudflare/Providers.js.map +1 -1
  149. package/lib/Cloudflare/Queue/Queue.d.ts +1 -1
  150. package/lib/Cloudflare/Queue/Queue.js +1 -1
  151. package/lib/Cloudflare/Queue/QueueConsumer.d.ts +6 -2
  152. package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -1
  153. package/lib/Cloudflare/Queue/QueueConsumer.js +194 -53
  154. package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -1
  155. package/lib/Cloudflare/Queue/QueueEventSource.d.ts +106 -0
  156. package/lib/Cloudflare/Queue/QueueEventSource.d.ts.map +1 -0
  157. package/lib/Cloudflare/Queue/QueueEventSource.js +145 -0
  158. package/lib/Cloudflare/Queue/QueueEventSource.js.map +1 -0
  159. package/lib/Cloudflare/Queue/index.d.ts +1 -0
  160. package/lib/Cloudflare/Queue/index.d.ts.map +1 -1
  161. package/lib/Cloudflare/Queue/index.js +1 -0
  162. package/lib/Cloudflare/Queue/index.js.map +1 -1
  163. package/lib/Cloudflare/R2/R2Bucket.d.ts +94 -0
  164. package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
  165. package/lib/Cloudflare/R2/R2Bucket.js +186 -2
  166. package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
  167. package/lib/Cloudflare/StateStore/State.d.ts +4 -3
  168. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
  169. package/lib/Cloudflare/StateStore/State.js +16 -8
  170. package/lib/Cloudflare/StateStore/State.js.map +1 -1
  171. package/lib/Cloudflare/VpcService/VpcServiceRef.d.ts +1 -1
  172. package/lib/Cloudflare/VpcService/VpcServiceRef.d.ts.map +1 -1
  173. package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
  174. package/lib/Cloudflare/Website/StaticSite.js +10 -1
  175. package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
  176. package/lib/Cloudflare/Workers/Assets.d.ts +1 -1
  177. package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
  178. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  179. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +11 -1
  180. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  181. package/lib/Cloudflare/Workers/Worker.d.ts +9 -7
  182. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  183. package/lib/Cloudflare/Workers/Worker.js +62 -142
  184. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  185. package/lib/Cloudflare/Workers/WorkerBundle.d.ts +2 -0
  186. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  187. package/lib/Cloudflare/Workers/WorkerBundle.js +21 -7
  188. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  189. package/lib/Cloudflare/Zone.d.ts +14 -0
  190. package/lib/Cloudflare/Zone.d.ts.map +1 -0
  191. package/lib/Cloudflare/Zone.js +44 -0
  192. package/lib/Cloudflare/Zone.js.map +1 -0
  193. package/lib/Drizzle/Schema.d.ts.map +1 -1
  194. package/lib/Drizzle/Schema.js +20 -5
  195. package/lib/Drizzle/Schema.js.map +1 -1
  196. package/lib/GitHub/AuthProvider.d.ts +3 -1
  197. package/lib/GitHub/AuthProvider.d.ts.map +1 -1
  198. package/lib/GitHub/AuthProvider.js +114 -108
  199. package/lib/GitHub/AuthProvider.js.map +1 -1
  200. package/lib/GitHub/Credentials.d.ts +2 -1
  201. package/lib/GitHub/Credentials.d.ts.map +1 -1
  202. package/lib/GitHub/Credentials.js +4 -4
  203. package/lib/GitHub/Credentials.js.map +1 -1
  204. package/lib/GitHub/Providers.d.ts +1 -1
  205. package/lib/GitHub/Providers.d.ts.map +1 -1
  206. package/lib/GitHub/Providers.js +3 -1
  207. package/lib/GitHub/Providers.js.map +1 -1
  208. package/lib/GitHub/Secrets.d.ts.map +1 -1
  209. package/lib/GitHub/Secrets.js +14 -1
  210. package/lib/GitHub/Secrets.js.map +1 -1
  211. package/lib/GitHub/Variables.d.ts +40 -0
  212. package/lib/GitHub/Variables.d.ts.map +1 -0
  213. package/lib/GitHub/Variables.js +28 -0
  214. package/lib/GitHub/Variables.js.map +1 -0
  215. package/lib/GitHub/index.d.ts +1 -0
  216. package/lib/GitHub/index.d.ts.map +1 -1
  217. package/lib/GitHub/index.js +1 -0
  218. package/lib/GitHub/index.js.map +1 -1
  219. package/lib/Neon/AuthProvider.d.ts +3 -1
  220. package/lib/Neon/AuthProvider.d.ts.map +1 -1
  221. package/lib/Neon/AuthProvider.js +87 -80
  222. package/lib/Neon/AuthProvider.js.map +1 -1
  223. package/lib/Neon/Credentials.d.ts +2 -1
  224. package/lib/Neon/Credentials.d.ts.map +1 -1
  225. package/lib/Neon/Credentials.js +4 -4
  226. package/lib/Neon/Credentials.js.map +1 -1
  227. package/lib/Neon/NeonEnvironment.d.ts +2 -1
  228. package/lib/Neon/NeonEnvironment.d.ts.map +1 -1
  229. package/lib/Neon/NeonEnvironment.js +3 -2
  230. package/lib/Neon/NeonEnvironment.js.map +1 -1
  231. package/lib/Neon/Project.d.ts +16 -0
  232. package/lib/Neon/Project.d.ts.map +1 -1
  233. package/lib/Neon/Project.js +25 -0
  234. package/lib/Neon/Project.js.map +1 -1
  235. package/lib/Neon/Providers.d.ts +1 -1
  236. package/lib/Neon/Providers.d.ts.map +1 -1
  237. package/lib/Neon/Providers.js +3 -1
  238. package/lib/Neon/Providers.js.map +1 -1
  239. package/lib/Neon/api.d.ts +1 -0
  240. package/lib/Neon/api.d.ts.map +1 -1
  241. package/lib/Neon/api.js +1 -0
  242. package/lib/Neon/api.js.map +1 -1
  243. package/lib/Sidecar/RpcClient.d.ts.map +1 -1
  244. package/lib/Sidecar/RpcClient.js +8 -5
  245. package/lib/Sidecar/RpcClient.js.map +1 -1
  246. package/lib/Sidecar/RpcPaths.d.ts +5 -0
  247. package/lib/Sidecar/RpcPaths.d.ts.map +1 -1
  248. package/lib/Sidecar/RpcPaths.js +10 -1
  249. package/lib/Sidecar/RpcPaths.js.map +1 -1
  250. package/lib/Sidecar/RpcServer.d.ts +24 -4
  251. package/lib/Sidecar/RpcServer.d.ts.map +1 -1
  252. package/lib/Sidecar/RpcServer.js +70 -15
  253. package/lib/Sidecar/RpcServer.js.map +1 -1
  254. package/lib/Sidecar/RpcServerBun.d.ts +4 -0
  255. package/lib/Sidecar/RpcServerBun.d.ts.map +1 -0
  256. package/lib/Sidecar/RpcServerBun.js +28 -0
  257. package/lib/Sidecar/RpcServerBun.js.map +1 -0
  258. package/lib/Sidecar/RpcServerNode.d.ts +4 -0
  259. package/lib/Sidecar/RpcServerNode.d.ts.map +1 -0
  260. package/lib/Sidecar/RpcServerNode.js +39 -0
  261. package/lib/Sidecar/RpcServerNode.js.map +1 -0
  262. package/lib/Sidecar/RpcServices.d.ts +6 -0
  263. package/lib/Sidecar/RpcServices.d.ts.map +1 -0
  264. package/lib/Sidecar/RpcServices.js +29 -0
  265. package/lib/Sidecar/RpcServices.js.map +1 -0
  266. package/lib/Stack.d.ts +5 -3
  267. package/lib/Stack.d.ts.map +1 -1
  268. package/lib/Stack.js +3 -1
  269. package/lib/Stack.js.map +1 -1
  270. package/lib/Test/Core.d.ts.map +1 -1
  271. package/lib/Test/Core.js +5 -4
  272. package/lib/Test/Core.js.map +1 -1
  273. package/lib/Util/PlatformServices.js +1 -1
  274. package/lib/tsconfig.test.tsbuildinfo +1 -1
  275. package/package.json +15 -12
  276. package/src/AWS/AuthProvider.ts +269 -259
  277. package/src/AWS/Environment.ts +57 -3
  278. package/src/AWS/IAM/OpenIDConnectProvider.ts +19 -8
  279. package/src/AWS/IAM/Policy.ts +1 -1
  280. package/src/AWS/Providers.ts +2 -0
  281. package/src/Auth/Credentials.ts +82 -46
  282. package/src/Auth/Profile.ts +123 -69
  283. package/src/Axiom/AuthProvider.ts +263 -255
  284. package/src/Axiom/Credentials.ts +3 -4
  285. package/src/Axiom/Providers.ts +4 -0
  286. package/src/Cli/LoggingCli.ts +127 -11
  287. package/src/Cli/checkVersion.ts +57 -0
  288. package/src/Cli/commands/_shared.ts +4 -4
  289. package/src/Cli/commands/aws.ts +127 -0
  290. package/src/Cli/commands/cloudflare.ts +222 -0
  291. package/src/Cli/commands/deploy.ts +11 -10
  292. package/src/Cli/commands/dev.ts +28 -33
  293. package/src/Cli/commands/login.ts +9 -12
  294. package/src/Cli/commands/logs.ts +8 -8
  295. package/src/Cli/commands/profile.ts +14 -16
  296. package/src/Cli/commands/state.ts +8 -8
  297. package/src/Cli/commands/tail.ts +8 -8
  298. package/src/Cli/exec.ts +7 -3
  299. package/src/Cli/main.ts +20 -5
  300. package/src/Cli/selectCli.ts +33 -0
  301. package/src/Cloudflare/Auth/AuthProvider.ts +445 -430
  302. package/src/Cloudflare/CloudflareEnvironment.ts +3 -2
  303. package/src/Cloudflare/Credentials.ts +3 -4
  304. package/src/Cloudflare/Local/Sidecar.ts +13 -10
  305. package/src/Cloudflare/Local/SidecarHandlers.ts +8 -13
  306. package/src/Cloudflare/Local/SidecarServer.ts +6 -1
  307. package/src/Cloudflare/Logs.ts +115 -1
  308. package/src/Cloudflare/Providers.ts +6 -0
  309. package/src/Cloudflare/Queue/Queue.ts +1 -1
  310. package/src/Cloudflare/Queue/QueueConsumer.ts +262 -60
  311. package/src/Cloudflare/Queue/QueueEventSource.ts +234 -0
  312. package/src/Cloudflare/Queue/index.ts +1 -0
  313. package/src/Cloudflare/R2/R2Bucket.ts +337 -2
  314. package/src/Cloudflare/StateStore/State.ts +25 -16
  315. package/src/Cloudflare/Website/StaticSite.ts +11 -1
  316. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +9 -1
  317. package/src/Cloudflare/Workers/Worker.ts +83 -203
  318. package/src/Cloudflare/Workers/WorkerBundle.ts +38 -12
  319. package/src/Cloudflare/Zone.ts +88 -0
  320. package/src/Drizzle/Schema.ts +21 -5
  321. package/src/GitHub/AuthProvider.ts +221 -217
  322. package/src/GitHub/Credentials.ts +3 -4
  323. package/src/GitHub/Providers.ts +4 -0
  324. package/src/GitHub/Secrets.ts +25 -1
  325. package/src/GitHub/Variables.ts +54 -0
  326. package/src/GitHub/index.ts +1 -0
  327. package/src/Neon/AuthProvider.ts +160 -154
  328. package/src/Neon/Credentials.ts +3 -4
  329. package/src/Neon/NeonEnvironment.ts +3 -2
  330. package/src/Neon/Project.ts +42 -0
  331. package/src/Neon/Providers.ts +4 -0
  332. package/src/Neon/api.ts +2 -0
  333. package/src/Sidecar/RpcClient.ts +8 -7
  334. package/src/Sidecar/RpcPaths.ts +11 -1
  335. package/src/Sidecar/RpcServer.ts +97 -24
  336. package/src/Sidecar/RpcServerBun.ts +41 -0
  337. package/src/Sidecar/RpcServerNode.ts +51 -0
  338. package/src/Sidecar/RpcServices.ts +48 -0
  339. package/src/Stack.ts +8 -0
  340. package/src/Test/Core.ts +10 -4
  341. package/src/Util/PlatformServices.ts +1 -1
  342. package/lib/Cli/commands/bootstrap.d.ts +0 -20
  343. package/lib/Cli/commands/bootstrap.d.ts.map +0 -1
  344. package/lib/Cli/commands/bootstrap.js +0 -107
  345. package/lib/Cli/commands/bootstrap.js.map +0 -1
  346. package/lib/Sidecar/RpcTransport.d.ts +0 -22
  347. package/lib/Sidecar/RpcTransport.d.ts.map +0 -1
  348. package/lib/Sidecar/RpcTransport.js +0 -81
  349. package/lib/Sidecar/RpcTransport.js.map +0 -1
  350. package/lib/Test/TestCli.d.ts +0 -19
  351. package/lib/Test/TestCli.d.ts.map +0 -1
  352. package/lib/Test/TestCli.js +0 -175
  353. package/lib/Test/TestCli.js.map +0 -1
  354. package/src/Cli/commands/bootstrap.ts +0 -216
  355. package/src/Sidecar/RpcTransport.ts +0 -85
  356. package/src/Test/TestCli.ts +0 -221
@@ -1,21 +1,137 @@
1
+ import * as Console from "effect/Console";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Layer from "effect/Layer";
4
+ import type { CRUD, Plan } from "../Plan.ts";
3
5
  import { Cli } from "./Cli.ts";
6
+ import type { ApplyEvent, ApplyStatus } from "./Event.ts";
7
+
8
+ const ESC = "\x1b[";
9
+ const RESET = `${ESC}0m`;
10
+ const useColor = process.stdout.hasColors?.() ?? !!process.stdout.isTTY;
11
+ const c = (code: string, s: string) =>
12
+ useColor ? `${ESC}${code}m${s}${RESET}` : s;
13
+ const dim = (s: string) => c("2", s);
14
+ const bold = (s: string) => c("1", s);
15
+ const red = (s: string) => c("31", s);
16
+ const green = (s: string) => c("32", s);
17
+ const yellow = (s: string) => c("33", s);
18
+ const blue = (s: string) => c("34", s);
19
+ const magenta = (s: string) => c("35", s);
20
+ const cyan = (s: string) => c("36", s);
21
+
22
+ const actionColor: Record<CRUD["action"], (s: string) => string> = {
23
+ create: green,
24
+ update: yellow,
25
+ replace: magenta,
26
+ delete: red,
27
+ noop: dim,
28
+ };
29
+
30
+ const statusColor = (status: ApplyStatus): ((s: string) => string) => {
31
+ switch (status) {
32
+ case "created":
33
+ case "updated":
34
+ case "replaced":
35
+ return green;
36
+ case "deleted":
37
+ return dim;
38
+ case "fail":
39
+ return red;
40
+ case "attaching":
41
+ case "post-attach":
42
+ return cyan;
43
+ default:
44
+ return yellow;
45
+ }
46
+ };
47
+
48
+ const tag = (id: string) => bold(`[${id}]`);
49
+
50
+ const isTerminal = (status: ApplyStatus): boolean =>
51
+ status === "created" ||
52
+ status === "updated" ||
53
+ status === "deleted" ||
54
+ status === "replaced" ||
55
+ status === "fail";
56
+
57
+ const formatPlanLines = (plan: Plan): string[] => {
58
+ const items = [
59
+ ...Object.values(plan.resources),
60
+ ...Object.values(plan.deletions),
61
+ ] as CRUD[];
62
+ if (items.length === 0) return [bold("Plan:") + " no changes"];
63
+
64
+ const counts = items.reduce(
65
+ (acc, item) => ((acc[item.action] = (acc[item.action] ?? 0) + 1), acc),
66
+ {} as Record<CRUD["action"], number>,
67
+ );
68
+ const summary = (["create", "update", "replace", "delete", "noop"] as const)
69
+ .filter((a) => counts[a])
70
+ .map((a) => actionColor[a](`${counts[a]} to ${a}`))
71
+ .join(dim(", "));
72
+
73
+ const sorted = [...items].sort((a, b) =>
74
+ a.resource.LogicalId.localeCompare(b.resource.LogicalId),
75
+ );
76
+ const lines = [`${bold("Plan:")} ${summary}`];
77
+ for (const item of sorted) {
78
+ const action = actionColor[item.action](item.action);
79
+ lines.push(`${tag(item.resource.LogicalId)} ${action}`);
80
+ for (const binding of item.bindings) {
81
+ if (binding.action === "noop") continue;
82
+ const bindingAction = actionColor[binding.action](binding.action);
83
+ lines.push(
84
+ `${tag(`${item.resource.LogicalId}/${binding.sid}`)} ${bindingAction}`,
85
+ );
86
+ }
87
+ }
88
+ return lines;
89
+ };
4
90
 
5
91
  export const LoggingCli = Layer.succeed(
6
92
  Cli,
7
93
  Cli.of({
8
- approvePlan: () => Effect.succeed(true),
9
- displayPlan: () => Effect.void,
10
- startApplySession: () =>
11
- Effect.succeed({
12
- done: () => Effect.void,
13
- emit: (event) =>
14
- Effect.log(
15
- event.kind === "status-change"
16
- ? `${event.status} ${event.id}(${event.type})`
17
- : `${event.id}: ${event.message}`,
18
- ),
94
+ approvePlan: (plan) =>
95
+ Effect.gen(function* () {
96
+ for (const line of formatPlanLines(plan)) yield* Console.log(line);
97
+ yield* Console.log(
98
+ `\n${yellow("Non-interactive terminal detected.")} Pass ${bold("--yes")} to approve, or set ${bold("ALCHEMY_TUI=1")} for the interactive UI.`,
99
+ );
100
+ return false;
101
+ }),
102
+ displayPlan: (plan) =>
103
+ Effect.gen(function* () {
104
+ for (const line of formatPlanLines(plan)) yield* Console.log(line);
105
+ }),
106
+ startApplySession: (plan) =>
107
+ Effect.gen(function* () {
108
+ for (const line of formatPlanLines(plan)) yield* Console.log(line);
109
+ yield* Console.log("");
110
+
111
+ const counts = { ok: 0, fail: 0 };
112
+ return {
113
+ emit: (event: ApplyEvent) =>
114
+ Effect.sync(() => {
115
+ if (event.kind === "annotate") {
116
+ console.log(`${tag(event.id)} ${blue(event.message)}`);
117
+ return;
118
+ }
119
+ const id = event.bindingId
120
+ ? `${event.id}/${event.bindingId}`
121
+ : event.id;
122
+ const status = statusColor(event.status)(event.status);
123
+ const msg = event.message ? ` ${dim("—")} ${event.message}` : "";
124
+ console.log(`${tag(id)} ${status}${msg}`);
125
+ if (isTerminal(event.status)) {
126
+ if (event.status === "fail") counts.fail++;
127
+ else counts.ok++;
128
+ }
129
+ }),
130
+ done: () =>
131
+ Console.log(
132
+ `\n${bold("Done:")} ${green(`${counts.ok} succeeded`)}${counts.fail ? dim(", ") + red(`${counts.fail} failed`) : ""}`,
133
+ ),
134
+ };
19
135
  }),
20
136
  }),
21
137
  );
@@ -0,0 +1,57 @@
1
+ import * as Duration from "effect/Duration";
2
+ import * as Effect from "effect/Effect";
3
+ import * as HttpClient from "effect/unstable/http/HttpClient";
4
+
5
+ import packageJson from "../../package.json" with { type: "json" };
6
+
7
+ const NPM_DIST_TAGS_URL =
8
+ "https://registry.npmjs.org/-/package/alchemy/dist-tags";
9
+
10
+ /**
11
+ * Pick the dist-tag matching the current channel. For pre-release versions
12
+ * like `2.0.0-beta.33`, npm's `latest` tag points at the most recent stable
13
+ * release — not the newest beta — so we match the prerelease identifier
14
+ * (`beta`, `next`, etc.), falling back through `next` → `latest`.
15
+ */
16
+ const pickDistTag = (
17
+ current: string,
18
+ distTags: Record<string, string>,
19
+ ): string | undefined => {
20
+ const pre = current.split("-", 2)[1];
21
+ if (pre) {
22
+ const id = pre.split(".")[0];
23
+ if (id && distTags[id]) return distTags[id];
24
+ if (distTags.next) return distTags.next;
25
+ }
26
+ return distTags.latest;
27
+ };
28
+
29
+ /**
30
+ * Fetch the published `alchemy` version on the dist-tag matching the
31
+ * current channel and log a warning if it's different from the bundled
32
+ * version. Best-effort: any failure (offline, registry hiccup, slow
33
+ * response) is swallowed silently.
34
+ */
35
+ export const checkLatestVersion = Effect.gen(function* () {
36
+ const http = yield* HttpClient.HttpClient;
37
+ const response = yield* http.get(NPM_DIST_TAGS_URL);
38
+ const distTags = (yield* response.json) as Record<string, string>;
39
+ if (typeof distTags !== "object" || distTags === null) return;
40
+ const current = packageJson.version;
41
+ const latest = pickDistTag(current, distTags);
42
+ if (typeof latest !== "string" || latest === current) return;
43
+ const installCmd =
44
+ typeof process !== "undefined" && (process as any).versions?.bun
45
+ ? `bun add alchemy@${latest}`
46
+ : `pnpm add alchemy@${latest}`;
47
+ yield* Effect.logWarning(
48
+ `alchemy ${latest} is available (you're on ${current}). ` +
49
+ `Run \`${installCmd}\` to upgrade.`,
50
+ );
51
+ }).pipe(
52
+ Effect.timeout(Duration.seconds(5)),
53
+ Effect.catch(() => Effect.void),
54
+ );
55
+
56
+ // Exported for tests.
57
+ export const _internal = { pickDistTag };
@@ -9,10 +9,10 @@ import * as Argument from "effect/unstable/cli/Argument";
9
9
  import * as CliError from "effect/unstable/cli/CliError";
10
10
  import * as Flag from "effect/unstable/cli/Flag";
11
11
 
12
- import { AuthError } from "../../Auth/AuthProvider";
13
- import type * as Stack from "../../Stack";
14
- import { recordCli } from "../../Telemetry/Metrics";
15
- import { PromptCancelled } from "../../Util/Clank";
12
+ import { AuthError } from "../../Auth/AuthProvider.ts";
13
+ import type * as Stack from "../../Stack.ts";
14
+ import { recordCli } from "../../Telemetry/Metrics.ts";
15
+ import { PromptCancelled } from "../../Util/Clank.ts";
16
16
 
17
17
  export const USER = Config.string("USER").pipe(
18
18
  Config.orElse(() => Config.string("USERNAME")),
@@ -0,0 +1,127 @@
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 "../../AWS/Bootstrap.ts";
18
+ import * as AWSCredentials from "../../AWS/Credentials.ts";
19
+ import * as AWSEnvironment from "../../AWS/Environment.ts";
20
+ import * as AWSRegion from "../../AWS/Region.ts";
21
+ import { loadConfigProvider } from "../../Util/ConfigProvider.ts";
22
+ import { fileLogger } from "../../Util/FileLogger.ts";
23
+
24
+ import { envFile, instrumentCommand } 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
+ const bootstrapCommand = Command.make(
46
+ "bootstrap",
47
+ {
48
+ envFile,
49
+ profile: awsProfile,
50
+ region: awsRegion,
51
+ destroy: bootstrapDestroy,
52
+ },
53
+ instrumentCommand(
54
+ "aws.bootstrap",
55
+ (a: { profile: string; region: string | undefined; destroy: boolean }) => ({
56
+ "alchemy.profile": a.profile,
57
+ "alchemy.region": a.region ?? "",
58
+ "alchemy.destroy": a.destroy,
59
+ }),
60
+ )(
61
+ Effect.fnUntraced(function* ({ envFile, profile, region, destroy }) {
62
+ const logger = Logger.layer([fileLogger("bootstrap.txt")], {
63
+ mergeWithExisting: true,
64
+ });
65
+
66
+ return yield* Effect.gen(function* () {
67
+ const ssoProfile = yield* Auth.loadProfile(profile);
68
+ if (!ssoProfile.sso_account_id) {
69
+ return yield* Effect.die(
70
+ `AWS SSO profile '${profile}' is missing sso_account_id`,
71
+ );
72
+ }
73
+
74
+ const ambient = yield* Effect.context<FileSystem | Path | HttpClient>();
75
+ const environment = AWSEnvironment.makeEnvironment({
76
+ accountId: ssoProfile.sso_account_id,
77
+ region: region ?? ssoProfile.region ?? "us-east-1",
78
+ credentials: Auth.loadProfileCredentials(profile).pipe(
79
+ Effect.provide(ambient),
80
+ ),
81
+ profile,
82
+ });
83
+
84
+ const awsLayers = Layer.provideMerge(
85
+ Layer.mergeAll(
86
+ AWSRegion.fromEnvironment,
87
+ AWSCredentials.fromEnvironment,
88
+ ),
89
+ environment,
90
+ );
91
+
92
+ return yield* Effect.gen(function* () {
93
+ const provider = yield* loadConfigProvider(envFile);
94
+ const bootstrapLayer = Layer.provide(
95
+ awsLayers,
96
+ Layer.succeed(ConfigProvider.ConfigProvider, provider),
97
+ );
98
+ if (destroy) {
99
+ yield* destroyBootstrapAws().pipe(
100
+ Effect.tap((result) =>
101
+ result.destroyed === 0
102
+ ? Console.log("✓ No bootstrap buckets found to destroy")
103
+ : Console.log(
104
+ `✓ Destroyed ${result.destroyed} bootstrap bucket(s): ${result.bucketNames.join(", ")}`,
105
+ ),
106
+ ),
107
+ Effect.provide(bootstrapLayer),
108
+ );
109
+ return;
110
+ }
111
+ yield* bootstrapAws().pipe(
112
+ Effect.tap(({ bucketName, created }) =>
113
+ created
114
+ ? Console.log(`✓ Created assets bucket: ${bucketName}`)
115
+ : Console.log(`✓ Assets bucket already exists: ${bucketName}`),
116
+ ),
117
+ Effect.provide(bootstrapLayer),
118
+ );
119
+ });
120
+ }).pipe(Effect.provide(logger));
121
+ }),
122
+ ),
123
+ );
124
+
125
+ export const awsCommand = Command.make("aws", {}).pipe(
126
+ Command.withSubcommands([bootstrapCommand]),
127
+ );
@@ -0,0 +1,222 @@
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 Stream from "effect/Stream";
8
+ import { Command, Flag } from "effect/unstable/cli";
9
+
10
+ import { AuthProviders } from "../../Auth/AuthProvider.ts";
11
+ import { withProfileOverride } from "../../Auth/Profile.ts";
12
+ import * as CloudflareAccess from "../../Cloudflare/Access.ts";
13
+ import { CloudflareAuth } from "../../Cloudflare/Auth/AuthProvider.ts";
14
+ import * as CloudflareEnvironment from "../../Cloudflare/CloudflareEnvironment.ts";
15
+ import * as CloudflareCredentials from "../../Cloudflare/Credentials.ts";
16
+ import { CloudflareLogs } from "../../Cloudflare/Logs.ts";
17
+ import { STATE_STORE_SCRIPT_NAME } from "../../Cloudflare/StateStore/Api.ts";
18
+ import { bootstrap as bootstrapCloudflare } from "../../Cloudflare/StateStore/State.ts";
19
+ import { loadConfigProvider } from "../../Util/ConfigProvider.ts";
20
+ import { fileLogger } from "../../Util/FileLogger.ts";
21
+
22
+ import {
23
+ envFile,
24
+ formatLocalTimestamp,
25
+ instrumentCommand,
26
+ parseSince,
27
+ profile,
28
+ } from "./_shared.ts";
29
+
30
+ /**
31
+ * Build the Cloudflare auth + environment layer stack used by every
32
+ * `alchemy cloudflare ...` subcommand. Mirrors the wiring inside
33
+ * `Cloudflare.state(...)` so the command can talk to the user's
34
+ * account out-of-band.
35
+ */
36
+ const cloudflareLayers = (
37
+ envFileOpt: Option.Option<string>,
38
+ profileName: string,
39
+ ) =>
40
+ Effect.gen(function* () {
41
+ const authProviders: AuthProviders["Service"] = {};
42
+ const authRegistry = Layer.succeed(AuthProviders, authProviders);
43
+ const authLayer = Layer.provideMerge(CloudflareAuth, authRegistry);
44
+ const cf = Layer.provideMerge(
45
+ Layer.mergeAll(
46
+ CloudflareCredentials.fromAuthProvider(),
47
+ CloudflareEnvironment.fromProfile(),
48
+ CloudflareAccess.AccessLive,
49
+ ),
50
+ authLayer,
51
+ );
52
+
53
+ const logger = Logger.layer([fileLogger("cloudflare.txt")], {
54
+ mergeWithExisting: true,
55
+ });
56
+
57
+ return Layer.mergeAll(
58
+ cf,
59
+ ConfigProvider.layer(
60
+ withProfileOverride(yield* loadConfigProvider(envFileOpt), profileName),
61
+ ),
62
+ logger,
63
+ );
64
+ });
65
+
66
+ const cloudflareForce = Flag.boolean("force").pipe(
67
+ Flag.withDescription(
68
+ "Force a full redeploy even if the state-store worker already exists. " +
69
+ "Without this flag, an existing worker is adopted and only its credentials are refreshed.",
70
+ ),
71
+ Flag.withDefault(false),
72
+ );
73
+
74
+ const cloudflareWorkerName = Flag.string("worker-name").pipe(
75
+ Flag.withDescription(
76
+ "Override the default state-store worker name (advanced; only needed for multiple state stores per account).",
77
+ ),
78
+ Flag.optional,
79
+ Flag.map(Option.getOrUndefined),
80
+ );
81
+
82
+ const bootstrapCommand = Command.make(
83
+ "bootstrap",
84
+ {
85
+ envFile,
86
+ profile,
87
+ force: cloudflareForce,
88
+ workerName: cloudflareWorkerName,
89
+ },
90
+ instrumentCommand(
91
+ "cloudflare.bootstrap",
92
+ (a: {
93
+ profile: string;
94
+ force: boolean;
95
+ workerName: string | undefined;
96
+ }) => ({
97
+ "alchemy.profile": a.profile,
98
+ "alchemy.force": a.force,
99
+ "alchemy.worker_name": a.workerName ?? "",
100
+ }),
101
+ )(
102
+ Effect.fnUntraced(function* ({ envFile, profile, force, workerName }) {
103
+ const services = yield* cloudflareLayers(envFile, profile);
104
+ yield* bootstrapCloudflare({ workerName, force }).pipe(
105
+ Effect.provide(services),
106
+ );
107
+ }),
108
+ ),
109
+ );
110
+
111
+ const tailFlag = Flag.boolean("tail").pipe(
112
+ Flag.withDescription(
113
+ "Stream logs in real time via the Cloudflare tail websocket instead of fetching past entries.",
114
+ ),
115
+ Flag.withDefault(false),
116
+ );
117
+
118
+ const limitFlag = Flag.integer("limit").pipe(
119
+ Flag.withDescription("Number of log entries to fetch (ignored with --tail)"),
120
+ Flag.withDefault(100),
121
+ );
122
+
123
+ const sinceFlag = Flag.string("since").pipe(
124
+ Flag.withDescription(
125
+ "Fetch logs since this time (e.g. '1h', '30m', '2024-01-01T00:00:00Z')",
126
+ ),
127
+ Flag.optional,
128
+ Flag.map(Option.getOrUndefined),
129
+ );
130
+
131
+ /**
132
+ * `alchemy cloudflare state logs` — get or tail logs from the
133
+ * `alchemy-state-store` Worker on the user's account. Lets us debug
134
+ * the state-store worker without standing up a stack file.
135
+ */
136
+ const stateLogsCommand = Command.make(
137
+ "logs",
138
+ {
139
+ envFile,
140
+ profile,
141
+ workerName: cloudflareWorkerName,
142
+ tail: tailFlag,
143
+ limit: limitFlag,
144
+ since: sinceFlag,
145
+ },
146
+ instrumentCommand(
147
+ "cloudflare.state.logs",
148
+ (a: {
149
+ profile: string;
150
+ workerName: string | undefined;
151
+ tail: boolean;
152
+ limit: number;
153
+ }) => ({
154
+ "alchemy.profile": a.profile,
155
+ "alchemy.worker_name": a.workerName ?? STATE_STORE_SCRIPT_NAME,
156
+ "alchemy.tail": a.tail,
157
+ "alchemy.limit": a.limit,
158
+ }),
159
+ )(
160
+ Effect.fnUntraced(function* ({
161
+ envFile,
162
+ profile,
163
+ workerName,
164
+ tail,
165
+ limit,
166
+ since,
167
+ }) {
168
+ const services = yield* cloudflareLayers(envFile, profile);
169
+ const scriptName = workerName ?? STATE_STORE_SCRIPT_NAME;
170
+
171
+ yield* Effect.gen(function* () {
172
+ const { accountId } =
173
+ yield* CloudflareEnvironment.CloudflareEnvironment;
174
+ const telemetry = yield* CloudflareLogs;
175
+
176
+ const formatLine = (line: { timestamp: Date; message: string }) =>
177
+ `${formatLocalTimestamp(line.timestamp)} [${scriptName}] ${line.message}`;
178
+
179
+ if (tail) {
180
+ yield* Console.log(`Tailing ${scriptName}...`);
181
+ yield* telemetry
182
+ .tailScript({ accountId, scriptName })
183
+ .pipe(Stream.runForEach((line) => Console.log(formatLine(line))));
184
+ return;
185
+ }
186
+
187
+ const sinceDate = since ? parseSince(since) : undefined;
188
+ const lines = yield* telemetry.queryLogs({
189
+ accountId,
190
+ filters: [
191
+ {
192
+ key: "$workers.scriptName",
193
+ operation: "eq",
194
+ type: "string",
195
+ value: scriptName,
196
+ },
197
+ ],
198
+ options: { limit, since: sinceDate },
199
+ });
200
+
201
+ if (lines.length === 0) {
202
+ yield* Console.log(`(no log entries for ${scriptName})`);
203
+ return;
204
+ }
205
+
206
+ for (const line of lines.sort(
207
+ (a, b) => a.timestamp.getTime() - b.timestamp.getTime(),
208
+ )) {
209
+ yield* Console.log(formatLine(line));
210
+ }
211
+ }).pipe(Effect.provide(services));
212
+ }),
213
+ ),
214
+ );
215
+
216
+ const stateCommand = Command.make("state", {}).pipe(
217
+ Command.withSubcommands([stateLogsCommand]),
218
+ );
219
+
220
+ export const cloudflareCommand = Command.make("cloudflare", {}).pipe(
221
+ Command.withSubcommands([bootstrapCommand, stateCommand]),
222
+ );
@@ -8,17 +8,17 @@ import * as Schema from "effect/Schema";
8
8
  import * as Command from "effect/unstable/cli/Command";
9
9
  import * as Flag from "effect/unstable/cli/Flag";
10
10
 
11
- import { AdoptPolicy } from "../../AdoptPolicy";
12
- import { AlchemyContext } from "../../AlchemyContext";
13
- import { apply } from "../../Apply";
14
- import { ArtifactStore, createArtifactStore } from "../../Artifacts";
15
- import { AuthProviders } from "../../Auth/AuthProvider";
16
- import { withProfileOverride } from "../../Auth/Profile";
11
+ import { AdoptPolicy } from "../../AdoptPolicy.ts";
12
+ import { AlchemyContext } from "../../AlchemyContext.ts";
13
+ import { apply } from "../../Apply.ts";
14
+ import { ArtifactStore, createArtifactStore } from "../../Artifacts.ts";
15
+ import { AuthProviders } from "../../Auth/AuthProvider.ts";
16
+ import { withProfileOverride } from "../../Auth/Profile.ts";
17
17
  import * as CLI from "../../Cli/Cli.ts";
18
- import * as Plan from "../../Plan";
19
- import { Stage } from "../../Stage";
20
- import { loadConfigProvider } from "../../Util/ConfigProvider";
21
- import { fileLogger } from "../../Util/FileLogger";
18
+ import * as Plan from "../../Plan.ts";
19
+ import { Stage } from "../../Stage.ts";
20
+ import { loadConfigProvider } from "../../Util/ConfigProvider.ts";
21
+ import { fileLogger } from "../../Util/FileLogger.ts";
22
22
 
23
23
  import {
24
24
  dryRun as dryRunFlag,
@@ -45,6 +45,7 @@ export const ExecStackOptions = Schema.Struct({
45
45
  adopt: Schema.optional(Schema.Boolean),
46
46
  });
47
47
  export type ExecStackOptions = typeof ExecStackOptions.Type;
48
+ export type ExecStackOptionsEncoded = typeof ExecStackOptions.Encoded;
48
49
 
49
50
  const stackSpanAttrs = (args: ExecStackOptions) => ({
50
51
  "alchemy.stage": args.stage,
@@ -6,16 +6,6 @@ import { fileURLToPath } from "node:url";
6
6
  import { envFile, force, profile, script, stage } from "./_shared.ts";
7
7
  import { ExecStackOptions } from "./deploy.ts";
8
8
 
9
- // Source iteration uses unbundled exec.ts so --watch sees source-file changes;
10
- // published installs use the bundled exec.js so react/ink/pathe stay
11
- // devDependencies (matching the CLI bundle's intent). Detect which world we're
12
- // in by whether dev.ts (or the alchemy.js bundle that contains it) lives
13
- // inside a node_modules tree — same heuristic as bin/cli.js.
14
- const selfPath = fileURLToPath(import.meta.url);
15
- const isInstalled =
16
- selfPath.includes("/node_modules/") || selfPath.includes("\\node_modules\\");
17
- const execEntry = isInstalled ? "alchemy/bin/exec.js" : "alchemy/bin/exec.ts";
18
-
19
9
  export const devCommand = Command.make(
20
10
  "dev",
21
11
  {
@@ -31,30 +21,35 @@ export const devCommand = Command.make(
31
21
  yes: true,
32
22
  dev: true,
33
23
  });
34
- const bin = typeof globalThis.Bun !== "undefined" ? "bun" : "node";
35
- const main = fileURLToPath(import.meta.resolve(execEntry));
36
- const child = yield* ChildProcess.make(
37
- bin,
38
- {
39
- bun: ["run", ...process.execArgv, "--watch", "--no-clear-screen", main],
40
- node: [
41
- ...process.execArgv,
42
- "--experimental-transform-types",
43
- "--watch",
44
- "--watch-preserve-output",
45
- main,
46
- ],
47
- }[bin],
48
- {
49
- stdin: "inherit",
50
- stdout: "inherit",
51
- stderr: "inherit",
52
- env: {
53
- ALCHEMY_EXEC_OPTIONS: JSON.stringify(options),
54
- },
55
- extendEnv: true,
24
+ // We no longer force Bun in development because this prevents us from testing in Node.
25
+ const command =
26
+ typeof globalThis.Bun !== "undefined"
27
+ ? [
28
+ "bun",
29
+ "run",
30
+ ...process.execArgv,
31
+ "--watch",
32
+ "--no-clear-screen",
33
+ fileURLToPath(import.meta.resolve("alchemy/bin/exec.ts")),
34
+ ]
35
+ : [
36
+ "node",
37
+ ...process.execArgv,
38
+ "--experimental-transform-types",
39
+ "--watch",
40
+ "--watch-preserve-output",
41
+ fileURLToPath(import.meta.resolve("alchemy/bin/exec.js")),
42
+ ];
43
+ const child = yield* ChildProcess.make(command[0], command.slice(1), {
44
+ stdin: "inherit",
45
+ stdout: "inherit",
46
+ stderr: "inherit",
47
+ env: {
48
+ ALCHEMY_EXEC_OPTIONS: JSON.stringify(options),
56
49
  },
57
- );
50
+ extendEnv: true,
51
+ detached: false,
52
+ });
58
53
  yield* child.exitCode;
59
54
  }),
60
55
  );