{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/utils.ts","../src/crypto-context.ts","../src/base32-context.ts","../src/utility-types.ts"],"sourcesContent":["export type {\n  Base32EncodeOptions,\n  Base32Plugin,\n  CryptoPlugin,\n  Digits,\n  HashAlgorithm,\n  SecretOptions,\n  OTPResult,\n  OTPResultOk,\n  OTPResultError,\n} from \"./types.js\";\n\nexport type { OTPGuardrailsConfig, OTPGuardrails } from \"./utils.js\";\n\nexport {\n  OTPError,\n  SecretError,\n  SecretTooShortError,\n  SecretTooLongError,\n  CounterError,\n  CounterNegativeError,\n  CounterOverflowError,\n  TimeError,\n  TimeNegativeError,\n  PeriodError,\n  PeriodTooSmallError,\n  PeriodTooLargeError,\n  DigitsError,\n  AlgorithmError,\n  TokenError,\n  TokenLengthError,\n  TokenFormatError,\n  CryptoError,\n  HMACError,\n  RandomBytesError,\n  Base32Error,\n  Base32EncodeError,\n  Base32DecodeError,\n  CounterToleranceError,\n  CounterToleranceTooLargeError,\n  EpochToleranceError,\n  EpochToleranceNegativeError,\n  EpochToleranceTooLargeError,\n  PluginError,\n  CryptoPluginMissingError,\n  Base32PluginMissingError,\n  ConfigurationError,\n  SecretMissingError,\n  LabelMissingError,\n  IssuerMissingError,\n  SecretTypeError,\n  type OTPErrorOptions,\n} from \"./errors.js\";\n\nexport {\n  createGuardrails,\n  hasGuardrailOverrides,\n  validateSecret,\n  validateCounter,\n  validateTime,\n  validatePeriod,\n  validateToken,\n  validateCounterTolerance,\n  validateEpochTolerance,\n  counterToBytes,\n  dynamicTruncate,\n  truncateDigits,\n  validateByteLengthEqual,\n  constantTimeEqual,\n  getDigestSize,\n  stringToBytes,\n  hexToBytes,\n  normalizeSecret,\n  normalizeCounterTolerance,\n  normalizeEpochTolerance,\n  generateSecret,\n  requireCryptoPlugin,\n  requireBase32Plugin,\n  requireSecret,\n  requireLabel,\n  requireIssuer,\n  requireBase32String,\n  wrapResult,\n  wrapResultAsync,\n  MIN_SECRET_BYTES,\n  MAX_SECRET_BYTES,\n  RECOMMENDED_SECRET_BYTES,\n  MIN_PERIOD,\n  MAX_PERIOD,\n  DEFAULT_PERIOD,\n  MAX_COUNTER,\n  MAX_WINDOW,\n} from \"./utils.js\";\n\nexport { CryptoContext, createCryptoContext } from \"./crypto-context.js\";\n\nexport { Base32Context, createBase32Context } from \"./base32-context.js\";\n\n// Utility types for enhanced developer experience\nexport type {\n  Brand,\n  Base32Secret,\n  OTPToken,\n  RequireKeys,\n  OptionalKeys,\n  PluginConfig,\n  WithRequiredPlugins,\n  GenerationReady,\n  NarrowBy,\n} from \"./utility-types.js\";\n\nexport { hasPlugins, hasCrypto, hasBase32 } from \"./utility-types.js\";\n","/**\n * Options for OTPError construction\n */\nexport type OTPErrorOptions = {\n  /**\n   * The underlying error that caused this error.\n   * Useful for error chaining and debugging.\n   */\n  cause?: unknown;\n};\n\n/**\n * Base error class for all otplib errors\n *\n * Supports ES2022 error chaining via the `cause` property.\n *\n * @example\n * ```typescript\n * try {\n *   // ... operation that throws\n * } catch (error) {\n *   throw new OTPError('Operation failed', { cause: error });\n * }\n * ```\n */\nexport class OTPError extends Error {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(message, options);\n    this.name = \"OTPError\";\n  }\n}\n\n/**\n * Error thrown when secret validation fails\n */\nexport class SecretError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"SecretError\";\n  }\n}\n\n/**\n * Error thrown when secret is too short (< 128 bits)\n */\nexport class SecretTooShortError extends SecretError {\n  constructor(minBytes: number, actualBytes: number) {\n    super(\n      `Secret must be at least ${minBytes} bytes (${minBytes * 8} bits), got ${actualBytes} bytes`,\n    );\n    this.name = \"SecretTooShortError\";\n  }\n}\n\n/**\n * Error thrown when secret is unreasonably large (> 64 bytes)\n */\nexport class SecretTooLongError extends SecretError {\n  constructor(maxBytes: number, actualBytes: number) {\n    super(`Secret must not exceed ${maxBytes} bytes, got ${actualBytes} bytes`);\n    this.name = \"SecretTooLongError\";\n  }\n}\n\n/**\n * Error thrown when counter is invalid\n */\nexport class CounterError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"CounterError\";\n  }\n}\n\n/**\n * Error thrown when counter is negative\n */\nexport class CounterNegativeError extends CounterError {\n  constructor() {\n    super(\"Counter must be non-negative\");\n    this.name = \"CounterNegativeError\";\n  }\n}\n\n/**\n * Error thrown when counter exceeds maximum value (2^53 - 1 for safe integer)\n */\nexport class CounterOverflowError extends CounterError {\n  constructor() {\n    super(\"Counter exceeds maximum safe integer value\");\n    this.name = \"CounterOverflowError\";\n  }\n}\n\n/**\n * Error thrown when time is invalid\n */\nexport class TimeError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"TimeError\";\n  }\n}\n\n/**\n * Error thrown when time is negative\n */\nexport class TimeNegativeError extends TimeError {\n  constructor() {\n    super(\"Time must be non-negative\");\n    this.name = \"TimeNegativeError\";\n  }\n}\n\n/**\n * Error thrown when period is invalid\n */\nexport class PeriodError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"PeriodError\";\n  }\n}\n\n/**\n * Error thrown when period is too small\n */\nexport class PeriodTooSmallError extends PeriodError {\n  constructor(minPeriod: number) {\n    super(`Period must be at least ${minPeriod} second(s)`);\n    this.name = \"PeriodTooSmallError\";\n  }\n}\n\n/**\n * Error thrown when period is too large\n */\nexport class PeriodTooLargeError extends PeriodError {\n  constructor(maxPeriod: number) {\n    super(`Period must not exceed ${maxPeriod} seconds`);\n    this.name = \"PeriodTooLargeError\";\n  }\n}\n\n/**\n * Error thrown when digits value is invalid\n */\nexport class DigitsError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"DigitsError\";\n  }\n}\n\n/**\n * Error thrown when hash algorithm is invalid\n */\nexport class AlgorithmError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"AlgorithmError\";\n  }\n}\n\n/**\n * Error thrown when token is invalid\n */\nexport class TokenError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"TokenError\";\n  }\n}\n\n/**\n * Error thrown when token has incorrect length\n */\nexport class TokenLengthError extends TokenError {\n  constructor(expected: number, actual: number) {\n    super(`Token must be ${expected} digits, got ${actual}`);\n    this.name = \"TokenLengthError\";\n  }\n}\n\n/**\n * Error thrown when token contains non-digit characters\n */\nexport class TokenFormatError extends TokenError {\n  constructor() {\n    super(\"Token must contain only digits\");\n    this.name = \"TokenFormatError\";\n  }\n}\n\n/**\n * Error thrown when crypto operation fails\n */\nexport class CryptoError extends OTPError {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(message, options);\n    this.name = \"CryptoError\";\n  }\n}\n\n/**\n * Error thrown when HMAC computation fails\n *\n * The original error from the crypto plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n *   await cryptoContext.hmac('sha1', key, data);\n * } catch (error) {\n *   if (error instanceof HMACError) {\n *     console.log('HMAC failed:', error.message);\n *     console.log('Original error:', error.cause);\n *   }\n * }\n * ```\n */\nexport class HMACError extends CryptoError {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(`HMAC computation failed: ${message}`, options);\n    this.name = \"HMACError\";\n  }\n}\n\n/**\n * Error thrown when random byte generation fails\n *\n * The original error from the crypto plugin is available via `cause`.\n */\nexport class RandomBytesError extends CryptoError {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(`Random byte generation failed: ${message}`, options);\n    this.name = \"RandomBytesError\";\n  }\n}\n\n/**\n * Error thrown when Base32 operation fails\n */\nexport class Base32Error extends OTPError {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(message, options);\n    this.name = \"Base32Error\";\n  }\n}\n\n/**\n * Error thrown when Base32 encoding fails\n *\n * The original error from the Base32 plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n *   base32Context.encode(data);\n * } catch (error) {\n *   if (error instanceof Base32EncodeError) {\n *     console.log('Encoding failed:', error.message);\n *     console.log('Original error:', error.cause);\n *   }\n * }\n * ```\n */\nexport class Base32EncodeError extends Base32Error {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(`Base32 encoding failed: ${message}`, options);\n    this.name = \"Base32EncodeError\";\n  }\n}\n\n/**\n * Error thrown when Base32 decoding fails\n *\n * The original error from the Base32 plugin is available via `cause`.\n *\n * @example\n * ```typescript\n * try {\n *   base32Context.decode(invalidString);\n * } catch (error) {\n *   if (error instanceof Base32DecodeError) {\n *     console.log('Decoding failed:', error.message);\n *     console.log('Original error:', error.cause);\n *   }\n * }\n * ```\n */\nexport class Base32DecodeError extends Base32Error {\n  constructor(message: string, options?: OTPErrorOptions) {\n    super(`Base32 decoding failed: ${message}`, options);\n    this.name = \"Base32DecodeError\";\n  }\n}\n\n/**\n * Error thrown when counter tolerance is invalid\n */\nexport class CounterToleranceError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"CounterToleranceError\";\n  }\n}\n\n/**\n * Error thrown when counter tolerance is too large\n */\nexport class CounterToleranceTooLargeError extends CounterToleranceError {\n  constructor(maxTolerance: number, actualSize: number) {\n    super(\n      `Counter tolerance size must not exceed ${maxTolerance}, got ${actualSize}. ` +\n        `Large tolerances can cause performance issues.`,\n    );\n    this.name = \"CounterToleranceTooLargeError\";\n  }\n}\n\n/**\n * Error thrown when epoch tolerance is invalid\n */\nexport class EpochToleranceError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"EpochToleranceError\";\n  }\n}\n\n/**\n * Error thrown when epoch tolerance contains negative values\n */\nexport class EpochToleranceNegativeError extends EpochToleranceError {\n  constructor() {\n    super(\"Epoch tolerance cannot contain negative values\");\n    this.name = \"EpochToleranceNegativeError\";\n  }\n}\n\n/**\n * Error thrown when epoch tolerance is too large\n */\nexport class EpochToleranceTooLargeError extends EpochToleranceError {\n  constructor(maxTolerance: number, actualValue: number) {\n    super(\n      `Epoch tolerance must not exceed ${maxTolerance} seconds, got ${actualValue}. ` +\n        `Large tolerances can cause performance issues.`,\n    );\n    this.name = \"EpochToleranceTooLargeError\";\n  }\n}\n\n/**\n * Error thrown when a required plugin is missing\n */\nexport class PluginError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"PluginError\";\n  }\n}\n\n/**\n * Error thrown when crypto plugin is not configured\n */\nexport class CryptoPluginMissingError extends PluginError {\n  constructor() {\n    super(\"Crypto plugin is required.\");\n    this.name = \"CryptoPluginMissingError\";\n  }\n}\n\n/**\n * Error thrown when Base32 plugin is not configured\n */\nexport class Base32PluginMissingError extends PluginError {\n  constructor() {\n    super(\"Base32 plugin is required.\");\n    this.name = \"Base32PluginMissingError\";\n  }\n}\n\n/**\n * Error thrown when required configuration is missing\n */\nexport class ConfigurationError extends OTPError {\n  constructor(message: string) {\n    super(message);\n    this.name = \"ConfigurationError\";\n  }\n}\n\n/**\n * Error thrown when secret is not configured\n */\nexport class SecretMissingError extends ConfigurationError {\n  constructor() {\n    super(\n      \"Secret is required. \" +\n        \"Use generateSecret() to create one, or provide via { secret: 'YOUR_BASE32_SECRET' }\",\n    );\n    this.name = \"SecretMissingError\";\n  }\n}\n\n/**\n * Error thrown when label is not configured (required for URI generation)\n */\nexport class LabelMissingError extends ConfigurationError {\n  constructor() {\n    super(\"Label is required for URI generation. Example: { label: 'user@example.com' }\");\n    this.name = \"LabelMissingError\";\n  }\n}\n\n/**\n * Error thrown when issuer is not configured (required for URI generation)\n */\nexport class IssuerMissingError extends ConfigurationError {\n  constructor() {\n    super(\"Issuer is required for URI generation. Example: { issuer: 'MyApp' }\");\n    this.name = \"IssuerMissingError\";\n  }\n}\n\n/**\n * Error thrown when secret must be a Base32 string but is provided as bytes\n */\nexport class SecretTypeError extends ConfigurationError {\n  constructor() {\n    super(\n      \"Class API requires secret to be a Base32 string, not Uint8Array. \" +\n        \"Use generateSecret() or provide a Base32-encoded string.\",\n    );\n    this.name = \"SecretTypeError\";\n  }\n}\n","import {\n  OTPError,\n  SecretTooShortError,\n  SecretTooLongError,\n  CounterNegativeError,\n  CounterOverflowError,\n  TimeNegativeError,\n  PeriodTooSmallError,\n  PeriodTooLargeError,\n  TokenLengthError,\n  TokenFormatError,\n  CounterToleranceTooLargeError,\n  EpochToleranceNegativeError,\n  EpochToleranceTooLargeError,\n  CryptoPluginMissingError,\n  Base32PluginMissingError,\n  SecretMissingError,\n  LabelMissingError,\n  IssuerMissingError,\n  SecretTypeError,\n} from \"./errors.js\";\n\nimport type {\n  HashAlgorithm,\n  SecretOptions,\n  OTPResultOk,\n  OTPResultError,\n  OTPResult,\n} from \"./types.js\";\n\n/**\n * Singleton TextEncoder instance to avoid repeated allocations\n */\nconst textEncoder = new TextEncoder();\n\n/**\n * Minimum secret length in bytes (128 bits as per RFC 4226)\n */\nexport const MIN_SECRET_BYTES = 16;\n\n/**\n * Maximum secret length in bytes (512 bits)\n *\n * The 64-byte maximum is not part of the RFCs.\n * This is to prevent excessive memory usage in HMAC operations.\n */\nexport const MAX_SECRET_BYTES = 64;\n\n/**\n * Recommended secret length in bytes (160 bits as per RFC 4226)\n */\nexport const RECOMMENDED_SECRET_BYTES = 20;\n\n/**\n * Minimum period in seconds\n */\nexport const MIN_PERIOD = 1;\n\n/**\n * Maximum period in seconds (1 hour)\n */\nexport const MAX_PERIOD = 3600;\n\n/**\n * Default period in seconds (30 seconds as per RFC 6238)\n */\nexport const DEFAULT_PERIOD = 30;\n\n/**\n * Maximum safe integer for counter (2^53 - 1)\n */\nexport const MAX_COUNTER = Number.MAX_SAFE_INTEGER;\n\n/**\n * Maximum verification window size\n *\n * Limits the number of HMAC computations during verification to prevent DoS attacks.\n * A window of 100 means up to 201 HMAC computations ([-100, +100] range).\n *\n * For TOTP: window=1 is typically sufficient (allows +-30 seconds clock drift)\n * For HOTP: window=10-50 handles reasonable counter desynchronization\n */\nexport const MAX_WINDOW = 100;\n\n/**\n * Configurable guardrails for OTP validation\n *\n * Allows overriding default safety limits for non-standard production requirements.\n * Use with caution - custom guardrails can weaken security.\n */\nexport type OTPGuardrailsConfig = {\n  MIN_SECRET_BYTES: number;\n  MAX_SECRET_BYTES: number;\n  MIN_PERIOD: number;\n  MAX_PERIOD: number;\n  MAX_COUNTER: number;\n  MAX_WINDOW: number;\n};\n\n/**\n * Module-private symbol to track guardrail override status\n *\n * This symbol is used as a property key to store whether guardrails contain custom values.\n * Being module-private and a symbol ensures:\n * - Cannot be accessed outside this module (not exported)\n * - Cannot be recreated (each Symbol() call is unique)\n * - Hidden from normal enumeration (Object.keys, JSON.stringify, for-in)\n * - Minimal memory overhead (~1 byte per object)\n * - No garbage collection concerns\n *\n * @internal\n */\nconst OVERRIDE_SYMBOL = Symbol(\"otplib.guardrails.override\");\n\n/**\n * Complete guardrails configuration\n *\n * This represents the final, immutable configuration used by validation functions.\n * Internally tracks whether any values were overridden from RFC recommendations,\n * enabling security auditing and compliance monitoring without exposing implementation\n * details in the public API.\n *\n * The override status is stored using a module-private Symbol that cannot be accessed\n * or recreated outside this module, providing true encapsulation.\n *\n * @see {@link OTPGuardrailsConfig} for the base configuration structure\n * @see {@link createGuardrails} for creating guardrails instances\n * @see {@link hasGuardrailOverrides} to check if guardrails were customized\n */\nexport type OTPGuardrails = Readonly<OTPGuardrailsConfig> & {\n  [OVERRIDE_SYMBOL]?: boolean;\n};\n\n/**\n * Default guardrails matching RFC recommendations\n *\n * Frozen to ensure immutability. Used as default parameter for validation functions.\n * For custom guardrails, use the createGuardrails() factory function.\n */\nconst DEFAULT_GUARDRAILS: OTPGuardrails = Object.freeze({\n  MIN_SECRET_BYTES,\n  MAX_SECRET_BYTES,\n  MIN_PERIOD,\n  MAX_PERIOD,\n  MAX_COUNTER,\n  MAX_WINDOW,\n  [OVERRIDE_SYMBOL]: false,\n});\n\n/**\n * Create guardrails configuration object\n *\n * Factory function that merges custom guardrails with defaults and returns\n * an immutable (frozen) object. Validates custom guardrails to ensure they\n * maintain basic safety invariants.\n *\n * When called without arguments or with `undefined`, returns the default guardrails\n * singleton (optimized to avoid unnecessary allocations). When called with custom\n * values, creates a new frozen object and internally marks it as overridden.\n *\n * @param custom - Optional partial guardrails to override defaults\n * @returns Frozen guardrails object\n * @throws {Error} If custom guardrails violate safety invariants\n *\n * @example Basic usage\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core'\n *\n * // Returns default singleton (no overrides)\n * const defaults = createGuardrails();\n * hasGuardrailOverrides(defaults); // false\n *\n * // Creates new object with overrides\n * const custom = createGuardrails({\n *   MIN_SECRET_BYTES: 8,\n *   MAX_WINDOW: 200\n * });\n * hasGuardrailOverrides(custom); // true\n * ```\n *\n * @example Monitoring custom guardrails\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core';\n *\n * const guardrails = createGuardrails({ MAX_WINDOW: 20 });\n *\n * if (hasGuardrailOverrides(guardrails)) {\n *   logger.warn('Non-default guardrails in use', { guardrails });\n * }\n * ```\n *\n * @see {@link hasGuardrailOverrides} to check if guardrails were customized\n */\nexport function createGuardrails(custom?: Partial<OTPGuardrailsConfig>): OTPGuardrails {\n  if (!custom) {\n    return DEFAULT_GUARDRAILS;\n  }\n\n  return Object.freeze({\n    ...DEFAULT_GUARDRAILS,\n    ...custom,\n    [OVERRIDE_SYMBOL]: true,\n  });\n}\n\n/**\n * Check if guardrails contain custom overrides\n *\n * Returns `true` if the guardrails object was created with custom values,\n * `false` if using RFC-recommended defaults. Useful for security auditing,\n * compliance monitoring, and development warnings.\n *\n * This function accesses a module-private Symbol property that cannot be\n * accessed or modified outside this module, ensuring reliable detection.\n *\n * @param guardrails - The guardrails object to check\n * @returns `true` if guardrails were customized, `false` if using defaults\n *\n * @example Security monitoring\n * ```ts\n * import { createGuardrails, hasGuardrailOverrides } from '@otplib/core';\n *\n * const guardrails = createGuardrails({ MAX_WINDOW: 20 });\n *\n * if (hasGuardrailOverrides(guardrails)) {\n *   console.warn('Custom guardrails detected:', guardrails);\n *   // Log to security audit system\n * }\n * ```\n *\n * @example Compliance check\n * ```ts\n * function validateGuardrails(guardrails: OTPGuardrails) {\n *   if (hasGuardrailOverrides(guardrails)) {\n *     throw new Error('Custom guardrails not allowed in production');\n *   }\n * }\n * ```\n */\nexport function hasGuardrailOverrides(guardrails: OTPGuardrails): boolean {\n  return guardrails[OVERRIDE_SYMBOL] ?? false;\n}\n\n/**\n * Validate secret key\n *\n * @param secret - The secret to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {SecretTooShortError} If secret is too short\n * @throws {SecretTooLongError} If secret is too long\n */\nexport function validateSecret(\n  secret: Uint8Array,\n  guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n  if (secret.length < guardrails.MIN_SECRET_BYTES) {\n    throw new SecretTooShortError(guardrails.MIN_SECRET_BYTES, secret.length);\n  }\n\n  if (secret.length > guardrails.MAX_SECRET_BYTES) {\n    throw new SecretTooLongError(guardrails.MAX_SECRET_BYTES, secret.length);\n  }\n}\n\n/**\n * Validate counter value\n *\n * @param counter - The counter to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {CounterNegativeError} If counter is negative\n * @throws {CounterOverflowError} If counter exceeds safe integer\n */\nexport function validateCounter(\n  counter: number | bigint,\n  guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n  const value = typeof counter === \"bigint\" ? counter : BigInt(counter);\n\n  if (value < 0n) {\n    throw new CounterNegativeError();\n  }\n\n  if (value > BigInt(guardrails.MAX_COUNTER)) {\n    throw new CounterOverflowError();\n  }\n}\n\n/**\n * Validate time value\n *\n * @param time - The time in seconds to validate\n * @throws {TimeNegativeError} If time is negative\n */\nexport function validateTime(time: number): void {\n  if (time < 0) {\n    throw new TimeNegativeError();\n  }\n}\n\n/**\n * Validate period value\n *\n * @param period - The period in seconds to validate\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {PeriodTooSmallError} If period is too small\n * @throws {PeriodTooLargeError} If period is too large\n */\nexport function validatePeriod(\n  period: number,\n  guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n  if (!Number.isInteger(period) || period < guardrails.MIN_PERIOD) {\n    throw new PeriodTooSmallError(guardrails.MIN_PERIOD);\n  }\n\n  if (period > guardrails.MAX_PERIOD) {\n    throw new PeriodTooLargeError(guardrails.MAX_PERIOD);\n  }\n}\n\n/**\n * Validate token\n *\n * @param token - The token string to validate\n * @param digits - Expected number of digits\n * @throws {TokenLengthError} If token has incorrect length\n * @throws {TokenFormatError} If token contains non-digit characters\n */\nexport function validateToken(token: string, digits: number): void {\n  if (token.length !== digits) {\n    throw new TokenLengthError(digits, token.length);\n  }\n\n  if (!/^\\d+$/.test(token)) {\n    throw new TokenFormatError();\n  }\n}\n\n/**\n * Validate counter tolerance for HOTP verification\n *\n * Prevents DoS attacks by limiting the number of counter values checked.\n *\n * @param counterTolerance - Counter tolerance specification (number or array of offsets)\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {CounterToleranceTooLargeError} If tolerance size exceeds MAX_WINDOW\n *\n * @example\n * ```ts\n * validateCounterTolerance(1);        // OK: 3 offsets [-1, 0, 1]\n * validateCounterTolerance(100);      // OK: 201 offsets [-100, ..., 100]\n * validateCounterTolerance(101);      // Throws: exceeds MAX_WINDOW\n * validateCounterTolerance([0, 1]);   // OK: 2 offsets\n * ```\n */\nexport function validateCounterTolerance(\n  counterTolerance: number | number[],\n  guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n  const size = Array.isArray(counterTolerance) ? counterTolerance.length : counterTolerance * 2 + 1;\n\n  if (size > guardrails.MAX_WINDOW * 2 + 1) {\n    throw new CounterToleranceTooLargeError(\n      guardrails.MAX_WINDOW,\n      Array.isArray(counterTolerance) ? counterTolerance.length : counterTolerance,\n    );\n  }\n}\n\n/**\n * Validate epoch tolerance for TOTP verification\n *\n * Prevents DoS attacks by limiting the time range checked.\n * Also validates that tolerance values are non-negative.\n *\n * @param epochTolerance - Epoch tolerance specification (number or tuple [past, future])\n * @param period - The TOTP period in seconds (default: 30). Used to calculate max tolerance.\n * @param guardrails - Validation guardrails (defaults to RFC recommendations)\n * @throws {EpochToleranceNegativeError} If tolerance contains negative values\n * @throws {EpochToleranceTooLargeError} If tolerance exceeds MAX_WINDOW periods\n *\n * @example\n * ```ts\n * validateEpochTolerance(30);            // OK: 30 seconds (default period 30s)\n * validateEpochTolerance([5, 0]);        // OK: 5 seconds past only\n * validateEpochTolerance([-5, 0]);       // Throws: negative values not allowed\n * validateEpochTolerance(3600);          // Throws: exceeds MAX_WINDOW * period\n * validateEpochTolerance(6000, 60);      // OK with 60s period (MAX_WINDOW * 60 = 6000)\n * ```\n */\nexport function validateEpochTolerance(\n  epochTolerance: number | [number, number],\n  period: number = DEFAULT_PERIOD,\n  guardrails: OTPGuardrails = DEFAULT_GUARDRAILS,\n): void {\n  const [pastTolerance, futureTolerance] = Array.isArray(epochTolerance)\n    ? epochTolerance\n    : [epochTolerance, epochTolerance];\n\n  // Check for negative values\n  if (pastTolerance < 0 || futureTolerance < 0) {\n    throw new EpochToleranceNegativeError();\n  }\n\n  // Check total tolerance doesn't exceed reasonable limits\n  // Convert to periods and check against MAX_WINDOW\n  const maxToleranceSeconds = guardrails.MAX_WINDOW * period;\n  const maxAllowed = Math.max(pastTolerance, futureTolerance);\n\n  if (maxAllowed > maxToleranceSeconds) {\n    throw new EpochToleranceTooLargeError(maxToleranceSeconds, maxAllowed);\n  }\n}\n\n/**\n * Convert counter to 8-byte big-endian array\n *\n * Per RFC 4226 Section 5.1, the counter value is represented as an 8-byte\n * big-endian (network byte order) unsigned integer.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.1 | RFC 4226 Section 5.1 - Symbol Descriptions}\n *\n * @param value - The counter value to convert\n * @returns 8-byte big-endian array\n */\nexport function counterToBytes(value: number | bigint): Uint8Array {\n  const bigintValue = typeof value === \"bigint\" ? value : BigInt(value);\n  const buffer = new ArrayBuffer(8);\n  const view = new DataView(buffer);\n\n  view.setBigUint64(0, bigintValue, false);\n\n  return new Uint8Array(buffer);\n}\n\n/**\n * Perform Dynamic Truncation as per RFC 4226 Section 5.3\n *\n * The algorithm:\n * 1. Take the low-order 4 bits of the last byte as offset\n * 2. Extract 4 bytes starting at offset\n * 3. Mask the most significant bit to get a 31-bit unsigned integer\n *\n * This ensures consistent extraction across different HMAC output sizes\n * while producing a value that fits in a signed 32-bit integer.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3 - Generating an HOTP Value}\n *\n * @param hmacResult - HMAC result (at least 20 bytes for SHA-1)\n * @returns Truncated 31-bit unsigned integer\n */\nexport function dynamicTruncate(hmacResult: Uint8Array): number {\n  const offset = hmacResult[hmacResult.length - 1] & 0x0f;\n\n  const binary =\n    ((hmacResult[offset] & 0x7f) << 24) |\n    (hmacResult[offset + 1] << 16) |\n    (hmacResult[offset + 2] << 8) |\n    hmacResult[offset + 3];\n\n  return binary;\n}\n\n/**\n * Convert truncated integer to OTP string with specified digits\n *\n * Computes: Snum mod 10^Digit (RFC 4226 Section 5.3)\n *\n * The result is zero-padded to ensure consistent length,\n * as required for proper token comparison.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-5.3 | RFC 4226 Section 5.3 - Generating an HOTP Value}\n *\n * @param value - The truncated integer value (Snum)\n * @param digits - Number of digits for the OTP (Digit, typically 6-8)\n * @returns OTP string with leading zeros if necessary\n */\nexport function truncateDigits(value: number, digits: number): string {\n  const maxOtp = 10 ** digits;\n  const otp = value % maxOtp;\n  return otp.toString().padStart(digits, \"0\");\n}\n\n/**\n * Validate that two byte arrays have equal length\n *\n * Useful as a preliminary check before performing byte-by-byte comparisons.\n *\n * @param a - First byte array\n * @param b - Second byte array\n * @returns true if arrays have equal length, false otherwise\n */\nexport function validateByteLengthEqual(a: Uint8Array, b: Uint8Array): boolean {\n  return a.length === b.length;\n}\n\n/**\n * Constant-time comparison to prevent timing attacks\n *\n * This implements a timing-safe equality check as recommended in\n * RFC 4226 Section 7.2 for token validation to prevent\n * timing side-channel attacks.\n *\n * @see {@link https://tools.ietf.org/html/rfc4226#section-7.2 | RFC 4226 Section 7.2 - Validation and Verification}\n *\n * @param a - First value to compare\n * @param b - Second value to compare\n * @returns true if values are equal, false otherwise\n */\nexport function constantTimeEqual(a: string | Uint8Array, b: string | Uint8Array): boolean {\n  const bufA = stringToBytes(a);\n  const bufB = stringToBytes(b);\n\n  if (!validateByteLengthEqual(bufA, bufB)) {\n    return false;\n  }\n\n  let result = 0;\n  for (let i = 0; i < bufA.length; i++) {\n    result |= bufA[i] ^ bufB[i];\n  }\n\n  return result === 0;\n}\n\n/**\n * Get HMAC digest size in bytes for a given algorithm\n *\n * @param algorithm - The hash algorithm\n * @returns Digest size in bytes\n */\nexport function getDigestSize(algorithm: HashAlgorithm): number {\n  switch (algorithm) {\n    case \"sha1\":\n      return 20;\n    case \"sha256\":\n      return 32;\n    case \"sha512\":\n      return 64;\n  }\n}\n\n/**\n * Convert a string or Uint8Array to Uint8Array\n *\n * This utility function normalizes input to Uint8Array, converting strings\n * using UTF-8 encoding. Uint8Array inputs are returned as-is.\n *\n * @param value - The value to convert (string or Uint8Array)\n * @returns The value as a Uint8Array (UTF-8 encoded for strings)\n *\n * @example\n * ```ts\n * import { stringToBytes } from '@otplib/core'\n *\n * const bytes1 = stringToBytes('1234567890123456')\n * // Returns: Uint8Array([49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54])\n *\n * const bytes2 = stringToBytes(new Uint8Array([1, 2, 3]))\n * // Returns: Uint8Array([1, 2, 3]) - returned as-is\n * ```\n */\nexport function stringToBytes(value: string | Uint8Array): Uint8Array {\n  return typeof value === \"string\" ? textEncoder.encode(value) : value;\n}\n\n/**\n * Convert a hex string to a Uint8Array\n *\n * This is useful for working with RFC test vectors and debugging HMAC outputs,\n * which are commonly represented as hexadecimal strings.\n *\n * If your environment supports it, consider using `Uint8Array.fromHex()` instead.\n *\n * @param hex - The hex string to convert (lowercase or uppercase, no 0x prefix)\n * @returns The bytes as a Uint8Array\n *\n * @example\n * ```ts\n * import { hexToBytes } from '@otplib/core'\n *\n * // Convert RFC 4226 HMAC test vector\n * const hmac = hexToBytes('cc93cf18508d94934c64b65d8ba7667fb7cde4b0')\n * // Returns: Uint8Array([0xcc, 0x93, 0xcf, ...])\n * ```\n */\nexport function hexToBytes(hex: string): Uint8Array {\n  const bytes = new Uint8Array(hex.length / 2);\n  for (let i = 0; i < hex.length; i += 2) {\n    bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n  }\n  return bytes;\n}\n\n/**\n * Normalize secret input to Uint8Array\n *\n * Accepts either a Base32-encoded string or Uint8Array and returns Uint8Array.\n * If a Base32Plugin is provided, string secrets will be automatically decoded.\n *\n * @param secret - The secret to normalize (string or Uint8Array)\n * @param base32 - Optional Base32Plugin to decode string secrets\n * @returns The secret as Uint8Array\n * @throws {Error} If secret is a string but no Base32Plugin is provided\n *\n * @example\n * ```ts\n * import { normalizeSecret } from '@otplib/core'\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure'\n *\n * const base32 = new ScureBase32Plugin()\n *\n * // Uint8Array - returned as-is\n * const secret1 = normalizeSecret(new Uint8Array([1, 2, 3]))\n *\n * // Base32 string - automatically decoded\n * const secret2 = normalizeSecret('JBSWY3DPEHPK3PXP', base32)\n * ```\n */\nexport function normalizeSecret(\n  secret: string | Uint8Array,\n  base32?: { decode: (str: string) => Uint8Array },\n): Uint8Array {\n  if (typeof secret === \"string\") {\n    requireBase32Plugin(base32);\n    return base32.decode(secret);\n  }\n  return secret;\n}\n\n/**\n * Generate a random Base32-encoded secret\n *\n * Creates a cryptographically secure random secret suitable for OTP generation.\n * The default length of 20 bytes (160 bits) matches RFC 4226 recommendations\n * and provides good security margin.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret string (without padding for Google Authenticator compatibility)\n *\n * @example\n * ```ts\n * import { generateSecret } from '@otplib/core';\n * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';\n * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';\n *\n * const secret = generateSecret({\n *   crypto: new NodeCryptoPlugin(),\n *   base32: new ScureBase32Plugin(),\n * });\n * // Returns: 'JBSWY3DPEHPK3PXP...' (32 characters)\n * ```\n *\n * @example Custom length\n * ```ts\n * const secret = generateSecret({\n *   crypto: new NodeCryptoPlugin(),\n *   base32: new ScureBase32Plugin(),\n *   length: 32, // 256 bits for SHA-256\n * });\n * ```\n */\nexport function generateSecret(options: SecretOptions): string {\n  const { crypto, base32, length = RECOMMENDED_SECRET_BYTES } = options;\n\n  requireCryptoPlugin(crypto);\n  requireBase32Plugin(base32);\n\n  const randomBytes = crypto.randomBytes(length);\n  return base32.encode(randomBytes, { padding: false });\n}\n\n/**\n * Normalize counter tolerance to an array of offsets\n *\n * Converts a number or array counter tolerance specification into an array of offsets\n * - Number: creates symmetric range [-tolerance, +tolerance]\n * - Array: uses the array as-is (already contains specific offsets)\n *\n * @param counterTolerance - Counter tolerance specification (number or array of offsets)\n * @returns Array of offsets to check\n *\n * @example\n * ```ts\n * normalizeCounterTolerance(0)  // [0]\n * normalizeCounterTolerance(1)  // [-1, 0, 1]\n * normalizeCounterTolerance(2)  // [-2, -1, 0, 1, 2]\n * normalizeCounterTolerance([0, 1])  // [0, 1]\n * normalizeCounterTolerance([-1, 0, 1])  // [-1, 0, 1]\n * ```\n */\nexport function normalizeCounterTolerance(counterTolerance: number | number[] = 0): number[] {\n  if (Array.isArray(counterTolerance)) {\n    return counterTolerance;\n  }\n\n  const result: number[] = [];\n  for (let i = -counterTolerance; i <= counterTolerance; i++) {\n    // Bitwise OR with 0 converts -0 to 0 and preserves other integers\n    result.push(i | 0);\n  }\n  return result;\n}\n\n/**\n * Normalize epoch tolerance to [past, future] tuple\n *\n * Converts a number or tuple epoch tolerance specification into a [past, future] tuple\n * - Number: creates symmetric tolerance [tolerance, tolerance]\n * - Tuple: uses the tuple as-is\n *\n * @param epochTolerance - Epoch tolerance specification (number or tuple [past, future])\n * @returns Tuple [pastTolerance, futureTolerance] in seconds\n *\n * @example\n * ```ts\n * normalizeEpochTolerance(0)        // [0, 0]\n * normalizeEpochTolerance(30)       // [30, 30]\n * normalizeEpochTolerance([5, 0])   // [5, 0]\n * normalizeEpochTolerance([10, 5])  // [10, 5]\n * ```\n */\nexport function normalizeEpochTolerance(\n  epochTolerance: number | [number, number] = 0,\n): [number, number] {\n  return Array.isArray(epochTolerance) ? epochTolerance : [epochTolerance, epochTolerance];\n}\n\n/**\n * Require crypto plugin to be configured\n *\n * @param crypto - The crypto plugin\n * @throws {CryptoPluginMissingError} If crypto plugin is not set\n */\nexport function requireCryptoPlugin<T>(crypto: T | undefined): asserts crypto is T {\n  if (!crypto) {\n    throw new CryptoPluginMissingError();\n  }\n}\n\n/**\n * Require Base32 plugin to be configured\n *\n * @param base32 - The Base32 plugin\n * @throws {Base32PluginMissingError} If Base32 plugin is not set\n */\nexport function requireBase32Plugin<T>(base32: T | undefined): asserts base32 is T {\n  if (!base32) {\n    throw new Base32PluginMissingError();\n  }\n}\n\n/**\n * Require secret to be configured\n *\n * @param secret - The secret value\n * @throws {SecretMissingError} If secret is not set\n */\nexport function requireSecret<T>(secret: T | undefined): asserts secret is T {\n  if (!secret) {\n    throw new SecretMissingError();\n  }\n}\n\n/**\n * Require label to be configured (for URI generation)\n *\n * @param label - The label value\n * @throws {LabelMissingError} If label is not set\n */\nexport function requireLabel(label: string | undefined): asserts label is string {\n  if (!label) {\n    throw new LabelMissingError();\n  }\n}\n\n/**\n * Require issuer to be configured (for URI generation)\n *\n * @param issuer - The issuer value\n * @throws {IssuerMissingError} If issuer is not set\n */\nexport function requireIssuer(issuer: string | undefined): asserts issuer is string {\n  if (!issuer) {\n    throw new IssuerMissingError();\n  }\n}\n\n/**\n * Require secret to be a Base32 string (for URI generation)\n *\n * @param secret - The secret value\n * @throws {SecretTypeError} If secret is not a string\n */\nexport function requireBase32String(secret: string | Uint8Array): asserts secret is string {\n  if (typeof secret !== \"string\") {\n    throw new SecretTypeError();\n  }\n}\n\n/**\n * Create a success result\n * @internal\n */\nfunction ok<T>(value: T): OTPResultOk<T> {\n  return { ok: true, value };\n}\n\n/**\n * Create a failure result\n * @internal\n */\nfunction err<E>(error: E): OTPResultError<E> {\n  return { ok: false, error };\n}\n\n/**\n * Wrap a synchronous function to return OTPResult instead of throwing\n *\n * Preserves the original OTPError subclass so users can access\n * specific error information via instanceof checks.\n *\n * @internal\n */\nexport function wrapResult<T, Args extends unknown[]>(\n  fn: (...args: Args) => T,\n): (...args: Args) => OTPResult<T, OTPError> {\n  return (...args: Args): OTPResult<T, OTPError> => {\n    try {\n      return ok(fn(...args));\n    } catch (error) {\n      return err(error as OTPError);\n    }\n  };\n}\n\n/**\n * Wrap an async function to return OTPResult instead of throwing\n *\n * Preserves the original OTPError subclass so users can access\n * specific error information via instanceof checks.\n *\n * @internal\n */\nexport function wrapResultAsync<T, Args extends unknown[]>(\n  fn: (...args: Args) => Promise<T>,\n): (...args: Args) => Promise<OTPResult<T, OTPError>> {\n  return async (...args: Args): Promise<OTPResult<T, OTPError>> => {\n    try {\n      return ok(await fn(...args));\n    } catch (error) {\n      return err(error as OTPError);\n    }\n  };\n}\n","import { HMACError, RandomBytesError } from \"./errors.js\";\n\nimport type { CryptoPlugin, HashAlgorithm } from \"./types.js\";\n\n/**\n * CryptoContext provides a unified interface for crypto operations\n * using a pluggable crypto backend\n */\nexport class CryptoContext {\n  /**\n   * Create a new CryptoContext with the given crypto plugin\n   *\n   * @param crypto - The crypto plugin to use\n   */\n  constructor(private readonly crypto: CryptoPlugin) {}\n\n  /**\n   * Get the underlying crypto plugin\n   */\n  get plugin(): CryptoPlugin {\n    return this.crypto;\n  }\n\n  /**\n   * Compute HMAC using the configured crypto plugin\n   *\n   * @param algorithm - The hash algorithm to use\n   * @param key - The secret key as a byte array\n   * @param data - The data to authenticate as a byte array\n   * @returns HMAC digest as a byte array\n   * @throws {HMACError} If HMAC computation fails\n   */\n  async hmac(algorithm: HashAlgorithm, key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {\n    try {\n      const result = this.crypto.hmac(algorithm, key, data);\n      return result instanceof Promise ? await result : result;\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      throw new HMACError(message, { cause: error });\n    }\n  }\n\n  /**\n   * Synchronous HMAC computation\n   *\n   * @param algorithm - The hash algorithm to use\n   * @param key - The secret key as a byte array\n   * @param data - The data to authenticate as a byte array\n   * @returns HMAC digest as a byte array\n   * @throws {HMACError} If HMAC computation fails or if crypto plugin doesn't support sync operations\n   */\n  hmacSync(algorithm: HashAlgorithm, key: Uint8Array, data: Uint8Array): Uint8Array {\n    try {\n      const result = this.crypto.hmac(algorithm, key, data);\n      if (result instanceof Promise) {\n        throw new HMACError(\"Crypto plugin does not support synchronous HMAC operations\");\n      }\n      return result;\n    } catch (error) {\n      if (error instanceof HMACError) {\n        throw error;\n      }\n      const message = error instanceof Error ? error.message : String(error);\n      throw new HMACError(message, { cause: error });\n    }\n  }\n\n  /**\n   * Generate cryptographically secure random bytes\n   *\n   * @param length - Number of random bytes to generate\n   * @returns Random bytes\n   * @throws {RandomBytesError} If random byte generation fails\n   */\n  randomBytes(length: number): Uint8Array {\n    try {\n      return this.crypto.randomBytes(length);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      throw new RandomBytesError(message, { cause: error });\n    }\n  }\n}\n\n/**\n * Create a CryptoContext from a crypto plugin\n *\n * @param crypto - The crypto plugin to use\n * @returns A new CryptoContext instance\n */\nexport function createCryptoContext(crypto: CryptoPlugin): CryptoContext {\n  return new CryptoContext(crypto);\n}\n","import { Base32EncodeError, Base32DecodeError } from \"./errors.js\";\n\nimport type { Base32Plugin, Base32EncodeOptions } from \"./types.js\";\n\n/**\n * Base32Context provides a unified interface for Base32 operations\n * using a pluggable Base32 backend.\n *\n * All errors from the underlying plugin are wrapped in otplib error types\n * with the original error preserved via the `cause` property.\n */\nexport class Base32Context {\n  /**\n   * Create a new Base32Context with the given Base32 plugin\n   *\n   * @param base32 - The Base32 plugin to use\n   */\n  constructor(private readonly base32: Base32Plugin) {}\n\n  /**\n   * Get the underlying Base32 plugin\n   */\n  get plugin(): Base32Plugin {\n    return this.base32;\n  }\n\n  /**\n   * Encode binary data to Base32 string using the configured plugin\n   *\n   * @param data - Uint8Array to encode\n   * @param options - Encoding options\n   * @returns Base32 encoded string\n   * @throws {Base32EncodeError} If encoding fails\n   */\n  encode(data: Uint8Array, options?: Base32EncodeOptions): string {\n    try {\n      return this.base32.encode(data, options);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      throw new Base32EncodeError(message, { cause: error });\n    }\n  }\n\n  /**\n   * Decode Base32 string to binary data using the configured plugin\n   *\n   * @param str - Base32 string to decode\n   * @returns Decoded Uint8Array\n   * @throws {Base32DecodeError} If string contains invalid characters or decoding fails\n   */\n  decode(str: string): Uint8Array {\n    try {\n      return this.base32.decode(str);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      throw new Base32DecodeError(message, { cause: error });\n    }\n  }\n}\n\n/**\n * Create a Base32Context from a Base32 plugin\n *\n * @param base32 - The Base32 plugin to use\n * @returns A new Base32Context instance\n */\nexport function createBase32Context(base32: Base32Plugin): Base32Context {\n  return new Base32Context(base32);\n}\n","/**\n * TypeScript Utility Types for otplib\n *\n * These types enhance developer experience by providing:\n * - Branded types for type-safe string handling\n * - Type guards for discriminated unions\n * - Helper types for option extraction\n */\n\nimport type { CryptoPlugin, Base32Plugin } from \"./types.js\";\n\n/**\n * Brand type for creating nominal types from primitives\n *\n * @example\n * ```ts\n * type UserId = Brand<string, 'UserId'>;\n * const id: UserId = 'abc' as UserId;\n * ```\n */\nexport type Brand<T, B extends string> = T & { readonly __brand: B };\n\n/**\n * Branded string type for Base32-encoded secrets\n *\n * Use this type to distinguish Base32-encoded secrets from regular strings\n * at compile time, preventing accidental misuse.\n *\n * @example\n * ```ts\n * import type { Base32Secret } from '@otplib/core';\n *\n * function processSecret(secret: Base32Secret): void {\n *   // TypeScript ensures only Base32Secret values are passed\n * }\n *\n * const secret = generateSecret() as Base32Secret;\n * processSecret(secret); // OK\n * processSecret('random-string'); // Type error\n * ```\n */\nexport type Base32Secret = Brand<string, \"Base32Secret\">;\n\n/**\n * Branded string type for OTP tokens\n *\n * Use this type to distinguish OTP tokens from regular strings\n * at compile time, preventing accidental misuse.\n *\n * @example\n * ```ts\n * import type { OTPToken } from '@otplib/core';\n *\n * function validateToken(token: OTPToken): boolean {\n *   // TypeScript ensures only OTPToken values are passed\n * }\n *\n * const token = await generate() as OTPToken;\n * validateToken(token); // OK\n * validateToken('123456'); // Type error\n * ```\n */\nexport type OTPToken = Brand<string, \"OTPToken\">;\n\n/**\n * Helper type to make all properties of T required except those in K\n *\n * @example\n * ```ts\n * type Options = { a?: string; b?: number; c?: boolean };\n * type RequiredAB = RequireKeys<Options, 'a' | 'b'>;\n * // { a: string; b: number; c?: boolean }\n * ```\n */\nexport type RequireKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;\n\n/**\n * Helper type to make all properties of T optional except those in K\n *\n * @example\n * ```ts\n * type Options = { a: string; b: number; c: boolean };\n * type OptionalBC = OptionalKeys<Options, 'b' | 'c'>;\n * // { a: string; b?: number; c?: boolean }\n * ```\n */\nexport type OptionalKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\n/**\n * Extract the plugin configuration from an options type\n *\n * @example\n * ```ts\n * type Plugins = PluginConfig<TOTPOptions>;\n * // { crypto: CryptoPlugin; base32?: Base32Plugin }\n * ```\n */\nexport type PluginConfig<T> = T extends { crypto?: CryptoPlugin; base32?: Base32Plugin }\n  ? Pick<T, \"crypto\" | \"base32\">\n  : never;\n\n/**\n * Ensure an options type has plugins defined\n *\n * @example\n * ```ts\n * type ConfiguredOptions = WithRequiredPlugins<TOTPOptions>;\n * // TOTPOptions with crypto and base32 required\n * ```\n */\nexport type WithRequiredPlugins<T extends { crypto?: CryptoPlugin; base32?: Base32Plugin }> = T & {\n  crypto: CryptoPlugin;\n  base32: Base32Plugin;\n};\n\n/**\n * Options type for OTP generation (crypto required)\n *\n * @example\n * ```ts\n * type MyGenerateOptions = GenerationReady<HOTPOptions>;\n * // HOTPOptions with crypto required\n * ```\n */\nexport type GenerationReady<T extends { crypto?: CryptoPlugin }> = T & {\n  crypto: CryptoPlugin;\n};\n\n/**\n * Type predicate to check if an object has the required plugins\n *\n * @example\n * ```ts\n * const options = getOptions();\n * if (hasPlugins(options)) {\n *   // TypeScript knows plugins are defined\n *   options.crypto.hmac(...);\n * }\n * ```\n */\nexport function hasPlugins<T extends { crypto?: CryptoPlugin; base32?: Base32Plugin }>(\n  options: T,\n): options is T & { crypto: CryptoPlugin; base32: Base32Plugin } {\n  return options.crypto !== undefined && options.base32 !== undefined;\n}\n\n/**\n * Type predicate to check if an object has a crypto plugin\n *\n * @example\n * ```ts\n * if (hasCrypto(options)) {\n *   await options.crypto.hmac('sha1', key, data);\n * }\n * ```\n */\nexport function hasCrypto<T extends { crypto?: CryptoPlugin }>(\n  options: T,\n): options is T & { crypto: CryptoPlugin } {\n  return options.crypto !== undefined;\n}\n\n/**\n * Type predicate to check if an object has a base32 plugin\n *\n * @example\n * ```ts\n * if (hasBase32(options)) {\n *   const decoded = options.base32.decode(secret);\n * }\n * ```\n */\nexport function hasBase32<T extends { base32?: Base32Plugin }>(\n  options: T,\n): options is T & { base32: Base32Plugin } {\n  return options.base32 !== undefined;\n}\n\n/**\n * Narrow union type by a specific property value\n *\n * @example\n * ```ts\n * type Result = VerifyResultValid | VerifyResultInvalid;\n * type ValidOnly = NarrowBy<Result, 'valid', true>;\n * // VerifyResultValid\n * ```\n */\nexport type NarrowBy<T, K extends keyof T, V extends T[K]> = T extends { [key in K]: V }\n  ? T\n  : never;\n"],"mappings":"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","names":["src_exports","__export","AlgorithmError","Base32Context","Base32DecodeError","Base32EncodeError","Base32Error","Base32PluginMissingError","ConfigurationError","CounterError","CounterNegativeError","CounterOverflowError","CounterToleranceError","CounterToleranceTooLargeError","CryptoContext","CryptoError","CryptoPluginMissingError","DEFAULT_PERIOD","DigitsError","EpochToleranceError","EpochToleranceNegativeError","EpochToleranceTooLargeError","HMACError","IssuerMissingError","LabelMissingError","MAX_COUNTER","MAX_PERIOD","MAX_SECRET_BYTES","MAX_WINDOW","MIN_PERIOD","MIN_SECRET_BYTES","OTPError","PeriodError","PeriodTooLargeError","PeriodTooSmallError","PluginError","RECOMMENDED_SECRET_BYTES","RandomBytesError","SecretError","SecretMissingError","SecretTooLongError","SecretTooShortError","SecretTypeError","TimeError","TimeNegativeError","TokenError","TokenFormatError","TokenLengthError","constantTimeEqual","counterToBytes","createBase32Context","createCryptoContext","createGuardrails","dynamicTruncate","generateSecret","getDigestSize","hasBase32","hasCrypto","hasGuardrailOverrides","hasPlugins","hexToBytes","normalizeCounterTolerance","normalizeEpochTolerance","normalizeSecret","requireBase32Plugin","requireBase32String","requireCryptoPlugin","requireIssuer","requireLabel","requireSecret","stringToBytes","truncateDigits","validateByteLengthEqual","validateCounter","validateCounterTolerance","validateEpochTolerance","validatePeriod","validateSecret","validateTime","validateToken","wrapResult","wrapResultAsync","__toCommonJS","OTPError","message","options","SecretError","SecretTooShortError","minBytes","actualBytes","SecretTooLongError","maxBytes","CounterError","CounterNegativeError","CounterOverflowError","TimeError","TimeNegativeError","PeriodError","PeriodTooSmallError","minPeriod","PeriodTooLargeError","maxPeriod","DigitsError","AlgorithmError","TokenError","TokenLengthError","expected","actual","TokenFormatError","CryptoError","HMACError","RandomBytesError","Base32Error","Base32EncodeError","Base32DecodeError","CounterToleranceError","CounterToleranceTooLargeError","maxTolerance","actualSize","EpochToleranceError","EpochToleranceNegativeError","EpochToleranceTooLargeError","actualValue","PluginError","CryptoPluginMissingError","Base32PluginMissingError","ConfigurationError","SecretMissingError","LabelMissingError","IssuerMissingError","SecretTypeError","textEncoder","MIN_SECRET_BYTES","MAX_SECRET_BYTES","RECOMMENDED_SECRET_BYTES","MIN_PERIOD","MAX_PERIOD","DEFAULT_PERIOD","MAX_COUNTER","MAX_WINDOW","OVERRIDE_SYMBOL","DEFAULT_GUARDRAILS","createGuardrails","custom","hasGuardrailOverrides","guardrails","validateSecret","secret","SecretTooShortError","SecretTooLongError","validateCounter","counter","value","CounterNegativeError","CounterOverflowError","validateTime","time","TimeNegativeError","validatePeriod","period","PeriodTooSmallError","PeriodTooLargeError","validateToken","token","digits","TokenLengthError","TokenFormatError","validateCounterTolerance","counterTolerance","CounterToleranceTooLargeError","validateEpochTolerance","epochTolerance","pastTolerance","futureTolerance","EpochToleranceNegativeError","maxToleranceSeconds","maxAllowed","EpochToleranceTooLargeError","counterToBytes","bigintValue","buffer","dynamicTruncate","hmacResult","offset","truncateDigits","maxOtp","validateByteLengthEqual","a","b","constantTimeEqual","bufA","stringToBytes","bufB","result","getDigestSize","algorithm","hexToBytes","hex","bytes","i","normalizeSecret","base32","requireBase32Plugin","generateSecret","options","crypto","length","requireCryptoPlugin","randomBytes","normalizeCounterTolerance","normalizeEpochTolerance","CryptoPluginMissingError","Base32PluginMissingError","requireSecret","SecretMissingError","requireLabel","label","LabelMissingError","requireIssuer","issuer","IssuerMissingError","requireBase32String","SecretTypeError","ok","err","error","wrapResult","fn","args","wrapResultAsync","CryptoContext","crypto","algorithm","key","data","result","error","message","HMACError","length","RandomBytesError","createCryptoContext","Base32Context","base32","data","options","error","message","Base32EncodeError","str","Base32DecodeError","createBase32Context","hasPlugins","options","hasCrypto","hasBase32"]}