import { Effect, Layer } from "effect";
import { type HttpClient } from "effect/unstable/http";
import type { Connection } from "./connection";
import type { IFumaClient, StorageFailure } from "./fuma-runtime";
import { AuthTemplateSlug, ConnectionName, IntegrationSlug, OAuthClientSlug, Owner } from "./ids";
import { type OAuthService } from "./oauth-client";
import type { OwnerBinding } from "./plugin";
import type { CredentialProvider } from "./provider";
import { type OAuthEndpointUrlPolicy } from "./oauth-helpers";
/** Connection-minting input for the OAuth flow — extends a connection create
 *  with the OAuth lifecycle fields (client slug, refresh material, expiry,
 *  granted scope). The executor's `mintOAuthConnection` writes these onto the
 *  `connection` row and produces the connection's tools. */
export interface MintOAuthConnectionInput {
    readonly owner: Owner;
    readonly name: ConnectionName;
    readonly integration: IntegrationSlug;
    readonly template: AuthTemplateSlug;
    readonly identityLabel?: string | null;
    /** Credential provider key + item id the access token is stored under. */
    readonly provider: string;
    readonly itemId: string;
    readonly oauthClient: OAuthClientSlug;
    /** The owner of `oauthClient` (persisted so refresh loads it by explicit owner). */
    readonly oauthClientOwner: Owner;
    readonly refreshItemId: string | null;
    readonly expiresAt: number | null;
    readonly oauthScope: string | null;
}
/** Everything the OAuth service needs from the executor: fuma access for the
 *  owned `oauth_client` / `oauth_session` tables, the default credential
 *  provider for minted tokens, a `mintOAuthConnection` callback (writes the
 *  connection row + produces tools), the owner binding, and the redirect base. */
export interface OAuthServiceDeps {
    readonly fuma: IFumaClient;
    readonly owner: OwnerBinding;
    readonly tenant: string;
    readonly subject: string | null;
    readonly ownedKeys: (owner: Owner) => {
        readonly tenant: string;
        readonly owner: Owner;
        readonly subject: string;
    };
    readonly defaultWritableProvider: () => CredentialProvider | null;
    /** Write the connection row with OAuth lifecycle fields + produce its tools. */
    readonly mintOAuthConnection: (input: MintOAuthConnectionInput) => Effect.Effect<Connection, StorageFailure>;
    /**
     * Resolve the integration's DECLARED OAuth scopes for a given
     * `(integration, template)` — the scopes the integration's auth template
     * advertises (e.g. an OpenAPI bundle's full authentication-template scope
     * union), NOT the scopes frozen on a specific `oauth_client` row.
     *
     * At connect (`start`) the requested scope set is the UNION of these declared
     * scopes and the client's configured scopes, so reusing a narrow client on a
     * broad integration still requests the integration's full scope set. When the
     * integration declares no OAuth scopes (MCP / DCR integrations discover scopes
     * from the server; integrations with no declared template scopes) this returns
     * `[]` and the union collapses to the client's scopes — current behavior,
     * unchanged.
     */
    readonly resolveDeclaredOAuthScopes: (integration: IntegrationSlug, template: AuthTemplateSlug) => Effect.Effect<readonly string[], StorageFailure>;
    readonly httpClientLayer?: Layer.Layer<HttpClient.HttpClient>;
    readonly endpointUrlPolicy?: OAuthEndpointUrlPolicy;
    /**
     * The OAuth callback URL (`${webBaseUrl}${mountPrefix}/oauth/callback`) the host
     * serves and sends to providers on every authorization request + DCR registration.
     * The path carries the host's API mount prefix (cloud: `/api`; root-mounted
     * hosts like local: none), so it matches the route that serves the callback.
     *
     * REQUIRED and EXPLICIT — there is no localhost default. Pass `null` only when
     * the host genuinely has no redirect callback (e.g. a pure client-credentials
     * or non-HTTP context); the redirect-requiring flows (`start` for
     * `authorization_code`, `registerDynamicClient`) then fail loudly instead of
     * silently handing the provider a wrong `http://127.0.0.1/callback`. Hosts
     * that serve OAuth MUST derive this from the request origin / web base URL.
     */
    readonly redirectUri: string | null;
}
export declare const makeOAuthService: (deps: OAuthServiceDeps) => OAuthService;
//# sourceMappingURL=oauth-service.d.ts.map