@pokewallet/sdk 0.1.7 → 0.1.8

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/README.md CHANGED
@@ -20,7 +20,7 @@ Pokémon, One Piece and the ten games (`pw.games.mtg`, `pw.games.ygo`, ...) shar
20
20
  - **Typed errors:** `AuthError`, `PlanRequiredError` (`redeemUrl` / `upgradeUrl`), `FeatureNotEnabledError`, `RateLimitError` (`limits`), `AmbiguousSetError` (`matches`), `NotFoundError`, `UnavailableError`, `ValidationError`.
21
21
  - **Retries:** only on 429 (when `Retry-After` is present, within `retryAfterCapSeconds`, default 30, and no quota window is exhausted) and on 503 (up to `maxRetries`, default 2). Never on other 4xx or 5xx. `fetch`, `timeoutMs` and `sleep` are injectable.
22
22
  - **Validation:** `limit` and `page` are checked before the request is sent.
23
- - **Normalization:** prices are `number | null`; set identifiers are exposed as `setId` / `setCode`; every object keeps the server value in `raw`; a card has `productType` and a set listing has `cardCount` / `sealedCount`. Ambiguous set answers (200, 300 and 409 on the wire) all raise `AmbiguousSetError`.
23
+ - **Normalization:** prices are `number | null`; set identifiers are exposed as `setId` / `setCode` / `setName` (One Piece too, in card detail and search); every object keeps the server value in `raw`; a card has `productType` and a set listing has `cardCount` / `sealedCount`. Ambiguous set answers (200, 300 and 409 on the wire) all raise `AmbiguousSetError`.
24
24
  - **Key safety:** the key is held in a private field and shown as `pk_***` by `JSON.stringify`, `util.inspect` and errors.
25
25
  - **Images:** `imageUrl(id)` only builds the URL. The image routes need the `X-API-Key` header, so the URL cannot be used directly in an `<img>` tag. A 404 `Image not found` means the source has no image (do not retry it in the same run); 5xx answers are temporary (retry with backoff); on 429 wait for `Retry-After`.
26
26
  - **CardMarket-only sets** (negative `set_id`): each `prices` row is one CardMarket product, and its `cardmarket` block is the `normal` price. A `tcgplayer` block there is an extra link with no finish and must not be compared or added to it; for European prices by finish use `card(id)`. An ambiguous `set_code` on `prices` is resolved with the numeric `set_id`.
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.7";
187
+ var VERSION = "0.1.8";
188
188
  var DEFAULT_BASE_URL = "https://api.pokewallet.io";
189
189
  var DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`;
190
190
 
@@ -504,9 +504,10 @@ function normalizeOpCard(raw, ctx) {
504
504
  productType: str2(r.product_type),
505
505
  text: str2(r.ext_description),
506
506
  variants: typeof finish === "string" ? [finish] : [],
507
- setId: ctx?.setId ?? null,
508
- setCode: ctx?.setCode ?? null,
509
- setName: null,
507
+ // Detail and search entries carry their set; set listings leave it to the `set` block (ctx).
508
+ setId: str2(r.set_id) ?? str2(r.group_id) ?? ctx?.setId ?? null,
509
+ setCode: str2(r.set_code) ?? ctx?.setCode ?? null,
510
+ setName: str2(r.set_name),
510
511
  tcgplayer: tcg ? { url: str2(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,
511
512
  cardmarket: cm ? { productName: str2(cm.product_name), url: str2(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] } : null,
512
513
  info,
@@ -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.7'\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: str(r.product_type),\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.8'\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: str(r.product_type),\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n // Detail and search entries carry their set; set listings leave it to the `set` block (ctx).\n setId: str(r.set_id) ?? str(r.group_id) ?? ctx?.setId ?? null,\n setCode: str(r.set_code) ?? ctx?.setCode ?? null,\n setName: str(r.set_name),\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/dist/index.d.cts CHANGED
@@ -571,7 +571,7 @@ declare class UnavailableError extends PokeWalletError {
571
571
  declare class ServerError extends PokeWalletError {
572
572
  }
573
573
 
574
- declare const VERSION = "0.1.7";
574
+ declare const VERSION = "0.1.8";
575
575
 
576
576
  /**
577
577
  * This file was auto-generated by openapi-typescript.
@@ -1574,6 +1574,13 @@ interface components {
1574
1574
  /** @description `card` or a sealed product type. */
1575
1575
  product_type?: string | null;
1576
1576
  clean_name?: string | null;
1577
+ /** @description Set name from the set mapping; falls back to the code. In `/op/cards/:id` and `/op/search` only: set listings carry it in the `set` block. */
1578
+ set_name?: string | null;
1579
+ set_code?: string | null;
1580
+ /** @description The set's `group_id`, always a string; negative for CardMarket-only sets. */
1581
+ set_id?: string;
1582
+ /** @description Alias of `set_id`. */
1583
+ group_id?: string;
1577
1584
  sub_type_name?: string | null;
1578
1585
  rarity?: string | null;
1579
1586
  card_type?: string | null;
package/dist/index.d.ts CHANGED
@@ -571,7 +571,7 @@ declare class UnavailableError extends PokeWalletError {
571
571
  declare class ServerError extends PokeWalletError {
572
572
  }
573
573
 
574
- declare const VERSION = "0.1.7";
574
+ declare const VERSION = "0.1.8";
575
575
 
576
576
  /**
577
577
  * This file was auto-generated by openapi-typescript.
@@ -1574,6 +1574,13 @@ interface components {
1574
1574
  /** @description `card` or a sealed product type. */
1575
1575
  product_type?: string | null;
1576
1576
  clean_name?: string | null;
1577
+ /** @description Set name from the set mapping; falls back to the code. In `/op/cards/:id` and `/op/search` only: set listings carry it in the `set` block. */
1578
+ set_name?: string | null;
1579
+ set_code?: string | null;
1580
+ /** @description The set's `group_id`, always a string; negative for CardMarket-only sets. */
1581
+ set_id?: string;
1582
+ /** @description Alias of `set_id`. */
1583
+ group_id?: string;
1577
1584
  sub_type_name?: string | null;
1578
1585
  rarity?: string | null;
1579
1586
  card_type?: string | null;
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.7";
144
+ var VERSION = "0.1.8";
145
145
  var DEFAULT_BASE_URL = "https://api.pokewallet.io";
146
146
  var DEFAULT_USER_AGENT = `pokewallet-sdk-ts/${VERSION}`;
147
147
 
@@ -461,9 +461,10 @@ function normalizeOpCard(raw, ctx) {
461
461
  productType: str2(r.product_type),
462
462
  text: str2(r.ext_description),
463
463
  variants: typeof finish === "string" ? [finish] : [],
464
- setId: ctx?.setId ?? null,
465
- setCode: ctx?.setCode ?? null,
466
- setName: null,
464
+ // Detail and search entries carry their set; set listings leave it to the `set` block (ctx).
465
+ setId: str2(r.set_id) ?? str2(r.group_id) ?? ctx?.setId ?? null,
466
+ setCode: str2(r.set_code) ?? ctx?.setCode ?? null,
467
+ setName: str2(r.set_name),
467
468
  tcgplayer: tcg ? { url: str2(tcg.url), prices: tcg.prices ? [tcgPrice(tcg.prices, finish)] : [] } : null,
468
469
  cardmarket: cm ? { productName: str2(cm.product_name), url: str2(cm.product_url), prices: cm.prices ? [cardmarketPrice(cm.prices, finish)] : [] } : null,
469
470
  info,
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.7'\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: str(r.product_type),\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.8'\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: str(r.product_type),\n text: str(r.ext_description),\n variants: typeof finish === 'string' ? [finish] : [],\n // Detail and search entries carry their set; set listings leave it to the `set` block (ctx).\n setId: str(r.set_id) ?? str(r.group_id) ?? ctx?.setId ?? null,\n setCode: str(r.set_code) ?? ctx?.setCode ?? null,\n setName: str(r.set_name),\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.7",
3
+ "version": "0.1.8",
4
4
  "description": "Official TypeScript SDK for the PokeWallet API",
5
5
  "license": "MIT",
6
6
  "type": "module",