import { Credentials } from "@distilled.cloud/axiom/Credentials"; import { ConfigError } from "@distilled.cloud/core/errors"; import * as Config from "effect/Config"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Match from "effect/Match"; import { getAuthProvider } from "../Auth/AuthProvider.ts"; import { ALCHEMY_PROFILE, AlchemyProfile } from "../Auth/Profile.ts"; import { AXIOM_AUTH_PROVIDER_NAME, type AxiomAuthConfig, type AxiomResolvedCredentials, } from "./AuthProvider.ts"; export { Credentials, CredentialsFromEnv, DEFAULT_API_BASE_URL, } from "@distilled.cloud/axiom/Credentials"; /** * Build a `Credentials` layer that resolves Axiom credentials via the Alchemy * AuthProvider using the configured profile (defaults to "default", overridable * with the `ALCHEMY_PROFILE` env/config value). */ export const fromAuthProvider = () => Layer.effect( Credentials, Effect.gen(function* () { const profile = yield* AlchemyProfile; const auth = yield* getAuthProvider< AxiomAuthConfig, AxiomResolvedCredentials >(AXIOM_AUTH_PROVIDER_NAME); const profileName = yield* ALCHEMY_PROFILE; const ci = yield* Config.boolean("CI").pipe(Config.withDefault(false)); return yield* profile.loadOrConfigure(auth, profileName, { ci }).pipe( Effect.flatMap((config) => auth.read(profileName, config as AxiomAuthConfig), ), Effect.map((creds) => Match.value(creds).pipe( Match.when({ type: "apiToken" }, (c) => ({ apiKey: c.apiToken, apiBaseUrl: c.apiBaseUrl, orgId: c.orgId, })), Match.when({ type: "pat" }, (c) => ({ apiKey: c.apiToken, apiBaseUrl: c.apiBaseUrl, orgId: c.orgId, })), Match.exhaustive, ), ), Effect.mapError( (e) => new ConfigError({ message: `Failed to resolve Axiom credentials for profile '${profileName}': ${(e as { message?: string }).message ?? String(e)}`, }), ), Effect.orDie, Effect.cached, ); }), );