import type { SuaveplanErrorOptions } from "@suaveplan/error"; import { defineCodes, SuaveplanError } from "@suaveplan/error"; /** * Frozen registry of typed error codes raised by `@suaveplan/webauthn`. * * Every code corresponds to a distinct W3C WebAuthn L3 / CTAP 2.1 failure * class. The literal union is pinned via `expectTypeOf` in tests so * accidental additions/removals fail typecheck. Every code is thrown by * at least one production path (or returned as the `code` field of a * discriminated-union `VerifyResult`). */ export const WEBAUTHN_CODES = defineCodes("WEBAUTHN", [ "NOT_SUPPORTED", "USER_CANCELLED", "INVALID_STATE", "SECURITY_ERROR", "NOT_ALLOWED", "MALFORMED_RESPONSE", "CHALLENGE_MISMATCH", "ORIGIN_MISMATCH", "RPID_HASH_MISMATCH", "SIGN_COUNTER_REGRESSION", "SIGNATURE_INVALID", "ATTESTATION_FORMAT_UNSUPPORTED", "UV_NOT_PERFORMED", "UP_NOT_PERFORMED", "ABORTED", "TIMEOUT", "INVALID_OPTIONS", ] as const); export type WebAuthnErrorCode = (typeof WEBAUTHN_CODES)[keyof typeof WEBAUTHN_CODES]; const DEFAULT_OPTIONS: SuaveplanErrorOptions = {}; /** * Concrete error subclass. All thrown errors in this package are * instances of `WebAuthnError`; switching on `error.code` narrows to * `WebAuthnErrorCode`. */ export class WebAuthnError extends SuaveplanError { public constructor( code: WebAuthnErrorCode, messageKey: string, options: SuaveplanErrorOptions = DEFAULT_OPTIONS ) { super(code, messageKey, options); } }