{"version":3,"sources":["../src/utils/dataloader.ts","../src/utils/markdown.ts","../src/utils/index.ts","../src/cache/normalized.ts","../src/cache/index.ts","../src/cache/redis.ts","../src/errors/index.ts","../src/queries/fragments.ts","../src/queries/media.ts","../src/queries/builders.ts","../src/queries/character.ts","../src/queries/metadata.ts","../src/queries/review.ts","../src/queries/staff.ts","../src/queries/studio.ts","../src/queries/thread.ts","../src/queries/user.ts","../src/rate-limiter/index.ts","../src/client/character.ts","../src/types/character.ts","../src/types/lists.ts","../src/types/media.ts","../src/types/review.ts","../src/types/staff.ts","../src/types/studio.ts","../src/types/thread.ts","../src/types/user.ts","../src/client/media.ts","../src/client/review.ts","../src/client/staff.ts","../src/client/studio.ts","../src/client/thread.ts","../src/client/user.ts","../src/client/index.ts"],"names":["text","result","CharacterSort","CharacterRole","MediaListStatus","MediaListSort","MediaType","MediaSource","MediaFormat","MediaStatus","MediaSeason","MediaSort","AiringSort","MediaRelationType","RecommendationSort","ReviewSort","StaffSort","StudioSort","ThreadSort","UserSort","data","query"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Generic DataLoader to batch multiple individual ID requests into a single batch request.\n *\n * @internal\n */\nexport class BatchLoader<T extends { id: number }> {\n  private queue = new Map<number, { resolve: (val: T) => void; reject: (err: unknown) => void }[]>();\n  private timeout: ReturnType<typeof setTimeout> | null = null;\n\n  constructor(\n    private readonly batchFetch: (ids: number[]) => Promise<T[]>,\n    private readonly maxWaitMs: number = 50,\n    private readonly maxBatchSize: number = 50,\n  ) {}\n\n  /**\n   * Queue an ID to be fetched in the next batch.\n   * Returns a Promise that resolves when the batch request completes.\n   */\n  async load(id: number): Promise<T> {\n    return new Promise<T>((resolve, reject) => {\n      let callbacks = this.queue.get(id);\n      if (!callbacks) {\n        callbacks = [];\n        this.queue.set(id, callbacks);\n      }\n      callbacks.push({ resolve, reject });\n\n      if (this.queue.size >= this.maxBatchSize) {\n        if (this.timeout) {\n          clearTimeout(this.timeout);\n          this.timeout = null;\n        }\n        // Dispatch immediately without waiting\n        // We use void to ignore the returned promise\n        void this.dispatch();\n        return;\n      }\n\n      if (this.timeout === null) {\n        this.timeout = setTimeout(() => {\n          void this.dispatch();\n        }, this.maxWaitMs);\n        const timer = this.timeout as unknown as { unref?: () => void };\n        if (typeof timer.unref === \"function\") {\n          timer.unref(); // Prevent blocking the event loop in Node.js\n        }\n      }\n    });\n  }\n\n  private async dispatch() {\n    this.timeout = null;\n    if (this.queue.size === 0) return;\n\n    const currentQueue = this.queue;\n    this.queue = new Map(); // Reset queue for subsequent requests\n\n    const ids = Array.from(currentQueue.keys());\n\n    try {\n      const results = await this.batchFetch(ids);\n      const resultMap = new Map<number, T>();\n      for (const item of results) {\n        resultMap.set(item.id, item);\n      }\n\n      for (const [id, callbacks] of currentQueue.entries()) {\n        const result = resultMap.get(id);\n        if (result) {\n          for (const cb of callbacks) cb.resolve(result);\n        } else {\n          const err = new Error(`Item with ID ${id} not found in batch response`);\n          for (const cb of callbacks) cb.reject(err);\n        }\n      }\n    } catch (err) {\n      // Propagate the error to all queued promises\n      for (const callbacks of currentQueue.values()) {\n        for (const cb of callbacks) cb.reject(err);\n      }\n    }\n  }\n}\n","/**\n * Parses AniList specific markdown into standard HTML.\n * Includes formatting for spoilers, images, videos (youtube/webm), headings,\n * lists, code blocks, and standard markdown elements.\n *\n * @security This function escapes HTML entities to prevent XSS attacks.\n * However, the output is still raw HTML — consumers should always use a\n * Content Security Policy and consider additional sanitization when rendering\n * user-generated content in a browser.\n *\n * @param text The AniList markdown text to parse\n * @returns The parsed HTML string\n */\n/** @internal Check that a URL uses a safe protocol (http/https). */\nfunction isSafeUrl(url: string): boolean {\n  return /^https?:\\/\\//i.test(url);\n}\n\nexport function parseAniListMarkdown(text: string): string {\n  if (!text) return \"\";\n\n  let html = text;\n\n  html = html\n    .replace(/&/g, \"&amp;\")\n    .replace(/</g, \"&lt;\")\n    .replace(/>/g, \"&gt;\")\n    .replace(/\"/g, \"&quot;\")\n    .replace(/'/g, \"&#39;\");\n\n  html = html.replace(/```([\\s\\S]*?)```/g, (_match, code: string) => {\n    return `<pre><code>${code.trim()}</code></pre>`;\n  });\n\n  html = html.replace(/`([^`]+)`/g, \"<code>$1</code>\");\n\n  html = html.replace(/~!(.*?)!~/gs, '<span class=\"anilist-spoiler\">$1</span>');\n\n  html = html.replace(/~~~(.*?)~~~/gs, '<div class=\"anilist-center\">$1</div>');\n\n  html = html.replace(/img(\\d+)\\((.*?)\\)/gi, (_match, width: string, url: string) =>\n    isSafeUrl(url) ? `<img src=\"${url}\" width=\"${width}\" alt=\"\" class=\"anilist-image\" />` : \"\",\n  );\n\n  html = html.replace(/img\\((.*?)\\)/gi, (_match, url: string) =>\n    isSafeUrl(url) ? `<img src=\"${url}\" alt=\"\" class=\"anilist-image\" />` : \"\",\n  );\n\n  html = html.replace(/youtube\\((.*?)\\)/gi, (_match, id: string) => {\n    if (!/^[\\w-]+$/.test(id)) return \"\";\n    return `<iframe src=\"https://www.youtube.com/embed/${id}\" frameborder=\"0\" allowfullscreen class=\"anilist-youtube\"></iframe>`;\n  });\n\n  html = html.replace(/webm\\((.*?)\\)/gi, (_match, url: string) =>\n    isSafeUrl(url) ? `<video src=\"${url}\" controls class=\"anilist-webm\"></video>` : \"\",\n  );\n\n  html = html.replace(/^######\\s+(.+)$/gm, \"<h6>$1</h6>\");\n  html = html.replace(/^#####\\s+(.+)$/gm, \"<h5>$1</h5>\");\n  html = html.replace(/^####\\s+(.+)$/gm, \"<h4>$1</h4>\");\n  html = html.replace(/^###\\s+(.+)$/gm, \"<h3>$1</h3>\");\n  html = html.replace(/^##\\s+(.+)$/gm, \"<h2>$1</h2>\");\n  html = html.replace(/^#\\s+(.+)$/gm, \"<h1>$1</h1>\");\n\n  html = html.replace(/__(.*?)__/g, \"<strong>$1</strong>\");\n  html = html.replace(/\\*\\*(.*?)\\*\\*/g, \"<strong>$1</strong>\");\n\n  html = html.replace(/_(.*?)_/g, \"<em>$1</em>\");\n  html = html.replace(/(?<!\\*)\\*(?!\\*)(.*?)(?<!\\*)\\*(?!\\*)/g, \"<em>$1</em>\");\n\n  html = html.replace(/~~(.*?)~~/g, \"<del>$1</del>\");\n\n  html = html.replace(/\\[(.*?)\\]\\((.*?)\\)/g, (_match, text: string, url: string) =>\n    isSafeUrl(url) ? `<a href=\"${url}\" target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>` : text,\n  );\n\n  html = html.replace(/\\r\\n/g, \"\\n\");\n  const lines = html.split(\"\\n\");\n  const processed: string[] = [];\n  let listType: \"ul\" | \"ol\" | null = null;\n\n  for (const line of lines) {\n    const ulMatch = line.match(/^[\\s]*[-*]\\s+(.*)/);\n    const olMatch = line.match(/^[\\s]*\\d+\\.\\s+(.*)/);\n\n    if (ulMatch) {\n      if (listType !== \"ul\") {\n        if (listType) processed.push(`</${listType}>`);\n        processed.push(\"<ul>\");\n        listType = \"ul\";\n      }\n      processed.push(`<li>${ulMatch[1]}</li>`);\n    } else if (olMatch) {\n      if (listType !== \"ol\") {\n        if (listType) processed.push(`</${listType}>`);\n        processed.push(\"<ol>\");\n        listType = \"ol\";\n      }\n      processed.push(`<li>${olMatch[1]}</li>`);\n    } else {\n      if (listType) {\n        processed.push(`</${listType}>`);\n        listType = null;\n      }\n      processed.push(line);\n    }\n  }\n  if (listType) processed.push(`</${listType}>`);\n\n  html = processed.join(\"\\n\");\n\n  const paragraphs = html.split(/\\n{2,}/);\n  html = paragraphs\n    .map((p) => {\n      const trimmed = p.trim();\n      if (!trimmed) return \"\";\n      const withBr = trimmed.replace(/\\n/g, \"<br />\");\n      if (withBr.match(/^(<div|<iframe|<video|<img|<h[1-6]|<ul|<ol|<pre)/)) {\n        return withBr;\n      }\n      return `<p>${withBr}</p>`;\n    })\n    .filter(Boolean)\n    .join(\"\\n\");\n\n  return html;\n}\n","/**\n * Utility functions for internal use.\n */\n\nconst WHITESPACE_RE = /\\s+/g;\n\n/**\n * Normalize a GraphQL query string by collapsing all whitespace.\n * Used for cache key generation and request body minification.\n *\n * @internal\n * @param query - The raw GraphQL query string\n * @returns The whitespace-normalized query\n */\nexport function normalizeQuery(query: string): string {\n  return query.replace(WHITESPACE_RE, \" \").trim();\n}\n\n/**\n * Clamp a number to a maximum and minimum value.\n * Used internally to ensure perPage does not exceed AniList's limit of 50.\n *\n * @internal\n * @param value - The number to clamp\n * @returns The clamped number between 1 and 50\n */\nexport function clampPerPage(value: number): number {\n  return Math.min(Math.max(value, 1), 50);\n}\n\n/**\n * Split an array into smaller chunks of a specific size.\n * Used internally for batching GraphQL queries.\n *\n * @internal\n * @param arr - The array to chunk\n * @param size - The maximum size of each chunk\n * @returns An array of chunks\n */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n  if (size < 1) throw new RangeError(\"chunk size must be >= 1\");\n  const chunks: T[][] = [];\n  for (let i = 0; i < arr.length; i += size) {\n    chunks.push(arr.slice(i, i + size));\n  }\n  return chunks;\n}\n\n/**\n * Validate that a value is a finite positive integer (valid AniList ID).\n *\n * @internal\n * @param id - The ID to validate\n * @param label - Label for the error message (e.g. \"mediaId\")\n * @throws {RangeError} If the ID is not a finite positive integer\n */\nexport function validateId(id: number, label = \"id\"): void {\n  if (!Number.isFinite(id) || !Number.isInteger(id) || id < 1) {\n    throw new RangeError(`Invalid ${label}: expected a positive integer, got ${id}`);\n  }\n}\n\n/**\n * Validate an array of IDs.\n *\n * @internal\n * @param ids - The IDs to validate\n * @param label - Label for the error message\n * @throws {RangeError} If any ID is not a finite positive integer\n */\nexport function validateIds(ids: number[], label = \"id\"): void {\n  for (const id of ids) {\n    validateId(id, label);\n  }\n}\n\n/**\n * Deep-sort an object's keys recursively for deterministic JSON serialization.\n *\n * @internal\n */\nexport function sortObjectKeys(obj: unknown): unknown {\n  if (obj === null || typeof obj !== \"object\") return obj;\n  if (Array.isArray(obj)) return obj.map(sortObjectKeys);\n\n  const keys = Object.keys(obj as Record<string, unknown>);\n  if (keys.length === 0) return obj;\n  if (keys.length === 1) {\n    const key = keys[0] as string;\n    const val = (obj as Record<string, unknown>)[key];\n    const sortedVal = sortObjectKeys(val);\n    if (val === sortedVal) return obj;\n    return { [key]: sortedVal };\n  }\n\n  const sorted: Record<string, unknown> = {};\n  for (const key of keys.sort()) {\n    sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n  }\n  return sorted;\n}\n\nexport * from \"./dataloader\";\nexport * from \"./markdown\";\n","import type { CacheAdapter, CacheOptions } from \"../types\";\nimport { normalizeQuery, sortObjectKeys } from \"../utils\";\nimport type { CacheStats } from \"./index\";\n\n/**\n * Normalized Cache Adapter for AniListClient.\n *\n * This cache intercepts GraphQL responses, extracts objects with `__typename` and `id`,\n * and stores them flat in an entity store.\n * This ensures data consistency across all queries (e.g., `getMedia(1)` and `searchMedia`\n * share the exact same `Media` object).\n */\nexport class NormalizedCache implements CacheAdapter {\n  private readonly ttl: number;\n  private readonly maxSize: number;\n  private readonly enabled: boolean;\n  private readonly swrMs: number;\n\n  private readonly queryStore = new Map<string, { data: unknown; refs: Set<string>; expiresAt: number }>();\n  private readonly entityStore = new Map<string, Record<string, unknown>>();\n  private readonly refCount = new Map<string, number>();\n\n  private _hits = 0;\n  private _misses = 0;\n  private _stales = 0;\n\n  constructor(options: CacheOptions = {}) {\n    this.ttl = options.ttl ?? 24 * 60 * 60 * 1000;\n    this.maxSize = options.maxSize ?? 500;\n    this.enabled = options.enabled ?? true;\n    this.swrMs = options.staleWhileRevalidateMs ?? 0;\n  }\n\n  static key(query: string, variables: Record<string, unknown>): string {\n    const normalized = normalizeQuery(query);\n    return `${normalized}|${JSON.stringify(sortObjectKeys(variables))}`;\n  }\n\n  /** Normalizes a GraphQL response, extracting entities and returning a tree of references. */\n  private normalize(data: unknown, refsOut: Set<string>, seen = new WeakSet<object>()): unknown {\n    if (Array.isArray(data)) {\n      if (seen.has(data)) return null;\n      seen.add(data);\n      return data.map((item) => this.normalize(item, refsOut, seen));\n    }\n    if (data !== null && typeof data === \"object\") {\n      if (seen.has(data)) return null;\n      seen.add(data);\n\n      const obj = data as Record<string, unknown>;\n\n      if (typeof obj.__typename === \"string\" && (typeof obj.id === \"number\" || typeof obj.id === \"string\")) {\n        const ref = `${obj.__typename}:${obj.id}`;\n        refsOut.add(ref);\n\n        const normalizedObj: Record<string, unknown> = {};\n        for (const k in obj) {\n          if (Object.hasOwn(obj, k)) {\n            normalizedObj[k] = this.normalize(obj[k], refsOut, seen);\n          }\n        }\n\n        const existing = this.entityStore.get(ref) || {};\n        this.entityStore.set(ref, { ...existing, ...normalizedObj });\n\n        return { __ref: ref };\n      }\n\n      const result: Record<string, unknown> = {};\n      for (const k in obj) {\n        if (Object.hasOwn(obj, k)) {\n          result[k] = this.normalize(obj[k], refsOut, seen);\n        }\n      }\n      return result;\n    }\n    return data;\n  }\n\n  /** Reconstructs a GraphQL response from references. */\n  private denormalize(data: unknown, seen = new Set<string>()): unknown {\n    if (Array.isArray(data)) {\n      return data.map((item) => this.denormalize(item, seen));\n    }\n    if (data !== null && typeof data === \"object\") {\n      const obj = data as Record<string, unknown>;\n\n      if (typeof obj.__ref === \"string\") {\n        const ref = obj.__ref;\n        if (seen.has(ref)) {\n          return { __ref: ref };\n        }\n        seen.add(ref);\n        const entity = this.entityStore.get(ref);\n        if (!entity) return undefined;\n\n        const result = this.denormalize(entity, seen);\n        seen.delete(ref);\n        return result;\n      }\n\n      const result: Record<string, unknown> = {};\n      for (const k in obj) {\n        if (Object.hasOwn(obj, k)) {\n          const denormalized = this.denormalize(obj[k], seen);\n          if (denormalized === undefined) return undefined;\n          result[k] = denormalized;\n        }\n      }\n      return result;\n    }\n    return data;\n  }\n\n  getWithMeta<T>(key: string): { data: T; stale: boolean } | undefined {\n    if (!this.enabled) return undefined;\n    const entry = this.queryStore.get(key);\n    if (!entry) {\n      this._misses++;\n      return undefined;\n    }\n\n    const now = Date.now();\n    let isStale = false;\n\n    if (now > entry.expiresAt) {\n      if (this.swrMs > 0 && now <= entry.expiresAt + this.swrMs) {\n        isStale = true;\n      } else {\n        this.deleteQueryEntry(key, entry);\n        this._misses++;\n        return undefined;\n      }\n    }\n\n    const denormalized = this.denormalize(entry.data);\n    if (denormalized === undefined) {\n      this.deleteQueryEntry(key, entry);\n      this._misses++;\n      return undefined;\n    }\n\n    // LRU bump\n    this.queryStore.delete(key);\n    this.queryStore.set(key, entry);\n\n    if (isStale) {\n      this._stales++;\n    } else {\n      this._hits++;\n    }\n\n    return { data: denormalized as T, stale: isStale };\n  }\n\n  get<T>(key: string): T | undefined {\n    const res = this.getWithMeta<T>(key);\n    return res ? res.data : undefined;\n  }\n\n  set<T>(key: string, data: T): void {\n    if (!this.enabled) return;\n\n    const refs = new Set<string>();\n    const normalizedData = this.normalize(data, refs);\n\n    const existing = this.queryStore.get(key);\n    if (existing) {\n      this.deleteQueryEntry(key, existing);\n    }\n\n    if (this.maxSize > 0 && this.queryStore.size >= this.maxSize) {\n      const firstKey = this.queryStore.keys().next().value;\n      if (firstKey !== undefined) {\n        const firstEntry = this.queryStore.get(firstKey);\n        if (firstEntry) this.deleteQueryEntry(firstKey, firstEntry);\n      }\n    }\n\n    for (const ref of refs) {\n      this.refCount.set(ref, (this.refCount.get(ref) ?? 0) + 1);\n    }\n\n    this.queryStore.set(key, { data: normalizedData, refs, expiresAt: Date.now() + this.ttl });\n  }\n\n  private deleteQueryEntry(key: string, entry: { refs: Set<string> }) {\n    this.queryStore.delete(key);\n    for (const ref of entry.refs) {\n      const count = (this.refCount.get(ref) ?? 0) - 1;\n      if (count <= 0) {\n        this.refCount.delete(ref);\n        this.entityStore.delete(ref);\n      } else {\n        this.refCount.set(ref, count);\n      }\n    }\n  }\n\n  delete(key: string): boolean {\n    const entry = this.queryStore.get(key);\n    if (!entry) return false;\n    this.deleteQueryEntry(key, entry);\n    return true;\n  }\n\n  clear(): void {\n    this.queryStore.clear();\n    this.entityStore.clear();\n    this.refCount.clear();\n    this._hits = 0;\n    this._misses = 0;\n    this._stales = 0;\n  }\n\n  get size(): number {\n    return this.queryStore.size;\n  }\n\n  keys(): string[] {\n    return [...this.queryStore.keys()];\n  }\n\n  invalidate(pattern: string | RegExp): number {\n    const test =\n      typeof pattern === \"string\" ? (key: string) => key.includes(pattern) : (key: string) => pattern.test(key);\n    const toDelete: string[] = [];\n    for (const key of this.queryStore.keys()) {\n      if (test(key)) toDelete.push(key);\n    }\n    for (const key of toDelete) {\n      this.delete(key);\n    }\n    return toDelete.length;\n  }\n\n  get stats(): CacheStats & { entitiesCount: number } {\n    const total = this._hits + this._misses + this._stales;\n    return {\n      hits: this._hits,\n      misses: this._misses,\n      stales: this._stales,\n      hitRate: total === 0 ? Number.NaN : this._hits / total,\n      entitiesCount: this.entityStore.size,\n    };\n  }\n\n  resetStats(): void {\n    this._hits = 0;\n    this._misses = 0;\n    this._stales = 0;\n  }\n}\n","import type { CacheAdapter, CacheOptions } from \"../types\";\nimport { normalizeQuery, sortObjectKeys } from \"../utils\";\n\n/**\n * Simple in-memory cache with configurable TTL, LRU eviction, and optional stale-while-revalidate.\n * Used internally by AniListClient to avoid redundant API calls.\n */\nexport type { CacheOptions };\n\n/** Cache performance statistics. */\nexport interface CacheStats {\n  /** Total cache hits. */\n  hits: number;\n  /** Total cache misses. */\n  misses: number;\n  /** Stale entries returned (only with stale-while-revalidate). */\n  stales: number;\n  /** Hit rate as a ratio 0–1 (NaN if no requests yet). */\n  hitRate: number;\n}\n\ninterface CacheEntry<T> {\n  data: T;\n  expiresAt: number;\n}\n\nconst ONE_DAY_MS = 24 * 60 * 60 * 1000;\n\nexport class MemoryCache implements CacheAdapter {\n  private readonly ttl: number;\n  private readonly maxSize: number;\n  private readonly enabled: boolean;\n  private readonly swrMs: number;\n  private readonly store = new Map<string, CacheEntry<unknown>>();\n\n  private _hits = 0;\n  private _misses = 0;\n  private _stales = 0;\n\n  constructor(options: CacheOptions = {}) {\n    this.ttl = options.ttl ?? ONE_DAY_MS;\n    this.maxSize = options.maxSize ?? 500;\n    this.enabled = options.enabled ?? true;\n    this.swrMs = options.staleWhileRevalidateMs ?? 0;\n  }\n\n  /** Build a deterministic cache key from a query + variables pair. */\n  static key(query: string, variables: Record<string, unknown>): string {\n    const normalized = normalizeQuery(query);\n    return `${normalized}|${JSON.stringify(sortObjectKeys(variables))}`;\n  }\n\n  /**\n   * Retrieve a cached value and its stale status.\n   * With stale-while-revalidate enabled, returns stale data within the grace window\n   * and flags it so the caller can refresh in the background.\n   */\n  getWithMeta<T>(key: string): { data: T; stale: boolean } | undefined {\n    if (!this.enabled) return undefined;\n    const entry = this.store.get(key);\n    if (!entry) {\n      this._misses++;\n      return undefined;\n    }\n    const now = Date.now();\n    if (now > entry.expiresAt) {\n      if (this.swrMs > 0 && now <= entry.expiresAt + this.swrMs) {\n        this.store.delete(key);\n        this.store.set(key, entry);\n        this._stales++;\n        return { data: entry.data as T, stale: true };\n      }\n      this.store.delete(key);\n      this._misses++;\n      return undefined;\n    }\n    this.store.delete(key);\n    this.store.set(key, entry);\n    this._hits++;\n    return { data: entry.data as T, stale: false };\n  }\n\n  get<T>(key: string): T | undefined {\n    const res = this.getWithMeta<T>(key);\n    return res ? res.data : undefined;\n  }\n\n  /** Store a value in the cache. */\n  set<T>(key: string, data: T): void {\n    if (!this.enabled) return;\n\n    this.store.delete(key);\n\n    if (this.maxSize > 0 && this.store.size >= this.maxSize) {\n      const firstKey = this.store.keys().next().value;\n      if (firstKey !== undefined) this.store.delete(firstKey);\n    }\n\n    this.store.set(key, { data, expiresAt: Date.now() + this.ttl });\n  }\n\n  /** Remove a specific entry. */\n  delete(key: string): boolean {\n    return this.store.delete(key);\n  }\n\n  /** Clear the entire cache and reset statistics. */\n  clear(): void {\n    this.store.clear();\n    this._hits = 0;\n    this._misses = 0;\n    this._stales = 0;\n  }\n\n  /** Number of entries currently stored. */\n  get size(): number | Promise<number> {\n    return this.store.size;\n  }\n\n  /** Return all cache keys. */\n  keys(): string[] {\n    return [...this.store.keys()];\n  }\n\n  /**\n   * Get cache performance statistics.\n   *\n   * @example\n   * ```ts\n   * const cache = new MemoryCache();\n   * // ... after some usage ...\n   * console.log(cache.stats);\n   * // { hits: 42, misses: 8, stales: 0, hitRate: 0.84 }\n   * ```\n   */\n  get stats(): CacheStats {\n    const total = this._hits + this._misses + this._stales;\n    return {\n      hits: this._hits,\n      misses: this._misses,\n      stales: this._stales,\n      hitRate: total === 0 ? Number.NaN : this._hits / total,\n    };\n  }\n\n  /** Reset cache statistics without clearing stored data. */\n  resetStats(): void {\n    this._hits = 0;\n    this._misses = 0;\n    this._stales = 0;\n  }\n\n  /**\n   * Remove all entries whose key matches the given pattern.\n   *\n   * - **String**: treated as a substring match (e.g. `\"Media\"` removes all keys containing `\"Media\"`).\n   * - **RegExp**: tested against each key directly.\n   *\n   * @param pattern — A string (substring match) or RegExp.\n   * @returns Number of entries removed.\n   */\n  invalidate(pattern: string | RegExp): number {\n    const test =\n      typeof pattern === \"string\" ? (key: string) => key.includes(pattern) : (key: string) => pattern.test(key);\n    const toDelete: string[] = [];\n    for (const key of this.store.keys()) {\n      if (test(key)) toDelete.push(key);\n    }\n    for (const key of toDelete) this.store.delete(key);\n    return toDelete.length;\n  }\n}\n\nexport * from \"./normalized\";\n","import type { CacheAdapter } from \"../types\";\n\n/**\n * Minimal interface representing a Redis client.\n * Compatible with both `ioredis` and `redis` (node-redis v4+).\n */\nexport interface RedisLikeClient {\n  get(key: string): Promise<string | null>;\n  set(key: string, value: string, ...args: unknown[]): Promise<unknown>;\n  del(...keys: (string | string[])[]): Promise<number>;\n  keys(pattern: string): Promise<string[]>;\n  /** Optional SCAN-based iteration — used when available to avoid blocking the server. */\n  scanIterator?(options: { MATCH: string; COUNT?: number }): AsyncIterable<string>;\n}\n\nexport interface RedisCacheOptions {\n  /** A Redis client instance (ioredis or node-redis). */\n  client: RedisLikeClient;\n  /** Key prefix to namespace ani-client entries (default: `\"ani:\"`) */\n  prefix?: string;\n  /** TTL in milliseconds (default: 86 400 000 = 24h) */\n  ttl?: number;\n}\n\n/**\n * Redis-backed cache adapter for AniListClient.\n *\n * @example\n * ```ts\n * import Redis from \"ioredis\";\n * import { AniListClient, RedisCache } from \"ani-client\";\n *\n * const redis = new Redis();\n * const client = new AniListClient({\n *   cacheAdapter: new RedisCache({ client: redis }),\n * });\n * ```\n */\nexport class RedisCache implements CacheAdapter {\n  private readonly client: RedisLikeClient;\n  private readonly prefix: string;\n  private readonly ttl: number;\n\n  constructor(options: RedisCacheOptions) {\n    this.client = options.client;\n    this.prefix = options.prefix ?? \"ani:\";\n    this.ttl = options.ttl !== undefined ? Math.floor(options.ttl / 1000) : 86_400;\n  }\n\n  private prefixedKey(key: string): string {\n    return `${this.prefix}${key}`;\n  }\n\n  async get<T>(key: string): Promise<T | undefined> {\n    const raw = await this.client.get(this.prefixedKey(key));\n    if (raw === null) return undefined;\n    try {\n      return JSON.parse(raw) as T;\n    } catch {\n      return undefined;\n    }\n  }\n\n  async set<T>(key: string, data: T): Promise<void> {\n    await this.client.set(this.prefixedKey(key), JSON.stringify(data), \"EX\", this.ttl);\n  }\n\n  async delete(key: string): Promise<boolean> {\n    const count = await this.client.del(this.prefixedKey(key));\n    return count > 0;\n  }\n\n  /**\n   * Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.\n   *\n   * **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.\n   * Provide a client with `scanIterator` support for production use.\n   * @internal\n   */\n  private async collectKeys(pattern: string): Promise<string[]> {\n    if (this.client.scanIterator) {\n      const keys: string[] = [];\n      for await (const key of this.client.scanIterator({ MATCH: pattern, COUNT: 100 })) {\n        keys.push(key);\n      }\n      return keys;\n    }\n    return this.client.keys(pattern);\n  }\n\n  async clear(): Promise<void> {\n    const keys = await this.collectKeys(`${this.prefix}*`);\n    if (keys.length > 0) {\n      await this.client.del(...keys);\n    }\n  }\n\n  /**\n   * Get the actual number of keys with this prefix in Redis.\n   */\n  get size(): Promise<number> {\n    return this.getSize();\n  }\n\n  /** @internal */\n  private async getSize(): Promise<number> {\n    const keys = await this.collectKeys(`${this.prefix}*`);\n    return keys.length;\n  }\n\n  async keys(): Promise<string[]> {\n    const raw = await this.collectKeys(`${this.prefix}*`);\n    return raw.map((k) => k.slice(this.prefix.length));\n  }\n\n  /**\n   * Remove all entries whose key matches the given pattern.\n   *\n   * - **String**: treated as a substring match (e.g. `\"Media\"` removes all keys containing `\"Media\"`).\n   * - **RegExp**: tested against each key directly.\n   *\n   * @param pattern — A string (substring match) or RegExp.\n   * @returns Number of entries removed.\n   */\n  async invalidate(pattern: string | RegExp): Promise<number> {\n    if (typeof pattern === \"string\") {\n      const keys = await this.collectKeys(`${this.prefix}*${pattern}*`);\n      if (keys.length === 0) return 0;\n      return this.client.del(...keys);\n    }\n\n    const allKeys = await this.collectKeys(`${this.prefix}*`);\n    const matching = allKeys.filter((k) => pattern.test(k.slice(this.prefix.length)));\n    if (matching.length === 0) return 0;\n    return this.client.del(...matching);\n  }\n}\n","/**\n * Represents a location in a GraphQL query where an error occurred.\n */\nexport interface GraphQLErrorLocation {\n  line: number;\n  column: number;\n}\n\n/**\n * Standard GraphQL error shape.\n */\nexport interface GraphQLError {\n  message: string;\n  locations?: GraphQLErrorLocation[];\n  path?: (string | number)[];\n  extensions?: Record<string, unknown>;\n  [key: string]: unknown;\n}\n\n/**\n * Custom error class for AniList API errors.\n */\nexport class AniListError extends Error {\n  /** HTTP status code returned by the API */\n  public readonly status: number;\n  /** Raw error body from the API response */\n  public readonly errors: GraphQLError[];\n\n  constructor(message: string, status: number, errors: GraphQLError[] | unknown[] = []) {\n    super(message);\n    this.name = \"AniListError\";\n    this.status = status;\n    // We cast to GraphQLError[] since we assume the API conforms to the GraphQL spec\n    // or we wrap raw network errors in a somewhat compatible shape.\n    this.errors = errors as GraphQLError[];\n    Object.setPrototypeOf(this, AniListError.prototype);\n    type ErrorWithCaptureStackTrace = typeof Error & {\n      captureStackTrace(target: object, fn: object): void;\n    };\n    if (\"captureStackTrace\" in Error) {\n      (Error as ErrorWithCaptureStackTrace).captureStackTrace(this, AniListError);\n    }\n  }\n}\n","/**\n * Lightweight media fields — minimal payload for list/search contexts.\n * Does NOT include tags, studios, trailer, synonyms, or nextAiringEpisode.\n */\nexport const MEDIA_FIELDS_LIGHT = `\n  __typename\n  id\n  idMal\n  title { romaji english native userPreferred }\n  type\n  format\n  status\n  coverImage { large medium color }\n  bannerImage\n  genres\n  averageScore\n  popularity\n  favourites\n  isAdult\n  siteUrl\n  season\n  seasonYear\n  episodes\n  chapters\n  nextAiringEpisode {\n    id\n    airingAt\n    episode\n    timeUntilAiring\n  }\n`;\n\n/** Core media fields — always returned. Does NOT include relations (opt-in via include). */\nexport const MEDIA_FIELDS_BASE = `\n  __typename\n  id\n  idMal\n  title { romaji english native userPreferred }\n  type\n  format\n  status\n  description(asHtml: false)\n  startDate { year month day }\n  endDate { year month day }\n  season\n  seasonYear\n  episodes\n  duration\n  chapters\n  volumes\n  countryOfOrigin\n  isLicensed\n  source\n  hashtag\n  trailer { id site thumbnail }\n  coverImage { extraLarge large medium color }\n  bannerImage\n  genres\n  synonyms\n  averageScore\n  meanScore\n  popularity\n  favourites\n  trending\n  tags { id name description category rank isMediaSpoiler }\n  studios { nodes { id name isAnimationStudio siteUrl } }\n  isAdult\n  siteUrl\n  nextAiringEpisode {\n    id\n    airingAt\n    episode\n    mediaId\n    timeUntilAiring\n  }\n`;\n\nexport const RELATIONS_FIELDS = `\n  relations {\n    edges {\n      relationType(version: 2)\n      node {\n        __typename\n        id\n        title { romaji english native userPreferred }\n        type\n        format\n        status\n        description(asHtml: false)\n        startDate { year month day }\n        endDate { year month day }\n        season\n        seasonYear\n        episodes\n        chapters\n        volumes\n        coverImage { extraLarge large medium color }\n        genres\n        averageScore\n        meanScore\n        studios { nodes { id name isAnimationStudio siteUrl } }\n        siteUrl\n        nextAiringEpisode {\n          id\n          airingAt\n          episode\n          mediaId\n          timeUntilAiring\n        }\n      }\n    }\n  }\n`;\n\n/** Media Recommendation fields - used for when fetching recommendation for a specific media entry */\nexport const MEDIA_RECOMMENDATION_FIELDS = `\n  __typename\n  id\n  rating\n  mediaRecommendation {\n    __typename\n    id\n    title { romaji english native userPreferred }\n    type\n    format\n    status\n    description(asHtml: false)\n    coverImage { extraLarge large medium color }\n    averageScore\n    meanScore\n   \tepisodes\n   \tchapters\n   \tvolumes\n    nextAiringEpisode {\n      id\n      airingAt\n      episode\n      mediaId\n      timeUntilAiring\n    }\n   \tseason\n   \tseasonYear\n   \tstartDate { year month day }\n    endDate { year month day }\n   \tstudios { nodes { id name isAnimationStudio siteUrl } }\n   \tgenres\n    siteUrl\n  }\n`;\n\n/** Full media fields with relations — used by existing queries for backward compat. */\nexport const MEDIA_FIELDS = `\n  ${MEDIA_FIELDS_BASE}\n  ${RELATIONS_FIELDS}\n`;\n\n/** Character fields without back-reference to media (used when embedding characters inside a Media query). */\nexport const CHARACTER_FIELDS_COMPACT = `\n  __typename\n  id\n  name { first middle last full native alternative }\n  image { large medium }\n  description(asHtml: false)\n  gender\n  dateOfBirth { year month day }\n  age\n  bloodType\n  favourites\n  siteUrl\n`;\n\nconst CHARACTER_MEDIA_NODES = `\n  media(perPage: 10) {\n    nodes {\n      __typename\n      id\n      title { romaji english native userPreferred }\n      type\n      coverImage { large medium }\n      siteUrl\n    }\n  }\n`;\n\n/** Compact voice actor fields — lightweight subset for embedding inside character edges. */\nexport const VOICE_ACTOR_FIELDS_COMPACT = `\n  __typename\n  id\n  name { first middle last full native userPreferred }\n  languageV2\n  image { large medium }\n  gender\n  primaryOccupations\n  siteUrl\n`;\n\nconst CHARACTER_MEDIA_EDGES_WITH_VA = `\n  media(perPage: 10) {\n    edges {\n      voiceActors {\n        ${VOICE_ACTOR_FIELDS_COMPACT}\n      }\n      node {\n        __typename\n        id\n        title { romaji english native userPreferred }\n        type\n        coverImage { large medium }\n        siteUrl\n      }\n    }\n  }\n`;\n\nexport const CHARACTER_FIELDS = `\n  ${CHARACTER_FIELDS_COMPACT}\n  ${CHARACTER_MEDIA_NODES}\n`;\n\nexport const CHARACTER_FIELDS_WITH_VA = `\n  ${CHARACTER_FIELDS_COMPACT}\n  ${CHARACTER_MEDIA_EDGES_WITH_VA}\n`;\n\nexport const STAFF_FIELDS = `\n  __typename\n  id\n  name { first middle last full native }\n  language\n  image { large medium }\n  description(asHtml: false)\n  primaryOccupations\n  gender\n  dateOfBirth { year month day }\n  dateOfDeath { year month day }\n  age\n  yearsActive\n  homeTown\n  bloodType\n  favourites\n  siteUrl\n`;\n\nexport const STAFF_MEDIA_FIELDS = `\n  staffMedia(perPage: $perPage, sort: [POPULARITY_DESC]) {\n    nodes {\n      __typename\n      id\n      title { romaji english native userPreferred }\n      type\n      format\n      status\n      coverImage { extraLarge large medium color }\n      bannerImage\n      genres\n      averageScore\n      meanScore\n      popularity\n      favourites\n      episodes\n      trending\n      hashtag\n      season\n      seasonYear\n      startDate { year month day }\n      endDate { year month day }\n      nextAiringEpisode {\n        id\n        airingAt\n        episode\n        mediaId\n        timeUntilAiring\n      }\n      studios {\n        edges {\n          node {\n            name\n          }\n        }\n      }\n      siteUrl\n    }\n  }\n`;\n\nexport const USER_FIELDS = `\n  __typename\n  id\n  name\n  about(asHtml: false)\n  avatar { large medium }\n  bannerImage\n  isFollowing\n  isFollower\n  donatorTier\n  donatorBadge\n  createdAt\n  siteUrl\n  statistics {\n    anime { count meanScore minutesWatched episodesWatched chaptersRead volumesRead }\n    manga { count meanScore minutesWatched episodesWatched chaptersRead volumesRead }\n  }\n`;\n\n/** Favorites fragment — lightweight fields for each favorite category. */\nexport const USER_FAVORITES_FIELDS = `\n  favourites {\n    anime(perPage: 25) {\n      nodes {\n        __typename\n        id\n        title { romaji english native userPreferred }\n        coverImage { large medium }\n        type\n        format\n        siteUrl\n      }\n    }\n    manga(perPage: 25) {\n      nodes {\n        __typename\n        id\n        title { romaji english native userPreferred }\n        coverImage { large medium }\n        type\n        format\n        siteUrl\n      }\n    }\n    characters(perPage: 25) {\n      nodes {\n        __typename\n        id\n        name { full native }\n        image { large medium }\n        siteUrl\n      }\n    }\n    staff(perPage: 25) {\n      nodes {\n        __typename\n        id\n        name { full native }\n        image { large medium }\n        siteUrl\n      }\n    }\n    studios(perPage: 25) {\n      nodes {\n        __typename\n        id\n        name\n        siteUrl\n      }\n    }\n  }\n`;\n\nexport const MEDIA_LIST_FIELDS = `\n  __typename\n  id\n  mediaId\n  status\n  score(format: POINT_100)\n  progress\n  progressVolumes\n  repeat\n  priority\n  private\n  notes\n  startedAt { year month day }\n  completedAt { year month day }\n  updatedAt\n  createdAt\n  media {\n    ${MEDIA_FIELDS_BASE}\n  }\n`;\n\nexport const STUDIO_FIELDS = `\n  __typename\n  id\n  name\n  isAnimationStudio\n  siteUrl\n  favourites\n  media(page: 1, perPage: 25, sort: POPULARITY_DESC) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    nodes {\n      __typename\n      id\n      title { romaji english native userPreferred }\n      type\n      format\n      coverImage { large medium }\n      siteUrl\n    }\n  }\n`;\n\nexport const THREAD_FIELDS = `\n  __typename\n  id\n  title\n  body(asHtml: false)\n  userId\n  replyUserId\n  replyCommentId\n  replyCount\n  viewCount\n  isLocked\n  isSticky\n  isSubscribed\n  repliedAt\n  createdAt\n  updatedAt\n  siteUrl\n  user {\n    __typename\n    id\n    name\n    avatar { large medium }\n  }\n  replyUser {\n    __typename\n    id\n    name\n    avatar { large medium }\n  }\n  categories {\n    __typename\n    id\n    name\n  }\n  mediaCategories {\n    __typename\n    id\n    title { romaji english native userPreferred }\n    type\n    coverImage { large medium }\n    siteUrl\n  }\n  likes {\n    __typename\n    id\n    name\n  }\n`;\n","import { MEDIA_FIELDS, MEDIA_FIELDS_BASE, MEDIA_RECOMMENDATION_FIELDS } from \"./fragments\";\n\nexport const QUERY_MEDIA_BY_ID = `\nquery ($id: Int!) {\n  Media(id: $id) {\n    ${MEDIA_FIELDS}\n  }\n}`;\n\nexport const QUERY_MEDIA_SEARCH = `\nquery (\n  $search: String,\n  $countryOfOrigin: CountryCode,\n  $type: MediaType,\n  $format: MediaFormat,\n  $format_in: [MediaFormat],\n  $status: MediaStatus,\n  $season: MediaSeason,\n  $seasonYear: Int,\n  $genre: String,\n  $tag: String,\n  $genre_in: [String],\n  $tag_in: [String],\n  $genre_not_in: [String],\n  $tag_not_in: [String],\n  $isAdult: Boolean,\n  $idNotIn: [Int],\n  $sort: [MediaSort],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    media(\n      search: $search,\n      countryOfOrigin: $countryOfOrigin,\n      type: $type,\n      format: $format,\n      format_in: $format_in,\n      status: $status,\n      season: $season,\n      seasonYear: $seasonYear,\n      genre: $genre,\n      tag: $tag,\n      genre_in: $genre_in,\n      tag_in: $tag_in,\n      genre_not_in: $genre_not_in,\n      tag_not_in: $tag_not_in,\n      isAdult: $isAdult,\n      id_not_in: $idNotIn,\n      sort: $sort\n    ) {\n      ${MEDIA_FIELDS_BASE}\n    }\n  }\n}`;\n\nexport const QUERY_TRENDING = `\nquery (\n  $type: MediaType,\n  $isAdult: Boolean,\n  $idNotIn: [Int],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    media(\n      type: $type,\n      isAdult: $isAdult,\n      id_not_in: $idNotIn,\n      sort: TRENDING_DESC\n    ) {\n      ${MEDIA_FIELDS_BASE}\n    }\n  }\n}`;\n\nexport const QUERY_AIRING_SCHEDULE = `\nquery (\n  $airingAt_greater: Int,\n  $airingAt_lesser: Int,\n  $sort: [AiringSort],\n  $idNotIn: [Int],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    airingSchedules(\n      airingAt_greater: $airingAt_greater,\n      airingAt_lesser: $airingAt_lesser,\n      id_not_in: $idNotIn,\n      sort: $sort\n    ) {\n      id\n      airingAt\n      timeUntilAiring\n      episode\n      mediaId\n      media {\n        ${MEDIA_FIELDS_BASE}\n      }\n    }\n  }\n}`;\n\nexport const QUERY_RECENT_CHAPTERS = `\nquery (\n  $isAdult: Boolean,\n  $idNotIn: [Int],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    media(\n      type: MANGA,\n      isAdult: $isAdult,\n      id_not_in: $idNotIn,\n      status: RELEASING,\n      sort: UPDATED_AT_DESC\n    ) {\n      ${MEDIA_FIELDS_BASE}\n    }\n  }\n}`;\n\nexport const QUERY_PLANNING = `\nquery (\n  $type: MediaType,\n  $isAdult: Boolean,\n  $idNotIn: [Int],\n  $sort: [MediaSort],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    media(\n      type: $type,\n      isAdult: $isAdult,\n      id_not_in: $idNotIn,\n      status: NOT_YET_RELEASED,\n      sort: $sort\n    ) {\n      ${MEDIA_FIELDS_BASE}\n    }\n  }\n}`;\n\nexport const QUERY_MEDIA_BY_SEASON = `\nquery (\n  $season: MediaSeason!,\n  $seasonYear: Int!,\n  $type: MediaType,\n  $isAdult: Boolean,\n  $idNotIn: [Int],\n  $sort: [MediaSort],\n  $page: Int,\n  $perPage: Int\n) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    media(\n      season: $season,\n      seasonYear: $seasonYear,\n      type: $type,\n      isAdult: $isAdult,\n      id_not_in: $idNotIn,\n      sort: $sort\n    ) {\n      ${MEDIA_FIELDS_BASE}\n    }\n  }\n}`;\n\nexport const QUERY_MEDIA_BY_MAL_ID = `\nquery ($idMal: Int!, $type: MediaType) {\n  Media(idMal: $idMal, type: $type) {\n    ${MEDIA_FIELDS}\n  }\n}`;\n\nexport const QUERY_RECOMMENDATIONS = `\nquery ($mediaId: Int!, $page: Int, $perPage: Int, $sort: [RecommendationSort]) {\n  Media(id: $mediaId) {\n    recommendations(page: $page, perPage: $perPage, sort: $sort) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      nodes {\n        ${MEDIA_RECOMMENDATION_FIELDS}\n        user {\n          id\n          name\n          avatar { large medium }\n        }\n      }\n    }\n  }\n}`;\n","import type { MediaIncludeOptions } from \"../types\";\nimport { clampPerPage } from \"../utils\";\nimport {\n  CHARACTER_FIELDS,\n  CHARACTER_FIELDS_COMPACT,\n  MEDIA_FIELDS,\n  MEDIA_FIELDS_BASE,\n  MEDIA_RECOMMENDATION_FIELDS,\n  RELATIONS_FIELDS,\n  STAFF_FIELDS,\n  VOICE_ACTOR_FIELDS_COMPACT,\n} from \"./fragments\";\nimport {\n  QUERY_MEDIA_BY_ID,\n  QUERY_MEDIA_BY_SEASON,\n  QUERY_MEDIA_SEARCH,\n  QUERY_PLANNING,\n  QUERY_RECENT_CHAPTERS,\n  QUERY_TRENDING,\n} from \"./media\";\n\n/**\n * Build extra part of media query which includes characters, staff,\n * relations, streaming episodes, external links, stats, and recommendations.\n *\n * When no include options are given, an empty array is returned.\n *\n * @internal\n */\nfunction buildMediaIncludeQuery(include: MediaIncludeOptions): string[] {\n  const extra: string[] = [];\n\n  if (include.relations !== false) {\n    extra.push(RELATIONS_FIELDS);\n  }\n\n  if (include.characters) {\n    const opts = typeof include.characters === \"object\" ? include.characters : {};\n    const perPage = clampPerPage(opts.perPage ?? 25);\n    const sortClause = opts.sort !== false ? \", sort: [ROLE, RELEVANCE, ID]\" : \"\";\n    const voiceActorBlock = opts.voiceActors\n      ? `\\n            voiceActors {\n              ${VOICE_ACTOR_FIELDS_COMPACT}\n            }`\n      : \"\";\n    extra.push(`\n    characters(perPage: ${perPage}${sortClause}) {\n      edges {\n        role\n        node {\n          ${CHARACTER_FIELDS_COMPACT}\n        }${voiceActorBlock}\n      }\n    }`);\n  }\n\n  if (include.staff) {\n    const opts = typeof include.staff === \"object\" ? include.staff : {};\n    const perPage = clampPerPage(opts.perPage ?? 25);\n    const sortClause = opts.sort !== false ? \", sort: [RELEVANCE, ID]\" : \"\";\n    extra.push(`\n    staff(perPage: ${perPage}${sortClause}) {\n      edges {\n        role\n        node {\n          ${STAFF_FIELDS}\n        }\n      }\n    }`);\n  }\n\n  if (include.recommendations) {\n    const perPage = clampPerPage(\n      typeof include.recommendations === \"object\" ? (include.recommendations.perPage ?? 10) : 10,\n    );\n    extra.push(`\n    recommendations(perPage: ${perPage}, sort: [RATING_DESC]) {\n      nodes {\n        ${MEDIA_RECOMMENDATION_FIELDS}\n      }\n    }`);\n  }\n\n  if (include.streamingEpisodes) {\n    extra.push(`\n    streamingEpisodes {\n      title\n      thumbnail\n      url\n      site\n    }`);\n  }\n\n  if (include.externalLinks) {\n    extra.push(`\n    externalLinks {\n      id\n      url\n      site\n      type\n      icon\n      color\n    }`);\n  }\n\n  if (include.stats) {\n    extra.push(`\n    stats {\n      scoreDistribution { score amount }\n      statusDistribution { status amount }\n    }`);\n  }\n\n  if (include.customFields) {\n    extra.push(include.customFields);\n  }\n\n  return extra;\n}\n\n/**\n * Build a `Media(id: $id)` query that optionally includes characters, staff,\n * relations, streaming episodes, external links, stats, and recommendations.\n *\n * When no include options are given, the query is identical to QUERY_MEDIA_BY_ID.\n *\n * @internal\n */\nexport function buildMediaByIdQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_MEDIA_BY_ID;\n\n  return `\nquery ($id: Int!) {\n  Media(id: $id) {\n    ${MEDIA_FIELDS_BASE}\n    ${buildMediaIncludeQuery(include).join(\"\\n\")}\n  }\n}`;\n}\n\n/**\n * Build a search media query that optionally includes characters, staff,\n * relations, streaming episodes, external links, stats, and recommendations.\n *\n * When no include options are given, the query is identical to\n * QUERY_MEDIA_SEARCH.\n *\n * @internal\n */\nexport function buildSearchMediaQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_MEDIA_SEARCH;\n\n  return `\n  query (\n    $search: String,\n    $countryOfOrigin: CountryCode,\n    $type: MediaType,\n    $format: MediaFormat,\n    $format_in: [MediaFormat],\n    $status: MediaStatus,\n    $season: MediaSeason,\n    $seasonYear: Int,\n    $genre: String,\n    $tag: String,\n    $genre_in: [String],\n    $tag_in: [String],\n    $genre_not_in: [String],\n    $tag_not_in: [String],\n    $isAdult: Boolean,\n    $idNotIn: [Int],\n    $sort: [MediaSort],\n    $page: Int,\n    $perPage: Int\n  ) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      media(\n        search: $search,\n        countryOfOrigin: $countryOfOrigin,\n        type: $type,\n        format: $format,\n        format_in: $format_in,\n        status: $status,\n        season: $season,\n        seasonYear: $seasonYear,\n        genre: $genre,\n        tag: $tag,\n        genre_in: $genre_in,\n        tag_in: $tag_in,\n        genre_not_in: $genre_not_in,\n        tag_not_in: $tag_not_in,\n        isAdult: $isAdult,\n        id_not_in: $idNotIn,\n        sort: $sort\n      ) {\n        ${MEDIA_FIELDS_BASE}\n        ${buildMediaIncludeQuery(include).join(\"\\n\")}\n      }\n    }\n  }`;\n}\n\n/**\n * Build a Media query, sorted trending descendingly, that optionally includes characters, staff,\n * relations, streaming episodes, external links, stats, and recommendations.\n *\n * When no include options are given, the query is identical to QUERY_TRENDING.\n *\n * @internal\n */\nexport function buildGetTrendingQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_TRENDING;\n\n  return `\n  query (\n    $type: MediaType,\n    $isAdult: Boolean,\n    $idNotIn: [Int],\n    $page: Int,\n    $perPage: Int\n  ) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      media(\n        type: $type,\n        isAdult: $isAdult,\n        id_not_in: $idNotIn,\n        sort: TRENDING_DESC\n      ) {\n        ${MEDIA_FIELDS_BASE}\n        ${buildMediaIncludeQuery(include).join(\"\\n\")}\n      }\n    }\n  }`;\n}\n\n/**\n * Build a Media query to fetch by season that optionally includes characters,\n * staff, relations, streaming episodes, external links, stats, and\n * recommendations.\n *\n * When no include options are given, the query is identical to QUERY_MEDIA_BY_SEASON.\n *\n * @internal\n */\nexport function buildGetMediaBySeasonQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_MEDIA_BY_SEASON;\n\n  return `\n  query (\n    $season: MediaSeason!,\n    $seasonYear: Int!,\n    $type: MediaType,\n    $isAdult: Boolean,\n    $idNotIn: [Int],\n    $sort: [MediaSort],\n    $page: Int,\n    $perPage: Int\n  ) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      media(\n        season: $season,\n        seasonYear: $seasonYear,\n        type: $type,\n        isAdult: $isAdult,\n        id_not_in: $idNotIn,\n        sort: $sort\n      ) {\n        ${MEDIA_FIELDS_BASE}\n        ${buildMediaIncludeQuery(include).join(\"\\n\")}\n      }\n    }\n  }`;\n}\n\n/**\n * Build a query to fetch recently updated manga that optionally includes\n * characters, staff, relations, streaming episodes, external links, stats, and\n * recommendations.\n *\n * When no include options are given, the query is identical to\n * QUERY_RECENT_CHAPTERS.\n *\n * @internal\n */\nexport function buildGetRecentlyUpdatedMangaQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_RECENT_CHAPTERS;\n\n  return `\n  query (\n    $isAdult: Boolean,\n    $idNotIn: [Int],\n    $page: Int,\n    $perPage: Int\n  ) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      media(\n        type: MANGA,\n        isAdult: $isAdult,\n        id_not_in: $idNotIn,\n        status: RELEASING,\n        sort: UPDATED_AT_DESC\n      ) {\n        ${MEDIA_FIELDS_BASE}\n        ${buildMediaIncludeQuery(include).join(\"\\n\")}\n      }\n    }\n  }`;\n}\n\n/**\n * Build a query to fetch upcoming media that optionally includes\n * characters, staff, relations, streaming episodes, external links, stats, and\n * recommendations.\n *\n * When no include options are given, the query is identical to\n * QUERY_PLANNING.\n *\n * @internal\n */\nexport function buildGetPlanningQuery(include?: MediaIncludeOptions): string {\n  if (!include) return QUERY_PLANNING;\n\n  return `\n  query (\n    $type: MediaType,\n    $isAdult: Boolean,\n    $idNotIn: [Int],\n    $sort: [MediaSort],\n    $page: Int,\n    $perPage: Int\n  ) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      media(\n        type: $type,\n        isAdult: $isAdult,\n        id_not_in: $idNotIn,\n        status: NOT_YET_RELEASED,\n        sort: $sort\n      ) {\n        ${MEDIA_FIELDS_BASE}\n        ${buildMediaIncludeQuery(include).join(\"\\n\")}\n      }\n    }\n  }`;\n}\n\nexport function buildMediaCharactersQuery(\n  options: { perPage?: number; sort?: boolean; voiceActors?: boolean } = {},\n): string {\n  const sortClause = options.sort === false ? \"\" : \", sort: [ROLE, RELEVANCE, ID]\";\n  const voiceActorBlock = options.voiceActors\n    ? `\\n            voiceActors {\n              ${VOICE_ACTOR_FIELDS_COMPACT}\n            }`\n    : \"\";\n\n  return `\nquery ($mediaId: Int!, $page: Int, $perPage: Int) {\n  Media(id: $mediaId) {\n    characters(page: $page, perPage: $perPage${sortClause}) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      edges {\n        role\n        node {\n          ${CHARACTER_FIELDS_COMPACT}\n        }${voiceActorBlock}\n      }\n    }\n  }\n}`;\n}\n\nexport function buildMediaStaffQuery(options: { perPage?: number; sort?: boolean } = {}): string {\n  const sortClause = options.sort === false ? \"\" : \", sort: [RELEVANCE, ID]\";\n\n  return `\nquery ($mediaId: Int!, $page: Int, $perPage: Int) {\n  Media(id: $mediaId) {\n    staff(page: $page, perPage: $perPage${sortClause}) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      edges {\n        role\n        node {\n          ${STAFF_FIELDS}\n        }\n      }\n    }\n  }\n}`;\n}\n\n/** @internal Build a batched GraphQL query using aliases. */\nfunction buildBatchQuery(ids: number[], typeName: string, fields: string, prefix: string): string {\n  const aliases = ids.map((id, i) => `${prefix}${i}: ${typeName}(id: ${id}) { ${fields} }`).join(\"\\n  \");\n  return `query {\\n  ${aliases}\\n}`;\n}\n\nexport const buildBatchMediaQuery = (ids: number[]): string => buildBatchQuery(ids, \"Media\", MEDIA_FIELDS, \"m\");\n\nexport const buildBatchCharacterQuery = (ids: number[]): string =>\n  buildBatchQuery(ids, \"Character\", CHARACTER_FIELDS, \"c\");\n\nexport const buildBatchStaffQuery = (ids: number[]): string => buildBatchQuery(ids, \"Staff\", STAFF_FIELDS, \"s\");\n","import { CHARACTER_FIELDS, CHARACTER_FIELDS_WITH_VA } from \"./fragments\";\n\nexport const QUERY_CHARACTER_BY_ID = `\nquery ($id: Int!) {\n  Character(id: $id) {\n    ${CHARACTER_FIELDS}\n  }\n}`;\n\nexport const QUERY_CHARACTER_BY_ID_WITH_VA = `\nquery ($id: Int!) {\n  Character(id: $id) {\n    ${CHARACTER_FIELDS_WITH_VA}\n  }\n}`;\n\nexport function buildCharacterByIdQuery(include?: import(\"../types\").CharacterIncludeOptions): string {\n  if (!include?.customFields) {\n    return include?.voiceActors ? QUERY_CHARACTER_BY_ID_WITH_VA : QUERY_CHARACTER_BY_ID;\n  }\n  const fields = include.voiceActors ? CHARACTER_FIELDS_WITH_VA : CHARACTER_FIELDS;\n  return `query ($id: Int!) { Character(id: $id) { ${fields}\\n${include.customFields} } }`;\n}\n\nexport const QUERY_CHARACTER_SEARCH = `\nquery ($search: String, $sort: [CharacterSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    characters(search: $search, sort: $sort) {\n      ${CHARACTER_FIELDS}\n    }\n  }\n}`;\n\nexport const QUERY_CHARACTER_SEARCH_WITH_VA = `\nquery ($search: String, $sort: [CharacterSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    characters(search: $search, sort: $sort) {\n      ${CHARACTER_FIELDS_WITH_VA}\n    }\n  }\n}`;\n","export const QUERY_GENRES = `\nquery {\n  GenreCollection\n}`;\n\nexport const QUERY_TAGS = `\nquery {\n  MediaTagCollection {\n    id\n    name\n    description\n    category\n    isAdult\n  }\n}`;\n","import { MEDIA_FIELDS_BASE, MEDIA_FIELDS_LIGHT } from \"./fragments\";\n\nexport const QUERY_REVIEWS = `\n  query ($page: Int, $perPage: Int, $sort: [ReviewSort], $mediaId: Int, $userId: Int) {\n    Page(page: $page, perPage: $perPage) {\n      pageInfo {\n        total\n        currentPage\n        lastPage\n        hasNextPage\n        perPage\n      }\n      reviews(sort: $sort, mediaId: $mediaId, userId: $userId) {\n        id\n        userId\n        mediaId\n        mediaType\n        summary\n        body\n        rating\n        ratingAmount\n        userRating\n        score\n        private\n        siteUrl\n        createdAt\n        updatedAt\n        user {\n          id\n          name\n          avatar { large medium }\n          siteUrl\n        }\n        media {\n          ${MEDIA_FIELDS_LIGHT}\n        }\n      }\n    }\n  }\n`;\n\nexport const QUERY_REVIEW_BY_ID = `\n  query ($id: Int) {\n    Review(id: $id) {\n      id\n      userId\n      mediaId\n      mediaType\n      summary\n      body\n      rating\n      ratingAmount\n      userRating\n      score\n      private\n      siteUrl\n      createdAt\n      updatedAt\n      user {\n        id\n        name\n        avatar { large medium }\n        siteUrl\n      }\n      media {\n        ${MEDIA_FIELDS_BASE}\n      }\n    }\n  }\n`;\n","import { STAFF_FIELDS, STAFF_MEDIA_FIELDS } from \"./fragments\";\n\nexport const QUERY_STAFF_BY_ID = `\nquery ($id: Int!) {\n  Staff(id: $id) {\n    ${STAFF_FIELDS}\n  }\n}`;\n\nexport const QUERY_STAFF_BY_ID_WITH_MEDIA = `\nquery ($id: Int!, $perPage: Int) {\n  Staff(id: $id) {\n    ${STAFF_FIELDS}\n    ${STAFF_MEDIA_FIELDS}\n  }\n}`;\n\nexport function buildStaffByIdQuery(include?: import(\"../types\").StaffIncludeOptions): string {\n  if (!include?.customFields) {\n    return include?.characterRoles || include?.media ? QUERY_STAFF_BY_ID_WITH_MEDIA : QUERY_STAFF_BY_ID;\n  }\n  const extra = include?.characterRoles || include?.media ? `\\n    ${STAFF_MEDIA_FIELDS}` : \"\";\n  return `query ($id: Int!, $perPage: Int) { Staff(id: $id) { ${STAFF_FIELDS}${extra}\\n${include.customFields} } }`;\n}\n\nexport const QUERY_STAFF_SEARCH = `\nquery ($search: String, $sort: [StaffSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    staff(search: $search, sort: $sort) {\n      ${STAFF_FIELDS}\n    }\n  }\n}`;\n","import { clampPerPage } from \"../utils\";\nimport { MEDIA_FIELDS_LIGHT, STUDIO_FIELDS } from \"./fragments\";\n\nexport const QUERY_STUDIO_BY_ID = `\nquery ($id: Int!) {\n  Studio(id: $id) {\n    ${STUDIO_FIELDS}\n  }\n}`;\n\n/**\n * Build a Studio-by-ID query with customisable media perPage.\n * @internal\n */\nexport function buildStudioByIdQuery(include?: import(\"../types\").StudioIncludeOptions): string {\n  const custom = include?.customFields ? `\\n    ${include.customFields}` : \"\";\n  if (!include?.media) {\n    if (!custom) return QUERY_STUDIO_BY_ID;\n    return `query ($id: Int!) { Studio(id: $id) { ${STUDIO_FIELDS}${custom} } }`;\n  }\n  const mediaOpts = typeof include.media === \"object\" ? include.media : {};\n  const pp = clampPerPage(mediaOpts.perPage ?? 25);\n  return `\nquery ($id: Int!) {\n  Studio(id: $id) {\n    id\n    name\n    isAnimationStudio\n    siteUrl\n    favourites\n    media(page: 1, perPage: ${pp}, sort: POPULARITY_DESC) {\n      pageInfo { total perPage currentPage lastPage hasNextPage }\n      nodes {\n        ${MEDIA_FIELDS_LIGHT}\n      }\n    }${custom}\n  }\n}`;\n}\n\nexport const QUERY_STUDIO_SEARCH = `\nquery ($search: String, $sort: [StudioSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    studios(search: $search, sort: $sort) {\n      ${STUDIO_FIELDS}\n    }\n  }\n}`;\n","import { THREAD_FIELDS } from \"./fragments\";\n\nexport const QUERY_THREAD_BY_ID = `\nquery ($id: Int!) {\n  Thread(id: $id) {\n    ${THREAD_FIELDS}\n  }\n}`;\n\nexport const QUERY_THREAD_SEARCH = `\nquery ($search: String, $mediaCategoryId: Int, $categoryId: Int, $sort: [ThreadSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    threads(search: $search, mediaCategoryId: $mediaCategoryId, categoryId: $categoryId, sort: $sort) {\n      ${THREAD_FIELDS}\n    }\n  }\n}`;\n","import { clampPerPage } from \"../utils\";\nimport { MEDIA_LIST_FIELDS, USER_FAVORITES_FIELDS, USER_FIELDS } from \"./fragments\";\n\nexport const QUERY_USER_BY_ID = `\nquery ($id: Int!) {\n  User(id: $id) {\n    ${USER_FIELDS}\n  }\n}`;\n\nexport const QUERY_USER_BY_NAME = `\nquery ($name: String!) {\n  User(name: $name) {\n    ${USER_FIELDS}\n  }\n}`;\n\nexport const QUERY_USER_SEARCH = `\nquery ($search: String, $sort: [UserSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    users(search: $search, sort: $sort) {\n      ${USER_FIELDS}\n    }\n  }\n}`;\n\nexport const QUERY_USER_MEDIA_LIST = `\nquery ($userId: Int, $userName: String, $type: MediaType!, $status: MediaListStatus, $sort: [MediaListSort], $page: Int, $perPage: Int) {\n  Page(page: $page, perPage: $perPage) {\n    pageInfo { total perPage currentPage lastPage hasNextPage }\n    mediaList(userId: $userId, userName: $userName, type: $type, status: $status, sort: $sort) {\n      ${MEDIA_LIST_FIELDS}\n    }\n  }\n}`;\n\nexport const QUERY_USER_FAVORITES_BY_ID = `\nquery ($id: Int!) {\n  User(id: $id) {\n    id\n    name\n    ${USER_FAVORITES_FIELDS}\n  }\n}`;\n\nexport const QUERY_USER_FAVORITES_BY_NAME = `\nquery ($name: String!) {\n  User(name: $name) {\n    id\n    name\n    ${USER_FAVORITES_FIELDS}\n  }\n}`;\n\n/**\n * Build a User Favorites query with customisable perPage per category.\n * @internal\n */\nexport function buildUserFavoritesQuery(idOrName: \"id\" | \"name\", perPage = 25): string {\n  const pp = clampPerPage(perPage);\n  const varDecl = idOrName === \"id\" ? \"$id: Int!\" : \"$name: String!\";\n  const selector = idOrName === \"id\" ? \"id: $id\" : \"name: $name\";\n  return `\nquery (${varDecl}) {\n  User(${selector}) {\n    id\n    name\n    favourites {\n      anime(perPage: ${pp}) {\n        nodes {\n          id\n          title { romaji english native userPreferred }\n          coverImage { large medium }\n          type\n          format\n          siteUrl\n        }\n      }\n      manga(perPage: ${pp}) {\n        nodes {\n          id\n          title { romaji english native userPreferred }\n          coverImage { large medium }\n          type\n          format\n          siteUrl\n        }\n      }\n      characters(perPage: ${pp}) {\n        nodes {\n          id\n          name { full native }\n          image { large medium }\n          siteUrl\n        }\n      }\n      staff(perPage: ${pp}) {\n        nodes {\n          id\n          name { full native }\n          image { large medium }\n          siteUrl\n        }\n      }\n      studios(perPage: ${pp}) {\n        nodes {\n          id\n          name\n          siteUrl\n        }\n      }\n    }\n  }\n}`;\n}\n","/**\n * Rate limiter with automatic retry for AniList API.\n *\n * AniList allows 30 requests per minute.\n * When a 429 (Too Many Requests) is received, the client\n * waits for the Retry-After header and retries automatically.\n */\n\nimport type { RateLimitOptions } from \"../types\";\n\nexport type { RateLimitOptions };\n\nexport class RateLimiter {\n  private readonly maxRequests: number;\n  private readonly windowMs: number;\n  private readonly maxRetries: number;\n  private readonly retryDelayMs: number;\n  private readonly enabled: boolean;\n  private readonly timeoutMs: number;\n  private readonly retryOnNetworkError: boolean;\n  private readonly retryStrategy?: (attempt: number, baseDelayMs: number) => number;\n\n  /** @internal — sliding window: circular buffer of timestamps */\n  private readonly timestamps: number[];\n  private head = 0;\n  private count = 0;\n  /** @internal — active sleep timers for cleanup */\n  private readonly activeTimers = new Set<ReturnType<typeof setTimeout>>();\n\n  constructor(options: RateLimitOptions = {}) {\n    this.maxRequests = options.maxRequests ?? 25;\n    this.windowMs = options.windowMs ?? 60_000;\n    this.maxRetries = options.maxRetries ?? 3;\n    this.retryDelayMs = options.retryDelayMs ?? 2_000;\n    this.enabled = options.enabled ?? true;\n    this.timeoutMs = options.timeoutMs ?? 30_000;\n    this.retryOnNetworkError = options.retryOnNetworkError ?? true;\n    this.retryStrategy = options.retryStrategy;\n    this.timestamps = new Array<number>(this.maxRequests).fill(0);\n  }\n\n  /**\n   * Wait until it's safe to make a request (respects rate limit window).\n   */\n  async acquire(): Promise<void> {\n    if (!this.enabled) return;\n\n    if (this.count >= this.maxRequests) {\n      const oldest = this.timestamps[this.head] as number;\n      const elapsed = Date.now() - oldest;\n      if (elapsed < this.windowMs) {\n        const waitMs = this.windowMs - elapsed + 50;\n        await this.sleep(waitMs);\n      }\n    }\n\n    const now = Date.now();\n    if (this.count < this.maxRequests) {\n      this.timestamps[(this.head + this.count) % this.maxRequests] = now;\n      this.count++;\n    } else {\n      this.timestamps[this.head] = now;\n      this.head = (this.head + 1) % this.maxRequests;\n    }\n  }\n\n  /**\n   * Execute a fetch with automatic retry on 429 responses and network errors.\n   * Uses exponential backoff with jitter for retry delays.\n   */\n  async fetchWithRetry(\n    url: string,\n    init: RequestInit,\n    hooks?: {\n      onRetry?: (attempt: number, reason: string, delayMs: number) => void;\n      onRateLimit?: (retryAfterMs: number) => void;\n    },\n  ): Promise<Response> {\n    await this.acquire();\n\n    let lastResponse: Response | undefined;\n    let lastError: unknown;\n\n    for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n      try {\n        const res = await this.fetchWithTimeout(url, init);\n\n        if (res.status !== 429) return res;\n\n        lastResponse = res;\n        if (attempt === this.maxRetries) break;\n\n        const retryAfter = res.headers.get(\"Retry-After\");\n        const delayMs = retryAfter ? Number.parseInt(retryAfter, 10) * 1000 : this.exponentialDelay(attempt);\n\n        hooks?.onRateLimit?.(delayMs);\n        hooks?.onRetry?.(attempt + 1, \"HTTP 429\", delayMs);\n\n        await this.sleep(delayMs);\n        await this.acquire();\n      } catch (err) {\n        lastError = err;\n\n        if (this.retryOnNetworkError && isNetworkError(err) && attempt < this.maxRetries) {\n          const delayMs = this.exponentialDelay(attempt);\n          hooks?.onRetry?.(attempt + 1, `Network error: ${(err as Error).message}`, delayMs);\n          await this.sleep(delayMs);\n          await this.acquire();\n          continue;\n        }\n\n        throw err;\n      }\n    }\n\n    if (lastResponse) return lastResponse;\n    /* v8 ignore next -- defensive fallback; unreachable in normal control flow */\n    throw lastError ?? new Error(`Request failed after ${this.maxRetries} retries`);\n  }\n\n  /** @internal — Exponential backoff with jitter, capped at 30s (or custom strategy) */\n  private exponentialDelay(attempt: number): number {\n    if (this.retryStrategy) {\n      return this.retryStrategy(attempt, this.retryDelayMs);\n    }\n    const base = this.retryDelayMs * 2 ** attempt;\n    const jitter = Math.random() * 1000;\n    return Math.min(base + jitter, 30_000);\n  }\n\n  /** @internal */\n  private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n    if (this.timeoutMs <= 0) return fetch(url, init);\n\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n    const signals = [controller.signal, init.signal].filter(Boolean) as AbortSignal[];\n    const combinedSignal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];\n\n    try {\n      return await fetch(url, { ...init, signal: combinedSignal });\n    } finally {\n      clearTimeout(timer);\n    }\n  }\n\n  private sleep(ms: number): Promise<void> {\n    return new Promise((resolve) => {\n      const timer = setTimeout(() => {\n        this.activeTimers.delete(timer);\n        resolve();\n      }, ms);\n      this.activeTimers.add(timer);\n    });\n  }\n\n  /** Cancel all pending sleep timers and reset internal state. */\n  dispose(): void {\n    for (const timer of this.activeTimers) {\n      clearTimeout(timer);\n    }\n    this.activeTimers.clear();\n    this.head = 0;\n    this.count = 0;\n    this.timestamps.fill(0);\n  }\n}\n\n/** Set of Node.js error codes that indicate a transient network failure. */\nconst RETRYABLE_NETWORK_CODES = new Set([\n  \"ECONNRESET\",\n  \"ECONNREFUSED\",\n  \"ETIMEDOUT\",\n  \"ENOTFOUND\",\n  \"EAI_AGAIN\",\n  \"UND_ERR_CONNECT_TIMEOUT\",\n  \"UND_ERR_SOCKET\",\n]);\n\n/** @internal */\nfunction isNetworkError(err: unknown): boolean {\n  if (err instanceof TypeError && err.message === \"fetch failed\") return true;\n  const code = (err as { code?: string })?.code;\n  if (code && RETRYABLE_NETWORK_CODES.has(code)) return true;\n  const cause = (err as { cause?: { code?: string } })?.cause?.code;\n  if (cause && RETRYABLE_NETWORK_CODES.has(cause)) return true;\n  return false;\n}\n","import { QUERY_CHARACTER_SEARCH, QUERY_CHARACTER_SEARCH_WITH_VA } from \"../queries\";\nimport { buildCharacterByIdQuery } from \"../queries/character\";\nimport type { Character, CharacterIncludeOptions, PagedResult, SearchCharacterOptions } from \"../types\";\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a character by AniList ID, optionally including voice actors. */\nexport async function getCharacter(\n  client: ClientBase,\n  id: number,\n  include?: CharacterIncludeOptions,\n): Promise<Character> {\n  validateId(id, \"characterId\");\n  const query = buildCharacterByIdQuery(include);\n  const data = await client.request<{ Character: Character }>(query, { id });\n  return data.Character;\n}\n\n/** @internal Search for characters by name. */\nexport async function searchCharacters(\n  client: ClientBase,\n  options: SearchCharacterOptions = {},\n): Promise<PagedResult<Character>> {\n  const { query: search, page = 1, perPage = 20, sort, voiceActors } = options;\n  const gqlQuery = voiceActors ? QUERY_CHARACTER_SEARCH_WITH_VA : QUERY_CHARACTER_SEARCH;\n  return client.pagedRequest<Character>(gqlQuery, { search, sort, page, perPage: clampPerPage(perPage) }, \"characters\");\n}\n","import type { FuzzyDate } from \"./common\";\nimport type { Media } from \"./media\";\nimport type { VoiceActor } from \"./staff\";\n\nexport enum CharacterSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  ROLE = \"ROLE\",\n  ROLE_DESC = \"ROLE_DESC\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n  FAVOURITES = \"FAVOURITES\",\n  FAVOURITES_DESC = \"FAVOURITES_DESC\",\n}\n\nexport enum CharacterRole {\n  MAIN = \"MAIN\",\n  SUPPORTING = \"SUPPORTING\",\n  BACKGROUND = \"BACKGROUND\",\n}\n\nexport interface CharacterName {\n  first: string | null;\n  middle: string | null;\n  last: string | null;\n  full: string | null;\n  native: string | null;\n  alternative: string[];\n}\n\nexport interface CharacterImage {\n  large: string | null;\n  medium: string | null;\n}\n\nexport type CharacterMediaNode = Pick<Media, \"id\" | \"title\" | \"type\" | \"coverImage\" | \"siteUrl\">;\n\nexport interface CharacterMediaEdge {\n  node: CharacterMediaNode;\n  voiceActors?: VoiceActor[];\n}\n\nexport interface Character {\n  id: number;\n  name: CharacterName;\n  image: CharacterImage;\n  description: string | null;\n  gender: string | null;\n  dateOfBirth: FuzzyDate | null;\n  age: string | null;\n  bloodType: string | null;\n  favourites: number | null;\n  siteUrl: string | null;\n  media: {\n    nodes?: CharacterMediaNode[];\n    edges?: CharacterMediaEdge[];\n  } | null;\n}\n\n/** Options for including extra data when fetching a character. */\nexport interface CharacterIncludeOptions {\n  /** Include voice actors for each media the character appears in. */\n  voiceActors?: boolean;\n  /** Raw GraphQL fields to append to the query (e.g. for custom data) */\n  customFields?: string;\n}\n\nexport interface SearchCharacterOptions {\n  query?: string;\n  sort?: CharacterSort[];\n  page?: number;\n  perPage?: number;\n  /** Include voice actors for each media the character appears in. */\n  voiceActors?: boolean;\n}\n","import type { FuzzyDate } from \"./common\";\nimport type { Media, MediaType } from \"./media\";\n\nexport enum MediaListStatus {\n  CURRENT = \"CURRENT\",\n  PLANNING = \"PLANNING\",\n  COMPLETED = \"COMPLETED\",\n  DROPPED = \"DROPPED\",\n  PAUSED = \"PAUSED\",\n  REPEATING = \"REPEATING\",\n}\n\nexport enum MediaListSort {\n  MEDIA_ID = \"MEDIA_ID\",\n  MEDIA_ID_DESC = \"MEDIA_ID_DESC\",\n  SCORE = \"SCORE\",\n  SCORE_DESC = \"SCORE_DESC\",\n  STATUS = \"STATUS\",\n  STATUS_DESC = \"STATUS_DESC\",\n  PROGRESS = \"PROGRESS\",\n  PROGRESS_DESC = \"PROGRESS_DESC\",\n  PROGRESS_VOLUMES = \"PROGRESS_VOLUMES\",\n  PROGRESS_VOLUMES_DESC = \"PROGRESS_VOLUMES_DESC\",\n  REPEAT = \"REPEAT\",\n  REPEAT_DESC = \"REPEAT_DESC\",\n  PRIORITY = \"PRIORITY\",\n  PRIORITY_DESC = \"PRIORITY_DESC\",\n  STARTED_ON = \"STARTED_ON\",\n  STARTED_ON_DESC = \"STARTED_ON_DESC\",\n  FINISHED_ON = \"FINISHED_ON\",\n  FINISHED_ON_DESC = \"FINISHED_ON_DESC\",\n  ADDED_TIME = \"ADDED_TIME\",\n  ADDED_TIME_DESC = \"ADDED_TIME_DESC\",\n  UPDATED_TIME = \"UPDATED_TIME\",\n  UPDATED_TIME_DESC = \"UPDATED_TIME_DESC\",\n  MEDIA_TITLE_ROMAJI = \"MEDIA_TITLE_ROMAJI\",\n  MEDIA_TITLE_ROMAJI_DESC = \"MEDIA_TITLE_ROMAJI_DESC\",\n  MEDIA_TITLE_ENGLISH = \"MEDIA_TITLE_ENGLISH\",\n  MEDIA_TITLE_ENGLISH_DESC = \"MEDIA_TITLE_ENGLISH_DESC\",\n  MEDIA_TITLE_NATIVE = \"MEDIA_TITLE_NATIVE\",\n  MEDIA_TITLE_NATIVE_DESC = \"MEDIA_TITLE_NATIVE_DESC\",\n  MEDIA_POPULARITY = \"MEDIA_POPULARITY\",\n  MEDIA_POPULARITY_DESC = \"MEDIA_POPULARITY_DESC\",\n}\n\nexport interface MediaListEntry {\n  id: number;\n  mediaId: number;\n  status: MediaListStatus;\n  score: number | null;\n  progress: number | null;\n  progressVolumes: number | null;\n  repeat: number | null;\n  priority: number | null;\n  private: boolean | null;\n  notes: string | null;\n  startedAt: FuzzyDate | null;\n  completedAt: FuzzyDate | null;\n  updatedAt: number | null;\n  createdAt: number | null;\n  media: Media;\n}\n\nexport interface GetUserMediaListOptions {\n  /** User ID (provide either userId or userName) */\n  userId?: number;\n  /** Username (provide either userId or userName) */\n  userName?: string;\n  /** ANIME or MANGA */\n  type: MediaType;\n  /** Filter by list status (CURRENT, COMPLETED, etc.) */\n  status?: MediaListStatus;\n  /** Sort order */\n  sort?: MediaListSort[];\n  page?: number;\n  perPage?: number;\n}\n","import type { Character, CharacterRole } from \"./character\";\nimport type { ExternalLink, FuzzyDate } from \"./common\";\nimport type { MediaListStatus } from \"./lists\";\nimport type { Staff, VoiceActor } from \"./staff\";\nimport type { StudioConnection } from \"./studio\";\nimport type { UserAvatar } from \"./user\";\n\nexport enum MediaType {\n  ANIME = \"ANIME\",\n  MANGA = \"MANGA\",\n}\n\nexport enum MediaSource {\n  ORIGINAL = \"ORIGINAL\",\n  MANGA = \"MANGA\",\n  LIGHT_NOVEL = \"LIGHT_NOVEL\",\n  VISUAL_NOVEL = \"VISUAL_NOVEL\",\n  VIDEO_GAME = \"VIDEO_GAME\",\n  OTHER = \"OTHER\",\n  NOVEL = \"NOVEL\",\n  DOUJINSHI = \"DOUJINSHI\",\n  ANIME = \"ANIME\",\n  WEB_NOVEL = \"WEB_NOVEL\",\n  LIVE_ACTION = \"LIVE_ACTION\",\n  GAME = \"GAME\",\n  COMIC = \"COMIC\",\n  MULTIMEDIA_PROJECT = \"MULTIMEDIA_PROJECT\",\n  PICTURE_BOOK = \"PICTURE_BOOK\",\n}\n\nexport enum MediaFormat {\n  TV = \"TV\",\n  TV_SHORT = \"TV_SHORT\",\n  MOVIE = \"MOVIE\",\n  SPECIAL = \"SPECIAL\",\n  OVA = \"OVA\",\n  ONA = \"ONA\",\n  MUSIC = \"MUSIC\",\n  MANGA = \"MANGA\",\n  NOVEL = \"NOVEL\",\n  ONE_SHOT = \"ONE_SHOT\",\n}\n\nexport enum MediaStatus {\n  FINISHED = \"FINISHED\",\n  RELEASING = \"RELEASING\",\n  NOT_YET_RELEASED = \"NOT_YET_RELEASED\",\n  CANCELLED = \"CANCELLED\",\n  HIATUS = \"HIATUS\",\n}\n\nexport enum MediaSeason {\n  WINTER = \"WINTER\",\n  SPRING = \"SPRING\",\n  SUMMER = \"SUMMER\",\n  FALL = \"FALL\",\n}\n\nexport enum MediaSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  TITLE_ROMAJI = \"TITLE_ROMAJI\",\n  TITLE_ROMAJI_DESC = \"TITLE_ROMAJI_DESC\",\n  TITLE_ENGLISH = \"TITLE_ENGLISH\",\n  TITLE_ENGLISH_DESC = \"TITLE_ENGLISH_DESC\",\n  TITLE_NATIVE = \"TITLE_NATIVE\",\n  TITLE_NATIVE_DESC = \"TITLE_NATIVE_DESC\",\n  TYPE = \"TYPE\",\n  TYPE_DESC = \"TYPE_DESC\",\n  FORMAT = \"FORMAT\",\n  FORMAT_DESC = \"FORMAT_DESC\",\n  START_DATE = \"START_DATE\",\n  START_DATE_DESC = \"START_DATE_DESC\",\n  END_DATE = \"END_DATE\",\n  END_DATE_DESC = \"END_DATE_DESC\",\n  SCORE = \"SCORE\",\n  SCORE_DESC = \"SCORE_DESC\",\n  POPULARITY = \"POPULARITY\",\n  POPULARITY_DESC = \"POPULARITY_DESC\",\n  TRENDING = \"TRENDING\",\n  TRENDING_DESC = \"TRENDING_DESC\",\n  EPISODES = \"EPISODES\",\n  EPISODES_DESC = \"EPISODES_DESC\",\n  DURATION = \"DURATION\",\n  DURATION_DESC = \"DURATION_DESC\",\n  STATUS = \"STATUS\",\n  STATUS_DESC = \"STATUS_DESC\",\n  FAVOURITES = \"FAVOURITES\",\n  FAVOURITES_DESC = \"FAVOURITES_DESC\",\n  UPDATED_AT = \"UPDATED_AT\",\n  UPDATED_AT_DESC = \"UPDATED_AT_DESC\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n}\n\nexport enum AiringSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  MEDIA_ID = \"MEDIA_ID\",\n  MEDIA_ID_DESC = \"MEDIA_ID_DESC\",\n  TIME = \"TIME\",\n  TIME_DESC = \"TIME_DESC\",\n  EPISODE = \"EPISODE\",\n  EPISODE_DESC = \"EPISODE_DESC\",\n}\n\nexport interface MediaTitle {\n  romaji: string | null;\n  english: string | null;\n  native: string | null;\n  userPreferred: string | null;\n}\n\nexport interface MediaCoverImage {\n  extraLarge: string | null;\n  large: string | null;\n  medium: string | null;\n  color: string | null;\n}\n\nexport interface MediaTrailer {\n  id: string | null;\n  site: string | null;\n  thumbnail: string | null;\n}\n\nexport interface MediaTag {\n  id: number;\n  name: string;\n  description: string | null;\n  category: string | null;\n  rank: number | null;\n  isAdult: boolean | null;\n  isMediaSpoiler: boolean | null;\n}\n\nexport enum MediaRelationType {\n  ADAPTATION = \"ADAPTATION\",\n  PREQUEL = \"PREQUEL\",\n  SEQUEL = \"SEQUEL\",\n  PARENT = \"PARENT\",\n  SIDE_STORY = \"SIDE_STORY\",\n  CHARACTER = \"CHARACTER\",\n  SUMMARY = \"SUMMARY\",\n  ALTERNATIVE = \"ALTERNATIVE\",\n  SPIN_OFF = \"SPIN_OFF\",\n  OTHER = \"OTHER\",\n  SOURCE = \"SOURCE\",\n  COMPILATION = \"COMPILATION\",\n  CONTAINS = \"CONTAINS\",\n}\n\nexport interface MediaEdge {\n  relationType: MediaRelationType;\n  node: Pick<\n    Media,\n    | \"id\"\n    | \"title\"\n    | \"type\"\n    | \"format\"\n    | \"status\"\n    | \"description\"\n    | \"startDate\"\n    | \"endDate\"\n    | \"season\"\n    | \"seasonYear\"\n    | \"episodes\"\n    | \"chapters\"\n    | \"volumes\"\n    | \"coverImage\"\n    | \"genres\"\n    | \"averageScore\"\n    | \"meanScore\"\n    | \"studios\"\n    | \"siteUrl\"\n    | \"nextAiringEpisode\"\n  >;\n}\n\nexport interface MediaConnection {\n  edges: MediaEdge[];\n}\n\nexport interface MediaCharacterEdge {\n  role: CharacterRole;\n  node: Omit<Character, \"media\">;\n  voiceActors?: VoiceActor[];\n}\n\nexport interface MediaCharacterConnection {\n  edges: MediaCharacterEdge[];\n}\n\nexport interface MediaStaffEdge {\n  role: string;\n  node: Staff;\n}\n\nexport interface MediaStaffConnection {\n  edges: MediaStaffEdge[];\n}\n\nexport interface StreamingEpisode {\n  title: string | null;\n  thumbnail: string | null;\n  url: string | null;\n  site: string | null;\n}\n\nexport interface ScoreDistribution {\n  score: number;\n  amount: number;\n}\n\nexport interface StatusDistribution {\n  status: MediaListStatus;\n  amount: number;\n}\n\nexport interface MediaStats {\n  scoreDistribution: ScoreDistribution[];\n  statusDistribution: StatusDistribution[];\n}\n\nexport interface MediaRecommendationNode {\n  id: number;\n  rating: number | null;\n  mediaRecommendation: Pick<\n    Media,\n    | \"id\"\n    | \"title\"\n    | \"type\"\n    | \"format\"\n    | \"status\"\n    | \"description\"\n    | \"coverImage\"\n    | \"averageScore\"\n    | \"meanScore\"\n    | \"episodes\"\n    | \"chapters\"\n    | \"volumes\"\n    | \"nextAiringEpisode\"\n    | \"season\"\n    | \"seasonYear\"\n    | \"startDate\"\n    | \"endDate\"\n    | \"studios\"\n    | \"genres\"\n    | \"siteUrl\"\n  >;\n}\n\nexport interface NextAiringEpisode {\n  id: number;\n  airingAt: number;\n  episode: number;\n  mediaId: number;\n  timeUntilAiring: number;\n}\n\nexport interface Media {\n  id: number;\n  idMal: number | null;\n  title: MediaTitle;\n  type: MediaType;\n  format: MediaFormat | null;\n  status: MediaStatus | null;\n  description: string | null;\n  startDate: FuzzyDate | null;\n  endDate: FuzzyDate | null;\n  season: MediaSeason | null;\n  seasonYear: number | null;\n  episodes: number | null;\n  duration: number | null;\n  chapters: number | null;\n  volumes: number | null;\n  countryOfOrigin: string | null;\n  isLicensed: boolean | null;\n  source: MediaSource | null;\n  hashtag: string | null;\n  trailer: MediaTrailer | null;\n  coverImage: MediaCoverImage;\n  bannerImage: string | null;\n  genres: string[];\n  synonyms: string[];\n  averageScore: number | null;\n  meanScore: number | null;\n  popularity: number | null;\n  favourites: number | null;\n  trending: number | null;\n  tags: MediaTag[];\n  studios: StudioConnection;\n  relations: MediaConnection | null;\n  characters?: MediaCharacterConnection;\n  staff?: MediaStaffConnection;\n  streamingEpisodes?: StreamingEpisode[];\n  externalLinks?: ExternalLink[];\n  stats?: MediaStats;\n  recommendations?: { nodes: MediaRecommendationNode[] };\n  nextAiringEpisode: NextAiringEpisode | null;\n  isAdult: boolean | null;\n  siteUrl: string | null;\n}\n\nexport interface SearchMediaOptions {\n  /** Search Term */\n  query?: string;\n  /** Filter by country code (e.g., \"JP\", \"KR\") */\n  countryOfOrigin?: string;\n  /** Filter by Anime or Manga */\n  type?: MediaType;\n  /** Filter by format (For multiple formats: [MediaFormat.TV]) */\n  format?: MediaFormat | MediaFormat[];\n  /** Filter by status of Media */\n  status?: MediaStatus;\n  /** Filter by Season (Winter, Spring, Summer, Fall) */\n  season?: MediaSeason;\n  /** Filter by Year */\n  seasonYear?: number;\n  /** Single genre filter (kept for backward compat) */\n  genre?: string;\n  /** Single tag filter (kept for backward compat) */\n  tag?: string;\n  /** Filter by multiple genres (media must match ALL) */\n  genres?: string[];\n  /** Filter by multiple tags (media must match ALL) */\n  tags?: string[];\n  /** Exclude media with any of these genres */\n  genresExclude?: string[];\n  /** Exclude media with any of these tags */\n  tagsExclude?: string[];\n  /** Include or Exclude explicit content (default: false) */\n  isAdult?: boolean;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Sort order */\n  sort?: MediaSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\nexport interface GeneralMediaQueryOptions {\n  /** Filter by Anime or Manga */\n  type?: MediaType;\n  /** Include or Exclude explicit content (default: false) */\n  isAdult?: boolean;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\nexport interface GetAiringOptions {\n  /** Only show episodes that aired after this UNIX timestamp */\n  airingAtGreater?: number;\n  /** Only show episodes that aired before this UNIX timestamp */\n  airingAtLesser?: number;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Sort order (default: TIME_DESC) */\n  sort?: AiringSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\nexport interface GetRecentChaptersOptions {\n  /** Include or Exclude explicit content (default: false) */\n  isAdult?: boolean;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Page number (default: 1) */\n  page?: number;\n  /** Results per page (default: 20, max 50) */\n  perPage?: number;\n}\n\nexport interface GetPlanningOptions {\n  /** Filter by ANIME or MANGA (returns both if omitted) */\n  type?: MediaType;\n  /** Include or Exclude explicit content (default: false) */\n  isAdult?: boolean;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Sort order (default: POPULARITY_DESC) */\n  sort?: MediaSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\nexport enum RecommendationSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  RATING = \"RATING\",\n  RATING_DESC = \"RATING_DESC\",\n}\n\nexport interface Recommendation {\n  id: number;\n  rating: number | null;\n  userRating: string | null;\n  mediaRecommendation: Media;\n  user: {\n    id: number;\n    name: string;\n    avatar: UserAvatar;\n  } | null;\n}\n\nexport interface GetRecommendationsOptions {\n  /** The AniList media ID to get recommendations for */\n  mediaId: number;\n  /** Sort order (default: RATING_DESC) */\n  sort?: RecommendationSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\nexport interface GetSeasonOptions {\n  /** The season (WINTER, SPRING, SUMMER, FALL) */\n  season: MediaSeason;\n  /** The year */\n  seasonYear: number;\n  /** Filter by ANIME or MANGA (defaults to ANIME) */\n  type?: MediaType;\n  /** Allow or disallow explicit content (defaults to False) */\n  isAdult?: boolean;\n  /** Exclude certain media entries by ID */\n  idNotIn?: number[];\n  /** Sort order (default: POPULARITY_DESC) */\n  sort?: MediaSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n\n/**\n * Options to include additional related data when fetching a media entry.\n * Pass `true` to include with defaults, or an object to customize.\n */\nexport interface MediaIncludeOptions {\n  /** Include characters with their roles (MAIN, SUPPORTING, BACKGROUND).\n   *  `true` = 25 results sorted by role. Object form to customize. */\n  characters?: boolean | { perPage?: number; sort?: boolean; voiceActors?: boolean };\n  /** Include staff members with their roles.\n   *  `true` = 25 results sorted by relevance. Object form to customize. */\n  staff?: boolean | { perPage?: number; sort?: boolean };\n  /** Include relations (default: `true` for backward compat). Set to `false` to exclude. */\n  relations?: boolean;\n  /** Include streaming episode links (Crunchyroll, Funimation, etc.) */\n  streamingEpisodes?: boolean;\n  /** Include external links (MAL, official site, etc.) */\n  externalLinks?: boolean;\n  /** Include score & status distribution stats */\n  stats?: boolean;\n  /** Include user recommendations. `true` = 10 results, or customize with `{ perPage }`. */\n  recommendations?: boolean | { perPage?: number };\n  /** Raw GraphQL fields to append to the query (e.g. for custom data) */\n  customFields?: string;\n}\n\nexport interface GetMediaCharactersOptions {\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n  /** Disable default sort order */\n  sort?: boolean;\n  /** Include voice actors for each character edge */\n  voiceActors?: boolean;\n}\n\nexport interface GetMediaStaffOptions {\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n  /** Disable default sort order */\n  sort?: boolean;\n}\n\nexport interface AiringSchedule {\n  id: number;\n  airingAt: number;\n  timeUntilAiring: number;\n  episode: number;\n  mediaId: number;\n  media: Media;\n}\n\nexport type DayOfWeek = \"Monday\" | \"Tuesday\" | \"Wednesday\" | \"Thursday\" | \"Friday\" | \"Saturday\" | \"Sunday\";\n\nexport type WeeklySchedule = Record<DayOfWeek, AiringSchedule[]>;\n","import type { Media } from \"./media\";\nimport type { User } from \"./user\";\n\nexport enum ReviewSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  SCORE = \"SCORE\",\n  SCORE_DESC = \"SCORE_DESC\",\n  RATING = \"RATING\",\n  RATING_DESC = \"RATING_DESC\",\n  CREATED_AT = \"CREATED_AT\",\n  CREATED_AT_DESC = \"CREATED_AT_DESC\",\n  UPDATED_AT = \"UPDATED_AT\",\n  UPDATED_AT_DESC = \"UPDATED_AT_DESC\",\n}\n\nexport interface Review {\n  id: number;\n  userId: number;\n  mediaId: number;\n  mediaType: \"ANIME\" | \"MANGA\";\n  summary: string;\n  body: string;\n  rating: number;\n  ratingAmount: number;\n  userRating: \"UP_VOTE\" | \"DOWN_VOTE\" | \"NO_VOTE\";\n  score: number;\n  private: boolean;\n  siteUrl: string;\n  createdAt: number;\n  updatedAt: number;\n  user: User;\n  media: Media;\n}\n\nexport interface SearchReviewOptions {\n  mediaId?: number;\n  userId?: number;\n  sort?: ReviewSort[];\n  page?: number;\n  perPage?: number;\n}\n","import type { FuzzyDate } from \"./common\";\nimport type { MediaCoverImage, MediaFormat, MediaSeason, MediaStatus, MediaTitle, MediaType } from \"./media\";\n\nexport enum StaffSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  ROLE = \"ROLE\",\n  ROLE_DESC = \"ROLE_DESC\",\n  LANGUAGE = \"LANGUAGE\",\n  LANGUAGE_DESC = \"LANGUAGE_DESC\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n  FAVOURITES = \"FAVOURITES\",\n  FAVOURITES_DESC = \"FAVOURITES_DESC\",\n  RELEVANCE = \"RELEVANCE\",\n}\n\nexport interface StaffName {\n  first: string | null;\n  middle: string | null;\n  last: string | null;\n  full: string | null;\n  native: string | null;\n}\n\nexport interface StaffImage {\n  large: string | null;\n  medium: string | null;\n}\n\n/** A media node returned inside `Staff.staffMedia`. */\nexport interface StaffMediaNode {\n  id: number;\n  title: MediaTitle;\n  type: MediaType;\n  format: MediaFormat | null;\n  status: MediaStatus | null;\n  coverImage: MediaCoverImage;\n  bannerImage: string | null;\n  genres: string[];\n  averageScore: number | null;\n  meanScore: number | null;\n  popularity: number | null;\n  favourites: number | null;\n  episodes: number | null;\n  trending: number | null;\n  hashtag: string | null;\n  season: MediaSeason | null;\n  seasonYear: number | null;\n  startDate: FuzzyDate | null;\n  endDate: FuzzyDate | null;\n  nextAiringEpisode: {\n    id: number;\n    airingAt: number;\n    episode: number;\n    mediaId: number;\n    timeUntilAiring: number;\n  } | null;\n  studios: { edges: { node: { name: string } }[] } | null;\n  siteUrl: string | null;\n}\n\nexport interface Staff {\n  id: number;\n  name: StaffName;\n  language: string | null;\n  image: StaffImage;\n  description: string | null;\n  primaryOccupations: string[];\n  gender: string | null;\n  dateOfBirth: FuzzyDate | null;\n  dateOfDeath: FuzzyDate | null;\n  age: string | null;\n  yearsActive: number[];\n  homeTown: string | null;\n  bloodType: string | null;\n  favourites: number | null;\n  siteUrl: string | null;\n  /** Media the staff member has worked on — only present when requested via include options. */\n  staffMedia?: {\n    nodes: StaffMediaNode[];\n  } | null;\n}\n\n/** Options to include additional related data when fetching a staff member by ID. */\nexport interface StaffIncludeOptions {\n  /** Include character roles (voice acting) for each media the staff member worked on. */\n  characterRoles?: boolean;\n  /** Raw GraphQL fields to append to the query (e.g. for custom data) */\n  customFields?: string;\n  /** Include media the staff member has worked on.\n   *  `true` = 25 results sorted by popularity. Object form to customize. */\n  media?: boolean | { perPage?: number; sort?: boolean };\n}\n\nexport interface SearchStaffOptions {\n  query?: string;\n  sort?: StaffSort[];\n  page?: number;\n  perPage?: number;\n}\n\n/** Compact voice actor data returned inside character edges. */\nexport interface VoiceActor extends Pick<Staff, \"id\" | \"image\" | \"gender\" | \"primaryOccupations\" | \"siteUrl\"> {\n  name: StaffName & { userPreferred: string | null };\n  languageV2: string | null;\n}\n","import type { PageInfo } from \"./common\";\nimport type { Media } from \"./media\";\n\nexport interface Studio {\n  id: number;\n  name: string;\n  isAnimationStudio: boolean;\n  siteUrl: string | null;\n  favourites?: number | null;\n  media?: {\n    pageInfo: PageInfo;\n    nodes: Pick<Media, \"id\" | \"title\" | \"type\" | \"format\" | \"coverImage\" | \"siteUrl\">[];\n  } | null;\n}\n\nexport interface StudioConnection {\n  nodes: Studio[];\n}\n\nexport enum StudioSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  NAME = \"NAME\",\n  NAME_DESC = \"NAME_DESC\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n  FAVOURITES = \"FAVOURITES\",\n  FAVOURITES_DESC = \"FAVOURITES_DESC\",\n}\n\nexport interface SearchStudioOptions {\n  query?: string;\n  sort?: StudioSort[];\n  page?: number;\n  perPage?: number;\n}\n\n/**\n * Options for controlling embedded media when fetching a single studio.\n * Pass `{ media: { perPage: 50 } }` to fetch more media per studio.\n */\nexport interface StudioIncludeOptions {\n  /** Include the media produced by this studio. */\n  media?: boolean | { perPage?: number; isMain?: boolean; sort?: boolean };\n  /** Raw GraphQL fields to append to the query (e.g. for custom data) */\n  customFields?: string;\n}\n","import type { MediaCoverImage, MediaTitle, MediaType } from \"./media\";\nimport type { UserAvatar } from \"./user\";\n\n/** Represents a forum thread on AniList. */\nexport interface Thread {\n  id: number;\n  title: string;\n  body: string | null;\n  userId: number;\n  replyUserId: number | null;\n  replyCommentId: number | null;\n  replyCount: number;\n  viewCount: number;\n  isLocked: boolean;\n  isSticky: boolean;\n  isSubscribed: boolean;\n  repliedAt: number | null;\n  createdAt: number;\n  updatedAt: number;\n  siteUrl: string | null;\n  user: {\n    id: number;\n    name: string;\n    avatar: UserAvatar;\n  } | null;\n  replyUser: {\n    id: number;\n    name: string;\n    avatar: UserAvatar;\n  } | null;\n  categories: ThreadCategory[] | null;\n  mediaCategories: ThreadMediaCategory[] | null;\n  likes: { id: number; name: string }[] | null;\n}\n\nexport interface ThreadCategory {\n  id: number;\n  name: string;\n}\n\nexport interface ThreadMediaCategory {\n  id: number;\n  title: MediaTitle;\n  type: MediaType;\n  coverImage: Pick<MediaCoverImage, \"large\" | \"medium\"> | null;\n  siteUrl: string | null;\n}\n\n/** Sort options for thread queries. */\nexport enum ThreadSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  TITLE = \"TITLE\",\n  TITLE_DESC = \"TITLE_DESC\",\n  CREATED_AT = \"CREATED_AT\",\n  CREATED_AT_DESC = \"CREATED_AT_DESC\",\n  UPDATED_AT = \"UPDATED_AT\",\n  UPDATED_AT_DESC = \"UPDATED_AT_DESC\",\n  REPLIED_AT = \"REPLIED_AT\",\n  REPLIED_AT_DESC = \"REPLIED_AT_DESC\",\n  REPLY_COUNT = \"REPLY_COUNT\",\n  REPLY_COUNT_DESC = \"REPLY_COUNT_DESC\",\n  VIEW_COUNT = \"VIEW_COUNT\",\n  VIEW_COUNT_DESC = \"VIEW_COUNT_DESC\",\n  IS_STICKY = \"IS_STICKY\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n}\n\n/** Options for searching/listing threads. */\nexport interface SearchThreadOptions {\n  /** Search query */\n  query?: string;\n  /** Filter by media ID */\n  mediaId?: number;\n  /** Filter by category ID */\n  categoryId?: number;\n  /** Sort order */\n  sort?: ThreadSort[];\n  /** Page number */\n  page?: number;\n  /** Results per page (max 50) */\n  perPage?: number;\n}\n","import type { MediaCoverImage, MediaFormat, MediaTitle, MediaType } from \"./media\";\n\nexport enum UserSort {\n  ID = \"ID\",\n  ID_DESC = \"ID_DESC\",\n  USERNAME = \"USERNAME\",\n  USERNAME_DESC = \"USERNAME_DESC\",\n  WATCHED_TIME = \"WATCHED_TIME\",\n  WATCHED_TIME_DESC = \"WATCHED_TIME_DESC\",\n  CHAPTERS_READ = \"CHAPTERS_READ\",\n  CHAPTERS_READ_DESC = \"CHAPTERS_READ_DESC\",\n  SEARCH_MATCH = \"SEARCH_MATCH\",\n}\n\nexport interface UserAvatar {\n  large: string | null;\n  medium: string | null;\n}\n\nexport interface UserStatistics {\n  count: number;\n  meanScore: number;\n  minutesWatched: number;\n  episodesWatched: number;\n  chaptersRead: number;\n  volumesRead: number;\n}\n\nexport interface User {\n  id: number;\n  name: string;\n  about: string | null;\n  avatar: UserAvatar;\n  bannerImage: string | null;\n  isFollowing: boolean | null;\n  isFollower: boolean | null;\n  donatorTier: number | null;\n  donatorBadge: string | null;\n  createdAt: number | null;\n  siteUrl: string | null;\n  statistics: {\n    anime: UserStatistics;\n    manga: UserStatistics;\n  } | null;\n}\n\nexport interface SearchUserOptions {\n  query?: string;\n  sort?: UserSort[];\n  page?: number;\n  perPage?: number;\n}\n\nexport interface FavoriteMediaNode {\n  id: number;\n  title: MediaTitle;\n  coverImage: Pick<MediaCoverImage, \"large\" | \"medium\">;\n  type: MediaType | null;\n  format: MediaFormat | null;\n  siteUrl: string | null;\n}\n\nexport interface FavoriteCharacterNode {\n  id: number;\n  name: { full: string | null; native: string | null };\n  image: { large: string | null; medium: string | null };\n  siteUrl: string | null;\n}\n\nexport interface FavoriteStaffNode {\n  id: number;\n  name: { full: string | null; native: string | null };\n  image: { large: string | null; medium: string | null };\n  siteUrl: string | null;\n}\n\nexport interface FavoriteStudioNode {\n  id: number;\n  name: string;\n  siteUrl: string | null;\n}\n\nexport interface UserFavorites {\n  anime: FavoriteMediaNode[];\n  manga: FavoriteMediaNode[];\n  characters: FavoriteCharacterNode[];\n  staff: FavoriteStaffNode[];\n  studios: FavoriteStudioNode[];\n}\n\n/**\n * Options for controlling the number of results when fetching user favorites.\n */\nexport interface UserFavoritesOptions {\n  /** Number of items per category (default: 25, max: 50). */\n  perPage?: number;\n}\n","import {\n  buildGetMediaBySeasonQuery,\n  buildGetPlanningQuery,\n  buildGetRecentlyUpdatedMangaQuery,\n  buildGetTrendingQuery,\n  buildMediaByIdQuery,\n  buildMediaCharactersQuery,\n  buildMediaStaffQuery,\n  buildSearchMediaQuery,\n  QUERY_AIRING_SCHEDULE,\n  QUERY_MEDIA_BY_MAL_ID,\n  QUERY_RECOMMENDATIONS,\n} from \"../queries\";\nimport type {\n  AiringSchedule,\n  DayOfWeek,\n  GeneralMediaQueryOptions,\n  GetAiringOptions,\n  GetMediaCharactersOptions,\n  GetMediaStaffOptions,\n  GetPlanningOptions,\n  GetRecentChaptersOptions,\n  GetRecommendationsOptions,\n  GetSeasonOptions,\n  Media,\n  MediaCharacterEdge,\n  MediaIncludeOptions,\n  MediaStaffEdge,\n  PagedResult,\n  PageInfo,\n  Recommendation,\n  SearchMediaOptions,\n  WeeklySchedule,\n} from \"../types\";\nimport { MediaSort, MediaType } from \"../types\";\n\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a single media entry by AniList ID with optional includes. */\nexport async function getMedia(client: ClientBase, id: number, include?: MediaIncludeOptions): Promise<Media> {\n  validateId(id, \"mediaId\");\n  const query = buildMediaByIdQuery(include);\n  const data = await client.request<{ Media: Media }>(query, { id });\n  return data.Media;\n}\n\n/** @internal Fetch paginated characters for a media entry. */\nexport async function getMediaCharacters(\n  client: ClientBase,\n  mediaId: number,\n  options: GetMediaCharactersOptions = {},\n): Promise<PagedResult<MediaCharacterEdge>> {\n  validateId(mediaId, \"mediaId\");\n  const query = buildMediaCharactersQuery(options);\n  const data = await client.request<{ Media: { characters: { pageInfo: PageInfo; edges: MediaCharacterEdge[] } } }>(\n    query,\n    { mediaId, page: options.page ?? 1, perPage: clampPerPage(options.perPage ?? 25) },\n  );\n\n  return { pageInfo: data.Media.characters.pageInfo, results: data.Media.characters.edges };\n}\n\n/** @internal Fetch paginated staff for a media entry. */\nexport async function getMediaStaff(\n  client: ClientBase,\n  mediaId: number,\n  options: GetMediaStaffOptions = {},\n): Promise<PagedResult<MediaStaffEdge>> {\n  validateId(mediaId, \"mediaId\");\n  const query = buildMediaStaffQuery(options);\n  const data = await client.request<{ Media: { staff: { pageInfo: PageInfo; edges: MediaStaffEdge[] } } }>(query, {\n    mediaId,\n    page: options.page ?? 1,\n    perPage: clampPerPage(options.perPage ?? 25),\n  });\n\n  return { pageInfo: data.Media.staff.pageInfo, results: data.Media.staff.edges };\n}\n\n/** @internal Fetch a media entry by its MyAnimeList ID. */\nexport async function getMediaByMalId(client: ClientBase, malId: number, type?: MediaType): Promise<Media> {\n  validateId(malId, \"malId\");\n  const data = await client.request<{ Media: Media }>(QUERY_MEDIA_BY_MAL_ID, {\n    idMal: malId,\n    type,\n  });\n  return data.Media;\n}\n\n/** @internal Search for anime or manga with optional filters. */\nexport async function searchMedia(\n  client: ClientBase,\n  options: SearchMediaOptions = {},\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const {\n    query: search,\n    page = 1,\n    perPage = 20,\n    genres,\n    tags,\n    genresExclude,\n    tagsExclude,\n    format,\n    ...filters\n  } = options;\n  const query = buildSearchMediaQuery(include);\n  return client.pagedRequest<Media>(\n    query,\n    {\n      search,\n      ...filters,\n      format: Array.isArray(format) ? undefined : format,\n      format_in: Array.isArray(format) ? format : undefined,\n      genre_in: genres,\n      tag_in: tags,\n      genre_not_in: genresExclude,\n      tag_not_in: tagsExclude,\n      page,\n      perPage: clampPerPage(perPage),\n    },\n    \"media\",\n  );\n}\n\n/** @internal Get currently trending anime or manga. */\nexport async function getTrending(\n  client: ClientBase,\n  options: GeneralMediaQueryOptions,\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const { type = MediaType.ANIME, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;\n  const query = buildGetTrendingQuery(include);\n  return client.pagedRequest<Media>(query, { type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) }, \"media\");\n}\n\n/** @internal Get the most popular anime or manga. */\nexport async function getPopular(\n  client: ClientBase,\n  options: GeneralMediaQueryOptions,\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const { type = MediaType.ANIME, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;\n  return searchMedia(client, { type, isAdult, idNotIn, sort: [MediaSort.POPULARITY_DESC], page, perPage }, include);\n}\n\n/** @internal Get the highest-rated anime or manga. */\nexport async function getTopRated(\n  client: ClientBase,\n  options: GeneralMediaQueryOptions,\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const { type = MediaType.ANIME, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;\n  return searchMedia(client, { type, isAdult, idNotIn, sort: [MediaSort.SCORE_DESC], page, perPage }, include);\n}\n\n/** @internal Get recently aired anime episodes. */\nexport async function getAiredEpisodes(\n  client: ClientBase,\n  options: GetAiringOptions = {},\n): Promise<PagedResult<AiringSchedule>> {\n  const now = Math.floor(Date.now() / 1000);\n  return client.pagedRequest<AiringSchedule>(\n    QUERY_AIRING_SCHEDULE,\n    {\n      airingAt_greater: options.airingAtGreater ?? now - 24 * 3600,\n      airingAt_lesser: options.airingAtLesser ?? now,\n      idNotIn: options.idNotIn ?? [],\n      sort: options.sort,\n      page: options.page ?? 1,\n      perPage: clampPerPage(options.perPage ?? 20),\n    },\n    \"airingSchedules\",\n  );\n}\n\n/** @internal Get currently releasing manga sorted by last update. */\nexport async function getRecentlyUpdatedManga(\n  client: ClientBase,\n  options: GetRecentChaptersOptions = {},\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const query = buildGetRecentlyUpdatedMangaQuery(include);\n  return client.pagedRequest<Media>(\n    query,\n    {\n      isAdult: options.isAdult ?? false,\n      idNotIn: options.idNotIn ?? [],\n      page: options.page ?? 1,\n      perPage: clampPerPage(options.perPage ?? 20),\n    },\n    \"media\",\n  );\n}\n\n/** @internal Get upcoming (not yet released) media. */\nexport async function getPlanning(\n  client: ClientBase,\n  options: GetPlanningOptions = {},\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const query = buildGetPlanningQuery(include);\n  return client.pagedRequest<Media>(\n    query,\n    {\n      type: options.type,\n      isAdult: options.isAdult ?? false,\n      idNotIn: options.idNotIn ?? [],\n      sort: options.sort ?? [MediaSort.POPULARITY_DESC],\n      page: options.page ?? 1,\n      perPage: clampPerPage(options.perPage ?? 20),\n    },\n    \"media\",\n  );\n}\n\n/** @internal Get user recommendations for a specific media entry. */\nexport async function getRecommendations(\n  client: ClientBase,\n  mediaId: number,\n  options: Omit<GetRecommendationsOptions, \"mediaId\"> = {},\n): Promise<PagedResult<Recommendation>> {\n  validateId(mediaId, \"mediaId\");\n  const data = await client.request<{\n    Media: {\n      recommendations: {\n        pageInfo: { total: number; perPage: number; currentPage: number; lastPage: number; hasNextPage: boolean };\n        nodes: Recommendation[];\n      };\n    };\n  }>(QUERY_RECOMMENDATIONS, {\n    mediaId,\n    page: options.page ?? 1,\n    perPage: clampPerPage(options.perPage ?? 20),\n    sort: options.sort,\n  });\n\n  return {\n    pageInfo: data.Media.recommendations.pageInfo,\n    results: data.Media.recommendations.nodes,\n  };\n}\n\n/** @internal Get anime or manga for a specific season and year. */\nexport async function getMediaBySeason(\n  client: ClientBase,\n  options: GetSeasonOptions,\n  include?: MediaIncludeOptions,\n): Promise<PagedResult<Media>> {\n  const query = buildGetMediaBySeasonQuery(include);\n  return client.pagedRequest<Media>(\n    query,\n    {\n      season: options.season,\n      seasonYear: options.seasonYear,\n      type: options.type,\n      isAdult: options.isAdult ?? false,\n      idNotIn: options.idNotIn ?? [],\n      sort: options.sort,\n      page: options.page ?? 1,\n      perPage: clampPerPage(options.perPage ?? 20),\n    },\n    \"media\",\n  );\n}\n\n/** @internal Get the detailed airing schedule for a given week, grouped by day. */\nexport async function getWeeklySchedule(\n  client: ClientBase,\n  date: Date = new Date(),\n  idNotIn?: number[],\n): Promise<WeeklySchedule> {\n  const schedule: WeeklySchedule = {\n    Monday: [],\n    Tuesday: [],\n    Wednesday: [],\n    Thursday: [],\n    Friday: [],\n    Saturday: [],\n    Sunday: [],\n  };\n\n  const utcDay = date.getUTCDay();\n  const diff = utcDay === 0 ? -6 : 1 - utcDay;\n  const startOfWeek = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + diff, 0, 0, 0));\n\n  const endOfWeek = new Date(startOfWeek);\n  endOfWeek.setUTCDate(startOfWeek.getUTCDate() + 6);\n  endOfWeek.setUTCHours(23, 59, 59, 999);\n\n  const startTimestamp = Math.floor(startOfWeek.getTime() / 1000);\n  const endTimestamp = Math.floor(endOfWeek.getTime() / 1000);\n\n  const iterator = client.paginate(\n    (page) =>\n      getAiredEpisodes(client, {\n        airingAtGreater: startTimestamp,\n        airingAtLesser: endTimestamp,\n        idNotIn,\n        page,\n        perPage: 50,\n      }),\n    20,\n  );\n\n  const names: DayOfWeek[] = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n\n  for await (const episode of iterator) {\n    const epDate = new Date(episode.airingAt * 1000);\n    const dayName = names[epDate.getUTCDay()];\n    if (dayName) schedule[dayName].push(episode);\n  }\n\n  return schedule;\n}\n","import { QUERY_REVIEW_BY_ID, QUERY_REVIEWS } from \"../queries\";\n\nimport type { PagedResult, Review, SearchReviewOptions } from \"../types\";\n\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a review by AniList ID. */\nexport async function getReview(client: ClientBase, id: number): Promise<Review> {\n  validateId(id, \"reviewId\");\n  const data = await client.request<{ Review: Review }>(QUERY_REVIEW_BY_ID, { id });\n  return data.Review;\n}\n\n/** @internal Search for reviews with optional media, user, and sort filters. */\nexport async function searchReviews(\n  client: ClientBase,\n  options: SearchReviewOptions = {},\n): Promise<PagedResult<Review>> {\n  const { mediaId, userId, sort, page = 1, perPage = 20 } = options;\n  return client.pagedRequest<Review>(\n    QUERY_REVIEWS,\n    { mediaId, userId, sort, page, perPage: clampPerPage(perPage) },\n    \"reviews\",\n  );\n}\n","import { QUERY_STAFF_SEARCH } from \"../queries\";\nimport { buildStaffByIdQuery } from \"../queries/staff\";\nimport type { PagedResult, SearchStaffOptions, Staff, StaffIncludeOptions } from \"../types\";\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a staff member by AniList ID, optionally including media credits. */\nexport async function getStaff(client: ClientBase, id: number, include?: StaffIncludeOptions): Promise<Staff> {\n  validateId(id, \"staffId\");\n  const query = buildStaffByIdQuery(include);\n  if (include?.characterRoles || include?.media) {\n    const perPage = typeof include.media === \"object\" ? (include.media.perPage ?? 25) : 25;\n    const data = await client.request<{ Staff: Staff }>(query, { id, perPage });\n    return data.Staff;\n  }\n  const data = await client.request<{ Staff: Staff }>(query, { id });\n  return data.Staff;\n}\n\n/** @internal Search for staff (voice actors, directors, etc.) by name. */\nexport async function searchStaff(client: ClientBase, options: SearchStaffOptions = {}): Promise<PagedResult<Staff>> {\n  const { query: search, page = 1, perPage = 20, sort } = options;\n  return client.pagedRequest<Staff>(\n    QUERY_STAFF_SEARCH,\n    { search, sort, page, perPage: clampPerPage(perPage) },\n    \"staff\",\n  );\n}\n","import { buildStudioByIdQuery, QUERY_STUDIO_SEARCH } from \"../queries\";\n\nimport type { PagedResult, SearchStudioOptions, Studio, StudioIncludeOptions } from \"../types\";\n\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a studio by AniList ID, optionally including its media catalogue. */\nexport async function getStudio(client: ClientBase, id: number, include?: StudioIncludeOptions): Promise<Studio> {\n  validateId(id, \"studioId\");\n  const query = buildStudioByIdQuery(include);\n  const data = await client.request<{ Studio: Studio }>(query, { id });\n  return data.Studio;\n}\n\n/** @internal Search for animation studios by name. */\nexport async function searchStudios(\n  client: ClientBase,\n  options: SearchStudioOptions = {},\n): Promise<PagedResult<Studio>> {\n  const { query: search, page = 1, perPage = 20, sort } = options;\n  return client.pagedRequest<Studio>(\n    QUERY_STUDIO_SEARCH,\n    {\n      search,\n      sort,\n      page,\n      perPage: clampPerPage(perPage),\n    },\n    \"studios\",\n  );\n}\n","import { QUERY_THREAD_BY_ID, QUERY_THREAD_SEARCH } from \"../queries\";\nimport type { PagedResult, SearchThreadOptions, Thread } from \"../types\";\nimport { ThreadSort } from \"../types\";\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a forum thread by AniList ID. */\nexport async function getThread(client: ClientBase, id: number): Promise<Thread> {\n  validateId(id, \"threadId\");\n  const data = await client.request<{ Thread: Thread }>(QUERY_THREAD_BY_ID, { id });\n  return data.Thread;\n}\n\n/** @internal Get recent forum threads with optional search, media, and category filters. */\nexport async function getRecentThreads(\n  client: ClientBase,\n  options: SearchThreadOptions = {},\n): Promise<PagedResult<Thread>> {\n  const { query: search, page = 1, perPage = 20, sort, mediaId, categoryId } = options;\n  return client.pagedRequest<Thread>(\n    QUERY_THREAD_SEARCH,\n    {\n      search,\n      mediaCategoryId: mediaId,\n      categoryId,\n      sort: sort ?? [ThreadSort.REPLIED_AT_DESC],\n      page,\n      perPage: clampPerPage(perPage),\n    },\n    \"threads\",\n  );\n}\n","import {\n  buildUserFavoritesQuery,\n  QUERY_USER_BY_ID,\n  QUERY_USER_BY_NAME,\n  QUERY_USER_FAVORITES_BY_ID,\n  QUERY_USER_FAVORITES_BY_NAME,\n  QUERY_USER_MEDIA_LIST,\n  QUERY_USER_SEARCH,\n} from \"../queries\";\nimport type {\n  GetUserMediaListOptions,\n  MediaListEntry,\n  PagedResult,\n  SearchUserOptions,\n  User,\n  UserFavorites,\n  UserFavoritesOptions,\n} from \"../types\";\nimport { clampPerPage, validateId } from \"../utils\";\nimport type { ClientBase } from \"./base\";\n\n/** @internal Fetch a user by AniList ID or username. */\nexport async function getUser(client: ClientBase, idOrName: number | string): Promise<User> {\n  if (typeof idOrName === \"number\") {\n    validateId(idOrName, \"userId\");\n    const data = await client.request<{ User: User }>(QUERY_USER_BY_ID, { id: idOrName });\n    return data.User;\n  }\n  const data = await client.request<{ User: User }>(QUERY_USER_BY_NAME, { name: idOrName });\n  return data.User;\n}\n\n/** @internal Search for AniList users by name. */\nexport async function searchUsers(client: ClientBase, options: SearchUserOptions = {}): Promise<PagedResult<User>> {\n  const { query: search, page = 1, perPage = 20, sort } = options;\n  return client.pagedRequest<User>(QUERY_USER_SEARCH, { search, sort, page, perPage: clampPerPage(perPage) }, \"users\");\n}\n\n/** @internal Get a user's anime or manga list with optional filters. */\nexport async function getUserMediaList(\n  client: ClientBase,\n  options: GetUserMediaListOptions,\n): Promise<PagedResult<MediaListEntry>> {\n  if (!options.userId && !options.userName) {\n    throw new TypeError(\"getUserMediaList requires either userId or userName\");\n  }\n  if (options.userId) {\n    validateId(options.userId, \"userId\");\n  }\n  return client.pagedRequest<MediaListEntry>(\n    QUERY_USER_MEDIA_LIST,\n    {\n      userId: options.userId,\n      userName: options.userName,\n      type: options.type,\n      status: options.status,\n      sort: options.sort,\n      page: options.page ?? 1,\n      perPage: clampPerPage(options.perPage ?? 20),\n    },\n    \"mediaList\",\n  );\n}\n\ninterface RawFavourites {\n  anime?: { nodes: UserFavorites[\"anime\"] };\n  manga?: { nodes: UserFavorites[\"manga\"] };\n  characters?: { nodes: UserFavorites[\"characters\"] };\n  staff?: { nodes: UserFavorites[\"staff\"] };\n  studios?: { nodes: UserFavorites[\"studios\"] };\n}\n\n/** @internal Fetch a user's favorite anime, manga, characters, staff, and studios. */\nexport async function getUserFavorites(\n  client: ClientBase,\n  idOrName: number | string,\n  options?: UserFavoritesOptions,\n): Promise<UserFavorites> {\n  const useBuilder = options?.perPage !== undefined;\n  if (typeof idOrName === \"number\") {\n    validateId(idOrName, \"userId\");\n    const query = useBuilder ? buildUserFavoritesQuery(\"id\", options.perPage) : QUERY_USER_FAVORITES_BY_ID;\n    const data = await client.request<{ User: { favourites: RawFavourites } }>(query, {\n      id: idOrName,\n    });\n    return mapFavorites(data.User.favourites);\n  }\n  const query = useBuilder ? buildUserFavoritesQuery(\"name\", options.perPage) : QUERY_USER_FAVORITES_BY_NAME;\n  const data = await client.request<{ User: { favourites: RawFavourites } }>(query, {\n    name: idOrName,\n  });\n  return mapFavorites(data.User.favourites);\n}\n\nfunction mapFavorites(fav: RawFavourites): UserFavorites {\n  return {\n    anime: fav.anime?.nodes ?? [],\n    manga: fav.manga?.nodes ?? [],\n    characters: fav.characters?.nodes ?? [],\n    staff: fav.staff?.nodes ?? [],\n    studios: fav.studios?.nodes ?? [],\n  };\n}\n","import { MemoryCache } from \"../cache\";\nimport { AniListError, type GraphQLError } from \"../errors\";\nimport {\n  buildBatchCharacterQuery,\n  buildBatchMediaQuery,\n  buildBatchStaffQuery,\n  QUERY_GENRES,\n  QUERY_TAGS,\n} from \"../queries\";\nimport { RateLimiter } from \"../rate-limiter\";\nimport type {\n  AiringSchedule,\n  AniListClientOptions,\n  AniListHooks,\n  CacheAdapter,\n  Character,\n  CharacterIncludeOptions,\n  GeneralMediaQueryOptions,\n  GetAiringOptions,\n  GetMediaCharactersOptions,\n  GetMediaStaffOptions,\n  GetPlanningOptions,\n  GetRecentChaptersOptions,\n  GetRecommendationsOptions,\n  GetSeasonOptions,\n  GetUserMediaListOptions,\n  Logger,\n  Media,\n  MediaCharacterEdge,\n  MediaIncludeOptions,\n  MediaListEntry,\n  MediaStaffEdge,\n  MediaTag,\n  MediaType,\n  PagedResult,\n  PageInfo,\n  RateLimitInfo,\n  Recommendation,\n  ResponseMeta,\n  Review,\n  SearchCharacterOptions,\n  SearchMediaOptions,\n  SearchReviewOptions,\n  SearchStaffOptions,\n  SearchStudioOptions,\n  SearchThreadOptions,\n  SearchUserOptions,\n  Staff,\n  StaffIncludeOptions,\n  Studio,\n  StudioIncludeOptions,\n  Thread,\n  User,\n  UserFavorites,\n  UserFavoritesOptions,\n  WeeklySchedule,\n} from \"../types\";\nimport { BatchLoader, chunk, normalizeQuery, validateIds } from \"../utils\";\nimport type { ClientBase } from \"./base\";\nimport * as characterMethods from \"./character\";\nimport * as mediaMethods from \"./media\";\nimport * as reviewMethods from \"./review\";\nimport * as staffMethods from \"./staff\";\nimport * as studioMethods from \"./studio\";\nimport * as threadMethods from \"./thread\";\nimport * as userMethods from \"./user\";\n\nconst DEFAULT_API_URL = \"https://graphql.anilist.co\";\n\ndeclare const __VERSION__: string;\n/** Injected at build time by tsup — falls back to `\"dev\"` in test/dev environments. */\nconst LIB_VERSION = typeof __VERSION__ !== \"undefined\" ? __VERSION__ : \"dev\";\n\n/**\n * Lightweight AniList GraphQL client with built-in caching and rate limiting.\n *\n * @example\n * ```ts\n * import { AniListClient } from \"ani-client\";\n *\n * const client = new AniListClient();\n * const anime = await client.getMedia(1);\n * console.log(anime.title.romaji);\n *\n * // Custom cache & rate limit options\n * const client2 = new AniListClient({\n *   cache: { ttl: 1000 * 60 * 60 }, // 1 hour cache\n *   rateLimit: { maxRequests: 60 },\n * });\n * ```\n */\nexport class AniListClient implements ClientBase {\n  private readonly apiUrl: string;\n  private readonly headers: Record<string, string>;\n  private readonly cacheAdapter: CacheAdapter;\n  private readonly rateLimiter: RateLimiter;\n  private readonly hooks: AniListHooks;\n  private readonly logger?: Logger;\n  private readonly signal?: AbortSignal;\n  private readonly inFlight = new Map<string, Promise<unknown>>();\n  private _rateLimitInfo?: RateLimitInfo;\n  private _lastRequestMeta?: ResponseMeta;\n\n  private readonly mediaLoader: BatchLoader<Media>;\n  private readonly characterLoader: BatchLoader<Character>;\n  private readonly staffLoader: BatchLoader<Staff>;\n\n  private readonly batchingEnabled: boolean;\n\n  constructor(options: AniListClientOptions = {}) {\n    this.apiUrl = options.apiUrl ?? DEFAULT_API_URL;\n    this.headers = {\n      \"Content-Type\": \"application/json\",\n      Accept: \"application/json\",\n      \"User-Agent\": `ani-client/${LIB_VERSION}`,\n    };\n    if (options.token) {\n      this.headers.Authorization = `Bearer ${options.token}`;\n    }\n    this.cacheAdapter = options.cacheAdapter ?? new MemoryCache(options.cache);\n    this.rateLimiter = new RateLimiter(options.rateLimit);\n    this.hooks = options.hooks ?? {};\n    this.logger = options.logger;\n    this.signal = options.signal;\n    this.batchingEnabled = options.batching?.enabled ?? true;\n\n    const windowMs = options.batching?.windowMs ?? 50;\n    const maxBatchSize = options.batching?.maxBatchSize ?? 50;\n\n    this.mediaLoader = new BatchLoader<Media>((ids) => this.getMediaBatch(ids), windowMs, maxBatchSize);\n    this.characterLoader = new BatchLoader<Character>((ids) => this.getCharacterBatch(ids), windowMs, maxBatchSize);\n    this.staffLoader = new BatchLoader<Staff>((ids) => this.getStaffBatch(ids), windowMs, maxBatchSize);\n  }\n\n  /**\n   * The current rate limit information from the last API response.\n   * Updated after every non-cached request.\n   */\n  get rateLimitInfo(): RateLimitInfo | undefined {\n    return this._rateLimitInfo;\n  }\n\n  /**\n   * Metadata about the last request (duration, cache status, rate limit info).\n   * Useful for debugging and monitoring.\n   */\n  get lastRequestMeta(): ResponseMeta | undefined {\n    return this._lastRequestMeta;\n  }\n\n  /** @internal */\n  async request<T>(query: string, variables: Record<string, unknown> = {}): Promise<T> {\n    const cacheKey = MemoryCache.key(query, variables);\n\n    let cached: T | undefined;\n    let isStale = false;\n\n    if (this.cacheAdapter.getWithMeta) {\n      const res = await this.cacheAdapter.getWithMeta<T>(cacheKey);\n      if (res) {\n        cached = res.data;\n        isStale = res.stale;\n      }\n    } else {\n      cached = await this.cacheAdapter.get<T>(cacheKey);\n    }\n\n    if (cached !== undefined) {\n      if (isStale) {\n        this.executeRequest<T>(query, variables, cacheKey).catch((err) => {\n          this.logger?.error(\"Background revalidation failed\", { error: (err as Error).message, cacheKey });\n        });\n      }\n\n      this.hooks.onCacheHit?.(cacheKey);\n      this.logger?.debug(\"Cache hit\", { cacheKey, isStale });\n      const meta: ResponseMeta = { durationMs: 0, fromCache: true };\n      this._lastRequestMeta = meta;\n      this.hooks.onResponse?.(query, 0, true);\n      return cached;\n    }\n\n    const existing = this.inFlight.get(cacheKey);\n    if (existing) return existing as Promise<T>;\n\n    const promise = this.executeRequest<T>(query, variables, cacheKey);\n    this.inFlight.set(cacheKey, promise);\n\n    try {\n      return await promise;\n    } finally {\n      this.inFlight.delete(cacheKey);\n    }\n  }\n\n  /** @internal */\n  private async executeRequest<T>(query: string, variables: Record<string, unknown>, cacheKey: string): Promise<T> {\n    const start = Date.now();\n    this.hooks.onRequest?.(query, variables);\n    this.logger?.debug(\"API request\", { variables });\n\n    const minifiedQuery = normalizeQuery(query);\n\n    let res: Response;\n    try {\n      res = await this.rateLimiter.fetchWithRetry(\n        this.apiUrl,\n        {\n          method: \"POST\",\n          headers: this.headers,\n          body: JSON.stringify({ query: minifiedQuery, variables }),\n          signal: this.signal,\n        },\n        { onRetry: this.hooks.onRetry, onRateLimit: this.hooks.onRateLimit },\n      );\n    } catch (err) {\n      const error =\n        err instanceof AniListError\n          ? err\n          : new AniListError((err as Error).message ?? \"Network request failed\", 0, [err]);\n      this.logger?.error(\"Request failed\", { error: error.message, status: error.status });\n      this.hooks.onError?.(error, query, variables);\n      throw error;\n    }\n\n    let json: { data?: T; errors?: GraphQLError[] };\n    try {\n      json = (await res.json()) as { data?: T; errors?: GraphQLError[] };\n    } catch {\n      const error = new AniListError(`Non-JSON response from AniList (HTTP ${res.status})`, res.status, []);\n      this.logger?.error(\"Request failed\", { error: error.message, status: error.status });\n      this.hooks.onError?.(error, query, variables);\n      throw error;\n    }\n\n    if (!res.ok || json.errors) {\n      const msgs = (json.errors || []).map((e) => e.message).filter(Boolean);\n      const message = msgs.length > 0 ? msgs.join(\" | \") : `AniList API error (HTTP ${res.status})`;\n      const error = new AniListError(message, res.status, json.errors ?? []);\n      this.logger?.error(\"Request failed\", { error: error.message, status: error.status });\n      this.hooks.onError?.(error, query, variables);\n      throw error;\n    }\n\n    const rlLimit = res.headers.get(\"X-RateLimit-Limit\");\n    const rlRemaining = res.headers.get(\"X-RateLimit-Remaining\");\n    const rlReset = res.headers.get(\"X-RateLimit-Reset\");\n    if (rlLimit && rlRemaining && rlReset) {\n      this._rateLimitInfo = {\n        limit: Number.parseInt(rlLimit, 10),\n        remaining: Number.parseInt(rlRemaining, 10),\n        reset: Number.parseInt(rlReset, 10),\n      };\n\n      const remainingPercent = this._rateLimitInfo.remaining / this._rateLimitInfo.limit;\n      if (remainingPercent <= 0.15) {\n        const resetIn = this._rateLimitInfo.reset - Math.floor(Date.now() / 1000);\n        const resetInSeconds = resetIn > 0 ? resetIn : 0;\n        this.logger?.warn(\"Smart Alert: AniList API rate limit is critically low\", {\n          remaining: this._rateLimitInfo.remaining,\n          limit: this._rateLimitInfo.limit,\n          resetInSeconds,\n        });\n        this.hooks.onRateLimitAlert?.(this._rateLimitInfo.remaining, resetInSeconds);\n      }\n    }\n\n    const durationMs = Date.now() - start;\n    const data = json.data as T;\n    await this.cacheAdapter.set(cacheKey, data);\n\n    const meta: ResponseMeta = { durationMs, fromCache: false, rateLimitInfo: this._rateLimitInfo };\n    this._lastRequestMeta = meta;\n    this.logger?.debug(\"Request complete\", { durationMs, rateLimitInfo: this._rateLimitInfo });\n    this.hooks.onResponse?.(query, durationMs, false, this._rateLimitInfo);\n    return data;\n  }\n\n  /** @internal */\n  async pagedRequest<T>(query: string, variables: Record<string, unknown>, field: string): Promise<PagedResult<T>> {\n    const data = await this.request<{ Page: Record<string, unknown> & { pageInfo: PageInfo } }>(query, variables);\n    const results = data.Page[field];\n    if (!Array.isArray(results)) {\n      throw new AniListError(`Unexpected response: missing field \"${field}\" in Page`, 0, []);\n    }\n    return { pageInfo: data.Page.pageInfo, results: results as T[] };\n  }\n\n  /**\n   * Fetch a single media entry by its AniList ID.\n   *\n   * Optionally include related data (characters, staff, relations, etc.) via the `include` parameter.\n   *\n   * @param id - The AniList media ID\n   * @param include - Optional related data to include\n   */\n  async getMedia(id: number, include?: MediaIncludeOptions): Promise<Media> {\n    if (!this.batchingEnabled || include) {\n      return mediaMethods.getMedia(this, id, include);\n    }\n    return this.mediaLoader.load(id);\n  }\n\n  async getMediaCharacters(\n    mediaId: number,\n    options: GetMediaCharactersOptions = {},\n  ): Promise<PagedResult<MediaCharacterEdge>> {\n    return mediaMethods.getMediaCharacters(this, mediaId, options);\n  }\n\n  async getMediaStaff(mediaId: number, options: GetMediaStaffOptions = {}): Promise<PagedResult<MediaStaffEdge>> {\n    return mediaMethods.getMediaStaff(this, mediaId, options);\n  }\n\n  /**\n   * Search for anime or manga.\n   *\n   * @param options - Search / filter parameters\n   * @returns Paginated results with matching media\n   */\n  async searchMedia(options: SearchMediaOptions = {}, include?: MediaIncludeOptions): Promise<PagedResult<Media>> {\n    return mediaMethods.searchMedia(this, options, include);\n  }\n\n  /** Get currently trending anime or manga. */\n  async getTrending(\n    options: GeneralMediaQueryOptions = {},\n    include?: MediaIncludeOptions,\n  ): Promise<PagedResult<Media>> {\n    return mediaMethods.getTrending(this, options, include);\n  }\n\n  /** Get the most popular anime or manga. */\n  async getPopular(options: GeneralMediaQueryOptions = {}, include?: MediaIncludeOptions): Promise<PagedResult<Media>> {\n    return mediaMethods.getPopular(this, options, include);\n  }\n\n  /** Get the highest-rated anime or manga. */\n  async getTopRated(\n    options: GeneralMediaQueryOptions = {},\n    include?: MediaIncludeOptions,\n  ): Promise<PagedResult<Media>> {\n    return mediaMethods.getTopRated(this, options, include);\n  }\n\n  /** Get recently aired anime episodes. */\n  async getAiredEpisodes(options: GetAiringOptions = {}): Promise<PagedResult<AiringSchedule>> {\n    return mediaMethods.getAiredEpisodes(this, options);\n  }\n\n  /**\n   * Get currently releasing manga sorted by most recently updated.\n   *\n   * @param options - Pagination parameters\n   */\n  async getRecentlyUpdatedManga(\n    options: GetRecentChaptersOptions = {},\n    include?: MediaIncludeOptions,\n  ): Promise<PagedResult<Media>> {\n    return mediaMethods.getRecentlyUpdatedManga(this, options, include);\n  }\n\n  /**\n   * Fetch a media entry by its MyAnimeList (MAL) ID.\n   *\n   * @param malId - The MyAnimeList ID\n   * @param type - Optional media type to disambiguate (some MAL IDs map to both ANIME and MANGA)\n   */\n  async getMediaByMalId(malId: number, type?: MediaType): Promise<Media> {\n    return mediaMethods.getMediaByMalId(this, malId, type);\n  }\n\n  /** Get the detailed schedule for the current week, sorted by day. */\n  async getWeeklySchedule(date?: Date, idNotIn?: number[]): Promise<WeeklySchedule> {\n    return mediaMethods.getWeeklySchedule(this, date, idNotIn);\n  }\n\n  /** Get upcoming (not yet released) media. */\n  async getPlanning(options: GetPlanningOptions = {}, include?: MediaIncludeOptions): Promise<PagedResult<Media>> {\n    return mediaMethods.getPlanning(this, options, include);\n  }\n\n  /** Get recommendations for a specific media. */\n  async getRecommendations(\n    mediaId: number,\n    options: Omit<GetRecommendationsOptions, \"mediaId\"> = {},\n  ): Promise<PagedResult<Recommendation>> {\n    return mediaMethods.getRecommendations(this, mediaId, options);\n  }\n\n  /** Get anime (or manga) for a specific season and year. */\n  async getMediaBySeason(options: GetSeasonOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>> {\n    return mediaMethods.getMediaBySeason(this, options, include);\n  }\n\n  /** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */\n  async getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character> {\n    if (!this.batchingEnabled || include) {\n      return characterMethods.getCharacter(this, id, include);\n    }\n    return this.characterLoader.load(id);\n  }\n\n  /** Search for characters by name. */\n  async searchCharacters(options: SearchCharacterOptions = {}): Promise<PagedResult<Character>> {\n    return characterMethods.searchCharacters(this, options);\n  }\n\n  /** Fetch a staff member by AniList ID. Pass `{ media: true }` or `{ media: { perPage } }` for media credits. */\n  async getStaff(id: number, include?: StaffIncludeOptions): Promise<Staff> {\n    if (!this.batchingEnabled || include) {\n      return staffMethods.getStaff(this, id, include);\n    }\n    return this.staffLoader.load(id);\n  }\n\n  /** Search for staff (voice actors, directors, etc.). */\n  async searchStaff(options: SearchStaffOptions = {}): Promise<PagedResult<Staff>> {\n    return staffMethods.searchStaff(this, options);\n  }\n\n  /**\n   * Fetch a user by AniList ID or username.\n   *\n   * @param idOrName - The AniList user ID (number) or username (string)\n   */\n  async getUser(idOrName: number | string): Promise<User> {\n    return userMethods.getUser(this, idOrName);\n  }\n\n  /** Search for users by name. */\n  async searchUsers(options: SearchUserOptions = {}): Promise<PagedResult<User>> {\n    return userMethods.searchUsers(this, options);\n  }\n\n  /** Get a user's anime or manga list. */\n  async getUserMediaList(options: GetUserMediaListOptions): Promise<PagedResult<MediaListEntry>> {\n    return userMethods.getUserMediaList(this, options);\n  }\n\n  /**\n   * Fetch a user's favorite anime, manga, characters, staff, and studios.\n   *\n   * @param idOrName - AniList user ID (number) or username (string)\n   * @param options - Optional pagination options (perPage per category)\n   * @returns The user's favorites grouped by category\n   *\n   * @example\n   * ```typescript\n   * const favs = await client.getUserFavorites(\"AniList\");\n   * favs.anime.forEach(a => console.log(a.title.romaji));\n   *\n   * // Fetch more results per category\n   * const moreResults = await client.getUserFavorites(1, { perPage: 50 });\n   * ```\n   */\n  async getUserFavorites(idOrName: number | string, options?: UserFavoritesOptions): Promise<UserFavorites> {\n    return userMethods.getUserFavorites(this, idOrName, options);\n  }\n\n  /**\n   * Fetch a review by its AniList ID.\n   *\n   * @param id - The AniList review ID\n   */\n  async getReview(id: number): Promise<Review> {\n    return reviewMethods.getReview(this, id);\n  }\n\n  /**\n   * Search for reviews with optional filters.\n   *\n   * @param options - Search and filter options\n   * @returns Paginated results with matching reviews\n   */\n  async searchReviews(options: SearchReviewOptions = {}): Promise<PagedResult<Review>> {\n    return reviewMethods.searchReviews(this, options);\n  }\n\n  /**\n   * Fetch a studio by its AniList ID.\n   * Pass `include` to customise the number of media returned.\n   *\n   * @example\n   * ```typescript\n   * const studio = await client.getStudio(21, { media: { perPage: 50 } });\n   * ```\n   */\n  async getStudio(id: number, include?: StudioIncludeOptions): Promise<Studio> {\n    return studioMethods.getStudio(this, id, include);\n  }\n\n  /** Search for studios by name. */\n  async searchStudios(options: SearchStudioOptions = {}): Promise<PagedResult<Studio>> {\n    return studioMethods.searchStudios(this, options);\n  }\n\n  /** Fetch a forum thread by its AniList ID. */\n  async getThread(id: number): Promise<Thread> {\n    return threadMethods.getThread(this, id);\n  }\n\n  /** Get recent forum threads, optionally filtered by search, media, or category. */\n  async getRecentThreads(options: SearchThreadOptions = {}): Promise<PagedResult<Thread>> {\n    return threadMethods.getRecentThreads(this, options);\n  }\n\n  /** Get all available genres on AniList. */\n  async getGenres(): Promise<string[]> {\n    const data = await this.request<{ GenreCollection: string[] }>(QUERY_GENRES);\n    return data.GenreCollection;\n  }\n\n  /** Get all available media tags on AniList. */\n  async getTags(): Promise<MediaTag[]> {\n    const data = await this.request<{ MediaTagCollection: MediaTag[] }>(QUERY_TAGS);\n    return data.MediaTagCollection;\n  }\n\n  /** Execute an arbitrary GraphQL query against the AniList API. */\n  async raw<T>(query: string, variables?: Record<string, unknown>): Promise<T> {\n    return this.request<T>(query, variables ?? {});\n  }\n\n  /**\n   * Auto-paginating async iterator. Yields individual items across all pages.\n   *\n   * @param fetchPage - A function that takes a page number and returns a `PagedResult<T>`\n   * @param maxPages - Maximum number of pages to fetch (default: Infinity)\n   */\n  async *paginate<T>(\n    fetchPage: (page: number) => Promise<PagedResult<T>>,\n    maxPages = Number.POSITIVE_INFINITY,\n  ): AsyncGenerator<T, void, undefined> {\n    let page = 1;\n    let hasNext = true;\n\n    while (hasNext && page <= maxPages) {\n      const result = await fetchPage(page);\n      for (const item of result.results) {\n        yield item;\n      }\n      hasNext = result.pageInfo.hasNextPage === true;\n      page++;\n    }\n  }\n\n  /**\n   * Utility to fetch all pages of a paginated request and return them as a single array.\n   *\n   * @param fetchPage - A function that takes a page number and returns a `PagedResult<T>`\n   * @param maxPages - Maximum number of pages to fetch (default: Infinity)\n   */\n  async fetchAll<T>(\n    fetchPage: (page: number) => Promise<PagedResult<T>>,\n    maxPages = Number.POSITIVE_INFINITY,\n  ): Promise<T[]> {\n    const results: T[] = [];\n    for await (const item of this.paginate(fetchPage, maxPages)) {\n      results.push(item);\n    }\n    return results;\n  }\n\n  /** Fetch multiple media entries in a single API request. */\n  async getMediaBatch(ids: number[]): Promise<Media[]> {\n    if (ids.length === 0) return [];\n    validateIds(ids, \"mediaId\");\n    const [singleMediaId] = ids;\n    if (ids.length === 1 && singleMediaId !== undefined) return [await mediaMethods.getMedia(this, singleMediaId)];\n    return this.executeBatch<Media>(ids, buildBatchMediaQuery, \"m\");\n  }\n\n  /** Fetch multiple characters in a single API request. */\n  async getCharacterBatch(ids: number[]): Promise<Character[]> {\n    if (ids.length === 0) return [];\n    validateIds(ids, \"characterId\");\n    const [singleCharId] = ids;\n    if (ids.length === 1 && singleCharId !== undefined)\n      return [await characterMethods.getCharacter(this, singleCharId)];\n    return this.executeBatch<Character>(ids, buildBatchCharacterQuery, \"c\");\n  }\n\n  /** Fetch multiple staff members in a single API request. */\n  async getStaffBatch(ids: number[]): Promise<Staff[]> {\n    if (ids.length === 0) return [];\n    validateIds(ids, \"staffId\");\n    const [singleStaffId] = ids;\n    if (ids.length === 1 && singleStaffId !== undefined) return [await staffMethods.getStaff(this, singleStaffId)];\n    return this.executeBatch<Staff>(ids, buildBatchStaffQuery, \"s\");\n  }\n\n  /** @internal */\n  private async executeBatch<T>(ids: number[], buildQuery: (ids: number[]) => string, prefix: string): Promise<T[]> {\n    const chunks = chunk(ids, 50);\n    const chunkResults = await Promise.all(\n      chunks.map(async (idChunk) => {\n        const query = buildQuery(idChunk);\n        const data = await this.request<Record<string, T>>(query);\n        return idChunk.map((_, i) => data[`${prefix}${i}`] as T);\n      }),\n    );\n    return chunkResults.flat();\n  }\n\n  /** Clear the entire response cache. */\n  async clearCache(): Promise<void> {\n    await this.cacheAdapter.clear();\n  }\n\n  /** Number of entries currently in the cache. */\n  async cacheSize(): Promise<number> {\n    return this.cacheAdapter.size;\n  }\n\n  /** Remove cache entries whose key matches the given pattern. */\n  async invalidateCache(pattern: string | RegExp): Promise<number> {\n    if (this.cacheAdapter.invalidate) {\n      return this.cacheAdapter.invalidate(pattern);\n    }\n    const allKeys = await this.cacheAdapter.keys();\n    const regex = typeof pattern === \"string\" ? new RegExp(pattern) : pattern;\n    let count = 0;\n    for (const key of allKeys) {\n      if (regex.test(key)) {\n        await this.cacheAdapter.delete(key);\n        count++;\n      }\n    }\n    return count;\n  }\n\n  /** Clean up resources held by the client. */\n  async destroy(): Promise<void> {\n    await this.cacheAdapter.clear();\n    this.inFlight.clear();\n    this.rateLimiter.dispose();\n  }\n\n  /**\n   * Return a scoped view of this client where every request uses the given `AbortSignal`.\n   * The returned object shares the same cache, rate limiter, and hooks.\n   *\n   * @example\n   * ```ts\n   * const controller = new AbortController();\n   * const media = await client.withSignal(controller.signal).getMedia(1);\n   *\n   * // Cancel all in-flight requests made through the scoped view\n   * controller.abort();\n   * ```\n   */\n  withSignal(signal: AbortSignal): AniListClient {\n    const scoped = Object.create(this) as AniListClient;\n    Object.defineProperty(scoped, \"signal\", { value: signal, configurable: true });\n    return scoped;\n  }\n}\n"]}