1/**
2 * Process bootstrap for `GCP.Run.Service`. The generated entry imports
3 * this module and the user's `main`, nothing else — see
4 * {@link ./Process.ts} for why.
5 *
6 * Runtime credentials come from the Cloud Run metadata server (the
7 * service's runtime service account), so HTTP bindings call GCP with
8 * exactly the IAM the deploy granted — never the deploy-time token.
9 */
10import { BunServices } from "@effect/platform-bun";
11import * as ConfigProvider from "effect/ConfigProvider";
12import * as Effect from "effect/Effect";
13import * as Layer from "effect/Layer";
14import * as FetchHttpClient from "effect/http/FetchHttpClient";
15import * as Logger from "effect/Logger";
16import { fromMetadataServer } from "../../GCP/MetadataCredentials.ts";
17import { BunHttpServer } from "../../Http.ts";
18import { reifyBoundConfigProvider } from "../../Runtime.ts";
19import {
20 entrypointLayer,
21 resolveProgram,
22 runProcess,
23 stackFromEnv,
24} from "./Process.ts";
25
26/** Serve the bundled program with a Bun HTTP server on the injected `PORT`. */
27export const bootstrap = (entrypoint: unknown): Promise<void> => {
28 const platform = Layer.mergeAll(
29 BunServices.layer,
30 FetchHttpClient.layer,
31 Logger.layer([Logger.consolePretty()]),
32 );
33
34 const program = resolveProgram("program", { telemetry: true }).pipe(
35 Effect.provide(
36 entrypointLayer(entrypoint).pipe(
37 Layer.provideMerge(stackFromEnv),
38 Layer.provideMerge(fromMetadataServer()),
39 Layer.provideMerge(BunHttpServer({ hostname: "0.0.0.0" })),
40 Layer.provideMerge(platform),
41 Layer.provideMerge(
42 Layer.succeed(
43 ConfigProvider.ConfigProvider,
44 reifyBoundConfigProvider(ConfigProvider.fromEnv(), process.env),
45 ),
46 ),
47 ),
48 ),
49 Effect.scoped,
50 );
51
52 return runProcess("Cloud Run service", program);
53};