1import { ConfigError } from "@distilled.cloud/core/errors";
2import { Credentials } from "@distilled.cloud/stripe";
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import {
6 deferUntilFirstUse,
7 orDieCredentialsUnavailable,
8 resolveProviderConfig,
9} from "../Auth/Resolve.ts";
10import {
11 STRIPE_AUTH_PROVIDER_NAME,
12 type StripeAuthConfig,
13 type StripeResolvedCredentials,
14} from "./AuthProvider.ts";
15
16export {
17 Credentials,
18 CredentialsFromEnv,
19 credentials,
20 DEFAULT_API_BASE_URL,
21 type Config as CredentialsConfig,
22} from "@distilled.cloud/stripe";
23
24/**
25 * Build a Stripe `Credentials` layer that resolves credentials via the
26 * Alchemy AuthProvider using the configured profile (defaults to "default",
27 * overridable with the `ALCHEMY_PROFILE` env/config value).
28 *
29 * Maps onto `@distilled.cloud/stripe`'s `{ apiKey, apiBaseUrl }` shape.
30 * Distilled's `Credentials` service is an `Effect<Config>` resolved per
31 * request. Environment credentials (`STRIPE_API_KEY`) take precedence;
32 * otherwise the selected profile is used.
33 */
34export const fromAuthProvider = () =>
35 Layer.effect(
36 Credentials,
37 Effect.gen(function* () {
38 // Defer profile lookup and credential resolution until first use, so
39 // building the provider layers never requires a configured profile.
40 const resolve = yield* resolveProviderConfig<
41 StripeAuthConfig,
42 StripeResolvedCredentials
43 >(STRIPE_AUTH_PROVIDER_NAME).pipe(
44 Effect.flatMap(({ profileName, resolve }) =>
45 resolve.pipe(
46 Effect.map((creds) => ({
47 apiKey: creds.apiKey,
48 apiBaseUrl: creds.apiBaseUrl,
49 })),
50 Effect.mapError(
51 (e) =>
52 new ConfigError({
53 message: `Failed to resolve Stripe credentials from ${profileName === undefined ? "the CI environment" : `profile '${profileName}'`}: ${(e as { message?: string }).message ?? String(e)}`,
54 }),
55 ),
56 ),
57 ),
58 deferUntilFirstUse,
59 );
60 return yield* resolve.pipe(
61 orDieCredentialsUnavailable(STRIPE_AUTH_PROVIDER_NAME),
62 Effect.cached,
63 );
64 }),
65 );