| 1 | /** |
| 2 | * The git-service example: a git host embedded in the app's own API, plus |
| 3 | * a GitHub-style web UI, on one origin. |
| 4 | * |
| 5 | * - `src/api/` — the backend, one file per piece: `auth.ts` (Better Auth |
| 6 | * and who a user is), `middleware.ts` (who may call what), `routes.ts` |
| 7 | * (the app's own routes), `api.ts` (the git routes plus ours behind the |
| 8 | * middleware), `git.ts` (the `alchemy/Git` block assembly), and |
| 9 | * `host.ts` (the `Cloudflare.Worker` that serves it). |
| 10 | * - `src/ui/` — the Vite SPA, a plain-fetch client of the API. |
| 11 | * - `src/worker.ts` — the website's Worker: forwards `/api/**` and the git |
| 12 | * wire paths to the GitHost over a service binding and serves the SPA for |
| 13 | * everything else, so clone URLs and the session cookie are same-host. |
| 14 | * |
| 15 | * ```sh |
| 16 | * bun run deploy |
| 17 | * ``` |
| 18 | * |
| 19 | * Open the printed `webUrl`, sign up, mint an API key on the settings page, |
| 20 | * and it is the password of your git remote: |
| 21 | * |
| 22 | * ```sh |
| 23 | * git remote add origin "https://x:<key>@<host>/<you>/web.git" |
| 24 | * git push origin main |
| 25 | * ``` |
| 26 | */ |
| 27 | import * as Alchemy from "alchemy"; |
| 28 | import * as Cloudflare from "alchemy/Cloudflare"; |
| 29 | import * as Effect from "effect/Effect"; |
| 30 | import GitHost from "./src/api/host.ts"; |
| 31 | |
| 32 | export default Alchemy.Stack( |
| 33 | "GitServiceExample", |
| 34 | { providers: Cloudflare.providers(), state: Alchemy.localState() }, |
| 35 | Effect.gen(function* () { |
| 36 | const git = yield* GitHost; |
| 37 | |
| 38 | const web = yield* Cloudflare.Website.Vite("Web", { |
| 39 | main: "src/worker.ts", |
| 40 | assets: { |
| 41 | notFoundHandling: "single-page-application", |
| 42 | runWorkerFirst: true, |
| 43 | }, |
| 44 | env: { |
| 45 | GIT: GitHost, |
| 46 | }, |
| 47 | }); |
| 48 | |
| 49 | return { url: git.url.as<string>(), webUrl: web.url }; |
| 50 | }), |
| 51 | ); |