{"version":3,"sources":["../../src/auth/token-store.ts"],"sourcesContent":["/**\n * Token storage primitives for OAuth grant and access tokens.\n *\n * @remarks\n * Defines the {@link TokenStore} interface and a default in-memory\n * implementation. Persistent backends (e.g., browser storage, secure\n * keychains) are intentionally not provided here — consumers can implement\n * the interface for their environment.\n *\n * @category Auth\n * @module auth/token-store\n */\n\n/**\n * A persisted token record.\n */\nexport interface TokenRecord {\n  /** The opaque token value. */\n  token: string;\n  /** Optional expiration as a Unix timestamp in seconds. */\n  expiresAt?: number;\n}\n\n/**\n * Async key/value store for token records.\n */\nexport interface TokenStore {\n  /**\n   * Returns the record for `key`, or `null` if missing or expired.\n   */\n  get(key: string): Promise<TokenRecord | null>;\n  /**\n   * Stores `record` under `key`, overwriting any existing entry.\n   */\n  set(key: string, record: TokenRecord): Promise<void>;\n  /**\n   * Removes the entry for `key`. No-op if `key` is absent.\n   */\n  delete(key: string): Promise<void>;\n  /**\n   * Removes all entries.\n   */\n  clear(): Promise<void>;\n}\n\n/**\n * In-memory {@link TokenStore} implementation.\n *\n * @remarks\n * Expired entries are evicted lazily on read. Records are shallow-copied on\n * `set` and `get` so caller mutations do not leak into stored state.\n */\nexport class InMemoryTokenStore implements TokenStore {\n  readonly #records = new Map<string, TokenRecord>();\n\n  public get(key: string): Promise<TokenRecord | null> {\n    const record = this.#records.get(key);\n    if (record === undefined) return Promise.resolve(null);\n    if (\n      record.expiresAt !== undefined &&\n      record.expiresAt <= Math.floor(Date.now() / 1000)\n    ) {\n      this.#records.delete(key);\n      return Promise.resolve(null);\n    }\n    return Promise.resolve({ ...record });\n  }\n\n  public set(key: string, record: TokenRecord): Promise<void> {\n    this.#records.set(key, { ...record });\n    return Promise.resolve();\n  }\n\n  public delete(key: string): Promise<void> {\n    this.#records.delete(key);\n    return Promise.resolve();\n  }\n\n  public clear(): Promise<void> {\n    this.#records.clear();\n    return Promise.resolve();\n  }\n\n  /**\n   * Returns the number of stored entries (including any not yet\n   * lazily evicted). Intended for tests and diagnostics.\n   */\n  public get size(): number {\n    return this.#records.size;\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDO,MAAM,mBAAyC;AAAA,EAC3C,WAAW,oBAAI,IAAyB;AAAA,EAE1C,IAAI,KAA0C;AACnD,UAAM,SAAS,KAAK,SAAS,IAAI,GAAG;AACpC,QAAI,WAAW,OAAW,QAAO,QAAQ,QAAQ,IAAI;AACrD,QACE,OAAO,cAAc,UACrB,OAAO,aAAa,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,GAChD;AACA,WAAK,SAAS,OAAO,GAAG;AACxB,aAAO,QAAQ,QAAQ,IAAI;AAAA,IAC7B;AACA,WAAO,QAAQ,QAAQ,EAAE,GAAG,OAAO,CAAC;AAAA,EACtC;AAAA,EAEO,IAAI,KAAa,QAAoC;AAC1D,SAAK,SAAS,IAAI,KAAK,EAAE,GAAG,OAAO,CAAC;AACpC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEO,OAAO,KAA4B;AACxC,SAAK,SAAS,OAAO,GAAG;AACxB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEO,QAAuB;AAC5B,SAAK,SAAS,MAAM;AACpB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,OAAe;AACxB,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;","names":[]}