import { H as HttpClientOptions$1, a as HttpClient$1, T as TokenManager$1, S as Session$1 } from './index.d-CS4ceNwT.cjs'; import { S as SessionStorageAdapter } from './storage-Nj6JAWej.cjs'; import { F } from './pooled-flags-ByrxSmnn.js'; declare class PalbaseError extends Error { readonly code: string; readonly status: number; readonly details?: unknown; constructor(code: string, message: string, status: number, details?: unknown); } interface PalbaseResponse { data: T | null; error: PalbaseError | null; count?: number; status: number; /** * The response's `ETag`, when it carried one. * * Lifted out of the header bag for the same reason `count` is (it comes from * `Content-Range`): a caller doing conditional requests needs exactly this * one value, and the validator it must echo is the SERVER's — not something * the caller can reconstruct. Offering a validator of one's own invention is * how a conditional request quietly stops being conditional: measured on * centauri 2026-09-11, where the flags poll sent `If-None-Match: 0` against * an `etag: "15-e0e4f431743eb0c5"` and so could never once be answered 304. */ etag?: string; } interface HttpClientOptions { /** * Auth requests are sealed automatically. Self-hosted stacks can pin their * own base64 Ed25519 root. `false` is an explicit opt-out for test servers or * older self-hosted stacks; it cannot satisfy a server requiring sealing. */ sealed?: { root?: string; stackRef?: string; } | false; /** * The host application's own version, sent as `X-Palbase-Client-Version` and * readable in flag targeting as `client.app_version`. * * Opt-in because the SDK cannot discover it on the web — there is no bundle * to read a version out of. iOS fills the same header automatically from * CFBundleShortVersionString. */ appVersion?: string; url?: string; headers?: Record; } interface RequestOptions { headers?: Record; body?: unknown; signal?: AbortSignal; /** Disable network/429 replay for one-time exchanges. Protocol retries remain bounded. */ retry?: boolean; /** Credential/token exchanges must not refresh an unrelated or expired bearer first. */ skipSessionRefresh?: boolean; } interface Session { accessToken: string; refreshToken: string; expiresAt: number; } type AuthStateEvent = 'SESSION_SET' | 'SESSION_CLEARED'; type AuthStateCallback = (event: AuthStateEvent, session: Session | null) => void; type Unsubscribe$2 = () => void; declare class TokenManager { private session; private listeners; private refreshPromise; private refreshing; refreshFunction: ((refreshToken: string) => Promise) | null; setSession(session: Session): void; getAccessToken(): string | null; getRefreshToken(): string | null; clearSession(): void; isExpired(): boolean; refreshSession(): Promise; onAuthStateChange(callback: AuthStateCallback): Unsubscribe$2; private executeRefresh; private notify; } /** * Request interceptor. Runs before every HTTP request. * Can modify headers, body, or reject the request. */ type RequestInterceptor = (request: { headers: Record; method: string; path: string; }) => void | Promise; declare class HttpClient { protected readonly apiKey: string; protected readonly options?: HttpClientOptions; tokenManager: TokenManager | null; /** * Admin JWT used for platform admin endpoints (/admin/*). * When set, takes precedence over tokenManager access token in the * Authorization header. */ adminToken: string | null; private readonly interceptors; private readonly forbiddenListeners; private sealedKeys?; constructor(apiKey: string, options?: HttpClientOptions); /** Set (or clear) the admin JWT used on admin endpoints. */ setAdminToken(token: string | null): void; /** * Called with the RAW body of every 403 this client receives (FR-010). Core * does not know the envelope's fields — the layer that does (palbe) reads * `required` out of it. Nothing is retried or swallowed: the error still * returns to the caller. */ onForbidden(handler: (body: Record) => void): () => void; /** * Create a scoped HttpClient that adds the given extra headers to every * request. The returned client shares the admin token and token manager * with the parent at runtime — later changes on the parent propagate to * the scope and vice versa. * * Typical use: adding an Environment-routing header for an admin call. */ withHeaders(extra: Record): HttpClient; /** Add a request interceptor. Runs before every request. */ addInterceptor(interceptor: RequestInterceptor): void; request(method: string, path: string, options?: RequestOptions): Promise>; /** * A response read as it arrives, for `text/event-stream` routes. * * Deliberately NOT `executeWithRetry`: a retry replays the request, and a * stream the caller has already begun reading cannot be replayed — the frames * it handed over would arrive a second time. A stream that fails to open fails * to the caller, once, with its status. * * The buffered path's headers, base URL and interceptors are reused verbatim, * so a streaming call is authenticated exactly like every other call; only the * body handling differs. `Accept` says what the caller wants, and the status * is returned beside the body because the CALLER decides what a non-2xx means * (an error envelope arrives as an ordinary buffered body). */ requestStream(method: string, path: string, options?: RequestOptions): Promise<{ status: number; body: ReadableStream | null; contentType: string; }>; private prepareSealed; private getBaseUrl; private buildHeaders; private executeWithRetry; private delay; } interface User { id: string; email: string; emailVerified: boolean; createdAt: string; updatedAt: string; metadata?: Record; /** * The caller's APPLICATION roles, as assigned in `auth.user_roles`. * * Empty array for a caller who holds none, never undefined — a UI hint, not * the boundary: the server decides, and it decides again on every request. */ roles: string[]; } interface TokenResponse { access_token: string; refresh_token: string; token_type: string; expires_in: number; } interface AuthSession { id: string; ip?: string; user_agent?: string; acr: string; amr: string[]; last_activity: string; created_at: string; current: boolean; } interface SignUpCredentials { email: string; password: string; /** * The language the account's mail is written in (BCP 47, e.g. `"tr"`), as an * explicit choice: it is STORED on the user and wins over the device's * language from then on. Omitted, the stack uses the request's language for * each mail and then its default — nothing is stored. */ locale?: string; } interface SignInCredentials { email: string; password: string; } interface VerifyEmailParams { token?: string; code?: string; email?: string; } interface PasswordResetParams { email: string; } interface PasswordResetConfirmParams { token: string; new_password: string; } interface PasswordChangeParams { current_password: string; new_password: string; } /** * Body of POST /auth/password/set — a passwordless account's FIRST password. * * No current password on purpose: the accounts this serves (passkey-first, * social-only) do not have one, which is why `changePassword` answers them 401. */ interface PasswordSetParams { new_password: string; } interface MFAEnrollParams { type: 'totp' | 'email'; } interface MFAEnrollResult { enrollment_id?: string; secret?: string; otp_url?: string; qr_code?: string; recovery_codes?: string[]; status?: string; } interface MFAChallengeParams { mfa_token: string; type: 'totp' | 'email'; code: string; } interface MFARecoveryParams { mfa_token: string; code: string; } interface MFAFactor { id: string; type: string; verified: boolean; created_at: string; } interface MFAEmailChallengeParams { mfa_token: string; } interface MFAEmailVerifyParams { mfa_token: string; code: string; } interface Identity { id: string; provider: string; provider_user_id: string; created_at: string; } interface MagicLinkParams { email: string; } interface MagicLinkVerifyParams { token: string; fingerprint_hash?: string; } interface RegisterTrustedDeviceParams { fingerprint_hash: string; device_name?: string; } interface TrustedDevice { id: string; device_name?: string; created_at: string; last_used_at: string; expires_at: string; } interface DeviceInfo { id: string; platform: string; attestation_status: string; bound: boolean; created_at: string; } interface AttestAndroidParams { verdict_token: string; } interface AttestAndroidResult { device_id: string; attestation_status: string; device_integrity?: string; } interface AttestiOSParams { attestation_object: string; key_id: string; challenge: string; } interface AttestiOSResult { device_id: string; attestation_status: string; } interface BindDeviceParams { device_id: string; public_key: string; platform_attestation?: string; } interface VerifyRequestSignatureParams { payload: string; signature: string; } type AuthEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'; type AuthStateChangeCallback = (event: AuthEvent, session: Session | null) => void; /** * Device attestation client. * Handles device challenge/attestation/bind and App Check JWT cache. */ declare class DeviceClient { private readonly httpClient; private cachedToken; private refreshTimer; constructor(httpClient: HttpClient); /** Generate a device attestation challenge. */ generateChallenge(): Promise>; /** Attest an Android device with a Play Integrity verdict token. */ attestAndroid(params: AttestAndroidParams): Promise>; /** Attest an iOS device with App Attest attestation data. */ attestiOS(params: AttestiOSParams): Promise>; /** Bind a verified device with a public key for request signing. */ bind(params: BindDeviceParams): Promise>; /** List all devices for the current user. */ list(): Promise>; /** Delete a device by ID. */ delete(deviceId: string): Promise>; /** * Verify a request signature from a device (server-only). * Should NOT be exposed in client SDK. */ verifyRequestSignature(deviceId: string, params: VerifyRequestSignatureParams): Promise>; /** Get the cached App Check token, or null if not available / expired. */ getToken(): string | null; /** Whether App Check is active (token cached and not expired). */ get isActive(): boolean; /** Set a cached App Check token manually (e.g. after attest flow). */ setCachedToken(token: string, expiresInMs: number): void; /** Clean up timers and cached state. */ dispose(): void; private scheduleRefresh; } type OAuthProvider = 'google' | 'apple' | 'microsoft' | 'github'; type OAuthPurpose = 'sign_in' | 'link'; interface OAuthConfig { contract_revision: 1; config_revision: string; environment_ref: string; application_key: string; platform: 'web'; variant: string; clients: Array<{ key: string; provider: OAuthProvider; mode: 'browser'; return_uris: string[]; }>; } interface OAuthOptions { provider: OAuthProvider; redirectTo?: string; purpose?: OAuthPurpose; } interface OAuthTransaction { id: string; clientKey: string; provider: OAuthProvider; purpose: OAuthPurpose; expiresAt: string; authorizationURL: string; } type OAuthResult = { status: 'signedIn'; user: User; session: Session; isNewUser: boolean; } | { status: 'mfaRequired'; mfaToken: string; factors: string[]; } | { status: 'linked'; identity: Identity; userId: string; }; /** Per-transaction proof storage. A failed write must reject; never fall back to memory. */ interface OAuthTransactionStorage { load(key: string): string | null | Promise; save(key: string, value: string, expiresAt: string): void | Promise; remove(key: string): void | Promise; } interface AuthClientOptions { oauth?: OAuthConfig; oauthStorage?: OAuthTransactionStorage; /** Coordinate rotating credentials with the runtime's shared session store. */ coordinateRefresh?: (refreshToken: string, exchange: (refreshToken: string) => Promise) => Promise; } declare class AuthClient { private readonly httpClient; private readonly tokenManager; private readonly apiKey; private readonly baseUrl; private currentSession; private hasSession; private _mfa; private readonly oauthFlow; private readonly coordinateRefresh; /** Device attestation */ readonly device: DeviceClient; constructor(httpClient: HttpClient, tokenManager: TokenManager, apiKey?: string, baseUrl?: string, options?: AuthClientOptions); signUp(credentials: SignUpCredentials, options?: { headers?: Record; }): Promise>; signIn(credentials: SignInCredentials): Promise>; signOut(): Promise>; verifyEmail(params: VerifyEmailParams): Promise>; resendVerification(email: string): Promise>; requestPasswordReset(params: PasswordResetParams): Promise>; confirmPasswordReset(params: PasswordResetConfirmParams): Promise>; changePassword(params: PasswordChangeParams): Promise>; /** * Give a PASSWORDLESS account its first password. * * Separate from `changePassword` because that one cannot serve the case: it * sends a current password and palauth answers an account that has none with * 401. Requires a RECENT sign-in (403 `reauthentication_required` otherwise, * the same gate passkey enrollment carries); an account that already has a * password gets 409 `password_already_set`. */ setPassword(params: PasswordSetParams): Promise>; refresh(): Promise>; getAccessToken(): string | null; onTokenChange(callback: (tokens: { accessToken: string | null; refreshToken: string | null; }) => void): () => void; setTokens(accessToken: string, refreshToken: string, expiresIn?: number): void; listSessions(): Promise>; revokeSession(sessionId: string): Promise>; revokeAllSessions(): Promise>; get mfa(): { enroll: (params: MFAEnrollParams) => Promise>; verifyEnrollment: (code: string) => Promise>; challenge: (params: MFAChallengeParams) => Promise>; recovery: (params: MFARecoveryParams) => Promise>; listFactors: () => Promise>; removeFactor: (factorId: string, currentPassword: string) => Promise>; regenerateRecoveryCodes: () => Promise>; emailEnroll: () => Promise>; emailChallenge: (params: MFAEmailChallengeParams) => Promise>; emailVerify: (params: MFAEmailVerifyParams) => Promise>; }; private buildMfa; getOAuthURL(options: OAuthOptions): Promise>; beginOAuth(options: OAuthOptions): Promise>; completeOAuth(params: { transactionId: string; resultCode?: string; callbackURL?: string; }): Promise>; cancelOAuth(transactionId: string): Promise>; listIdentities(): Promise>; linkIdentity(options: Omit): Promise>; unlinkIdentity(identityId: string): Promise>; requestMagicLink(params: MagicLinkParams): Promise>; verifyMagicLink(params: MagicLinkVerifyParams): Promise>; listTrustedDevices(): Promise>; registerTrustedDevice(params: RegisterTrustedDeviceParams): Promise>; revokeTrustedDevice(deviceId: string): Promise>; getSession(): { data: Session | null; error: null; }; onAuthStateChange(callback: AuthStateChangeCallback): { data: { subscription: { unsubscribe: () => void; }; }; }; /** * Verify a user's JWT token by calling GET /auth/user with their token. * Server-only — should NOT be exposed in client SDK. */ verifyUserToken(jwt: string): Promise>; private setSessionAndWireRefresh; private refreshToken; private requestRefresh; } type CallState = 'connecting' | 'active' | 'ended'; interface CallParticipant { identity: string; isSpeaking: boolean; audioMuted: boolean; videoEnabled: boolean; /** The live