import type { CheckAuthorizationFromSessionClaims, Jwt, JwtPayload, PendingSessionOptions, ServerGetToken, SessionStatusClaim, SharedSignedInAuthObjectProperties } from '@clerk/types';
import type { CreateBackendApiOptions } from '../api';
import type { AuthenticateContext } from './authenticateContext';
import type { MachineTokenType, SessionTokenType } from './tokenTypes';
import type { AuthenticateRequestOptions, MachineAuthType } from './types';
/**
 * @inline
 */
type AuthObjectDebugData = Record<string, any>;
/**
 * @inline
 */
type AuthObjectDebug = () => AuthObjectDebugData;
type Claims = Record<string, any>;
/**
 * @internal
 */
export type SignedInAuthObjectOptions = CreateBackendApiOptions & {
    token: string;
};
/**
 * @internal
 */
export type SignedInAuthObject = SharedSignedInAuthObjectProperties & {
    /**
     * The allowed token type.
     */
    tokenType: SessionTokenType;
    /**
     * A function that gets the current user's [session token](https://clerk.com/docs/guides/sessions/session-tokens) or a [custom JWT template](https://clerk.com/docs/guides/sessions/jwt-templates).
     */
    getToken: ServerGetToken;
    /**
     * A function that checks if the user has an Organization Role or Custom Permission.
     */
    has: CheckAuthorizationFromSessionClaims;
    /**
     * Used to help debug issues when using Clerk in development.
     */
    debug: AuthObjectDebug;
    isAuthenticated: true;
};
/**
 * @internal
 */
export type SignedOutAuthObject = {
    sessionClaims: null;
    sessionId: null;
    sessionStatus: SessionStatusClaim | null;
    actor: null;
    tokenType: SessionTokenType;
    userId: null;
    orgId: null;
    orgRole: null;
    orgSlug: null;
    orgPermissions: null;
    factorVerificationAge: null;
    getToken: ServerGetToken;
    has: CheckAuthorizationFromSessionClaims;
    debug: AuthObjectDebug;
    isAuthenticated: false;
};
/**
 * Extended properties specific to each machine token type.
 * While all machine token types share common properties (id, name, subject, etc),
 * this type defines the additional properties that are unique to each token type.
 *
 * @template TAuthenticated - Whether the machine object is authenticated or not
 */
type MachineObjectExtendedProperties<TAuthenticated extends boolean> = {
    api_key: TAuthenticated extends true ? {
        name: string;
        claims: Claims | null;
        userId: string;
        orgId: null;
    } | {
        name: string;
        claims: Claims | null;
        userId: null;
        orgId: string;
    } : {
        name: null;
        claims: null;
        userId: null;
        orgId: null;
    };
    m2m_token: {
        claims: TAuthenticated extends true ? Claims | null : null;
        machineId: TAuthenticated extends true ? string : null;
    };
    oauth_token: {
        userId: TAuthenticated extends true ? string : null;
        clientId: TAuthenticated extends true ? string : null;
    };
};
/**
 * @internal
 *
 * Uses `T extends any` to create a distributive conditional type.
 * This ensures that union types like `'api_key' | 'oauth_token'` are processed
 * individually, creating proper discriminated unions where each token type
 * gets its own distinct properties (e.g., oauth_token won't have claims).
 */
export type AuthenticatedMachineObject<T extends MachineTokenType = MachineTokenType> = T extends any ? {
    id: string;
    subject: string;
    scopes: string[];
    getToken: () => Promise<string>;
    has: CheckAuthorizationFromSessionClaims;
    debug: AuthObjectDebug;
    tokenType: T;
    isAuthenticated: true;
} & MachineObjectExtendedProperties<true>[T] : never;
/**
 * @internal
 *
 * Uses `T extends any` to create a distributive conditional type.
 * This ensures that union types like `'api_key' | 'oauth_token'` are processed
 * individually, creating proper discriminated unions where each token type
 * gets its own distinct properties (e.g., oauth_token won't have claims).
 */
export type UnauthenticatedMachineObject<T extends MachineTokenType = MachineTokenType> = T extends any ? {
    id: null;
    subject: null;
    scopes: null;
    getToken: () => Promise<null>;
    has: CheckAuthorizationFromSessionClaims;
    debug: AuthObjectDebug;
    tokenType: T;
    isAuthenticated: false;
} & MachineObjectExtendedProperties<false>[T] : never;
export type InvalidTokenAuthObject = {
    isAuthenticated: false;
    tokenType: null;
    getToken: () => Promise<null>;
    has: () => false;
    debug: AuthObjectDebug;
};
/**
 * @interface
 */
export type AuthObject = SignedInAuthObject | SignedOutAuthObject | AuthenticatedMachineObject | UnauthenticatedMachineObject | InvalidTokenAuthObject;
/**
 * @internal
 */
export declare function signedInAuthObject(authenticateContext: Partial<AuthenticateContext>, sessionToken: string, sessionClaims: JwtPayload): SignedInAuthObject;
/**
 * @internal
 */
export declare function signedOutAuthObject(debugData?: AuthObjectDebugData, initialSessionStatus?: SessionStatusClaim): SignedOutAuthObject;
/**
 * @internal
 */
export declare function authenticatedMachineObject<T extends MachineTokenType>(tokenType: T, token: string, verificationResult: MachineAuthType, debugData?: AuthObjectDebugData): AuthenticatedMachineObject<T>;
/**
 * @internal
 */
export declare function unauthenticatedMachineObject<T extends MachineTokenType>(tokenType: T, debugData?: AuthObjectDebugData): UnauthenticatedMachineObject<T>;
/**
 * @internal
 */
export declare function invalidTokenAuthObject(): InvalidTokenAuthObject;
/**
 * Auth objects moving through the server -> client boundary need to be serializable
 * as we need to ensure that they can be transferred via the network as pure strings.
 * Some frameworks like Remix or Next (/pages dir only) handle this serialization by simply
 * ignoring any non-serializable keys, however Nextjs /app directory is stricter and
 * throws an error if a non-serializable value is found.
 *
 * @internal
 */
export declare const makeAuthObjectSerializable: <T extends Record<string, unknown>>(obj: T) => T;
/**
 * @internal
 */
export declare const getAuthObjectFromJwt: (jwt: Jwt, { treatPendingAsSignedOut, ...options }: PendingSessionOptions & Partial<AuthenticateContext>) => SignedInAuthObject | SignedOutAuthObject;
/**
 * @internal
 * Returns an auth object matching the requested token type(s).
 *
 * If the parsed token type does not match any in acceptsToken, returns:
 *   - an invalid token auth object if the token is not in the accepted array
 *   - an unauthenticated machine object for machine tokens, or
 *   - a signed-out session object otherwise.
 *
 * This ensures the returned object always matches the developer's intent.
 */
export declare const getAuthObjectForAcceptedToken: ({ authObject, acceptsToken, }: {
    authObject: AuthObject;
    acceptsToken: AuthenticateRequestOptions["acceptsToken"];
}) => AuthObject;
export {};
//# sourceMappingURL=authObjects.d.ts.map