alchemy 2.0.0-beta.13 → 2.0.0-beta.15

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 (311) hide show
  1. package/bin/alchemy.js +9477 -9290
  2. package/bin/alchemy.js.map +1 -1
  3. package/bin/alchemy.ts +6 -2
  4. package/bin/cli.js +61 -0
  5. package/bin/commands/deploy.ts +6 -4
  6. package/bin/commands/login.ts +1 -1
  7. package/bin/commands/logs.ts +1 -1
  8. package/bin/commands/state.ts +233 -0
  9. package/bin/commands/tail.ts +1 -1
  10. package/lib/AWS/AutoScaling/LaunchTemplate.d.ts +1 -1
  11. package/lib/AWS/EC2/Instance.d.ts +1 -1
  12. package/lib/AWS/EC2/hosted.d.ts +2 -2
  13. package/lib/AWS/ECS/Task.d.ts +4 -4
  14. package/lib/AWS/ECS/Task.d.ts.map +1 -1
  15. package/lib/AWS/ECS/Task.js +2 -2
  16. package/lib/AWS/ECS/Task.js.map +1 -1
  17. package/lib/AWS/Environment.d.ts +2 -2
  18. package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
  19. package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
  20. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
  21. package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
  22. package/lib/AWS/Lambda/Function.d.ts +2 -2
  23. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  24. package/lib/AWS/Lambda/Function.js +1 -2
  25. package/lib/AWS/Lambda/Function.js.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/SQS/QueueSink.d.ts.map +1 -1
  35. package/lib/AWS/SQS/QueueSink.js +1 -2
  36. package/lib/AWS/SQS/QueueSink.js.map +1 -1
  37. package/lib/Agent/coding/bash.d.ts +2 -6
  38. package/lib/Agent/coding/bash.d.ts.map +1 -1
  39. package/lib/Agent/coding/bash.js +2 -3
  40. package/lib/Agent/coding/bash.js.map +1 -1
  41. package/lib/Agent/coding/edit.d.ts +1 -1
  42. package/lib/Agent/coding/glob.d.ts +2 -4
  43. package/lib/Agent/coding/glob.d.ts.map +1 -1
  44. package/lib/Agent/coding/glob.js +1 -2
  45. package/lib/Agent/coding/glob.js.map +1 -1
  46. package/lib/Agent/coding/grep.d.ts +2 -4
  47. package/lib/Agent/coding/grep.d.ts.map +1 -1
  48. package/lib/Agent/coding/grep.js +1 -2
  49. package/lib/Agent/coding/grep.js.map +1 -1
  50. package/lib/Agent/coding/read.d.ts +1 -1
  51. package/lib/Agent/coding/write.d.ts +1 -1
  52. package/lib/Agent/lsp/client.d.ts +2 -2
  53. package/lib/Agent/util/ripgrep.d.ts +2 -2
  54. package/lib/AlchemyContext.d.ts +13 -0
  55. package/lib/AlchemyContext.d.ts.map +1 -0
  56. package/lib/AlchemyContext.js +18 -0
  57. package/lib/AlchemyContext.js.map +1 -0
  58. package/lib/Auth/AuthProvider.js +1 -1
  59. package/lib/Auth/AuthProvider.js.map +1 -1
  60. package/lib/Auth/Profile.d.ts +1 -1
  61. package/lib/Auth/index.d.ts +3 -1
  62. package/lib/Auth/index.d.ts.map +1 -1
  63. package/lib/Auth/index.js +3 -0
  64. package/lib/Auth/index.js.map +1 -1
  65. package/lib/Build/Command.d.ts +1 -1
  66. package/lib/Build/Memo.d.ts +1 -1
  67. package/lib/Bundle/Docker.d.ts +3 -3
  68. package/lib/Bundle/TempRoot.d.ts +3 -3
  69. package/lib/Cli/LoggingCli.d.ts +4 -0
  70. package/lib/Cli/LoggingCli.d.ts.map +1 -0
  71. package/lib/{Test/TestCli.js → Cli/LoggingCli.js} +3 -3
  72. package/lib/Cli/LoggingCli.js.map +1 -0
  73. package/lib/Cli/index.d.ts +0 -1
  74. package/lib/Cli/index.d.ts.map +1 -1
  75. package/lib/Cli/index.js +4 -1
  76. package/lib/Cli/index.js.map +1 -1
  77. package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts +58 -0
  78. package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts.map +1 -0
  79. package/lib/Cloudflare/ApiToken/AccountApiToken.js +137 -0
  80. package/lib/Cloudflare/ApiToken/AccountApiToken.js.map +1 -0
  81. package/lib/Cloudflare/ApiToken/Common.d.ts +91 -0
  82. package/lib/Cloudflare/ApiToken/Common.d.ts.map +1 -0
  83. package/lib/Cloudflare/ApiToken/Common.js +61 -0
  84. package/lib/Cloudflare/ApiToken/Common.js.map +1 -0
  85. package/lib/Cloudflare/ApiToken/PermissionGroups.d.ts +1549 -0
  86. package/lib/Cloudflare/ApiToken/PermissionGroups.d.ts.map +1 -0
  87. package/lib/Cloudflare/ApiToken/PermissionGroups.js +1856 -0
  88. package/lib/Cloudflare/ApiToken/PermissionGroups.js.map +1 -0
  89. package/lib/Cloudflare/ApiToken/UserApiToken.d.ts +49 -0
  90. package/lib/Cloudflare/ApiToken/UserApiToken.d.ts.map +1 -0
  91. package/lib/Cloudflare/ApiToken/UserApiToken.js +113 -0
  92. package/lib/Cloudflare/ApiToken/UserApiToken.js.map +1 -0
  93. package/lib/Cloudflare/ApiToken/index.d.ts +5 -0
  94. package/lib/Cloudflare/ApiToken/index.d.ts.map +1 -0
  95. package/lib/Cloudflare/ApiToken/index.js +5 -0
  96. package/lib/Cloudflare/ApiToken/index.js.map +1 -0
  97. package/lib/Cloudflare/Auth/AuthProvider.js +2 -2
  98. package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
  99. package/lib/Cloudflare/CloudflareEnvironment.d.ts +1 -1
  100. package/lib/Cloudflare/Container/ContainerApplication.d.ts +2 -2
  101. package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
  102. package/lib/Cloudflare/Container/ContainerApplication.js +7 -2
  103. package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
  104. package/lib/Cloudflare/EdgeSession.d.ts +53 -0
  105. package/lib/Cloudflare/EdgeSession.d.ts.map +1 -0
  106. package/lib/Cloudflare/EdgeSession.js +78 -0
  107. package/lib/Cloudflare/EdgeSession.js.map +1 -0
  108. package/lib/Cloudflare/Providers.d.ts +1 -1
  109. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  110. package/lib/Cloudflare/Providers.js +4 -1
  111. package/lib/Cloudflare/Providers.js.map +1 -1
  112. package/lib/Cloudflare/StateStore/Api.d.ts +61 -0
  113. package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -0
  114. package/lib/Cloudflare/StateStore/Api.js +103 -0
  115. package/lib/Cloudflare/StateStore/Api.js.map +1 -0
  116. package/lib/Cloudflare/StateStore/State.d.ts +39 -0
  117. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -0
  118. package/lib/Cloudflare/StateStore/State.js +217 -0
  119. package/lib/Cloudflare/StateStore/State.js.map +1 -0
  120. package/lib/Cloudflare/StateStore/Store.d.ts +82 -0
  121. package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -0
  122. package/lib/Cloudflare/StateStore/Store.js +191 -0
  123. package/lib/Cloudflare/StateStore/Store.js.map +1 -0
  124. package/lib/Cloudflare/StateStore/Token.d.ts +43 -0
  125. package/lib/Cloudflare/StateStore/Token.d.ts.map +1 -0
  126. package/lib/Cloudflare/StateStore/Token.js +61 -0
  127. package/lib/Cloudflare/StateStore/Token.js.map +1 -0
  128. package/lib/Cloudflare/StateStore/index.d.ts +2 -0
  129. package/lib/Cloudflare/StateStore/index.d.ts.map +1 -0
  130. package/lib/Cloudflare/StateStore/index.js +2 -0
  131. package/lib/Cloudflare/StateStore/index.js.map +1 -0
  132. package/lib/Cloudflare/Workers/Assets.d.ts +2 -2
  133. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts +2 -2
  134. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts.map +1 -1
  135. package/lib/Cloudflare/Workers/DurableObjectNamespace.js +0 -1
  136. package/lib/Cloudflare/Workers/DurableObjectNamespace.js.map +1 -1
  137. package/lib/Cloudflare/Workers/HttpServer.d.ts +1 -1
  138. package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
  139. package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
  140. package/lib/Cloudflare/Workers/Worker.d.ts +5 -5
  141. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  142. package/lib/Cloudflare/Workers/Worker.js +0 -1
  143. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  144. package/lib/Cloudflare/index.d.ts +4 -1
  145. package/lib/Cloudflare/index.d.ts.map +1 -1
  146. package/lib/Cloudflare/index.js +4 -1
  147. package/lib/Cloudflare/index.js.map +1 -1
  148. package/lib/Deploy.d.ts +10 -0
  149. package/lib/Deploy.d.ts.map +1 -0
  150. package/lib/Deploy.js +12 -0
  151. package/lib/Deploy.js.map +1 -0
  152. package/lib/Destroy.d.ts +8 -3
  153. package/lib/Destroy.d.ts.map +1 -1
  154. package/lib/Destroy.js +8 -8
  155. package/lib/Destroy.js.map +1 -1
  156. package/lib/GitHub/Providers.d.ts +3 -0
  157. package/lib/GitHub/Providers.d.ts.map +1 -0
  158. package/lib/GitHub/Providers.js +5 -0
  159. package/lib/GitHub/Providers.js.map +1 -0
  160. package/lib/GitHub/index.d.ts +1 -0
  161. package/lib/GitHub/index.d.ts.map +1 -1
  162. package/lib/GitHub/index.js +1 -0
  163. package/lib/GitHub/index.js.map +1 -1
  164. package/lib/Http.d.ts +1 -1
  165. package/lib/Http.d.ts.map +1 -1
  166. package/lib/Http.js +7 -3
  167. package/lib/Http.js.map +1 -1
  168. package/lib/Kubernetes/client.d.ts +10 -10
  169. package/lib/Output.d.ts.map +1 -1
  170. package/lib/Output.js +4 -0
  171. package/lib/Output.js.map +1 -1
  172. package/lib/Plan.d.ts.map +1 -1
  173. package/lib/Plan.js +4 -0
  174. package/lib/Plan.js.map +1 -1
  175. package/lib/Platform.d.ts +2 -2
  176. package/lib/Platform.d.ts.map +1 -1
  177. package/lib/Platform.js.map +1 -1
  178. package/lib/Provider.d.ts.map +1 -1
  179. package/lib/Provider.js +0 -1
  180. package/lib/Provider.js.map +1 -1
  181. package/lib/Stack.d.ts +24 -12
  182. package/lib/Stack.d.ts.map +1 -1
  183. package/lib/Stack.js +47 -10
  184. package/lib/Stack.js.map +1 -1
  185. package/lib/State/HttpStateApi.d.ts +96 -0
  186. package/lib/State/HttpStateApi.d.ts.map +1 -0
  187. package/lib/State/HttpStateApi.js +96 -0
  188. package/lib/State/HttpStateApi.js.map +1 -0
  189. package/lib/State/HttpStateStore.d.ts +10 -0
  190. package/lib/State/HttpStateStore.d.ts.map +1 -0
  191. package/lib/State/HttpStateStore.js +102 -0
  192. package/lib/State/HttpStateStore.js.map +1 -0
  193. package/lib/State/InMemoryState.d.ts +2 -30
  194. package/lib/State/InMemoryState.d.ts.map +1 -1
  195. package/lib/State/InMemoryState.js +23 -18
  196. package/lib/State/InMemoryState.js.map +1 -1
  197. package/lib/State/LocalState.d.ts +4 -2
  198. package/lib/State/LocalState.d.ts.map +1 -1
  199. package/lib/State/LocalState.js +9 -41
  200. package/lib/State/LocalState.js.map +1 -1
  201. package/lib/State/State.d.ts +11 -4
  202. package/lib/State/State.d.ts.map +1 -1
  203. package/lib/State/State.js +1 -1
  204. package/lib/State/State.js.map +1 -1
  205. package/lib/State/StateEncoding.d.ts +31 -0
  206. package/lib/State/StateEncoding.d.ts.map +1 -0
  207. package/lib/State/StateEncoding.js +82 -0
  208. package/lib/State/StateEncoding.js.map +1 -0
  209. package/lib/State/Sync.d.ts +23 -0
  210. package/lib/State/Sync.d.ts.map +1 -0
  211. package/lib/State/Sync.js +49 -0
  212. package/lib/State/Sync.js.map +1 -0
  213. package/lib/State/index.d.ts +4 -0
  214. package/lib/State/index.d.ts.map +1 -1
  215. package/lib/State/index.js +4 -0
  216. package/lib/State/index.js.map +1 -1
  217. package/lib/Test/Bun.d.ts +13 -17
  218. package/lib/Test/Bun.d.ts.map +1 -1
  219. package/lib/Test/Bun.js +17 -36
  220. package/lib/Test/Bun.js.map +1 -1
  221. package/lib/Test/TestState.d.ts +1 -2
  222. package/lib/Test/TestState.d.ts.map +1 -1
  223. package/lib/Test/TestState.js +5 -9
  224. package/lib/Test/TestState.js.map +1 -1
  225. package/lib/Test/Vitest.d.ts +3 -2
  226. package/lib/Test/Vitest.d.ts.map +1 -1
  227. package/lib/Test/Vitest.js +20 -11
  228. package/lib/Test/Vitest.js.map +1 -1
  229. package/lib/Test/index.d.ts +0 -1
  230. package/lib/Test/index.d.ts.map +1 -1
  231. package/lib/Test/index.js +0 -1
  232. package/lib/Test/index.js.map +1 -1
  233. package/lib/Util/FileLogger.d.ts +2 -2
  234. package/lib/Util/FileLogger.d.ts.map +1 -1
  235. package/lib/Util/FileLogger.js +2 -2
  236. package/lib/Util/FileLogger.js.map +1 -1
  237. package/lib/cli/index.d.ts +10 -5
  238. package/lib/cli/index.d.ts.map +1 -1
  239. package/lib/cli/index.js +2 -43045
  240. package/lib/cli/index.js.map +1 -1
  241. package/lib/index.d.ts +2 -1
  242. package/lib/index.d.ts.map +1 -1
  243. package/lib/index.js +2 -1
  244. package/lib/index.js.map +1 -1
  245. package/package.json +30 -15
  246. package/src/AWS/ECS/Task.ts +4 -4
  247. package/src/AWS/Lambda/Function.ts +2 -3
  248. package/src/AWS/SQS/QueueSink.ts +1 -2
  249. package/src/Agent/coding/bash.ts +2 -3
  250. package/src/Agent/coding/glob.ts +1 -2
  251. package/src/Agent/coding/grep.ts +1 -2
  252. package/src/AlchemyContext.ts +27 -0
  253. package/src/Auth/AuthProvider.ts +1 -1
  254. package/src/Auth/index.ts +3 -1
  255. package/src/{Test/TestCli.ts → Cli/LoggingCli.ts} +2 -2
  256. package/src/Cli/index.ts +4 -1
  257. package/src/Cloudflare/ApiToken/AccountApiToken.ts +197 -0
  258. package/src/Cloudflare/ApiToken/Common.ts +148 -0
  259. package/src/Cloudflare/ApiToken/PermissionGroups.ts +1910 -0
  260. package/src/Cloudflare/ApiToken/UserApiToken.ts +168 -0
  261. package/src/Cloudflare/ApiToken/index.ts +4 -0
  262. package/src/Cloudflare/Auth/AuthProvider.ts +2 -2
  263. package/src/Cloudflare/Container/ContainerApplication.ts +8 -2
  264. package/src/Cloudflare/EdgeSession.ts +144 -0
  265. package/src/Cloudflare/Providers.ts +5 -0
  266. package/src/Cloudflare/StateStore/Api.ts +159 -0
  267. package/src/Cloudflare/StateStore/State.ts +318 -0
  268. package/src/Cloudflare/StateStore/Store.ts +290 -0
  269. package/src/Cloudflare/StateStore/Token.ts +68 -0
  270. package/src/Cloudflare/StateStore/index.ts +1 -0
  271. package/src/Cloudflare/Workers/DurableObjectNamespace.ts +1 -6
  272. package/src/Cloudflare/Workers/HttpServer.ts +1 -1
  273. package/src/Cloudflare/Workers/Worker.ts +7 -7
  274. package/src/Cloudflare/index.ts +4 -1
  275. package/src/Deploy.ts +25 -0
  276. package/src/Destroy.ts +25 -13
  277. package/src/GitHub/Providers.ts +6 -0
  278. package/src/GitHub/index.ts +1 -0
  279. package/src/Http.ts +31 -16
  280. package/src/Output.ts +3 -2
  281. package/src/Plan.ts +3 -0
  282. package/src/Platform.ts +8 -2
  283. package/src/Provider.ts +0 -2
  284. package/src/Stack.ts +146 -45
  285. package/src/State/HttpStateApi.ts +155 -0
  286. package/src/State/HttpStateStore.ts +156 -0
  287. package/src/State/InMemoryState.ts +15 -17
  288. package/src/State/LocalState.ts +13 -45
  289. package/src/State/State.ts +13 -4
  290. package/src/State/StateEncoding.ts +83 -0
  291. package/src/State/Sync.ts +89 -0
  292. package/src/State/index.ts +4 -0
  293. package/src/Test/Bun.ts +31 -89
  294. package/src/Test/TestState.ts +6 -8
  295. package/src/Test/Vitest.ts +32 -19
  296. package/src/Test/index.ts +0 -1
  297. package/src/Util/FileLogger.ts +2 -2
  298. package/src/index.ts +2 -1
  299. package/lib/Config.d.ts +0 -20
  300. package/lib/Config.d.ts.map +0 -1
  301. package/lib/Config.js +0 -22
  302. package/lib/Config.js.map +0 -1
  303. package/lib/Observability.d.ts +0 -2
  304. package/lib/Observability.d.ts.map +0 -1
  305. package/lib/Observability.js +0 -1
  306. package/lib/Observability.js.map +0 -1
  307. package/lib/Test/TestCli.d.ts +0 -4
  308. package/lib/Test/TestCli.d.ts.map +0 -1
  309. package/lib/Test/TestCli.js.map +0 -1
  310. package/src/Config.ts +0 -31
  311. package/src/Observability.ts +0 -0
@@ -14,7 +14,7 @@ import { isWorkerEvent, type WorkerServices } from "./Worker.ts";
14
14
  export type HttpEffect = Http.HttpEffect<WorkerServices>;
15
15
 
16
16
  export const workersHttpHandler = <Req = never>(
17
- handler: Http.HttpEffect<Req>,
17
+ handler: Http.HttpEffect<Req> | Effect.Effect<Http.HttpEffect<Req>>,
18
18
  ) => {
19
19
  const safeHandler = Http.safeHttpEffect(handler);
20
20
  return (event: any) => {
@@ -48,11 +48,11 @@ import { Stack } from "../../Stack.ts";
48
48
  import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
49
49
  import { D1Database } from "../D1/D1Database.ts";
50
50
  import { fromCloudflareFetcher } from "../Fetcher.ts";
51
+ import type { KVNamespace } from "../KV/KVNamespace.ts";
51
52
  import { CloudflareLogs } from "../Logs.ts";
52
53
  import type { Providers } from "../Providers.ts";
53
- import type { R2Bucket } from "../R2/R2Bucket.ts";
54
- import type { KVNamespace } from "../KV/KVNamespace.ts";
55
54
  import type { Queue as CloudflareQueue } from "../Queue/Queue.ts";
55
+ import type { R2Bucket } from "../R2/R2Bucket.ts";
56
56
  import {
57
57
  isAssets,
58
58
  readAssets,
@@ -173,9 +173,9 @@ export interface WorkerExecutionContext extends Serverless.FunctionContext {
173
173
  export(name: string, value: any): Effect.Effect<void>;
174
174
  }
175
175
 
176
- export type WorkerServices = Worker | WorkerEnvironment | Request;
176
+ export type WorkerServices = Worker | Request;
177
177
 
178
- export type WorkerShape = Main<WorkerServices>;
178
+ export type WorkerShape = Main<WorkerServices | WorkerEnvironment>;
179
179
 
180
180
  export type WorkerBindingResource =
181
181
  | Assets
@@ -764,8 +764,9 @@ export const Worker: Platform<
764
764
  );
765
765
  return key;
766
766
  }),
767
- serve: <Req = never>(handler: HttpEffect<Req>) =>
768
- ctx.listen(workersHttpHandler(handler)),
767
+ serve: <Req = never>(
768
+ handler: HttpEffect<Req> | Effect.Effect<HttpEffect<Req>>,
769
+ ) => ctx.listen(workersHttpHandler(handler)),
769
770
  listen: ((
770
771
  handler:
771
772
  | Serverless.FunctionListener
@@ -1280,7 +1281,6 @@ const stack = Layer.succeed(
1280
1281
 
1281
1282
  const exportsEffect = tag.asEffect().pipe(
1282
1283
  Effect.flatMap(func => func.ExecutionContext.exports),
1283
- Effect.map(exports => exports),
1284
1284
  Effect.provide(
1285
1285
  layer.pipe(
1286
1286
  Layer.provideMerge(stack),
@@ -1,10 +1,13 @@
1
+ export * from "./ApiToken/index.ts";
1
2
  export * from "./CloudflareEnvironment.ts";
2
3
  export * from "./Container/index.ts";
3
4
  export * from "./D1/index.ts";
5
+ export * from "./EdgeSession.ts";
4
6
  export * from "./KV/index.ts";
5
- export * from "./Queue/index.ts";
6
7
  export * from "./Providers.ts";
8
+ export * from "./Queue/index.ts";
7
9
  export * from "./R2/index.ts";
8
10
  export * from "./SecretsStore/index.ts";
11
+ export * from "./StateStore/index.ts";
9
12
  export * from "./Website/index.ts";
10
13
  export * from "./Workers/index.ts";
package/src/Deploy.ts ADDED
@@ -0,0 +1,25 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { AlchemyContext } from "./AlchemyContext.ts";
3
+ import * as Apply from "./Apply.ts";
4
+ import type { Input } from "./Input.ts";
5
+ import * as Plan from "./Plan.ts";
6
+ import { evalStack, type CompiledStack, type StackEffect } from "./Stack.ts";
7
+ import { Stage } from "./Stage.ts";
8
+
9
+ export const deploy = <A>({
10
+ stack,
11
+ stage,
12
+ }: {
13
+ stack: StackEffect<CompiledStack<A>, Stage | AlchemyContext>;
14
+ stage: string;
15
+ }) =>
16
+ evalStack(
17
+ stack,
18
+ (stack) =>
19
+ Effect.gen(function* () {
20
+ const plan = yield* Plan.make(stack);
21
+ const output = yield* Apply.apply(plan);
22
+ return output as Input.Resolve<A>;
23
+ }),
24
+ { stage },
25
+ );
package/src/Destroy.ts CHANGED
@@ -1,16 +1,28 @@
1
- import * as Effect from "effect/Effect";
2
- import { apply } from "./Apply.ts";
3
- import { provideFreshArtifactStore } from "./Artifacts.ts";
1
+ import { Effect } from "effect";
2
+ import type { AlchemyContext } from "./AlchemyContext.ts";
3
+ import * as Apply from "./Apply.ts";
4
4
  import * as Plan from "./Plan.ts";
5
- import { Stack } from "./Stack.ts";
5
+ import type { CompiledStack, StackEffect } from "./Stack.ts";
6
+ import { evalStack } from "./Stack.ts";
7
+ import type { Stage } from "./Stage.ts";
6
8
 
7
- export const destroy = () =>
8
- Stack.use((stack) =>
9
- Plan.make({
10
- name: stack.name,
11
- stage: stack.stage,
12
- resources: {},
13
- bindings: {},
14
- output: {},
15
- }).pipe(Effect.flatMap(apply), provideFreshArtifactStore),
9
+ export const destroy = ({
10
+ stack,
11
+ stage,
12
+ }: {
13
+ stack: StackEffect<CompiledStack, Stage | AlchemyContext>;
14
+ stage: string;
15
+ }) =>
16
+ evalStack(
17
+ stack,
18
+ (stack) =>
19
+ Plan.make({
20
+ ...stack,
21
+ // zero these out (destroy will treat all as orphans)
22
+ // TODO(sam): probably better to have Plan.destroy and Plan.update
23
+ resources: {},
24
+ bindings: {},
25
+ output: {},
26
+ }).pipe(Effect.flatMap(Apply.apply)),
27
+ { stage },
16
28
  );
@@ -0,0 +1,6 @@
1
+ import * as Layer from "effect/Layer";
2
+ import { SecretProvider } from "./Secret.ts";
3
+ import { VariableProvider } from "./Variable.ts";
4
+
5
+ export const providers = () =>
6
+ Layer.mergeAll(SecretProvider(), VariableProvider());
@@ -1,3 +1,4 @@
1
1
  export * from "./Comment.ts";
2
+ export * from "./Providers.ts";
2
3
  export * from "./Secret.ts";
3
4
  export * from "./Variable.ts";
package/src/Http.ts CHANGED
@@ -25,7 +25,6 @@ export const serve = <Req = never>(
25
25
  ) =>
26
26
  Effect.serviceOption(HttpServer).pipe(
27
27
  Effect.map(Option.getOrUndefined),
28
- Effect.tap((http) => Effect.logInfo("http", http)),
29
28
  Effect.flatMap((http) => (http ? http.serve(handler) : Effect.void)),
30
29
  );
31
30
 
@@ -45,22 +44,38 @@ export class HttpServer extends Context.Service<
45
44
  }
46
45
  >()("HttpServer") {}
47
46
 
48
- export const safeHttpEffect = <Req = never>(handler: HttpEffect<Req>) =>
49
- Effect.catchCause(handler, (cause) => {
50
- const message = Option.match(Cause.findErrorOption(cause), {
51
- onNone: () => "Internal Server Error",
52
- onSome: (error) => error.message ?? "Internal Server Error",
53
- });
47
+ export const safeHttpEffect = <Req = never>(
48
+ handler: HttpEffect<Req> | Effect.Effect<HttpEffect<Req>>,
49
+ ): Effect.Effect<
50
+ HttpServerResponse.HttpServerResponse,
51
+ never,
52
+ Req | HttpServerRequest | Scope
53
+ > =>
54
+ Effect.catchCause(
55
+ handler.pipe(
56
+ // @ts-expect-error
57
+ Effect.flatMap((response) =>
58
+ HttpServerResponse.isHttpServerResponse(response)
59
+ ? Effect.succeed(response)
60
+ : response,
61
+ ),
62
+ ) as any as HttpEffect<Req>,
63
+ (cause) => {
64
+ const message = Option.match(Cause.findErrorOption(cause), {
65
+ onNone: () => "Internal Server Error",
66
+ onSome: (error) => error.message ?? "Internal Server Error",
67
+ });
54
68
 
55
- return Effect.map(
56
- Effect.all([Effect.logInfo(message), Effect.logInfo(cause)]),
57
- () =>
58
- HttpServerResponse.text(message, {
59
- status: 500,
60
- statusText: message,
61
- }),
62
- );
63
- });
69
+ return Effect.map(
70
+ Effect.all([Effect.logError(message), Effect.logError(cause)]),
71
+ () =>
72
+ HttpServerResponse.text(message, {
73
+ status: 500,
74
+ statusText: message,
75
+ }),
76
+ );
77
+ },
78
+ );
64
79
 
65
80
  export const resolvePort = (options: { port?: number } | undefined) =>
66
81
  options?.port !== undefined
package/src/Output.ts CHANGED
@@ -3,6 +3,7 @@ import type { Yieldable } from "effect/Effect";
3
3
  import * as Effect from "effect/Effect";
4
4
  import { pipe } from "effect/Function";
5
5
  import type { Pipeable } from "effect/Pipeable";
6
+ import * as Redacted from "effect/Redacted";
6
7
  import { SingleShotGen } from "effect/Utils";
7
8
  import { ExecutionContext } from "./ExecutionContext.ts";
8
9
  import { getRefMetadata, isRef, ref as stageRef, type Ref } from "./Ref.ts";
@@ -208,8 +209,6 @@ export const map: {
208
209
  new ApplyExpr(output as Expr<A, Req>, args[0]) as any
209
210
  : new ApplyExpr(args[0] as any, args[1])) as any;
210
211
 
211
- type _ = Parameters<typeof map>;
212
-
213
212
  //Output.ApplyExpr<any, any, ResourceLike, any>
214
213
  export const isApplyExpr = <In = any, Out = any, Req = any>(
215
214
  node: Output<Out, Req>,
@@ -470,6 +469,8 @@ export const evaluate: <A, Req = never>(
470
469
  }
471
470
  if (Array.isArray(expr)) {
472
471
  return yield* Effect.all(expr.map((item) => evaluate(item, upstream)));
472
+ } else if (Redacted.isRedacted(expr)) {
473
+ return expr;
473
474
  } else if (typeof expr === "object" && expr !== null) {
474
475
  return Object.fromEntries(
475
476
  yield* Effect.all(
package/src/Plan.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as Data from "effect/Data";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as Option from "effect/Option";
4
+ import * as Redacted from "effect/Redacted";
4
5
  import { asEffect } from ".//Util/types.ts";
5
6
  import {
6
7
  Artifacts,
@@ -271,6 +272,8 @@ export const make = <A>(
271
272
  return input;
272
273
  } else if (Output.isExpr(input)) {
273
274
  return yield* resolveOutput(input);
275
+ } else if (Redacted.isRedacted(input)) {
276
+ return input;
274
277
  } else if (Array.isArray(input)) {
275
278
  return yield* Effect.all(input.map(resolveInput), {
276
279
  concurrency: "unbounded",
package/src/Platform.ts CHANGED
@@ -28,8 +28,14 @@ export interface PlatformProps {
28
28
  isExternal?: boolean;
29
29
  }
30
30
 
31
- export type Main<Services = never> = void | {
32
- fetch: HttpEffect<Services | PlatformServices>;
31
+ export type Main<InitServices = never> = void | {
32
+ fetch:
33
+ | HttpEffect<InitServices | PlatformServices>
34
+ | Effect.Effect<
35
+ HttpEffect<InitServices | PlatformServices>,
36
+ never,
37
+ InitServices | PlatformServices
38
+ >;
33
39
  };
34
40
 
35
41
  export type Rpc<Shape> = {
package/src/Provider.ts CHANGED
@@ -381,7 +381,5 @@ export const tryFindProviderByType: {
381
381
  }
382
382
  }
383
383
  }
384
-
385
- console.log(context.mapUnsafe.keys());
386
384
  return Option.none();
387
385
  }) as any;
package/src/Stack.ts CHANGED
@@ -1,20 +1,29 @@
1
+ import { ConfigProvider } from "effect/ConfigProvider";
1
2
  import * as Context from "effect/Context";
2
3
  import * as Effect from "effect/Effect";
3
4
  import { FileSystem } from "effect/FileSystem";
4
5
  import * as Layer from "effect/Layer";
6
+ import * as Logger from "effect/Logger";
5
7
  import * as Option from "effect/Option";
6
8
  import { Path } from "effect/Path";
7
9
  import type { Scope } from "effect/Scope";
10
+ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
8
11
  import type { HttpClient } from "effect/unstable/http/HttpClient";
9
12
  import type { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner";
10
- import type { AuthProviders } from "./Auth/AuthProvider.ts";
11
- import { DotAlchemy } from "./Config.ts";
13
+ import { AlchemyContext, AlchemyContextLive } from "./AlchemyContext.ts";
14
+ import { provideFreshArtifactStore } from "./Artifacts.ts";
15
+ import { AuthProviders } from "./Auth/AuthProvider.ts";
16
+ import { Cli } from "./Cli/Cli.ts";
12
17
  import type { Input, InputProps } from "./Input.ts";
13
18
  import * as Output from "./Output.ts";
14
19
  import { ref } from "./Ref.ts";
15
20
  import type { ResourceBinding, ResourceLike } from "./Resource.ts";
16
21
  import { Stage } from "./Stage.ts";
22
+ import type { State } from "./State/State.ts";
23
+ import { loadConfigProvider } from "./Util/ConfigProvider.ts";
17
24
  import { taggedFunction } from "./Util/effect.ts";
25
+ import { fileLogger } from "./Util/FileLogger.ts";
26
+ import { PlatformServices } from "./Util/PlatformServices.ts";
18
27
 
19
28
  export type StackServices =
20
29
  | Stack
@@ -22,16 +31,35 @@ export type StackServices =
22
31
  | Scope
23
32
  | FileSystem
24
33
  | Path
25
- | DotAlchemy
34
+ | AlchemyContext
26
35
  | HttpClient
27
36
  | ChildProcessSpawner
28
- | AuthProviders;
37
+ | AuthProviders
38
+ | Cli;
39
+
40
+ export type StackEffect<A, Err = never, Req = never> = Effect.Effect<
41
+ A,
42
+ Err,
43
+ | PlatformServices
44
+ | HttpClient
45
+ | Scope
46
+ | AuthProviders
47
+ | AlchemyContext
48
+ | Cli
49
+ | State
50
+ | Req
51
+ >;
29
52
 
30
53
  export type Stack = Context.ServiceClass.Shape<
31
54
  "Stack",
32
55
  Omit<StackSpec, "output">
33
56
  >;
34
57
 
58
+ export interface StackProps<Req> {
59
+ providers: Layer.Layer<NoInfer<Req>, never, StackServices>;
60
+ state: Layer.Layer<State, never, StackServices>;
61
+ }
62
+
35
63
  export const Stack: Context.ServiceClass<
36
64
  Stack,
37
65
  "Stack",
@@ -50,9 +78,7 @@ export const Stack: Context.ServiceClass<
50
78
  <Self>(): {
51
79
  <A, Req>(
52
80
  stackName: string,
53
- options: {
54
- providers: Layer.Layer<NoInfer<Req>, never, StackServices>;
55
- },
81
+ options: StackProps<NoInfer<Req>>,
56
82
  eff: Effect.Effect<A, never, Req>,
57
83
  ): Effect.Effect<Self> & {
58
84
  new (_: never): A extends object ? A : {};
@@ -75,9 +101,7 @@ export const Stack: Context.ServiceClass<
75
101
  };
76
102
  <A, Req>(
77
103
  stackName: string,
78
- options: {
79
- providers: Layer.Layer<NoInfer<Req>, never, StackServices>;
80
- },
104
+ options: StackProps<NoInfer<Req>>,
81
105
  eff: Effect.Effect<A, never, Req | StackServices>,
82
106
  ): Effect.Effect<CompiledStack<A>>;
83
107
  } = Object.assign(
@@ -87,23 +111,29 @@ export const Stack: Context.ServiceClass<
87
111
  stackName: string,
88
112
  options: {
89
113
  providers: Layer.Layer<NoInfer<Req>, never, StackServices>;
114
+ state: Layer.Layer<State, never, StackServices>;
90
115
  },
91
116
  eff: Effect.Effect<A, never, Req>,
92
117
  ) =>
93
- eff.pipe(make(stackName, options.providers), (eff) =>
94
- Object.assign(eff, {
95
- stage: new Proxy(
96
- {},
97
- {
98
- get: (_, stage: string) =>
99
- ref({
100
- stack: stackName,
101
- stage,
102
- id: stackName,
103
- }),
104
- },
105
- ),
118
+ eff.pipe(
119
+ make({
120
+ name: stackName,
121
+ ...options,
106
122
  }),
123
+ (eff) =>
124
+ Object.assign(eff, {
125
+ stage: new Proxy(
126
+ {},
127
+ {
128
+ get: (_, stage: string) =>
129
+ ref({
130
+ stack: stackName,
131
+ stage,
132
+ id: stackName,
133
+ }),
134
+ },
135
+ ),
136
+ }),
107
137
  ),
108
138
  ),
109
139
  ) as any;
@@ -130,35 +160,64 @@ export interface CompiledStack<
130
160
 
131
161
  export const StackName = Stack.use((stack) => Effect.succeed(stack.name));
132
162
 
163
+ export interface MakeStackProps<ROut = never> {
164
+ name: string;
165
+ providers: Layer.Layer<ROut, never, StackServices>;
166
+ state: Layer.Layer<State, never, StackServices>;
167
+ /** @internal */
168
+ stack?: StackSpec;
169
+ }
170
+
133
171
  export const make =
134
- <ROut = never>(
135
- name: string,
136
- providers: Layer.Layer<ROut, never, StackServices>,
137
- /** @internal */
138
- stack?: StackSpec,
139
- ) =>
172
+ <ROut = never>(options: MakeStackProps<ROut>) =>
140
173
  <A, Err = never, Req extends ROut | StackServices = never>(
141
174
  effect: Effect.Effect<A, Err, Req>,
142
175
  ) =>
143
176
  Effect.scope.pipe(
144
177
  Effect.flatMap((scope) => {
145
- const stackLayer = Layer.effect(
146
- Stack,
147
- Stage.asEffect().pipe(
148
- Effect.map(
149
- (stage) =>
150
- stack ?? {
151
- name,
152
- stage,
153
- resources: {},
154
- bindings: {},
155
- },
178
+ if (options.state == null) {
179
+ return Effect.die(
180
+ new Error(
181
+ `Stack "${options.name}" is missing a state store. ` +
182
+ `Add a \`state\` layer to the stack options, e.g.:\n` +
183
+ ` Alchemy.Stack("${options.name}", {\n` +
184
+ ` providers: Cloudflare.providers(),\n` +
185
+ ` state: Cloudflare.state(), // <-- required\n` +
186
+ ` }, ...)\n` +
187
+ `See https://alchemy.run/concepts/state-store for available state stores.`,
188
+ ),
189
+ );
190
+ }
191
+ if (options.providers == null) {
192
+ return Effect.die(
193
+ new Error(
194
+ `Stack "${options.name}" is missing a providers layer. ` +
195
+ `Add a \`providers\` layer to the stack options, e.g.:\n` +
196
+ ` Alchemy.Stack("${options.name}", {\n` +
197
+ ` providers: Cloudflare.providers(), // <-- required\n` +
198
+ ` state: Cloudflare.state(),\n` +
199
+ ` }, ...)`,
200
+ ),
201
+ );
202
+ }
203
+ return options.providers.pipe(
204
+ Layer.provideMerge(options.state),
205
+ Layer.provideMerge(
206
+ Layer.effect(
207
+ Stack,
208
+ Stage.asEffect().pipe(
209
+ Effect.map(
210
+ (stage) =>
211
+ options.stack ?? {
212
+ name: options.name,
213
+ stage,
214
+ resources: {},
215
+ bindings: {},
216
+ },
217
+ ),
218
+ ),
156
219
  ),
157
- Effect.tap(Effect.logInfo),
158
220
  ),
159
- );
160
- return providers.pipe(
161
- Layer.provideMerge(stackLayer),
162
221
  Layer.buildWithScope(scope),
163
222
  );
164
223
  }),
@@ -175,7 +234,7 @@ export const make =
175
234
  > => ({
176
235
  ...stack,
177
236
  output,
178
- services,
237
+ services: Context.merge(services, context),
179
238
  }),
180
239
  ),
181
240
  Effect.provideContext(context),
@@ -186,3 +245,45 @@ export const make =
186
245
  export const CurrentStack = Effect.serviceOption(Stack)
187
246
  .asEffect()
188
247
  .pipe(Effect.map(Option.getOrUndefined));
248
+
249
+ const platform = Layer.mergeAll(
250
+ PlatformServices,
251
+ FetchHttpClient.layer,
252
+ Logger.layer([fileLogger("out")]),
253
+ );
254
+ // override alchemy state store, CLI/reporting, state, and Config
255
+ const alchemy = Layer.mergeAll(
256
+ // CLI.inkCLI(),
257
+ // optional
258
+ AlchemyContextLive,
259
+ );
260
+
261
+ export const evalStack = <A, B, Err, Req>(
262
+ effect: StackEffect<CompiledStack<A>, Stage | AlchemyContext>,
263
+ fn: (stack: CompiledStack<A>) => Effect.Effect<B, Err, Req>,
264
+ options: {
265
+ stage: string;
266
+ },
267
+ ) =>
268
+ Effect.gen(function* () {
269
+ const stack = yield* effect;
270
+ const configProvider = yield* loadConfigProvider(Option.none());
271
+
272
+ return yield* fn(stack).pipe(
273
+ provideFreshArtifactStore,
274
+ Effect.provide(stack.services),
275
+ Effect.provide(Layer.succeed(ConfigProvider, configProvider)),
276
+ );
277
+ }).pipe(
278
+ Effect.provide(
279
+ Layer.effect(
280
+ AuthProviders,
281
+ Effect.serviceOption(AuthProviders).pipe(
282
+ Effect.map(Option.getOrElse(() => ({}))),
283
+ ),
284
+ ),
285
+ ),
286
+ Effect.provide(Layer.succeed(Stage, options.stage)),
287
+ Effect.provide(Layer.provideMerge(alchemy, platform)),
288
+ Effect.scoped,
289
+ );