1import * as Config from "effect/Config";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Option from "effect/Option";
5import {
6 deferUntilFirstUse,
7 orDieCredentialsUnavailable,
8 resolveProviderConfig,
9} from "../Auth/Resolve.ts";
10import {
11 CLOUDFLARE_AUTH_PROVIDER_NAME,
12 type CloudflareAuthConfig,
13 type CloudflareResolvedCredentials,
14} from "./Auth/AuthConfig.ts";
15
16import { CloudflareEnvironment } from "./CloudflareEnvironmentService.ts";
17
18export { CloudflareEnvironment } from "./CloudflareEnvironmentService.ts";
19
20const CLOUDFLARE_ACCOUNT_ID = Config.String("CLOUDFLARE_ACCOUNT_ID");
21
22export const fromEnv = () =>
23 Layer.effect(
24 CloudflareEnvironment,
25 Effect.gen(function* () {
26 const accountId = yield* CLOUDFLARE_ACCOUNT_ID.pipe(
27 Config.option,
28 Config.map(Option.getOrUndefined),
29 );
30 return { account: accountId } as any;
31 }),
32 );
33
34export const fromProfile = () =>
35 Layer.effect(
36 CloudflareEnvironment,
37 Effect.gen(function* () {
38 // Building providers must work before Cloudflare is configured. Capture
39 // the resolver's services now, but read profiles/credentials only when
40 // a cloud operation actually evaluates this environment.
41 const resolve = yield* resolveProviderConfig<
42 CloudflareAuthConfig,
43 CloudflareResolvedCredentials
44 >(CLOUDFLARE_AUTH_PROVIDER_NAME).pipe(
45 Effect.flatMap(({ resolve }) => resolve),
46 deferUntilFirstUse,
47 );
48 return yield* resolve.pipe(
49 orDieCredentialsUnavailable(CLOUDFLARE_AUTH_PROVIDER_NAME),
50 Effect.cached,
51 );
52 }),
53 );