1import * as Config from "effect/Config";
2import * as Effect from "effect/Effect";
3import * as Option from "effect/Option";
4import * as Schema from "effect/Schema";
5import { ProfileStore } from "../Auth/Profile.ts";
6import {
7 CLOUDFLARE_AUTH_PROVIDER_NAME,
8 CloudflareAuthConfigSchema,
9} from "./Auth/AuthConfig.ts";
10
11/** Fallback identity when local dev has no configured Cloudflare account. */
12export const LOCAL_ACCOUNT_ID = "00000000000000000000000000000000";
13
14// Read identity only: expired OAuth credentials must not prevent local dev,
15// and discovering an account must never authenticate or refresh a token.
16export const localAccountId = Effect.gen(function* () {
17 const accountId = (yield* Config.String("CLOUDFLARE_ACCOUNT_ID").pipe(
18 Config.withDefault(""),
19 )).trim();
20 if (accountId.length > 0) {
21 return accountId;
22 }
23
24 const isCI = yield* Config.Boolean("CI").pipe(Config.withDefault(false));
25 if (isCI) {
26 return LOCAL_ACCOUNT_ID;
27 }
28
29 const profiles = Option.getOrUndefined(
30 yield* Effect.serviceOption(ProfileStore),
31 );
32 if (profiles === undefined) {
33 return LOCAL_ACCOUNT_ID;
34 }
35
36 const currentProfile = yield* profiles.current;
37 const profile = yield* profiles.getProfile(currentProfile.name);
38 const cloudflareConfig = profile?.providers[CLOUDFLARE_AUTH_PROVIDER_NAME];
39 if (cloudflareConfig === undefined) {
40 return LOCAL_ACCOUNT_ID;
41 }
42
43 const config = yield* Schema.decodeUnknownEffect(CloudflareAuthConfigSchema)(
44 cloudflareConfig,
45 );
46 if ("accountId" in config) {
47 return config.accountId;
48 }
49
50 return LOCAL_ACCOUNT_ID;
51}).pipe(Effect.orDie);