@pokewallet/sdk 0.1.3 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -184,7 +184,7 @@ function errorFromResponse(ctx) {
184
184
  }
185
185
 
186
186
  // src/version.ts
187
- var VERSION = "0.1.3";
187
+ var VERSION = "0.1.6";
188
188
  var DEFAULT_BASE_URL = "https://api.pokewallet.io";
189
189
  var DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`;
190
190
 
@@ -220,6 +220,7 @@ var HttpClient = class {
220
220
  #key;
221
221
  baseUrl;
222
222
  userAgent;
223
+ client;
223
224
  fetchImpl;
224
225
  maxRetries;
225
226
  capSeconds;
@@ -229,6 +230,7 @@ var HttpClient = class {
229
230
  this.#key = readKey(options);
230
231
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
231
232
  this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;
233
+ this.client = options.client ?? DEFAULT_USER_AGENT;
232
234
  const g = globalThis;
233
235
  const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : void 0);
234
236
  if (!f) throw new ValidationError("No fetch available: pass options.fetch (Node 18+ has one built in)");
@@ -281,6 +283,7 @@ var HttpClient = class {
281
283
  headers: {
282
284
  ...this.#key === void 0 ? {} : { "X-API-Key": this.#key },
283
285
  "User-Agent": this.userAgent,
286
+ "X-PokeWallet-Client": this.client,
284
287
  Accept: "application/json"
285
288
  },
286
289
  signal: AbortSignal.timeout(this.timeoutMs)
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/error-map.ts","../src/version.ts","../src/http.ts","../src/types.ts","../src/images.ts","../src/normalize/common.ts","../src/normalize/misc.ts","../src/normalize/prices.ts","../src/normalize/card.ts","../src/normalize/pro.ts","../src/normalize/sets.ts","../src/pagination.ts","../src/validation.ts","../src/worlds/world.ts","../src/worlds/card-world.ts","../src/worlds/onepiece-world.ts","../src/worlds/pokemon-world.ts","../src/client.ts"],"sourcesContent":["export { PokeWallet } from './client.js'\nexport { imageUrl, type ImageUrlOptions } from './images.js'\nexport { paginate } from './pagination.js'\nexport type { ClientOptions, FetchLike, RateLimitInfo } from './http.js'\nexport type { World } from './worlds/world.js'\nexport type { PokemonWorld } from './worlds/pokemon-world.js'\nexport * from './errors.js'\nexport * from './types.js'\nexport { VERSION } from './version.js'\n/** Raw wire types generated from `openapi/pokewallet.yaml`, for code that wants the unnormalized shapes. */\nexport type { paths, components, operations } from './generated/schema.js'\n","/** Hourly or daily quota window as reported in a 429 body. */\nexport interface LimitWindow {\n limit: number\n used: number\n remaining: number\n}\n\nexport interface RateLimitWindows {\n hourly?: LimitWindow\n daily?: LimitWindow\n}\n\n/** One candidate of an ambiguous set. `setId` is the value to pass back to pick it. */\nexport interface SetMatch {\n setId: string\n setCode: string | null\n name: string | null\n language: string | null\n releaseDate: string | null\n}\n\nexport interface ErrorInit {\n status: number\n body?: unknown\n message?: string\n}\n\n/** Base class of every error raised by the SDK for an API answer. */\nexport class PokeWalletError extends Error {\n readonly status: number\n /** Parsed JSON body of the answer, when there was one. */\n readonly body: unknown\n /** The `error` field of the body, when present. */\n readonly code: string | undefined\n\n constructor(init: ErrorInit) {\n const code = bodyString(init.body, 'error')\n super(init.message ?? bodyString(init.body, 'message') ?? code ?? `HTTP ${init.status}`)\n this.name = new.target.name\n this.status = init.status\n this.body = init.body\n this.code = code\n }\n}\n\n/** Raised before any request when an argument is out of range. */\nexport class ValidationError extends RangeError {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/** The request never produced an HTTP answer (DNS, connection, timeout). */\nexport class NetworkError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'NetworkError'\n }\n}\n\n/** 400: missing or invalid parameter, or an id that cannot be decoded. */\nexport class BadRequestError extends PokeWalletError {}\n\n/** 401: key missing, malformed or unknown. */\nexport class AuthError extends PokeWalletError {}\n\n/**\n * 403 on a plan-gated endpoint. `redeemUrl` is set when the free trial was never\n * activated; `upgradeUrl` when the trial expired or the plan is too low.\n */\nexport class PlanRequiredError extends PokeWalletError {\n readonly redeemUrl: string | undefined\n readonly upgradeUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.redeemUrl = bodyString(init.body, 'redeem_url')\n this.upgradeUrl = bodyString(init.body, 'upgrade_url')\n }\n}\n\n/** 403 `Feature not enabled`: this account does not have access to this feature. */\nexport class FeatureNotEnabledError extends PokeWalletError {\n readonly contactUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.contactUrl = bodyString(init.body, 'contact_url')\n }\n}\n\n/** 404: unknown card, set or route. Carries the server's suggestions when it sent any. */\nexport class NotFoundError extends PokeWalletError {\n readonly didYouMean: string | undefined\n readonly suggestions: unknown[]\n\n constructor(init: ErrorInit) {\n super(init)\n this.didYouMean = bodyString(init.body, 'did_you_mean')\n const s = (init.body as { suggestions?: unknown } | null | undefined)?.suggestions\n this.suggestions = Array.isArray(s) ? s : []\n }\n}\n\n/** 404 on a game route: the game is switched off for this account. */\nexport class GameUnavailableError extends NotFoundError {}\n\n/**\n * The set code matches several sets. Unifies the three ways the API says so\n * (200 with `disambiguation`, 300, 409). Retry with one `matches[i].setId`.\n */\nexport class AmbiguousSetError extends PokeWalletError {\n readonly matches: SetMatch[]\n\n constructor(init: ErrorInit & { matches: SetMatch[] }) {\n super({ ...init, message: init.message ?? 'Several sets match this code: pick one by setId' })\n this.matches = init.matches\n }\n}\n\n/**\n * 429. The API sends no `Retry-After`, so the SDK retries only when the header is\n * present and within the cap. `limits` mirrors the body: when a window shows\n * `remaining === 0`, waiting seconds cannot help.\n */\nexport class RateLimitError extends PokeWalletError {\n readonly limits: RateLimitWindows\n /** Seconds, from the `Retry-After` header, when present. */\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n const l = (init.body as { limits?: Record<string, unknown> } | null | undefined)?.limits\n this.limits = { hourly: toWindow(l?.hourly), daily: toWindow(l?.daily) }\n }\n}\n\n/** 503: database busy or feature not yet enabled. `retryAfter` is 5 or 3600 seconds. */\nexport class UnavailableError extends PokeWalletError {\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n }\n}\n\n/** Any other 5xx. Never retried. */\nexport class ServerError extends PokeWalletError {}\n\nfunction bodyString(body: unknown, key: string): string | undefined {\n const v = (body as Record<string, unknown> | null | undefined)?.[key]\n return typeof v === 'string' ? v : undefined\n}\n\nfunction toWindow(v: unknown): LimitWindow | undefined {\n if (!v || typeof v !== 'object') return undefined\n const w = v as Record<string, unknown>\n if (typeof w.limit !== 'number' || typeof w.used !== 'number' || typeof w.remaining !== 'number') return undefined\n return { limit: w.limit, used: w.used, remaining: w.remaining }\n}\n","import {\n AmbiguousSetError,\n AuthError,\n BadRequestError,\n FeatureNotEnabledError,\n GameUnavailableError,\n NotFoundError,\n PlanRequiredError,\n PokeWalletError,\n RateLimitError,\n ServerError,\n UnavailableError,\n type SetMatch,\n} from './errors.js'\n\ninterface RawMatch {\n set_id?: unknown\n set_code?: unknown\n name?: unknown\n language?: unknown\n release_date?: unknown\n}\n\nconst str = (v: unknown): string | null => (typeof v === 'string' ? v : typeof v === 'number' ? String(v) : null)\n\n/** Converts the `matches` array of any ambiguous-set body into the public shape. */\nexport function toSetMatches(body: unknown): SetMatch[] {\n const raw = (body as { matches?: unknown } | null | undefined)?.matches\n if (!Array.isArray(raw)) return []\n return raw.map((m: RawMatch) => ({\n setId: str(m.set_id) ?? '',\n setCode: str(m.set_code),\n name: str(m.name),\n language: str(m.language),\n releaseDate: str(m.release_date),\n }))\n}\n\n/** True for the 200 body the API uses to say \"several sets match\". */\nexport function isDisambiguation(body: unknown): boolean {\n return !!body && typeof body === 'object' && (body as { disambiguation?: unknown }).disambiguation === true\n}\n\nexport function ambiguousSetError(status: number, body: unknown): AmbiguousSetError {\n return new AmbiguousSetError({ status, body, matches: toSetMatches(body) })\n}\n\nexport interface ErrorContext {\n status: number\n body: unknown\n retryAfter: number | undefined\n /** True when the request went to one of the ten `/{game}` prefixes. */\n gameRoute: boolean\n}\n\n/** Maps a non-success answer to its typed error. Pure: no retry decisions here. */\nexport function errorFromResponse(ctx: ErrorContext): PokeWalletError {\n const { status, body, retryAfter, gameRoute } = ctx\n const init = { status, body }\n const code = (body as { error?: unknown } | null | undefined)?.error\n\n if (status === 300 || (status === 409 && isDisambiguation(body)) || (status === 409 && code === 'Ambiguous set code')) {\n return ambiguousSetError(status, body)\n }\n switch (status) {\n case 400:\n return new BadRequestError(init)\n case 401:\n return new AuthError(init)\n case 403:\n return code === 'Feature not enabled' ? new FeatureNotEnabledError(init) : new PlanRequiredError(init)\n case 404:\n // A switched-off game answers with the generic route 404, not a resource 404.\n return gameRoute && code === 'Endpoint not found' ? new GameUnavailableError(init) : new NotFoundError(init)\n case 429:\n return new RateLimitError({ ...init, retryAfter })\n case 503:\n return new UnavailableError({ ...init, retryAfter })\n default:\n return status >= 500 ? new ServerError(init) : new PokeWalletError(init)\n }\n}\n","export const VERSION = '0.1.3'\nexport const DEFAULT_BASE_URL = 'https://api.pokewallet.io'\nexport const DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`\n","import { ValidationError, NetworkError, RateLimitError, type PokeWalletError } from './errors.js'\nimport { errorFromResponse } from './error-map.js'\nimport { DEFAULT_BASE_URL, DEFAULT_USER_AGENT } from './version.js'\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface ClientOptions {\n /**\n * API key (`pk_…`). Falls back to the `POKEWALLET_API_KEY` environment variable. Optional at\n * construction: only `health()` and `listGames()` work without one, every other call throws\n * `ValidationError` before touching the network.\n */\n apiKey?: string\n baseUrl?: string\n /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */\n userAgent?: string\n /** Custom `fetch`, mainly for tests. Defaults to the global one. */\n fetch?: FetchLike\n /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */\n maxRetries?: number\n /** Longest `Retry-After` the SDK will sit through, in seconds. Default 30. */\n retryAfterCapSeconds?: number\n /** Per-request timeout in milliseconds. Default 30000. */\n timeoutMs?: number\n /** Replaces the delay between retries, mainly for tests. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Quota counters from the `X-RateLimit-*` headers of the last answer. */\nexport interface RateLimitInfo {\n limitHour: number | null\n remainingHour: number | null\n limitDay: number | null\n remainingDay: number | null\n}\n\nexport type Query = Record<string, string | number | boolean | undefined | null>\n\nconst GAME_PREFIX = /^\\/(mtg|ygo|cfv|dbs|fab|dgm|swu|lor|rft|cpk)\\//\n\nexport const KEY_REQUIRED = 'An API key is required: pass apiKey or set POKEWALLET_API_KEY'\n\n/** The key from the options or the environment; undefined when there is none (public endpoints still work). */\nfunction readKey(options: ClientOptions): string | undefined {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env\n const key = (options.apiKey ?? env?.POKEWALLET_API_KEY ?? '').trim()\n if (!key) return undefined\n if (!key.startsWith('pk_')) throw new ValidationError('API keys start with \"pk_\"')\n return key\n}\n\n/** Seconds from a `Retry-After` value (delta-seconds or HTTP date), or undefined. */\nexport function parseRetryAfter(value: string | null, now = Date.now()): number | undefined {\n if (value == null || value.trim() === '') return undefined\n const n = Number(value)\n if (Number.isFinite(n) && n >= 0) return n\n const t = Date.parse(value)\n return Number.isNaN(t) ? undefined : Math.max(0, Math.ceil((t - now) / 1000))\n}\n\nfunction num(h: Headers, name: string): number | null {\n const v = h.get(name)\n if (v == null) return null\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n}\n\nfunction exhausted(err: RateLimitError): boolean {\n return [err.limits.hourly, err.limits.daily].some((w) => w !== undefined && w.remaining <= 0)\n}\n\nexport class HttpClient {\n /** Quota counters of the most recent answer that carried them. */\n lastRateLimit: RateLimitInfo | null = null\n\n readonly #key: string | undefined\n private readonly baseUrl: string\n private readonly userAgent: string\n private readonly fetchImpl: FetchLike\n private readonly maxRetries: number\n private readonly capSeconds: number\n private readonly timeoutMs: number\n private readonly sleep: (ms: number) => Promise<void>\n\n constructor(options: ClientOptions = {}) {\n this.#key = readKey(options)\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT\n const g = globalThis as { fetch?: FetchLike }\n const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : undefined)\n if (!f) throw new ValidationError('No fetch available: pass options.fetch (Node 18+ has one built in)')\n this.fetchImpl = f\n this.maxRetries = options.maxRetries ?? 2\n this.capSeconds = options.retryAfterCapSeconds ?? 30\n this.timeoutMs = options.timeoutMs ?? 30_000\n this.sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)))\n }\n\n url(path: string, query?: Query): string {\n const qs = new URLSearchParams()\n for (const [k, v] of Object.entries(query ?? {})) if (v !== undefined && v !== null) qs.set(k, String(v))\n const s = qs.toString()\n return `${this.baseUrl}${path}${s ? `?${s}` : ''}`\n }\n\n /**\n * GET `path` and return the parsed JSON body; throws a typed error otherwise. `isPublic`\n * marks the two endpoints the server answers without a key; everything else needs one.\n * `accept` lets a caller treat a non-2xx body as data (see `health()`).\n */\n async get<T>(\n path: string,\n query?: Query,\n options: { isPublic?: boolean; accept?: (body: unknown) => boolean } = {},\n ): Promise<T> {\n if (this.#key === undefined && !options.isPublic) throw new ValidationError(KEY_REQUIRED)\n const url = this.url(path, query)\n for (let attempt = 0; ; attempt++) {\n const res = await this.send(url)\n const body = parseJson(this.#redact(await res.text()))\n this.trackQuota(res.headers)\n if (res.status >= 200 && res.status < 300) return body as T\n // Some non-2xx answers are data, not failures (an \"unhealthy\" report): return them as is, no retry.\n if (options.accept?.(body)) return body as T\n\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'))\n const err = errorFromResponse({ status: res.status, body, retryAfter, gameRoute: GAME_PREFIX.test(path) })\n if (attempt < this.maxRetries && this.shouldRetry(err, retryAfter)) {\n await this.sleep((retryAfter ?? 1) * 1000)\n continue\n }\n throw err\n }\n }\n\n private shouldRetry(err: PokeWalletError, retryAfter: number | undefined): boolean {\n if (err.status === 429) {\n // Never guess a wait: no header, or an exhausted window, means retrying is pointless.\n return retryAfter !== undefined && retryAfter <= this.capSeconds && !exhausted(err as RateLimitError)\n }\n if (err.status === 503) return (retryAfter ?? 1) <= this.capSeconds\n return false\n }\n\n private async send(url: string): Promise<Response> {\n try {\n return await this.fetchImpl(url, {\n method: 'GET',\n headers: {\n ...(this.#key === undefined ? {} : { 'X-API-Key': this.#key }),\n 'User-Agent': this.userAgent,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n } catch (cause) {\n throw new NetworkError('Request failed before an answer arrived', { cause: this.#scrubError(cause) })\n }\n }\n\n /** Masked form: the only representation of this object that logging or serializing can reach. */\n toJSON(): { baseUrl: string; userAgent: string; apiKey: string | null } {\n return { baseUrl: this.baseUrl, userAgent: this.userAgent, apiKey: this.#key === undefined ? null : 'pk_***' }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `HttpClient ${JSON.stringify(this.toJSON())}`\n }\n\n #redact(text: string): string {\n return this.#key === undefined ? text : text.split(this.#key).join('pk_***')\n }\n\n /** A copy of a thrown value with the key removed from its message, stack and string fields. */\n #scrubError(cause: unknown): unknown {\n if (!(cause instanceof Error)) return typeof cause === 'string' ? this.#redact(cause) : undefined\n const copy = new Error(this.#redact(cause.message))\n copy.name = cause.name\n if (cause.stack) copy.stack = this.#redact(cause.stack)\n const code = (cause as { code?: unknown }).code\n if (typeof code === 'string') (copy as { code?: string }).code = code\n return copy\n }\n\n private trackQuota(h: Headers): void {\n const info: RateLimitInfo = {\n limitHour: num(h, 'x-ratelimit-limit-hour'),\n remainingHour: num(h, 'x-ratelimit-remaining-hour'),\n limitDay: num(h, 'x-ratelimit-limit-day'),\n remainingDay: num(h, 'x-ratelimit-remaining-day'),\n }\n if (Object.values(info).some((v) => v !== null)) this.lastRateLimit = info\n }\n}\n\nfunction parseJson(text: string): unknown {\n if (!text) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return { error: text.slice(0, 200) }\n }\n}\n","/**\n * Public, normalized types. Every object keeps the unmodified server value in `raw`.\n * Prices are `number | null`; the API sometimes sends numeric strings.\n */\n\nexport const GAME_CODES = ['mtg', 'ygo', 'cfv', 'dbs', 'fab', 'dgm', 'swu', 'lor', 'rft', 'cpk'] as const\nexport type GameCode = (typeof GAME_CODES)[number]\n\nexport interface TcgPrice {\n /** Finish (`Normal`, `Holofoil`, `Foil`...). Null for rows that have no finish. */\n variant: string | null\n low: number | null\n mid: number | null\n high: number | null\n market: number | null\n directLow: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface CardmarketPrice {\n variant: string | null\n avg: number | null\n low: number | null\n trend: number | null\n avg1: number | null\n avg7: number | null\n avg30: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface Card {\n /** `pk_…` (Pokémon), `op_…`, `<code>_…`, or a 64-character hex CardMarket id. Reuse as is. */\n id: string\n name: string\n cleanName: string | null\n number: string | null\n rarity: string | null\n cardType: string | null\n productType: string | null\n text: string | null\n variants: string[]\n /**\n * Set identifiers. `setId` is the numeric id (possibly negative); `setCode` the short code.\n * Source: `card_info.set_id` / `card_info.set_code`; for cards listed by a set, both come from the\n * response's `set` object.\n * One Piece search and detail answers carry neither, so both are null there.\n */\n setId: string | null\n setCode: string | null\n setName: string | null\n tcgplayer: { url: string | null; prices: TcgPrice[] } | null\n cardmarket: { productName: string | null; url: string | null; prices: CardmarketPrice[] } | null\n /** Game-specific fields: `hp`, `attacks`, `p`, `t`, `ext_color`... as sent by the API. */\n info: Record<string, unknown>\n raw: unknown\n}\n\nexport interface SetSummary {\n /** Numeric set id as a string (`set_id`; `group_id` for One Piece). */\n id: string\n code: string | null\n name: string\n /** Free text. Pokémon uses `eng`/`jap`/`chn`, One Piece `en`/`jp`. */\n language: string | null\n releaseDate: string | null\n cardCount: number | null\n sealedCount: number | null\n raw: unknown\n}\n\nexport interface Page<T> {\n items: T[]\n page: number\n limit: number\n total: number\n /** Computed from `total` and `limit`, so it is always a finite number. */\n totalPages: number\n}\n\nexport interface SearchPage extends Page<Card> {\n /** Pokémon and games: the candidate list was cut at its cap, refine the query instead of paging. Always false for One Piece. */\n truncated: boolean\n}\n\nexport interface SetPage extends Page<Card> {\n set: SetSummary\n}\n\nexport interface PriceRow {\n id: string\n number: string | null\n name: string\n variant: string | null\n productType: string | null\n tcgplayer: TcgPrice | null\n cardmarket: CardmarketPrice | null\n}\n\nexport interface SetPrices {\n source: string\n setId: string | null\n setCode: string | null\n rows: PriceRow[]\n total: number\n raw: unknown\n}\n\nexport interface SetRef {\n id: string | null\n code: string | null\n name: string | null\n}\n\nexport interface PriceStats {\n avg: number | null\n min: number | null\n max: number | null\n mostExpensive: { id: string | null; name: string | null; price: number | null } | null\n trendDirection: string | null\n}\n\nexport interface SetStatistics {\n set: SetRef & { totalCards: number | null }\n tcgplayer: PriceStats | null\n cardmarket: PriceStats | null\n rarityBreakdown: Record<string, number>\n raw: unknown\n}\n\nexport interface CompletionValue {\n set: SetRef & { totalCards: number | null }\n tcgplayer: { currency: string | null; low: number | null; market: number | null; high: number | null } | null\n cardmarket: { currency: string | null; low: number | null; avg: number | null; trend: number | null } | null\n byRarity: Record<string, { count: number; totalCost: number | null }>\n note: string | null\n raw: unknown\n}\n\nexport interface TrendingSet {\n set: SetRef\n cardCount: number | null\n /** As sent: `+446.7%`. */\n change: string | null\n changePct: number | null\n avgPriceCurrent: number | null\n avgPricePrevious: number | null\n topMovers: Array<{ name: string | null; change: string | null }>\n raw: unknown\n}\n\nexport interface TopCard {\n id: string\n name: string\n number: string | null\n rarity: string | null\n setName: string | null\n setId: string | null\n setCode: string | null\n price: number | null\n change7d: string | null\n raw: unknown\n}\n\nexport interface HistoryPoint {\n /** Snapshot price keyed by days back: 7, 14, 30, 60, 120. */\n price: Record<number, number | null>\n change: Record<number, string | null>\n current: Record<string, number | null>\n lastUpdated: string | null\n}\n\nexport interface PriceHistory {\n id: string\n name: string | null\n tcgplayer: Record<string, HistoryPoint> | null\n cardmarket: Record<string, HistoryPoint> | null\n raw: unknown\n}\n\nexport type SearchOptions = { page?: number; limit?: number }\nexport type SetOptions = { page?: number; limit?: number; language?: string }\nexport type PricesOptions = { source?: 'tcg' | 'cm' }\nexport type StatisticsOptions = { variant?: 'normal' | 'foil' }\nexport type TrendingOptions = { period?: '7d'; limit?: number }\nexport type TopCardsOptions = { metric?: 'price' | 'growth'; source?: 'tcg' | 'cm'; limit?: number }\n\nexport interface Game {\n /** Route prefix and `game` code: `mtg`, `ygo`, ... */\n code: GameCode\n name: string\n /** Free routes, keyed by role: `sets`, `set`, `card`, `search`, `image`. */\n endpoints: Record<string, string>\n /** Plan-gated routes: `prices`, `statistics`, `completion_value`, `trending`, `top_cards`. */\n proEndpoints: Record<string, string>\n raw: unknown\n}\n\nexport interface HealthCheck {\n /** `healthy`, `degraded` or `unhealthy`. */\n status: string\n /** Set by the server when the check failed or is limited. */\n message: string | null\n responseTime: number | null\n}\n\nexport interface Health {\n /** Overall status: `healthy` or `unhealthy`. Only the database and storage are critical. */\n status: string\n timestamp: string | null\n version: string | null\n /** Per-service checks: `database`, `cache`, `storage`. */\n checks: Record<string, HealthCheck>\n responseTime: number | null\n region: string | null\n message: string | null\n raw: unknown\n}\n","import { ValidationError } from './errors.js'\nimport { DEFAULT_BASE_URL } from './version.js'\nimport { GAME_CODES, type GameCode } from './types.js'\n\nexport interface ImageUrlOptions {\n baseUrl?: string\n /** Pokémon only: `low` (default) or `high`. */\n size?: 'low' | 'high'\n /** Pokémon only: localized render (`it`, `fr`, `de`, `es`, `pt`). */\n lang?: string\n /** Pokémon only: set code, to disambiguate a plain card number. */\n set?: string\n}\n\n/**\n * Builds the image URL of a card from its id. Pure string work: nothing is fetched.\n *\n * The image routes are protected like every other route: the request MUST carry the\n * `X-API-Key` header, so the URL cannot be used directly in an `<img>` tag. Fetch it\n * yourself with the header, or proxy it server-side.\n */\nexport function imageUrl(id: string, options: ImageUrlOptions = {}): string {\n const clean = id.trim()\n if (!clean) throw new ValidationError('id is required')\n const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n const game = GAME_CODES.find((g: GameCode) => clean.toLowerCase().startsWith(`${g}_`))\n const path = game ? `/${game}/images/${encodeURIComponent(clean)}` : `/images/${encodeURIComponent(clean)}`\n const qs = new URLSearchParams()\n if (!game) {\n if (options.size) qs.set('size', options.size)\n if (options.lang) qs.set('lang', options.lang)\n if (options.set) qs.set('set', options.set)\n }\n const s = qs.toString()\n return `${base}${path}${s ? `?${s}` : ''}`\n}\n","import type { SetRef } from '../types.js'\n\nexport type Rec = Record<string, unknown>\n\nexport const rec = (v: unknown): Rec => (v && typeof v === 'object' && !Array.isArray(v) ? (v as Rec) : {})\nexport const arr = (v: unknown): unknown[] => (Array.isArray(v) ? v : [])\n\nexport function str(v: unknown): string | null {\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return null\n}\n\n/** Numbers pass through, numeric strings are converted, everything else is null. */\nexport function num(v: unknown): number | null {\n if (typeof v === 'number') return Number.isFinite(v) ? v : null\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n }\n return null\n}\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * Some answers put the numeric set id in a field named `set_code` and omit `set_id`\n * (Pokémon statistics, trending, set listings). When no id is given and the \"code\" is\n * purely numeric, it is the id.\n */\nexport function setPair(code: unknown, id: unknown): { id: string | null; code: string | null } {\n const c = str(code)\n const i = str(id)\n if (i === null && c !== null && NUMERIC_ID.test(c)) return { id: c, code: null }\n return { id: i, code: c }\n}\n\nexport function setRef(name: unknown, code: unknown, id: unknown): SetRef {\n return { ...setPair(code, id), name: str(name) }\n}\n","import { GAME_CODES, type Game, type GameCode, type Health, type HealthCheck } from '../types.js'\nimport { arr, num, rec, str } from './common.js'\n\nfunction strings(v: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(rec(v))) if (typeof val === 'string') out[k] = val\n return out\n}\n\n/** `/games`: `{success, data: [{code, name, endpoints, pro_endpoints}]}` becomes a plain array. */\nexport function normalizeGames(raw: unknown): Game[] {\n return arr(rec(raw).data)\n .map((item): Game | null => {\n const g = rec(item)\n const code = str(g.code)\n if (code === null || !(GAME_CODES as readonly string[]).includes(code)) return null\n return { code: code as GameCode, name: str(g.name) ?? code, endpoints: strings(g.endpoints), proEndpoints: strings(g.pro_endpoints), raw: item }\n })\n .filter((g): g is Game => g !== null)\n}\n\n/** True when a body looks like a health report, whatever the HTTP status. */\nexport function isHealthReport(body: unknown): boolean {\n return typeof rec(body).status === 'string'\n}\n\nexport function normalizeHealth(raw: unknown): Health {\n const r = rec(raw)\n const checks: Record<string, HealthCheck> = {}\n for (const [name, value] of Object.entries(rec(r.checks))) {\n const c = rec(value)\n checks[name] = { status: str(c.status) ?? 'unknown', message: str(c.message), responseTime: num(c.responseTime) }\n }\n return {\n status: str(r.status) ?? 'unknown',\n timestamp: str(r.timestamp),\n version: str(r.version),\n checks,\n responseTime: num(r.responseTime),\n region: str(r.region),\n message: str(r.message),\n raw,\n }\n}\n","import type { CardmarketPrice, TcgPrice } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** `variant` is the finish when the API names one (`sub_type_name` / `variant_type` / `variant`). */\nexport function tcgPrice(v: unknown, variant?: unknown): TcgPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.sub_type_name ?? r.variant),\n low: num(r.low_price),\n mid: num(r.mid_price),\n high: num(r.high_price),\n market: num(r.market_price),\n directLow: num(r.direct_low_price),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n\nexport function cardmarketPrice(v: unknown, variant?: unknown): CardmarketPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.variant_type ?? r.variant),\n avg: num(r.avg),\n low: num(r.low),\n trend: num(r.trend),\n avg1: num(r.avg1),\n avg7: num(r.avg7),\n avg30: num(r.avg30),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n","import type { Card } from '../types.js'\nimport { arr, rec, setPair, str, type Rec } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\n/** Where a card was listed, when the surrounding response knows better than `card_info`. */\nexport interface SetContext {\n setId: string | null\n setCode: string | null\n}\n\nconst KNOWN = new Set([\n 'name', 'clean_name', 'set_name', 'set_code', 'set_id', 'card_number', 'rarity', 'card_type',\n 'product_type', 'variants', 'card_text',\n])\n\n/** Card in the Pokémon shape (Pokémon and the ten games): `{id, card_info, tcgplayer, cardmarket}`. */\nexport function normalizeCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const info = rec(r.card_info)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const pair = ctx ?? { setId: setPair(info.set_code, info.set_id).id, setCode: setPair(info.set_code, info.set_id).code }\n return {\n id: str(r.id) ?? '',\n name: str(info.name) ?? '',\n cleanName: str(info.clean_name),\n number: str(info.card_number),\n rarity: str(info.rarity),\n cardType: str(info.card_type),\n productType: str(info.product_type),\n text: str(info.card_text),\n variants: arr(info.variants).filter((v): v is string => typeof v === 'string'),\n setId: pair.setId,\n setCode: pair.setCode,\n setName: str(info.set_name),\n tcgplayer: tcg ? { url: str(tcg.url), prices: arr(tcg.prices).map((p) => tcgPrice(p)) } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: arr(cm.prices).map((p) => cardmarketPrice(p)) }\n : null,\n info: extras(info),\n raw,\n }\n}\n\nfunction extras(info: Rec): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(info)) if (!KNOWN.has(k)) out[k] = v\n return out\n}\n\n/** One Piece card: flat, `ext_*` fields, a single price object per source. */\nexport function normalizeOpCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const finish = r.sub_type_name\n const info: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(r)) if (k.startsWith('ext_')) info[k] = v\n return {\n id: str(r.id) ?? '',\n name: str(r.name) ?? '',\n cleanName: str(r.clean_name),\n number: str(r.card_number),\n rarity: str(r.rarity),\n cardType: str(r.card_type),\n productType: null,\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n setId: ctx?.setId ?? null,\n setCode: ctx?.setCode ?? null,\n setName: null,\n tcgplayer: tcg ? { url: str(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] }\n : null,\n info,\n raw,\n }\n}\n","import type {\n CompletionValue,\n HistoryPoint,\n PriceHistory,\n PriceRow,\n PriceStats,\n SetPrices,\n SetStatistics,\n TopCard,\n TrendingSet,\n} from '../types.js'\nimport { arr, num, rec, setPair, setRef, str } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\nconst DAYS = [7, 14, 30, 60, 120] as const\n\n/** Set prices. Pokémon and One Piece name the set id `group_id`, the games `set_id`. */\nexport function normalizeSetPrices(raw: unknown): SetPrices {\n const r = rec(raw)\n const pair = setPair(r.set_code, r.set_id ?? r.group_id)\n const rows: PriceRow[] = arr(r.data).map((d) => {\n const row = rec(d)\n return {\n id: str(row.id) ?? '',\n number: str(row.card_number),\n name: str(row.name) ?? '',\n variant: str(row.variant),\n productType: str(row.product_type),\n tcgplayer: row.tcgplayer ? tcgPrice(row.tcgplayer, row.variant) : null,\n cardmarket: row.cardmarket ? cardmarketPrice(row.cardmarket, row.variant) : null,\n }\n })\n return { source: str(r.source) ?? 'both', setId: pair.id, setCode: pair.code, rows, total: num(r.total) ?? rows.length, raw }\n}\n\nfunction priceStats(v: unknown): PriceStats | null {\n if (!v || typeof v !== 'object') return null\n const s = rec(v)\n const top = s.most_expensive ? rec(s.most_expensive) : null\n return {\n avg: num(s.avg_market_price ?? s.avg_price),\n min: num(s.min_price),\n max: num(s.max_price),\n mostExpensive: top ? { id: str(top.id), name: str(top.name), price: num(top.price) } : null,\n trendDirection: str(s.trend_direction),\n }\n}\n\nexport function normalizeStatistics(raw: unknown): SetStatistics {\n const r = rec(raw)\n const info = rec(r.set_info)\n const stats = rec(r.price_statistics)\n const rarity: Record<string, number> = {}\n for (const [k, v] of Object.entries(rec(r.rarity_breakdown))) rarity[k] = num(v) ?? 0\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: priceStats(stats.tcgplayer),\n cardmarket: priceStats(stats.cardmarket),\n rarityBreakdown: rarity,\n raw,\n }\n}\n\nexport function normalizeCompletionValue(raw: unknown): CompletionValue {\n const r = rec(raw)\n const info = rec(r.set_info)\n const cost = rec(r.completion_cost)\n const t = cost.tcgplayer ? rec(cost.tcgplayer) : null\n const c = cost.cardmarket ? rec(cost.cardmarket) : null\n const byRarity: CompletionValue['byRarity'] = {}\n for (const [k, v] of Object.entries(rec(r.breakdown_by_rarity))) {\n byRarity[k] = { count: num(rec(v).count) ?? 0, totalCost: num(rec(v).total_cost) }\n }\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: t ? { currency: str(t.currency), low: num(t.low_estimate), market: num(t.market_estimate), high: num(t.high_estimate) } : null,\n cardmarket: c ? { currency: str(c.currency), low: num(c.low_estimate), avg: num(c.avg_estimate), trend: num(c.trend_estimate) } : null,\n byRarity,\n note: str(cost.note),\n raw,\n }\n}\n\n/** `+446.7%` -> 446.7. */\nfunction pct(v: unknown): number | null {\n const s = str(v)\n return s === null ? null : num(s.replace('%', '').replace('+', ''))\n}\n\nexport function normalizeTrending(raw: unknown): TrendingSet[] {\n return arr(rec(raw).trending_sets).map((item) => {\n const s = rec(item)\n const cm = rec(s.cardmarket)\n return {\n set: setRef(s.set_name, s.set_code, s.set_id),\n cardCount: num(s.card_count),\n change: str(cm.price_change),\n changePct: pct(cm.price_change),\n avgPriceCurrent: num(cm.avg_price_current),\n avgPricePrevious: num(cm.avg_price_previous),\n topMovers: arr(cm.top_movers).map((m) => ({ name: str(rec(m).name), change: str(rec(m).change) })),\n raw: item,\n }\n })\n}\n\nexport function normalizeTopCards(raw: unknown): TopCard[] {\n return arr(rec(raw).top_cards).map((item) => {\n const c = rec(item)\n const info = rec(c.card_info)\n const pair = setPair(info.set_code, info.set_id)\n return {\n id: str(c.id) ?? '',\n name: str(info.name) ?? '',\n number: str(info.card_number),\n rarity: str(info.rarity),\n setName: str(info.set_name),\n setId: pair.id,\n setCode: pair.code,\n price: num(c.current_price),\n change7d: str(c.change_7d),\n raw: item,\n }\n })\n}\n\nfunction historySide(v: unknown): Record<string, HistoryPoint> | null {\n const variants = v && typeof v === 'object' ? rec(rec(v).variants) : null\n if (!variants) return null\n const out: Record<string, HistoryPoint> = {}\n for (const [name, data] of Object.entries(variants)) {\n const d = rec(data)\n const current: Record<string, number | null> = {}\n for (const [k, val] of Object.entries(rec(d.current))) current[k] = num(val)\n const price: Record<number, number | null> = {}\n const change: Record<number, string | null> = {}\n for (const day of DAYS) {\n price[day] = num(d[`price_${day}d`])\n change[day] = str(d[`change_${day}d`])\n }\n out[name] = { price, change, current, lastUpdated: str(d.last_updated) }\n }\n return out\n}\n\nexport function normalizePriceHistory(raw: unknown): PriceHistory {\n const r = rec(raw)\n return { id: str(r.id) ?? '', name: str(r.card_name), tcgplayer: historySide(r.tcgplayer), cardmarket: historySide(r.cardmarket), raw }\n}\n","import type { SetSummary } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** Set entry from any list or detail. One Piece names the id `group_id`, everything else `set_id`. */\nexport function normalizeSet(raw: unknown): SetSummary {\n const r = rec(raw)\n return {\n id: str(r.set_id) ?? str(r.group_id) ?? '',\n code: str(r.set_code),\n name: str(r.name) ?? str(r.set_name) ?? '',\n language: str(r.language),\n releaseDate: str(r.release_date),\n cardCount: num(r.card_count ?? r.total_cards),\n sealedCount: num(r.sealed_count),\n raw,\n }\n}\n","import type { Page } from './types.js'\n\n/** Builds a Page, computing `totalPages` here so it is always a finite number. */\nexport function makePage<T>(items: T[], meta: { page: number; limit: number; total: number }): Page<T> {\n const totalPages = meta.limit > 0 ? Math.ceil(meta.total / meta.limit) : 0\n return { items, page: meta.page, limit: meta.limit, total: meta.total, totalPages }\n}\n\n/**\n * Walks every page of any list endpoint as one async sequence. The two pagination\n * shapes of the API are already hidden behind `fetchPage`.\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<Page<T>>,\n options: { startPage?: number; maxItems?: number } = {},\n): AsyncGenerator<T, void, undefined> {\n let page = options.startPage ?? 1\n let yielded = 0\n for (;;) {\n const res = await fetchPage(page)\n for (const item of res.items) {\n if (options.maxItems !== undefined && yielded >= options.maxItems) return\n yield item\n yielded++\n }\n if (res.items.length === 0 || page >= res.totalPages) return\n page++\n }\n}\n","import { ValidationError } from './errors.js'\n\n/** `page` must be a positive integer. */\nexport function checkPage(page: number | undefined): number | undefined {\n if (page === undefined) return undefined\n if (!Number.isInteger(page) || page < 1) throw new ValidationError(`page must be an integer >= 1 (got ${page})`)\n return page\n}\n\n/** `limit` must be an integer in [1, max]. Checked here so out-of-range values never reach the server. */\nexport function checkLimit(limit: number | undefined, max: number): number | undefined {\n if (limit === undefined) return undefined\n if (!Number.isInteger(limit) || limit < 1 || limit > max) {\n throw new ValidationError(`limit must be an integer between 1 and ${max} (got ${limit})`)\n }\n return limit\n}\n\n/** Only `7d` exists, in every world. */\nexport function checkPeriod(period: string | undefined): '7d' {\n if (period !== undefined && period !== '7d') throw new ValidationError(`period ${period} is not available (only 7d)`)\n return '7d'\n}\n\n/** `variant` is `normal` or `foil`. */\nexport function checkVariant(variant: string | undefined): 'normal' | 'foil' | undefined {\n if (variant === undefined) return undefined\n if (variant !== 'normal' && variant !== 'foil') throw new ValidationError(`variant must be normal or foil (got ${variant})`)\n return variant\n}\n\nexport function checkText(name: string, value: string, min = 1): string {\n if (typeof value !== 'string' || value.trim().length < min) {\n throw new ValidationError(`${name} must be at least ${min} character${min === 1 ? '' : 's'} long`)\n }\n return value.trim()\n}\n\n/** Path segment for a user-supplied id or set code. */\nexport function seg(value: string): string {\n return encodeURIComponent(checkText('id', value))\n}\n","import type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\n\n/**\n * The one interface shared by Pokémon, One Piece and the ten games. Where the API\n * needs a different route, parameter or response shape, the world hides it.\n *\n * Plan-gated methods (`prices`, `statistics`, `completionValue`, `trending`, `topCards`)\n * throw `PlanRequiredError` when the account's plan or trial does not cover them.\n * An ambiguous set code throws `AmbiguousSetError`; retry with one of its `matches[].setId`.\n */\nexport interface World {\n /** One page of search results. `q` is 2-100 characters for the ten games. */\n search(q: string, options?: SearchOptions): Promise<SearchPage>\n /** Every result of a search, page after page. */\n searchAll(q: string, options?: { limit?: number; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Card by id (`pk_…`, `op_…`, `<code>_…`, or a 64-hex CardMarket id). */\n card(id: string): Promise<Card>\n /** All sets of the world. The API does not paginate this list. */\n sets(options?: { language?: string }): Promise<SetSummary[]>\n /** One page of a set's cards. `code` is a set code or a numeric set id. */\n set(code: string, options?: SetOptions): Promise<SetPage>\n /** Every card of a set, page after page. */\n setCards(code: string, options?: { limit?: number; language?: string; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Prices of every card in a set: hundreds to thousands of rows. */\n prices(code: string, options?: PricesOptions): Promise<SetPrices>\n statistics(code: string, options?: StatisticsOptions): Promise<SetStatistics>\n completionValue(code: string): Promise<CompletionValue>\n trending(options?: TrendingOptions): Promise<TrendingSet[]>\n topCards(options?: TopCardsOptions): Promise<TopCard[]>\n}\n\nexport const LIMITS = { search: 100, set: 200, trending: 50, topCards: 100 } as const\n","import { ambiguousSetError, isDisambiguation } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nexport interface CardWorldConfig {\n /** Route prefix: `''` for Pokémon, `/mtg` for a game. */\n prefix: string\n /** Minimum search length: the games reject queries shorter than 2 characters. */\n minQuery: number\n}\n\n/** Pokémon and the ten games share one response shape, so one class serves them all. */\nexport class CardWorld implements World {\n constructor(\n protected readonly http: HttpClient,\n protected readonly config: CardWorldConfig,\n ) {}\n\n protected path(rest: string): string {\n return `${this.config.prefix}${rest}`\n }\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get(this.path('/search'), {\n q: checkText('q', q, this.config.minQuery),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const p = rec(body.pagination)\n const items = arr(body.results).map((c) => normalizeCard(c))\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, truncated: rec(body.metadata).truncated === true }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeCard(await this.http.get(this.path(`/cards/${seg(id)}`)))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get(this.path('/sets'), { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(this.path(`/sets/${seg(code)}`), {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n language: options.language,\n }),\n )\n // 200 with a candidate list instead of cards: same condition as the 300/409 answers.\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n const set = normalizeSet(body.set)\n // A set listing names its set once: use the set object for every card.\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.cards).map((c) => normalizeCard(c, ctx))\n const p = rec(body.pagination)\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit, language: options.language }), {\n maxItems: options.maxItems,\n })\n }\n\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n return normalizeSetPrices(await this.http.get(this.path(`/prices/${seg(code)}`), { source: options.source }))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(this.path(`/sets/${seg(code)}/statistics`), { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(this.path(`/sets/${seg(code)}/completion-value`)))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get(this.path('/sets/trending'), { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get(this.path('/analytics/top-cards'), {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n\n","import { ValidationError } from '../errors.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeOpCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * One Piece lives under `/op` with its own shapes: flat cards, flat pagination\n * (`{data,total,page,limit}`), `group_id` instead of `set_id`, and set prices selected\n * through the query string. This class hides all of it behind the shared interface.\n */\nexport class OnePieceWorld implements World {\n constructor(private readonly http: HttpClient) {}\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get('/op/search', {\n q: checkText('q', q),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const items = arr(body.data).map((c) => normalizeOpCard(c))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, truncated: false }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeOpCard(await this.http.get(`/op/cards/${seg(id)}`))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get('/op/sets', { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n /** `options.language` is ignored: One Piece maps a code to its first matching set. */\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(`/op/sets/${seg(code)}`, {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n }),\n )\n const set = normalizeSet(body.set)\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.data).map((c) => normalizeOpCard(c, ctx))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n /** The set goes in the query here (`group_id` for numeric ids, `set_code` otherwise). */\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n if (options.source !== undefined) throw new ValidationError('source is not supported for One Piece prices')\n const c = checkText('code', code)\n const query = NUMERIC_ID.test(c) ? { group_id: c } : { set_code: c }\n return normalizeSetPrices(await this.http.get('/op/prices', query))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(`/op/sets/${seg(code)}/statistics`, { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(`/op/sets/${seg(code)}/completion-value`))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get('/op/sets/trending', { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get('/op/analytics/top-cards', {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n","import { isDisambiguation, ambiguousSetError } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { normalizePriceHistory } from '../normalize/pro.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport type { Card, PriceHistory } from '../types.js'\nimport { seg } from '../validation.js'\nimport { CardWorld } from './card-world.js'\n\n/** Pokémon: the shared card world plus the endpoints only Pokémon has. */\nexport class PokemonWorld extends CardWorld {\n constructor(http: HttpClient) {\n super(http, { prefix: '', minQuery: 1 })\n }\n\n /**\n * Card by id, or by plain card number together with `setCode` (`card('086/078', { setCode: 'SV8a' })`).\n * Ids from `search` and `set` are the safest input.\n */\n override async card(id: string, options: { setCode?: string } = {}): Promise<Card> {\n const body = await this.http.get(this.path(`/cards/${seg(id)}`), { set_code: options.setCode })\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n return normalizeCard(body)\n }\n\n /** Price snapshots at 7/14/30/60/120 days, per finish (not a time series). Pro or trial. */\n async priceHistory(id: string): Promise<PriceHistory> {\n return normalizePriceHistory(await this.http.get(`/cards/${seg(id)}/price-history`))\n }\n}\n","import { HttpClient, type ClientOptions, type RateLimitInfo } from './http.js'\nimport { imageUrl, type ImageUrlOptions } from './images.js'\nimport { normalizeGames, normalizeHealth, isHealthReport } from './normalize/misc.js'\nimport { GAME_CODES, type Game, type GameCode, type Health } from './types.js'\nimport { CardWorld } from './worlds/card-world.js'\nimport { OnePieceWorld } from './worlds/onepiece-world.js'\nimport { PokemonWorld } from './worlds/pokemon-world.js'\nimport type { World } from './worlds/world.js'\n\n/**\n * Entry point. One interface for every world:\n *\n * ```ts\n * const pw = new PokeWallet({ apiKey: process.env.POKEWALLET_API_KEY })\n * await pw.pokemon.search('charizard')\n * await pw.onepiece.set('OP01')\n * await pw.games.mtg.search('black lotus')\n * ```\n */\nexport class PokeWallet {\n readonly pokemon: PokemonWorld\n readonly onepiece: World\n readonly games: Readonly<Record<GameCode, World>>\n\n readonly #http: HttpClient\n readonly #baseUrl: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.#http = new HttpClient(options)\n this.#baseUrl = options.baseUrl\n this.pokemon = new PokemonWorld(this.#http)\n this.onepiece = new OnePieceWorld(this.#http)\n const games = {} as Record<GameCode, World>\n for (const code of GAME_CODES) {\n games[code] = new CardWorld(this.#http, { prefix: `/${code}`, minQuery: 2 })\n }\n this.games = games\n }\n\n /** Quota counters from the most recent answer, or null before the first call. */\n get lastRateLimit(): RateLimitInfo | null {\n return this.#http.lastRateLimit\n }\n\n /** The world for a game code known only at runtime. */\n game(code: GameCode): World {\n return this.games[code]\n }\n\n /**\n * Service status. Works without a key; the header is sent only when a key is set.\n *\n * The API answers 503 with a full report when a critical service is down. That report is\n * information, not a failure: it is returned like a 200, with `status: 'unhealthy'` and the\n * failing `checks`, and is never retried. A 503 without a report (for example an error page\n * from the edge) still throws `UnavailableError`.\n */\n async health(): Promise<Health> {\n return normalizeHealth(await this.#http.get('/health', undefined, { isPublic: true, accept: isHealthReport }))\n }\n\n /** The ten games with their route maps. Works without a key. */\n async listGames(): Promise<Game[]> {\n return normalizeGames(await this.#http.get('/games', undefined, { isPublic: true }))\n }\n\n toJSON(): { client: unknown } {\n return { client: this.#http.toJSON() }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `PokeWallet ${JSON.stringify(this.toJSON())}`\n }\n\n /** See {@link imageUrl}: the URL still needs the API key header. */\n imageUrl(id: string, options: Omit<ImageUrlOptions, 'baseUrl'> = {}): string {\n return imageUrl(id, { ...options, baseUrl: this.#baseUrl })\n }\n}\n"],"mappings":"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","names":["str","num","str","num","str","num","str","str","num","str","num","num","NUMERIC_ID","num"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/error-map.ts","../src/version.ts","../src/http.ts","../src/types.ts","../src/images.ts","../src/normalize/common.ts","../src/normalize/misc.ts","../src/normalize/prices.ts","../src/normalize/card.ts","../src/normalize/pro.ts","../src/normalize/sets.ts","../src/pagination.ts","../src/validation.ts","../src/worlds/world.ts","../src/worlds/card-world.ts","../src/worlds/onepiece-world.ts","../src/worlds/pokemon-world.ts","../src/client.ts"],"sourcesContent":["export { PokeWallet } from './client.js'\nexport { imageUrl, type ImageUrlOptions } from './images.js'\nexport { paginate } from './pagination.js'\nexport type { ClientOptions, FetchLike, RateLimitInfo } from './http.js'\nexport type { World } from './worlds/world.js'\nexport type { PokemonWorld } from './worlds/pokemon-world.js'\nexport * from './errors.js'\nexport * from './types.js'\nexport { VERSION } from './version.js'\n/** Raw wire types generated from `openapi/pokewallet.yaml`, for code that wants the unnormalized shapes. */\nexport type { paths, components, operations } from './generated/schema.js'\n","/** Hourly or daily quota window as reported in a 429 body. */\nexport interface LimitWindow {\n limit: number\n used: number\n remaining: number\n}\n\nexport interface RateLimitWindows {\n hourly?: LimitWindow\n daily?: LimitWindow\n}\n\n/** One candidate of an ambiguous set. `setId` is the value to pass back to pick it. */\nexport interface SetMatch {\n setId: string\n setCode: string | null\n name: string | null\n language: string | null\n releaseDate: string | null\n}\n\nexport interface ErrorInit {\n status: number\n body?: unknown\n message?: string\n}\n\n/** Base class of every error raised by the SDK for an API answer. */\nexport class PokeWalletError extends Error {\n readonly status: number\n /** Parsed JSON body of the answer, when there was one. */\n readonly body: unknown\n /** The `error` field of the body, when present. */\n readonly code: string | undefined\n\n constructor(init: ErrorInit) {\n const code = bodyString(init.body, 'error')\n super(init.message ?? bodyString(init.body, 'message') ?? code ?? `HTTP ${init.status}`)\n this.name = new.target.name\n this.status = init.status\n this.body = init.body\n this.code = code\n }\n}\n\n/** Raised before any request when an argument is out of range. */\nexport class ValidationError extends RangeError {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/** The request never produced an HTTP answer (DNS, connection, timeout). */\nexport class NetworkError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'NetworkError'\n }\n}\n\n/** 400: missing or invalid parameter, or an id that cannot be decoded. */\nexport class BadRequestError extends PokeWalletError {}\n\n/** 401: key missing, malformed or unknown. */\nexport class AuthError extends PokeWalletError {}\n\n/**\n * 403 on a plan-gated endpoint. `redeemUrl` is set when the free trial was never\n * activated; `upgradeUrl` when the trial expired or the plan is too low.\n */\nexport class PlanRequiredError extends PokeWalletError {\n readonly redeemUrl: string | undefined\n readonly upgradeUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.redeemUrl = bodyString(init.body, 'redeem_url')\n this.upgradeUrl = bodyString(init.body, 'upgrade_url')\n }\n}\n\n/** 403 `Feature not enabled`: this account does not have access to this feature. */\nexport class FeatureNotEnabledError extends PokeWalletError {\n readonly contactUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.contactUrl = bodyString(init.body, 'contact_url')\n }\n}\n\n/** 404: unknown card, set or route. Carries the server's suggestions when it sent any. */\nexport class NotFoundError extends PokeWalletError {\n readonly didYouMean: string | undefined\n readonly suggestions: unknown[]\n\n constructor(init: ErrorInit) {\n super(init)\n this.didYouMean = bodyString(init.body, 'did_you_mean')\n const s = (init.body as { suggestions?: unknown } | null | undefined)?.suggestions\n this.suggestions = Array.isArray(s) ? s : []\n }\n}\n\n/** 404 on a game route: the game is switched off for this account. */\nexport class GameUnavailableError extends NotFoundError {}\n\n/**\n * The set code matches several sets. Unifies the three ways the API says so\n * (200 with `disambiguation`, 300, 409). Retry with one `matches[i].setId`.\n */\nexport class AmbiguousSetError extends PokeWalletError {\n readonly matches: SetMatch[]\n\n constructor(init: ErrorInit & { matches: SetMatch[] }) {\n super({ ...init, message: init.message ?? 'Several sets match this code: pick one by setId' })\n this.matches = init.matches\n }\n}\n\n/**\n * 429. The API sends no `Retry-After`, so the SDK retries only when the header is\n * present and within the cap. `limits` mirrors the body: when a window shows\n * `remaining === 0`, waiting seconds cannot help.\n */\nexport class RateLimitError extends PokeWalletError {\n readonly limits: RateLimitWindows\n /** Seconds, from the `Retry-After` header, when present. */\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n const l = (init.body as { limits?: Record<string, unknown> } | null | undefined)?.limits\n this.limits = { hourly: toWindow(l?.hourly), daily: toWindow(l?.daily) }\n }\n}\n\n/** 503: database busy or feature not yet enabled. `retryAfter` is 5 or 3600 seconds. */\nexport class UnavailableError extends PokeWalletError {\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n }\n}\n\n/** Any other 5xx. Never retried. */\nexport class ServerError extends PokeWalletError {}\n\nfunction bodyString(body: unknown, key: string): string | undefined {\n const v = (body as Record<string, unknown> | null | undefined)?.[key]\n return typeof v === 'string' ? v : undefined\n}\n\nfunction toWindow(v: unknown): LimitWindow | undefined {\n if (!v || typeof v !== 'object') return undefined\n const w = v as Record<string, unknown>\n if (typeof w.limit !== 'number' || typeof w.used !== 'number' || typeof w.remaining !== 'number') return undefined\n return { limit: w.limit, used: w.used, remaining: w.remaining }\n}\n","import {\n AmbiguousSetError,\n AuthError,\n BadRequestError,\n FeatureNotEnabledError,\n GameUnavailableError,\n NotFoundError,\n PlanRequiredError,\n PokeWalletError,\n RateLimitError,\n ServerError,\n UnavailableError,\n type SetMatch,\n} from './errors.js'\n\ninterface RawMatch {\n set_id?: unknown\n set_code?: unknown\n name?: unknown\n language?: unknown\n release_date?: unknown\n}\n\nconst str = (v: unknown): string | null => (typeof v === 'string' ? v : typeof v === 'number' ? String(v) : null)\n\n/** Converts the `matches` array of any ambiguous-set body into the public shape. */\nexport function toSetMatches(body: unknown): SetMatch[] {\n const raw = (body as { matches?: unknown } | null | undefined)?.matches\n if (!Array.isArray(raw)) return []\n return raw.map((m: RawMatch) => ({\n setId: str(m.set_id) ?? '',\n setCode: str(m.set_code),\n name: str(m.name),\n language: str(m.language),\n releaseDate: str(m.release_date),\n }))\n}\n\n/** True for the 200 body the API uses to say \"several sets match\". */\nexport function isDisambiguation(body: unknown): boolean {\n return !!body && typeof body === 'object' && (body as { disambiguation?: unknown }).disambiguation === true\n}\n\nexport function ambiguousSetError(status: number, body: unknown): AmbiguousSetError {\n return new AmbiguousSetError({ status, body, matches: toSetMatches(body) })\n}\n\nexport interface ErrorContext {\n status: number\n body: unknown\n retryAfter: number | undefined\n /** True when the request went to one of the ten `/{game}` prefixes. */\n gameRoute: boolean\n}\n\n/** Maps a non-success answer to its typed error. Pure: no retry decisions here. */\nexport function errorFromResponse(ctx: ErrorContext): PokeWalletError {\n const { status, body, retryAfter, gameRoute } = ctx\n const init = { status, body }\n const code = (body as { error?: unknown } | null | undefined)?.error\n\n if (status === 300 || (status === 409 && isDisambiguation(body)) || (status === 409 && code === 'Ambiguous set code')) {\n return ambiguousSetError(status, body)\n }\n switch (status) {\n case 400:\n return new BadRequestError(init)\n case 401:\n return new AuthError(init)\n case 403:\n return code === 'Feature not enabled' ? new FeatureNotEnabledError(init) : new PlanRequiredError(init)\n case 404:\n // A switched-off game answers with the generic route 404, not a resource 404.\n return gameRoute && code === 'Endpoint not found' ? new GameUnavailableError(init) : new NotFoundError(init)\n case 429:\n return new RateLimitError({ ...init, retryAfter })\n case 503:\n return new UnavailableError({ ...init, retryAfter })\n default:\n return status >= 500 ? new ServerError(init) : new PokeWalletError(init)\n }\n}\n","export const VERSION = '0.1.6'\nexport const DEFAULT_BASE_URL = 'https://api.pokewallet.io'\nexport const DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`\n","import { ValidationError, NetworkError, RateLimitError, type PokeWalletError } from './errors.js'\nimport { errorFromResponse } from './error-map.js'\nimport { DEFAULT_BASE_URL, DEFAULT_USER_AGENT } from './version.js'\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface ClientOptions {\n /**\n * API key (`pk_…`). Falls back to the `POKEWALLET_API_KEY` environment variable. Optional at\n * construction: only `health()` and `listGames()` work without one, every other call throws\n * `ValidationError` before touching the network.\n */\n apiKey?: string\n baseUrl?: string\n /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */\n userAgent?: string\n /**\n * Sent as `X-PokeWallet-Client`, so the API can tell which integration made a call. Browsers\n * cannot set `User-Agent`, so this is the only identification they can send. Default\n * `pokewallet-sdk-ts/<version>`.\n */\n client?: string\n /** Custom `fetch`, mainly for tests. Defaults to the global one. */\n fetch?: FetchLike\n /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */\n maxRetries?: number\n /** Longest `Retry-After` the SDK will sit through, in seconds. Default 30. */\n retryAfterCapSeconds?: number\n /** Per-request timeout in milliseconds. Default 30000. */\n timeoutMs?: number\n /** Replaces the delay between retries, mainly for tests. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Quota counters from the `X-RateLimit-*` headers of the last answer. */\nexport interface RateLimitInfo {\n limitHour: number | null\n remainingHour: number | null\n limitDay: number | null\n remainingDay: number | null\n}\n\nexport type Query = Record<string, string | number | boolean | undefined | null>\n\nconst GAME_PREFIX = /^\\/(mtg|ygo|cfv|dbs|fab|dgm|swu|lor|rft|cpk)\\//\n\nexport const KEY_REQUIRED = 'An API key is required: pass apiKey or set POKEWALLET_API_KEY'\n\n/** The key from the options or the environment; undefined when there is none (public endpoints still work). */\nfunction readKey(options: ClientOptions): string | undefined {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env\n const key = (options.apiKey ?? env?.POKEWALLET_API_KEY ?? '').trim()\n if (!key) return undefined\n if (!key.startsWith('pk_')) throw new ValidationError('API keys start with \"pk_\"')\n return key\n}\n\n/** Seconds from a `Retry-After` value (delta-seconds or HTTP date), or undefined. */\nexport function parseRetryAfter(value: string | null, now = Date.now()): number | undefined {\n if (value == null || value.trim() === '') return undefined\n const n = Number(value)\n if (Number.isFinite(n) && n >= 0) return n\n const t = Date.parse(value)\n return Number.isNaN(t) ? undefined : Math.max(0, Math.ceil((t - now) / 1000))\n}\n\nfunction num(h: Headers, name: string): number | null {\n const v = h.get(name)\n if (v == null) return null\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n}\n\nfunction exhausted(err: RateLimitError): boolean {\n return [err.limits.hourly, err.limits.daily].some((w) => w !== undefined && w.remaining <= 0)\n}\n\nexport class HttpClient {\n /** Quota counters of the most recent answer that carried them. */\n lastRateLimit: RateLimitInfo | null = null\n\n readonly #key: string | undefined\n private readonly baseUrl: string\n private readonly userAgent: string\n private readonly client: string\n private readonly fetchImpl: FetchLike\n private readonly maxRetries: number\n private readonly capSeconds: number\n private readonly timeoutMs: number\n private readonly sleep: (ms: number) => Promise<void>\n\n constructor(options: ClientOptions = {}) {\n this.#key = readKey(options)\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT\n this.client = options.client ?? DEFAULT_USER_AGENT\n const g = globalThis as { fetch?: FetchLike }\n const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : undefined)\n if (!f) throw new ValidationError('No fetch available: pass options.fetch (Node 18+ has one built in)')\n this.fetchImpl = f\n this.maxRetries = options.maxRetries ?? 2\n this.capSeconds = options.retryAfterCapSeconds ?? 30\n this.timeoutMs = options.timeoutMs ?? 30_000\n this.sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)))\n }\n\n url(path: string, query?: Query): string {\n const qs = new URLSearchParams()\n for (const [k, v] of Object.entries(query ?? {})) if (v !== undefined && v !== null) qs.set(k, String(v))\n const s = qs.toString()\n return `${this.baseUrl}${path}${s ? `?${s}` : ''}`\n }\n\n /**\n * GET `path` and return the parsed JSON body; throws a typed error otherwise. `isPublic`\n * marks the two endpoints the server answers without a key; everything else needs one.\n * `accept` lets a caller treat a non-2xx body as data (see `health()`).\n */\n async get<T>(\n path: string,\n query?: Query,\n options: { isPublic?: boolean; accept?: (body: unknown) => boolean } = {},\n ): Promise<T> {\n if (this.#key === undefined && !options.isPublic) throw new ValidationError(KEY_REQUIRED)\n const url = this.url(path, query)\n for (let attempt = 0; ; attempt++) {\n const res = await this.send(url)\n const body = parseJson(this.#redact(await res.text()))\n this.trackQuota(res.headers)\n if (res.status >= 200 && res.status < 300) return body as T\n // Some non-2xx answers are data, not failures (an \"unhealthy\" report): return them as is, no retry.\n if (options.accept?.(body)) return body as T\n\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'))\n const err = errorFromResponse({ status: res.status, body, retryAfter, gameRoute: GAME_PREFIX.test(path) })\n if (attempt < this.maxRetries && this.shouldRetry(err, retryAfter)) {\n await this.sleep((retryAfter ?? 1) * 1000)\n continue\n }\n throw err\n }\n }\n\n private shouldRetry(err: PokeWalletError, retryAfter: number | undefined): boolean {\n if (err.status === 429) {\n // Never guess a wait: no header, or an exhausted window, means retrying is pointless.\n return retryAfter !== undefined && retryAfter <= this.capSeconds && !exhausted(err as RateLimitError)\n }\n if (err.status === 503) return (retryAfter ?? 1) <= this.capSeconds\n return false\n }\n\n private async send(url: string): Promise<Response> {\n try {\n return await this.fetchImpl(url, {\n method: 'GET',\n headers: {\n ...(this.#key === undefined ? {} : { 'X-API-Key': this.#key }),\n 'User-Agent': this.userAgent,\n 'X-PokeWallet-Client': this.client,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n } catch (cause) {\n throw new NetworkError('Request failed before an answer arrived', { cause: this.#scrubError(cause) })\n }\n }\n\n /** Masked form: the only representation of this object that logging or serializing can reach. */\n toJSON(): { baseUrl: string; userAgent: string; apiKey: string | null } {\n return { baseUrl: this.baseUrl, userAgent: this.userAgent, apiKey: this.#key === undefined ? null : 'pk_***' }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `HttpClient ${JSON.stringify(this.toJSON())}`\n }\n\n #redact(text: string): string {\n return this.#key === undefined ? text : text.split(this.#key).join('pk_***')\n }\n\n /** A copy of a thrown value with the key removed from its message, stack and string fields. */\n #scrubError(cause: unknown): unknown {\n if (!(cause instanceof Error)) return typeof cause === 'string' ? this.#redact(cause) : undefined\n const copy = new Error(this.#redact(cause.message))\n copy.name = cause.name\n if (cause.stack) copy.stack = this.#redact(cause.stack)\n const code = (cause as { code?: unknown }).code\n if (typeof code === 'string') (copy as { code?: string }).code = code\n return copy\n }\n\n private trackQuota(h: Headers): void {\n const info: RateLimitInfo = {\n limitHour: num(h, 'x-ratelimit-limit-hour'),\n remainingHour: num(h, 'x-ratelimit-remaining-hour'),\n limitDay: num(h, 'x-ratelimit-limit-day'),\n remainingDay: num(h, 'x-ratelimit-remaining-day'),\n }\n if (Object.values(info).some((v) => v !== null)) this.lastRateLimit = info\n }\n}\n\nfunction parseJson(text: string): unknown {\n if (!text) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return { error: text.slice(0, 200) }\n }\n}\n","/**\n * Public, normalized types. Every object keeps the unmodified server value in `raw`.\n * Prices are `number | null`; the API sometimes sends numeric strings.\n */\n\nexport const GAME_CODES = ['mtg', 'ygo', 'cfv', 'dbs', 'fab', 'dgm', 'swu', 'lor', 'rft', 'cpk'] as const\nexport type GameCode = (typeof GAME_CODES)[number]\n\nexport interface TcgPrice {\n /** Finish (`Normal`, `Holofoil`, `Foil`...). Null for rows that have no finish. */\n variant: string | null\n low: number | null\n mid: number | null\n high: number | null\n market: number | null\n directLow: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface CardmarketPrice {\n variant: string | null\n avg: number | null\n low: number | null\n trend: number | null\n avg1: number | null\n avg7: number | null\n avg30: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface Card {\n /** `pk_…` (Pokémon), `op_…`, `<code>_…`, or a 64-character hex CardMarket id. Reuse as is. */\n id: string\n name: string\n cleanName: string | null\n number: string | null\n rarity: string | null\n cardType: string | null\n productType: string | null\n text: string | null\n variants: string[]\n /**\n * Set identifiers. `setId` is the numeric id (possibly negative); `setCode` the short code.\n * Source: `card_info.set_id` / `card_info.set_code`; for cards listed by a set, both come from the\n * response's `set` object.\n * One Piece search and detail answers carry neither, so both are null there.\n */\n setId: string | null\n setCode: string | null\n setName: string | null\n tcgplayer: { url: string | null; prices: TcgPrice[] } | null\n cardmarket: { productName: string | null; url: string | null; prices: CardmarketPrice[] } | null\n /** Game-specific fields: `hp`, `attacks`, `p`, `t`, `ext_color`... as sent by the API. */\n info: Record<string, unknown>\n raw: unknown\n}\n\nexport interface SetSummary {\n /** Numeric set id as a string (`set_id`; `group_id` for One Piece). */\n id: string\n code: string | null\n name: string\n /** Free text. Pokémon uses `eng`/`jap`/`chn`, One Piece `en`/`jp`. */\n language: string | null\n releaseDate: string | null\n cardCount: number | null\n sealedCount: number | null\n raw: unknown\n}\n\nexport interface Page<T> {\n items: T[]\n page: number\n limit: number\n total: number\n /** Computed from `total` and `limit`, so it is always a finite number. */\n totalPages: number\n}\n\nexport interface SearchPage extends Page<Card> {\n /** Pokémon and games: the candidate list was cut at its cap, refine the query instead of paging. Always false for One Piece. */\n truncated: boolean\n}\n\nexport interface SetPage extends Page<Card> {\n set: SetSummary\n}\n\nexport interface PriceRow {\n id: string\n number: string | null\n name: string\n variant: string | null\n productType: string | null\n tcgplayer: TcgPrice | null\n cardmarket: CardmarketPrice | null\n}\n\nexport interface SetPrices {\n source: string\n setId: string | null\n setCode: string | null\n rows: PriceRow[]\n total: number\n raw: unknown\n}\n\nexport interface SetRef {\n id: string | null\n code: string | null\n name: string | null\n}\n\nexport interface PriceStats {\n avg: number | null\n min: number | null\n max: number | null\n mostExpensive: { id: string | null; name: string | null; price: number | null } | null\n trendDirection: string | null\n}\n\nexport interface SetStatistics {\n set: SetRef & { totalCards: number | null }\n tcgplayer: PriceStats | null\n cardmarket: PriceStats | null\n rarityBreakdown: Record<string, number>\n raw: unknown\n}\n\nexport interface CompletionValue {\n set: SetRef & { totalCards: number | null }\n tcgplayer: { currency: string | null; low: number | null; market: number | null; high: number | null } | null\n cardmarket: { currency: string | null; low: number | null; avg: number | null; trend: number | null } | null\n byRarity: Record<string, { count: number; totalCost: number | null }>\n note: string | null\n raw: unknown\n}\n\nexport interface TrendingSet {\n set: SetRef\n cardCount: number | null\n /** As sent: `+446.7%`. */\n change: string | null\n changePct: number | null\n avgPriceCurrent: number | null\n avgPricePrevious: number | null\n topMovers: Array<{ name: string | null; change: string | null }>\n raw: unknown\n}\n\nexport interface TopCard {\n id: string\n name: string\n number: string | null\n rarity: string | null\n setName: string | null\n setId: string | null\n setCode: string | null\n price: number | null\n change7d: string | null\n raw: unknown\n}\n\nexport interface HistoryPoint {\n /** Snapshot price keyed by days back: 7, 14, 30, 60, 120. */\n price: Record<number, number | null>\n change: Record<number, string | null>\n current: Record<string, number | null>\n lastUpdated: string | null\n}\n\nexport interface PriceHistory {\n id: string\n name: string | null\n tcgplayer: Record<string, HistoryPoint> | null\n cardmarket: Record<string, HistoryPoint> | null\n raw: unknown\n}\n\nexport type SearchOptions = { page?: number; limit?: number }\nexport type SetOptions = { page?: number; limit?: number; language?: string }\nexport type PricesOptions = { source?: 'tcg' | 'cm' }\nexport type StatisticsOptions = { variant?: 'normal' | 'foil' }\nexport type TrendingOptions = { period?: '7d'; limit?: number }\nexport type TopCardsOptions = { metric?: 'price' | 'growth'; source?: 'tcg' | 'cm'; limit?: number }\n\nexport interface Game {\n /** Route prefix and `game` code: `mtg`, `ygo`, ... */\n code: GameCode\n name: string\n /** Free routes, keyed by role: `sets`, `set`, `card`, `search`, `image`. */\n endpoints: Record<string, string>\n /** Plan-gated routes: `prices`, `statistics`, `completion_value`, `trending`, `top_cards`. */\n proEndpoints: Record<string, string>\n raw: unknown\n}\n\nexport interface HealthCheck {\n /** `healthy`, `degraded` or `unhealthy`. */\n status: string\n /** Set by the server when the check failed or is limited. */\n message: string | null\n responseTime: number | null\n}\n\nexport interface Health {\n /** Overall status: `healthy` or `unhealthy`. Only the database and storage are critical. */\n status: string\n timestamp: string | null\n version: string | null\n /** Per-service checks: `database`, `cache`, `storage`. */\n checks: Record<string, HealthCheck>\n responseTime: number | null\n region: string | null\n message: string | null\n raw: unknown\n}\n","import { ValidationError } from './errors.js'\nimport { DEFAULT_BASE_URL } from './version.js'\nimport { GAME_CODES, type GameCode } from './types.js'\n\nexport interface ImageUrlOptions {\n baseUrl?: string\n /** Pokémon only: `low` (default) or `high`. */\n size?: 'low' | 'high'\n /** Pokémon only: localized render (`it`, `fr`, `de`, `es`, `pt`). */\n lang?: string\n /** Pokémon only: set code, to disambiguate a plain card number. */\n set?: string\n}\n\n/**\n * Builds the image URL of a card from its id. Pure string work: nothing is fetched.\n *\n * The image routes are protected like every other route: the request MUST carry the\n * `X-API-Key` header, so the URL cannot be used directly in an `<img>` tag. Fetch it\n * yourself with the header, or proxy it server-side.\n */\nexport function imageUrl(id: string, options: ImageUrlOptions = {}): string {\n const clean = id.trim()\n if (!clean) throw new ValidationError('id is required')\n const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n const game = GAME_CODES.find((g: GameCode) => clean.toLowerCase().startsWith(`${g}_`))\n const path = game ? `/${game}/images/${encodeURIComponent(clean)}` : `/images/${encodeURIComponent(clean)}`\n const qs = new URLSearchParams()\n if (!game) {\n if (options.size) qs.set('size', options.size)\n if (options.lang) qs.set('lang', options.lang)\n if (options.set) qs.set('set', options.set)\n }\n const s = qs.toString()\n return `${base}${path}${s ? `?${s}` : ''}`\n}\n","import type { SetRef } from '../types.js'\n\nexport type Rec = Record<string, unknown>\n\nexport const rec = (v: unknown): Rec => (v && typeof v === 'object' && !Array.isArray(v) ? (v as Rec) : {})\nexport const arr = (v: unknown): unknown[] => (Array.isArray(v) ? v : [])\n\nexport function str(v: unknown): string | null {\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return null\n}\n\n/** Numbers pass through, numeric strings are converted, everything else is null. */\nexport function num(v: unknown): number | null {\n if (typeof v === 'number') return Number.isFinite(v) ? v : null\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n }\n return null\n}\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * Some answers put the numeric set id in a field named `set_code` and omit `set_id`\n * (Pokémon statistics, trending, set listings). When no id is given and the \"code\" is\n * purely numeric, it is the id.\n */\nexport function setPair(code: unknown, id: unknown): { id: string | null; code: string | null } {\n const c = str(code)\n const i = str(id)\n if (i === null && c !== null && NUMERIC_ID.test(c)) return { id: c, code: null }\n return { id: i, code: c }\n}\n\nexport function setRef(name: unknown, code: unknown, id: unknown): SetRef {\n return { ...setPair(code, id), name: str(name) }\n}\n","import { GAME_CODES, type Game, type GameCode, type Health, type HealthCheck } from '../types.js'\nimport { arr, num, rec, str } from './common.js'\n\nfunction strings(v: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(rec(v))) if (typeof val === 'string') out[k] = val\n return out\n}\n\n/** `/games`: `{success, data: [{code, name, endpoints, pro_endpoints}]}` becomes a plain array. */\nexport function normalizeGames(raw: unknown): Game[] {\n return arr(rec(raw).data)\n .map((item): Game | null => {\n const g = rec(item)\n const code = str(g.code)\n if (code === null || !(GAME_CODES as readonly string[]).includes(code)) return null\n return { code: code as GameCode, name: str(g.name) ?? code, endpoints: strings(g.endpoints), proEndpoints: strings(g.pro_endpoints), raw: item }\n })\n .filter((g): g is Game => g !== null)\n}\n\n/** True when a body looks like a health report, whatever the HTTP status. */\nexport function isHealthReport(body: unknown): boolean {\n return typeof rec(body).status === 'string'\n}\n\nexport function normalizeHealth(raw: unknown): Health {\n const r = rec(raw)\n const checks: Record<string, HealthCheck> = {}\n for (const [name, value] of Object.entries(rec(r.checks))) {\n const c = rec(value)\n checks[name] = { status: str(c.status) ?? 'unknown', message: str(c.message), responseTime: num(c.responseTime) }\n }\n return {\n status: str(r.status) ?? 'unknown',\n timestamp: str(r.timestamp),\n version: str(r.version),\n checks,\n responseTime: num(r.responseTime),\n region: str(r.region),\n message: str(r.message),\n raw,\n }\n}\n","import type { CardmarketPrice, TcgPrice } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** `variant` is the finish when the API names one (`sub_type_name` / `variant_type` / `variant`). */\nexport function tcgPrice(v: unknown, variant?: unknown): TcgPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.sub_type_name ?? r.variant),\n low: num(r.low_price),\n mid: num(r.mid_price),\n high: num(r.high_price),\n market: num(r.market_price),\n directLow: num(r.direct_low_price),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n\nexport function cardmarketPrice(v: unknown, variant?: unknown): CardmarketPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.variant_type ?? r.variant),\n avg: num(r.avg),\n low: num(r.low),\n trend: num(r.trend),\n avg1: num(r.avg1),\n avg7: num(r.avg7),\n avg30: num(r.avg30),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n","import type { Card } from '../types.js'\nimport { arr, rec, setPair, str, type Rec } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\n/** Where a card was listed, when the surrounding response knows better than `card_info`. */\nexport interface SetContext {\n setId: string | null\n setCode: string | null\n}\n\nconst KNOWN = new Set([\n 'name', 'clean_name', 'set_name', 'set_code', 'set_id', 'card_number', 'rarity', 'card_type',\n 'product_type', 'variants', 'card_text',\n])\n\n/** Card in the Pokémon shape (Pokémon and the ten games): `{id, card_info, tcgplayer, cardmarket}`. */\nexport function normalizeCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const info = rec(r.card_info)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const pair = ctx ?? { setId: setPair(info.set_code, info.set_id).id, setCode: setPair(info.set_code, info.set_id).code }\n return {\n id: str(r.id) ?? '',\n name: str(info.name) ?? '',\n cleanName: str(info.clean_name),\n number: str(info.card_number),\n rarity: str(info.rarity),\n cardType: str(info.card_type),\n productType: str(info.product_type),\n text: str(info.card_text),\n variants: arr(info.variants).filter((v): v is string => typeof v === 'string'),\n setId: pair.setId,\n setCode: pair.setCode,\n setName: str(info.set_name),\n tcgplayer: tcg ? { url: str(tcg.url), prices: arr(tcg.prices).map((p) => tcgPrice(p)) } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: arr(cm.prices).map((p) => cardmarketPrice(p)) }\n : null,\n info: extras(info),\n raw,\n }\n}\n\nfunction extras(info: Rec): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(info)) if (!KNOWN.has(k)) out[k] = v\n return out\n}\n\n/** One Piece card: flat, `ext_*` fields, a single price object per source. */\nexport function normalizeOpCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const finish = r.sub_type_name\n const info: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(r)) if (k.startsWith('ext_')) info[k] = v\n return {\n id: str(r.id) ?? '',\n name: str(r.name) ?? '',\n cleanName: str(r.clean_name),\n number: str(r.card_number),\n rarity: str(r.rarity),\n cardType: str(r.card_type),\n productType: null,\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n setId: ctx?.setId ?? null,\n setCode: ctx?.setCode ?? null,\n setName: null,\n tcgplayer: tcg ? { url: str(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] }\n : null,\n info,\n raw,\n }\n}\n","import type {\n CompletionValue,\n HistoryPoint,\n PriceHistory,\n PriceRow,\n PriceStats,\n SetPrices,\n SetStatistics,\n TopCard,\n TrendingSet,\n} from '../types.js'\nimport { arr, num, rec, setPair, setRef, str } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\nconst DAYS = [7, 14, 30, 60, 120] as const\n\n/** Set prices. Pokémon and One Piece name the set id `group_id`, the games `set_id`. */\nexport function normalizeSetPrices(raw: unknown): SetPrices {\n const r = rec(raw)\n const pair = setPair(r.set_code, r.set_id ?? r.group_id)\n const rows: PriceRow[] = arr(r.data).map((d) => {\n const row = rec(d)\n return {\n id: str(row.id) ?? '',\n number: str(row.card_number),\n name: str(row.name) ?? '',\n variant: str(row.variant),\n productType: str(row.product_type),\n tcgplayer: row.tcgplayer ? tcgPrice(row.tcgplayer, row.variant) : null,\n cardmarket: row.cardmarket ? cardmarketPrice(row.cardmarket, row.variant) : null,\n }\n })\n return { source: str(r.source) ?? 'both', setId: pair.id, setCode: pair.code, rows, total: num(r.total) ?? rows.length, raw }\n}\n\nfunction priceStats(v: unknown): PriceStats | null {\n if (!v || typeof v !== 'object') return null\n const s = rec(v)\n const top = s.most_expensive ? rec(s.most_expensive) : null\n return {\n avg: num(s.avg_market_price ?? s.avg_price),\n min: num(s.min_price),\n max: num(s.max_price),\n mostExpensive: top ? { id: str(top.id), name: str(top.name), price: num(top.price) } : null,\n trendDirection: str(s.trend_direction),\n }\n}\n\nexport function normalizeStatistics(raw: unknown): SetStatistics {\n const r = rec(raw)\n const info = rec(r.set_info)\n const stats = rec(r.price_statistics)\n const rarity: Record<string, number> = {}\n for (const [k, v] of Object.entries(rec(r.rarity_breakdown))) rarity[k] = num(v) ?? 0\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: priceStats(stats.tcgplayer),\n cardmarket: priceStats(stats.cardmarket),\n rarityBreakdown: rarity,\n raw,\n }\n}\n\nexport function normalizeCompletionValue(raw: unknown): CompletionValue {\n const r = rec(raw)\n const info = rec(r.set_info)\n const cost = rec(r.completion_cost)\n const t = cost.tcgplayer ? rec(cost.tcgplayer) : null\n const c = cost.cardmarket ? rec(cost.cardmarket) : null\n const byRarity: CompletionValue['byRarity'] = {}\n for (const [k, v] of Object.entries(rec(r.breakdown_by_rarity))) {\n byRarity[k] = { count: num(rec(v).count) ?? 0, totalCost: num(rec(v).total_cost) }\n }\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: t ? { currency: str(t.currency), low: num(t.low_estimate), market: num(t.market_estimate), high: num(t.high_estimate) } : null,\n cardmarket: c ? { currency: str(c.currency), low: num(c.low_estimate), avg: num(c.avg_estimate), trend: num(c.trend_estimate) } : null,\n byRarity,\n note: str(cost.note),\n raw,\n }\n}\n\n/** `+446.7%` -> 446.7. */\nfunction pct(v: unknown): number | null {\n const s = str(v)\n return s === null ? null : num(s.replace('%', '').replace('+', ''))\n}\n\nexport function normalizeTrending(raw: unknown): TrendingSet[] {\n return arr(rec(raw).trending_sets).map((item) => {\n const s = rec(item)\n const cm = rec(s.cardmarket)\n return {\n set: setRef(s.set_name, s.set_code, s.set_id),\n cardCount: num(s.card_count),\n change: str(cm.price_change),\n changePct: pct(cm.price_change),\n avgPriceCurrent: num(cm.avg_price_current),\n avgPricePrevious: num(cm.avg_price_previous),\n topMovers: arr(cm.top_movers).map((m) => ({ name: str(rec(m).name), change: str(rec(m).change) })),\n raw: item,\n }\n })\n}\n\nexport function normalizeTopCards(raw: unknown): TopCard[] {\n return arr(rec(raw).top_cards).map((item) => {\n const c = rec(item)\n const info = rec(c.card_info)\n const pair = setPair(info.set_code, info.set_id)\n return {\n id: str(c.id) ?? '',\n name: str(info.name) ?? '',\n number: str(info.card_number),\n rarity: str(info.rarity),\n setName: str(info.set_name),\n setId: pair.id,\n setCode: pair.code,\n price: num(c.current_price),\n change7d: str(c.change_7d),\n raw: item,\n }\n })\n}\n\nfunction historySide(v: unknown): Record<string, HistoryPoint> | null {\n const variants = v && typeof v === 'object' ? rec(rec(v).variants) : null\n if (!variants) return null\n const out: Record<string, HistoryPoint> = {}\n for (const [name, data] of Object.entries(variants)) {\n const d = rec(data)\n const current: Record<string, number | null> = {}\n for (const [k, val] of Object.entries(rec(d.current))) current[k] = num(val)\n const price: Record<number, number | null> = {}\n const change: Record<number, string | null> = {}\n for (const day of DAYS) {\n price[day] = num(d[`price_${day}d`])\n change[day] = str(d[`change_${day}d`])\n }\n out[name] = { price, change, current, lastUpdated: str(d.last_updated) }\n }\n return out\n}\n\nexport function normalizePriceHistory(raw: unknown): PriceHistory {\n const r = rec(raw)\n return { id: str(r.id) ?? '', name: str(r.card_name), tcgplayer: historySide(r.tcgplayer), cardmarket: historySide(r.cardmarket), raw }\n}\n","import type { SetSummary } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** Set entry from any list or detail. One Piece names the id `group_id`, everything else `set_id`. */\nexport function normalizeSet(raw: unknown): SetSummary {\n const r = rec(raw)\n return {\n id: str(r.set_id) ?? str(r.group_id) ?? '',\n code: str(r.set_code),\n name: str(r.name) ?? str(r.set_name) ?? '',\n language: str(r.language),\n releaseDate: str(r.release_date),\n cardCount: num(r.card_count ?? r.total_cards),\n sealedCount: num(r.sealed_count),\n raw,\n }\n}\n","import type { Page } from './types.js'\n\n/** Builds a Page, computing `totalPages` here so it is always a finite number. */\nexport function makePage<T>(items: T[], meta: { page: number; limit: number; total: number }): Page<T> {\n const totalPages = meta.limit > 0 ? Math.ceil(meta.total / meta.limit) : 0\n return { items, page: meta.page, limit: meta.limit, total: meta.total, totalPages }\n}\n\n/**\n * Walks every page of any list endpoint as one async sequence. The two pagination\n * shapes of the API are already hidden behind `fetchPage`.\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<Page<T>>,\n options: { startPage?: number; maxItems?: number } = {},\n): AsyncGenerator<T, void, undefined> {\n let page = options.startPage ?? 1\n let yielded = 0\n for (;;) {\n const res = await fetchPage(page)\n for (const item of res.items) {\n if (options.maxItems !== undefined && yielded >= options.maxItems) return\n yield item\n yielded++\n }\n if (res.items.length === 0 || page >= res.totalPages) return\n page++\n }\n}\n","import { ValidationError } from './errors.js'\n\n/** `page` must be a positive integer. */\nexport function checkPage(page: number | undefined): number | undefined {\n if (page === undefined) return undefined\n if (!Number.isInteger(page) || page < 1) throw new ValidationError(`page must be an integer >= 1 (got ${page})`)\n return page\n}\n\n/** `limit` must be an integer in [1, max]. Checked here so out-of-range values never reach the server. */\nexport function checkLimit(limit: number | undefined, max: number): number | undefined {\n if (limit === undefined) return undefined\n if (!Number.isInteger(limit) || limit < 1 || limit > max) {\n throw new ValidationError(`limit must be an integer between 1 and ${max} (got ${limit})`)\n }\n return limit\n}\n\n/** Only `7d` exists, in every world. */\nexport function checkPeriod(period: string | undefined): '7d' {\n if (period !== undefined && period !== '7d') throw new ValidationError(`period ${period} is not available (only 7d)`)\n return '7d'\n}\n\n/** `variant` is `normal` or `foil`. */\nexport function checkVariant(variant: string | undefined): 'normal' | 'foil' | undefined {\n if (variant === undefined) return undefined\n if (variant !== 'normal' && variant !== 'foil') throw new ValidationError(`variant must be normal or foil (got ${variant})`)\n return variant\n}\n\nexport function checkText(name: string, value: string, min = 1): string {\n if (typeof value !== 'string' || value.trim().length < min) {\n throw new ValidationError(`${name} must be at least ${min} character${min === 1 ? '' : 's'} long`)\n }\n return value.trim()\n}\n\n/** Path segment for a user-supplied id or set code. */\nexport function seg(value: string): string {\n return encodeURIComponent(checkText('id', value))\n}\n","import type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\n\n/**\n * The one interface shared by Pokémon, One Piece and the ten games. Where the API\n * needs a different route, parameter or response shape, the world hides it.\n *\n * Plan-gated methods (`prices`, `statistics`, `completionValue`, `trending`, `topCards`)\n * throw `PlanRequiredError` when the account's plan or trial does not cover them.\n * An ambiguous set code throws `AmbiguousSetError`; retry with one of its `matches[].setId`.\n */\nexport interface World {\n /** One page of search results. `q` is 2-100 characters for the ten games. */\n search(q: string, options?: SearchOptions): Promise<SearchPage>\n /** Every result of a search, page after page. */\n searchAll(q: string, options?: { limit?: number; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Card by id (`pk_…`, `op_…`, `<code>_…`, or a 64-hex CardMarket id). */\n card(id: string): Promise<Card>\n /** All sets of the world. The API does not paginate this list. */\n sets(options?: { language?: string }): Promise<SetSummary[]>\n /** One page of a set's cards. `code` is a set code or a numeric set id. */\n set(code: string, options?: SetOptions): Promise<SetPage>\n /** Every card of a set, page after page. */\n setCards(code: string, options?: { limit?: number; language?: string; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Prices of every card in a set: hundreds to thousands of rows. */\n prices(code: string, options?: PricesOptions): Promise<SetPrices>\n statistics(code: string, options?: StatisticsOptions): Promise<SetStatistics>\n completionValue(code: string): Promise<CompletionValue>\n trending(options?: TrendingOptions): Promise<TrendingSet[]>\n topCards(options?: TopCardsOptions): Promise<TopCard[]>\n}\n\nexport const LIMITS = { search: 100, set: 200, trending: 50, topCards: 100 } as const\n","import { ambiguousSetError, isDisambiguation } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nexport interface CardWorldConfig {\n /** Route prefix: `''` for Pokémon, `/mtg` for a game. */\n prefix: string\n /** Minimum search length: the games reject queries shorter than 2 characters. */\n minQuery: number\n}\n\n/** Pokémon and the ten games share one response shape, so one class serves them all. */\nexport class CardWorld implements World {\n constructor(\n protected readonly http: HttpClient,\n protected readonly config: CardWorldConfig,\n ) {}\n\n protected path(rest: string): string {\n return `${this.config.prefix}${rest}`\n }\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get(this.path('/search'), {\n q: checkText('q', q, this.config.minQuery),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const p = rec(body.pagination)\n const items = arr(body.results).map((c) => normalizeCard(c))\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, truncated: rec(body.metadata).truncated === true }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeCard(await this.http.get(this.path(`/cards/${seg(id)}`)))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get(this.path('/sets'), { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(this.path(`/sets/${seg(code)}`), {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n language: options.language,\n }),\n )\n // 200 with a candidate list instead of cards: same condition as the 300/409 answers.\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n const set = normalizeSet(body.set)\n // A set listing names its set once: use the set object for every card.\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.cards).map((c) => normalizeCard(c, ctx))\n const p = rec(body.pagination)\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit, language: options.language }), {\n maxItems: options.maxItems,\n })\n }\n\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n return normalizeSetPrices(await this.http.get(this.path(`/prices/${seg(code)}`), { source: options.source }))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(this.path(`/sets/${seg(code)}/statistics`), { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(this.path(`/sets/${seg(code)}/completion-value`)))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get(this.path('/sets/trending'), { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get(this.path('/analytics/top-cards'), {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n\n","import { ValidationError } from '../errors.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeOpCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * One Piece lives under `/op` with its own shapes: flat cards, flat pagination\n * (`{data,total,page,limit}`), `group_id` instead of `set_id`, and set prices selected\n * through the query string. This class hides all of it behind the shared interface.\n */\nexport class OnePieceWorld implements World {\n constructor(private readonly http: HttpClient) {}\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get('/op/search', {\n q: checkText('q', q),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const items = arr(body.data).map((c) => normalizeOpCard(c))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, truncated: false }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeOpCard(await this.http.get(`/op/cards/${seg(id)}`))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get('/op/sets', { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n /** `options.language` is ignored: One Piece maps a code to its first matching set. */\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(`/op/sets/${seg(code)}`, {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n }),\n )\n const set = normalizeSet(body.set)\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.data).map((c) => normalizeOpCard(c, ctx))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n /** The set goes in the query here (`group_id` for numeric ids, `set_code` otherwise). */\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n if (options.source !== undefined) throw new ValidationError('source is not supported for One Piece prices')\n const c = checkText('code', code)\n const query = NUMERIC_ID.test(c) ? { group_id: c } : { set_code: c }\n return normalizeSetPrices(await this.http.get('/op/prices', query))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(`/op/sets/${seg(code)}/statistics`, { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(`/op/sets/${seg(code)}/completion-value`))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get('/op/sets/trending', { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get('/op/analytics/top-cards', {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n","import { isDisambiguation, ambiguousSetError } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { normalizePriceHistory } from '../normalize/pro.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport type { Card, PriceHistory } from '../types.js'\nimport { seg } from '../validation.js'\nimport { CardWorld } from './card-world.js'\n\n/** Pokémon: the shared card world plus the endpoints only Pokémon has. */\nexport class PokemonWorld extends CardWorld {\n constructor(http: HttpClient) {\n super(http, { prefix: '', minQuery: 1 })\n }\n\n /**\n * Card by id, or by plain card number together with `setCode` (`card('086/078', { setCode: 'SV8a' })`).\n * Ids from `search` and `set` are the safest input.\n */\n override async card(id: string, options: { setCode?: string } = {}): Promise<Card> {\n const body = await this.http.get(this.path(`/cards/${seg(id)}`), { set_code: options.setCode })\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n return normalizeCard(body)\n }\n\n /** Price snapshots at 7/14/30/60/120 days, per finish (not a time series). Pro or trial. */\n async priceHistory(id: string): Promise<PriceHistory> {\n return normalizePriceHistory(await this.http.get(`/cards/${seg(id)}/price-history`))\n }\n}\n","import { HttpClient, type ClientOptions, type RateLimitInfo } from './http.js'\nimport { imageUrl, type ImageUrlOptions } from './images.js'\nimport { normalizeGames, normalizeHealth, isHealthReport } from './normalize/misc.js'\nimport { GAME_CODES, type Game, type GameCode, type Health } from './types.js'\nimport { CardWorld } from './worlds/card-world.js'\nimport { OnePieceWorld } from './worlds/onepiece-world.js'\nimport { PokemonWorld } from './worlds/pokemon-world.js'\nimport type { World } from './worlds/world.js'\n\n/**\n * Entry point. One interface for every world:\n *\n * ```ts\n * const pw = new PokeWallet({ apiKey: process.env.POKEWALLET_API_KEY })\n * await pw.pokemon.search('charizard')\n * await pw.onepiece.set('OP01')\n * await pw.games.mtg.search('black lotus')\n * ```\n */\nexport class PokeWallet {\n readonly pokemon: PokemonWorld\n readonly onepiece: World\n readonly games: Readonly<Record<GameCode, World>>\n\n readonly #http: HttpClient\n readonly #baseUrl: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.#http = new HttpClient(options)\n this.#baseUrl = options.baseUrl\n this.pokemon = new PokemonWorld(this.#http)\n this.onepiece = new OnePieceWorld(this.#http)\n const games = {} as Record<GameCode, World>\n for (const code of GAME_CODES) {\n games[code] = new CardWorld(this.#http, { prefix: `/${code}`, minQuery: 2 })\n }\n this.games = games\n }\n\n /** Quota counters from the most recent answer, or null before the first call. */\n get lastRateLimit(): RateLimitInfo | null {\n return this.#http.lastRateLimit\n }\n\n /** The world for a game code known only at runtime. */\n game(code: GameCode): World {\n return this.games[code]\n }\n\n /**\n * Service status. Works without a key; the header is sent only when a key is set.\n *\n * The API answers 503 with a full report when a critical service is down. That report is\n * information, not a failure: it is returned like a 200, with `status: 'unhealthy'` and the\n * failing `checks`, and is never retried. A 503 without a report (for example an error page\n * from the edge) still throws `UnavailableError`.\n */\n async health(): Promise<Health> {\n return normalizeHealth(await this.#http.get('/health', undefined, { isPublic: true, accept: isHealthReport }))\n }\n\n /** The ten games with their route maps. Works without a key. */\n async listGames(): Promise<Game[]> {\n return normalizeGames(await this.#http.get('/games', undefined, { isPublic: true }))\n }\n\n toJSON(): { client: unknown } {\n return { client: this.#http.toJSON() }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `PokeWallet ${JSON.stringify(this.toJSON())}`\n }\n\n /** See {@link imageUrl}: the URL still needs the API key header. */\n imageUrl(id: string, options: Omit<ImageUrlOptions, 'baseUrl'> = {}): string {\n return imageUrl(id, { ...options, baseUrl: this.#baseUrl })\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4BO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,MAAiB;AAC3B,UAAM,OAAO,WAAW,KAAK,MAAM,OAAO;AAC1C,UAAM,KAAK,WAAW,WAAW,KAAK,MAAM,SAAS,KAAK,QAAQ,QAAQ,KAAK,MAAM,EAAE;AACvF,SAAK,OAAO,WAAW;AACvB,SAAK,SAAS,KAAK;AACnB,SAAK,OAAO,KAAK;AACjB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,WAAW;AAAA,EAC9C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB,SAA+B;AAC1D,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,gBAAgB;AAAC;AAG/C,IAAM,YAAN,cAAwB,gBAAgB;AAAC;AAMzC,IAAM,oBAAN,cAAgC,gBAAgB;AAAA,EAC5C;AAAA,EACA;AAAA,EAET,YAAY,MAAiB;AAC3B,UAAM,IAAI;AACV,SAAK,YAAY,WAAW,KAAK,MAAM,YAAY;AACnD,SAAK,aAAa,WAAW,KAAK,MAAM,aAAa;AAAA,EACvD;AACF;AAGO,IAAM,yBAAN,cAAqC,gBAAgB;AAAA,EACjD;AAAA,EAET,YAAY,MAAiB;AAC3B,UAAM,IAAI;AACV,SAAK,aAAa,WAAW,KAAK,MAAM,aAAa;AAAA,EACvD;AACF;AAGO,IAAM,gBAAN,cAA4B,gBAAgB;AAAA,EACxC;AAAA,EACA;AAAA,EAET,YAAY,MAAiB;AAC3B,UAAM,IAAI;AACV,SAAK,aAAa,WAAW,KAAK,MAAM,cAAc;AACtD,UAAM,IAAK,KAAK,MAAuD;AACvE,SAAK,cAAc,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AAAA,EAC7C;AACF;AAGO,IAAM,uBAAN,cAAmC,cAAc;AAAC;AAMlD,IAAM,oBAAN,cAAgC,gBAAgB;AAAA,EAC5C;AAAA,EAET,YAAY,MAA2C;AACrD,UAAM,EAAE,GAAG,MAAM,SAAS,KAAK,WAAW,kDAAkD,CAAC;AAC7F,SAAK,UAAU,KAAK;AAAA,EACtB;AACF;AAOO,IAAM,iBAAN,cAA6B,gBAAgB;AAAA,EACzC;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,MAA2C;AACrD,UAAM,IAAI;AACV,SAAK,aAAa,KAAK;AACvB,UAAM,IAAK,KAAK,MAAkE;AAClF,SAAK,SAAS,EAAE,QAAQ,SAAS,GAAG,MAAM,GAAG,OAAO,SAAS,GAAG,KAAK,EAAE;AAAA,EACzE;AACF;AAGO,IAAM,mBAAN,cAA+B,gBAAgB;AAAA,EAC3C;AAAA,EAET,YAAY,MAA2C;AACrD,UAAM,IAAI;AACV,SAAK,aAAa,KAAK;AAAA,EACzB;AACF;AAGO,IAAM,cAAN,cAA0B,gBAAgB;AAAC;AAElD,SAAS,WAAW,MAAe,KAAiC;AAClE,QAAM,IAAK,OAAsD,GAAG;AACpE,SAAO,OAAO,MAAM,WAAW,IAAI;AACrC;AAEA,SAAS,SAAS,GAAqC;AACrD,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,UAAU,YAAY,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,cAAc,SAAU,QAAO;AACzG,SAAO,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,WAAW,EAAE,UAAU;AAChE;;;AC3IA,IAAM,MAAM,CAAC,MAA+B,OAAO,MAAM,WAAW,IAAI,OAAO,MAAM,WAAW,OAAO,CAAC,IAAI;AAGrG,SAAS,aAAa,MAA2B;AACtD,QAAM,MAAO,MAAmD;AAChE,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,SAAO,IAAI,IAAI,CAAC,OAAiB;AAAA,IAC/B,OAAO,IAAI,EAAE,MAAM,KAAK;AAAA,IACxB,SAAS,IAAI,EAAE,QAAQ;AAAA,IACvB,MAAM,IAAI,EAAE,IAAI;AAAA,IAChB,UAAU,IAAI,EAAE,QAAQ;AAAA,IACxB,aAAa,IAAI,EAAE,YAAY;AAAA,EACjC,EAAE;AACJ;AAGO,SAAS,iBAAiB,MAAwB;AACvD,SAAO,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAa,KAAsC,mBAAmB;AACzG;AAEO,SAAS,kBAAkB,QAAgB,MAAkC;AAClF,SAAO,IAAI,kBAAkB,EAAE,QAAQ,MAAM,SAAS,aAAa,IAAI,EAAE,CAAC;AAC5E;AAWO,SAAS,kBAAkB,KAAoC;AACpE,QAAM,EAAE,QAAQ,MAAM,YAAY,UAAU,IAAI;AAChD,QAAM,OAAO,EAAE,QAAQ,KAAK;AAC5B,QAAM,OAAQ,MAAiD;AAE/D,MAAI,WAAW,OAAQ,WAAW,OAAO,iBAAiB,IAAI,KAAO,WAAW,OAAO,SAAS,sBAAuB;AACrH,WAAO,kBAAkB,QAAQ,IAAI;AAAA,EACvC;AACA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,IAAI,gBAAgB,IAAI;AAAA,IACjC,KAAK;AACH,aAAO,IAAI,UAAU,IAAI;AAAA,IAC3B,KAAK;AACH,aAAO,SAAS,wBAAwB,IAAI,uBAAuB,IAAI,IAAI,IAAI,kBAAkB,IAAI;AAAA,IACvG,KAAK;AAEH,aAAO,aAAa,SAAS,uBAAuB,IAAI,qBAAqB,IAAI,IAAI,IAAI,cAAc,IAAI;AAAA,IAC7G,KAAK;AACH,aAAO,IAAI,eAAe,EAAE,GAAG,MAAM,WAAW,CAAC;AAAA,IACnD,KAAK;AACH,aAAO,IAAI,iBAAiB,EAAE,GAAG,MAAM,WAAW,CAAC;AAAA,IACrD;AACE,aAAO,UAAU,MAAM,IAAI,YAAY,IAAI,IAAI,IAAI,gBAAgB,IAAI;AAAA,EAC3E;AACF;;;ACjFO,IAAM,UAAU;AAChB,IAAM,mBAAmB;AACzB,IAAM,qBAAqB,qBAAqB,OAAO;;;AC0C9D,IAAM,cAAc;AAEb,IAAM,eAAe;AAG5B,SAAS,QAAQ,SAA4C;AAC3D,QAAM,MAAO,WAA0E,SAAS;AAChG,QAAM,OAAO,QAAQ,UAAU,KAAK,sBAAsB,IAAI,KAAK;AACnE,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,CAAC,IAAI,WAAW,KAAK,EAAG,OAAM,IAAI,gBAAgB,2BAA2B;AACjF,SAAO;AACT;AAGO,SAAS,gBAAgB,OAAsB,MAAM,KAAK,IAAI,GAAuB;AAC1F,MAAI,SAAS,QAAQ,MAAM,KAAK,MAAM,GAAI,QAAO;AACjD,QAAM,IAAI,OAAO,KAAK;AACtB,MAAI,OAAO,SAAS,CAAC,KAAK,KAAK,EAAG,QAAO;AACzC,QAAM,IAAI,KAAK,MAAM,KAAK;AAC1B,SAAO,OAAO,MAAM,CAAC,IAAI,SAAY,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,OAAO,GAAI,CAAC;AAC9E;AAEA,SAAS,IAAI,GAAY,MAA6B;AACpD,QAAM,IAAI,EAAE,IAAI,IAAI;AACpB,MAAI,KAAK,KAAM,QAAO;AACtB,QAAM,IAAI,OAAO,CAAC;AAClB,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAEA,SAAS,UAAU,KAA8B;AAC/C,SAAO,CAAC,IAAI,OAAO,QAAQ,IAAI,OAAO,KAAK,EAAE,KAAK,CAAC,MAAM,MAAM,UAAa,EAAE,aAAa,CAAC;AAC9F;AAEO,IAAM,aAAN,MAAiB;AAAA;AAAA,EAEtB,gBAAsC;AAAA,EAE7B;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAAyB,CAAC,GAAG;AACvC,SAAK,OAAO,QAAQ,OAAO;AAC3B,SAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACvE,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,SAAS,QAAQ,UAAU;AAChC,UAAM,IAAI;AACV,UAAM,IAAI,QAAQ,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,UAAU,IAAI;AACjE,QAAI,CAAC,EAAG,OAAM,IAAI,gBAAgB,oEAAoE;AACtG,SAAK,YAAY;AACjB,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,aAAa,QAAQ,wBAAwB;AAClD,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,QAAQ,QAAQ,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,EAC7E;AAAA,EAEA,IAAI,MAAc,OAAuB;AACvC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,SAAS,CAAC,CAAC,EAAG,KAAI,MAAM,UAAa,MAAM,KAAM,IAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AACxG,UAAM,IAAI,GAAG,SAAS;AACtB,WAAO,GAAG,KAAK,OAAO,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,IACJ,MACA,OACA,UAAuE,CAAC,GAC5D;AACZ,QAAI,KAAK,SAAS,UAAa,CAAC,QAAQ,SAAU,OAAM,IAAI,gBAAgB,YAAY;AACxF,UAAM,MAAM,KAAK,IAAI,MAAM,KAAK;AAChC,aAAS,UAAU,KAAK,WAAW;AACjC,YAAM,MAAM,MAAM,KAAK,KAAK,GAAG;AAC/B,YAAM,OAAO,UAAU,KAAK,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC;AACrD,WAAK,WAAW,IAAI,OAAO;AAC3B,UAAI,IAAI,UAAU,OAAO,IAAI,SAAS,IAAK,QAAO;AAElD,UAAI,QAAQ,SAAS,IAAI,EAAG,QAAO;AAEnC,YAAM,aAAa,gBAAgB,IAAI,QAAQ,IAAI,aAAa,CAAC;AACjE,YAAM,MAAM,kBAAkB,EAAE,QAAQ,IAAI,QAAQ,MAAM,YAAY,WAAW,YAAY,KAAK,IAAI,EAAE,CAAC;AACzG,UAAI,UAAU,KAAK,cAAc,KAAK,YAAY,KAAK,UAAU,GAAG;AAClE,cAAM,KAAK,OAAO,cAAc,KAAK,GAAI;AACzC;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,YAAY,KAAsB,YAAyC;AACjF,QAAI,IAAI,WAAW,KAAK;AAEtB,aAAO,eAAe,UAAa,cAAc,KAAK,cAAc,CAAC,UAAU,GAAqB;AAAA,IACtG;AACA,QAAI,IAAI,WAAW,IAAK,SAAQ,cAAc,MAAM,KAAK;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,KAAK,KAAgC;AACjD,QAAI;AACF,aAAO,MAAM,KAAK,UAAU,KAAK;AAAA,QAC/B,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,GAAI,KAAK,SAAS,SAAY,CAAC,IAAI,EAAE,aAAa,KAAK,KAAK;AAAA,UAC5D,cAAc,KAAK;AAAA,UACnB,uBAAuB,KAAK;AAAA,UAC5B,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,YAAY,QAAQ,KAAK,SAAS;AAAA,MAC5C,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,aAAa,2CAA2C,EAAE,OAAO,KAAK,YAAY,KAAK,EAAE,CAAC;AAAA,IACtG;AAAA,EACF;AAAA;AAAA,EAGA,SAAwE;AACtE,WAAO,EAAE,SAAS,KAAK,SAAS,WAAW,KAAK,WAAW,QAAQ,KAAK,SAAS,SAAY,OAAO,SAAS;AAAA,EAC/G;AAAA,EAEA,CAAC,uBAAO,IAAI,4BAA4B,CAAC,IAAY;AACnD,WAAO,cAAc,KAAK,UAAU,KAAK,OAAO,CAAC,CAAC;AAAA,EACpD;AAAA,EAEA,QAAQ,MAAsB;AAC5B,WAAO,KAAK,SAAS,SAAY,OAAO,KAAK,MAAM,KAAK,IAAI,EAAE,KAAK,QAAQ;AAAA,EAC7E;AAAA;AAAA,EAGA,YAAY,OAAyB;AACnC,QAAI,EAAE,iBAAiB,OAAQ,QAAO,OAAO,UAAU,WAAW,KAAK,QAAQ,KAAK,IAAI;AACxF,UAAM,OAAO,IAAI,MAAM,KAAK,QAAQ,MAAM,OAAO,CAAC;AAClD,SAAK,OAAO,MAAM;AAClB,QAAI,MAAM,MAAO,MAAK,QAAQ,KAAK,QAAQ,MAAM,KAAK;AACtD,UAAM,OAAQ,MAA6B;AAC3C,QAAI,OAAO,SAAS,SAAU,CAAC,KAA2B,OAAO;AACjE,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,GAAkB;AACnC,UAAM,OAAsB;AAAA,MAC1B,WAAW,IAAI,GAAG,wBAAwB;AAAA,MAC1C,eAAe,IAAI,GAAG,4BAA4B;AAAA,MAClD,UAAU,IAAI,GAAG,uBAAuB;AAAA,MACxC,cAAc,IAAI,GAAG,2BAA2B;AAAA,IAClD;AACA,QAAI,OAAO,OAAO,IAAI,EAAE,KAAK,CAAC,MAAM,MAAM,IAAI,EAAG,MAAK,gBAAgB;AAAA,EACxE;AACF;AAEA,SAAS,UAAU,MAAuB;AACxC,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO,EAAE,OAAO,KAAK,MAAM,GAAG,GAAG,EAAE;AAAA,EACrC;AACF;;;AC9MO,IAAM,aAAa,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;;;ACgBxF,SAAS,SAAS,IAAY,UAA2B,CAAC,GAAW;AAC1E,QAAM,QAAQ,GAAG,KAAK;AACtB,MAAI,CAAC,MAAO,OAAM,IAAI,gBAAgB,gBAAgB;AACtD,QAAM,QAAQ,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACrE,QAAM,OAAO,WAAW,KAAK,CAAC,MAAgB,MAAM,YAAY,EAAE,WAAW,GAAG,CAAC,GAAG,CAAC;AACrF,QAAM,OAAO,OAAO,IAAI,IAAI,WAAW,mBAAmB,KAAK,CAAC,KAAK,WAAW,mBAAmB,KAAK,CAAC;AACzG,QAAM,KAAK,IAAI,gBAAgB;AAC/B,MAAI,CAAC,MAAM;AACT,QAAI,QAAQ,KAAM,IAAG,IAAI,QAAQ,QAAQ,IAAI;AAC7C,QAAI,QAAQ,KAAM,IAAG,IAAI,QAAQ,QAAQ,IAAI;AAC7C,QAAI,QAAQ,IAAK,IAAG,IAAI,OAAO,QAAQ,GAAG;AAAA,EAC5C;AACA,QAAM,IAAI,GAAG,SAAS;AACtB,SAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE;AAC1C;;;AC/BO,IAAM,MAAM,CAAC,MAAqB,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC,IAAK,IAAY,CAAC;AAClG,IAAM,MAAM,CAAC,MAA2B,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AAEhE,SAASA,KAAI,GAA2B;AAC7C,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,CAAC;AAChE,SAAO;AACT;AAGO,SAASC,KAAI,GAA2B;AAC7C,MAAI,OAAO,MAAM,SAAU,QAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAC3D,MAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,IAAI;AAC5C,UAAM,IAAI,OAAO,CAAC;AAClB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAEA,IAAM,aAAa;AAOZ,SAAS,QAAQ,MAAe,IAAyD;AAC9F,QAAM,IAAID,KAAI,IAAI;AAClB,QAAM,IAAIA,KAAI,EAAE;AAChB,MAAI,MAAM,QAAQ,MAAM,QAAQ,WAAW,KAAK,CAAC,EAAG,QAAO,EAAE,IAAI,GAAG,MAAM,KAAK;AAC/E,SAAO,EAAE,IAAI,GAAG,MAAM,EAAE;AAC1B;AAEO,SAAS,OAAO,MAAe,MAAe,IAAqB;AACxE,SAAO,EAAE,GAAG,QAAQ,MAAM,EAAE,GAAG,MAAMA,KAAI,IAAI,EAAE;AACjD;;;ACpCA,SAAS,QAAQ,GAAoC;AACnD,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,IAAI,CAAC,CAAC,EAAG,KAAI,OAAO,QAAQ,SAAU,KAAI,CAAC,IAAI;AACrF,SAAO;AACT;AAGO,SAAS,eAAe,KAAsB;AACnD,SAAO,IAAI,IAAI,GAAG,EAAE,IAAI,EACrB,IAAI,CAAC,SAAsB;AAC1B,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,OAAOE,KAAI,EAAE,IAAI;AACvB,QAAI,SAAS,QAAQ,CAAE,WAAiC,SAAS,IAAI,EAAG,QAAO;AAC/E,WAAO,EAAE,MAAwB,MAAMA,KAAI,EAAE,IAAI,KAAK,MAAM,WAAW,QAAQ,EAAE,SAAS,GAAG,cAAc,QAAQ,EAAE,aAAa,GAAG,KAAK,KAAK;AAAA,EACjJ,CAAC,EACA,OAAO,CAAC,MAAiB,MAAM,IAAI;AACxC;AAGO,SAAS,eAAe,MAAwB;AACrD,SAAO,OAAO,IAAI,IAAI,EAAE,WAAW;AACrC;AAEO,SAAS,gBAAgB,KAAsB;AACpD,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,SAAsC,CAAC;AAC7C,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,IAAI,EAAE,MAAM,CAAC,GAAG;AACzD,UAAM,IAAI,IAAI,KAAK;AACnB,WAAO,IAAI,IAAI,EAAE,QAAQA,KAAI,EAAE,MAAM,KAAK,WAAW,SAASA,KAAI,EAAE,OAAO,GAAG,cAAcC,KAAI,EAAE,YAAY,EAAE;AAAA,EAClH;AACA,SAAO;AAAA,IACL,QAAQD,KAAI,EAAE,MAAM,KAAK;AAAA,IACzB,WAAWA,KAAI,EAAE,SAAS;AAAA,IAC1B,SAASA,KAAI,EAAE,OAAO;AAAA,IACtB;AAAA,IACA,cAAcC,KAAI,EAAE,YAAY;AAAA,IAChC,QAAQD,KAAI,EAAE,MAAM;AAAA,IACpB,SAASA,KAAI,EAAE,OAAO;AAAA,IACtB;AAAA,EACF;AACF;;;ACvCO,SAAS,SAAS,GAAY,SAA6B;AAChE,QAAM,IAAI,IAAI,CAAC;AACf,SAAO;AAAA,IACL,SAASE,KAAI,WAAW,EAAE,iBAAiB,EAAE,OAAO;AAAA,IACpD,KAAKC,KAAI,EAAE,SAAS;AAAA,IACpB,KAAKA,KAAI,EAAE,SAAS;AAAA,IACpB,MAAMA,KAAI,EAAE,UAAU;AAAA,IACtB,QAAQA,KAAI,EAAE,YAAY;AAAA,IAC1B,WAAWA,KAAI,EAAE,gBAAgB;AAAA,IACjC,WAAWD,KAAI,EAAE,UAAU;AAAA,IAC3B,KAAK;AAAA,EACP;AACF;AAEO,SAAS,gBAAgB,GAAY,SAAoC;AAC9E,QAAM,IAAI,IAAI,CAAC;AACf,SAAO;AAAA,IACL,SAASA,KAAI,WAAW,EAAE,gBAAgB,EAAE,OAAO;AAAA,IACnD,KAAKC,KAAI,EAAE,GAAG;AAAA,IACd,KAAKA,KAAI,EAAE,GAAG;AAAA,IACd,OAAOA,KAAI,EAAE,KAAK;AAAA,IAClB,MAAMA,KAAI,EAAE,IAAI;AAAA,IAChB,MAAMA,KAAI,EAAE,IAAI;AAAA,IAChB,OAAOA,KAAI,EAAE,KAAK;AAAA,IAClB,WAAWD,KAAI,EAAE,UAAU;AAAA,IAC3B,KAAK;AAAA,EACP;AACF;;;ACrBA,IAAM,QAAQ,oBAAI,IAAI;AAAA,EACpB;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAY;AAAA,EAAY;AAAA,EAAU;AAAA,EAAe;AAAA,EAAU;AAAA,EACjF;AAAA,EAAgB;AAAA,EAAY;AAC9B,CAAC;AAGM,SAAS,cAAc,KAAc,KAAwB;AAClE,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,OAAO,IAAI,EAAE,SAAS;AAC5B,QAAM,MAAM,EAAE,YAAY,IAAI,EAAE,SAAS,IAAI;AAC7C,QAAM,KAAK,EAAE,aAAa,IAAI,EAAE,UAAU,IAAI;AAC9C,QAAM,OAAO,OAAO,EAAE,OAAO,QAAQ,KAAK,UAAU,KAAK,MAAM,EAAE,IAAI,SAAS,QAAQ,KAAK,UAAU,KAAK,MAAM,EAAE,KAAK;AACvH,SAAO;AAAA,IACL,IAAIE,KAAI,EAAE,EAAE,KAAK;AAAA,IACjB,MAAMA,KAAI,KAAK,IAAI,KAAK;AAAA,IACxB,WAAWA,KAAI,KAAK,UAAU;AAAA,IAC9B,QAAQA,KAAI,KAAK,WAAW;AAAA,IAC5B,QAAQA,KAAI,KAAK,MAAM;AAAA,IACvB,UAAUA,KAAI,KAAK,SAAS;AAAA,IAC5B,aAAaA,KAAI,KAAK,YAAY;AAAA,IAClC,MAAMA,KAAI,KAAK,SAAS;AAAA,IACxB,UAAU,IAAI,KAAK,QAAQ,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,IAC7E,OAAO,KAAK;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,SAASA,KAAI,KAAK,QAAQ;AAAA,IAC1B,WAAW,MAAM,EAAE,KAAKA,KAAI,IAAI,GAAG,GAAG,QAAQ,IAAI,IAAI,MAAM,EAAE,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC,EAAE,IAAI;AAAA,IAC1F,YAAY,KACR,EAAE,aAAaA,KAAI,GAAG,YAAY,GAAG,KAAKA,KAAI,GAAG,WAAW,GAAG,QAAQ,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC,EAAE,IACrH;AAAA,IACJ,MAAM,OAAO,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,OAAO,MAAoC;AAClD,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,EAAG,KAAI,CAAC,MAAM,IAAI,CAAC,EAAG,KAAI,CAAC,IAAI;AACvE,SAAO;AACT;AAGO,SAAS,gBAAgB,KAAc,KAAwB;AACpE,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,MAAM,EAAE,YAAY,IAAI,EAAE,SAAS,IAAI;AAC7C,QAAM,KAAK,EAAE,aAAa,IAAI,EAAE,UAAU,IAAI;AAC9C,QAAM,SAAS,EAAE;AACjB,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,CAAC,EAAG,KAAI,EAAE,WAAW,MAAM,EAAG,MAAK,CAAC,IAAI;AAC5E,SAAO;AAAA,IACL,IAAIA,KAAI,EAAE,EAAE,KAAK;AAAA,IACjB,MAAMA,KAAI,EAAE,IAAI,KAAK;AAAA,IACrB,WAAWA,KAAI,EAAE,UAAU;AAAA,IAC3B,QAAQA,KAAI,EAAE,WAAW;AAAA,IACzB,QAAQA,KAAI,EAAE,MAAM;AAAA,IACpB,UAAUA,KAAI,EAAE,SAAS;AAAA,IACzB,aAAa;AAAA,IACb,MAAMA,KAAI,EAAE,eAAe;AAAA,IAC3B,UAAU,OAAO,WAAW,WAAW,CAAC,MAAM,IAAI,CAAC;AAAA,IACnD,OAAO,KAAK,SAAS;AAAA,IACrB,SAAS,KAAK,WAAW;AAAA,IACzB,SAAS;AAAA,IACT,WAAW,MAAM,EAAE,KAAKA,KAAI,IAAI,GAAG,GAAG,QAAQ,IAAI,SAAS,CAAC,SAAS,IAAI,QAAQ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI;AAAA,IACnG,YAAY,KACR,EAAE,aAAaA,KAAI,GAAG,YAAY,GAAG,KAAKA,KAAI,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,gBAAgB,GAAG,QAAQ,MAAM,CAAC,IAAI,CAAC,EAAE,IAC7H;AAAA,IACJ;AAAA,IACA;AAAA,EACF;AACF;;;AChEA,IAAM,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG;AAGzB,SAAS,mBAAmB,KAAyB;AAC1D,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,OAAO,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ;AACvD,QAAM,OAAmB,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM;AAC9C,UAAM,MAAM,IAAI,CAAC;AACjB,WAAO;AAAA,MACL,IAAIC,KAAI,IAAI,EAAE,KAAK;AAAA,MACnB,QAAQA,KAAI,IAAI,WAAW;AAAA,MAC3B,MAAMA,KAAI,IAAI,IAAI,KAAK;AAAA,MACvB,SAASA,KAAI,IAAI,OAAO;AAAA,MACxB,aAAaA,KAAI,IAAI,YAAY;AAAA,MACjC,WAAW,IAAI,YAAY,SAAS,IAAI,WAAW,IAAI,OAAO,IAAI;AAAA,MAClE,YAAY,IAAI,aAAa,gBAAgB,IAAI,YAAY,IAAI,OAAO,IAAI;AAAA,IAC9E;AAAA,EACF,CAAC;AACD,SAAO,EAAE,QAAQA,KAAI,EAAE,MAAM,KAAK,QAAQ,OAAO,KAAK,IAAI,SAAS,KAAK,MAAM,MAAM,OAAOC,KAAI,EAAE,KAAK,KAAK,KAAK,QAAQ,IAAI;AAC9H;AAEA,SAAS,WAAW,GAA+B;AACjD,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAM,IAAI,IAAI,CAAC;AACf,QAAM,MAAM,EAAE,iBAAiB,IAAI,EAAE,cAAc,IAAI;AACvD,SAAO;AAAA,IACL,KAAKA,KAAI,EAAE,oBAAoB,EAAE,SAAS;AAAA,IAC1C,KAAKA,KAAI,EAAE,SAAS;AAAA,IACpB,KAAKA,KAAI,EAAE,SAAS;AAAA,IACpB,eAAe,MAAM,EAAE,IAAID,KAAI,IAAI,EAAE,GAAG,MAAMA,KAAI,IAAI,IAAI,GAAG,OAAOC,KAAI,IAAI,KAAK,EAAE,IAAI;AAAA,IACvF,gBAAgBD,KAAI,EAAE,eAAe;AAAA,EACvC;AACF;AAEO,SAAS,oBAAoB,KAA6B;AAC/D,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,OAAO,IAAI,EAAE,QAAQ;AAC3B,QAAM,QAAQ,IAAI,EAAE,gBAAgB;AACpC,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,EAAE,gBAAgB,CAAC,EAAG,QAAO,CAAC,IAAIC,KAAI,CAAC,KAAK;AACpF,SAAO;AAAA,IACL,KAAK,EAAE,GAAG,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,MAAM,GAAG,YAAYA,KAAI,KAAK,WAAW,EAAE;AAAA,IAC3F,WAAW,WAAW,MAAM,SAAS;AAAA,IACrC,YAAY,WAAW,MAAM,UAAU;AAAA,IACvC,iBAAiB;AAAA,IACjB;AAAA,EACF;AACF;AAEO,SAAS,yBAAyB,KAA+B;AACtE,QAAM,IAAI,IAAI,GAAG;AACjB,QAAM,OAAO,IAAI,EAAE,QAAQ;AAC3B,QAAM,OAAO,IAAI,EAAE,eAAe;AAClC,QAAM,IAAI,KAAK,YAAY,IAAI,KAAK,SAAS,IAAI;AACjD,QAAM,IAAI,KAAK,aAAa,IAAI,KAAK,UAAU,IAAI;AACnD,QAAM,WAAwC,CAAC;AAC/C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,EAAE,mBAAmB,CAAC,GAAG;AAC/D,aAAS,CAAC,IAAI,EAAE,OAAOA,KAAI,IAAI,CAAC,EAAE,KAAK,KAAK,GAAG,WAAWA,KAAI,IAAI,CAAC,EAAE,UAAU,EAAE;AAAA,EACnF;AACA,SAAO;AAAA,IACL,KAAK,EAAE,GAAG,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,MAAM,GAAG,YAAYA,KAAI,KAAK,WAAW,EAAE;AAAA,IAC3F,WAAW,IAAI,EAAE,UAAUD,KAAI,EAAE,QAAQ,GAAG,KAAKC,KAAI,EAAE,YAAY,GAAG,QAAQA,KAAI,EAAE,eAAe,GAAG,MAAMA,KAAI,EAAE,aAAa,EAAE,IAAI;AAAA,IACrI,YAAY,IAAI,EAAE,UAAUD,KAAI,EAAE,QAAQ,GAAG,KAAKC,KAAI,EAAE,YAAY,GAAG,KAAKA,KAAI,EAAE,YAAY,GAAG,OAAOA,KAAI,EAAE,cAAc,EAAE,IAAI;AAAA,IAClI;AAAA,IACA,MAAMD,KAAI,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AACF;AAGA,SAAS,IAAI,GAA2B;AACtC,QAAM,IAAIA,KAAI,CAAC;AACf,SAAO,MAAM,OAAO,OAAOC,KAAI,EAAE,QAAQ,KAAK,EAAE,EAAE,QAAQ,KAAK,EAAE,CAAC;AACpE;AAEO,SAAS,kBAAkB,KAA6B;AAC7D,SAAO,IAAI,IAAI,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,SAAS;AAC/C,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,KAAK,IAAI,EAAE,UAAU;AAC3B,WAAO;AAAA,MACL,KAAK,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM;AAAA,MAC5C,WAAWA,KAAI,EAAE,UAAU;AAAA,MAC3B,QAAQD,KAAI,GAAG,YAAY;AAAA,MAC3B,WAAW,IAAI,GAAG,YAAY;AAAA,MAC9B,iBAAiBC,KAAI,GAAG,iBAAiB;AAAA,MACzC,kBAAkBA,KAAI,GAAG,kBAAkB;AAAA,MAC3C,WAAW,IAAI,GAAG,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,MAAMD,KAAI,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQA,KAAI,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE;AAAA,MACjG,KAAK;AAAA,IACP;AAAA,EACF,CAAC;AACH;AAEO,SAAS,kBAAkB,KAAyB;AACzD,SAAO,IAAI,IAAI,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS;AAC3C,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,OAAO,IAAI,EAAE,SAAS;AAC5B,UAAM,OAAO,QAAQ,KAAK,UAAU,KAAK,MAAM;AAC/C,WAAO;AAAA,MACL,IAAIA,KAAI,EAAE,EAAE,KAAK;AAAA,MACjB,MAAMA,KAAI,KAAK,IAAI,KAAK;AAAA,MACxB,QAAQA,KAAI,KAAK,WAAW;AAAA,MAC5B,QAAQA,KAAI,KAAK,MAAM;AAAA,MACvB,SAASA,KAAI,KAAK,QAAQ;AAAA,MAC1B,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,OAAOC,KAAI,EAAE,aAAa;AAAA,MAC1B,UAAUD,KAAI,EAAE,SAAS;AAAA,MACzB,KAAK;AAAA,IACP;AAAA,EACF,CAAC;AACH;AAEA,SAAS,YAAY,GAAiD;AACpE,QAAM,WAAW,KAAK,OAAO,MAAM,WAAW,IAAI,IAAI,CAAC,EAAE,QAAQ,IAAI;AACrE,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,MAAoC,CAAC;AAC3C,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,UAAyC,CAAC;AAChD,eAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,IAAI,EAAE,OAAO,CAAC,EAAG,SAAQ,CAAC,IAAIC,KAAI,GAAG;AAC3E,UAAM,QAAuC,CAAC;AAC9C,UAAM,SAAwC,CAAC;AAC/C,eAAW,OAAO,MAAM;AACtB,YAAM,GAAG,IAAIA,KAAI,EAAE,SAAS,GAAG,GAAG,CAAC;AACnC,aAAO,GAAG,IAAID,KAAI,EAAE,UAAU,GAAG,GAAG,CAAC;AAAA,IACvC;AACA,QAAI,IAAI,IAAI,EAAE,OAAO,QAAQ,SAAS,aAAaA,KAAI,EAAE,YAAY,EAAE;AAAA,EACzE;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,KAA4B;AAChE,QAAM,IAAI,IAAI,GAAG;AACjB,SAAO,EAAE,IAAIA,KAAI,EAAE,EAAE,KAAK,IAAI,MAAMA,KAAI,EAAE,SAAS,GAAG,WAAW,YAAY,EAAE,SAAS,GAAG,YAAY,YAAY,EAAE,UAAU,GAAG,IAAI;AACxI;;;AChJO,SAAS,aAAa,KAA0B;AACrD,QAAM,IAAI,IAAI,GAAG;AACjB,SAAO;AAAA,IACL,IAAIE,KAAI,EAAE,MAAM,KAAKA,KAAI,EAAE,QAAQ,KAAK;AAAA,IACxC,MAAMA,KAAI,EAAE,QAAQ;AAAA,IACpB,MAAMA,KAAI,EAAE,IAAI,KAAKA,KAAI,EAAE,QAAQ,KAAK;AAAA,IACxC,UAAUA,KAAI,EAAE,QAAQ;AAAA,IACxB,aAAaA,KAAI,EAAE,YAAY;AAAA,IAC/B,WAAWC,KAAI,EAAE,cAAc,EAAE,WAAW;AAAA,IAC5C,aAAaA,KAAI,EAAE,YAAY;AAAA,IAC/B;AAAA,EACF;AACF;;;ACbO,SAAS,SAAY,OAAY,MAA+D;AACrG,QAAM,aAAa,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,IAAI;AACzE,SAAO,EAAE,OAAO,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,WAAW;AACpF;AAMA,gBAAuB,SACrB,WACA,UAAqD,CAAC,GAClB;AACpC,MAAI,OAAO,QAAQ,aAAa;AAChC,MAAI,UAAU;AACd,aAAS;AACP,UAAM,MAAM,MAAM,UAAU,IAAI;AAChC,eAAW,QAAQ,IAAI,OAAO;AAC5B,UAAI,QAAQ,aAAa,UAAa,WAAW,QAAQ,SAAU;AACnE,YAAM;AACN;AAAA,IACF;AACA,QAAI,IAAI,MAAM,WAAW,KAAK,QAAQ,IAAI,WAAY;AACtD;AAAA,EACF;AACF;;;ACzBO,SAAS,UAAU,MAA8C;AACtE,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,EAAG,OAAM,IAAI,gBAAgB,qCAAqC,IAAI,GAAG;AAC/G,SAAO;AACT;AAGO,SAAS,WAAW,OAA2B,KAAiC;AACrF,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,KAAK;AACxD,UAAM,IAAI,gBAAgB,0CAA0C,GAAG,SAAS,KAAK,GAAG;AAAA,EAC1F;AACA,SAAO;AACT;AAGO,SAAS,YAAY,QAAkC;AAC5D,MAAI,WAAW,UAAa,WAAW,KAAM,OAAM,IAAI,gBAAgB,UAAU,MAAM,6BAA6B;AACpH,SAAO;AACT;AAGO,SAAS,aAAa,SAA4D;AACvF,MAAI,YAAY,OAAW,QAAO;AAClC,MAAI,YAAY,YAAY,YAAY,OAAQ,OAAM,IAAI,gBAAgB,uCAAuC,OAAO,GAAG;AAC3H,SAAO;AACT;AAEO,SAAS,UAAU,MAAc,OAAe,MAAM,GAAW;AACtE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,KAAK;AAC1D,UAAM,IAAI,gBAAgB,GAAG,IAAI,qBAAqB,GAAG,aAAa,QAAQ,IAAI,KAAK,GAAG,OAAO;AAAA,EACnG;AACA,SAAO,MAAM,KAAK;AACpB;AAGO,SAAS,IAAI,OAAuB;AACzC,SAAO,mBAAmB,UAAU,MAAM,KAAK,CAAC;AAClD;;;ACMO,IAAM,SAAS,EAAE,QAAQ,KAAK,KAAK,KAAK,UAAU,IAAI,UAAU,IAAI;;;ACNpE,IAAM,YAAN,MAAiC;AAAA,EACtC,YACqB,MACA,QACnB;AAFmB;AACA;AAAA,EAClB;AAAA,EAFkB;AAAA,EACA;AAAA,EAGX,KAAK,MAAsB;AACnC,WAAO,GAAG,KAAK,OAAO,MAAM,GAAG,IAAI;AAAA,EACrC;AAAA,EAEA,MAAM,OAAO,GAAW,UAAyB,CAAC,GAAwB;AACxE,UAAM,OAAO;AAAA,MACX,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,GAAG;AAAA,QACxC,GAAG,UAAU,KAAK,GAAG,KAAK,OAAO,QAAQ;AAAA,QACzC,MAAM,UAAU,QAAQ,IAAI;AAAA,QAC5B,OAAO,WAAW,QAAQ,OAAO,OAAO,MAAM;AAAA,MAChD,CAAC;AAAA,IACH;AACA,UAAM,IAAI,IAAI,KAAK,UAAU;AAC7B,UAAM,QAAQ,IAAI,KAAK,OAAO,EAAE,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC;AAC3D,UAAM,OAAO,SAAS,OAAO,EAAE,MAAMC,KAAI,EAAE,IAAI,KAAK,GAAG,OAAOA,KAAI,EAAE,KAAK,KAAK,MAAM,QAAQ,OAAOA,KAAI,EAAE,KAAK,KAAK,MAAM,OAAO,CAAC;AACjI,WAAO,EAAE,GAAG,MAAM,WAAW,IAAI,KAAK,QAAQ,EAAE,cAAc,KAAK;AAAA,EACrE;AAAA,EAEA,UAAU,GAAW,UAAiD,CAAC,GAA0C;AAC/G,WAAO,SAAS,CAAC,SAAS,KAAK,OAAO,GAAG,EAAE,MAAM,OAAO,QAAQ,MAAM,CAAC,GAAG,EAAE,UAAU,QAAQ,SAAS,CAAC;AAAA,EAC1G;AAAA,EAEA,MAAM,KAAK,IAA2B;AACpC,WAAO,cAAc,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAAA,EAC1E;AAAA,EAEA,MAAM,KAAK,UAAiC,CAAC,GAA0B;AACrE,UAAM,OAAO,IAAI,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,EAAE,UAAU,QAAQ,SAAS,CAAC,CAAC;AACxF,WAAO,IAAI,KAAK,IAAI,EAAE,IAAI,YAAY;AAAA,EACxC;AAAA,EAEA,MAAM,IAAI,MAAc,UAAsB,CAAC,GAAqB;AAClE,UAAM,OAAO;AAAA,MACX,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,GAAG;AAAA,QACnD,MAAM,UAAU,QAAQ,IAAI;AAAA,QAC5B,OAAO,WAAW,QAAQ,OAAO,OAAO,GAAG;AAAA,QAC3C,UAAU,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,QAAI,iBAAiB,IAAI,EAAG,OAAM,kBAAkB,KAAK,IAAI;AAC7D,UAAM,MAAM,aAAa,KAAK,GAAG;AAEjC,UAAM,MAAM,EAAE,OAAO,IAAI,MAAM,MAAM,SAAS,IAAI,KAAK;AACvD,UAAM,QAAQ,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAC9D,UAAM,IAAI,IAAI,KAAK,UAAU;AAC7B,UAAM,OAAO,SAAS,OAAO,EAAE,MAAMA,KAAI,EAAE,IAAI,KAAK,GAAG,OAAOA,KAAI,EAAE,KAAK,KAAK,MAAM,QAAQ,OAAOA,KAAI,EAAE,KAAK,KAAK,MAAM,OAAO,CAAC;AACjI,WAAO,EAAE,GAAG,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,SAAS,MAAc,UAAoE,CAAC,GAA0C;AACpI,WAAO,SAAS,CAAC,SAAS,KAAK,IAAI,MAAM,EAAE,MAAM,OAAO,QAAQ,OAAO,UAAU,QAAQ,SAAS,CAAC,GAAG;AAAA,MACpG,UAAU,QAAQ;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,MAAc,UAAyB,CAAC,GAAuB;AAC1E,WAAO,mBAAmB,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,QAAQ,OAAO,CAAC,CAAC;AAAA,EAC9G;AAAA,EAEA,MAAM,WAAW,MAAc,UAA6B,CAAC,GAA2B;AACtF,WAAO,oBAAoB,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,SAAS,aAAa,QAAQ,OAAO,EAAE,CAAC,CAAC;AAAA,EACxI;AAAA,EAEA,MAAM,gBAAgB,MAAwC;AAC5D,WAAO,yBAAyB,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAAA,EACvG;AAAA,EAEA,MAAM,SAAS,UAA2B,CAAC,GAA2B;AACpE,UAAM,SAAS,YAAY,QAAQ,MAAM;AACzC,WAAO,kBAAkB,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,gBAAgB,GAAG,EAAE,QAAQ,OAAO,WAAW,QAAQ,OAAO,OAAO,QAAQ,EAAE,CAAC,CAAC;AAAA,EAC1I;AAAA,EAEA,MAAM,SAAS,UAA2B,CAAC,GAAuB;AAChE,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,sBAAsB,GAAG;AAAA,QACrD,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,OAAO,WAAW,QAAQ,OAAO,OAAO,QAAQ;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AChGA,IAAMC,cAAa;AAOZ,IAAM,gBAAN,MAAqC;AAAA,EAC1C,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA,EAE7B,MAAM,OAAO,GAAW,UAAyB,CAAC,GAAwB;AACxE,UAAM,OAAO;AAAA,MACX,MAAM,KAAK,KAAK,IAAI,cAAc;AAAA,QAChC,GAAG,UAAU,KAAK,CAAC;AAAA,QACnB,MAAM,UAAU,QAAQ,IAAI;AAAA,QAC5B,OAAO,WAAW,QAAQ,OAAO,OAAO,MAAM;AAAA,MAChD,CAAC;AAAA,IACH;AACA,UAAM,QAAQ,IAAI,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AAC1D,UAAM,OAAO,SAAS,OAAO,EAAE,MAAMC,KAAI,KAAK,IAAI,KAAK,GAAG,OAAOA,KAAI,KAAK,KAAK,KAAK,MAAM,QAAQ,OAAOA,KAAI,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAC1I,WAAO,EAAE,GAAG,MAAM,WAAW,MAAM;AAAA,EACrC;AAAA,EAEA,UAAU,GAAW,UAAiD,CAAC,GAA0C;AAC/G,WAAO,SAAS,CAAC,SAAS,KAAK,OAAO,GAAG,EAAE,MAAM,OAAO,QAAQ,MAAM,CAAC,GAAG,EAAE,UAAU,QAAQ,SAAS,CAAC;AAAA,EAC1G;AAAA,EAEA,MAAM,KAAK,IAA2B;AACpC,WAAO,gBAAgB,MAAM,KAAK,KAAK,IAAI,aAAa,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,KAAK,UAAiC,CAAC,GAA0B;AACrE,UAAM,OAAO,IAAI,MAAM,KAAK,KAAK,IAAI,YAAY,EAAE,UAAU,QAAQ,SAAS,CAAC,CAAC;AAChF,WAAO,IAAI,KAAK,IAAI,EAAE,IAAI,YAAY;AAAA,EACxC;AAAA;AAAA,EAGA,MAAM,IAAI,MAAc,UAAsB,CAAC,GAAqB;AAClE,UAAM,OAAO;AAAA,MACX,MAAM,KAAK,KAAK,IAAI,YAAY,IAAI,IAAI,CAAC,IAAI;AAAA,QAC3C,MAAM,UAAU,QAAQ,IAAI;AAAA,QAC5B,OAAO,WAAW,QAAQ,OAAO,OAAO,GAAG;AAAA,MAC7C,CAAC;AAAA,IACH;AACA,UAAM,MAAM,aAAa,KAAK,GAAG;AACjC,UAAM,MAAM,EAAE,OAAO,IAAI,MAAM,MAAM,SAAS,IAAI,KAAK;AACvD,UAAM,QAAQ,IAAI,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC/D,UAAM,OAAO,SAAS,OAAO,EAAE,MAAMA,KAAI,KAAK,IAAI,KAAK,GAAG,OAAOA,KAAI,KAAK,KAAK,KAAK,MAAM,QAAQ,OAAOA,KAAI,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAC1I,WAAO,EAAE,GAAG,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,SAAS,MAAc,UAAoE,CAAC,GAA0C;AACpI,WAAO,SAAS,CAAC,SAAS,KAAK,IAAI,MAAM,EAAE,MAAM,OAAO,QAAQ,MAAM,CAAC,GAAG,EAAE,UAAU,QAAQ,SAAS,CAAC;AAAA,EAC1G;AAAA;AAAA,EAGA,MAAM,OAAO,MAAc,UAAyB,CAAC,GAAuB;AAC1E,QAAI,QAAQ,WAAW,OAAW,OAAM,IAAI,gBAAgB,8CAA8C;AAC1G,UAAM,IAAI,UAAU,QAAQ,IAAI;AAChC,UAAM,QAAQD,YAAW,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;AACnE,WAAO,mBAAmB,MAAM,KAAK,KAAK,IAAI,cAAc,KAAK,CAAC;AAAA,EACpE;AAAA,EAEA,MAAM,WAAW,MAAc,UAA6B,CAAC,GAA2B;AACtF,WAAO,oBAAoB,MAAM,KAAK,KAAK,IAAI,YAAY,IAAI,IAAI,CAAC,eAAe,EAAE,SAAS,aAAa,QAAQ,OAAO,EAAE,CAAC,CAAC;AAAA,EAChI;AAAA,EAEA,MAAM,gBAAgB,MAAwC;AAC5D,WAAO,yBAAyB,MAAM,KAAK,KAAK,IAAI,YAAY,IAAI,IAAI,CAAC,mBAAmB,CAAC;AAAA,EAC/F;AAAA,EAEA,MAAM,SAAS,UAA2B,CAAC,GAA2B;AACpE,UAAM,SAAS,YAAY,QAAQ,MAAM;AACzC,WAAO,kBAAkB,MAAM,KAAK,KAAK,IAAI,qBAAqB,EAAE,QAAQ,OAAO,WAAW,QAAQ,OAAO,OAAO,QAAQ,EAAE,CAAC,CAAC;AAAA,EAClI;AAAA,EAEA,MAAM,SAAS,UAA2B,CAAC,GAAuB;AAChE,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,IAAI,2BAA2B;AAAA,QAC7C,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,OAAO,WAAW,QAAQ,OAAO,OAAO,QAAQ;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC7GO,IAAM,eAAN,cAA2B,UAAU;AAAA,EAC1C,YAAY,MAAkB;AAC5B,UAAM,MAAM,EAAE,QAAQ,IAAI,UAAU,EAAE,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAe,KAAK,IAAY,UAAgC,CAAC,GAAkB;AACjF,UAAM,OAAO,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,QAAQ,QAAQ,CAAC;AAC9F,QAAI,iBAAiB,IAAI,EAAG,OAAM,kBAAkB,KAAK,IAAI;AAC7D,WAAO,cAAc,IAAI;AAAA,EAC3B;AAAA;AAAA,EAGA,MAAM,aAAa,IAAmC;AACpD,WAAO,sBAAsB,MAAM,KAAK,KAAK,IAAI,UAAU,IAAI,EAAE,CAAC,gBAAgB,CAAC;AAAA,EACrF;AACF;;;ACTO,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAET,YAAY,UAAyB,CAAC,GAAG;AACvC,SAAK,QAAQ,IAAI,WAAW,OAAO;AACnC,SAAK,WAAW,QAAQ;AACxB,SAAK,UAAU,IAAI,aAAa,KAAK,KAAK;AAC1C,SAAK,WAAW,IAAI,cAAc,KAAK,KAAK;AAC5C,UAAM,QAAQ,CAAC;AACf,eAAW,QAAQ,YAAY;AAC7B,YAAM,IAAI,IAAI,IAAI,UAAU,KAAK,OAAO,EAAE,QAAQ,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;AAAA,IAC7E;AACA,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA,EAGA,IAAI,gBAAsC;AACxC,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,KAAK,MAAuB;AAC1B,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAA0B;AAC9B,WAAO,gBAAgB,MAAM,KAAK,MAAM,IAAI,WAAW,QAAW,EAAE,UAAU,MAAM,QAAQ,eAAe,CAAC,CAAC;AAAA,EAC/G;AAAA;AAAA,EAGA,MAAM,YAA6B;AACjC,WAAO,eAAe,MAAM,KAAK,MAAM,IAAI,UAAU,QAAW,EAAE,UAAU,KAAK,CAAC,CAAC;AAAA,EACrF;AAAA,EAEA,SAA8B;AAC5B,WAAO,EAAE,QAAQ,KAAK,MAAM,OAAO,EAAE;AAAA,EACvC;AAAA,EAEA,CAAC,uBAAO,IAAI,4BAA4B,CAAC,IAAY;AACnD,WAAO,cAAc,KAAK,UAAU,KAAK,OAAO,CAAC,CAAC;AAAA,EACpD;AAAA;AAAA,EAGA,SAAS,IAAY,UAA4C,CAAC,GAAW;AAC3E,WAAO,SAAS,IAAI,EAAE,GAAG,SAAS,SAAS,KAAK,SAAS,CAAC;AAAA,EAC5D;AACF;","names":["str","num","str","num","str","num","str","str","num","str","num","num","NUMERIC_ID","num"]}
package/dist/index.d.cts CHANGED
@@ -9,6 +9,12 @@ interface ClientOptions {
9
9
  baseUrl?: string;
10
10
  /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */
11
11
  userAgent?: string;
12
+ /**
13
+ * Sent as `X-PokeWallet-Client`, so the API can tell which integration made a call. Browsers
14
+ * cannot set `User-Agent`, so this is the only identification they can send. Default
15
+ * `pokewallet-sdk-ts/<version>`.
16
+ */
17
+ client?: string;
12
18
  /** Custom `fetch`, mainly for tests. Defaults to the global one. */
13
19
  fetch?: FetchLike;
14
20
  /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */
@@ -34,6 +40,7 @@ declare class HttpClient {
34
40
  lastRateLimit: RateLimitInfo | null;
35
41
  private readonly baseUrl;
36
42
  private readonly userAgent;
43
+ private readonly client;
37
44
  private readonly fetchImpl;
38
45
  private readonly maxRetries;
39
46
  private readonly capSeconds;
@@ -564,7 +571,7 @@ declare class UnavailableError extends PokeWalletError {
564
571
  declare class ServerError extends PokeWalletError {
565
572
  }
566
573
 
567
- declare const VERSION = "0.1.3";
574
+ declare const VERSION = "0.1.6";
568
575
 
569
576
  /**
570
577
  * This file was auto-generated by openapi-typescript.
@@ -753,7 +760,19 @@ interface paths {
753
760
  /**
754
761
  * Prices of every card in a set (Pro or trial; hundreds of rows)
755
762
  * @description The response carries both `set_id` and `group_id` (the same value).
756
- * Ambiguous set: **300** with the `Disambiguation` body (no `error` field).
763
+ * Ambiguous set: **300** with the `Disambiguation` body (no `error` field); send the numeric
764
+ * `set_id` of the match you want instead of the `set_code`.
765
+ *
766
+ * Sets with a negative `set_id` exist on CardMarket only (`source` is `cm`). Each row is one
767
+ * CardMarket product and its `cardmarket` block is the `normal` price of that product. A
768
+ * `tcgplayer` block, when present, is an extra link made through CardTrader: it has no finish
769
+ * (`variant` is `null`) and may be for another finish than the CardMarket one (for example
770
+ * 1st Edition Holofoil). Do not compare or add the two. For European prices by finish
771
+ * (`normal` and `holo`), use `/cards/{id}`.
772
+ *
773
+ * Trainer Gallery and Galarian Gallery sets (`CRZ:GG`, `SWSH09:TG`, `SWSH10:TG`, `SWSH11: TG`,
774
+ * `SWSH12: TG`) carry a `cardmarket` block on every card here, in `/cards/{id}`, `/sets/{setCode}`
775
+ * and `/search`. Their CardMarket rows live in the main set and are matched by the TG / GG number.
757
776
  */
758
777
  get: operations["pokemonSetPrices"];
759
778
  put?: never;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,12 @@ interface ClientOptions {
9
9
  baseUrl?: string;
10
10
  /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */
11
11
  userAgent?: string;
12
+ /**
13
+ * Sent as `X-PokeWallet-Client`, so the API can tell which integration made a call. Browsers
14
+ * cannot set `User-Agent`, so this is the only identification they can send. Default
15
+ * `pokewallet-sdk-ts/<version>`.
16
+ */
17
+ client?: string;
12
18
  /** Custom `fetch`, mainly for tests. Defaults to the global one. */
13
19
  fetch?: FetchLike;
14
20
  /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */
@@ -34,6 +40,7 @@ declare class HttpClient {
34
40
  lastRateLimit: RateLimitInfo | null;
35
41
  private readonly baseUrl;
36
42
  private readonly userAgent;
43
+ private readonly client;
37
44
  private readonly fetchImpl;
38
45
  private readonly maxRetries;
39
46
  private readonly capSeconds;
@@ -564,7 +571,7 @@ declare class UnavailableError extends PokeWalletError {
564
571
  declare class ServerError extends PokeWalletError {
565
572
  }
566
573
 
567
- declare const VERSION = "0.1.3";
574
+ declare const VERSION = "0.1.6";
568
575
 
569
576
  /**
570
577
  * This file was auto-generated by openapi-typescript.
@@ -753,7 +760,19 @@ interface paths {
753
760
  /**
754
761
  * Prices of every card in a set (Pro or trial; hundreds of rows)
755
762
  * @description The response carries both `set_id` and `group_id` (the same value).
756
- * Ambiguous set: **300** with the `Disambiguation` body (no `error` field).
763
+ * Ambiguous set: **300** with the `Disambiguation` body (no `error` field); send the numeric
764
+ * `set_id` of the match you want instead of the `set_code`.
765
+ *
766
+ * Sets with a negative `set_id` exist on CardMarket only (`source` is `cm`). Each row is one
767
+ * CardMarket product and its `cardmarket` block is the `normal` price of that product. A
768
+ * `tcgplayer` block, when present, is an extra link made through CardTrader: it has no finish
769
+ * (`variant` is `null`) and may be for another finish than the CardMarket one (for example
770
+ * 1st Edition Holofoil). Do not compare or add the two. For European prices by finish
771
+ * (`normal` and `holo`), use `/cards/{id}`.
772
+ *
773
+ * Trainer Gallery and Galarian Gallery sets (`CRZ:GG`, `SWSH09:TG`, `SWSH10:TG`, `SWSH11: TG`,
774
+ * `SWSH12: TG`) carry a `cardmarket` block on every card here, in `/cards/{id}`, `/sets/{setCode}`
775
+ * and `/search`. Their CardMarket rows live in the main set and are matched by the TG / GG number.
757
776
  */
758
777
  get: operations["pokemonSetPrices"];
759
778
  put?: never;
package/dist/index.js CHANGED
@@ -141,7 +141,7 @@ function errorFromResponse(ctx) {
141
141
  }
142
142
 
143
143
  // src/version.ts
144
- var VERSION = "0.1.3";
144
+ var VERSION = "0.1.6";
145
145
  var DEFAULT_BASE_URL = "https://api.pokewallet.io";
146
146
  var DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`;
147
147
 
@@ -177,6 +177,7 @@ var HttpClient = class {
177
177
  #key;
178
178
  baseUrl;
179
179
  userAgent;
180
+ client;
180
181
  fetchImpl;
181
182
  maxRetries;
182
183
  capSeconds;
@@ -186,6 +187,7 @@ var HttpClient = class {
186
187
  this.#key = readKey(options);
187
188
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
188
189
  this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;
190
+ this.client = options.client ?? DEFAULT_USER_AGENT;
189
191
  const g = globalThis;
190
192
  const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : void 0);
191
193
  if (!f) throw new ValidationError("No fetch available: pass options.fetch (Node 18+ has one built in)");
@@ -238,6 +240,7 @@ var HttpClient = class {
238
240
  headers: {
239
241
  ...this.#key === void 0 ? {} : { "X-API-Key": this.#key },
240
242
  "User-Agent": this.userAgent,
243
+ "X-PokeWallet-Client": this.client,
241
244
  Accept: "application/json"
242
245
  },
243
246
  signal: AbortSignal.timeout(this.timeoutMs)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/error-map.ts","../src/version.ts","../src/http.ts","../src/types.ts","../src/images.ts","../src/normalize/common.ts","../src/normalize/misc.ts","../src/normalize/prices.ts","../src/normalize/card.ts","../src/normalize/pro.ts","../src/normalize/sets.ts","../src/pagination.ts","../src/validation.ts","../src/worlds/world.ts","../src/worlds/card-world.ts","../src/worlds/onepiece-world.ts","../src/worlds/pokemon-world.ts","../src/client.ts"],"sourcesContent":["/** Hourly or daily quota window as reported in a 429 body. */\nexport interface LimitWindow {\n limit: number\n used: number\n remaining: number\n}\n\nexport interface RateLimitWindows {\n hourly?: LimitWindow\n daily?: LimitWindow\n}\n\n/** One candidate of an ambiguous set. `setId` is the value to pass back to pick it. */\nexport interface SetMatch {\n setId: string\n setCode: string | null\n name: string | null\n language: string | null\n releaseDate: string | null\n}\n\nexport interface ErrorInit {\n status: number\n body?: unknown\n message?: string\n}\n\n/** Base class of every error raised by the SDK for an API answer. */\nexport class PokeWalletError extends Error {\n readonly status: number\n /** Parsed JSON body of the answer, when there was one. */\n readonly body: unknown\n /** The `error` field of the body, when present. */\n readonly code: string | undefined\n\n constructor(init: ErrorInit) {\n const code = bodyString(init.body, 'error')\n super(init.message ?? bodyString(init.body, 'message') ?? code ?? `HTTP ${init.status}`)\n this.name = new.target.name\n this.status = init.status\n this.body = init.body\n this.code = code\n }\n}\n\n/** Raised before any request when an argument is out of range. */\nexport class ValidationError extends RangeError {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/** The request never produced an HTTP answer (DNS, connection, timeout). */\nexport class NetworkError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'NetworkError'\n }\n}\n\n/** 400: missing or invalid parameter, or an id that cannot be decoded. */\nexport class BadRequestError extends PokeWalletError {}\n\n/** 401: key missing, malformed or unknown. */\nexport class AuthError extends PokeWalletError {}\n\n/**\n * 403 on a plan-gated endpoint. `redeemUrl` is set when the free trial was never\n * activated; `upgradeUrl` when the trial expired or the plan is too low.\n */\nexport class PlanRequiredError extends PokeWalletError {\n readonly redeemUrl: string | undefined\n readonly upgradeUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.redeemUrl = bodyString(init.body, 'redeem_url')\n this.upgradeUrl = bodyString(init.body, 'upgrade_url')\n }\n}\n\n/** 403 `Feature not enabled`: this account does not have access to this feature. */\nexport class FeatureNotEnabledError extends PokeWalletError {\n readonly contactUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.contactUrl = bodyString(init.body, 'contact_url')\n }\n}\n\n/** 404: unknown card, set or route. Carries the server's suggestions when it sent any. */\nexport class NotFoundError extends PokeWalletError {\n readonly didYouMean: string | undefined\n readonly suggestions: unknown[]\n\n constructor(init: ErrorInit) {\n super(init)\n this.didYouMean = bodyString(init.body, 'did_you_mean')\n const s = (init.body as { suggestions?: unknown } | null | undefined)?.suggestions\n this.suggestions = Array.isArray(s) ? s : []\n }\n}\n\n/** 404 on a game route: the game is switched off for this account. */\nexport class GameUnavailableError extends NotFoundError {}\n\n/**\n * The set code matches several sets. Unifies the three ways the API says so\n * (200 with `disambiguation`, 300, 409). Retry with one `matches[i].setId`.\n */\nexport class AmbiguousSetError extends PokeWalletError {\n readonly matches: SetMatch[]\n\n constructor(init: ErrorInit & { matches: SetMatch[] }) {\n super({ ...init, message: init.message ?? 'Several sets match this code: pick one by setId' })\n this.matches = init.matches\n }\n}\n\n/**\n * 429. The API sends no `Retry-After`, so the SDK retries only when the header is\n * present and within the cap. `limits` mirrors the body: when a window shows\n * `remaining === 0`, waiting seconds cannot help.\n */\nexport class RateLimitError extends PokeWalletError {\n readonly limits: RateLimitWindows\n /** Seconds, from the `Retry-After` header, when present. */\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n const l = (init.body as { limits?: Record<string, unknown> } | null | undefined)?.limits\n this.limits = { hourly: toWindow(l?.hourly), daily: toWindow(l?.daily) }\n }\n}\n\n/** 503: database busy or feature not yet enabled. `retryAfter` is 5 or 3600 seconds. */\nexport class UnavailableError extends PokeWalletError {\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n }\n}\n\n/** Any other 5xx. Never retried. */\nexport class ServerError extends PokeWalletError {}\n\nfunction bodyString(body: unknown, key: string): string | undefined {\n const v = (body as Record<string, unknown> | null | undefined)?.[key]\n return typeof v === 'string' ? v : undefined\n}\n\nfunction toWindow(v: unknown): LimitWindow | undefined {\n if (!v || typeof v !== 'object') return undefined\n const w = v as Record<string, unknown>\n if (typeof w.limit !== 'number' || typeof w.used !== 'number' || typeof w.remaining !== 'number') return undefined\n return { limit: w.limit, used: w.used, remaining: w.remaining }\n}\n","import {\n AmbiguousSetError,\n AuthError,\n BadRequestError,\n FeatureNotEnabledError,\n GameUnavailableError,\n NotFoundError,\n PlanRequiredError,\n PokeWalletError,\n RateLimitError,\n ServerError,\n UnavailableError,\n type SetMatch,\n} from './errors.js'\n\ninterface RawMatch {\n set_id?: unknown\n set_code?: unknown\n name?: unknown\n language?: unknown\n release_date?: unknown\n}\n\nconst str = (v: unknown): string | null => (typeof v === 'string' ? v : typeof v === 'number' ? String(v) : null)\n\n/** Converts the `matches` array of any ambiguous-set body into the public shape. */\nexport function toSetMatches(body: unknown): SetMatch[] {\n const raw = (body as { matches?: unknown } | null | undefined)?.matches\n if (!Array.isArray(raw)) return []\n return raw.map((m: RawMatch) => ({\n setId: str(m.set_id) ?? '',\n setCode: str(m.set_code),\n name: str(m.name),\n language: str(m.language),\n releaseDate: str(m.release_date),\n }))\n}\n\n/** True for the 200 body the API uses to say \"several sets match\". */\nexport function isDisambiguation(body: unknown): boolean {\n return !!body && typeof body === 'object' && (body as { disambiguation?: unknown }).disambiguation === true\n}\n\nexport function ambiguousSetError(status: number, body: unknown): AmbiguousSetError {\n return new AmbiguousSetError({ status, body, matches: toSetMatches(body) })\n}\n\nexport interface ErrorContext {\n status: number\n body: unknown\n retryAfter: number | undefined\n /** True when the request went to one of the ten `/{game}` prefixes. */\n gameRoute: boolean\n}\n\n/** Maps a non-success answer to its typed error. Pure: no retry decisions here. */\nexport function errorFromResponse(ctx: ErrorContext): PokeWalletError {\n const { status, body, retryAfter, gameRoute } = ctx\n const init = { status, body }\n const code = (body as { error?: unknown } | null | undefined)?.error\n\n if (status === 300 || (status === 409 && isDisambiguation(body)) || (status === 409 && code === 'Ambiguous set code')) {\n return ambiguousSetError(status, body)\n }\n switch (status) {\n case 400:\n return new BadRequestError(init)\n case 401:\n return new AuthError(init)\n case 403:\n return code === 'Feature not enabled' ? new FeatureNotEnabledError(init) : new PlanRequiredError(init)\n case 404:\n // A switched-off game answers with the generic route 404, not a resource 404.\n return gameRoute && code === 'Endpoint not found' ? new GameUnavailableError(init) : new NotFoundError(init)\n case 429:\n return new RateLimitError({ ...init, retryAfter })\n case 503:\n return new UnavailableError({ ...init, retryAfter })\n default:\n return status >= 500 ? new ServerError(init) : new PokeWalletError(init)\n }\n}\n","export const VERSION = '0.1.3'\nexport const DEFAULT_BASE_URL = 'https://api.pokewallet.io'\nexport const DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`\n","import { ValidationError, NetworkError, RateLimitError, type PokeWalletError } from './errors.js'\nimport { errorFromResponse } from './error-map.js'\nimport { DEFAULT_BASE_URL, DEFAULT_USER_AGENT } from './version.js'\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface ClientOptions {\n /**\n * API key (`pk_…`). Falls back to the `POKEWALLET_API_KEY` environment variable. Optional at\n * construction: only `health()` and `listGames()` work without one, every other call throws\n * `ValidationError` before touching the network.\n */\n apiKey?: string\n baseUrl?: string\n /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */\n userAgent?: string\n /** Custom `fetch`, mainly for tests. Defaults to the global one. */\n fetch?: FetchLike\n /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */\n maxRetries?: number\n /** Longest `Retry-After` the SDK will sit through, in seconds. Default 30. */\n retryAfterCapSeconds?: number\n /** Per-request timeout in milliseconds. Default 30000. */\n timeoutMs?: number\n /** Replaces the delay between retries, mainly for tests. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Quota counters from the `X-RateLimit-*` headers of the last answer. */\nexport interface RateLimitInfo {\n limitHour: number | null\n remainingHour: number | null\n limitDay: number | null\n remainingDay: number | null\n}\n\nexport type Query = Record<string, string | number | boolean | undefined | null>\n\nconst GAME_PREFIX = /^\\/(mtg|ygo|cfv|dbs|fab|dgm|swu|lor|rft|cpk)\\//\n\nexport const KEY_REQUIRED = 'An API key is required: pass apiKey or set POKEWALLET_API_KEY'\n\n/** The key from the options or the environment; undefined when there is none (public endpoints still work). */\nfunction readKey(options: ClientOptions): string | undefined {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env\n const key = (options.apiKey ?? env?.POKEWALLET_API_KEY ?? '').trim()\n if (!key) return undefined\n if (!key.startsWith('pk_')) throw new ValidationError('API keys start with \"pk_\"')\n return key\n}\n\n/** Seconds from a `Retry-After` value (delta-seconds or HTTP date), or undefined. */\nexport function parseRetryAfter(value: string | null, now = Date.now()): number | undefined {\n if (value == null || value.trim() === '') return undefined\n const n = Number(value)\n if (Number.isFinite(n) && n >= 0) return n\n const t = Date.parse(value)\n return Number.isNaN(t) ? undefined : Math.max(0, Math.ceil((t - now) / 1000))\n}\n\nfunction num(h: Headers, name: string): number | null {\n const v = h.get(name)\n if (v == null) return null\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n}\n\nfunction exhausted(err: RateLimitError): boolean {\n return [err.limits.hourly, err.limits.daily].some((w) => w !== undefined && w.remaining <= 0)\n}\n\nexport class HttpClient {\n /** Quota counters of the most recent answer that carried them. */\n lastRateLimit: RateLimitInfo | null = null\n\n readonly #key: string | undefined\n private readonly baseUrl: string\n private readonly userAgent: string\n private readonly fetchImpl: FetchLike\n private readonly maxRetries: number\n private readonly capSeconds: number\n private readonly timeoutMs: number\n private readonly sleep: (ms: number) => Promise<void>\n\n constructor(options: ClientOptions = {}) {\n this.#key = readKey(options)\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT\n const g = globalThis as { fetch?: FetchLike }\n const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : undefined)\n if (!f) throw new ValidationError('No fetch available: pass options.fetch (Node 18+ has one built in)')\n this.fetchImpl = f\n this.maxRetries = options.maxRetries ?? 2\n this.capSeconds = options.retryAfterCapSeconds ?? 30\n this.timeoutMs = options.timeoutMs ?? 30_000\n this.sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)))\n }\n\n url(path: string, query?: Query): string {\n const qs = new URLSearchParams()\n for (const [k, v] of Object.entries(query ?? {})) if (v !== undefined && v !== null) qs.set(k, String(v))\n const s = qs.toString()\n return `${this.baseUrl}${path}${s ? `?${s}` : ''}`\n }\n\n /**\n * GET `path` and return the parsed JSON body; throws a typed error otherwise. `isPublic`\n * marks the two endpoints the server answers without a key; everything else needs one.\n * `accept` lets a caller treat a non-2xx body as data (see `health()`).\n */\n async get<T>(\n path: string,\n query?: Query,\n options: { isPublic?: boolean; accept?: (body: unknown) => boolean } = {},\n ): Promise<T> {\n if (this.#key === undefined && !options.isPublic) throw new ValidationError(KEY_REQUIRED)\n const url = this.url(path, query)\n for (let attempt = 0; ; attempt++) {\n const res = await this.send(url)\n const body = parseJson(this.#redact(await res.text()))\n this.trackQuota(res.headers)\n if (res.status >= 200 && res.status < 300) return body as T\n // Some non-2xx answers are data, not failures (an \"unhealthy\" report): return them as is, no retry.\n if (options.accept?.(body)) return body as T\n\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'))\n const err = errorFromResponse({ status: res.status, body, retryAfter, gameRoute: GAME_PREFIX.test(path) })\n if (attempt < this.maxRetries && this.shouldRetry(err, retryAfter)) {\n await this.sleep((retryAfter ?? 1) * 1000)\n continue\n }\n throw err\n }\n }\n\n private shouldRetry(err: PokeWalletError, retryAfter: number | undefined): boolean {\n if (err.status === 429) {\n // Never guess a wait: no header, or an exhausted window, means retrying is pointless.\n return retryAfter !== undefined && retryAfter <= this.capSeconds && !exhausted(err as RateLimitError)\n }\n if (err.status === 503) return (retryAfter ?? 1) <= this.capSeconds\n return false\n }\n\n private async send(url: string): Promise<Response> {\n try {\n return await this.fetchImpl(url, {\n method: 'GET',\n headers: {\n ...(this.#key === undefined ? {} : { 'X-API-Key': this.#key }),\n 'User-Agent': this.userAgent,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n } catch (cause) {\n throw new NetworkError('Request failed before an answer arrived', { cause: this.#scrubError(cause) })\n }\n }\n\n /** Masked form: the only representation of this object that logging or serializing can reach. */\n toJSON(): { baseUrl: string; userAgent: string; apiKey: string | null } {\n return { baseUrl: this.baseUrl, userAgent: this.userAgent, apiKey: this.#key === undefined ? null : 'pk_***' }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `HttpClient ${JSON.stringify(this.toJSON())}`\n }\n\n #redact(text: string): string {\n return this.#key === undefined ? text : text.split(this.#key).join('pk_***')\n }\n\n /** A copy of a thrown value with the key removed from its message, stack and string fields. */\n #scrubError(cause: unknown): unknown {\n if (!(cause instanceof Error)) return typeof cause === 'string' ? this.#redact(cause) : undefined\n const copy = new Error(this.#redact(cause.message))\n copy.name = cause.name\n if (cause.stack) copy.stack = this.#redact(cause.stack)\n const code = (cause as { code?: unknown }).code\n if (typeof code === 'string') (copy as { code?: string }).code = code\n return copy\n }\n\n private trackQuota(h: Headers): void {\n const info: RateLimitInfo = {\n limitHour: num(h, 'x-ratelimit-limit-hour'),\n remainingHour: num(h, 'x-ratelimit-remaining-hour'),\n limitDay: num(h, 'x-ratelimit-limit-day'),\n remainingDay: num(h, 'x-ratelimit-remaining-day'),\n }\n if (Object.values(info).some((v) => v !== null)) this.lastRateLimit = info\n }\n}\n\nfunction parseJson(text: string): unknown {\n if (!text) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return { error: text.slice(0, 200) }\n }\n}\n","/**\n * Public, normalized types. Every object keeps the unmodified server value in `raw`.\n * Prices are `number | null`; the API sometimes sends numeric strings.\n */\n\nexport const GAME_CODES = ['mtg', 'ygo', 'cfv', 'dbs', 'fab', 'dgm', 'swu', 'lor', 'rft', 'cpk'] as const\nexport type GameCode = (typeof GAME_CODES)[number]\n\nexport interface TcgPrice {\n /** Finish (`Normal`, `Holofoil`, `Foil`...). Null for rows that have no finish. */\n variant: string | null\n low: number | null\n mid: number | null\n high: number | null\n market: number | null\n directLow: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface CardmarketPrice {\n variant: string | null\n avg: number | null\n low: number | null\n trend: number | null\n avg1: number | null\n avg7: number | null\n avg30: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface Card {\n /** `pk_…` (Pokémon), `op_…`, `<code>_…`, or a 64-character hex CardMarket id. Reuse as is. */\n id: string\n name: string\n cleanName: string | null\n number: string | null\n rarity: string | null\n cardType: string | null\n productType: string | null\n text: string | null\n variants: string[]\n /**\n * Set identifiers. `setId` is the numeric id (possibly negative); `setCode` the short code.\n * Source: `card_info.set_id` / `card_info.set_code`; for cards listed by a set, both come from the\n * response's `set` object.\n * One Piece search and detail answers carry neither, so both are null there.\n */\n setId: string | null\n setCode: string | null\n setName: string | null\n tcgplayer: { url: string | null; prices: TcgPrice[] } | null\n cardmarket: { productName: string | null; url: string | null; prices: CardmarketPrice[] } | null\n /** Game-specific fields: `hp`, `attacks`, `p`, `t`, `ext_color`... as sent by the API. */\n info: Record<string, unknown>\n raw: unknown\n}\n\nexport interface SetSummary {\n /** Numeric set id as a string (`set_id`; `group_id` for One Piece). */\n id: string\n code: string | null\n name: string\n /** Free text. Pokémon uses `eng`/`jap`/`chn`, One Piece `en`/`jp`. */\n language: string | null\n releaseDate: string | null\n cardCount: number | null\n sealedCount: number | null\n raw: unknown\n}\n\nexport interface Page<T> {\n items: T[]\n page: number\n limit: number\n total: number\n /** Computed from `total` and `limit`, so it is always a finite number. */\n totalPages: number\n}\n\nexport interface SearchPage extends Page<Card> {\n /** Pokémon and games: the candidate list was cut at its cap, refine the query instead of paging. Always false for One Piece. */\n truncated: boolean\n}\n\nexport interface SetPage extends Page<Card> {\n set: SetSummary\n}\n\nexport interface PriceRow {\n id: string\n number: string | null\n name: string\n variant: string | null\n productType: string | null\n tcgplayer: TcgPrice | null\n cardmarket: CardmarketPrice | null\n}\n\nexport interface SetPrices {\n source: string\n setId: string | null\n setCode: string | null\n rows: PriceRow[]\n total: number\n raw: unknown\n}\n\nexport interface SetRef {\n id: string | null\n code: string | null\n name: string | null\n}\n\nexport interface PriceStats {\n avg: number | null\n min: number | null\n max: number | null\n mostExpensive: { id: string | null; name: string | null; price: number | null } | null\n trendDirection: string | null\n}\n\nexport interface SetStatistics {\n set: SetRef & { totalCards: number | null }\n tcgplayer: PriceStats | null\n cardmarket: PriceStats | null\n rarityBreakdown: Record<string, number>\n raw: unknown\n}\n\nexport interface CompletionValue {\n set: SetRef & { totalCards: number | null }\n tcgplayer: { currency: string | null; low: number | null; market: number | null; high: number | null } | null\n cardmarket: { currency: string | null; low: number | null; avg: number | null; trend: number | null } | null\n byRarity: Record<string, { count: number; totalCost: number | null }>\n note: string | null\n raw: unknown\n}\n\nexport interface TrendingSet {\n set: SetRef\n cardCount: number | null\n /** As sent: `+446.7%`. */\n change: string | null\n changePct: number | null\n avgPriceCurrent: number | null\n avgPricePrevious: number | null\n topMovers: Array<{ name: string | null; change: string | null }>\n raw: unknown\n}\n\nexport interface TopCard {\n id: string\n name: string\n number: string | null\n rarity: string | null\n setName: string | null\n setId: string | null\n setCode: string | null\n price: number | null\n change7d: string | null\n raw: unknown\n}\n\nexport interface HistoryPoint {\n /** Snapshot price keyed by days back: 7, 14, 30, 60, 120. */\n price: Record<number, number | null>\n change: Record<number, string | null>\n current: Record<string, number | null>\n lastUpdated: string | null\n}\n\nexport interface PriceHistory {\n id: string\n name: string | null\n tcgplayer: Record<string, HistoryPoint> | null\n cardmarket: Record<string, HistoryPoint> | null\n raw: unknown\n}\n\nexport type SearchOptions = { page?: number; limit?: number }\nexport type SetOptions = { page?: number; limit?: number; language?: string }\nexport type PricesOptions = { source?: 'tcg' | 'cm' }\nexport type StatisticsOptions = { variant?: 'normal' | 'foil' }\nexport type TrendingOptions = { period?: '7d'; limit?: number }\nexport type TopCardsOptions = { metric?: 'price' | 'growth'; source?: 'tcg' | 'cm'; limit?: number }\n\nexport interface Game {\n /** Route prefix and `game` code: `mtg`, `ygo`, ... */\n code: GameCode\n name: string\n /** Free routes, keyed by role: `sets`, `set`, `card`, `search`, `image`. */\n endpoints: Record<string, string>\n /** Plan-gated routes: `prices`, `statistics`, `completion_value`, `trending`, `top_cards`. */\n proEndpoints: Record<string, string>\n raw: unknown\n}\n\nexport interface HealthCheck {\n /** `healthy`, `degraded` or `unhealthy`. */\n status: string\n /** Set by the server when the check failed or is limited. */\n message: string | null\n responseTime: number | null\n}\n\nexport interface Health {\n /** Overall status: `healthy` or `unhealthy`. Only the database and storage are critical. */\n status: string\n timestamp: string | null\n version: string | null\n /** Per-service checks: `database`, `cache`, `storage`. */\n checks: Record<string, HealthCheck>\n responseTime: number | null\n region: string | null\n message: string | null\n raw: unknown\n}\n","import { ValidationError } from './errors.js'\nimport { DEFAULT_BASE_URL } from './version.js'\nimport { GAME_CODES, type GameCode } from './types.js'\n\nexport interface ImageUrlOptions {\n baseUrl?: string\n /** Pokémon only: `low` (default) or `high`. */\n size?: 'low' | 'high'\n /** Pokémon only: localized render (`it`, `fr`, `de`, `es`, `pt`). */\n lang?: string\n /** Pokémon only: set code, to disambiguate a plain card number. */\n set?: string\n}\n\n/**\n * Builds the image URL of a card from its id. Pure string work: nothing is fetched.\n *\n * The image routes are protected like every other route: the request MUST carry the\n * `X-API-Key` header, so the URL cannot be used directly in an `<img>` tag. Fetch it\n * yourself with the header, or proxy it server-side.\n */\nexport function imageUrl(id: string, options: ImageUrlOptions = {}): string {\n const clean = id.trim()\n if (!clean) throw new ValidationError('id is required')\n const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n const game = GAME_CODES.find((g: GameCode) => clean.toLowerCase().startsWith(`${g}_`))\n const path = game ? `/${game}/images/${encodeURIComponent(clean)}` : `/images/${encodeURIComponent(clean)}`\n const qs = new URLSearchParams()\n if (!game) {\n if (options.size) qs.set('size', options.size)\n if (options.lang) qs.set('lang', options.lang)\n if (options.set) qs.set('set', options.set)\n }\n const s = qs.toString()\n return `${base}${path}${s ? `?${s}` : ''}`\n}\n","import type { SetRef } from '../types.js'\n\nexport type Rec = Record<string, unknown>\n\nexport const rec = (v: unknown): Rec => (v && typeof v === 'object' && !Array.isArray(v) ? (v as Rec) : {})\nexport const arr = (v: unknown): unknown[] => (Array.isArray(v) ? v : [])\n\nexport function str(v: unknown): string | null {\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return null\n}\n\n/** Numbers pass through, numeric strings are converted, everything else is null. */\nexport function num(v: unknown): number | null {\n if (typeof v === 'number') return Number.isFinite(v) ? v : null\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n }\n return null\n}\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * Some answers put the numeric set id in a field named `set_code` and omit `set_id`\n * (Pokémon statistics, trending, set listings). When no id is given and the \"code\" is\n * purely numeric, it is the id.\n */\nexport function setPair(code: unknown, id: unknown): { id: string | null; code: string | null } {\n const c = str(code)\n const i = str(id)\n if (i === null && c !== null && NUMERIC_ID.test(c)) return { id: c, code: null }\n return { id: i, code: c }\n}\n\nexport function setRef(name: unknown, code: unknown, id: unknown): SetRef {\n return { ...setPair(code, id), name: str(name) }\n}\n","import { GAME_CODES, type Game, type GameCode, type Health, type HealthCheck } from '../types.js'\nimport { arr, num, rec, str } from './common.js'\n\nfunction strings(v: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(rec(v))) if (typeof val === 'string') out[k] = val\n return out\n}\n\n/** `/games`: `{success, data: [{code, name, endpoints, pro_endpoints}]}` becomes a plain array. */\nexport function normalizeGames(raw: unknown): Game[] {\n return arr(rec(raw).data)\n .map((item): Game | null => {\n const g = rec(item)\n const code = str(g.code)\n if (code === null || !(GAME_CODES as readonly string[]).includes(code)) return null\n return { code: code as GameCode, name: str(g.name) ?? code, endpoints: strings(g.endpoints), proEndpoints: strings(g.pro_endpoints), raw: item }\n })\n .filter((g): g is Game => g !== null)\n}\n\n/** True when a body looks like a health report, whatever the HTTP status. */\nexport function isHealthReport(body: unknown): boolean {\n return typeof rec(body).status === 'string'\n}\n\nexport function normalizeHealth(raw: unknown): Health {\n const r = rec(raw)\n const checks: Record<string, HealthCheck> = {}\n for (const [name, value] of Object.entries(rec(r.checks))) {\n const c = rec(value)\n checks[name] = { status: str(c.status) ?? 'unknown', message: str(c.message), responseTime: num(c.responseTime) }\n }\n return {\n status: str(r.status) ?? 'unknown',\n timestamp: str(r.timestamp),\n version: str(r.version),\n checks,\n responseTime: num(r.responseTime),\n region: str(r.region),\n message: str(r.message),\n raw,\n }\n}\n","import type { CardmarketPrice, TcgPrice } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** `variant` is the finish when the API names one (`sub_type_name` / `variant_type` / `variant`). */\nexport function tcgPrice(v: unknown, variant?: unknown): TcgPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.sub_type_name ?? r.variant),\n low: num(r.low_price),\n mid: num(r.mid_price),\n high: num(r.high_price),\n market: num(r.market_price),\n directLow: num(r.direct_low_price),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n\nexport function cardmarketPrice(v: unknown, variant?: unknown): CardmarketPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.variant_type ?? r.variant),\n avg: num(r.avg),\n low: num(r.low),\n trend: num(r.trend),\n avg1: num(r.avg1),\n avg7: num(r.avg7),\n avg30: num(r.avg30),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n","import type { Card } from '../types.js'\nimport { arr, rec, setPair, str, type Rec } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\n/** Where a card was listed, when the surrounding response knows better than `card_info`. */\nexport interface SetContext {\n setId: string | null\n setCode: string | null\n}\n\nconst KNOWN = new Set([\n 'name', 'clean_name', 'set_name', 'set_code', 'set_id', 'card_number', 'rarity', 'card_type',\n 'product_type', 'variants', 'card_text',\n])\n\n/** Card in the Pokémon shape (Pokémon and the ten games): `{id, card_info, tcgplayer, cardmarket}`. */\nexport function normalizeCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const info = rec(r.card_info)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const pair = ctx ?? { setId: setPair(info.set_code, info.set_id).id, setCode: setPair(info.set_code, info.set_id).code }\n return {\n id: str(r.id) ?? '',\n name: str(info.name) ?? '',\n cleanName: str(info.clean_name),\n number: str(info.card_number),\n rarity: str(info.rarity),\n cardType: str(info.card_type),\n productType: str(info.product_type),\n text: str(info.card_text),\n variants: arr(info.variants).filter((v): v is string => typeof v === 'string'),\n setId: pair.setId,\n setCode: pair.setCode,\n setName: str(info.set_name),\n tcgplayer: tcg ? { url: str(tcg.url), prices: arr(tcg.prices).map((p) => tcgPrice(p)) } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: arr(cm.prices).map((p) => cardmarketPrice(p)) }\n : null,\n info: extras(info),\n raw,\n }\n}\n\nfunction extras(info: Rec): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(info)) if (!KNOWN.has(k)) out[k] = v\n return out\n}\n\n/** One Piece card: flat, `ext_*` fields, a single price object per source. */\nexport function normalizeOpCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const finish = r.sub_type_name\n const info: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(r)) if (k.startsWith('ext_')) info[k] = v\n return {\n id: str(r.id) ?? '',\n name: str(r.name) ?? '',\n cleanName: str(r.clean_name),\n number: str(r.card_number),\n rarity: str(r.rarity),\n cardType: str(r.card_type),\n productType: null,\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n setId: ctx?.setId ?? null,\n setCode: ctx?.setCode ?? null,\n setName: null,\n tcgplayer: tcg ? { url: str(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] }\n : null,\n info,\n raw,\n }\n}\n","import type {\n CompletionValue,\n HistoryPoint,\n PriceHistory,\n PriceRow,\n PriceStats,\n SetPrices,\n SetStatistics,\n TopCard,\n TrendingSet,\n} from '../types.js'\nimport { arr, num, rec, setPair, setRef, str } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\nconst DAYS = [7, 14, 30, 60, 120] as const\n\n/** Set prices. Pokémon and One Piece name the set id `group_id`, the games `set_id`. */\nexport function normalizeSetPrices(raw: unknown): SetPrices {\n const r = rec(raw)\n const pair = setPair(r.set_code, r.set_id ?? r.group_id)\n const rows: PriceRow[] = arr(r.data).map((d) => {\n const row = rec(d)\n return {\n id: str(row.id) ?? '',\n number: str(row.card_number),\n name: str(row.name) ?? '',\n variant: str(row.variant),\n productType: str(row.product_type),\n tcgplayer: row.tcgplayer ? tcgPrice(row.tcgplayer, row.variant) : null,\n cardmarket: row.cardmarket ? cardmarketPrice(row.cardmarket, row.variant) : null,\n }\n })\n return { source: str(r.source) ?? 'both', setId: pair.id, setCode: pair.code, rows, total: num(r.total) ?? rows.length, raw }\n}\n\nfunction priceStats(v: unknown): PriceStats | null {\n if (!v || typeof v !== 'object') return null\n const s = rec(v)\n const top = s.most_expensive ? rec(s.most_expensive) : null\n return {\n avg: num(s.avg_market_price ?? s.avg_price),\n min: num(s.min_price),\n max: num(s.max_price),\n mostExpensive: top ? { id: str(top.id), name: str(top.name), price: num(top.price) } : null,\n trendDirection: str(s.trend_direction),\n }\n}\n\nexport function normalizeStatistics(raw: unknown): SetStatistics {\n const r = rec(raw)\n const info = rec(r.set_info)\n const stats = rec(r.price_statistics)\n const rarity: Record<string, number> = {}\n for (const [k, v] of Object.entries(rec(r.rarity_breakdown))) rarity[k] = num(v) ?? 0\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: priceStats(stats.tcgplayer),\n cardmarket: priceStats(stats.cardmarket),\n rarityBreakdown: rarity,\n raw,\n }\n}\n\nexport function normalizeCompletionValue(raw: unknown): CompletionValue {\n const r = rec(raw)\n const info = rec(r.set_info)\n const cost = rec(r.completion_cost)\n const t = cost.tcgplayer ? rec(cost.tcgplayer) : null\n const c = cost.cardmarket ? rec(cost.cardmarket) : null\n const byRarity: CompletionValue['byRarity'] = {}\n for (const [k, v] of Object.entries(rec(r.breakdown_by_rarity))) {\n byRarity[k] = { count: num(rec(v).count) ?? 0, totalCost: num(rec(v).total_cost) }\n }\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: t ? { currency: str(t.currency), low: num(t.low_estimate), market: num(t.market_estimate), high: num(t.high_estimate) } : null,\n cardmarket: c ? { currency: str(c.currency), low: num(c.low_estimate), avg: num(c.avg_estimate), trend: num(c.trend_estimate) } : null,\n byRarity,\n note: str(cost.note),\n raw,\n }\n}\n\n/** `+446.7%` -> 446.7. */\nfunction pct(v: unknown): number | null {\n const s = str(v)\n return s === null ? null : num(s.replace('%', '').replace('+', ''))\n}\n\nexport function normalizeTrending(raw: unknown): TrendingSet[] {\n return arr(rec(raw).trending_sets).map((item) => {\n const s = rec(item)\n const cm = rec(s.cardmarket)\n return {\n set: setRef(s.set_name, s.set_code, s.set_id),\n cardCount: num(s.card_count),\n change: str(cm.price_change),\n changePct: pct(cm.price_change),\n avgPriceCurrent: num(cm.avg_price_current),\n avgPricePrevious: num(cm.avg_price_previous),\n topMovers: arr(cm.top_movers).map((m) => ({ name: str(rec(m).name), change: str(rec(m).change) })),\n raw: item,\n }\n })\n}\n\nexport function normalizeTopCards(raw: unknown): TopCard[] {\n return arr(rec(raw).top_cards).map((item) => {\n const c = rec(item)\n const info = rec(c.card_info)\n const pair = setPair(info.set_code, info.set_id)\n return {\n id: str(c.id) ?? '',\n name: str(info.name) ?? '',\n number: str(info.card_number),\n rarity: str(info.rarity),\n setName: str(info.set_name),\n setId: pair.id,\n setCode: pair.code,\n price: num(c.current_price),\n change7d: str(c.change_7d),\n raw: item,\n }\n })\n}\n\nfunction historySide(v: unknown): Record<string, HistoryPoint> | null {\n const variants = v && typeof v === 'object' ? rec(rec(v).variants) : null\n if (!variants) return null\n const out: Record<string, HistoryPoint> = {}\n for (const [name, data] of Object.entries(variants)) {\n const d = rec(data)\n const current: Record<string, number | null> = {}\n for (const [k, val] of Object.entries(rec(d.current))) current[k] = num(val)\n const price: Record<number, number | null> = {}\n const change: Record<number, string | null> = {}\n for (const day of DAYS) {\n price[day] = num(d[`price_${day}d`])\n change[day] = str(d[`change_${day}d`])\n }\n out[name] = { price, change, current, lastUpdated: str(d.last_updated) }\n }\n return out\n}\n\nexport function normalizePriceHistory(raw: unknown): PriceHistory {\n const r = rec(raw)\n return { id: str(r.id) ?? '', name: str(r.card_name), tcgplayer: historySide(r.tcgplayer), cardmarket: historySide(r.cardmarket), raw }\n}\n","import type { SetSummary } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** Set entry from any list or detail. One Piece names the id `group_id`, everything else `set_id`. */\nexport function normalizeSet(raw: unknown): SetSummary {\n const r = rec(raw)\n return {\n id: str(r.set_id) ?? str(r.group_id) ?? '',\n code: str(r.set_code),\n name: str(r.name) ?? str(r.set_name) ?? '',\n language: str(r.language),\n releaseDate: str(r.release_date),\n cardCount: num(r.card_count ?? r.total_cards),\n sealedCount: num(r.sealed_count),\n raw,\n }\n}\n","import type { Page } from './types.js'\n\n/** Builds a Page, computing `totalPages` here so it is always a finite number. */\nexport function makePage<T>(items: T[], meta: { page: number; limit: number; total: number }): Page<T> {\n const totalPages = meta.limit > 0 ? Math.ceil(meta.total / meta.limit) : 0\n return { items, page: meta.page, limit: meta.limit, total: meta.total, totalPages }\n}\n\n/**\n * Walks every page of any list endpoint as one async sequence. The two pagination\n * shapes of the API are already hidden behind `fetchPage`.\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<Page<T>>,\n options: { startPage?: number; maxItems?: number } = {},\n): AsyncGenerator<T, void, undefined> {\n let page = options.startPage ?? 1\n let yielded = 0\n for (;;) {\n const res = await fetchPage(page)\n for (const item of res.items) {\n if (options.maxItems !== undefined && yielded >= options.maxItems) return\n yield item\n yielded++\n }\n if (res.items.length === 0 || page >= res.totalPages) return\n page++\n }\n}\n","import { ValidationError } from './errors.js'\n\n/** `page` must be a positive integer. */\nexport function checkPage(page: number | undefined): number | undefined {\n if (page === undefined) return undefined\n if (!Number.isInteger(page) || page < 1) throw new ValidationError(`page must be an integer >= 1 (got ${page})`)\n return page\n}\n\n/** `limit` must be an integer in [1, max]. Checked here so out-of-range values never reach the server. */\nexport function checkLimit(limit: number | undefined, max: number): number | undefined {\n if (limit === undefined) return undefined\n if (!Number.isInteger(limit) || limit < 1 || limit > max) {\n throw new ValidationError(`limit must be an integer between 1 and ${max} (got ${limit})`)\n }\n return limit\n}\n\n/** Only `7d` exists, in every world. */\nexport function checkPeriod(period: string | undefined): '7d' {\n if (period !== undefined && period !== '7d') throw new ValidationError(`period ${period} is not available (only 7d)`)\n return '7d'\n}\n\n/** `variant` is `normal` or `foil`. */\nexport function checkVariant(variant: string | undefined): 'normal' | 'foil' | undefined {\n if (variant === undefined) return undefined\n if (variant !== 'normal' && variant !== 'foil') throw new ValidationError(`variant must be normal or foil (got ${variant})`)\n return variant\n}\n\nexport function checkText(name: string, value: string, min = 1): string {\n if (typeof value !== 'string' || value.trim().length < min) {\n throw new ValidationError(`${name} must be at least ${min} character${min === 1 ? '' : 's'} long`)\n }\n return value.trim()\n}\n\n/** Path segment for a user-supplied id or set code. */\nexport function seg(value: string): string {\n return encodeURIComponent(checkText('id', value))\n}\n","import type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\n\n/**\n * The one interface shared by Pokémon, One Piece and the ten games. Where the API\n * needs a different route, parameter or response shape, the world hides it.\n *\n * Plan-gated methods (`prices`, `statistics`, `completionValue`, `trending`, `topCards`)\n * throw `PlanRequiredError` when the account's plan or trial does not cover them.\n * An ambiguous set code throws `AmbiguousSetError`; retry with one of its `matches[].setId`.\n */\nexport interface World {\n /** One page of search results. `q` is 2-100 characters for the ten games. */\n search(q: string, options?: SearchOptions): Promise<SearchPage>\n /** Every result of a search, page after page. */\n searchAll(q: string, options?: { limit?: number; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Card by id (`pk_…`, `op_…`, `<code>_…`, or a 64-hex CardMarket id). */\n card(id: string): Promise<Card>\n /** All sets of the world. The API does not paginate this list. */\n sets(options?: { language?: string }): Promise<SetSummary[]>\n /** One page of a set's cards. `code` is a set code or a numeric set id. */\n set(code: string, options?: SetOptions): Promise<SetPage>\n /** Every card of a set, page after page. */\n setCards(code: string, options?: { limit?: number; language?: string; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Prices of every card in a set: hundreds to thousands of rows. */\n prices(code: string, options?: PricesOptions): Promise<SetPrices>\n statistics(code: string, options?: StatisticsOptions): Promise<SetStatistics>\n completionValue(code: string): Promise<CompletionValue>\n trending(options?: TrendingOptions): Promise<TrendingSet[]>\n topCards(options?: TopCardsOptions): Promise<TopCard[]>\n}\n\nexport const LIMITS = { search: 100, set: 200, trending: 50, topCards: 100 } as const\n","import { ambiguousSetError, isDisambiguation } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nexport interface CardWorldConfig {\n /** Route prefix: `''` for Pokémon, `/mtg` for a game. */\n prefix: string\n /** Minimum search length: the games reject queries shorter than 2 characters. */\n minQuery: number\n}\n\n/** Pokémon and the ten games share one response shape, so one class serves them all. */\nexport class CardWorld implements World {\n constructor(\n protected readonly http: HttpClient,\n protected readonly config: CardWorldConfig,\n ) {}\n\n protected path(rest: string): string {\n return `${this.config.prefix}${rest}`\n }\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get(this.path('/search'), {\n q: checkText('q', q, this.config.minQuery),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const p = rec(body.pagination)\n const items = arr(body.results).map((c) => normalizeCard(c))\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, truncated: rec(body.metadata).truncated === true }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeCard(await this.http.get(this.path(`/cards/${seg(id)}`)))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get(this.path('/sets'), { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(this.path(`/sets/${seg(code)}`), {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n language: options.language,\n }),\n )\n // 200 with a candidate list instead of cards: same condition as the 300/409 answers.\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n const set = normalizeSet(body.set)\n // A set listing names its set once: use the set object for every card.\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.cards).map((c) => normalizeCard(c, ctx))\n const p = rec(body.pagination)\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit, language: options.language }), {\n maxItems: options.maxItems,\n })\n }\n\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n return normalizeSetPrices(await this.http.get(this.path(`/prices/${seg(code)}`), { source: options.source }))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(this.path(`/sets/${seg(code)}/statistics`), { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(this.path(`/sets/${seg(code)}/completion-value`)))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get(this.path('/sets/trending'), { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get(this.path('/analytics/top-cards'), {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n\n","import { ValidationError } from '../errors.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeOpCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * One Piece lives under `/op` with its own shapes: flat cards, flat pagination\n * (`{data,total,page,limit}`), `group_id` instead of `set_id`, and set prices selected\n * through the query string. This class hides all of it behind the shared interface.\n */\nexport class OnePieceWorld implements World {\n constructor(private readonly http: HttpClient) {}\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get('/op/search', {\n q: checkText('q', q),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const items = arr(body.data).map((c) => normalizeOpCard(c))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, truncated: false }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeOpCard(await this.http.get(`/op/cards/${seg(id)}`))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get('/op/sets', { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n /** `options.language` is ignored: One Piece maps a code to its first matching set. */\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(`/op/sets/${seg(code)}`, {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n }),\n )\n const set = normalizeSet(body.set)\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.data).map((c) => normalizeOpCard(c, ctx))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n /** The set goes in the query here (`group_id` for numeric ids, `set_code` otherwise). */\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n if (options.source !== undefined) throw new ValidationError('source is not supported for One Piece prices')\n const c = checkText('code', code)\n const query = NUMERIC_ID.test(c) ? { group_id: c } : { set_code: c }\n return normalizeSetPrices(await this.http.get('/op/prices', query))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(`/op/sets/${seg(code)}/statistics`, { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(`/op/sets/${seg(code)}/completion-value`))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get('/op/sets/trending', { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get('/op/analytics/top-cards', {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n","import { isDisambiguation, ambiguousSetError } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { normalizePriceHistory } from '../normalize/pro.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport type { Card, PriceHistory } from '../types.js'\nimport { seg } from '../validation.js'\nimport { CardWorld } from './card-world.js'\n\n/** Pokémon: the shared card world plus the endpoints only Pokémon has. */\nexport class PokemonWorld extends CardWorld {\n constructor(http: HttpClient) {\n super(http, { prefix: '', minQuery: 1 })\n }\n\n /**\n * Card by id, or by plain card number together with `setCode` (`card('086/078', { setCode: 'SV8a' })`).\n * Ids from `search` and `set` are the safest input.\n */\n override async card(id: string, options: { setCode?: string } = {}): Promise<Card> {\n const body = await this.http.get(this.path(`/cards/${seg(id)}`), { set_code: options.setCode })\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n return normalizeCard(body)\n }\n\n /** Price snapshots at 7/14/30/60/120 days, per finish (not a time series). Pro or trial. */\n async priceHistory(id: string): Promise<PriceHistory> {\n return normalizePriceHistory(await this.http.get(`/cards/${seg(id)}/price-history`))\n }\n}\n","import { HttpClient, type ClientOptions, type RateLimitInfo } from './http.js'\nimport { imageUrl, type ImageUrlOptions } from './images.js'\nimport { normalizeGames, normalizeHealth, isHealthReport } from './normalize/misc.js'\nimport { GAME_CODES, type Game, type GameCode, type Health } from './types.js'\nimport { CardWorld } from './worlds/card-world.js'\nimport { OnePieceWorld } from './worlds/onepiece-world.js'\nimport { PokemonWorld } from './worlds/pokemon-world.js'\nimport type { World } from './worlds/world.js'\n\n/**\n * Entry point. One interface for every world:\n *\n * ```ts\n * const pw = new PokeWallet({ apiKey: process.env.POKEWALLET_API_KEY })\n * await pw.pokemon.search('charizard')\n * await pw.onepiece.set('OP01')\n * await pw.games.mtg.search('black lotus')\n * ```\n */\nexport class PokeWallet {\n readonly pokemon: PokemonWorld\n readonly onepiece: World\n readonly games: Readonly<Record<GameCode, World>>\n\n readonly #http: HttpClient\n readonly #baseUrl: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.#http = new HttpClient(options)\n this.#baseUrl = options.baseUrl\n this.pokemon = new PokemonWorld(this.#http)\n this.onepiece = new OnePieceWorld(this.#http)\n const games = {} as Record<GameCode, World>\n for (const code of GAME_CODES) {\n games[code] = new CardWorld(this.#http, { prefix: `/${code}`, minQuery: 2 })\n }\n this.games = games\n }\n\n /** Quota counters from the most recent answer, or null before the first call. */\n get lastRateLimit(): RateLimitInfo | null {\n return this.#http.lastRateLimit\n }\n\n /** The world for a game code known only at runtime. */\n game(code: GameCode): World {\n return this.games[code]\n }\n\n /**\n * Service status. Works without a key; the header is sent only when a key is set.\n *\n * The API answers 503 with a full report when a critical service is down. That report is\n * information, not a failure: it is returned like a 200, with `status: 'unhealthy'` and the\n * failing `checks`, and is never retried. A 503 without a report (for example an error page\n * from the edge) still throws `UnavailableError`.\n */\n async health(): Promise<Health> {\n return normalizeHealth(await this.#http.get('/health', undefined, { isPublic: true, accept: isHealthReport }))\n }\n\n /** The ten games with their route maps. Works without a key. */\n async listGames(): Promise<Game[]> {\n return normalizeGames(await this.#http.get('/games', undefined, { isPublic: true }))\n }\n\n toJSON(): { client: unknown } {\n return { client: this.#http.toJSON() }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `PokeWallet ${JSON.stringify(this.toJSON())}`\n }\n\n /** See {@link imageUrl}: the URL still needs the API key header. */\n imageUrl(id: string, options: Omit<ImageUrlOptions, 'baseUrl'> = {}): string {\n return imageUrl(id, { ...options, baseUrl: this.#baseUrl })\n }\n}\n"],"mappings":"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","names":["str","num","str","num","str","num","str","str","num","str","num","num","NUMERIC_ID","num"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/error-map.ts","../src/version.ts","../src/http.ts","../src/types.ts","../src/images.ts","../src/normalize/common.ts","../src/normalize/misc.ts","../src/normalize/prices.ts","../src/normalize/card.ts","../src/normalize/pro.ts","../src/normalize/sets.ts","../src/pagination.ts","../src/validation.ts","../src/worlds/world.ts","../src/worlds/card-world.ts","../src/worlds/onepiece-world.ts","../src/worlds/pokemon-world.ts","../src/client.ts"],"sourcesContent":["/** Hourly or daily quota window as reported in a 429 body. */\nexport interface LimitWindow {\n limit: number\n used: number\n remaining: number\n}\n\nexport interface RateLimitWindows {\n hourly?: LimitWindow\n daily?: LimitWindow\n}\n\n/** One candidate of an ambiguous set. `setId` is the value to pass back to pick it. */\nexport interface SetMatch {\n setId: string\n setCode: string | null\n name: string | null\n language: string | null\n releaseDate: string | null\n}\n\nexport interface ErrorInit {\n status: number\n body?: unknown\n message?: string\n}\n\n/** Base class of every error raised by the SDK for an API answer. */\nexport class PokeWalletError extends Error {\n readonly status: number\n /** Parsed JSON body of the answer, when there was one. */\n readonly body: unknown\n /** The `error` field of the body, when present. */\n readonly code: string | undefined\n\n constructor(init: ErrorInit) {\n const code = bodyString(init.body, 'error')\n super(init.message ?? bodyString(init.body, 'message') ?? code ?? `HTTP ${init.status}`)\n this.name = new.target.name\n this.status = init.status\n this.body = init.body\n this.code = code\n }\n}\n\n/** Raised before any request when an argument is out of range. */\nexport class ValidationError extends RangeError {\n constructor(message: string) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n\n/** The request never produced an HTTP answer (DNS, connection, timeout). */\nexport class NetworkError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options)\n this.name = 'NetworkError'\n }\n}\n\n/** 400: missing or invalid parameter, or an id that cannot be decoded. */\nexport class BadRequestError extends PokeWalletError {}\n\n/** 401: key missing, malformed or unknown. */\nexport class AuthError extends PokeWalletError {}\n\n/**\n * 403 on a plan-gated endpoint. `redeemUrl` is set when the free trial was never\n * activated; `upgradeUrl` when the trial expired or the plan is too low.\n */\nexport class PlanRequiredError extends PokeWalletError {\n readonly redeemUrl: string | undefined\n readonly upgradeUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.redeemUrl = bodyString(init.body, 'redeem_url')\n this.upgradeUrl = bodyString(init.body, 'upgrade_url')\n }\n}\n\n/** 403 `Feature not enabled`: this account does not have access to this feature. */\nexport class FeatureNotEnabledError extends PokeWalletError {\n readonly contactUrl: string | undefined\n\n constructor(init: ErrorInit) {\n super(init)\n this.contactUrl = bodyString(init.body, 'contact_url')\n }\n}\n\n/** 404: unknown card, set or route. Carries the server's suggestions when it sent any. */\nexport class NotFoundError extends PokeWalletError {\n readonly didYouMean: string | undefined\n readonly suggestions: unknown[]\n\n constructor(init: ErrorInit) {\n super(init)\n this.didYouMean = bodyString(init.body, 'did_you_mean')\n const s = (init.body as { suggestions?: unknown } | null | undefined)?.suggestions\n this.suggestions = Array.isArray(s) ? s : []\n }\n}\n\n/** 404 on a game route: the game is switched off for this account. */\nexport class GameUnavailableError extends NotFoundError {}\n\n/**\n * The set code matches several sets. Unifies the three ways the API says so\n * (200 with `disambiguation`, 300, 409). Retry with one `matches[i].setId`.\n */\nexport class AmbiguousSetError extends PokeWalletError {\n readonly matches: SetMatch[]\n\n constructor(init: ErrorInit & { matches: SetMatch[] }) {\n super({ ...init, message: init.message ?? 'Several sets match this code: pick one by setId' })\n this.matches = init.matches\n }\n}\n\n/**\n * 429. The API sends no `Retry-After`, so the SDK retries only when the header is\n * present and within the cap. `limits` mirrors the body: when a window shows\n * `remaining === 0`, waiting seconds cannot help.\n */\nexport class RateLimitError extends PokeWalletError {\n readonly limits: RateLimitWindows\n /** Seconds, from the `Retry-After` header, when present. */\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n const l = (init.body as { limits?: Record<string, unknown> } | null | undefined)?.limits\n this.limits = { hourly: toWindow(l?.hourly), daily: toWindow(l?.daily) }\n }\n}\n\n/** 503: database busy or feature not yet enabled. `retryAfter` is 5 or 3600 seconds. */\nexport class UnavailableError extends PokeWalletError {\n readonly retryAfter: number | undefined\n\n constructor(init: ErrorInit & { retryAfter?: number }) {\n super(init)\n this.retryAfter = init.retryAfter\n }\n}\n\n/** Any other 5xx. Never retried. */\nexport class ServerError extends PokeWalletError {}\n\nfunction bodyString(body: unknown, key: string): string | undefined {\n const v = (body as Record<string, unknown> | null | undefined)?.[key]\n return typeof v === 'string' ? v : undefined\n}\n\nfunction toWindow(v: unknown): LimitWindow | undefined {\n if (!v || typeof v !== 'object') return undefined\n const w = v as Record<string, unknown>\n if (typeof w.limit !== 'number' || typeof w.used !== 'number' || typeof w.remaining !== 'number') return undefined\n return { limit: w.limit, used: w.used, remaining: w.remaining }\n}\n","import {\n AmbiguousSetError,\n AuthError,\n BadRequestError,\n FeatureNotEnabledError,\n GameUnavailableError,\n NotFoundError,\n PlanRequiredError,\n PokeWalletError,\n RateLimitError,\n ServerError,\n UnavailableError,\n type SetMatch,\n} from './errors.js'\n\ninterface RawMatch {\n set_id?: unknown\n set_code?: unknown\n name?: unknown\n language?: unknown\n release_date?: unknown\n}\n\nconst str = (v: unknown): string | null => (typeof v === 'string' ? v : typeof v === 'number' ? String(v) : null)\n\n/** Converts the `matches` array of any ambiguous-set body into the public shape. */\nexport function toSetMatches(body: unknown): SetMatch[] {\n const raw = (body as { matches?: unknown } | null | undefined)?.matches\n if (!Array.isArray(raw)) return []\n return raw.map((m: RawMatch) => ({\n setId: str(m.set_id) ?? '',\n setCode: str(m.set_code),\n name: str(m.name),\n language: str(m.language),\n releaseDate: str(m.release_date),\n }))\n}\n\n/** True for the 200 body the API uses to say \"several sets match\". */\nexport function isDisambiguation(body: unknown): boolean {\n return !!body && typeof body === 'object' && (body as { disambiguation?: unknown }).disambiguation === true\n}\n\nexport function ambiguousSetError(status: number, body: unknown): AmbiguousSetError {\n return new AmbiguousSetError({ status, body, matches: toSetMatches(body) })\n}\n\nexport interface ErrorContext {\n status: number\n body: unknown\n retryAfter: number | undefined\n /** True when the request went to one of the ten `/{game}` prefixes. */\n gameRoute: boolean\n}\n\n/** Maps a non-success answer to its typed error. Pure: no retry decisions here. */\nexport function errorFromResponse(ctx: ErrorContext): PokeWalletError {\n const { status, body, retryAfter, gameRoute } = ctx\n const init = { status, body }\n const code = (body as { error?: unknown } | null | undefined)?.error\n\n if (status === 300 || (status === 409 && isDisambiguation(body)) || (status === 409 && code === 'Ambiguous set code')) {\n return ambiguousSetError(status, body)\n }\n switch (status) {\n case 400:\n return new BadRequestError(init)\n case 401:\n return new AuthError(init)\n case 403:\n return code === 'Feature not enabled' ? new FeatureNotEnabledError(init) : new PlanRequiredError(init)\n case 404:\n // A switched-off game answers with the generic route 404, not a resource 404.\n return gameRoute && code === 'Endpoint not found' ? new GameUnavailableError(init) : new NotFoundError(init)\n case 429:\n return new RateLimitError({ ...init, retryAfter })\n case 503:\n return new UnavailableError({ ...init, retryAfter })\n default:\n return status >= 500 ? new ServerError(init) : new PokeWalletError(init)\n }\n}\n","export const VERSION = '0.1.6'\nexport const DEFAULT_BASE_URL = 'https://api.pokewallet.io'\nexport const DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`\n","import { ValidationError, NetworkError, RateLimitError, type PokeWalletError } from './errors.js'\nimport { errorFromResponse } from './error-map.js'\nimport { DEFAULT_BASE_URL, DEFAULT_USER_AGENT } from './version.js'\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface ClientOptions {\n /**\n * API key (`pk_…`). Falls back to the `POKEWALLET_API_KEY` environment variable. Optional at\n * construction: only `health()` and `listGames()` work without one, every other call throws\n * `ValidationError` before touching the network.\n */\n apiKey?: string\n baseUrl?: string\n /** Sent on every request. Some network layers reject the default user agents of HTTP libraries. */\n userAgent?: string\n /**\n * Sent as `X-PokeWallet-Client`, so the API can tell which integration made a call. Browsers\n * cannot set `User-Agent`, so this is the only identification they can send. Default\n * `pokewallet-sdk-ts/<version>`.\n */\n client?: string\n /** Custom `fetch`, mainly for tests. Defaults to the global one. */\n fetch?: FetchLike\n /** Retries after a 429 (with `Retry-After`) or a 503. Default 2. */\n maxRetries?: number\n /** Longest `Retry-After` the SDK will sit through, in seconds. Default 30. */\n retryAfterCapSeconds?: number\n /** Per-request timeout in milliseconds. Default 30000. */\n timeoutMs?: number\n /** Replaces the delay between retries, mainly for tests. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Quota counters from the `X-RateLimit-*` headers of the last answer. */\nexport interface RateLimitInfo {\n limitHour: number | null\n remainingHour: number | null\n limitDay: number | null\n remainingDay: number | null\n}\n\nexport type Query = Record<string, string | number | boolean | undefined | null>\n\nconst GAME_PREFIX = /^\\/(mtg|ygo|cfv|dbs|fab|dgm|swu|lor|rft|cpk)\\//\n\nexport const KEY_REQUIRED = 'An API key is required: pass apiKey or set POKEWALLET_API_KEY'\n\n/** The key from the options or the environment; undefined when there is none (public endpoints still work). */\nfunction readKey(options: ClientOptions): string | undefined {\n const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env\n const key = (options.apiKey ?? env?.POKEWALLET_API_KEY ?? '').trim()\n if (!key) return undefined\n if (!key.startsWith('pk_')) throw new ValidationError('API keys start with \"pk_\"')\n return key\n}\n\n/** Seconds from a `Retry-After` value (delta-seconds or HTTP date), or undefined. */\nexport function parseRetryAfter(value: string | null, now = Date.now()): number | undefined {\n if (value == null || value.trim() === '') return undefined\n const n = Number(value)\n if (Number.isFinite(n) && n >= 0) return n\n const t = Date.parse(value)\n return Number.isNaN(t) ? undefined : Math.max(0, Math.ceil((t - now) / 1000))\n}\n\nfunction num(h: Headers, name: string): number | null {\n const v = h.get(name)\n if (v == null) return null\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n}\n\nfunction exhausted(err: RateLimitError): boolean {\n return [err.limits.hourly, err.limits.daily].some((w) => w !== undefined && w.remaining <= 0)\n}\n\nexport class HttpClient {\n /** Quota counters of the most recent answer that carried them. */\n lastRateLimit: RateLimitInfo | null = null\n\n readonly #key: string | undefined\n private readonly baseUrl: string\n private readonly userAgent: string\n private readonly client: string\n private readonly fetchImpl: FetchLike\n private readonly maxRetries: number\n private readonly capSeconds: number\n private readonly timeoutMs: number\n private readonly sleep: (ms: number) => Promise<void>\n\n constructor(options: ClientOptions = {}) {\n this.#key = readKey(options)\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT\n this.client = options.client ?? DEFAULT_USER_AGENT\n const g = globalThis as { fetch?: FetchLike }\n const f = options.fetch ?? (g.fetch ? g.fetch.bind(globalThis) : undefined)\n if (!f) throw new ValidationError('No fetch available: pass options.fetch (Node 18+ has one built in)')\n this.fetchImpl = f\n this.maxRetries = options.maxRetries ?? 2\n this.capSeconds = options.retryAfterCapSeconds ?? 30\n this.timeoutMs = options.timeoutMs ?? 30_000\n this.sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)))\n }\n\n url(path: string, query?: Query): string {\n const qs = new URLSearchParams()\n for (const [k, v] of Object.entries(query ?? {})) if (v !== undefined && v !== null) qs.set(k, String(v))\n const s = qs.toString()\n return `${this.baseUrl}${path}${s ? `?${s}` : ''}`\n }\n\n /**\n * GET `path` and return the parsed JSON body; throws a typed error otherwise. `isPublic`\n * marks the two endpoints the server answers without a key; everything else needs one.\n * `accept` lets a caller treat a non-2xx body as data (see `health()`).\n */\n async get<T>(\n path: string,\n query?: Query,\n options: { isPublic?: boolean; accept?: (body: unknown) => boolean } = {},\n ): Promise<T> {\n if (this.#key === undefined && !options.isPublic) throw new ValidationError(KEY_REQUIRED)\n const url = this.url(path, query)\n for (let attempt = 0; ; attempt++) {\n const res = await this.send(url)\n const body = parseJson(this.#redact(await res.text()))\n this.trackQuota(res.headers)\n if (res.status >= 200 && res.status < 300) return body as T\n // Some non-2xx answers are data, not failures (an \"unhealthy\" report): return them as is, no retry.\n if (options.accept?.(body)) return body as T\n\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'))\n const err = errorFromResponse({ status: res.status, body, retryAfter, gameRoute: GAME_PREFIX.test(path) })\n if (attempt < this.maxRetries && this.shouldRetry(err, retryAfter)) {\n await this.sleep((retryAfter ?? 1) * 1000)\n continue\n }\n throw err\n }\n }\n\n private shouldRetry(err: PokeWalletError, retryAfter: number | undefined): boolean {\n if (err.status === 429) {\n // Never guess a wait: no header, or an exhausted window, means retrying is pointless.\n return retryAfter !== undefined && retryAfter <= this.capSeconds && !exhausted(err as RateLimitError)\n }\n if (err.status === 503) return (retryAfter ?? 1) <= this.capSeconds\n return false\n }\n\n private async send(url: string): Promise<Response> {\n try {\n return await this.fetchImpl(url, {\n method: 'GET',\n headers: {\n ...(this.#key === undefined ? {} : { 'X-API-Key': this.#key }),\n 'User-Agent': this.userAgent,\n 'X-PokeWallet-Client': this.client,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n } catch (cause) {\n throw new NetworkError('Request failed before an answer arrived', { cause: this.#scrubError(cause) })\n }\n }\n\n /** Masked form: the only representation of this object that logging or serializing can reach. */\n toJSON(): { baseUrl: string; userAgent: string; apiKey: string | null } {\n return { baseUrl: this.baseUrl, userAgent: this.userAgent, apiKey: this.#key === undefined ? null : 'pk_***' }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `HttpClient ${JSON.stringify(this.toJSON())}`\n }\n\n #redact(text: string): string {\n return this.#key === undefined ? text : text.split(this.#key).join('pk_***')\n }\n\n /** A copy of a thrown value with the key removed from its message, stack and string fields. */\n #scrubError(cause: unknown): unknown {\n if (!(cause instanceof Error)) return typeof cause === 'string' ? this.#redact(cause) : undefined\n const copy = new Error(this.#redact(cause.message))\n copy.name = cause.name\n if (cause.stack) copy.stack = this.#redact(cause.stack)\n const code = (cause as { code?: unknown }).code\n if (typeof code === 'string') (copy as { code?: string }).code = code\n return copy\n }\n\n private trackQuota(h: Headers): void {\n const info: RateLimitInfo = {\n limitHour: num(h, 'x-ratelimit-limit-hour'),\n remainingHour: num(h, 'x-ratelimit-remaining-hour'),\n limitDay: num(h, 'x-ratelimit-limit-day'),\n remainingDay: num(h, 'x-ratelimit-remaining-day'),\n }\n if (Object.values(info).some((v) => v !== null)) this.lastRateLimit = info\n }\n}\n\nfunction parseJson(text: string): unknown {\n if (!text) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return { error: text.slice(0, 200) }\n }\n}\n","/**\n * Public, normalized types. Every object keeps the unmodified server value in `raw`.\n * Prices are `number | null`; the API sometimes sends numeric strings.\n */\n\nexport const GAME_CODES = ['mtg', 'ygo', 'cfv', 'dbs', 'fab', 'dgm', 'swu', 'lor', 'rft', 'cpk'] as const\nexport type GameCode = (typeof GAME_CODES)[number]\n\nexport interface TcgPrice {\n /** Finish (`Normal`, `Holofoil`, `Foil`...). Null for rows that have no finish. */\n variant: string | null\n low: number | null\n mid: number | null\n high: number | null\n market: number | null\n directLow: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface CardmarketPrice {\n variant: string | null\n avg: number | null\n low: number | null\n trend: number | null\n avg1: number | null\n avg7: number | null\n avg30: number | null\n updatedAt: string | null\n raw: unknown\n}\n\nexport interface Card {\n /** `pk_…` (Pokémon), `op_…`, `<code>_…`, or a 64-character hex CardMarket id. Reuse as is. */\n id: string\n name: string\n cleanName: string | null\n number: string | null\n rarity: string | null\n cardType: string | null\n productType: string | null\n text: string | null\n variants: string[]\n /**\n * Set identifiers. `setId` is the numeric id (possibly negative); `setCode` the short code.\n * Source: `card_info.set_id` / `card_info.set_code`; for cards listed by a set, both come from the\n * response's `set` object.\n * One Piece search and detail answers carry neither, so both are null there.\n */\n setId: string | null\n setCode: string | null\n setName: string | null\n tcgplayer: { url: string | null; prices: TcgPrice[] } | null\n cardmarket: { productName: string | null; url: string | null; prices: CardmarketPrice[] } | null\n /** Game-specific fields: `hp`, `attacks`, `p`, `t`, `ext_color`... as sent by the API. */\n info: Record<string, unknown>\n raw: unknown\n}\n\nexport interface SetSummary {\n /** Numeric set id as a string (`set_id`; `group_id` for One Piece). */\n id: string\n code: string | null\n name: string\n /** Free text. Pokémon uses `eng`/`jap`/`chn`, One Piece `en`/`jp`. */\n language: string | null\n releaseDate: string | null\n cardCount: number | null\n sealedCount: number | null\n raw: unknown\n}\n\nexport interface Page<T> {\n items: T[]\n page: number\n limit: number\n total: number\n /** Computed from `total` and `limit`, so it is always a finite number. */\n totalPages: number\n}\n\nexport interface SearchPage extends Page<Card> {\n /** Pokémon and games: the candidate list was cut at its cap, refine the query instead of paging. Always false for One Piece. */\n truncated: boolean\n}\n\nexport interface SetPage extends Page<Card> {\n set: SetSummary\n}\n\nexport interface PriceRow {\n id: string\n number: string | null\n name: string\n variant: string | null\n productType: string | null\n tcgplayer: TcgPrice | null\n cardmarket: CardmarketPrice | null\n}\n\nexport interface SetPrices {\n source: string\n setId: string | null\n setCode: string | null\n rows: PriceRow[]\n total: number\n raw: unknown\n}\n\nexport interface SetRef {\n id: string | null\n code: string | null\n name: string | null\n}\n\nexport interface PriceStats {\n avg: number | null\n min: number | null\n max: number | null\n mostExpensive: { id: string | null; name: string | null; price: number | null } | null\n trendDirection: string | null\n}\n\nexport interface SetStatistics {\n set: SetRef & { totalCards: number | null }\n tcgplayer: PriceStats | null\n cardmarket: PriceStats | null\n rarityBreakdown: Record<string, number>\n raw: unknown\n}\n\nexport interface CompletionValue {\n set: SetRef & { totalCards: number | null }\n tcgplayer: { currency: string | null; low: number | null; market: number | null; high: number | null } | null\n cardmarket: { currency: string | null; low: number | null; avg: number | null; trend: number | null } | null\n byRarity: Record<string, { count: number; totalCost: number | null }>\n note: string | null\n raw: unknown\n}\n\nexport interface TrendingSet {\n set: SetRef\n cardCount: number | null\n /** As sent: `+446.7%`. */\n change: string | null\n changePct: number | null\n avgPriceCurrent: number | null\n avgPricePrevious: number | null\n topMovers: Array<{ name: string | null; change: string | null }>\n raw: unknown\n}\n\nexport interface TopCard {\n id: string\n name: string\n number: string | null\n rarity: string | null\n setName: string | null\n setId: string | null\n setCode: string | null\n price: number | null\n change7d: string | null\n raw: unknown\n}\n\nexport interface HistoryPoint {\n /** Snapshot price keyed by days back: 7, 14, 30, 60, 120. */\n price: Record<number, number | null>\n change: Record<number, string | null>\n current: Record<string, number | null>\n lastUpdated: string | null\n}\n\nexport interface PriceHistory {\n id: string\n name: string | null\n tcgplayer: Record<string, HistoryPoint> | null\n cardmarket: Record<string, HistoryPoint> | null\n raw: unknown\n}\n\nexport type SearchOptions = { page?: number; limit?: number }\nexport type SetOptions = { page?: number; limit?: number; language?: string }\nexport type PricesOptions = { source?: 'tcg' | 'cm' }\nexport type StatisticsOptions = { variant?: 'normal' | 'foil' }\nexport type TrendingOptions = { period?: '7d'; limit?: number }\nexport type TopCardsOptions = { metric?: 'price' | 'growth'; source?: 'tcg' | 'cm'; limit?: number }\n\nexport interface Game {\n /** Route prefix and `game` code: `mtg`, `ygo`, ... */\n code: GameCode\n name: string\n /** Free routes, keyed by role: `sets`, `set`, `card`, `search`, `image`. */\n endpoints: Record<string, string>\n /** Plan-gated routes: `prices`, `statistics`, `completion_value`, `trending`, `top_cards`. */\n proEndpoints: Record<string, string>\n raw: unknown\n}\n\nexport interface HealthCheck {\n /** `healthy`, `degraded` or `unhealthy`. */\n status: string\n /** Set by the server when the check failed or is limited. */\n message: string | null\n responseTime: number | null\n}\n\nexport interface Health {\n /** Overall status: `healthy` or `unhealthy`. Only the database and storage are critical. */\n status: string\n timestamp: string | null\n version: string | null\n /** Per-service checks: `database`, `cache`, `storage`. */\n checks: Record<string, HealthCheck>\n responseTime: number | null\n region: string | null\n message: string | null\n raw: unknown\n}\n","import { ValidationError } from './errors.js'\nimport { DEFAULT_BASE_URL } from './version.js'\nimport { GAME_CODES, type GameCode } from './types.js'\n\nexport interface ImageUrlOptions {\n baseUrl?: string\n /** Pokémon only: `low` (default) or `high`. */\n size?: 'low' | 'high'\n /** Pokémon only: localized render (`it`, `fr`, `de`, `es`, `pt`). */\n lang?: string\n /** Pokémon only: set code, to disambiguate a plain card number. */\n set?: string\n}\n\n/**\n * Builds the image URL of a card from its id. Pure string work: nothing is fetched.\n *\n * The image routes are protected like every other route: the request MUST carry the\n * `X-API-Key` header, so the URL cannot be used directly in an `<img>` tag. Fetch it\n * yourself with the header, or proxy it server-side.\n */\nexport function imageUrl(id: string, options: ImageUrlOptions = {}): string {\n const clean = id.trim()\n if (!clean) throw new ValidationError('id is required')\n const base = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '')\n const game = GAME_CODES.find((g: GameCode) => clean.toLowerCase().startsWith(`${g}_`))\n const path = game ? `/${game}/images/${encodeURIComponent(clean)}` : `/images/${encodeURIComponent(clean)}`\n const qs = new URLSearchParams()\n if (!game) {\n if (options.size) qs.set('size', options.size)\n if (options.lang) qs.set('lang', options.lang)\n if (options.set) qs.set('set', options.set)\n }\n const s = qs.toString()\n return `${base}${path}${s ? `?${s}` : ''}`\n}\n","import type { SetRef } from '../types.js'\n\nexport type Rec = Record<string, unknown>\n\nexport const rec = (v: unknown): Rec => (v && typeof v === 'object' && !Array.isArray(v) ? (v as Rec) : {})\nexport const arr = (v: unknown): unknown[] => (Array.isArray(v) ? v : [])\n\nexport function str(v: unknown): string | null {\n if (typeof v === 'string') return v\n if (typeof v === 'number' && Number.isFinite(v)) return String(v)\n return null\n}\n\n/** Numbers pass through, numeric strings are converted, everything else is null. */\nexport function num(v: unknown): number | null {\n if (typeof v === 'number') return Number.isFinite(v) ? v : null\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n return Number.isFinite(n) ? n : null\n }\n return null\n}\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * Some answers put the numeric set id in a field named `set_code` and omit `set_id`\n * (Pokémon statistics, trending, set listings). When no id is given and the \"code\" is\n * purely numeric, it is the id.\n */\nexport function setPair(code: unknown, id: unknown): { id: string | null; code: string | null } {\n const c = str(code)\n const i = str(id)\n if (i === null && c !== null && NUMERIC_ID.test(c)) return { id: c, code: null }\n return { id: i, code: c }\n}\n\nexport function setRef(name: unknown, code: unknown, id: unknown): SetRef {\n return { ...setPair(code, id), name: str(name) }\n}\n","import { GAME_CODES, type Game, type GameCode, type Health, type HealthCheck } from '../types.js'\nimport { arr, num, rec, str } from './common.js'\n\nfunction strings(v: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(rec(v))) if (typeof val === 'string') out[k] = val\n return out\n}\n\n/** `/games`: `{success, data: [{code, name, endpoints, pro_endpoints}]}` becomes a plain array. */\nexport function normalizeGames(raw: unknown): Game[] {\n return arr(rec(raw).data)\n .map((item): Game | null => {\n const g = rec(item)\n const code = str(g.code)\n if (code === null || !(GAME_CODES as readonly string[]).includes(code)) return null\n return { code: code as GameCode, name: str(g.name) ?? code, endpoints: strings(g.endpoints), proEndpoints: strings(g.pro_endpoints), raw: item }\n })\n .filter((g): g is Game => g !== null)\n}\n\n/** True when a body looks like a health report, whatever the HTTP status. */\nexport function isHealthReport(body: unknown): boolean {\n return typeof rec(body).status === 'string'\n}\n\nexport function normalizeHealth(raw: unknown): Health {\n const r = rec(raw)\n const checks: Record<string, HealthCheck> = {}\n for (const [name, value] of Object.entries(rec(r.checks))) {\n const c = rec(value)\n checks[name] = { status: str(c.status) ?? 'unknown', message: str(c.message), responseTime: num(c.responseTime) }\n }\n return {\n status: str(r.status) ?? 'unknown',\n timestamp: str(r.timestamp),\n version: str(r.version),\n checks,\n responseTime: num(r.responseTime),\n region: str(r.region),\n message: str(r.message),\n raw,\n }\n}\n","import type { CardmarketPrice, TcgPrice } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** `variant` is the finish when the API names one (`sub_type_name` / `variant_type` / `variant`). */\nexport function tcgPrice(v: unknown, variant?: unknown): TcgPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.sub_type_name ?? r.variant),\n low: num(r.low_price),\n mid: num(r.mid_price),\n high: num(r.high_price),\n market: num(r.market_price),\n directLow: num(r.direct_low_price),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n\nexport function cardmarketPrice(v: unknown, variant?: unknown): CardmarketPrice {\n const r = rec(v)\n return {\n variant: str(variant ?? r.variant_type ?? r.variant),\n avg: num(r.avg),\n low: num(r.low),\n trend: num(r.trend),\n avg1: num(r.avg1),\n avg7: num(r.avg7),\n avg30: num(r.avg30),\n updatedAt: str(r.updated_at),\n raw: v,\n }\n}\n","import type { Card } from '../types.js'\nimport { arr, rec, setPair, str, type Rec } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\n/** Where a card was listed, when the surrounding response knows better than `card_info`. */\nexport interface SetContext {\n setId: string | null\n setCode: string | null\n}\n\nconst KNOWN = new Set([\n 'name', 'clean_name', 'set_name', 'set_code', 'set_id', 'card_number', 'rarity', 'card_type',\n 'product_type', 'variants', 'card_text',\n])\n\n/** Card in the Pokémon shape (Pokémon and the ten games): `{id, card_info, tcgplayer, cardmarket}`. */\nexport function normalizeCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const info = rec(r.card_info)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const pair = ctx ?? { setId: setPair(info.set_code, info.set_id).id, setCode: setPair(info.set_code, info.set_id).code }\n return {\n id: str(r.id) ?? '',\n name: str(info.name) ?? '',\n cleanName: str(info.clean_name),\n number: str(info.card_number),\n rarity: str(info.rarity),\n cardType: str(info.card_type),\n productType: str(info.product_type),\n text: str(info.card_text),\n variants: arr(info.variants).filter((v): v is string => typeof v === 'string'),\n setId: pair.setId,\n setCode: pair.setCode,\n setName: str(info.set_name),\n tcgplayer: tcg ? { url: str(tcg.url), prices: arr(tcg.prices).map((p) => tcgPrice(p)) } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: arr(cm.prices).map((p) => cardmarketPrice(p)) }\n : null,\n info: extras(info),\n raw,\n }\n}\n\nfunction extras(info: Rec): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(info)) if (!KNOWN.has(k)) out[k] = v\n return out\n}\n\n/** One Piece card: flat, `ext_*` fields, a single price object per source. */\nexport function normalizeOpCard(raw: unknown, ctx?: SetContext): Card {\n const r = rec(raw)\n const tcg = r.tcgplayer ? rec(r.tcgplayer) : null\n const cm = r.cardmarket ? rec(r.cardmarket) : null\n const finish = r.sub_type_name\n const info: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(r)) if (k.startsWith('ext_')) info[k] = v\n return {\n id: str(r.id) ?? '',\n name: str(r.name) ?? '',\n cleanName: str(r.clean_name),\n number: str(r.card_number),\n rarity: str(r.rarity),\n cardType: str(r.card_type),\n productType: null,\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n setId: ctx?.setId ?? null,\n setCode: ctx?.setCode ?? null,\n setName: null,\n tcgplayer: tcg ? { url: str(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,\n cardmarket: cm\n ? { productName: str(cm.product_name), url: str(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] }\n : null,\n info,\n raw,\n }\n}\n","import type {\n CompletionValue,\n HistoryPoint,\n PriceHistory,\n PriceRow,\n PriceStats,\n SetPrices,\n SetStatistics,\n TopCard,\n TrendingSet,\n} from '../types.js'\nimport { arr, num, rec, setPair, setRef, str } from './common.js'\nimport { cardmarketPrice, tcgPrice } from './prices.js'\n\nconst DAYS = [7, 14, 30, 60, 120] as const\n\n/** Set prices. Pokémon and One Piece name the set id `group_id`, the games `set_id`. */\nexport function normalizeSetPrices(raw: unknown): SetPrices {\n const r = rec(raw)\n const pair = setPair(r.set_code, r.set_id ?? r.group_id)\n const rows: PriceRow[] = arr(r.data).map((d) => {\n const row = rec(d)\n return {\n id: str(row.id) ?? '',\n number: str(row.card_number),\n name: str(row.name) ?? '',\n variant: str(row.variant),\n productType: str(row.product_type),\n tcgplayer: row.tcgplayer ? tcgPrice(row.tcgplayer, row.variant) : null,\n cardmarket: row.cardmarket ? cardmarketPrice(row.cardmarket, row.variant) : null,\n }\n })\n return { source: str(r.source) ?? 'both', setId: pair.id, setCode: pair.code, rows, total: num(r.total) ?? rows.length, raw }\n}\n\nfunction priceStats(v: unknown): PriceStats | null {\n if (!v || typeof v !== 'object') return null\n const s = rec(v)\n const top = s.most_expensive ? rec(s.most_expensive) : null\n return {\n avg: num(s.avg_market_price ?? s.avg_price),\n min: num(s.min_price),\n max: num(s.max_price),\n mostExpensive: top ? { id: str(top.id), name: str(top.name), price: num(top.price) } : null,\n trendDirection: str(s.trend_direction),\n }\n}\n\nexport function normalizeStatistics(raw: unknown): SetStatistics {\n const r = rec(raw)\n const info = rec(r.set_info)\n const stats = rec(r.price_statistics)\n const rarity: Record<string, number> = {}\n for (const [k, v] of Object.entries(rec(r.rarity_breakdown))) rarity[k] = num(v) ?? 0\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: priceStats(stats.tcgplayer),\n cardmarket: priceStats(stats.cardmarket),\n rarityBreakdown: rarity,\n raw,\n }\n}\n\nexport function normalizeCompletionValue(raw: unknown): CompletionValue {\n const r = rec(raw)\n const info = rec(r.set_info)\n const cost = rec(r.completion_cost)\n const t = cost.tcgplayer ? rec(cost.tcgplayer) : null\n const c = cost.cardmarket ? rec(cost.cardmarket) : null\n const byRarity: CompletionValue['byRarity'] = {}\n for (const [k, v] of Object.entries(rec(r.breakdown_by_rarity))) {\n byRarity[k] = { count: num(rec(v).count) ?? 0, totalCost: num(rec(v).total_cost) }\n }\n return {\n set: { ...setRef(info.name, info.set_code, info.set_id), totalCards: num(info.total_cards) },\n tcgplayer: t ? { currency: str(t.currency), low: num(t.low_estimate), market: num(t.market_estimate), high: num(t.high_estimate) } : null,\n cardmarket: c ? { currency: str(c.currency), low: num(c.low_estimate), avg: num(c.avg_estimate), trend: num(c.trend_estimate) } : null,\n byRarity,\n note: str(cost.note),\n raw,\n }\n}\n\n/** `+446.7%` -> 446.7. */\nfunction pct(v: unknown): number | null {\n const s = str(v)\n return s === null ? null : num(s.replace('%', '').replace('+', ''))\n}\n\nexport function normalizeTrending(raw: unknown): TrendingSet[] {\n return arr(rec(raw).trending_sets).map((item) => {\n const s = rec(item)\n const cm = rec(s.cardmarket)\n return {\n set: setRef(s.set_name, s.set_code, s.set_id),\n cardCount: num(s.card_count),\n change: str(cm.price_change),\n changePct: pct(cm.price_change),\n avgPriceCurrent: num(cm.avg_price_current),\n avgPricePrevious: num(cm.avg_price_previous),\n topMovers: arr(cm.top_movers).map((m) => ({ name: str(rec(m).name), change: str(rec(m).change) })),\n raw: item,\n }\n })\n}\n\nexport function normalizeTopCards(raw: unknown): TopCard[] {\n return arr(rec(raw).top_cards).map((item) => {\n const c = rec(item)\n const info = rec(c.card_info)\n const pair = setPair(info.set_code, info.set_id)\n return {\n id: str(c.id) ?? '',\n name: str(info.name) ?? '',\n number: str(info.card_number),\n rarity: str(info.rarity),\n setName: str(info.set_name),\n setId: pair.id,\n setCode: pair.code,\n price: num(c.current_price),\n change7d: str(c.change_7d),\n raw: item,\n }\n })\n}\n\nfunction historySide(v: unknown): Record<string, HistoryPoint> | null {\n const variants = v && typeof v === 'object' ? rec(rec(v).variants) : null\n if (!variants) return null\n const out: Record<string, HistoryPoint> = {}\n for (const [name, data] of Object.entries(variants)) {\n const d = rec(data)\n const current: Record<string, number | null> = {}\n for (const [k, val] of Object.entries(rec(d.current))) current[k] = num(val)\n const price: Record<number, number | null> = {}\n const change: Record<number, string | null> = {}\n for (const day of DAYS) {\n price[day] = num(d[`price_${day}d`])\n change[day] = str(d[`change_${day}d`])\n }\n out[name] = { price, change, current, lastUpdated: str(d.last_updated) }\n }\n return out\n}\n\nexport function normalizePriceHistory(raw: unknown): PriceHistory {\n const r = rec(raw)\n return { id: str(r.id) ?? '', name: str(r.card_name), tcgplayer: historySide(r.tcgplayer), cardmarket: historySide(r.cardmarket), raw }\n}\n","import type { SetSummary } from '../types.js'\nimport { num, rec, str } from './common.js'\n\n/** Set entry from any list or detail. One Piece names the id `group_id`, everything else `set_id`. */\nexport function normalizeSet(raw: unknown): SetSummary {\n const r = rec(raw)\n return {\n id: str(r.set_id) ?? str(r.group_id) ?? '',\n code: str(r.set_code),\n name: str(r.name) ?? str(r.set_name) ?? '',\n language: str(r.language),\n releaseDate: str(r.release_date),\n cardCount: num(r.card_count ?? r.total_cards),\n sealedCount: num(r.sealed_count),\n raw,\n }\n}\n","import type { Page } from './types.js'\n\n/** Builds a Page, computing `totalPages` here so it is always a finite number. */\nexport function makePage<T>(items: T[], meta: { page: number; limit: number; total: number }): Page<T> {\n const totalPages = meta.limit > 0 ? Math.ceil(meta.total / meta.limit) : 0\n return { items, page: meta.page, limit: meta.limit, total: meta.total, totalPages }\n}\n\n/**\n * Walks every page of any list endpoint as one async sequence. The two pagination\n * shapes of the API are already hidden behind `fetchPage`.\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<Page<T>>,\n options: { startPage?: number; maxItems?: number } = {},\n): AsyncGenerator<T, void, undefined> {\n let page = options.startPage ?? 1\n let yielded = 0\n for (;;) {\n const res = await fetchPage(page)\n for (const item of res.items) {\n if (options.maxItems !== undefined && yielded >= options.maxItems) return\n yield item\n yielded++\n }\n if (res.items.length === 0 || page >= res.totalPages) return\n page++\n }\n}\n","import { ValidationError } from './errors.js'\n\n/** `page` must be a positive integer. */\nexport function checkPage(page: number | undefined): number | undefined {\n if (page === undefined) return undefined\n if (!Number.isInteger(page) || page < 1) throw new ValidationError(`page must be an integer >= 1 (got ${page})`)\n return page\n}\n\n/** `limit` must be an integer in [1, max]. Checked here so out-of-range values never reach the server. */\nexport function checkLimit(limit: number | undefined, max: number): number | undefined {\n if (limit === undefined) return undefined\n if (!Number.isInteger(limit) || limit < 1 || limit > max) {\n throw new ValidationError(`limit must be an integer between 1 and ${max} (got ${limit})`)\n }\n return limit\n}\n\n/** Only `7d` exists, in every world. */\nexport function checkPeriod(period: string | undefined): '7d' {\n if (period !== undefined && period !== '7d') throw new ValidationError(`period ${period} is not available (only 7d)`)\n return '7d'\n}\n\n/** `variant` is `normal` or `foil`. */\nexport function checkVariant(variant: string | undefined): 'normal' | 'foil' | undefined {\n if (variant === undefined) return undefined\n if (variant !== 'normal' && variant !== 'foil') throw new ValidationError(`variant must be normal or foil (got ${variant})`)\n return variant\n}\n\nexport function checkText(name: string, value: string, min = 1): string {\n if (typeof value !== 'string' || value.trim().length < min) {\n throw new ValidationError(`${name} must be at least ${min} character${min === 1 ? '' : 's'} long`)\n }\n return value.trim()\n}\n\n/** Path segment for a user-supplied id or set code. */\nexport function seg(value: string): string {\n return encodeURIComponent(checkText('id', value))\n}\n","import type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\n\n/**\n * The one interface shared by Pokémon, One Piece and the ten games. Where the API\n * needs a different route, parameter or response shape, the world hides it.\n *\n * Plan-gated methods (`prices`, `statistics`, `completionValue`, `trending`, `topCards`)\n * throw `PlanRequiredError` when the account's plan or trial does not cover them.\n * An ambiguous set code throws `AmbiguousSetError`; retry with one of its `matches[].setId`.\n */\nexport interface World {\n /** One page of search results. `q` is 2-100 characters for the ten games. */\n search(q: string, options?: SearchOptions): Promise<SearchPage>\n /** Every result of a search, page after page. */\n searchAll(q: string, options?: { limit?: number; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Card by id (`pk_…`, `op_…`, `<code>_…`, or a 64-hex CardMarket id). */\n card(id: string): Promise<Card>\n /** All sets of the world. The API does not paginate this list. */\n sets(options?: { language?: string }): Promise<SetSummary[]>\n /** One page of a set's cards. `code` is a set code or a numeric set id. */\n set(code: string, options?: SetOptions): Promise<SetPage>\n /** Every card of a set, page after page. */\n setCards(code: string, options?: { limit?: number; language?: string; maxItems?: number }): AsyncGenerator<Card, void, undefined>\n /** Prices of every card in a set: hundreds to thousands of rows. */\n prices(code: string, options?: PricesOptions): Promise<SetPrices>\n statistics(code: string, options?: StatisticsOptions): Promise<SetStatistics>\n completionValue(code: string): Promise<CompletionValue>\n trending(options?: TrendingOptions): Promise<TrendingSet[]>\n topCards(options?: TopCardsOptions): Promise<TopCard[]>\n}\n\nexport const LIMITS = { search: 100, set: 200, trending: 50, topCards: 100 } as const\n","import { ambiguousSetError, isDisambiguation } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nexport interface CardWorldConfig {\n /** Route prefix: `''` for Pokémon, `/mtg` for a game. */\n prefix: string\n /** Minimum search length: the games reject queries shorter than 2 characters. */\n minQuery: number\n}\n\n/** Pokémon and the ten games share one response shape, so one class serves them all. */\nexport class CardWorld implements World {\n constructor(\n protected readonly http: HttpClient,\n protected readonly config: CardWorldConfig,\n ) {}\n\n protected path(rest: string): string {\n return `${this.config.prefix}${rest}`\n }\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get(this.path('/search'), {\n q: checkText('q', q, this.config.minQuery),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const p = rec(body.pagination)\n const items = arr(body.results).map((c) => normalizeCard(c))\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, truncated: rec(body.metadata).truncated === true }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeCard(await this.http.get(this.path(`/cards/${seg(id)}`)))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get(this.path('/sets'), { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(this.path(`/sets/${seg(code)}`), {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n language: options.language,\n }),\n )\n // 200 with a candidate list instead of cards: same condition as the 300/409 answers.\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n const set = normalizeSet(body.set)\n // A set listing names its set once: use the set object for every card.\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.cards).map((c) => normalizeCard(c, ctx))\n const p = rec(body.pagination)\n const page = makePage(items, { page: num(p.page) ?? 1, limit: num(p.limit) ?? items.length, total: num(p.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit, language: options.language }), {\n maxItems: options.maxItems,\n })\n }\n\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n return normalizeSetPrices(await this.http.get(this.path(`/prices/${seg(code)}`), { source: options.source }))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(this.path(`/sets/${seg(code)}/statistics`), { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(this.path(`/sets/${seg(code)}/completion-value`)))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get(this.path('/sets/trending'), { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get(this.path('/analytics/top-cards'), {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n\n","import { ValidationError } from '../errors.js'\nimport type { HttpClient } from '../http.js'\nimport { arr, num, rec } from '../normalize/common.js'\nimport { normalizeOpCard } from '../normalize/card.js'\nimport {\n normalizeCompletionValue,\n normalizeSetPrices,\n normalizeStatistics,\n normalizeTopCards,\n normalizeTrending,\n} from '../normalize/pro.js'\nimport { normalizeSet } from '../normalize/sets.js'\nimport { makePage, paginate } from '../pagination.js'\nimport type {\n Card,\n CompletionValue,\n PricesOptions,\n SearchOptions,\n SearchPage,\n SetOptions,\n SetPage,\n SetPrices,\n SetStatistics,\n SetSummary,\n StatisticsOptions,\n TopCard,\n TopCardsOptions,\n TrendingOptions,\n TrendingSet,\n} from '../types.js'\nimport { checkLimit, checkPage, checkPeriod, checkText, checkVariant, seg } from '../validation.js'\nimport { LIMITS, type World } from './world.js'\n\nconst NUMERIC_ID = /^-?\\d+$/\n\n/**\n * One Piece lives under `/op` with its own shapes: flat cards, flat pagination\n * (`{data,total,page,limit}`), `group_id` instead of `set_id`, and set prices selected\n * through the query string. This class hides all of it behind the shared interface.\n */\nexport class OnePieceWorld implements World {\n constructor(private readonly http: HttpClient) {}\n\n async search(q: string, options: SearchOptions = {}): Promise<SearchPage> {\n const body = rec(\n await this.http.get('/op/search', {\n q: checkText('q', q),\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.search),\n }),\n )\n const items = arr(body.data).map((c) => normalizeOpCard(c))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, truncated: false }\n }\n\n searchAll(q: string, options: { limit?: number; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.search(q, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n async card(id: string): Promise<Card> {\n return normalizeOpCard(await this.http.get(`/op/cards/${seg(id)}`))\n }\n\n async sets(options: { language?: string } = {}): Promise<SetSummary[]> {\n const body = rec(await this.http.get('/op/sets', { language: options.language }))\n return arr(body.data).map(normalizeSet)\n }\n\n /** `options.language` is ignored: One Piece maps a code to its first matching set. */\n async set(code: string, options: SetOptions = {}): Promise<SetPage> {\n const body = rec(\n await this.http.get(`/op/sets/${seg(code)}`, {\n page: checkPage(options.page),\n limit: checkLimit(options.limit, LIMITS.set),\n }),\n )\n const set = normalizeSet(body.set)\n const ctx = { setId: set.id || null, setCode: set.code }\n const items = arr(body.data).map((c) => normalizeOpCard(c, ctx))\n const page = makePage(items, { page: num(body.page) ?? 1, limit: num(body.limit) ?? items.length, total: num(body.total) ?? items.length })\n return { ...page, set }\n }\n\n setCards(code: string, options: { limit?: number; language?: string; maxItems?: number } = {}): AsyncGenerator<Card, void, undefined> {\n return paginate((page) => this.set(code, { page, limit: options.limit }), { maxItems: options.maxItems })\n }\n\n /** The set goes in the query here (`group_id` for numeric ids, `set_code` otherwise). */\n async prices(code: string, options: PricesOptions = {}): Promise<SetPrices> {\n if (options.source !== undefined) throw new ValidationError('source is not supported for One Piece prices')\n const c = checkText('code', code)\n const query = NUMERIC_ID.test(c) ? { group_id: c } : { set_code: c }\n return normalizeSetPrices(await this.http.get('/op/prices', query))\n }\n\n async statistics(code: string, options: StatisticsOptions = {}): Promise<SetStatistics> {\n return normalizeStatistics(await this.http.get(`/op/sets/${seg(code)}/statistics`, { variant: checkVariant(options.variant) }))\n }\n\n async completionValue(code: string): Promise<CompletionValue> {\n return normalizeCompletionValue(await this.http.get(`/op/sets/${seg(code)}/completion-value`))\n }\n\n async trending(options: TrendingOptions = {}): Promise<TrendingSet[]> {\n const period = checkPeriod(options.period)\n return normalizeTrending(await this.http.get('/op/sets/trending', { period, limit: checkLimit(options.limit, LIMITS.trending) }))\n }\n\n async topCards(options: TopCardsOptions = {}): Promise<TopCard[]> {\n return normalizeTopCards(\n await this.http.get('/op/analytics/top-cards', {\n metric: options.metric,\n source: options.source,\n limit: checkLimit(options.limit, LIMITS.topCards),\n }),\n )\n }\n}\n","import { isDisambiguation, ambiguousSetError } from '../error-map.js'\nimport type { HttpClient } from '../http.js'\nimport { normalizePriceHistory } from '../normalize/pro.js'\nimport { normalizeCard } from '../normalize/card.js'\nimport type { Card, PriceHistory } from '../types.js'\nimport { seg } from '../validation.js'\nimport { CardWorld } from './card-world.js'\n\n/** Pokémon: the shared card world plus the endpoints only Pokémon has. */\nexport class PokemonWorld extends CardWorld {\n constructor(http: HttpClient) {\n super(http, { prefix: '', minQuery: 1 })\n }\n\n /**\n * Card by id, or by plain card number together with `setCode` (`card('086/078', { setCode: 'SV8a' })`).\n * Ids from `search` and `set` are the safest input.\n */\n override async card(id: string, options: { setCode?: string } = {}): Promise<Card> {\n const body = await this.http.get(this.path(`/cards/${seg(id)}`), { set_code: options.setCode })\n if (isDisambiguation(body)) throw ambiguousSetError(200, body)\n return normalizeCard(body)\n }\n\n /** Price snapshots at 7/14/30/60/120 days, per finish (not a time series). Pro or trial. */\n async priceHistory(id: string): Promise<PriceHistory> {\n return normalizePriceHistory(await this.http.get(`/cards/${seg(id)}/price-history`))\n }\n}\n","import { HttpClient, type ClientOptions, type RateLimitInfo } from './http.js'\nimport { imageUrl, type ImageUrlOptions } from './images.js'\nimport { normalizeGames, normalizeHealth, isHealthReport } from './normalize/misc.js'\nimport { GAME_CODES, type Game, type GameCode, type Health } from './types.js'\nimport { CardWorld } from './worlds/card-world.js'\nimport { OnePieceWorld } from './worlds/onepiece-world.js'\nimport { PokemonWorld } from './worlds/pokemon-world.js'\nimport type { World } from './worlds/world.js'\n\n/**\n * Entry point. One interface for every world:\n *\n * ```ts\n * const pw = new PokeWallet({ apiKey: process.env.POKEWALLET_API_KEY })\n * await pw.pokemon.search('charizard')\n * await pw.onepiece.set('OP01')\n * await pw.games.mtg.search('black lotus')\n * ```\n */\nexport class PokeWallet {\n readonly pokemon: PokemonWorld\n readonly onepiece: World\n readonly games: Readonly<Record<GameCode, World>>\n\n readonly #http: HttpClient\n readonly #baseUrl: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.#http = new HttpClient(options)\n this.#baseUrl = options.baseUrl\n this.pokemon = new PokemonWorld(this.#http)\n this.onepiece = new OnePieceWorld(this.#http)\n const games = {} as Record<GameCode, World>\n for (const code of GAME_CODES) {\n games[code] = new CardWorld(this.#http, { prefix: `/${code}`, minQuery: 2 })\n }\n this.games = games\n }\n\n /** Quota counters from the most recent answer, or null before the first call. */\n get lastRateLimit(): RateLimitInfo | null {\n return this.#http.lastRateLimit\n }\n\n /** The world for a game code known only at runtime. */\n game(code: GameCode): World {\n return this.games[code]\n }\n\n /**\n * Service status. Works without a key; the header is sent only when a key is set.\n *\n * The API answers 503 with a full report when a critical service is down. That report is\n * information, not a failure: it is returned like a 200, with `status: 'unhealthy'` and the\n * failing `checks`, and is never retried. A 503 without a report (for example an error page\n * from the edge) still throws `UnavailableError`.\n */\n async health(): Promise<Health> {\n return normalizeHealth(await this.#http.get('/health', undefined, { isPublic: true, accept: isHealthReport }))\n }\n\n /** The ten games with their route maps. Works without a key. */\n async listGames(): Promise<Game[]> {\n return normalizeGames(await this.#http.get('/games', undefined, { isPublic: true }))\n }\n\n toJSON(): { client: unknown } {\n return { client: this.#http.toJSON() }\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `PokeWallet ${JSON.stringify(this.toJSON())}`\n }\n\n /** See {@link imageUrl}: the URL still needs the API key header. */\n imageUrl(id: string, options: Omit<ImageUrlOptions, 'baseUrl'> = {}): string {\n return imageUrl(id, { ...options, baseUrl: this.#baseUrl })\n }\n}\n"],"mappings":"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","names":["str","num","str","num","str","num","str","str","num","str","num","num","NUMERIC_ID","num"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pokewallet/sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.6",
4
4
  "description": "Official TypeScript SDK for the PokeWallet API",
5
5
  "license": "MIT",
6
6
  "type": "module",