import { Effect, Schema } from "effect";
import type { StorageFailure } from "./fuma-runtime";
import { ConnectionId } from "./ids";
/** RFC 9728 + RFC 8414 + RFC 7591 + PKCE: discover protected-resource
 *  metadata, discover the authorization server, dynamically register a
 *  client, then PKCE-encode the authorization URL. Zero pre-configured
 *  credentials — the user just pastes a resource URL. */
export declare const OAuthDynamicDcrStrategy: Schema.Struct<{
    readonly kind: Schema.Literal<"dynamic-dcr">;
    /** Scopes to request. Defaults to whatever `scopes_supported`
     *  advertises; caller can narrow or extend. */
    readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
}>;
export type OAuthDynamicDcrStrategy = typeof OAuthDynamicDcrStrategy.Type;
/** RFC 6749 authorization code + PKCE with pre-configured endpoints +
 *  client_id. Used when the caller has out-of-band-registered an OAuth
 *  app (Google via Cloud Console, GitHub via developer portal, etc.) or
 *  when the auth-server URL is declared in an OpenAPI `securityScheme`. */
export declare const OAuthAuthorizationCodeStrategy: Schema.Struct<{
    readonly kind: Schema.Literal<"authorization-code">;
    readonly authorizationEndpoint: Schema.String;
    readonly tokenEndpoint: Schema.String;
    /** Expected authorization-server issuer for ID token validation. Some
     *  providers use a token endpoint host that differs from issuer, or a
     *  path-scoped issuer such as Okta custom authorization servers. */
    readonly issuerUrl: Schema.optional<Schema.NullOr<Schema.String>>;
    /** Secret id holding the `client_id`. Using a secret row rather than
     *  an inline string so the value lives at the scope where the caller
     *  configured it and shadowing behaves consistently. */
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    /** Secret id for `client_secret`. Null for public clients using
     *  PKCE without a confidential secret. */
    readonly clientSecretSecretId: Schema.NullOr<Schema.String>;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly scopes: Schema.$Array<Schema.String>;
    /** Separator between scopes. RFC 6749 says space; some providers
     *  (GitHub classic) use comma. */
    readonly scopeSeparator: Schema.optional<Schema.String>;
    /** Provider-specific params injected at authorization URL build time
     *  (Google's `access_type=offline`, `prompt=consent`, ...). */
    readonly extraAuthorizationParams: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
    /** `"body"` (default) sends client creds in the form body; `"basic"`
     *  uses HTTP Basic auth. Stripe-style servers require basic. */
    readonly clientAuth: Schema.optional<Schema.Literals<readonly ["body", "basic"]>>;
}>;
export type OAuthAuthorizationCodeStrategy = typeof OAuthAuthorizationCodeStrategy.Type;
/** RFC 6749 §4.4 client credentials — no user redirect, no PKCE. Used
 *  for server-to-server integrations where the plugin has both
 *  `client_id` and `client_secret` and the server will mint tokens
 *  directly on the token endpoint. */
export declare const OAuthClientCredentialsStrategy: Schema.Struct<{
    readonly kind: Schema.Literal<"client-credentials">;
    readonly tokenEndpoint: Schema.String;
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientSecretSecretId: Schema.String;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
    readonly scopeSeparator: Schema.optional<Schema.String>;
    readonly clientAuth: Schema.optional<Schema.Literals<readonly ["body", "basic"]>>;
}>;
export type OAuthClientCredentialsStrategy = typeof OAuthClientCredentialsStrategy.Type;
/** Tagged union of every start-time strategy shape. A new strategy (e.g.
 *  device-code) is added here; the service's start/complete routes on
 *  `kind`. */
export declare const OAuthStrategy: Schema.Union<readonly [Schema.Struct<{
    readonly kind: Schema.Literal<"dynamic-dcr">;
    /** Scopes to request. Defaults to whatever `scopes_supported`
     *  advertises; caller can narrow or extend. */
    readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
}>, Schema.Struct<{
    readonly kind: Schema.Literal<"authorization-code">;
    readonly authorizationEndpoint: Schema.String;
    readonly tokenEndpoint: Schema.String;
    /** Expected authorization-server issuer for ID token validation. Some
     *  providers use a token endpoint host that differs from issuer, or a
     *  path-scoped issuer such as Okta custom authorization servers. */
    readonly issuerUrl: Schema.optional<Schema.NullOr<Schema.String>>;
    /** Secret id holding the `client_id`. Using a secret row rather than
     *  an inline string so the value lives at the scope where the caller
     *  configured it and shadowing behaves consistently. */
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    /** Secret id for `client_secret`. Null for public clients using
     *  PKCE without a confidential secret. */
    readonly clientSecretSecretId: Schema.NullOr<Schema.String>;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly scopes: Schema.$Array<Schema.String>;
    /** Separator between scopes. RFC 6749 says space; some providers
     *  (GitHub classic) use comma. */
    readonly scopeSeparator: Schema.optional<Schema.String>;
    /** Provider-specific params injected at authorization URL build time
     *  (Google's `access_type=offline`, `prompt=consent`, ...). */
    readonly extraAuthorizationParams: Schema.optional<Schema.$Record<Schema.String, Schema.String>>;
    /** `"body"` (default) sends client creds in the form body; `"basic"`
     *  uses HTTP Basic auth. Stripe-style servers require basic. */
    readonly clientAuth: Schema.optional<Schema.Literals<readonly ["body", "basic"]>>;
}>, Schema.Struct<{
    readonly kind: Schema.Literal<"client-credentials">;
    readonly tokenEndpoint: Schema.String;
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientSecretSecretId: Schema.String;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
    readonly scopeSeparator: Schema.optional<Schema.String>;
    readonly clientAuth: Schema.optional<Schema.Literals<readonly ["body", "basic"]>>;
}>]>;
export type OAuthStrategy = typeof OAuthStrategy.Type;
/** Discriminator mirrors `OAuthStrategy["kind"]`. Refresh reads
 *  `tokenEndpoint` + `clientAuth` + client id/secret refs directly and
 *  never re-runs discovery. */
export declare const OAuthProviderState: Schema.Union<readonly [Schema.Struct<{
    readonly kind: Schema.Literal<"dynamic-dcr">;
    readonly tokenEndpoint: Schema.String;
    readonly issuerUrl: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly authorizationServerUrl: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly authorizationServerMetadataUrl: Schema.NullOr<Schema.String>;
    readonly idTokenSigningAlgValuesSupported: Schema.optional<Schema.$Array<Schema.String>>;
    /** DCR-minted client_id. Embedded inline (not a secret) — DCR
     *  clients are public-ish by design; the secret part (if the AS
     *  issued one) is a separate secret row. */
    readonly clientId: Schema.String;
    readonly clientSecretSecretId: Schema.NullOr<Schema.String>;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientAuth: Schema.Literals<readonly ["body", "basic"]>;
    readonly scopes: Schema.withDecodingDefaultType<Schema.$Array<Schema.String>>;
    readonly scopeSeparator: Schema.optional<Schema.String>;
    readonly scope: Schema.NullOr<Schema.String>;
    /** RFC 8707 canonical resource URL. Replayed on refresh so the new
     *  access token's audience stays bound to the same resource. */
    readonly resource: Schema.optional<Schema.NullOr<Schema.String>>;
}>, Schema.Struct<{
    readonly kind: Schema.Literal<"authorization-code">;
    readonly tokenEndpoint: Schema.String;
    readonly issuerUrl: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientSecretSecretId: Schema.NullOr<Schema.String>;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientAuth: Schema.Literals<readonly ["body", "basic"]>;
    readonly scopes: Schema.withDecodingDefaultType<Schema.$Array<Schema.String>>;
    readonly scopeSeparator: Schema.optional<Schema.String>;
    readonly scope: Schema.NullOr<Schema.String>;
    readonly resource: Schema.optional<Schema.NullOr<Schema.String>>;
}>, Schema.Struct<{
    readonly kind: Schema.Literal<"client-credentials">;
    readonly tokenEndpoint: Schema.String;
    readonly clientIdSecretId: Schema.String;
    readonly clientIdSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly clientSecretSecretId: Schema.String;
    readonly clientSecretSecretScopeId: Schema.optional<Schema.NullOr<Schema.String>>;
    readonly scopes: Schema.$Array<Schema.String>;
    readonly scopeSeparator: Schema.optional<Schema.String>;
    readonly clientAuth: Schema.Literals<readonly ["body", "basic"]>;
    readonly scope: Schema.NullOr<Schema.String>;
}>]>;
export type OAuthProviderState = typeof OAuthProviderState.Type;
/** The canonical refresh handler key. Every OAuth2-minted connection
 *  registers under this single value; the handler switches on
 *  `providerState.kind`. */
export declare const OAUTH2_PROVIDER_KEY: "oauth2";
export interface OAuthProbeInput {
    readonly endpoint: string;
    readonly headers?: Record<string, string>;
    readonly queryParams?: Record<string, string>;
}
export interface OAuthProbeResult {
    /** RFC 9728 resource metadata the server advertises, if any. */
    readonly resourceMetadata: Record<string, unknown> | null;
    readonly resourceMetadataUrl: string | null;
    /** RFC 8414 / OIDC metadata for the authorization server tied to the
     *  resource, if the server advertised one and we could fetch it. */
    readonly authorizationServerMetadata: Record<string, unknown> | null;
    readonly authorizationServerMetadataUrl: string | null;
    readonly authorizationServerUrl: string | null;
    /** True iff the AS advertises `registration_endpoint` and
     *  `token_endpoint_auth_methods_supported` includes `"none"` (public
     *  client + PKCE). A `false` value here doesn't mean OAuth is
     *  unavailable — just that the dynamic-DCR strategy can't run and the
     *  caller must fall back to `authorization-code` with user-supplied
     *  client credentials. */
    readonly supportsDynamicRegistration: boolean;
    /** True iff an unauth POST to the endpoint responded with `401` and
     *  an MCP-shaped `WWW-Authenticate: Bearer` challenge (RFC 6750).
     *  MCP-only signal; non-MCP OAuth-protected APIs usually encode auth
     *  failures inside their own protocol envelope and never surface
     *  this flag. */
    readonly isBearerChallengeEndpoint: boolean;
}
export interface OAuthStartInput {
    /** Resource URL the caller wants a token for. For `dynamic-dcr` this
     *  is the probe target; for `authorization-code` it's stored only so
     *  the UI can display "signed in to X." */
    readonly endpoint: string;
    readonly headers?: Record<string, string>;
    readonly queryParams?: Record<string, string>;
    /** Pre-decided `Connection.id`. Writing it before the flow starts
     *  lets callers stamp `{kind:"oauth2", connectionId}` onto a source
     *  row atomically with the start call. Convention:
     *  `${pluginId}-oauth2-${namespace}`. */
    readonly connectionId: string;
    /** Scope where the resulting `Connection` + its backing secrets
     *  land. Innermost scope for per-user sign-ins. */
    readonly tokenScope: string;
    /** Redirect URL the authorization server will bounce back to. For
     *  strategies that don't redirect (`client-credentials`) pass a
     *  placeholder; it's persisted but unused. */
    readonly redirectUrl: string;
    readonly strategy: OAuthStrategy;
    /** Which plugin is initiating the flow. Persisted on the session +
     *  stamped on the minted Connection's identity label for UI. */
    readonly pluginId: string;
    /** Optional human label for the minted Connection, e.g. "Spotify OAuth". */
    readonly identityLabel?: string;
}
export interface OAuthStartResult {
    readonly sessionId: string;
    /** Present for user-interactive strategies. `null` for
     *  `client-credentials`, which skips straight to a Connection write
     *  inside `start`. */
    readonly authorizationUrl: string | null;
    /** For strategies that don't redirect, the Connection has already
     *  been minted. Surfaced so callers can stamp the source row
     *  immediately without waiting on a completion callback. */
    readonly completedConnection: {
        readonly connectionId: string;
    } | null;
}
export interface OAuthCompleteInput {
    /** RFC 6749 `state` parameter — maps to a session row id. */
    readonly state: string;
    /** Optional scope check for route-scoped completions. Browser callback
     *  completions omit this because the callback URL has no scope path. */
    readonly tokenScope?: string;
    readonly code?: string;
    /** RFC 6749 `error` parameter — set when the AS redirected back with
     *  a failure. The service surfaces this as a tagged error. */
    readonly error?: string;
}
export interface OAuthCompleteResult {
    readonly connectionId: string;
    readonly expiresAt: number | null;
    readonly scope: string | null;
}
declare const OAuthProbeError_base: Schema.Class<OAuthProbeError, Schema.TaggedStruct<"OAuthProbeError", {
    readonly message: Schema.String;
}>, import("effect/Cause").YieldableError>;
export declare class OAuthProbeError extends OAuthProbeError_base {
}
declare const OAuthStartError_base: Schema.Class<OAuthStartError, Schema.TaggedStruct<"OAuthStartError", {
    readonly message: Schema.String;
    /** RFC 6749 §5.2 / RFC 7591 §3.2.2 error code propagated up from the
     *  authorization server (e.g. `invalid_client_metadata`). UI surfaces
     *  it as the structured "AS rejected the registration" reason. */
    readonly error: Schema.optional<Schema.String>;
    readonly errorDescription: Schema.optional<Schema.String>;
}>, import("effect/Cause").YieldableError>;
export declare class OAuthStartError extends OAuthStartError_base {
}
declare const OAuthCompleteError_base: Schema.Class<OAuthCompleteError, Schema.TaggedStruct<"OAuthCompleteError", {
    readonly message: Schema.String;
    /** RFC 6749 §5.2 error code, when the token endpoint returned one.
     *  Callers distinguish terminal failures (`invalid_grant` ⇒
     *  re-auth required) from transient ones. */
    readonly code: Schema.optional<Schema.String>;
}>, import("effect/Cause").YieldableError>;
export declare class OAuthCompleteError extends OAuthCompleteError_base {
}
declare const OAuthSessionNotFoundError_base: Schema.Class<OAuthSessionNotFoundError, Schema.TaggedStruct<"OAuthSessionNotFoundError", {
    readonly sessionId: Schema.String;
}>, import("effect/Cause").YieldableError>;
export declare class OAuthSessionNotFoundError extends OAuthSessionNotFoundError_base {
}
export interface OAuthService {
    readonly probe: (input: OAuthProbeInput) => Effect.Effect<OAuthProbeResult, OAuthProbeError>;
    readonly start: (input: OAuthStartInput) => Effect.Effect<OAuthStartResult, OAuthStartError | StorageFailure>;
    readonly complete: (input: OAuthCompleteInput) => Effect.Effect<OAuthCompleteResult, OAuthCompleteError | OAuthSessionNotFoundError | StorageFailure>;
    /** Drop an in-flight session without completing — used when the
     *  user cancels the popup or the source is deleted mid-onboarding. */
    readonly cancel: (sessionId: string, tokenScope: string) => Effect.Effect<void, StorageFailure>;
}
export declare const OAUTH2_SESSION_TTL_MS: number;
export { ConnectionId };
//# sourceMappingURL=oauth.d.ts.map