1import * as HttpRouter from "effect/http/HttpRouter";
2import { TestRoutes } from "./http.ts";
3/**
4 * The Git host with its bytes on S3 (DESIGN §22): the same building-block
5 * assembly as `stack.ts`, with `BlobStoreS3(GitObjects)` in place of R2. Needs BOTH
6 * provider sets — the bucket is an `AWS.S3.Bucket` and the Worker binds
7 * the S3 operations cross-cloud (an IAM identity is minted for it).
8 */
9import * as AWS from "@/AWS";
10import * as Cloudflare from "@/Cloudflare";
11import * as Alchemy from "@/index.ts";
12import * as Effect from "effect/Effect";
13import * as Layer from "effect/Layer";
14import {
15 BlobStoreS3,
16 GIT_WORKER_OPTIONS,
17 ApiHandlersLive,
18 HasherInline,
19 ReposDurableObject,
20 RegistryDurableObject,
21} from "@/Git/index.ts";
22
23import { TEST_SECRET, TestApi, TestAuthLive } from "./stack.ts";
24export { TEST_SECRET };
25
26/** Declared here so the stack tears it down with the packs still inside. */
27export const GitObjects = AWS.S3.Bucket("GitS3Objects", { forceDestroy: true });
28
29const GitLive = TestRoutes.pipe(
30 Layer.provide(ApiHandlersLive),
31 Layer.provide(ReposDurableObject),
32 Layer.provide(RegistryDurableObject),
33 Layer.provide(HasherInline),
34 Layer.provide(BlobStoreS3(GitObjects)),
35);
36
37export default class S3GitHost extends Cloudflare.Worker<S3GitHost>()(
38 "GitS3Worker",
39 {
40 main: import.meta.url,
41 ...GIT_WORKER_OPTIONS,
42 observability: { enabled: true },
43 },
44 Effect.gen(function* () {
45 const fetch = yield* HttpRouter.toHttpEffect(GitLive);
46 return { fetch };
47 }),
48) {}
49
50export const makeS3TestStack = (name: string) =>
51 Alchemy.Stack(
52 name,
53 {
54 providers: Layer.mergeAll(AWS.providers(), Cloudflare.providers()),
55 state: Cloudflare.state(),
56 },
57 Effect.gen(function* () {
58 const host = yield* S3GitHost;
59 return { url: host.url.as<string>() };
60 }),
61 );