@carddex/sdk 0.2.0 → 0.3.0

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
@@ -35,6 +35,21 @@ const history = await client.cards.priceHistory('sv06-001', { days: 180, source:
35
35
  An API key is optional. Omit it to call the API anonymously. The SDK sends the key in the `X-API-Key` header.
36
36
 
37
37
  You can also sign in with an email link at [carddex.dev/account](https://carddex.dev/account) to see your keys, create up to 2 active keys, and rotate or revoke them.
38
+
39
+ ### Card names in German, French, Italian, Spanish and Portuguese
40
+
41
+ The catalogue is the English one, and `name` is always the English name. Pass `lang` (`de`, `fr`, `it`, `es` or `pt`) and every card and set also carries `localized_name`: its name in that language edition, or `null` where none is known. With `lang`, `name` and `q` also match names in that language. `include: ['translations']` lists every localized name a card has.
42
+
43
+ ```ts
44
+ const { data } = await client.cards.list({ name: 'Glurak', lang: 'de' });
45
+ // data[0].name === 'Charizard', data[0].localized_name === 'Glurak'
46
+
47
+ const sets = await client.sets.list({ lang: 'fr' });
48
+ const card = await client.cards.get('base1-4', { include: ['translations'] });
49
+ ```
50
+
51
+ Polish card names are not available from any source, so `lang: 'pl'` is rejected (the API answers 400). Japanese cards are not in the catalogue yet.
52
+
38
53
  ### Get a free API key
39
54
 
40
55
  ```ts
package/dist/index.cjs CHANGED
@@ -356,15 +356,16 @@ var SetsResource = class {
356
356
  this.http = http;
357
357
  }
358
358
  http;
359
- /** `GET /v1/sets` — every set. */
360
- async list() {
361
- const res = await this.http.get("/v1/sets");
359
+ /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
360
+ async list(params) {
361
+ const res = await this.http.get("/v1/sets", params);
362
362
  return res.data;
363
363
  }
364
- /** `GET /v1/sets/{id}` */
365
- async get(id) {
364
+ /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
365
+ async get(id, params) {
366
366
  const res = await this.http.get(
367
- `/v1/sets/${encodeURIComponent(id)}`
367
+ `/v1/sets/${encodeURIComponent(id)}`,
368
+ params
368
369
  );
369
370
  return res.data;
370
371
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/resources/auth.ts","../src/pagination.ts","../src/resources/cards.ts","../src/resources/prices.ts","../src/resources/sealed.ts","../src/resources/sets.ts","../src/client.ts"],"sourcesContent":["export type { CardDexOptions } from './client.js';\nexport { CardDex } from './client.js';\nexport type { RateLimitInfo } from './errors.js';\nexport { CardDexError } from './errors.js';\nexport type { RetryOptions } from './http.js';\nexport { paginate } from './pagination.js';\nexport * from './params.js';\nexport * from './types.js';\n","/** Rate-limit info parsed from response headers, when present. */\nexport interface RateLimitInfo {\n /** `X-RateLimit-Limit`: requests allowed per minute. */\n limit: number | null;\n /** `X-RateLimit-Daily-Limit`: requests allowed per UTC day, or `null` when the tier is uncapped. */\n dailyLimit: number | null;\n /** `X-RateLimit-Daily-Remaining`: approximate, can lag by about a minute. `null` when the API couldn't compute it. */\n dailyRemaining: number | null;\n}\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const num = (name: string): number | null => {\n const raw = headers.get(name);\n if (raw == null) return null;\n const n = Number(raw);\n return Number.isFinite(n) ? n : null;\n };\n return {\n limit: num('X-RateLimit-Limit'),\n dailyLimit: num('X-RateLimit-Daily-Limit'),\n dailyRemaining: num('X-RateLimit-Daily-Remaining'),\n };\n}\n\n/**\n * Thrown for any non-2xx response, and for network/parse failures the fetch\n * layer can't attribute to the API itself.\n */\nexport class CardDexError extends Error {\n /** HTTP status code. `0` for a request that never got a response (network failure, abort). */\n readonly status: number;\n /**\n * The API's own `error.code`. For a response the API actually produced,\n * this is the same number as `status` (see the note on `ApiErrorBody` in\n * `types.ts`) — kept as its own field because a transport-level failure\n * (no response at all) sets it to a string like `NETWORK_ERROR` instead.\n */\n readonly code: number | string;\n /** Seconds to wait before retrying, parsed from `Retry-After` on a 429. `null` otherwise. */\n readonly retryAfter: number | null;\n /** Rate-limit headers on the response, when there was one. */\n readonly rateLimit: RateLimitInfo | null;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: number | string;\n retryAfter?: number | null;\n rateLimit?: RateLimitInfo | null;\n cause?: unknown;\n },\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CardDexError';\n this.status = options.status;\n this.code = options.code;\n this.retryAfter = options.retryAfter ?? null;\n this.rateLimit = options.rateLimit ?? null;\n Object.setPrototypeOf(this, CardDexError.prototype);\n }\n\n /** Whether this is a 429 (either the per-minute or the daily cap). */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n static async fromResponse(response: Response): Promise<CardDexError> {\n const rateLimit = parseRateLimitHeaders(response.headers);\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader != null ? Number(retryAfterHeader) : null;\n\n let message = `CardDex API error (${response.status})`;\n let code: number | string = response.status;\n try {\n const body = (await response.clone().json()) as {\n error?: { code?: unknown; message?: unknown };\n };\n if (body?.error) {\n if (typeof body.error.message === 'string') message = body.error.message;\n if (typeof body.error.code === 'number' || typeof body.error.code === 'string') {\n code = body.error.code;\n }\n }\n } catch {\n // Non-JSON or empty error body — fall back to the status-derived message above.\n }\n\n return new CardDexError(message, {\n status: response.status,\n code,\n retryAfter: Number.isFinite(retryAfter) ? retryAfter : null,\n rateLimit,\n });\n }\n\n static network(cause: unknown): CardDexError {\n const message = cause instanceof Error ? cause.message : 'Network request failed';\n return new CardDexError(message, { status: 0, code: 'NETWORK_ERROR', cause });\n }\n}\n","import { CardDexError } from './errors.js';\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | undefined\n | null\n | readonly (string | number)[];\nexport type QueryParams = Record<string, QueryValue>;\n\nexport interface RetryOptions {\n /** Max retry attempts on 429. Default 2. */\n maxRetries?: number;\n /**\n * A computed `Retry-After` above this many seconds is never honoured — the\n * request fails immediately instead of sleeping (this is what keeps a\n * daily-quota 429, whose `Retry-After` can be most of a day, from blocking\n * for hours). Default 60, matching the per-minute limiter's own\n * `Retry-After: 60`.\n */\n maxWaitSeconds?: number;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** `false` (default) disables retries; `true` enables them with the defaults below. */\n retry?: boolean | RetryOptions;\n}\n\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_WAIT_SECONDS = 60;\n\nfunction buildQueryString(params?: QueryParams): string {\n if (!params) return '';\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n if (value.length === 0) continue;\n search.set(key, value.join(','));\n } else {\n search.set(key, String(value));\n }\n }\n const qs = search.toString();\n return qs ? `?${qs}` : '';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Minimal fetch wrapper: builds URLs, attaches auth, parses JSON, and turns\n * non-2xx responses into `CardDexError`. No dependency beyond global `fetch`.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly fetchImpl: typeof fetch;\n private readonly retryConfig: Required<RetryOptions> | null;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetch;\n if (options.retry === true) {\n this.retryConfig = {\n maxRetries: DEFAULT_MAX_RETRIES,\n maxWaitSeconds: DEFAULT_MAX_WAIT_SECONDS,\n };\n } else if (options.retry && typeof options.retry === 'object') {\n this.retryConfig = {\n maxRetries: options.retry.maxRetries ?? DEFAULT_MAX_RETRIES,\n maxWaitSeconds: options.retry.maxWaitSeconds ?? DEFAULT_MAX_WAIT_SECONDS,\n };\n } else {\n this.retryConfig = null;\n }\n }\n\n async get<T>(path: string, query?: QueryParams, signal?: AbortSignal): Promise<T> {\n return this.request<T>('GET', path, { query, signal });\n }\n\n async post<T>(path: string, body?: unknown, signal?: AbortSignal): Promise<T> {\n return this.request<T>('POST', path, { body, signal });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { query?: QueryParams; body?: unknown; signal?: AbortSignal },\n ): Promise<T> {\n const url = `${this.baseUrl}${path}${buildQueryString(opts.query)}`;\n const headers: Record<string, string> = { Accept: 'application/json' };\n if (this.apiKey) headers['X-API-Key'] = this.apiKey;\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n\n let attempt = 0;\n for (;;) {\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n } catch (cause) {\n throw CardDexError.network(cause);\n }\n\n if (response.status === 429 && this.retryConfig && attempt < this.retryConfig.maxRetries) {\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfterSeconds = retryAfterHeader != null ? Number(retryAfterHeader) : Number.NaN;\n if (\n Number.isFinite(retryAfterSeconds) &&\n retryAfterSeconds <= this.retryConfig.maxWaitSeconds\n ) {\n attempt++;\n await sleep(retryAfterSeconds * 1000);\n continue;\n }\n // Retry-After is missing or longer than we're willing to wait\n // (typically the daily cap, which resets at UTC midnight) — surface\n // the error instead of blocking.\n }\n\n if (!response.ok) {\n throw await CardDexError.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { RegisterResponse, SingleResponse, UsageResponse } from '../types.js';\n\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `POST /v1/auth/register` — claim a free API key. The key is returned\n * exactly once, so store it immediately. A lost key can be replaced by signing\n * in at https://carddex.dev/account (create, rotate or revoke keys there).\n */\n async register(email: string, name?: string): Promise<RegisterResponse> {\n const res = await this.http.post<SingleResponse<RegisterResponse>>('/v1/auth/register', {\n email,\n name,\n });\n return res.data;\n }\n\n /** `GET /v1/auth/usage` — usage stats for the API key this client was constructed with. Requires an `apiKey`. */\n async usage(): Promise<UsageResponse> {\n const res = await this.http.get<SingleResponse<UsageResponse>>('/v1/auth/usage');\n return res.data;\n }\n}\n","import type { PaginatedResponse } from './types.js';\n\n/**\n * Turns a page-fetching function into an async iterator over every item,\n * fetching the next page lazily as the caller consumes items.\n *\n * @example\n * ```ts\n * for await (const card of paginate((page) => client.cards.list({ set: 'sv06', page }))) {\n * console.log(card.name);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<PaginatedResponse<T>>,\n startPage = 1,\n): AsyncGenerator<T, void, void> {\n let page = startPage;\n for (;;) {\n const response = await fetchPage(page);\n if (response.data.length === 0) return;\n yield* response.data;\n if (page >= response.meta.totalPages) return;\n page++;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type {\n CardGetParams,\n CardListParams,\n CardPriceHistoryParams,\n CardPricesParams,\n} from '../params.js';\nimport type {\n Card,\n CardPrice,\n CardWithRelations,\n PaginatedResponse,\n SingleResponse,\n} from '../types.js';\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/cards` — list, search, filter and sort cards. */\n list(params?: CardListParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>('/v1/cards', params);\n }\n\n /**\n * Iterates every card matching `params` across all pages, fetching pages\n * lazily as you consume them.\n *\n * @example\n * ```ts\n * for await (const card of client.cards.listAll({ set: 'sv06' })) { ... }\n * ```\n */\n listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/cards/random` */\n async random(): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random');\n return res.data;\n }\n\n /** `GET /v1/cards/{id}` */\n async get(id: string, params?: CardGetParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>(\n `/v1/cards/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */\n async prices(id: string, params?: CardPricesParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices/history` — one row per day per price guide, oldest first. */\n async priceHistory(id: string, params?: CardPriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n BargainsParams,\n BulkPricesParams,\n PriceHistoryParams,\n RankingParams,\n TrendsParams,\n} from '../params.js';\nimport type { BargainCardPrice, CardPrice, SingleResponse } from '../types.js';\n\nexport class PricesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `GET /v1/prices` — latest price rows for up to 100 card ids (and/or up\n * to 100 print/variant ids) in one request. Keyed by the id you asked for;\n * an id with no price data maps to `[]`.\n */\n async bulk(params: BulkPricesParams): Promise<Record<string, CardPrice[]>> {\n const res = await this.http.get<SingleResponse<Record<string, CardPrice[]>>>(\n '/v1/prices',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/top` — highest-valued cards. */\n async top(params?: RankingParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/top', params);\n return res.data;\n }\n\n /** `GET /v1/prices/trends` — biggest movers against the card's own rolling average. */\n async trends(params?: TrendsParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/trends', params);\n return res.data;\n }\n\n /** `GET /v1/prices/bargains` — cards trading below a reference price, best discount first. */\n async bargains(params?: BargainsParams): Promise<BargainCardPrice[]> {\n const res = await this.http.get<SingleResponse<BargainCardPrice[]>>(\n '/v1/prices/bargains',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/{cardId}/history` — one row per day per guide, oldest first. */\n async history(cardId: string, params?: PriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/prices/${encodeURIComponent(cardId)}/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedListParams, SealedPriceHistoryParams } from '../params.js';\nimport type { PaginatedResponse, SealedPrice, SealedProduct, SingleResponse } from '../types.js';\n\nexport class SealedResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sealed` — list sealed products with their latest price. */\n list(params?: SealedListParams): Promise<PaginatedResponse<SealedProduct>> {\n return this.http.get<PaginatedResponse<SealedProduct>>('/v1/sealed', params);\n }\n\n /** Iterates every sealed product matching `params` across all pages. */\n listAll(params?: Omit<SealedListParams, 'page'>): AsyncGenerator<SealedProduct, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/sealed/{id}` */\n async get(id: string, params?: { source?: SealedListParams['source'] }): Promise<SealedProduct> {\n const res = await this.http.get<SingleResponse<SealedProduct>>(\n `/v1/sealed/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sealed/{id}/prices` — one row per synced day, oldest first. */\n async prices(id: string, params?: SealedPriceHistoryParams): Promise<SealedPrice[]> {\n const res = await this.http.get<SingleResponse<SealedPrice[]>>(\n `/v1/sealed/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedPriceSource, SetCardsParams } from '../params.js';\nimport type {\n Card,\n CardDexSet,\n CardNeighbors,\n PaginatedResponse,\n SealedProduct,\n SingleResponse,\n} from '../types.js';\n\nexport class SetsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sets` — every set. */\n async list(): Promise<CardDexSet[]> {\n const res = await this.http.get<SingleResponse<CardDexSet[]>>('/v1/sets');\n return res.data;\n }\n\n /** `GET /v1/sets/{id}` */\n async get(id: string): Promise<CardDexSet> {\n const res = await this.http.get<SingleResponse<CardDexSet>>(\n `/v1/sets/${encodeURIComponent(id)}`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/cards` */\n cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>(\n `/v1/sets/${encodeURIComponent(id)}/cards`,\n params,\n );\n }\n\n /** Iterates every card in a set across all pages. */\n cardsAll(id: string, params?: Omit<SetCardsParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.cards(id, { ...params, page }));\n }\n\n /** `GET /v1/sets/{id}/cards/{cardId}/neighbors` — the 2 previous / 2 next card ids. */\n async neighbors(setId: string, cardId: string): Promise<CardNeighbors> {\n const res = await this.http.get<SingleResponse<CardNeighbors>>(\n `/v1/sets/${encodeURIComponent(setId)}/cards/${encodeURIComponent(cardId)}/neighbors`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/sealed` — sealed products attached to a set, each with its latest price. */\n async sealed(id: string, params?: { source?: SealedPriceSource }): Promise<SealedProduct[]> {\n const res = await this.http.get<SingleResponse<SealedProduct[]>>(\n `/v1/sets/${encodeURIComponent(id)}/sealed`,\n params,\n );\n return res.data;\n }\n}\n","import type { RetryOptions } from './http.js';\nimport { HttpClient } from './http.js';\nimport { AuthResource } from './resources/auth.js';\nimport { CardsResource } from './resources/cards.js';\nimport { PricesResource } from './resources/prices.js';\nimport { SealedResource } from './resources/sealed.js';\nimport { SetsResource } from './resources/sets.js';\nimport type { HealthResponse, UsageResponse } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.carddex.dev';\n\nexport interface CardDexOptions {\n /**\n * A `pk_live_...` key from `POST /v1/auth/register`. Omit it to call the\n * API anonymously — CardDex allows this at a lower rate (30 req/min,\n * 5,000 req/day per IP), specifically so a browser can call it without a\n * key. **Never ship a real API key in public frontend code**: it would be\n * readable by anyone who opens dev tools and shared by every visitor to\n * your site. Proxy through your own backend instead if you need the\n * higher, keyed limits from a browser context.\n */\n apiKey?: string;\n /** Defaults to `https://api.carddex.dev`. Override for a local/staging API or a CORS proxy. */\n baseUrl?: string;\n /** Defaults to the global `fetch`. Override to inject a custom implementation (proxies, logging, tests). */\n fetch?: typeof fetch;\n /**\n * Automatic retry on `429`, honouring `Retry-After`. **Off by default.**\n * Pass `true` for the defaults (up to 2 retries, never waiting more than\n * 60s), or an object to tune them. A `Retry-After` longer than\n * `maxWaitSeconds` — typically the daily-quota reset, which can be most of\n * a day away — is never honoured; the request fails immediately instead.\n */\n retry?: boolean | RetryOptions;\n}\n\nfunction isBrowserLike(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof (window as { document?: unknown }).document !== 'undefined'\n );\n}\n\n/**\n * CardDex API client.\n *\n * ```ts\n * import { CardDex } from '@carddex/sdk';\n *\n * const client = new CardDex({ apiKey: process.env.CARDDEX_API_KEY });\n * const { data } = await client.cards.list({ name: 'Charizard' });\n * ```\n */\nexport class CardDex {\n readonly cards: CardsResource;\n readonly sets: SetsResource;\n readonly sealed: SealedResource;\n readonly prices: PricesResource;\n readonly auth: AuthResource;\n\n private readonly http: HttpClient;\n\n constructor(options: CardDexOptions = {}) {\n if (options.apiKey && isBrowserLike()) {\n // biome-ignore lint/suspicious/noConsole: deliberate one-time safety warning, not app logging\n console.warn(\n '[@carddex/sdk] An apiKey was passed in what looks like a browser environment. ' +\n 'API keys shipped in frontend code are visible to every visitor. Omit apiKey for ' +\n \"CardDex's anonymous browser mode, or proxy authenticated requests through your own backend.\",\n );\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n '@carddex/sdk requires a global fetch implementation. On Node < 18, pass one via `fetch` in the options.',\n );\n }\n\n this.http = new HttpClient({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n apiKey: options.apiKey,\n fetch: fetchImpl.bind(globalThis),\n retry: options.retry,\n });\n\n this.cards = new CardsResource(this.http);\n this.sets = new SetsResource(this.http);\n this.sealed = new SealedResource(this.http);\n this.prices = new PricesResource(this.http);\n this.auth = new AuthResource(this.http);\n }\n\n /** `GET /v1/auth/usage` — shorthand for `client.auth.usage()`. Requires an `apiKey`. */\n usage(): Promise<UsageResponse> {\n return this.auth.usage();\n }\n\n /** `GET /v1/health` — API health, price freshness, and cron status. */\n async health(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/v1/health');\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/resources/auth.ts","../src/pagination.ts","../src/resources/cards.ts","../src/resources/prices.ts","../src/resources/sealed.ts","../src/resources/sets.ts","../src/client.ts"],"sourcesContent":["export type { CardDexOptions } from './client.js';\nexport { CardDex } from './client.js';\nexport type { RateLimitInfo } from './errors.js';\nexport { CardDexError } from './errors.js';\nexport type { RetryOptions } from './http.js';\nexport { paginate } from './pagination.js';\nexport * from './params.js';\nexport * from './types.js';\n","/** Rate-limit info parsed from response headers, when present. */\nexport interface RateLimitInfo {\n /** `X-RateLimit-Limit`: requests allowed per minute. */\n limit: number | null;\n /** `X-RateLimit-Daily-Limit`: requests allowed per UTC day, or `null` when the tier is uncapped. */\n dailyLimit: number | null;\n /** `X-RateLimit-Daily-Remaining`: approximate, can lag by about a minute. `null` when the API couldn't compute it. */\n dailyRemaining: number | null;\n}\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const num = (name: string): number | null => {\n const raw = headers.get(name);\n if (raw == null) return null;\n const n = Number(raw);\n return Number.isFinite(n) ? n : null;\n };\n return {\n limit: num('X-RateLimit-Limit'),\n dailyLimit: num('X-RateLimit-Daily-Limit'),\n dailyRemaining: num('X-RateLimit-Daily-Remaining'),\n };\n}\n\n/**\n * Thrown for any non-2xx response, and for network/parse failures the fetch\n * layer can't attribute to the API itself.\n */\nexport class CardDexError extends Error {\n /** HTTP status code. `0` for a request that never got a response (network failure, abort). */\n readonly status: number;\n /**\n * The API's own `error.code`. For a response the API actually produced,\n * this is the same number as `status` (see the note on `ApiErrorBody` in\n * `types.ts`) — kept as its own field because a transport-level failure\n * (no response at all) sets it to a string like `NETWORK_ERROR` instead.\n */\n readonly code: number | string;\n /** Seconds to wait before retrying, parsed from `Retry-After` on a 429. `null` otherwise. */\n readonly retryAfter: number | null;\n /** Rate-limit headers on the response, when there was one. */\n readonly rateLimit: RateLimitInfo | null;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: number | string;\n retryAfter?: number | null;\n rateLimit?: RateLimitInfo | null;\n cause?: unknown;\n },\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CardDexError';\n this.status = options.status;\n this.code = options.code;\n this.retryAfter = options.retryAfter ?? null;\n this.rateLimit = options.rateLimit ?? null;\n Object.setPrototypeOf(this, CardDexError.prototype);\n }\n\n /** Whether this is a 429 (either the per-minute or the daily cap). */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n static async fromResponse(response: Response): Promise<CardDexError> {\n const rateLimit = parseRateLimitHeaders(response.headers);\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader != null ? Number(retryAfterHeader) : null;\n\n let message = `CardDex API error (${response.status})`;\n let code: number | string = response.status;\n try {\n const body = (await response.clone().json()) as {\n error?: { code?: unknown; message?: unknown };\n };\n if (body?.error) {\n if (typeof body.error.message === 'string') message = body.error.message;\n if (typeof body.error.code === 'number' || typeof body.error.code === 'string') {\n code = body.error.code;\n }\n }\n } catch {\n // Non-JSON or empty error body — fall back to the status-derived message above.\n }\n\n return new CardDexError(message, {\n status: response.status,\n code,\n retryAfter: Number.isFinite(retryAfter) ? retryAfter : null,\n rateLimit,\n });\n }\n\n static network(cause: unknown): CardDexError {\n const message = cause instanceof Error ? cause.message : 'Network request failed';\n return new CardDexError(message, { status: 0, code: 'NETWORK_ERROR', cause });\n }\n}\n","import { CardDexError } from './errors.js';\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | undefined\n | null\n | readonly (string | number)[];\nexport type QueryParams = Record<string, QueryValue>;\n\nexport interface RetryOptions {\n /** Max retry attempts on 429. Default 2. */\n maxRetries?: number;\n /**\n * A computed `Retry-After` above this many seconds is never honoured — the\n * request fails immediately instead of sleeping (this is what keeps a\n * daily-quota 429, whose `Retry-After` can be most of a day, from blocking\n * for hours). Default 60, matching the per-minute limiter's own\n * `Retry-After: 60`.\n */\n maxWaitSeconds?: number;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** `false` (default) disables retries; `true` enables them with the defaults below. */\n retry?: boolean | RetryOptions;\n}\n\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_WAIT_SECONDS = 60;\n\nfunction buildQueryString(params?: QueryParams): string {\n if (!params) return '';\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n if (value.length === 0) continue;\n search.set(key, value.join(','));\n } else {\n search.set(key, String(value));\n }\n }\n const qs = search.toString();\n return qs ? `?${qs}` : '';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Minimal fetch wrapper: builds URLs, attaches auth, parses JSON, and turns\n * non-2xx responses into `CardDexError`. No dependency beyond global `fetch`.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly fetchImpl: typeof fetch;\n private readonly retryConfig: Required<RetryOptions> | null;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetch;\n if (options.retry === true) {\n this.retryConfig = {\n maxRetries: DEFAULT_MAX_RETRIES,\n maxWaitSeconds: DEFAULT_MAX_WAIT_SECONDS,\n };\n } else if (options.retry && typeof options.retry === 'object') {\n this.retryConfig = {\n maxRetries: options.retry.maxRetries ?? DEFAULT_MAX_RETRIES,\n maxWaitSeconds: options.retry.maxWaitSeconds ?? DEFAULT_MAX_WAIT_SECONDS,\n };\n } else {\n this.retryConfig = null;\n }\n }\n\n async get<T>(path: string, query?: QueryParams, signal?: AbortSignal): Promise<T> {\n return this.request<T>('GET', path, { query, signal });\n }\n\n async post<T>(path: string, body?: unknown, signal?: AbortSignal): Promise<T> {\n return this.request<T>('POST', path, { body, signal });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { query?: QueryParams; body?: unknown; signal?: AbortSignal },\n ): Promise<T> {\n const url = `${this.baseUrl}${path}${buildQueryString(opts.query)}`;\n const headers: Record<string, string> = { Accept: 'application/json' };\n if (this.apiKey) headers['X-API-Key'] = this.apiKey;\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n\n let attempt = 0;\n for (;;) {\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n } catch (cause) {\n throw CardDexError.network(cause);\n }\n\n if (response.status === 429 && this.retryConfig && attempt < this.retryConfig.maxRetries) {\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfterSeconds = retryAfterHeader != null ? Number(retryAfterHeader) : Number.NaN;\n if (\n Number.isFinite(retryAfterSeconds) &&\n retryAfterSeconds <= this.retryConfig.maxWaitSeconds\n ) {\n attempt++;\n await sleep(retryAfterSeconds * 1000);\n continue;\n }\n // Retry-After is missing or longer than we're willing to wait\n // (typically the daily cap, which resets at UTC midnight) — surface\n // the error instead of blocking.\n }\n\n if (!response.ok) {\n throw await CardDexError.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { RegisterResponse, SingleResponse, UsageResponse } from '../types.js';\n\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `POST /v1/auth/register` — claim a free API key. The key is returned\n * exactly once, so store it immediately. A lost key can be replaced by signing\n * in at https://carddex.dev/account (create, rotate or revoke keys there).\n */\n async register(email: string, name?: string): Promise<RegisterResponse> {\n const res = await this.http.post<SingleResponse<RegisterResponse>>('/v1/auth/register', {\n email,\n name,\n });\n return res.data;\n }\n\n /** `GET /v1/auth/usage` — usage stats for the API key this client was constructed with. Requires an `apiKey`. */\n async usage(): Promise<UsageResponse> {\n const res = await this.http.get<SingleResponse<UsageResponse>>('/v1/auth/usage');\n return res.data;\n }\n}\n","import type { PaginatedResponse } from './types.js';\n\n/**\n * Turns a page-fetching function into an async iterator over every item,\n * fetching the next page lazily as the caller consumes items.\n *\n * @example\n * ```ts\n * for await (const card of paginate((page) => client.cards.list({ set: 'sv06', page }))) {\n * console.log(card.name);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<PaginatedResponse<T>>,\n startPage = 1,\n): AsyncGenerator<T, void, void> {\n let page = startPage;\n for (;;) {\n const response = await fetchPage(page);\n if (response.data.length === 0) return;\n yield* response.data;\n if (page >= response.meta.totalPages) return;\n page++;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type {\n CardGetParams,\n CardListParams,\n CardPriceHistoryParams,\n CardPricesParams,\n} from '../params.js';\nimport type {\n Card,\n CardPrice,\n CardWithRelations,\n PaginatedResponse,\n SingleResponse,\n} from '../types.js';\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/cards` — list, search, filter and sort cards. */\n list(params?: CardListParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>('/v1/cards', params);\n }\n\n /**\n * Iterates every card matching `params` across all pages, fetching pages\n * lazily as you consume them.\n *\n * @example\n * ```ts\n * for await (const card of client.cards.listAll({ set: 'sv06' })) { ... }\n * ```\n */\n listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/cards/random` */\n async random(): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random');\n return res.data;\n }\n\n /** `GET /v1/cards/{id}` */\n async get(id: string, params?: CardGetParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>(\n `/v1/cards/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */\n async prices(id: string, params?: CardPricesParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices/history` — one row per day per price guide, oldest first. */\n async priceHistory(id: string, params?: CardPriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n BargainsParams,\n BulkPricesParams,\n PriceHistoryParams,\n RankingParams,\n TrendsParams,\n} from '../params.js';\nimport type { BargainCardPrice, CardPrice, SingleResponse } from '../types.js';\n\nexport class PricesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `GET /v1/prices` — latest price rows for up to 100 card ids (and/or up\n * to 100 print/variant ids) in one request. Keyed by the id you asked for;\n * an id with no price data maps to `[]`.\n */\n async bulk(params: BulkPricesParams): Promise<Record<string, CardPrice[]>> {\n const res = await this.http.get<SingleResponse<Record<string, CardPrice[]>>>(\n '/v1/prices',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/top` — highest-valued cards. */\n async top(params?: RankingParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/top', params);\n return res.data;\n }\n\n /** `GET /v1/prices/trends` — biggest movers against the card's own rolling average. */\n async trends(params?: TrendsParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/trends', params);\n return res.data;\n }\n\n /** `GET /v1/prices/bargains` — cards trading below a reference price, best discount first. */\n async bargains(params?: BargainsParams): Promise<BargainCardPrice[]> {\n const res = await this.http.get<SingleResponse<BargainCardPrice[]>>(\n '/v1/prices/bargains',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/{cardId}/history` — one row per day per guide, oldest first. */\n async history(cardId: string, params?: PriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/prices/${encodeURIComponent(cardId)}/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedListParams, SealedPriceHistoryParams } from '../params.js';\nimport type { PaginatedResponse, SealedPrice, SealedProduct, SingleResponse } from '../types.js';\n\nexport class SealedResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sealed` — list sealed products with their latest price. */\n list(params?: SealedListParams): Promise<PaginatedResponse<SealedProduct>> {\n return this.http.get<PaginatedResponse<SealedProduct>>('/v1/sealed', params);\n }\n\n /** Iterates every sealed product matching `params` across all pages. */\n listAll(params?: Omit<SealedListParams, 'page'>): AsyncGenerator<SealedProduct, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/sealed/{id}` */\n async get(id: string, params?: { source?: SealedListParams['source'] }): Promise<SealedProduct> {\n const res = await this.http.get<SingleResponse<SealedProduct>>(\n `/v1/sealed/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sealed/{id}/prices` — one row per synced day, oldest first. */\n async prices(id: string, params?: SealedPriceHistoryParams): Promise<SealedPrice[]> {\n const res = await this.http.get<SingleResponse<SealedPrice[]>>(\n `/v1/sealed/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedPriceSource, SetCardsParams, SetGetParams } from '../params.js';\nimport type {\n Card,\n CardDexSet,\n CardNeighbors,\n PaginatedResponse,\n SealedProduct,\n SingleResponse,\n} from '../types.js';\n\nexport class SetsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */\n async list(params?: SetGetParams): Promise<CardDexSet[]> {\n const res = await this.http.get<SingleResponse<CardDexSet[]>>('/v1/sets', params);\n return res.data;\n }\n\n /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */\n async get(id: string, params?: SetGetParams): Promise<CardDexSet> {\n const res = await this.http.get<SingleResponse<CardDexSet>>(\n `/v1/sets/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/cards` */\n cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>(\n `/v1/sets/${encodeURIComponent(id)}/cards`,\n params,\n );\n }\n\n /** Iterates every card in a set across all pages. */\n cardsAll(id: string, params?: Omit<SetCardsParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.cards(id, { ...params, page }));\n }\n\n /** `GET /v1/sets/{id}/cards/{cardId}/neighbors` — the 2 previous / 2 next card ids. */\n async neighbors(setId: string, cardId: string): Promise<CardNeighbors> {\n const res = await this.http.get<SingleResponse<CardNeighbors>>(\n `/v1/sets/${encodeURIComponent(setId)}/cards/${encodeURIComponent(cardId)}/neighbors`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/sealed` — sealed products attached to a set, each with its latest price. */\n async sealed(id: string, params?: { source?: SealedPriceSource }): Promise<SealedProduct[]> {\n const res = await this.http.get<SingleResponse<SealedProduct[]>>(\n `/v1/sets/${encodeURIComponent(id)}/sealed`,\n params,\n );\n return res.data;\n }\n}\n","import type { RetryOptions } from './http.js';\nimport { HttpClient } from './http.js';\nimport { AuthResource } from './resources/auth.js';\nimport { CardsResource } from './resources/cards.js';\nimport { PricesResource } from './resources/prices.js';\nimport { SealedResource } from './resources/sealed.js';\nimport { SetsResource } from './resources/sets.js';\nimport type { HealthResponse, UsageResponse } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.carddex.dev';\n\nexport interface CardDexOptions {\n /**\n * A `pk_live_...` key from `POST /v1/auth/register`. Omit it to call the\n * API anonymously — CardDex allows this at a lower rate (30 req/min,\n * 5,000 req/day per IP), specifically so a browser can call it without a\n * key. **Never ship a real API key in public frontend code**: it would be\n * readable by anyone who opens dev tools and shared by every visitor to\n * your site. Proxy through your own backend instead if you need the\n * higher, keyed limits from a browser context.\n */\n apiKey?: string;\n /** Defaults to `https://api.carddex.dev`. Override for a local/staging API or a CORS proxy. */\n baseUrl?: string;\n /** Defaults to the global `fetch`. Override to inject a custom implementation (proxies, logging, tests). */\n fetch?: typeof fetch;\n /**\n * Automatic retry on `429`, honouring `Retry-After`. **Off by default.**\n * Pass `true` for the defaults (up to 2 retries, never waiting more than\n * 60s), or an object to tune them. A `Retry-After` longer than\n * `maxWaitSeconds` — typically the daily-quota reset, which can be most of\n * a day away — is never honoured; the request fails immediately instead.\n */\n retry?: boolean | RetryOptions;\n}\n\nfunction isBrowserLike(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof (window as { document?: unknown }).document !== 'undefined'\n );\n}\n\n/**\n * CardDex API client.\n *\n * ```ts\n * import { CardDex } from '@carddex/sdk';\n *\n * const client = new CardDex({ apiKey: process.env.CARDDEX_API_KEY });\n * const { data } = await client.cards.list({ name: 'Charizard' });\n * ```\n */\nexport class CardDex {\n readonly cards: CardsResource;\n readonly sets: SetsResource;\n readonly sealed: SealedResource;\n readonly prices: PricesResource;\n readonly auth: AuthResource;\n\n private readonly http: HttpClient;\n\n constructor(options: CardDexOptions = {}) {\n if (options.apiKey && isBrowserLike()) {\n // biome-ignore lint/suspicious/noConsole: deliberate one-time safety warning, not app logging\n console.warn(\n '[@carddex/sdk] An apiKey was passed in what looks like a browser environment. ' +\n 'API keys shipped in frontend code are visible to every visitor. Omit apiKey for ' +\n \"CardDex's anonymous browser mode, or proxy authenticated requests through your own backend.\",\n );\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n '@carddex/sdk requires a global fetch implementation. On Node < 18, pass one via `fetch` in the options.',\n );\n }\n\n this.http = new HttpClient({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n apiKey: options.apiKey,\n fetch: fetchImpl.bind(globalThis),\n retry: options.retry,\n });\n\n this.cards = new CardsResource(this.http);\n this.sets = new SetsResource(this.http);\n this.sealed = new SealedResource(this.http);\n this.prices = new PricesResource(this.http);\n this.auth = new AuthResource(this.http);\n }\n\n /** `GET /v1/auth/usage` — shorthand for `client.auth.usage()`. Requires an `apiKey`. */\n usage(): Promise<UsageResponse> {\n return this.auth.usage();\n }\n\n /** `GET /v1/health` — API health, price freshness, and cron status. */\n async health(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/v1/health');\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -53,7 +53,10 @@ declare class HttpClient {
53
53
  */
54
54
  interface CardDexSet {
55
55
  id: string;
56
+ /** The English name. */
56
57
  name: string;
58
+ /** The name in the `lang` edition, or null where none is known. Only when `lang` is not `en`. */
59
+ localized_name?: string | null;
57
60
  series: string | null;
58
61
  release_date: string | null;
59
62
  official_cards: number | null;
@@ -147,7 +150,10 @@ interface CardVariant {
147
150
  interface Card {
148
151
  id: string;
149
152
  set_id: string;
153
+ /** The English name, always. */
150
154
  name: string;
155
+ /** The name in the `lang` edition (de, fr, it, es, pt), or null where none is known. Only when `lang` is not `en`. */
156
+ localized_name?: string | null;
151
157
  number: string;
152
158
  supertype: string;
153
159
  subtypes: string[] | null;
@@ -178,8 +184,15 @@ interface CardWithRelations extends Card {
178
184
  images?: CardImage[];
179
185
  prices?: CardPrice[];
180
186
  variants?: CardVariant[];
187
+ /** Every localized name of the card, ordered by language code (`include: 'translations'`). */
188
+ translations?: CardTranslation[];
181
189
  set?: CardDexSet;
182
190
  }
191
+ /** A card name in one language edition (de, fr, it, es, pt), from TCGdex. */
192
+ interface CardTranslation {
193
+ language: string;
194
+ name: string;
195
+ }
183
196
  /** The 2 previous / 2 next card ids within a set, from `/v1/sets/{id}/cards/{cardId}/neighbors`. */
184
197
  interface CardNeighbors {
185
198
  prev_prev: string | null;
@@ -319,7 +332,16 @@ type CardPriceSourceOne = 'cardmarket' | 'tcgplayer';
319
332
  /** Sealed products are priced by Cardmarket only. */
320
333
  type SealedPriceSource = 'cardmarket';
321
334
  type CardSortField = 'name' | 'hp' | 'number' | 'rarity' | 'set' | 'artist' | 'release_date';
322
- type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'images' | 'prices' | 'variants';
335
+ type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'images' | 'prices' | 'variants'
336
+ /** Every localized name of the card (`translations: CardTranslation[]`). Never a default. */
337
+ | 'translations';
338
+ /**
339
+ * Language edition for names. `name` is always the English name; with any
340
+ * value but `en`, cards and sets also carry `localized_name` (null where none
341
+ * is known), and `name` / `q` match names in that language too. `pl` is not
342
+ * accepted: no source has Polish card names.
343
+ */
344
+ type CardLanguage = 'en' | 'de' | 'fr' | 'it' | 'es' | 'pt';
323
345
  type CardListParams = {
324
346
  name?: string;
325
347
  q?: string;
@@ -330,8 +352,8 @@ type CardListParams = {
330
352
  hp_gte?: number;
331
353
  hp_lte?: number;
332
354
  artist?: string;
333
- /** The catalogue is English-only for now; anything else is a 400. Defaults to `en`. */
334
- lang?: 'en';
355
+ /** Adds `localized_name` and searches names in that language too. Defaults to `en`. */
356
+ lang?: CardLanguage;
335
357
  page?: number;
336
358
  /** Max 250. */
337
359
  pageSize?: number;
@@ -345,6 +367,12 @@ type CardListParams = {
345
367
  type CardGetParams = {
346
368
  include?: CardInclude | CardInclude[];
347
369
  source?: CardPriceSource | CardPriceSource[];
370
+ /** Adds `localized_name`. Defaults to `en`. */
371
+ lang?: CardLanguage;
372
+ };
373
+ type SetGetParams = {
374
+ /** Adds `localized_name` to the set(s). Defaults to `en`. */
375
+ lang?: CardLanguage;
348
376
  };
349
377
  type CardPricesParams = {
350
378
  /** Price this print instead of the base card. */
@@ -358,6 +386,8 @@ type CardPriceHistoryParams = CardPricesParams & {
358
386
  type SetCardsParams = {
359
387
  page?: number;
360
388
  pageSize?: number;
389
+ /** Adds `localized_name` to every card. Defaults to `en`. */
390
+ lang?: CardLanguage;
361
391
  };
362
392
  type SealedListParams = {
363
393
  set_id?: string;
@@ -463,10 +493,10 @@ declare class SealedResource {
463
493
  declare class SetsResource {
464
494
  private readonly http;
465
495
  constructor(http: HttpClient);
466
- /** `GET /v1/sets` — every set. */
467
- list(): Promise<CardDexSet[]>;
468
- /** `GET /v1/sets/{id}` */
469
- get(id: string): Promise<CardDexSet>;
496
+ /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
497
+ list(params?: SetGetParams): Promise<CardDexSet[]>;
498
+ /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
499
+ get(id: string, params?: SetGetParams): Promise<CardDexSet>;
470
500
  /** `GET /v1/sets/{id}/cards` */
471
501
  cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>>;
472
502
  /** Iterates every card in a set across all pages. */
@@ -580,4 +610,4 @@ declare class CardDexError extends Error {
580
610
  */
581
611
  declare function paginate<T>(fetchPage: (page: number) => Promise<PaginatedResponse<T>>, startPage?: number): AsyncGenerator<T, void, void>;
582
612
 
583
- export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, CardDex, CardDexError, type CardDexOptions, type CardDexSet, type CardGetParams, type CardImage, type CardInclude, type CardListParams, type CardNeighbors, type CardPrice, type CardPriceHistoryParams, type CardPriceSource, type CardPriceSourceOne, type CardPricesParams, type CardResistance, type CardSortField, type CardVariant, type CardWeakness, type CardWithRelations, type HealthResponse, type PaginatedResponse, type PaginationMeta, type PriceHistoryParams, type RankingParams, type RateLimitInfo, type RegisterResponse, type RetryOptions, type SealedLatestPrice, type SealedListParams, type SealedPrice, type SealedPriceHistoryParams, type SealedPriceSource, type SealedProduct, type SealedProductType, type SetCardsParams, type SingleResponse, type TrendsParams, type UsageRecentRequest, type UsageResponse, paginate };
613
+ export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, CardDex, CardDexError, type CardDexOptions, type CardDexSet, type CardGetParams, type CardImage, type CardInclude, type CardLanguage, type CardListParams, type CardNeighbors, type CardPrice, type CardPriceHistoryParams, type CardPriceSource, type CardPriceSourceOne, type CardPricesParams, type CardResistance, type CardSortField, type CardTranslation, type CardVariant, type CardWeakness, type CardWithRelations, type HealthResponse, type PaginatedResponse, type PaginationMeta, type PriceHistoryParams, type RankingParams, type RateLimitInfo, type RegisterResponse, type RetryOptions, type SealedLatestPrice, type SealedListParams, type SealedPrice, type SealedPriceHistoryParams, type SealedPriceSource, type SealedProduct, type SealedProductType, type SetCardsParams, type SetGetParams, type SingleResponse, type TrendsParams, type UsageRecentRequest, type UsageResponse, paginate };
package/dist/index.d.ts CHANGED
@@ -53,7 +53,10 @@ declare class HttpClient {
53
53
  */
54
54
  interface CardDexSet {
55
55
  id: string;
56
+ /** The English name. */
56
57
  name: string;
58
+ /** The name in the `lang` edition, or null where none is known. Only when `lang` is not `en`. */
59
+ localized_name?: string | null;
57
60
  series: string | null;
58
61
  release_date: string | null;
59
62
  official_cards: number | null;
@@ -147,7 +150,10 @@ interface CardVariant {
147
150
  interface Card {
148
151
  id: string;
149
152
  set_id: string;
153
+ /** The English name, always. */
150
154
  name: string;
155
+ /** The name in the `lang` edition (de, fr, it, es, pt), or null where none is known. Only when `lang` is not `en`. */
156
+ localized_name?: string | null;
151
157
  number: string;
152
158
  supertype: string;
153
159
  subtypes: string[] | null;
@@ -178,8 +184,15 @@ interface CardWithRelations extends Card {
178
184
  images?: CardImage[];
179
185
  prices?: CardPrice[];
180
186
  variants?: CardVariant[];
187
+ /** Every localized name of the card, ordered by language code (`include: 'translations'`). */
188
+ translations?: CardTranslation[];
181
189
  set?: CardDexSet;
182
190
  }
191
+ /** A card name in one language edition (de, fr, it, es, pt), from TCGdex. */
192
+ interface CardTranslation {
193
+ language: string;
194
+ name: string;
195
+ }
183
196
  /** The 2 previous / 2 next card ids within a set, from `/v1/sets/{id}/cards/{cardId}/neighbors`. */
184
197
  interface CardNeighbors {
185
198
  prev_prev: string | null;
@@ -319,7 +332,16 @@ type CardPriceSourceOne = 'cardmarket' | 'tcgplayer';
319
332
  /** Sealed products are priced by Cardmarket only. */
320
333
  type SealedPriceSource = 'cardmarket';
321
334
  type CardSortField = 'name' | 'hp' | 'number' | 'rarity' | 'set' | 'artist' | 'release_date';
322
- type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'images' | 'prices' | 'variants';
335
+ type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'images' | 'prices' | 'variants'
336
+ /** Every localized name of the card (`translations: CardTranslation[]`). Never a default. */
337
+ | 'translations';
338
+ /**
339
+ * Language edition for names. `name` is always the English name; with any
340
+ * value but `en`, cards and sets also carry `localized_name` (null where none
341
+ * is known), and `name` / `q` match names in that language too. `pl` is not
342
+ * accepted: no source has Polish card names.
343
+ */
344
+ type CardLanguage = 'en' | 'de' | 'fr' | 'it' | 'es' | 'pt';
323
345
  type CardListParams = {
324
346
  name?: string;
325
347
  q?: string;
@@ -330,8 +352,8 @@ type CardListParams = {
330
352
  hp_gte?: number;
331
353
  hp_lte?: number;
332
354
  artist?: string;
333
- /** The catalogue is English-only for now; anything else is a 400. Defaults to `en`. */
334
- lang?: 'en';
355
+ /** Adds `localized_name` and searches names in that language too. Defaults to `en`. */
356
+ lang?: CardLanguage;
335
357
  page?: number;
336
358
  /** Max 250. */
337
359
  pageSize?: number;
@@ -345,6 +367,12 @@ type CardListParams = {
345
367
  type CardGetParams = {
346
368
  include?: CardInclude | CardInclude[];
347
369
  source?: CardPriceSource | CardPriceSource[];
370
+ /** Adds `localized_name`. Defaults to `en`. */
371
+ lang?: CardLanguage;
372
+ };
373
+ type SetGetParams = {
374
+ /** Adds `localized_name` to the set(s). Defaults to `en`. */
375
+ lang?: CardLanguage;
348
376
  };
349
377
  type CardPricesParams = {
350
378
  /** Price this print instead of the base card. */
@@ -358,6 +386,8 @@ type CardPriceHistoryParams = CardPricesParams & {
358
386
  type SetCardsParams = {
359
387
  page?: number;
360
388
  pageSize?: number;
389
+ /** Adds `localized_name` to every card. Defaults to `en`. */
390
+ lang?: CardLanguage;
361
391
  };
362
392
  type SealedListParams = {
363
393
  set_id?: string;
@@ -463,10 +493,10 @@ declare class SealedResource {
463
493
  declare class SetsResource {
464
494
  private readonly http;
465
495
  constructor(http: HttpClient);
466
- /** `GET /v1/sets` — every set. */
467
- list(): Promise<CardDexSet[]>;
468
- /** `GET /v1/sets/{id}` */
469
- get(id: string): Promise<CardDexSet>;
496
+ /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
497
+ list(params?: SetGetParams): Promise<CardDexSet[]>;
498
+ /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
499
+ get(id: string, params?: SetGetParams): Promise<CardDexSet>;
470
500
  /** `GET /v1/sets/{id}/cards` */
471
501
  cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>>;
472
502
  /** Iterates every card in a set across all pages. */
@@ -580,4 +610,4 @@ declare class CardDexError extends Error {
580
610
  */
581
611
  declare function paginate<T>(fetchPage: (page: number) => Promise<PaginatedResponse<T>>, startPage?: number): AsyncGenerator<T, void, void>;
582
612
 
583
- export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, CardDex, CardDexError, type CardDexOptions, type CardDexSet, type CardGetParams, type CardImage, type CardInclude, type CardListParams, type CardNeighbors, type CardPrice, type CardPriceHistoryParams, type CardPriceSource, type CardPriceSourceOne, type CardPricesParams, type CardResistance, type CardSortField, type CardVariant, type CardWeakness, type CardWithRelations, type HealthResponse, type PaginatedResponse, type PaginationMeta, type PriceHistoryParams, type RankingParams, type RateLimitInfo, type RegisterResponse, type RetryOptions, type SealedLatestPrice, type SealedListParams, type SealedPrice, type SealedPriceHistoryParams, type SealedPriceSource, type SealedProduct, type SealedProductType, type SetCardsParams, type SingleResponse, type TrendsParams, type UsageRecentRequest, type UsageResponse, paginate };
613
+ export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, CardDex, CardDexError, type CardDexOptions, type CardDexSet, type CardGetParams, type CardImage, type CardInclude, type CardLanguage, type CardListParams, type CardNeighbors, type CardPrice, type CardPriceHistoryParams, type CardPriceSource, type CardPriceSourceOne, type CardPricesParams, type CardResistance, type CardSortField, type CardTranslation, type CardVariant, type CardWeakness, type CardWithRelations, type HealthResponse, type PaginatedResponse, type PaginationMeta, type PriceHistoryParams, type RankingParams, type RateLimitInfo, type RegisterResponse, type RetryOptions, type SealedLatestPrice, type SealedListParams, type SealedPrice, type SealedPriceHistoryParams, type SealedPriceSource, type SealedProduct, type SealedProductType, type SetCardsParams, type SetGetParams, type SingleResponse, type TrendsParams, type UsageRecentRequest, type UsageResponse, paginate };
package/dist/index.js CHANGED
@@ -328,15 +328,16 @@ var SetsResource = class {
328
328
  this.http = http;
329
329
  }
330
330
  http;
331
- /** `GET /v1/sets` — every set. */
332
- async list() {
333
- const res = await this.http.get("/v1/sets");
331
+ /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
332
+ async list(params) {
333
+ const res = await this.http.get("/v1/sets", params);
334
334
  return res.data;
335
335
  }
336
- /** `GET /v1/sets/{id}` */
337
- async get(id) {
336
+ /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
337
+ async get(id, params) {
338
338
  const res = await this.http.get(
339
- `/v1/sets/${encodeURIComponent(id)}`
339
+ `/v1/sets/${encodeURIComponent(id)}`,
340
+ params
340
341
  );
341
342
  return res.data;
342
343
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/auth.ts","../src/pagination.ts","../src/resources/cards.ts","../src/resources/prices.ts","../src/resources/sealed.ts","../src/resources/sets.ts","../src/client.ts"],"sourcesContent":["/** Rate-limit info parsed from response headers, when present. */\nexport interface RateLimitInfo {\n /** `X-RateLimit-Limit`: requests allowed per minute. */\n limit: number | null;\n /** `X-RateLimit-Daily-Limit`: requests allowed per UTC day, or `null` when the tier is uncapped. */\n dailyLimit: number | null;\n /** `X-RateLimit-Daily-Remaining`: approximate, can lag by about a minute. `null` when the API couldn't compute it. */\n dailyRemaining: number | null;\n}\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const num = (name: string): number | null => {\n const raw = headers.get(name);\n if (raw == null) return null;\n const n = Number(raw);\n return Number.isFinite(n) ? n : null;\n };\n return {\n limit: num('X-RateLimit-Limit'),\n dailyLimit: num('X-RateLimit-Daily-Limit'),\n dailyRemaining: num('X-RateLimit-Daily-Remaining'),\n };\n}\n\n/**\n * Thrown for any non-2xx response, and for network/parse failures the fetch\n * layer can't attribute to the API itself.\n */\nexport class CardDexError extends Error {\n /** HTTP status code. `0` for a request that never got a response (network failure, abort). */\n readonly status: number;\n /**\n * The API's own `error.code`. For a response the API actually produced,\n * this is the same number as `status` (see the note on `ApiErrorBody` in\n * `types.ts`) — kept as its own field because a transport-level failure\n * (no response at all) sets it to a string like `NETWORK_ERROR` instead.\n */\n readonly code: number | string;\n /** Seconds to wait before retrying, parsed from `Retry-After` on a 429. `null` otherwise. */\n readonly retryAfter: number | null;\n /** Rate-limit headers on the response, when there was one. */\n readonly rateLimit: RateLimitInfo | null;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: number | string;\n retryAfter?: number | null;\n rateLimit?: RateLimitInfo | null;\n cause?: unknown;\n },\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CardDexError';\n this.status = options.status;\n this.code = options.code;\n this.retryAfter = options.retryAfter ?? null;\n this.rateLimit = options.rateLimit ?? null;\n Object.setPrototypeOf(this, CardDexError.prototype);\n }\n\n /** Whether this is a 429 (either the per-minute or the daily cap). */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n static async fromResponse(response: Response): Promise<CardDexError> {\n const rateLimit = parseRateLimitHeaders(response.headers);\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader != null ? Number(retryAfterHeader) : null;\n\n let message = `CardDex API error (${response.status})`;\n let code: number | string = response.status;\n try {\n const body = (await response.clone().json()) as {\n error?: { code?: unknown; message?: unknown };\n };\n if (body?.error) {\n if (typeof body.error.message === 'string') message = body.error.message;\n if (typeof body.error.code === 'number' || typeof body.error.code === 'string') {\n code = body.error.code;\n }\n }\n } catch {\n // Non-JSON or empty error body — fall back to the status-derived message above.\n }\n\n return new CardDexError(message, {\n status: response.status,\n code,\n retryAfter: Number.isFinite(retryAfter) ? retryAfter : null,\n rateLimit,\n });\n }\n\n static network(cause: unknown): CardDexError {\n const message = cause instanceof Error ? cause.message : 'Network request failed';\n return new CardDexError(message, { status: 0, code: 'NETWORK_ERROR', cause });\n }\n}\n","import { CardDexError } from './errors.js';\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | undefined\n | null\n | readonly (string | number)[];\nexport type QueryParams = Record<string, QueryValue>;\n\nexport interface RetryOptions {\n /** Max retry attempts on 429. Default 2. */\n maxRetries?: number;\n /**\n * A computed `Retry-After` above this many seconds is never honoured — the\n * request fails immediately instead of sleeping (this is what keeps a\n * daily-quota 429, whose `Retry-After` can be most of a day, from blocking\n * for hours). Default 60, matching the per-minute limiter's own\n * `Retry-After: 60`.\n */\n maxWaitSeconds?: number;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** `false` (default) disables retries; `true` enables them with the defaults below. */\n retry?: boolean | RetryOptions;\n}\n\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_WAIT_SECONDS = 60;\n\nfunction buildQueryString(params?: QueryParams): string {\n if (!params) return '';\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n if (value.length === 0) continue;\n search.set(key, value.join(','));\n } else {\n search.set(key, String(value));\n }\n }\n const qs = search.toString();\n return qs ? `?${qs}` : '';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Minimal fetch wrapper: builds URLs, attaches auth, parses JSON, and turns\n * non-2xx responses into `CardDexError`. No dependency beyond global `fetch`.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly fetchImpl: typeof fetch;\n private readonly retryConfig: Required<RetryOptions> | null;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetch;\n if (options.retry === true) {\n this.retryConfig = {\n maxRetries: DEFAULT_MAX_RETRIES,\n maxWaitSeconds: DEFAULT_MAX_WAIT_SECONDS,\n };\n } else if (options.retry && typeof options.retry === 'object') {\n this.retryConfig = {\n maxRetries: options.retry.maxRetries ?? DEFAULT_MAX_RETRIES,\n maxWaitSeconds: options.retry.maxWaitSeconds ?? DEFAULT_MAX_WAIT_SECONDS,\n };\n } else {\n this.retryConfig = null;\n }\n }\n\n async get<T>(path: string, query?: QueryParams, signal?: AbortSignal): Promise<T> {\n return this.request<T>('GET', path, { query, signal });\n }\n\n async post<T>(path: string, body?: unknown, signal?: AbortSignal): Promise<T> {\n return this.request<T>('POST', path, { body, signal });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { query?: QueryParams; body?: unknown; signal?: AbortSignal },\n ): Promise<T> {\n const url = `${this.baseUrl}${path}${buildQueryString(opts.query)}`;\n const headers: Record<string, string> = { Accept: 'application/json' };\n if (this.apiKey) headers['X-API-Key'] = this.apiKey;\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n\n let attempt = 0;\n for (;;) {\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n } catch (cause) {\n throw CardDexError.network(cause);\n }\n\n if (response.status === 429 && this.retryConfig && attempt < this.retryConfig.maxRetries) {\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfterSeconds = retryAfterHeader != null ? Number(retryAfterHeader) : Number.NaN;\n if (\n Number.isFinite(retryAfterSeconds) &&\n retryAfterSeconds <= this.retryConfig.maxWaitSeconds\n ) {\n attempt++;\n await sleep(retryAfterSeconds * 1000);\n continue;\n }\n // Retry-After is missing or longer than we're willing to wait\n // (typically the daily cap, which resets at UTC midnight) — surface\n // the error instead of blocking.\n }\n\n if (!response.ok) {\n throw await CardDexError.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { RegisterResponse, SingleResponse, UsageResponse } from '../types.js';\n\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `POST /v1/auth/register` — claim a free API key. The key is returned\n * exactly once, so store it immediately. A lost key can be replaced by signing\n * in at https://carddex.dev/account (create, rotate or revoke keys there).\n */\n async register(email: string, name?: string): Promise<RegisterResponse> {\n const res = await this.http.post<SingleResponse<RegisterResponse>>('/v1/auth/register', {\n email,\n name,\n });\n return res.data;\n }\n\n /** `GET /v1/auth/usage` — usage stats for the API key this client was constructed with. Requires an `apiKey`. */\n async usage(): Promise<UsageResponse> {\n const res = await this.http.get<SingleResponse<UsageResponse>>('/v1/auth/usage');\n return res.data;\n }\n}\n","import type { PaginatedResponse } from './types.js';\n\n/**\n * Turns a page-fetching function into an async iterator over every item,\n * fetching the next page lazily as the caller consumes items.\n *\n * @example\n * ```ts\n * for await (const card of paginate((page) => client.cards.list({ set: 'sv06', page }))) {\n * console.log(card.name);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<PaginatedResponse<T>>,\n startPage = 1,\n): AsyncGenerator<T, void, void> {\n let page = startPage;\n for (;;) {\n const response = await fetchPage(page);\n if (response.data.length === 0) return;\n yield* response.data;\n if (page >= response.meta.totalPages) return;\n page++;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type {\n CardGetParams,\n CardListParams,\n CardPriceHistoryParams,\n CardPricesParams,\n} from '../params.js';\nimport type {\n Card,\n CardPrice,\n CardWithRelations,\n PaginatedResponse,\n SingleResponse,\n} from '../types.js';\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/cards` — list, search, filter and sort cards. */\n list(params?: CardListParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>('/v1/cards', params);\n }\n\n /**\n * Iterates every card matching `params` across all pages, fetching pages\n * lazily as you consume them.\n *\n * @example\n * ```ts\n * for await (const card of client.cards.listAll({ set: 'sv06' })) { ... }\n * ```\n */\n listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/cards/random` */\n async random(): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random');\n return res.data;\n }\n\n /** `GET /v1/cards/{id}` */\n async get(id: string, params?: CardGetParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>(\n `/v1/cards/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */\n async prices(id: string, params?: CardPricesParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices/history` — one row per day per price guide, oldest first. */\n async priceHistory(id: string, params?: CardPriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n BargainsParams,\n BulkPricesParams,\n PriceHistoryParams,\n RankingParams,\n TrendsParams,\n} from '../params.js';\nimport type { BargainCardPrice, CardPrice, SingleResponse } from '../types.js';\n\nexport class PricesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `GET /v1/prices` — latest price rows for up to 100 card ids (and/or up\n * to 100 print/variant ids) in one request. Keyed by the id you asked for;\n * an id with no price data maps to `[]`.\n */\n async bulk(params: BulkPricesParams): Promise<Record<string, CardPrice[]>> {\n const res = await this.http.get<SingleResponse<Record<string, CardPrice[]>>>(\n '/v1/prices',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/top` — highest-valued cards. */\n async top(params?: RankingParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/top', params);\n return res.data;\n }\n\n /** `GET /v1/prices/trends` — biggest movers against the card's own rolling average. */\n async trends(params?: TrendsParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/trends', params);\n return res.data;\n }\n\n /** `GET /v1/prices/bargains` — cards trading below a reference price, best discount first. */\n async bargains(params?: BargainsParams): Promise<BargainCardPrice[]> {\n const res = await this.http.get<SingleResponse<BargainCardPrice[]>>(\n '/v1/prices/bargains',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/{cardId}/history` — one row per day per guide, oldest first. */\n async history(cardId: string, params?: PriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/prices/${encodeURIComponent(cardId)}/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedListParams, SealedPriceHistoryParams } from '../params.js';\nimport type { PaginatedResponse, SealedPrice, SealedProduct, SingleResponse } from '../types.js';\n\nexport class SealedResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sealed` — list sealed products with their latest price. */\n list(params?: SealedListParams): Promise<PaginatedResponse<SealedProduct>> {\n return this.http.get<PaginatedResponse<SealedProduct>>('/v1/sealed', params);\n }\n\n /** Iterates every sealed product matching `params` across all pages. */\n listAll(params?: Omit<SealedListParams, 'page'>): AsyncGenerator<SealedProduct, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/sealed/{id}` */\n async get(id: string, params?: { source?: SealedListParams['source'] }): Promise<SealedProduct> {\n const res = await this.http.get<SingleResponse<SealedProduct>>(\n `/v1/sealed/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sealed/{id}/prices` — one row per synced day, oldest first. */\n async prices(id: string, params?: SealedPriceHistoryParams): Promise<SealedPrice[]> {\n const res = await this.http.get<SingleResponse<SealedPrice[]>>(\n `/v1/sealed/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedPriceSource, SetCardsParams } from '../params.js';\nimport type {\n Card,\n CardDexSet,\n CardNeighbors,\n PaginatedResponse,\n SealedProduct,\n SingleResponse,\n} from '../types.js';\n\nexport class SetsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sets` — every set. */\n async list(): Promise<CardDexSet[]> {\n const res = await this.http.get<SingleResponse<CardDexSet[]>>('/v1/sets');\n return res.data;\n }\n\n /** `GET /v1/sets/{id}` */\n async get(id: string): Promise<CardDexSet> {\n const res = await this.http.get<SingleResponse<CardDexSet>>(\n `/v1/sets/${encodeURIComponent(id)}`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/cards` */\n cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>(\n `/v1/sets/${encodeURIComponent(id)}/cards`,\n params,\n );\n }\n\n /** Iterates every card in a set across all pages. */\n cardsAll(id: string, params?: Omit<SetCardsParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.cards(id, { ...params, page }));\n }\n\n /** `GET /v1/sets/{id}/cards/{cardId}/neighbors` — the 2 previous / 2 next card ids. */\n async neighbors(setId: string, cardId: string): Promise<CardNeighbors> {\n const res = await this.http.get<SingleResponse<CardNeighbors>>(\n `/v1/sets/${encodeURIComponent(setId)}/cards/${encodeURIComponent(cardId)}/neighbors`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/sealed` — sealed products attached to a set, each with its latest price. */\n async sealed(id: string, params?: { source?: SealedPriceSource }): Promise<SealedProduct[]> {\n const res = await this.http.get<SingleResponse<SealedProduct[]>>(\n `/v1/sets/${encodeURIComponent(id)}/sealed`,\n params,\n );\n return res.data;\n }\n}\n","import type { RetryOptions } from './http.js';\nimport { HttpClient } from './http.js';\nimport { AuthResource } from './resources/auth.js';\nimport { CardsResource } from './resources/cards.js';\nimport { PricesResource } from './resources/prices.js';\nimport { SealedResource } from './resources/sealed.js';\nimport { SetsResource } from './resources/sets.js';\nimport type { HealthResponse, UsageResponse } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.carddex.dev';\n\nexport interface CardDexOptions {\n /**\n * A `pk_live_...` key from `POST /v1/auth/register`. Omit it to call the\n * API anonymously — CardDex allows this at a lower rate (30 req/min,\n * 5,000 req/day per IP), specifically so a browser can call it without a\n * key. **Never ship a real API key in public frontend code**: it would be\n * readable by anyone who opens dev tools and shared by every visitor to\n * your site. Proxy through your own backend instead if you need the\n * higher, keyed limits from a browser context.\n */\n apiKey?: string;\n /** Defaults to `https://api.carddex.dev`. Override for a local/staging API or a CORS proxy. */\n baseUrl?: string;\n /** Defaults to the global `fetch`. Override to inject a custom implementation (proxies, logging, tests). */\n fetch?: typeof fetch;\n /**\n * Automatic retry on `429`, honouring `Retry-After`. **Off by default.**\n * Pass `true` for the defaults (up to 2 retries, never waiting more than\n * 60s), or an object to tune them. A `Retry-After` longer than\n * `maxWaitSeconds` — typically the daily-quota reset, which can be most of\n * a day away — is never honoured; the request fails immediately instead.\n */\n retry?: boolean | RetryOptions;\n}\n\nfunction isBrowserLike(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof (window as { document?: unknown }).document !== 'undefined'\n );\n}\n\n/**\n * CardDex API client.\n *\n * ```ts\n * import { CardDex } from '@carddex/sdk';\n *\n * const client = new CardDex({ apiKey: process.env.CARDDEX_API_KEY });\n * const { data } = await client.cards.list({ name: 'Charizard' });\n * ```\n */\nexport class CardDex {\n readonly cards: CardsResource;\n readonly sets: SetsResource;\n readonly sealed: SealedResource;\n readonly prices: PricesResource;\n readonly auth: AuthResource;\n\n private readonly http: HttpClient;\n\n constructor(options: CardDexOptions = {}) {\n if (options.apiKey && isBrowserLike()) {\n // biome-ignore lint/suspicious/noConsole: deliberate one-time safety warning, not app logging\n console.warn(\n '[@carddex/sdk] An apiKey was passed in what looks like a browser environment. ' +\n 'API keys shipped in frontend code are visible to every visitor. Omit apiKey for ' +\n \"CardDex's anonymous browser mode, or proxy authenticated requests through your own backend.\",\n );\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n '@carddex/sdk requires a global fetch implementation. On Node < 18, pass one via `fetch` in the options.',\n );\n }\n\n this.http = new HttpClient({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n apiKey: options.apiKey,\n fetch: fetchImpl.bind(globalThis),\n retry: options.retry,\n });\n\n this.cards = new CardsResource(this.http);\n this.sets = new SetsResource(this.http);\n this.sealed = new SealedResource(this.http);\n this.prices = new PricesResource(this.http);\n this.auth = new AuthResource(this.http);\n }\n\n /** `GET /v1/auth/usage` — shorthand for `client.auth.usage()`. Requires an `apiKey`. */\n usage(): Promise<UsageResponse> {\n return this.auth.usage();\n }\n\n /** `GET /v1/health` — API health, price freshness, and cron status. */\n async health(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/v1/health');\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/auth.ts","../src/pagination.ts","../src/resources/cards.ts","../src/resources/prices.ts","../src/resources/sealed.ts","../src/resources/sets.ts","../src/client.ts"],"sourcesContent":["/** Rate-limit info parsed from response headers, when present. */\nexport interface RateLimitInfo {\n /** `X-RateLimit-Limit`: requests allowed per minute. */\n limit: number | null;\n /** `X-RateLimit-Daily-Limit`: requests allowed per UTC day, or `null` when the tier is uncapped. */\n dailyLimit: number | null;\n /** `X-RateLimit-Daily-Remaining`: approximate, can lag by about a minute. `null` when the API couldn't compute it. */\n dailyRemaining: number | null;\n}\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitInfo {\n const num = (name: string): number | null => {\n const raw = headers.get(name);\n if (raw == null) return null;\n const n = Number(raw);\n return Number.isFinite(n) ? n : null;\n };\n return {\n limit: num('X-RateLimit-Limit'),\n dailyLimit: num('X-RateLimit-Daily-Limit'),\n dailyRemaining: num('X-RateLimit-Daily-Remaining'),\n };\n}\n\n/**\n * Thrown for any non-2xx response, and for network/parse failures the fetch\n * layer can't attribute to the API itself.\n */\nexport class CardDexError extends Error {\n /** HTTP status code. `0` for a request that never got a response (network failure, abort). */\n readonly status: number;\n /**\n * The API's own `error.code`. For a response the API actually produced,\n * this is the same number as `status` (see the note on `ApiErrorBody` in\n * `types.ts`) — kept as its own field because a transport-level failure\n * (no response at all) sets it to a string like `NETWORK_ERROR` instead.\n */\n readonly code: number | string;\n /** Seconds to wait before retrying, parsed from `Retry-After` on a 429. `null` otherwise. */\n readonly retryAfter: number | null;\n /** Rate-limit headers on the response, when there was one. */\n readonly rateLimit: RateLimitInfo | null;\n\n constructor(\n message: string,\n options: {\n status: number;\n code: number | string;\n retryAfter?: number | null;\n rateLimit?: RateLimitInfo | null;\n cause?: unknown;\n },\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CardDexError';\n this.status = options.status;\n this.code = options.code;\n this.retryAfter = options.retryAfter ?? null;\n this.rateLimit = options.rateLimit ?? null;\n Object.setPrototypeOf(this, CardDexError.prototype);\n }\n\n /** Whether this is a 429 (either the per-minute or the daily cap). */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n\n static async fromResponse(response: Response): Promise<CardDexError> {\n const rateLimit = parseRateLimitHeaders(response.headers);\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfter = retryAfterHeader != null ? Number(retryAfterHeader) : null;\n\n let message = `CardDex API error (${response.status})`;\n let code: number | string = response.status;\n try {\n const body = (await response.clone().json()) as {\n error?: { code?: unknown; message?: unknown };\n };\n if (body?.error) {\n if (typeof body.error.message === 'string') message = body.error.message;\n if (typeof body.error.code === 'number' || typeof body.error.code === 'string') {\n code = body.error.code;\n }\n }\n } catch {\n // Non-JSON or empty error body — fall back to the status-derived message above.\n }\n\n return new CardDexError(message, {\n status: response.status,\n code,\n retryAfter: Number.isFinite(retryAfter) ? retryAfter : null,\n rateLimit,\n });\n }\n\n static network(cause: unknown): CardDexError {\n const message = cause instanceof Error ? cause.message : 'Network request failed';\n return new CardDexError(message, { status: 0, code: 'NETWORK_ERROR', cause });\n }\n}\n","import { CardDexError } from './errors.js';\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | undefined\n | null\n | readonly (string | number)[];\nexport type QueryParams = Record<string, QueryValue>;\n\nexport interface RetryOptions {\n /** Max retry attempts on 429. Default 2. */\n maxRetries?: number;\n /**\n * A computed `Retry-After` above this many seconds is never honoured — the\n * request fails immediately instead of sleeping (this is what keeps a\n * daily-quota 429, whose `Retry-After` can be most of a day, from blocking\n * for hours). Default 60, matching the per-minute limiter's own\n * `Retry-After: 60`.\n */\n maxWaitSeconds?: number;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n apiKey?: string;\n fetch: typeof fetch;\n /** `false` (default) disables retries; `true` enables them with the defaults below. */\n retry?: boolean | RetryOptions;\n}\n\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_WAIT_SECONDS = 60;\n\nfunction buildQueryString(params?: QueryParams): string {\n if (!params) return '';\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n if (value.length === 0) continue;\n search.set(key, value.join(','));\n } else {\n search.set(key, String(value));\n }\n }\n const qs = search.toString();\n return qs ? `?${qs}` : '';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Minimal fetch wrapper: builds URLs, attaches auth, parses JSON, and turns\n * non-2xx responses into `CardDexError`. No dependency beyond global `fetch`.\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly fetchImpl: typeof fetch;\n private readonly retryConfig: Required<RetryOptions> | null;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetch;\n if (options.retry === true) {\n this.retryConfig = {\n maxRetries: DEFAULT_MAX_RETRIES,\n maxWaitSeconds: DEFAULT_MAX_WAIT_SECONDS,\n };\n } else if (options.retry && typeof options.retry === 'object') {\n this.retryConfig = {\n maxRetries: options.retry.maxRetries ?? DEFAULT_MAX_RETRIES,\n maxWaitSeconds: options.retry.maxWaitSeconds ?? DEFAULT_MAX_WAIT_SECONDS,\n };\n } else {\n this.retryConfig = null;\n }\n }\n\n async get<T>(path: string, query?: QueryParams, signal?: AbortSignal): Promise<T> {\n return this.request<T>('GET', path, { query, signal });\n }\n\n async post<T>(path: string, body?: unknown, signal?: AbortSignal): Promise<T> {\n return this.request<T>('POST', path, { body, signal });\n }\n\n private async request<T>(\n method: string,\n path: string,\n opts: { query?: QueryParams; body?: unknown; signal?: AbortSignal },\n ): Promise<T> {\n const url = `${this.baseUrl}${path}${buildQueryString(opts.query)}`;\n const headers: Record<string, string> = { Accept: 'application/json' };\n if (this.apiKey) headers['X-API-Key'] = this.apiKey;\n if (opts.body !== undefined) headers['Content-Type'] = 'application/json';\n\n let attempt = 0;\n for (;;) {\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: opts.signal,\n });\n } catch (cause) {\n throw CardDexError.network(cause);\n }\n\n if (response.status === 429 && this.retryConfig && attempt < this.retryConfig.maxRetries) {\n const retryAfterHeader = response.headers.get('Retry-After');\n const retryAfterSeconds = retryAfterHeader != null ? Number(retryAfterHeader) : Number.NaN;\n if (\n Number.isFinite(retryAfterSeconds) &&\n retryAfterSeconds <= this.retryConfig.maxWaitSeconds\n ) {\n attempt++;\n await sleep(retryAfterSeconds * 1000);\n continue;\n }\n // Retry-After is missing or longer than we're willing to wait\n // (typically the daily cap, which resets at UTC midnight) — surface\n // the error instead of blocking.\n }\n\n if (!response.ok) {\n throw await CardDexError.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n }\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { RegisterResponse, SingleResponse, UsageResponse } from '../types.js';\n\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `POST /v1/auth/register` — claim a free API key. The key is returned\n * exactly once, so store it immediately. A lost key can be replaced by signing\n * in at https://carddex.dev/account (create, rotate or revoke keys there).\n */\n async register(email: string, name?: string): Promise<RegisterResponse> {\n const res = await this.http.post<SingleResponse<RegisterResponse>>('/v1/auth/register', {\n email,\n name,\n });\n return res.data;\n }\n\n /** `GET /v1/auth/usage` — usage stats for the API key this client was constructed with. Requires an `apiKey`. */\n async usage(): Promise<UsageResponse> {\n const res = await this.http.get<SingleResponse<UsageResponse>>('/v1/auth/usage');\n return res.data;\n }\n}\n","import type { PaginatedResponse } from './types.js';\n\n/**\n * Turns a page-fetching function into an async iterator over every item,\n * fetching the next page lazily as the caller consumes items.\n *\n * @example\n * ```ts\n * for await (const card of paginate((page) => client.cards.list({ set: 'sv06', page }))) {\n * console.log(card.name);\n * }\n * ```\n */\nexport async function* paginate<T>(\n fetchPage: (page: number) => Promise<PaginatedResponse<T>>,\n startPage = 1,\n): AsyncGenerator<T, void, void> {\n let page = startPage;\n for (;;) {\n const response = await fetchPage(page);\n if (response.data.length === 0) return;\n yield* response.data;\n if (page >= response.meta.totalPages) return;\n page++;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type {\n CardGetParams,\n CardListParams,\n CardPriceHistoryParams,\n CardPricesParams,\n} from '../params.js';\nimport type {\n Card,\n CardPrice,\n CardWithRelations,\n PaginatedResponse,\n SingleResponse,\n} from '../types.js';\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/cards` — list, search, filter and sort cards. */\n list(params?: CardListParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>('/v1/cards', params);\n }\n\n /**\n * Iterates every card matching `params` across all pages, fetching pages\n * lazily as you consume them.\n *\n * @example\n * ```ts\n * for await (const card of client.cards.listAll({ set: 'sv06' })) { ... }\n * ```\n */\n listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/cards/random` */\n async random(): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random');\n return res.data;\n }\n\n /** `GET /v1/cards/{id}` */\n async get(id: string, params?: CardGetParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>(\n `/v1/cards/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */\n async prices(id: string, params?: CardPricesParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/cards/{id}/prices/history` — one row per day per price guide, oldest first. */\n async priceHistory(id: string, params?: CardPriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/cards/${encodeURIComponent(id)}/prices/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type {\n BargainsParams,\n BulkPricesParams,\n PriceHistoryParams,\n RankingParams,\n TrendsParams,\n} from '../params.js';\nimport type { BargainCardPrice, CardPrice, SingleResponse } from '../types.js';\n\nexport class PricesResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * `GET /v1/prices` — latest price rows for up to 100 card ids (and/or up\n * to 100 print/variant ids) in one request. Keyed by the id you asked for;\n * an id with no price data maps to `[]`.\n */\n async bulk(params: BulkPricesParams): Promise<Record<string, CardPrice[]>> {\n const res = await this.http.get<SingleResponse<Record<string, CardPrice[]>>>(\n '/v1/prices',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/top` — highest-valued cards. */\n async top(params?: RankingParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/top', params);\n return res.data;\n }\n\n /** `GET /v1/prices/trends` — biggest movers against the card's own rolling average. */\n async trends(params?: TrendsParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>('/v1/prices/trends', params);\n return res.data;\n }\n\n /** `GET /v1/prices/bargains` — cards trading below a reference price, best discount first. */\n async bargains(params?: BargainsParams): Promise<BargainCardPrice[]> {\n const res = await this.http.get<SingleResponse<BargainCardPrice[]>>(\n '/v1/prices/bargains',\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/prices/{cardId}/history` — one row per day per guide, oldest first. */\n async history(cardId: string, params?: PriceHistoryParams): Promise<CardPrice[]> {\n const res = await this.http.get<SingleResponse<CardPrice[]>>(\n `/v1/prices/${encodeURIComponent(cardId)}/history`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedListParams, SealedPriceHistoryParams } from '../params.js';\nimport type { PaginatedResponse, SealedPrice, SealedProduct, SingleResponse } from '../types.js';\n\nexport class SealedResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sealed` — list sealed products with their latest price. */\n list(params?: SealedListParams): Promise<PaginatedResponse<SealedProduct>> {\n return this.http.get<PaginatedResponse<SealedProduct>>('/v1/sealed', params);\n }\n\n /** Iterates every sealed product matching `params` across all pages. */\n listAll(params?: Omit<SealedListParams, 'page'>): AsyncGenerator<SealedProduct, void, void> {\n return paginate((page) => this.list({ ...params, page }));\n }\n\n /** `GET /v1/sealed/{id}` */\n async get(id: string, params?: { source?: SealedListParams['source'] }): Promise<SealedProduct> {\n const res = await this.http.get<SingleResponse<SealedProduct>>(\n `/v1/sealed/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sealed/{id}/prices` — one row per synced day, oldest first. */\n async prices(id: string, params?: SealedPriceHistoryParams): Promise<SealedPrice[]> {\n const res = await this.http.get<SingleResponse<SealedPrice[]>>(\n `/v1/sealed/${encodeURIComponent(id)}/prices`,\n params,\n );\n return res.data;\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { paginate } from '../pagination.js';\nimport type { SealedPriceSource, SetCardsParams, SetGetParams } from '../params.js';\nimport type {\n Card,\n CardDexSet,\n CardNeighbors,\n PaginatedResponse,\n SealedProduct,\n SingleResponse,\n} from '../types.js';\n\nexport class SetsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /v1/sets` — every set. `lang` adds `localized_name`. */\n async list(params?: SetGetParams): Promise<CardDexSet[]> {\n const res = await this.http.get<SingleResponse<CardDexSet[]>>('/v1/sets', params);\n return res.data;\n }\n\n /** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */\n async get(id: string, params?: SetGetParams): Promise<CardDexSet> {\n const res = await this.http.get<SingleResponse<CardDexSet>>(\n `/v1/sets/${encodeURIComponent(id)}`,\n params,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/cards` */\n cards(id: string, params?: SetCardsParams): Promise<PaginatedResponse<Card>> {\n return this.http.get<PaginatedResponse<Card>>(\n `/v1/sets/${encodeURIComponent(id)}/cards`,\n params,\n );\n }\n\n /** Iterates every card in a set across all pages. */\n cardsAll(id: string, params?: Omit<SetCardsParams, 'page'>): AsyncGenerator<Card, void, void> {\n return paginate((page) => this.cards(id, { ...params, page }));\n }\n\n /** `GET /v1/sets/{id}/cards/{cardId}/neighbors` — the 2 previous / 2 next card ids. */\n async neighbors(setId: string, cardId: string): Promise<CardNeighbors> {\n const res = await this.http.get<SingleResponse<CardNeighbors>>(\n `/v1/sets/${encodeURIComponent(setId)}/cards/${encodeURIComponent(cardId)}/neighbors`,\n );\n return res.data;\n }\n\n /** `GET /v1/sets/{id}/sealed` — sealed products attached to a set, each with its latest price. */\n async sealed(id: string, params?: { source?: SealedPriceSource }): Promise<SealedProduct[]> {\n const res = await this.http.get<SingleResponse<SealedProduct[]>>(\n `/v1/sets/${encodeURIComponent(id)}/sealed`,\n params,\n );\n return res.data;\n }\n}\n","import type { RetryOptions } from './http.js';\nimport { HttpClient } from './http.js';\nimport { AuthResource } from './resources/auth.js';\nimport { CardsResource } from './resources/cards.js';\nimport { PricesResource } from './resources/prices.js';\nimport { SealedResource } from './resources/sealed.js';\nimport { SetsResource } from './resources/sets.js';\nimport type { HealthResponse, UsageResponse } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.carddex.dev';\n\nexport interface CardDexOptions {\n /**\n * A `pk_live_...` key from `POST /v1/auth/register`. Omit it to call the\n * API anonymously — CardDex allows this at a lower rate (30 req/min,\n * 5,000 req/day per IP), specifically so a browser can call it without a\n * key. **Never ship a real API key in public frontend code**: it would be\n * readable by anyone who opens dev tools and shared by every visitor to\n * your site. Proxy through your own backend instead if you need the\n * higher, keyed limits from a browser context.\n */\n apiKey?: string;\n /** Defaults to `https://api.carddex.dev`. Override for a local/staging API or a CORS proxy. */\n baseUrl?: string;\n /** Defaults to the global `fetch`. Override to inject a custom implementation (proxies, logging, tests). */\n fetch?: typeof fetch;\n /**\n * Automatic retry on `429`, honouring `Retry-After`. **Off by default.**\n * Pass `true` for the defaults (up to 2 retries, never waiting more than\n * 60s), or an object to tune them. A `Retry-After` longer than\n * `maxWaitSeconds` — typically the daily-quota reset, which can be most of\n * a day away — is never honoured; the request fails immediately instead.\n */\n retry?: boolean | RetryOptions;\n}\n\nfunction isBrowserLike(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof (window as { document?: unknown }).document !== 'undefined'\n );\n}\n\n/**\n * CardDex API client.\n *\n * ```ts\n * import { CardDex } from '@carddex/sdk';\n *\n * const client = new CardDex({ apiKey: process.env.CARDDEX_API_KEY });\n * const { data } = await client.cards.list({ name: 'Charizard' });\n * ```\n */\nexport class CardDex {\n readonly cards: CardsResource;\n readonly sets: SetsResource;\n readonly sealed: SealedResource;\n readonly prices: PricesResource;\n readonly auth: AuthResource;\n\n private readonly http: HttpClient;\n\n constructor(options: CardDexOptions = {}) {\n if (options.apiKey && isBrowserLike()) {\n // biome-ignore lint/suspicious/noConsole: deliberate one-time safety warning, not app logging\n console.warn(\n '[@carddex/sdk] An apiKey was passed in what looks like a browser environment. ' +\n 'API keys shipped in frontend code are visible to every visitor. Omit apiKey for ' +\n \"CardDex's anonymous browser mode, or proxy authenticated requests through your own backend.\",\n );\n }\n\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (!fetchImpl) {\n throw new Error(\n '@carddex/sdk requires a global fetch implementation. On Node < 18, pass one via `fetch` in the options.',\n );\n }\n\n this.http = new HttpClient({\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n apiKey: options.apiKey,\n fetch: fetchImpl.bind(globalThis),\n retry: options.retry,\n });\n\n this.cards = new CardsResource(this.http);\n this.sets = new SetsResource(this.http);\n this.sealed = new SealedResource(this.http);\n this.prices = new PricesResource(this.http);\n this.auth = new AuthResource(this.http);\n }\n\n /** `GET /v1/auth/usage` — shorthand for `client.auth.usage()`. Requires an `apiKey`. */\n usage(): Promise<UsageResponse> {\n return this.auth.usage();\n }\n\n /** `GET /v1/health` — API health, price freshness, and cron status. */\n async health(): Promise<HealthResponse> {\n return this.http.get<HealthResponse>('/v1/health');\n }\n}\n"],"mappings":";AAUA,SAAS,sBAAsB,SAAiC;AAC9D,QAAM,MAAM,CAAC,SAAgC;AAC3C,UAAM,MAAM,QAAQ,IAAI,IAAI;AAC5B,QAAI,OAAO,KAAM,QAAO;AACxB,UAAM,IAAI,OAAO,GAAG;AACpB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AAAA,IACL,OAAO,IAAI,mBAAmB;AAAA,IAC9B,YAAY,IAAI,yBAAyB;AAAA,IACzC,gBAAgB,IAAI,6BAA6B;AAAA,EACnD;AACF;AAMO,IAAM,eAAN,MAAM,sBAAqB,MAAM;AAAA;AAAA,EAE7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,SAOA;AACA,UAAM,SAAS,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAS;AACjF,SAAK,OAAO;AACZ,SAAK,SAAS,QAAQ;AACtB,SAAK,OAAO,QAAQ;AACpB,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,YAAY,QAAQ,aAAa;AACtC,WAAO,eAAe,MAAM,cAAa,SAAS;AAAA,EACpD;AAAA;AAAA,EAGA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,aAAa,aAAa,UAA2C;AACnE,UAAM,YAAY,sBAAsB,SAAS,OAAO;AACxD,UAAM,mBAAmB,SAAS,QAAQ,IAAI,aAAa;AAC3D,UAAM,aAAa,oBAAoB,OAAO,OAAO,gBAAgB,IAAI;AAEzE,QAAI,UAAU,sBAAsB,SAAS,MAAM;AACnD,QAAI,OAAwB,SAAS;AACrC,QAAI;AACF,YAAM,OAAQ,MAAM,SAAS,MAAM,EAAE,KAAK;AAG1C,UAAI,MAAM,OAAO;AACf,YAAI,OAAO,KAAK,MAAM,YAAY,SAAU,WAAU,KAAK,MAAM;AACjE,YAAI,OAAO,KAAK,MAAM,SAAS,YAAY,OAAO,KAAK,MAAM,SAAS,UAAU;AAC9E,iBAAO,KAAK,MAAM;AAAA,QACpB;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,WAAO,IAAI,cAAa,SAAS;AAAA,MAC/B,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA,YAAY,OAAO,SAAS,UAAU,IAAI,aAAa;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,QAAQ,OAA8B;AAC3C,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,IAAI,cAAa,SAAS,EAAE,QAAQ,GAAG,MAAM,iBAAiB,MAAM,CAAC;AAAA,EAC9E;AACF;;;ACpEA,IAAM,sBAAsB;AAC5B,IAAM,2BAA2B;AAEjC,SAAS,iBAAiB,QAA8B;AACtD,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAI,MAAM,WAAW,EAAG;AACxB,aAAO,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,IACjC,OAAO;AACL,aAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAC/B;AAAA,EACF;AACA,QAAM,KAAK,OAAO,SAAS;AAC3B,SAAO,KAAK,IAAI,EAAE,KAAK;AACzB;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAMO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AACjD,SAAK,SAAS,QAAQ;AACtB,SAAK,YAAY,QAAQ;AACzB,QAAI,QAAQ,UAAU,MAAM;AAC1B,WAAK,cAAc;AAAA,QACjB,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,IACF,WAAW,QAAQ,SAAS,OAAO,QAAQ,UAAU,UAAU;AAC7D,WAAK,cAAc;AAAA,QACjB,YAAY,QAAQ,MAAM,cAAc;AAAA,QACxC,gBAAgB,QAAQ,MAAM,kBAAkB;AAAA,MAClD;AAAA,IACF,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,IAAO,MAAc,OAAqB,QAAkC;AAChF,WAAO,KAAK,QAAW,OAAO,MAAM,EAAE,OAAO,OAAO,CAAC;AAAA,EACvD;AAAA,EAEA,MAAM,KAAQ,MAAc,MAAgB,QAAkC;AAC5E,WAAO,KAAK,QAAW,QAAQ,MAAM,EAAE,MAAM,OAAO,CAAC;AAAA,EACvD;AAAA,EAEA,MAAc,QACZ,QACA,MACA,MACY;AACZ,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,GAAG,iBAAiB,KAAK,KAAK,CAAC;AACjE,UAAM,UAAkC,EAAE,QAAQ,mBAAmB;AACrE,QAAI,KAAK,OAAQ,SAAQ,WAAW,IAAI,KAAK;AAC7C,QAAI,KAAK,SAAS,OAAW,SAAQ,cAAc,IAAI;AAEvD,QAAI,UAAU;AACd,eAAS;AACP,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,KAAK,UAAU,KAAK;AAAA,UACnC;AAAA,UACA;AAAA,UACA,MAAM,KAAK,SAAS,SAAY,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,UAC5D,QAAQ,KAAK;AAAA,QACf,CAAC;AAAA,MACH,SAAS,OAAO;AACd,cAAM,aAAa,QAAQ,KAAK;AAAA,MAClC;AAEA,UAAI,SAAS,WAAW,OAAO,KAAK,eAAe,UAAU,KAAK,YAAY,YAAY;AACxF,cAAM,mBAAmB,SAAS,QAAQ,IAAI,aAAa;AAC3D,cAAM,oBAAoB,oBAAoB,OAAO,OAAO,gBAAgB,IAAI,OAAO;AACvF,YACE,OAAO,SAAS,iBAAiB,KACjC,qBAAqB,KAAK,YAAY,gBACtC;AACA;AACA,gBAAM,MAAM,oBAAoB,GAAI;AACpC;AAAA,QACF;AAAA,MAIF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,MAAM,aAAa,aAAa,QAAQ;AAAA,MAChD;AAEA,UAAI,SAAS,WAAW,IAAK,QAAO;AACpC,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,EACF;AACF;;;ACzIO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,MAAM,SAAS,OAAe,MAA0C;AACtE,UAAM,MAAM,MAAM,KAAK,KAAK,KAAuC,qBAAqB;AAAA,MACtF;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,QAAgC;AACpC,UAAM,MAAM,MAAM,KAAK,KAAK,IAAmC,gBAAgB;AAC/E,WAAO,IAAI;AAAA,EACb;AACF;;;ACXA,gBAAuB,SACrB,WACA,YAAY,GACmB;AAC/B,MAAI,OAAO;AACX,aAAS;AACP,UAAM,WAAW,MAAM,UAAU,IAAI;AACrC,QAAI,SAAS,KAAK,WAAW,EAAG;AAChC,WAAO,SAAS;AAChB,QAAI,QAAQ,SAAS,KAAK,WAAY;AACtC;AAAA,EACF;AACF;;;ACTO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA,EAG7B,KAAK,QAA2D;AAC9D,WAAO,KAAK,KAAK,IAA6B,aAAa,MAAM;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAQ,QAAyE;AAC/E,WAAO,SAAS,CAAC,SAAS,KAAK,KAAK,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,SAAqC;AACzC,UAAM,MAAM,MAAM,KAAK,KAAK,IAAuC,kBAAkB;AACrF,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,IAAI,IAAY,QAAoD;AACxE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,aAAa,mBAAmB,EAAE,CAAC;AAAA,MACnC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,QAAiD;AACxE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,aAAa,mBAAmB,EAAE,CAAC;AAAA,MACnC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,aAAa,IAAY,QAAuD;AACpF,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,aAAa,mBAAmB,EAAE,CAAC;AAAA,MACnC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AACF;;;AC3DO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,MAAM,KAAK,QAAgE;AACzE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,IAAI,QAA8C;AACtD,UAAM,MAAM,MAAM,KAAK,KAAK,IAAiC,kBAAkB,MAAM;AACrF,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,OAAO,QAA6C;AACxD,UAAM,MAAM,MAAM,KAAK,KAAK,IAAiC,qBAAqB,MAAM;AACxF,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,SAAS,QAAsD;AACnE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,QAAQ,QAAgB,QAAmD;AAC/E,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,cAAc,mBAAmB,MAAM,CAAC;AAAA,MACxC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AACF;;;AClDO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA,EAG7B,KAAK,QAAsE;AACzE,WAAO,KAAK,KAAK,IAAsC,cAAc,MAAM;AAAA,EAC7E;AAAA;AAAA,EAGA,QAAQ,QAAoF;AAC1F,WAAO,SAAS,CAAC,SAAS,KAAK,KAAK,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,IAAI,IAAY,QAA0E;AAC9F,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,cAAc,mBAAmB,EAAE,CAAC;AAAA,MACpC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,QAA2D;AAClF,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,cAAc,mBAAmB,EAAE,CAAC;AAAA,MACpC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AACF;;;ACvBO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAAnB;AAAA;AAAA,EAG7B,MAAM,KAAK,QAA8C;AACvD,UAAM,MAAM,MAAM,KAAK,KAAK,IAAkC,YAAY,MAAM;AAChF,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,IAAI,IAAY,QAA4C;AAChE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,YAAY,mBAAmB,EAAE,CAAC;AAAA,MAClC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,IAAY,QAA2D;AAC3E,WAAO,KAAK,KAAK;AAAA,MACf,YAAY,mBAAmB,EAAE,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,SAAS,IAAY,QAAyE;AAC5F,WAAO,SAAS,CAAC,SAAS,KAAK,MAAM,IAAI,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,UAAU,OAAe,QAAwC;AACrE,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,YAAY,mBAAmB,KAAK,CAAC,UAAU,mBAAmB,MAAM,CAAC;AAAA,IAC3E;AACA,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,QAAmE;AAC1F,UAAM,MAAM,MAAM,KAAK,KAAK;AAAA,MAC1B,YAAY,mBAAmB,EAAE,CAAC;AAAA,MAClC;AAAA,IACF;AACA,WAAO,IAAI;AAAA,EACb;AACF;;;AClDA,IAAM,mBAAmB;AA2BzB,SAAS,gBAAyB;AAChC,SACE,OAAO,WAAW,eAClB,OAAQ,OAAkC,aAAa;AAE3D;AAYO,IAAM,UAAN,MAAc;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EAEjB,YAAY,UAA0B,CAAC,GAAG;AACxC,QAAI,QAAQ,UAAU,cAAc,GAAG;AAErC,cAAQ;AAAA,QACN;AAAA,MAGF;AAAA,IACF;AAEA,UAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,SAAS,QAAQ,WAAW;AAAA,MAC5B,QAAQ,QAAQ;AAAA,MAChB,OAAO,UAAU,KAAK,UAAU;AAAA,MAChC,OAAO,QAAQ;AAAA,IACjB,CAAC;AAED,SAAK,QAAQ,IAAI,cAAc,KAAK,IAAI;AACxC,SAAK,OAAO,IAAI,aAAa,KAAK,IAAI;AACtC,SAAK,SAAS,IAAI,eAAe,KAAK,IAAI;AAC1C,SAAK,SAAS,IAAI,eAAe,KAAK,IAAI;AAC1C,SAAK,OAAO,IAAI,aAAa,KAAK,IAAI;AAAA,EACxC;AAAA;AAAA,EAGA,QAAgC;AAC9B,WAAO,KAAK,KAAK,MAAM;AAAA,EACzB;AAAA;AAAA,EAGA,MAAM,SAAkC;AACtC,WAAO,KAAK,KAAK,IAAoB,YAAY;AAAA,EACnD;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carddex/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Official TypeScript/JavaScript client for the CardDex Pokémon TCG API",
5
5
  "keywords": [
6
6
  "pokemon",