alchemy 2.0.0-beta.13 → 2.0.0-beta.14

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 (264) hide show
  1. package/bin/alchemy.js +8386 -8205
  2. package/bin/alchemy.js.map +1 -1
  3. package/bin/alchemy.ts +4 -2
  4. package/bin/cli.js +61 -0
  5. package/bin/commands/deploy.ts +6 -3
  6. package/bin/commands/login.ts +1 -1
  7. package/bin/commands/logs.ts +1 -1
  8. package/bin/commands/state.ts +230 -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/util/ripgrep.d.ts +2 -2
  53. package/lib/AlchemyContext.d.ts +13 -0
  54. package/lib/AlchemyContext.d.ts.map +1 -0
  55. package/lib/AlchemyContext.js +18 -0
  56. package/lib/AlchemyContext.js.map +1 -0
  57. package/lib/Auth/AuthProvider.js +1 -1
  58. package/lib/Auth/AuthProvider.js.map +1 -1
  59. package/lib/Auth/Profile.d.ts +1 -1
  60. package/lib/Auth/index.d.ts +3 -1
  61. package/lib/Auth/index.d.ts.map +1 -1
  62. package/lib/Auth/index.js +3 -0
  63. package/lib/Auth/index.js.map +1 -1
  64. package/lib/Build/Command.d.ts +1 -1
  65. package/lib/Build/Memo.d.ts +1 -1
  66. package/lib/Bundle/Docker.d.ts +3 -3
  67. package/lib/Bundle/TempRoot.d.ts +3 -3
  68. package/lib/Cli/InkCLI.d.ts +1 -0
  69. package/lib/Cli/InkCLI.d.ts.map +1 -1
  70. package/lib/Cli/InkCLI.js +5 -0
  71. package/lib/Cli/InkCLI.js.map +1 -1
  72. package/lib/Cli/LoggingCli.d.ts +4 -0
  73. package/lib/Cli/LoggingCli.d.ts.map +1 -0
  74. package/lib/{Test/TestCli.js → Cli/LoggingCli.js} +3 -3
  75. package/lib/Cli/LoggingCli.js.map +1 -0
  76. package/lib/Cloudflare/CloudflareEnvironment.d.ts +1 -1
  77. package/lib/Cloudflare/Container/ContainerApplication.d.ts +2 -2
  78. package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
  79. package/lib/Cloudflare/Container/ContainerApplication.js +7 -2
  80. package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
  81. package/lib/Cloudflare/EdgeSession.d.ts +53 -0
  82. package/lib/Cloudflare/EdgeSession.d.ts.map +1 -0
  83. package/lib/Cloudflare/EdgeSession.js +78 -0
  84. package/lib/Cloudflare/EdgeSession.js.map +1 -0
  85. package/lib/Cloudflare/Providers.d.ts +1 -1
  86. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  87. package/lib/Cloudflare/StateStore/Api.d.ts +62 -0
  88. package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -0
  89. package/lib/Cloudflare/StateStore/Api.js +101 -0
  90. package/lib/Cloudflare/StateStore/Api.js.map +1 -0
  91. package/lib/Cloudflare/StateStore/State.d.ts +39 -0
  92. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -0
  93. package/lib/Cloudflare/StateStore/State.js +217 -0
  94. package/lib/Cloudflare/StateStore/State.js.map +1 -0
  95. package/lib/Cloudflare/StateStore/Store.d.ts +82 -0
  96. package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -0
  97. package/lib/Cloudflare/StateStore/Store.js +189 -0
  98. package/lib/Cloudflare/StateStore/Store.js.map +1 -0
  99. package/lib/Cloudflare/StateStore/Token.d.ts +41 -0
  100. package/lib/Cloudflare/StateStore/Token.d.ts.map +1 -0
  101. package/lib/Cloudflare/StateStore/Token.js +57 -0
  102. package/lib/Cloudflare/StateStore/Token.js.map +1 -0
  103. package/lib/Cloudflare/StateStore/index.d.ts +2 -0
  104. package/lib/Cloudflare/StateStore/index.d.ts.map +1 -0
  105. package/lib/Cloudflare/StateStore/index.js +2 -0
  106. package/lib/Cloudflare/StateStore/index.js.map +1 -0
  107. package/lib/Cloudflare/Workers/Assets.d.ts +2 -2
  108. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts +2 -2
  109. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts.map +1 -1
  110. package/lib/Cloudflare/Workers/DurableObjectNamespace.js +0 -1
  111. package/lib/Cloudflare/Workers/DurableObjectNamespace.js.map +1 -1
  112. package/lib/Cloudflare/Workers/HttpServer.d.ts +1 -1
  113. package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
  114. package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
  115. package/lib/Cloudflare/Workers/Worker.d.ts +5 -5
  116. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  117. package/lib/Cloudflare/Workers/Worker.js +0 -1
  118. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  119. package/lib/Cloudflare/index.d.ts +3 -1
  120. package/lib/Cloudflare/index.d.ts.map +1 -1
  121. package/lib/Cloudflare/index.js +3 -1
  122. package/lib/Cloudflare/index.js.map +1 -1
  123. package/lib/Deploy.d.ts +10 -0
  124. package/lib/Deploy.d.ts.map +1 -0
  125. package/lib/Deploy.js +12 -0
  126. package/lib/Deploy.js.map +1 -0
  127. package/lib/Destroy.d.ts +8 -3
  128. package/lib/Destroy.d.ts.map +1 -1
  129. package/lib/Destroy.js +8 -8
  130. package/lib/Destroy.js.map +1 -1
  131. package/lib/Http.d.ts +1 -1
  132. package/lib/Http.d.ts.map +1 -1
  133. package/lib/Http.js +7 -3
  134. package/lib/Http.js.map +1 -1
  135. package/lib/Kubernetes/client.d.ts +10 -10
  136. package/lib/Output.d.ts.map +1 -1
  137. package/lib/Output.js.map +1 -1
  138. package/lib/Platform.d.ts +2 -2
  139. package/lib/Platform.d.ts.map +1 -1
  140. package/lib/Platform.js.map +1 -1
  141. package/lib/Provider.d.ts.map +1 -1
  142. package/lib/Provider.js +0 -1
  143. package/lib/Provider.js.map +1 -1
  144. package/lib/Stack.d.ts +23 -12
  145. package/lib/Stack.d.ts.map +1 -1
  146. package/lib/Stack.js +32 -14
  147. package/lib/Stack.js.map +1 -1
  148. package/lib/State/HttpStateApi.d.ts +96 -0
  149. package/lib/State/HttpStateApi.d.ts.map +1 -0
  150. package/lib/State/HttpStateApi.js +96 -0
  151. package/lib/State/HttpStateApi.js.map +1 -0
  152. package/lib/State/HttpStateStore.d.ts +10 -0
  153. package/lib/State/HttpStateStore.d.ts.map +1 -0
  154. package/lib/State/HttpStateStore.js +102 -0
  155. package/lib/State/HttpStateStore.js.map +1 -0
  156. package/lib/State/InMemoryState.d.ts +2 -30
  157. package/lib/State/InMemoryState.d.ts.map +1 -1
  158. package/lib/State/InMemoryState.js +23 -18
  159. package/lib/State/InMemoryState.js.map +1 -1
  160. package/lib/State/LocalState.d.ts +4 -2
  161. package/lib/State/LocalState.d.ts.map +1 -1
  162. package/lib/State/LocalState.js +9 -41
  163. package/lib/State/LocalState.js.map +1 -1
  164. package/lib/State/State.d.ts +11 -4
  165. package/lib/State/State.d.ts.map +1 -1
  166. package/lib/State/State.js +1 -1
  167. package/lib/State/State.js.map +1 -1
  168. package/lib/State/StateEncoding.d.ts +31 -0
  169. package/lib/State/StateEncoding.d.ts.map +1 -0
  170. package/lib/State/StateEncoding.js +82 -0
  171. package/lib/State/StateEncoding.js.map +1 -0
  172. package/lib/State/Sync.d.ts +23 -0
  173. package/lib/State/Sync.d.ts.map +1 -0
  174. package/lib/State/Sync.js +49 -0
  175. package/lib/State/Sync.js.map +1 -0
  176. package/lib/State/index.d.ts +4 -0
  177. package/lib/State/index.d.ts.map +1 -1
  178. package/lib/State/index.js +4 -0
  179. package/lib/State/index.js.map +1 -1
  180. package/lib/Test/Bun.d.ts +13 -17
  181. package/lib/Test/Bun.d.ts.map +1 -1
  182. package/lib/Test/Bun.js +16 -33
  183. package/lib/Test/Bun.js.map +1 -1
  184. package/lib/Test/TestState.d.ts +1 -2
  185. package/lib/Test/TestState.d.ts.map +1 -1
  186. package/lib/Test/TestState.js +5 -9
  187. package/lib/Test/TestState.js.map +1 -1
  188. package/lib/Test/Vitest.d.ts +3 -2
  189. package/lib/Test/Vitest.d.ts.map +1 -1
  190. package/lib/Test/Vitest.js +20 -15
  191. package/lib/Test/Vitest.js.map +1 -1
  192. package/lib/Test/index.d.ts +0 -1
  193. package/lib/Test/index.d.ts.map +1 -1
  194. package/lib/Test/index.js +0 -1
  195. package/lib/Test/index.js.map +1 -1
  196. package/lib/Util/FileLogger.d.ts +2 -2
  197. package/lib/Util/FileLogger.d.ts.map +1 -1
  198. package/lib/Util/FileLogger.js +2 -2
  199. package/lib/Util/FileLogger.js.map +1 -1
  200. package/lib/cli/index.d.ts +10 -1
  201. package/lib/cli/index.d.ts.map +1 -1
  202. package/lib/cli/index.js +9 -4
  203. package/lib/cli/index.js.map +1 -1
  204. package/lib/index.d.ts +2 -1
  205. package/lib/index.d.ts.map +1 -1
  206. package/lib/index.js +2 -1
  207. package/lib/index.js.map +1 -1
  208. package/package.json +26 -11
  209. package/src/AWS/ECS/Task.ts +4 -4
  210. package/src/AWS/Lambda/Function.ts +2 -3
  211. package/src/AWS/SQS/QueueSink.ts +1 -2
  212. package/src/Agent/coding/bash.ts +2 -3
  213. package/src/Agent/coding/glob.ts +1 -2
  214. package/src/Agent/coding/grep.ts +1 -2
  215. package/src/AlchemyContext.ts +27 -0
  216. package/src/Auth/AuthProvider.ts +1 -1
  217. package/src/Auth/index.ts +3 -1
  218. package/src/Cli/InkCLI.tsx +10 -0
  219. package/src/{Test/TestCli.ts → Cli/LoggingCli.ts} +2 -2
  220. package/src/Cloudflare/Container/ContainerApplication.ts +8 -2
  221. package/src/Cloudflare/EdgeSession.ts +144 -0
  222. package/src/Cloudflare/StateStore/Api.ts +157 -0
  223. package/src/Cloudflare/StateStore/State.ts +318 -0
  224. package/src/Cloudflare/StateStore/Store.ts +288 -0
  225. package/src/Cloudflare/StateStore/Token.ts +62 -0
  226. package/src/Cloudflare/StateStore/index.ts +1 -0
  227. package/src/Cloudflare/Workers/DurableObjectNamespace.ts +1 -6
  228. package/src/Cloudflare/Workers/HttpServer.ts +1 -1
  229. package/src/Cloudflare/Workers/Worker.ts +7 -7
  230. package/src/Cloudflare/index.ts +3 -1
  231. package/src/Deploy.ts +25 -0
  232. package/src/Destroy.ts +25 -13
  233. package/src/Http.ts +31 -16
  234. package/src/Output.ts +0 -2
  235. package/src/Platform.ts +8 -2
  236. package/src/Provider.ts +0 -2
  237. package/src/Stack.ts +122 -47
  238. package/src/State/HttpStateApi.ts +155 -0
  239. package/src/State/HttpStateStore.ts +155 -0
  240. package/src/State/InMemoryState.ts +15 -17
  241. package/src/State/LocalState.ts +13 -45
  242. package/src/State/State.ts +13 -4
  243. package/src/State/StateEncoding.ts +83 -0
  244. package/src/State/Sync.ts +89 -0
  245. package/src/State/index.ts +4 -0
  246. package/src/Test/Bun.ts +29 -87
  247. package/src/Test/TestState.ts +6 -8
  248. package/src/Test/Vitest.ts +32 -23
  249. package/src/Test/index.ts +0 -1
  250. package/src/Util/FileLogger.ts +2 -2
  251. package/src/index.ts +2 -1
  252. package/lib/Config.d.ts +0 -20
  253. package/lib/Config.d.ts.map +0 -1
  254. package/lib/Config.js +0 -22
  255. package/lib/Config.js.map +0 -1
  256. package/lib/Observability.d.ts +0 -2
  257. package/lib/Observability.d.ts.map +0 -1
  258. package/lib/Observability.js +0 -1
  259. package/lib/Observability.js.map +0 -1
  260. package/lib/Test/TestCli.d.ts +0 -4
  261. package/lib/Test/TestCli.d.ts.map +0 -1
  262. package/lib/Test/TestCli.js.map +0 -1
  263. package/src/Config.ts +0 -31
  264. package/src/Observability.ts +0 -0
@@ -0,0 +1,62 @@
1
+ import * as Cloudflare from "alchemy/Cloudflare";
2
+ import * as Effect from "effect/Effect";
3
+ export declare const STATE_STORE_SCRIPT_NAME: "alchemy-state-store";
4
+ declare const _default: Effect.Effect<import("effect/Pipeable").Pipeable & import("../../Resource.ts").ResourceLike<"Cloudflare.Worker", Cloudflare.WorkerProps<any, Cloudflare.WorkerAssetsConfig | undefined>, {
5
+ workerId: string;
6
+ workerName: string;
7
+ logpush: boolean | undefined;
8
+ url: string | undefined;
9
+ tags: string[] | undefined;
10
+ durableObjectNamespaces: Record<string, string>;
11
+ accountId: string;
12
+ domains: {
13
+ hostname: string;
14
+ id: string;
15
+ zoneId: string;
16
+ }[];
17
+ hash?: {
18
+ assets: string | undefined;
19
+ bundle: string | undefined;
20
+ input: string | undefined;
21
+ };
22
+ }, {
23
+ bindings?: Cloudflare.WorkerBinding[];
24
+ containers?: {
25
+ className: string;
26
+ }[];
27
+ }, Cloudflare.Providers> & {
28
+ bind(sid: string, binding: import("../../Input.ts").Input<{
29
+ bindings?: Cloudflare.WorkerBinding[];
30
+ containers?: {
31
+ className: string;
32
+ }[];
33
+ }>): Effect.Effect<void>;
34
+ bind(template: TemplateStringsArray, ...args: any[]): (binding: import("../../Input.ts").Input<{
35
+ bindings?: Cloudflare.WorkerBinding[];
36
+ containers?: {
37
+ className: string;
38
+ }[];
39
+ }>) => Effect.Effect<void>;
40
+ } & {
41
+ workerId: import("../../Output.ts").Output<string, never>;
42
+ workerName: import("../../Output.ts").Output<string, never>;
43
+ logpush: import("../../Output.ts").Output<boolean | undefined, never>;
44
+ url: import("../../Output.ts").Output<string | undefined, never>;
45
+ tags: import("../../Output.ts").Output<string[] | undefined, never>;
46
+ durableObjectNamespaces: import("../../Output.ts").Output<Record<string, string>, never>;
47
+ accountId: import("../../Output.ts").Output<string, never>;
48
+ domains: import("../../Output.ts").Output<{
49
+ hostname: string;
50
+ id: string;
51
+ zoneId: string;
52
+ }[], never>;
53
+ hash: import("../../Output.ts").Output<{
54
+ assets: string | undefined;
55
+ bundle: string | undefined;
56
+ input: string | undefined;
57
+ } | undefined, never>;
58
+ } & import("../../Platform.ts").Rpc<{
59
+ fetch: Effect.Effect<Effect.Effect<import("effect/unstable/http/HttpServerResponse").HttpServerResponse, import("effect/unstable/http/HttpServerError").HttpServerError, import("effect/Scope").Scope | import("effect/unstable/http/HttpServerRequest").HttpServerRequest>, never, import("effect/FileSystem").FileSystem | import("effect/Scope").Scope | Cloudflare.WorkerEnvironment>;
60
+ }>, never, Cloudflare.Providers>;
61
+ export default _default;
62
+ //# sourceMappingURL=Api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Api.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/StateStore/Api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AAMjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAYxC,eAAO,MAAM,uBAAuB,EAAG,qBAA8B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtE,wBA6GE"}
@@ -0,0 +1,101 @@
1
+ import * as Cloudflare from "alchemy/Cloudflare";
2
+ import { BearerTokenValidator, StateApi, StateAuthLive, } from "alchemy/State/HttpStateApi";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Path from "effect/Path";
6
+ import * as Etag from "effect/unstable/http/Etag";
7
+ import * as HttpPlatform from "effect/unstable/http/HttpPlatform";
8
+ import * as HttpRouter from "effect/unstable/http/HttpRouter";
9
+ import * as HttpApiBuilder from "effect/unstable/httpapi/HttpApiBuilder";
10
+ import * as HttpApiError from "effect/unstable/httpapi/HttpApiError";
11
+ import crypto from "node:crypto";
12
+ import Store from "./Store.js";
13
+ import { AuthToken } from "./Token.js";
14
+ export const STATE_STORE_SCRIPT_NAME = "alchemy-state-store";
15
+ export default Cloudflare.Worker("Api", {
16
+ name: STATE_STORE_SCRIPT_NAME,
17
+ main: import.meta.path,
18
+ url: true,
19
+ compatibility: {
20
+ flags: ["nodejs_compat"],
21
+ date: "2026-03-17",
22
+ },
23
+ }, Effect.gen(function* () {
24
+ const secret = yield* Cloudflare.Secret.bind(AuthToken);
25
+ const store = yield* Store;
26
+ const bearerTokenValidator = Layer.effect(BearerTokenValidator, secret.get().pipe(Effect.map((expected) => BearerTokenValidator.of({
27
+ validate: (token) => !!expected && timingSafeEqual(token, expected)
28
+ ? Effect.void
29
+ : Effect.fail(new HttpApiError.Unauthorized()),
30
+ })), Effect.orDie));
31
+ const stateApi = HttpApiBuilder.group(StateApi, "state", (handlers) => handlers
32
+ .handle("listStacks", () => store.getByName(Store.ROOT_DO_NAME).listStacks())
33
+ .handle("listStages", ({ params }) => store.getByName(params.stack).listStages())
34
+ .handle("listResources", ({ params }) => store.getByName(params.stack).listResources({ stage: params.stage }))
35
+ .handle("getState", ({ params }) => store
36
+ .getByName(params.stack)
37
+ .get({ stage: params.stage, fqn: decodeURIComponent(params.fqn) }))
38
+ .handle("setState", ({ params, payload }) => store
39
+ .getByName(params.stack)
40
+ .set({
41
+ stage: params.stage,
42
+ fqn: decodeURIComponent(params.fqn),
43
+ value: payload,
44
+ })
45
+ .pipe(Effect.tap(() => store
46
+ .getByName(Store.ROOT_DO_NAME)
47
+ .registerStack({ stack: params.stack }))))
48
+ .handle("deleteState", ({ params }) =>
49
+ // The DO method is `remove`, not `delete` — `delete` is
50
+ // reserved by Cloudflare's RPC stub proxy.
51
+ store
52
+ .getByName(params.stack)
53
+ .remove({
54
+ stage: params.stage,
55
+ fqn: decodeURIComponent(params.fqn),
56
+ })
57
+ .pipe(Effect.asVoid))
58
+ .handle("getReplacedResources", ({ params }) => store
59
+ .getByName(params.stack)
60
+ .getReplacedResources({ stage: params.stage }))
61
+ .handle("deleteStack", ({ params, query }) => store
62
+ .getByName(params.stack)
63
+ .deleteStack(query.stage === undefined ? {} : { stage: query.stage })
64
+ .pipe(Effect.flatMap(() => query.stage === undefined
65
+ ? store
66
+ .getByName(Store.ROOT_DO_NAME)
67
+ .unregisterStack({ stack: params.stack })
68
+ : Effect.void), Effect.asVoid)));
69
+ return {
70
+ fetch: HttpApiBuilder.layer(StateApi).pipe(Layer.provide(stateApi), Layer.provide(StateAuthLive), Layer.provide(bearerTokenValidator),
71
+ // The state-store worker never serves files, so HttpPlatform's
72
+ // file-response surface is stubbed.
73
+ Layer.provide([Etag.layer, HttpPlatformStub, Path.layer]), HttpRouter.toHttpEffect),
74
+ };
75
+ }).pipe(Effect.provide(Layer.mergeAll(Cloudflare.SecretBindingLive))));
76
+ /**
77
+ * Stub `HttpPlatform` for the worker. The state-store API never
78
+ * issues file responses, so both surface methods die if invoked. Lets
79
+ * us avoid pulling in a `FileSystem` dependency that workers don't
80
+ * have.
81
+ */
82
+ const HttpPlatformStub = Layer.succeed(HttpPlatform.HttpPlatform, {
83
+ fileResponse: () => Effect.die("HttpPlatform.fileResponse not supported"),
84
+ fileWebResponse: () => Effect.die("HttpPlatform.fileWebResponse not supported"),
85
+ });
86
+ /**
87
+ * Timing-safe string comparison using the Workers runtime's built-in
88
+ * `crypto.subtle.timingSafeEqual`.
89
+ *
90
+ * @see https://developers.cloudflare.com/workers/examples/protect-against-timing-attacks/
91
+ */
92
+ const timingSafeEqual = (a, b) => {
93
+ const encoder = new TextEncoder();
94
+ const aBytes = encoder.encode(a);
95
+ const bBytes = encoder.encode(b);
96
+ if (aBytes.byteLength !== bBytes.byteLength)
97
+ return false;
98
+ // @ts-expect-error - TODO(sam)
99
+ return crypto.subtle.timingSafeEqual(aBytes, bBytes);
100
+ };
101
+ //# sourceMappingURL=Api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Api.js","sourceRoot":"","sources":["../../../src/Cloudflare/StateStore/Api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import * as SecretsStore from "@distilled.cloud/cloudflare/secrets-store";
2
+ import * as workers from "@distilled.cloud/cloudflare/workers";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as HttpClient from "effect/unstable/http/HttpClient";
6
+ import * as Config from "effect/Config";
7
+ import { AuthError } from "../../Auth/AuthProvider.ts";
8
+ import * as Cloudflare from "../../Cloudflare/Providers.ts";
9
+ import * as CloudflareEnvironment from "../CloudflareEnvironment.ts";
10
+ import { AlchemyContext } from "../../AlchemyContext.ts";
11
+ import { State } from "../../State/State.ts";
12
+ export declare const state: (props?: {
13
+ /**
14
+ * The name of the script to use for the state store.
15
+ * @default "alchemy-state-store"
16
+ */
17
+ workerName?: string;
18
+ }) => Layer.Layer<State | Cloudflare.Credentials | CloudflareEnvironment.CloudflareEnvironment, never, AlchemyContext | import("effect/Path").Path | import("effect/FileSystem").FileSystem | HttpClient.HttpClient | import("../../Auth/AuthProvider.ts").AuthProviders>;
19
+ /**
20
+ * Log in to a Cloudflare-deployed HTTP state-store.
21
+ *
22
+ * 1. Find the single account-wide Secrets Store.
23
+ * 2. Upload a short-lived edge-preview worker that binds the
24
+ * auth-token secret and returns its value.
25
+ * 3. Derive the state-store worker URL from
26
+ * {@link STATE_STORE_SCRIPT_NAME} and the account's workers.dev
27
+ * subdomain.
28
+ * 4. Persist `{ url, token }` under the `http-state-store`
29
+ * credentials file.
30
+ *
31
+ * Requirements are covered by the Cloudflare provider stack —
32
+ * `CloudflareEnvironment`, `Credentials`, `HttpClient`, and
33
+ * `FileSystem`.
34
+ */
35
+ export declare const loginWithCloudflare: () => Effect.Effect<{
36
+ url: string;
37
+ authToken: string;
38
+ }, Config.ConfigError | AuthError | import("@distilled.cloud/cloudflare").Unauthorized | import("@distilled.cloud/cloudflare").TooManyRequests | import("@distilled.cloud/cloudflare").InternalServerError | import("@distilled.cloud/cloudflare").BadGateway | import("@distilled.cloud/cloudflare").ServiceUnavailable | import("@distilled.cloud/cloudflare").GatewayTimeout | import("@distilled.cloud/cloudflare").CloudflareHttpError | import("@distilled.cloud/cloudflare").CloudflareParseError | import("@distilled.cloud/cloudflare").UnknownCloudflareError | workers.InvalidRoute | SecretsStore.InvalidAccountId, import("effect/FileSystem").FileSystem | HttpClient.HttpClient | Cloudflare.Credentials | CloudflareEnvironment.CloudflareEnvironment>;
39
+ //# sourceMappingURL=State.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/StateStore/State.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,2CAA2C,CAAC;AAC1E,OAAO,KAAK,OAAO,MAAM,qCAAqC,CAAC;AAE/D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAE9D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGvD,OAAO,KAAK,UAAU,MAAM,+BAA+B,CAAC;AAO5D,OAAO,KAAK,qBAAqB,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,KAAK,EAAqB,MAAM,sBAAsB,CAAC;AAWhE,eAAO,MAAM,KAAK,GAAI,QAAQ;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,wQAuGE,CAAC;AAoCJ;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB;;;suBA6D7B,CAAC"}
@@ -0,0 +1,217 @@
1
+ import * as SecretsStore from "@distilled.cloud/cloudflare/secrets-store";
2
+ import * as workers from "@distilled.cloud/cloudflare/workers";
3
+ import * as Output from "alchemy/Output";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import * as Redacted from "effect/Redacted";
7
+ import * as HttpClient from "effect/unstable/http/HttpClient";
8
+ import * as Config from "effect/Config";
9
+ import { AuthError } from "../../Auth/AuthProvider.js";
10
+ import { readCredentials, writeCredentials } from "../../Auth/Credentials.js";
11
+ import { ALCHEMY_PROFILE } from "../../Auth/Profile.js";
12
+ import * as Cloudflare from "../../Cloudflare/Providers.js";
13
+ import { deploy } from "../../Deploy.js";
14
+ import * as Alchemy from "../../Stack.js";
15
+ import { makeHttpStateStore, } from "../../State/HttpStateStore.js";
16
+ import * as CloudflareEnvironment from "../CloudflareEnvironment.js";
17
+ import * as Credentials from "../Credentials.js";
18
+ import { AlchemyContext } from "../../AlchemyContext.js";
19
+ import { makeLocalState } from "../../State/LocalState.js";
20
+ import { State } from "../../State/State.js";
21
+ import { syncState } from "../../State/Sync.js";
22
+ import * as Clank from "../../Util/Clank.js";
23
+ import { CloudflareAuth } from "../Auth/AuthProvider.js";
24
+ import { EdgeSessionError, createEdgeSession } from "../EdgeSession.js";
25
+ import Api, { STATE_STORE_SCRIPT_NAME } from "./Api.js";
26
+ import { AuthTokenSecretName, TokenValue } from "./Token.js";
27
+ /** Filename used for stored credentials under the profile directory. */
28
+ const CREDENTIALS_FILE = "cloudflare-state-store";
29
+ export const state = (props) => Layer.effect(State, Effect.gen(function* () {
30
+ const isCI = yield* Config.boolean("CI").pipe(Config.withDefault(false));
31
+ const alchemyContext = yield* AlchemyContext;
32
+ const profileName = yield* ALCHEMY_PROFILE;
33
+ const credentials = yield* readCredentials(profileName, CREDENTIALS_FILE);
34
+ const scriptName = props?.workerName ?? STATE_STORE_SCRIPT_NAME;
35
+ // TODO(sam): support upgrading state store, right now we only deploy once
36
+ if (credentials) {
37
+ // it's in the profile, let's go
38
+ const httpState = yield* makeHttpStateStore(credentials);
39
+ if (alchemyContext.updateStateStore) {
40
+ yield* deployStateStore(scriptName, httpState);
41
+ }
42
+ return httpState;
43
+ }
44
+ else {
45
+ // our profile does not contain a reference to the state store, let's try and resolve it
46
+ const { accountId } = yield* CloudflareEnvironment.CloudflareEnvironment;
47
+ const workerExists = yield* workers
48
+ .getScriptSetting({
49
+ accountId,
50
+ scriptName,
51
+ })
52
+ .pipe(Effect.map((setting) => setting !== undefined), Effect.catchTag("WorkerNotFound", () => Effect.succeed(false)));
53
+ if (workerExists) {
54
+ // it exists, so fetch the secret token
55
+ const credentials = yield* loginWithCloudflare();
56
+ if (!isCI) {
57
+ yield* writeCredentials(profileName, CREDENTIALS_FILE, credentials);
58
+ }
59
+ const httpState = yield* makeHttpStateStore(credentials);
60
+ if (alchemyContext.updateStateStore) {
61
+ yield* deployStateStore(scriptName, httpState);
62
+ }
63
+ return httpState;
64
+ }
65
+ else if (isCI) {
66
+ // TODO(sam): do we want to support bootstrapping the state store from CI?
67
+ // for now - just die here
68
+ return yield* Effect.die(new AuthError({
69
+ message: `State store not found for script ${scriptName}. Deploy the state store first.`,
70
+ }));
71
+ }
72
+ const shouldDeploy = yield* Clank.confirm({
73
+ message: "Cloudflare State Store not found. Do you want to deploy it?",
74
+ });
75
+ if (!shouldDeploy) {
76
+ return yield* Effect.die(new Clank.PromptCancelled());
77
+ }
78
+ const { url, authToken, localState } = yield* deployStateStore(scriptName);
79
+ const httpState = yield* makeHttpStateStore({ url, authToken });
80
+ yield* syncState(localState, httpState);
81
+ yield* writeCredentials(profileName, CREDENTIALS_FILE, {
82
+ url,
83
+ authToken,
84
+ });
85
+ yield* localState.deleteStack({
86
+ stack: "CloudflareStateStore",
87
+ stage: scriptName,
88
+ });
89
+ return httpState;
90
+ }
91
+ }).pipe(Effect.orDie)).pipe(Layer.provideMerge(Credentials.fromAuthProvider()), Layer.provideMerge(CloudflareEnvironment.fromProfile()), Layer.provideMerge(CloudflareAuth), Layer.orDie);
92
+ const deployStateStore = (scriptName, state) => Effect.gen(function* () {
93
+ const localState = state ?? (yield* makeLocalState());
94
+ // deploy it with local state (which we will then hoist into the Cloudflare state store)
95
+ const stateLayer = Layer.succeed(State, localState);
96
+ const { url, authToken } = yield* deploy({
97
+ // use the script name as the stage name (so the user can have multiple state stores)
98
+ stage: scriptName,
99
+ stack: Alchemy.Stack("CloudflareStateStore", {
100
+ providers: Cloudflare.providers(),
101
+ state: stateLayer,
102
+ }, Effect.gen(function* () {
103
+ const token = yield* TokenValue;
104
+ const api = yield* Api;
105
+ // Surface the bearer token so tests and clients can authenticate
106
+ // after deploy. The underlying value lives in the Cloudflare
107
+ // Secrets Store; this output carries the same generated string.
108
+ return {
109
+ url: api.url.as(),
110
+ authToken: token.text.pipe(Output.map(Redacted.value)),
111
+ };
112
+ })),
113
+ }).pipe(
114
+ // TODO(sam): we should not need to do this, but types do complain. fix deploy
115
+ Effect.provide(stateLayer));
116
+ return { url, authToken, localState };
117
+ });
118
+ /**
119
+ * Log in to a Cloudflare-deployed HTTP state-store.
120
+ *
121
+ * 1. Find the single account-wide Secrets Store.
122
+ * 2. Upload a short-lived edge-preview worker that binds the
123
+ * auth-token secret and returns its value.
124
+ * 3. Derive the state-store worker URL from
125
+ * {@link STATE_STORE_SCRIPT_NAME} and the account's workers.dev
126
+ * subdomain.
127
+ * 4. Persist `{ url, token }` under the `http-state-store`
128
+ * credentials file.
129
+ *
130
+ * Requirements are covered by the Cloudflare provider stack —
131
+ * `CloudflareEnvironment`, `Credentials`, `HttpClient`, and
132
+ * `FileSystem`.
133
+ */
134
+ export const loginWithCloudflare = () => Effect.gen(function* () {
135
+ const isCI = yield* Config.boolean("CI").pipe(Config.withDefault(false));
136
+ const profileName = yield* ALCHEMY_PROFILE;
137
+ const { accountId } = yield* CloudflareEnvironment.CloudflareEnvironment;
138
+ // 1. Locate the single Secrets Store on the account.
139
+ const stores = yield* SecretsStore.listStores({ accountId });
140
+ const store = stores.result[0];
141
+ if (!store) {
142
+ return yield* Effect.fail(new AuthError({
143
+ message: "No Secrets Store found on this account. Deploy the state store first.",
144
+ }));
145
+ }
146
+ // 2. Fetch the auth-token value via an edge-preview worker.
147
+ const authToken = yield* readSecretViaEdge(store.id, AuthTokenSecretName);
148
+ // 3. Derive the deployed worker URL.
149
+ const { subdomain } = yield* workers.getSubdomain({ accountId });
150
+ const url = `https://${STATE_STORE_SCRIPT_NAME}.${subdomain}.workers.dev`;
151
+ if (!isCI) {
152
+ // 4. Persist credentials. The profile entry is managed by
153
+ // `loadOrConfigure` when this is invoked through `configure`.
154
+ yield* writeCredentials(profileName, CREDENTIALS_FILE, {
155
+ url,
156
+ authToken: authToken.trim(),
157
+ }).pipe(Effect.mapError((e) => new AuthError({ message: "Failed to write credentials", cause: e })));
158
+ yield* Clank.success(`HTTP state store credentials saved for '${profileName}'.`);
159
+ yield* Clank.info(` url: ${url}`);
160
+ }
161
+ return {
162
+ url,
163
+ authToken: authToken.trim(),
164
+ };
165
+ }).pipe(Effect.catchTag("EdgeSessionError", (e) => Effect.fail(new AuthError({
166
+ message: `Edge-preview secret read failed: ${e.message}`,
167
+ cause: e.cause,
168
+ }))));
169
+ /** Preview script name used by the edge-probe worker. */
170
+ const PROBE_SCRIPT_NAME = "alchemy-state-store-probe";
171
+ /**
172
+ * Tiny ES-module worker that reads `env.SECRET.get()` and echoes it
173
+ * back. Uploaded as an ephemeral edge-preview, called once, then
174
+ * discarded — see {@link readSecretViaEdge}.
175
+ */
176
+ const SECRET_PROBE_SOURCE = `export default {
177
+ async fetch(_request, env) {
178
+ try {
179
+ const value = await env.SECRET.get();
180
+ return new Response(value ?? "", { status: 200, headers: { "content-type": "text/plain" } });
181
+ } catch (e) {
182
+ return new Response("Error: " + (e && e.message ? e.message : String(e)), { status: 500 });
183
+ }
184
+ },
185
+ };`;
186
+ /**
187
+ * Upload a tiny edge-preview worker that binds the given Secrets
188
+ * Store secret, call it once, and return the decoded value. The
189
+ * Cloudflare REST API deliberately hides secret values; only worker
190
+ * bindings can resolve them, so this is the out-of-band path.
191
+ */
192
+ const readSecretViaEdge = (storeId, secretName) => Effect.gen(function* () {
193
+ const http = yield* HttpClient.HttpClient;
194
+ const file = new File([SECRET_PROBE_SOURCE], "worker.js", {
195
+ type: "application/javascript+module",
196
+ });
197
+ const session = yield* createEdgeSession({
198
+ scriptName: PROBE_SCRIPT_NAME,
199
+ files: [file],
200
+ bindings: [
201
+ { type: "secrets_store_secret", name: "SECRET", secretName, storeId },
202
+ ],
203
+ });
204
+ const response = yield* http.get(session.url, {
205
+ headers: session.headers,
206
+ });
207
+ if (response.status !== 200) {
208
+ const body = yield* response.text.pipe(Effect.catch(() => Effect.succeed("")));
209
+ return yield* Effect.fail(new EdgeSessionError({
210
+ message: `Secret probe returned ${response.status}: ${body.slice(0, 200)}`,
211
+ }));
212
+ }
213
+ return yield* response.text;
214
+ }).pipe(Effect.mapError((cause) => cause instanceof EdgeSessionError
215
+ ? cause
216
+ : new EdgeSessionError({ message: "Failed to read secret", cause })));
217
+ //# sourceMappingURL=State.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"State.js","sourceRoot":"","sources":["../../../src/Cloudflare/StateStore/State.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import * as Cloudflare from "alchemy/Cloudflare";
2
+ import type { ReplacedResourceState, ResourceState } from "alchemy/State";
3
+ import * as Effect from "effect/Effect";
4
+ declare const Store_base: Effect.Effect<Cloudflare.DurableObjectNamespace<Store>, never, Cloudflare.Worker | Cloudflare.SecretBinding> & (new (_: never) => {
5
+ /**
6
+ * (Root DO only) List every stack name ever registered.
7
+ */
8
+ listStacks: () => Effect.Effect<string[], never, never>;
9
+ /**
10
+ * (Root DO only) Register a stack name. Idempotent — safe to
11
+ * call on every `set` to the corresponding stack DO.
12
+ */
13
+ registerStack: ({ stack }: {
14
+ stack: string;
15
+ }) => Effect.Effect<void, never, never>;
16
+ /**
17
+ * (Root DO only) Remove a stack name from the global index.
18
+ */
19
+ unregisterStack: ({ stack }: {
20
+ stack: string;
21
+ }) => Effect.Effect<boolean, never, never>;
22
+ /** (Stack DO only) List stages with at least one resource. */
23
+ listStages: () => Effect.Effect<string[], never, never>;
24
+ /** (Stack DO only) List every resource FQN in a stage. */
25
+ listResources: ({ stage }: {
26
+ stage: string;
27
+ }) => Effect.Effect<string[], never, never>;
28
+ /**
29
+ * (Stack DO only) Get a resource by (stage, fqn). Returns
30
+ * null if missing.
31
+ */
32
+ get: ({ stage, fqn }: {
33
+ stage: string;
34
+ fqn: string;
35
+ }) => Effect.Effect<ResourceState | undefined, never, never>;
36
+ /**
37
+ * (Stack DO only) Persist a resource. Returns the stored
38
+ * value unchanged.
39
+ */
40
+ set: ({ stage, fqn, value, }: {
41
+ stage: string;
42
+ fqn: string;
43
+ value: ResourceState;
44
+ }) => Effect.Effect<ResourceState, never, never>;
45
+ /**
46
+ * (Stack DO only) Delete a resource. Idempotent.
47
+ *
48
+ * Exposed as `remove` (not `delete`) because Cloudflare's
49
+ * Durable Object RPC stub reserves `delete` and refuses to
50
+ * proxy the call, surfacing as "RPC receiver does not
51
+ * implement the method 'delete'".
52
+ */
53
+ remove: ({ stage, fqn }: {
54
+ stage: string;
55
+ fqn: string;
56
+ }) => Effect.Effect<boolean, never, never>;
57
+ /**
58
+ * (Stack DO only) Delete every resource in this stack, or every
59
+ * resource in a single stage when specified.
60
+ */
61
+ deleteStack: ({ stage }?: {
62
+ stage?: string;
63
+ }) => Effect.Effect<void, never, never>;
64
+ /**
65
+ * (Stack DO only) Return every resource in a stage whose
66
+ * `status === "replaced"`. Each entry is decrypted so the
67
+ * `status` field can be inspected.
68
+ */
69
+ getReplacedResources: ({ stage }: {
70
+ stage: string;
71
+ }) => Effect.Effect<ReplacedResourceState[], never, never>;
72
+ });
73
+ export default class Store extends Store_base {
74
+ /**
75
+ * Well-known DO name whose sole job is to track the set of stacks
76
+ * that have ever had resources written. `listStacks` queries it;
77
+ * every `set` asks it to register the stack (idempotent).
78
+ */
79
+ static readonly ROOT_DO_NAME: "__root__";
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=Store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../../src/Cloudflare/StateStore/Store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;IAiEhC;;OAEG;;IAYH;;;OAGG;+BACwB;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;IAG5C;;OAEG;iCAC0B;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;IAK9C,8DAA8D;;IAiB9D,0DAA0D;+BAC/B;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;IAgB5C;;;OAGG;0BACmB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IASpD;;;OAGG;kCAKA;QACD,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,aAAa,CAAC;KACtB;IAUD;;;;;;;OAOG;6BACsB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAGvD;;;OAGG;8BACsB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAa3C;;;;OAIG;sCAC+B;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;;AAhM3D,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,UAkNlC;IACC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAG,UAAU,CAAU;CACpD"}