@carddex/sdk 0.3.0 → 0.5.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 +39 -4
- package/dist/index.cjs +9 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -14
- package/dist/index.d.ts +86 -14
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,19 +36,54 @@ An API key is optional. Omit it to call the API anonymously. The SDK sends the k
|
|
|
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
38
|
|
|
39
|
-
### Card names in German, French, Italian, Spanish and Portuguese
|
|
39
|
+
### Card names and scans in German, French, Italian, Spanish and Portuguese
|
|
40
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.
|
|
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. Cards also carry `localized_image`: the scan in that edition (`thumb_url`, `small_url`, `large_url`), or `null` where there is none, in which case show the English image. `image_url` and `images` stay the English scan whatever `lang` is. With `lang`, `name` and `q` also match names in that language. `include: ['translations']` lists every localized name a card has. Cards also carry `base_finish` (`holo`, `reverse` or `normal`) where the card's own print has a known finish that the rarity does not say (for example the HGSS Black Star Promos, catalogued as Common): it is present only when known, otherwise omitted.
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
44
|
const { data } = await client.cards.list({ name: 'Glurak', lang: 'de' });
|
|
45
45
|
// data[0].name === 'Charizard', data[0].localized_name === 'Glurak'
|
|
46
|
+
const image = data[0].localized_image?.small_url ?? data[0].image_url;
|
|
46
47
|
|
|
47
48
|
const sets = await client.sets.list({ lang: 'fr' });
|
|
48
49
|
const card = await client.cards.get('base1-4', { include: ['translations'] });
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
Polish card names are not available from any source, so `lang: 'pl'` is rejected (the API answers 400).
|
|
52
|
+
Polish card names are not available from any source, so `lang: 'pl'` is rejected (the API answers 400).
|
|
53
|
+
|
|
54
|
+
### Japanese catalogue
|
|
55
|
+
|
|
56
|
+
Pass `catalog: 'ja'` (default `'en'`) to read the Japanese catalogue: its own sets, numbering and printed names. It works on `cards.list`, `cards.random`, `cards.rarities`, `sets.list`, `sets.cards`, `prices.bulk` and the `prices.top` / `trends` / `bargains` rankings. Reads keyed by an id (`cards.get`, `sets.get`, prices, history) work out the catalogue from the `ja-` prefix, so they need no `catalog`.
|
|
57
|
+
|
|
58
|
+
Cards and sets of the Japanese catalogue carry `catalog: "ja"` (English ones carry no `catalog`). A Japanese card's `name` is its printed Japanese name and `name_en` its English name, or null where unknown; a set's `set_code` is the code printed on its cards (`sv2a`). Prices come back as `source: "cardmarket"` (EUR). `lang` translates the English catalogue only: on Japanese cards `localized_name` and `localized_image` are null. Further catalogues (Traditional and Simplified Chinese, Korean, Thai) are not available yet; the API answers 400 for them.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const { data } = await client.cards.list({ catalog: 'ja', q: 'charizard', pageSize: 3 });
|
|
62
|
+
const card = await client.cards.get('ja-SV2a-006');
|
|
63
|
+
const [price] = await client.cards.prices('ja-SV2a-006');
|
|
64
|
+
console.log(card.name, card.name_en, price?.trend_price, price?.currency);
|
|
65
|
+
// リザードンex Charizard ex 2.82 EUR
|
|
66
|
+
|
|
67
|
+
const sets = await client.sets.list({ catalog: 'ja' }); // set_code === 'sv2a' for ja-SV2a
|
|
68
|
+
const top = await client.prices.top({ catalog: 'ja', limit: 5 }); // row.card_name, row.card_name_en
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Polish catalogue
|
|
72
|
+
|
|
73
|
+
Pass `catalog: 'pl'` (default `'en'`) to read the Polish catalogue: the historical Polish releases of Diamond & Pearl and Mysterious Treasures, and the World Collection 2010 Pikachu promo (`pl-dp1`, `pl-dp2`, `pl-promo`). Reads keyed by an id (`cards.get`, `sets.get`, prices, history) work out the catalogue from the `pl-` prefix, so they need no `catalog`.
|
|
74
|
+
|
|
75
|
+
Cards and sets of the Polish catalogue carry `catalog: "pl"`. `name` is the printed Polish name and `name_en` its English name. Cards also carry `english_id`: the English twin card's id (`pl-dp1-1` gives `dp1-1`), or null for cards with no English counterpart (`pl-promo-1`). `set_code` is null for Polish sets.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const { data } = await client.cards.list({ catalog: 'pl', q: 'Dusknoir' });
|
|
79
|
+
const card = await client.cards.get('pl-dp1-2');
|
|
80
|
+
console.log(card.name, card.name_en, card.english_id);
|
|
81
|
+
// Dusknoir Dusknoir dp1-2
|
|
82
|
+
|
|
83
|
+
const sets = await client.sets.list({ catalog: 'pl' });
|
|
84
|
+
// [{ id: 'pl-dp2', name: 'Tajemne Skarby' }, { id: 'pl-dp1', name: 'Diament i Perła' }, { id: 'pl-promo', name: 'Promo' }]
|
|
85
|
+
```
|
|
86
|
+
|
|
52
87
|
|
|
53
88
|
### Get a free API key
|
|
54
89
|
|
|
@@ -141,7 +176,7 @@ This SDK talks to the native `/v1` API, which uses CardDex ids (`sv02-062`) but
|
|
|
141
176
|
|
|
142
177
|
| Resource | Methods |
|
|
143
178
|
| --- | --- |
|
|
144
|
-
| `client.cards` | `list`, `listAll`, `get`, `random`, `prices`, `priceHistory` |
|
|
179
|
+
| `client.cards` | `list`, `listAll`, `get`, `random`, `rarities`, `prices`, `priceHistory` |
|
|
145
180
|
| `client.sets` | `list`, `get`, `cards`, `cardsAll`, `neighbors`, `sealed` |
|
|
146
181
|
| `client.sealed` | `list`, `listAll`, `get`, `prices` |
|
|
147
182
|
| `client.prices` | `bulk`, `top`, `trends`, `bargains`, `history` |
|
package/dist/index.cjs
CHANGED
|
@@ -241,9 +241,14 @@ var CardsResource = class {
|
|
|
241
241
|
listAll(params) {
|
|
242
242
|
return paginate((page) => this.list({ ...params, page }));
|
|
243
243
|
}
|
|
244
|
-
/** `GET /v1/cards/random` */
|
|
245
|
-
async random() {
|
|
246
|
-
const res = await this.http.get("/v1/cards/random");
|
|
244
|
+
/** `GET /v1/cards/random` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */
|
|
245
|
+
async random(params) {
|
|
246
|
+
const res = await this.http.get("/v1/cards/random", params);
|
|
247
|
+
return res.data;
|
|
248
|
+
}
|
|
249
|
+
/** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */
|
|
250
|
+
async rarities(params) {
|
|
251
|
+
const res = await this.http.get("/v1/cards/rarities", params);
|
|
247
252
|
return res.data;
|
|
248
253
|
}
|
|
249
254
|
/** `GET /v1/cards/{id}` */
|
|
@@ -356,7 +361,7 @@ var SetsResource = class {
|
|
|
356
361
|
this.http = http;
|
|
357
362
|
}
|
|
358
363
|
http;
|
|
359
|
-
/** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
|
|
364
|
+
/** `GET /v1/sets` — every set of one catalogue (`catalog`, default `en`). `lang` adds `localized_name`. */
|
|
360
365
|
async list(params) {
|
|
361
366
|
const res = await this.http.get("/v1/sets", params);
|
|
362
367
|
return res.data;
|
package/dist/index.cjs.map
CHANGED
|
@@ -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, 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":[]}
|
|
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 CatalogParams,\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` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */\n async random(params?: CatalogParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random', params);\n return res.data;\n }\n\n /** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */\n async rarities(params?: CatalogParams): Promise<string[]> {\n const res = await this.http.get<SingleResponse<string[]>>('/v1/cards/rarities', params);\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 of one catalogue (`catalog`, default `en`). `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,9 @@ declare class HttpClient {
|
|
|
53
53
|
*/
|
|
54
54
|
interface CardDexSet {
|
|
55
55
|
id: string;
|
|
56
|
-
/**
|
|
56
|
+
/** `'ja'` or `'pl'` on non-English sets; absent on English sets. */
|
|
57
|
+
catalog?: 'ja' | 'pl' | (string & {});
|
|
58
|
+
/** The English name; for a Japanese set (`catalog: 'ja'`) or Polish set (`catalog: 'pl'`) the name printed on the set. */
|
|
57
59
|
name: string;
|
|
58
60
|
/** The name in the `lang` edition, or null where none is known. Only when `lang` is not `en`. */
|
|
59
61
|
localized_name?: string | null;
|
|
@@ -63,6 +65,7 @@ interface CardDexSet {
|
|
|
63
65
|
total_cards: number | null;
|
|
64
66
|
logo_url: string | null;
|
|
65
67
|
symbol_url: string | null;
|
|
68
|
+
/** The code printed on the set's cards (e.g. `sv2a` on a Japanese set); null for Polish sets or where there is none. */
|
|
66
69
|
set_code: string | null;
|
|
67
70
|
created_at: string;
|
|
68
71
|
updated_at: string;
|
|
@@ -102,11 +105,27 @@ interface CardImage {
|
|
|
102
105
|
small_url: string | null;
|
|
103
106
|
large_url: string | null;
|
|
104
107
|
}
|
|
105
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* A card's scan in the `lang` edition (de, fr, it, es, pt): `localized_image`.
|
|
110
|
+
* Each URL falls back to the next larger size, as the English ones do.
|
|
111
|
+
*/
|
|
112
|
+
interface LocalizedCardImage {
|
|
113
|
+
/** The `lang` of the request. */
|
|
114
|
+
language: string;
|
|
115
|
+
thumb_url: string | null;
|
|
116
|
+
small_url: string | null;
|
|
117
|
+
large_url: string | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* One price guide's currency and figures. `source` is `'cardmarket' | 'tcgplayer'`
|
|
121
|
+
* in practice; Japanese cards are priced by `'cardmarket'` (EUR).
|
|
122
|
+
*/
|
|
106
123
|
interface CardPrice {
|
|
107
124
|
id: number;
|
|
108
125
|
card_id: string;
|
|
109
126
|
card_name?: string | null;
|
|
127
|
+
/** Rankings with a non-English catalogue (`catalog=ja`, `catalog=pl`): the card's English name (`card_name` is the printed name). */
|
|
128
|
+
card_name_en?: string | null;
|
|
110
129
|
number?: string | null;
|
|
111
130
|
set_id?: string | null;
|
|
112
131
|
rarity?: string | null;
|
|
@@ -149,17 +168,37 @@ interface CardVariant {
|
|
|
149
168
|
}
|
|
150
169
|
interface Card {
|
|
151
170
|
id: string;
|
|
171
|
+
/** `'ja'` or `'pl'` on non-English cards; absent on English cards. */
|
|
172
|
+
catalog?: 'ja' | 'pl' | (string & {});
|
|
152
173
|
set_id: string;
|
|
153
|
-
/** The English name
|
|
174
|
+
/** The English name; for a Japanese card (`catalog: 'ja'`) or Polish card (`catalog: 'pl'`) the printed name. */
|
|
154
175
|
name: string;
|
|
176
|
+
/** A Japanese or Polish card's English name, or null where unknown. Absent on English cards. */
|
|
177
|
+
name_en?: string | null;
|
|
178
|
+
/** Polish cards only (absent on English and Japanese ones): the English twin card's id (e.g. `dp1-1` for `pl-dp1-1`), or null for cards without an English twin (`pl-promo-1`). */
|
|
179
|
+
english_id?: string | null;
|
|
155
180
|
/** The name in the `lang` edition (de, fr, it, es, pt), or null where none is known. Only when `lang` is not `en`. */
|
|
156
181
|
localized_name?: string | null;
|
|
182
|
+
/**
|
|
183
|
+
* The scan in the `lang` edition, or null when there is none (show the
|
|
184
|
+
* English image then). Only when `lang` is not `en`. The English image
|
|
185
|
+
* fields (`image_url`, `images`) never change with `lang`.
|
|
186
|
+
*/
|
|
187
|
+
localized_image?: LocalizedCardImage | null;
|
|
157
188
|
number: string;
|
|
158
189
|
supertype: string;
|
|
159
190
|
subtypes: string[] | null;
|
|
160
191
|
hp: number | null;
|
|
161
192
|
types: string[] | null;
|
|
162
193
|
rarity: string | null;
|
|
194
|
+
/**
|
|
195
|
+
* The finish of the card's own print, where the rarity does not say it:
|
|
196
|
+
* `holo` for a card only ever printed holo (e.g. the HGSS Black Star Promos,
|
|
197
|
+
* catalogued as Common). Present only when known; absent, never null, on
|
|
198
|
+
* every other card. A variant (`/v1/cards/{id}/variants`) still names its own
|
|
199
|
+
* print's finish; this describes the card when no variant is named.
|
|
200
|
+
*/
|
|
201
|
+
base_finish?: 'holo' | 'reverse' | 'normal';
|
|
163
202
|
artist: string | null;
|
|
164
203
|
regulation_mark: string | null;
|
|
165
204
|
flavor_text: string | null;
|
|
@@ -336,12 +375,22 @@ type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'ima
|
|
|
336
375
|
/** Every localized name of the card (`translations: CardTranslation[]`). Never a default. */
|
|
337
376
|
| 'translations';
|
|
338
377
|
/**
|
|
339
|
-
* Language edition for names. `name` is always the English name;
|
|
340
|
-
* value but `en`, cards and sets also carry `localized_name` (null
|
|
341
|
-
* is known),
|
|
342
|
-
*
|
|
378
|
+
* Language edition for names and scans. `name` is always the English name;
|
|
379
|
+
* with any value but `en`, cards and sets also carry `localized_name` (null
|
|
380
|
+
* where none is known), cards also carry `localized_image` (the scan in that
|
|
381
|
+
* edition, or null: show the English image), and `name` / `q` match names in
|
|
382
|
+
* that language too. `pl` is not accepted: no source has Polish card names.
|
|
343
383
|
*/
|
|
344
384
|
type CardLanguage = 'en' | 'de' | 'fr' | 'it' | 'es' | 'pt';
|
|
385
|
+
/**
|
|
386
|
+
* Card catalogue. `en` (English, the default), `ja` (Japanese: its own sets,
|
|
387
|
+
* numbering and printed names; ids are prefixed `ja-`), or `pl` (Polish:
|
|
388
|
+
* Diamond & Pearl, Mysterious Treasures, and promo Pikachu; ids are prefixed `pl-`).
|
|
389
|
+
* The API reserves further codes (`zh-tw`, `zh-cn`, `ko`, `th`) that answer
|
|
390
|
+
* 400 "not available yet"; they will be added here as they go live, and any
|
|
391
|
+
* string is accepted.
|
|
392
|
+
*/
|
|
393
|
+
type CardCatalog = 'en' | 'ja' | 'pl';
|
|
345
394
|
type CardListParams = {
|
|
346
395
|
name?: string;
|
|
347
396
|
q?: string;
|
|
@@ -352,8 +401,10 @@ type CardListParams = {
|
|
|
352
401
|
hp_gte?: number;
|
|
353
402
|
hp_lte?: number;
|
|
354
403
|
artist?: string;
|
|
355
|
-
/** Adds `localized_name` and searches names in that language too. Defaults to `en`. */
|
|
404
|
+
/** Adds `localized_name` and `localized_image`, and searches names in that language too. Defaults to `en`. */
|
|
356
405
|
lang?: CardLanguage;
|
|
406
|
+
/** Card catalogue; defaults to `en`. Lists, searches and rankings read one catalogue only. */
|
|
407
|
+
catalog?: CardCatalog;
|
|
357
408
|
page?: number;
|
|
358
409
|
/** Max 250. */
|
|
359
410
|
pageSize?: number;
|
|
@@ -365,16 +416,22 @@ type CardListParams = {
|
|
|
365
416
|
source?: CardPriceSource | CardPriceSource[];
|
|
366
417
|
};
|
|
367
418
|
type CardGetParams = {
|
|
419
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
420
|
+
catalog?: CardCatalog;
|
|
368
421
|
include?: CardInclude | CardInclude[];
|
|
369
422
|
source?: CardPriceSource | CardPriceSource[];
|
|
370
|
-
/** Adds `localized_name`. Defaults to `en`. */
|
|
423
|
+
/** Adds `localized_name` and `localized_image`. Defaults to `en`. */
|
|
371
424
|
lang?: CardLanguage;
|
|
372
425
|
};
|
|
373
426
|
type SetGetParams = {
|
|
427
|
+
/** Card catalogue; defaults to `en`. `sets.list` returns one catalogue's sets. */
|
|
428
|
+
catalog?: CardCatalog;
|
|
374
429
|
/** Adds `localized_name` to the set(s). Defaults to `en`. */
|
|
375
430
|
lang?: CardLanguage;
|
|
376
431
|
};
|
|
377
432
|
type CardPricesParams = {
|
|
433
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
434
|
+
catalog?: CardCatalog;
|
|
378
435
|
/** Price this print instead of the base card. */
|
|
379
436
|
variant_id?: string;
|
|
380
437
|
source?: CardPriceSource | CardPriceSource[];
|
|
@@ -384,9 +441,11 @@ type CardPriceHistoryParams = CardPricesParams & {
|
|
|
384
441
|
days?: number;
|
|
385
442
|
};
|
|
386
443
|
type SetCardsParams = {
|
|
444
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
445
|
+
catalog?: CardCatalog;
|
|
387
446
|
page?: number;
|
|
388
447
|
pageSize?: number;
|
|
389
|
-
/** Adds `localized_name` to every card. Defaults to `en`. */
|
|
448
|
+
/** Adds `localized_name` and `localized_image` to every card. Defaults to `en`. */
|
|
390
449
|
lang?: CardLanguage;
|
|
391
450
|
};
|
|
392
451
|
type SealedListParams = {
|
|
@@ -408,9 +467,13 @@ type BulkPricesParams = {
|
|
|
408
467
|
ids?: string[];
|
|
409
468
|
/** Print (variant) ids, up to 100. At least one of `ids`/`variants` is required. */
|
|
410
469
|
variants?: string[];
|
|
470
|
+
/** Catalogue to read; defaults to `en` when `ids` is absent. Each id is otherwise priced in its own catalogue. */
|
|
471
|
+
catalog?: CardCatalog;
|
|
411
472
|
source?: CardPriceSource | CardPriceSource[];
|
|
412
473
|
};
|
|
413
474
|
type RankingParams = {
|
|
475
|
+
/** Card catalogue; defaults to `en`. Rankings rank one catalogue only. */
|
|
476
|
+
catalog?: CardCatalog;
|
|
414
477
|
limit?: number;
|
|
415
478
|
offset?: number;
|
|
416
479
|
/** Narrow to one CardDex set id. */
|
|
@@ -425,11 +488,18 @@ type BargainsParams = RankingParams & {
|
|
|
425
488
|
minPrice?: number;
|
|
426
489
|
};
|
|
427
490
|
type PriceHistoryParams = {
|
|
491
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
492
|
+
catalog?: CardCatalog;
|
|
428
493
|
days?: number;
|
|
429
494
|
/** Print (variant) id; defaults to the base card. */
|
|
430
495
|
variant?: string;
|
|
431
496
|
source?: CardPriceSource | CardPriceSource[];
|
|
432
497
|
};
|
|
498
|
+
/** `GET /v1/cards/random` and `GET /v1/cards/rarities`. */
|
|
499
|
+
type CatalogParams = {
|
|
500
|
+
/** Card catalogue; defaults to `en`. */
|
|
501
|
+
catalog?: CardCatalog;
|
|
502
|
+
};
|
|
433
503
|
|
|
434
504
|
declare class CardsResource {
|
|
435
505
|
private readonly http;
|
|
@@ -446,8 +516,10 @@ declare class CardsResource {
|
|
|
446
516
|
* ```
|
|
447
517
|
*/
|
|
448
518
|
listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void>;
|
|
449
|
-
/** `GET /v1/cards/random` */
|
|
450
|
-
random(): Promise<CardWithRelations>;
|
|
519
|
+
/** `GET /v1/cards/random` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */
|
|
520
|
+
random(params?: CatalogParams): Promise<CardWithRelations>;
|
|
521
|
+
/** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */
|
|
522
|
+
rarities(params?: CatalogParams): Promise<string[]>;
|
|
451
523
|
/** `GET /v1/cards/{id}` */
|
|
452
524
|
get(id: string, params?: CardGetParams): Promise<CardWithRelations>;
|
|
453
525
|
/** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */
|
|
@@ -493,7 +565,7 @@ declare class SealedResource {
|
|
|
493
565
|
declare class SetsResource {
|
|
494
566
|
private readonly http;
|
|
495
567
|
constructor(http: HttpClient);
|
|
496
|
-
/** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
|
|
568
|
+
/** `GET /v1/sets` — every set of one catalogue (`catalog`, default `en`). `lang` adds `localized_name`. */
|
|
497
569
|
list(params?: SetGetParams): Promise<CardDexSet[]>;
|
|
498
570
|
/** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
|
|
499
571
|
get(id: string, params?: SetGetParams): Promise<CardDexSet>;
|
|
@@ -610,4 +682,4 @@ declare class CardDexError extends Error {
|
|
|
610
682
|
*/
|
|
611
683
|
declare function paginate<T>(fetchPage: (page: number) => Promise<PaginatedResponse<T>>, startPage?: number): AsyncGenerator<T, void, void>;
|
|
612
684
|
|
|
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 };
|
|
685
|
+
export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, type CardCatalog, 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 CatalogParams, type HealthResponse, type LocalizedCardImage, 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,9 @@ declare class HttpClient {
|
|
|
53
53
|
*/
|
|
54
54
|
interface CardDexSet {
|
|
55
55
|
id: string;
|
|
56
|
-
/**
|
|
56
|
+
/** `'ja'` or `'pl'` on non-English sets; absent on English sets. */
|
|
57
|
+
catalog?: 'ja' | 'pl' | (string & {});
|
|
58
|
+
/** The English name; for a Japanese set (`catalog: 'ja'`) or Polish set (`catalog: 'pl'`) the name printed on the set. */
|
|
57
59
|
name: string;
|
|
58
60
|
/** The name in the `lang` edition, or null where none is known. Only when `lang` is not `en`. */
|
|
59
61
|
localized_name?: string | null;
|
|
@@ -63,6 +65,7 @@ interface CardDexSet {
|
|
|
63
65
|
total_cards: number | null;
|
|
64
66
|
logo_url: string | null;
|
|
65
67
|
symbol_url: string | null;
|
|
68
|
+
/** The code printed on the set's cards (e.g. `sv2a` on a Japanese set); null for Polish sets or where there is none. */
|
|
66
69
|
set_code: string | null;
|
|
67
70
|
created_at: string;
|
|
68
71
|
updated_at: string;
|
|
@@ -102,11 +105,27 @@ interface CardImage {
|
|
|
102
105
|
small_url: string | null;
|
|
103
106
|
large_url: string | null;
|
|
104
107
|
}
|
|
105
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* A card's scan in the `lang` edition (de, fr, it, es, pt): `localized_image`.
|
|
110
|
+
* Each URL falls back to the next larger size, as the English ones do.
|
|
111
|
+
*/
|
|
112
|
+
interface LocalizedCardImage {
|
|
113
|
+
/** The `lang` of the request. */
|
|
114
|
+
language: string;
|
|
115
|
+
thumb_url: string | null;
|
|
116
|
+
small_url: string | null;
|
|
117
|
+
large_url: string | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* One price guide's currency and figures. `source` is `'cardmarket' | 'tcgplayer'`
|
|
121
|
+
* in practice; Japanese cards are priced by `'cardmarket'` (EUR).
|
|
122
|
+
*/
|
|
106
123
|
interface CardPrice {
|
|
107
124
|
id: number;
|
|
108
125
|
card_id: string;
|
|
109
126
|
card_name?: string | null;
|
|
127
|
+
/** Rankings with a non-English catalogue (`catalog=ja`, `catalog=pl`): the card's English name (`card_name` is the printed name). */
|
|
128
|
+
card_name_en?: string | null;
|
|
110
129
|
number?: string | null;
|
|
111
130
|
set_id?: string | null;
|
|
112
131
|
rarity?: string | null;
|
|
@@ -149,17 +168,37 @@ interface CardVariant {
|
|
|
149
168
|
}
|
|
150
169
|
interface Card {
|
|
151
170
|
id: string;
|
|
171
|
+
/** `'ja'` or `'pl'` on non-English cards; absent on English cards. */
|
|
172
|
+
catalog?: 'ja' | 'pl' | (string & {});
|
|
152
173
|
set_id: string;
|
|
153
|
-
/** The English name
|
|
174
|
+
/** The English name; for a Japanese card (`catalog: 'ja'`) or Polish card (`catalog: 'pl'`) the printed name. */
|
|
154
175
|
name: string;
|
|
176
|
+
/** A Japanese or Polish card's English name, or null where unknown. Absent on English cards. */
|
|
177
|
+
name_en?: string | null;
|
|
178
|
+
/** Polish cards only (absent on English and Japanese ones): the English twin card's id (e.g. `dp1-1` for `pl-dp1-1`), or null for cards without an English twin (`pl-promo-1`). */
|
|
179
|
+
english_id?: string | null;
|
|
155
180
|
/** The name in the `lang` edition (de, fr, it, es, pt), or null where none is known. Only when `lang` is not `en`. */
|
|
156
181
|
localized_name?: string | null;
|
|
182
|
+
/**
|
|
183
|
+
* The scan in the `lang` edition, or null when there is none (show the
|
|
184
|
+
* English image then). Only when `lang` is not `en`. The English image
|
|
185
|
+
* fields (`image_url`, `images`) never change with `lang`.
|
|
186
|
+
*/
|
|
187
|
+
localized_image?: LocalizedCardImage | null;
|
|
157
188
|
number: string;
|
|
158
189
|
supertype: string;
|
|
159
190
|
subtypes: string[] | null;
|
|
160
191
|
hp: number | null;
|
|
161
192
|
types: string[] | null;
|
|
162
193
|
rarity: string | null;
|
|
194
|
+
/**
|
|
195
|
+
* The finish of the card's own print, where the rarity does not say it:
|
|
196
|
+
* `holo` for a card only ever printed holo (e.g. the HGSS Black Star Promos,
|
|
197
|
+
* catalogued as Common). Present only when known; absent, never null, on
|
|
198
|
+
* every other card. A variant (`/v1/cards/{id}/variants`) still names its own
|
|
199
|
+
* print's finish; this describes the card when no variant is named.
|
|
200
|
+
*/
|
|
201
|
+
base_finish?: 'holo' | 'reverse' | 'normal';
|
|
163
202
|
artist: string | null;
|
|
164
203
|
regulation_mark: string | null;
|
|
165
204
|
flavor_text: string | null;
|
|
@@ -336,12 +375,22 @@ type CardInclude = 'attacks' | 'abilities' | 'weaknesses' | 'resistances' | 'ima
|
|
|
336
375
|
/** Every localized name of the card (`translations: CardTranslation[]`). Never a default. */
|
|
337
376
|
| 'translations';
|
|
338
377
|
/**
|
|
339
|
-
* Language edition for names. `name` is always the English name;
|
|
340
|
-
* value but `en`, cards and sets also carry `localized_name` (null
|
|
341
|
-
* is known),
|
|
342
|
-
*
|
|
378
|
+
* Language edition for names and scans. `name` is always the English name;
|
|
379
|
+
* with any value but `en`, cards and sets also carry `localized_name` (null
|
|
380
|
+
* where none is known), cards also carry `localized_image` (the scan in that
|
|
381
|
+
* edition, or null: show the English image), and `name` / `q` match names in
|
|
382
|
+
* that language too. `pl` is not accepted: no source has Polish card names.
|
|
343
383
|
*/
|
|
344
384
|
type CardLanguage = 'en' | 'de' | 'fr' | 'it' | 'es' | 'pt';
|
|
385
|
+
/**
|
|
386
|
+
* Card catalogue. `en` (English, the default), `ja` (Japanese: its own sets,
|
|
387
|
+
* numbering and printed names; ids are prefixed `ja-`), or `pl` (Polish:
|
|
388
|
+
* Diamond & Pearl, Mysterious Treasures, and promo Pikachu; ids are prefixed `pl-`).
|
|
389
|
+
* The API reserves further codes (`zh-tw`, `zh-cn`, `ko`, `th`) that answer
|
|
390
|
+
* 400 "not available yet"; they will be added here as they go live, and any
|
|
391
|
+
* string is accepted.
|
|
392
|
+
*/
|
|
393
|
+
type CardCatalog = 'en' | 'ja' | 'pl';
|
|
345
394
|
type CardListParams = {
|
|
346
395
|
name?: string;
|
|
347
396
|
q?: string;
|
|
@@ -352,8 +401,10 @@ type CardListParams = {
|
|
|
352
401
|
hp_gte?: number;
|
|
353
402
|
hp_lte?: number;
|
|
354
403
|
artist?: string;
|
|
355
|
-
/** Adds `localized_name` and searches names in that language too. Defaults to `en`. */
|
|
404
|
+
/** Adds `localized_name` and `localized_image`, and searches names in that language too. Defaults to `en`. */
|
|
356
405
|
lang?: CardLanguage;
|
|
406
|
+
/** Card catalogue; defaults to `en`. Lists, searches and rankings read one catalogue only. */
|
|
407
|
+
catalog?: CardCatalog;
|
|
357
408
|
page?: number;
|
|
358
409
|
/** Max 250. */
|
|
359
410
|
pageSize?: number;
|
|
@@ -365,16 +416,22 @@ type CardListParams = {
|
|
|
365
416
|
source?: CardPriceSource | CardPriceSource[];
|
|
366
417
|
};
|
|
367
418
|
type CardGetParams = {
|
|
419
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
420
|
+
catalog?: CardCatalog;
|
|
368
421
|
include?: CardInclude | CardInclude[];
|
|
369
422
|
source?: CardPriceSource | CardPriceSource[];
|
|
370
|
-
/** Adds `localized_name`. Defaults to `en`. */
|
|
423
|
+
/** Adds `localized_name` and `localized_image`. Defaults to `en`. */
|
|
371
424
|
lang?: CardLanguage;
|
|
372
425
|
};
|
|
373
426
|
type SetGetParams = {
|
|
427
|
+
/** Card catalogue; defaults to `en`. `sets.list` returns one catalogue's sets. */
|
|
428
|
+
catalog?: CardCatalog;
|
|
374
429
|
/** Adds `localized_name` to the set(s). Defaults to `en`. */
|
|
375
430
|
lang?: CardLanguage;
|
|
376
431
|
};
|
|
377
432
|
type CardPricesParams = {
|
|
433
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
434
|
+
catalog?: CardCatalog;
|
|
378
435
|
/** Price this print instead of the base card. */
|
|
379
436
|
variant_id?: string;
|
|
380
437
|
source?: CardPriceSource | CardPriceSource[];
|
|
@@ -384,9 +441,11 @@ type CardPriceHistoryParams = CardPricesParams & {
|
|
|
384
441
|
days?: number;
|
|
385
442
|
};
|
|
386
443
|
type SetCardsParams = {
|
|
444
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
445
|
+
catalog?: CardCatalog;
|
|
387
446
|
page?: number;
|
|
388
447
|
pageSize?: number;
|
|
389
|
-
/** Adds `localized_name` to every card. Defaults to `en`. */
|
|
448
|
+
/** Adds `localized_name` and `localized_image` to every card. Defaults to `en`. */
|
|
390
449
|
lang?: CardLanguage;
|
|
391
450
|
};
|
|
392
451
|
type SealedListParams = {
|
|
@@ -408,9 +467,13 @@ type BulkPricesParams = {
|
|
|
408
467
|
ids?: string[];
|
|
409
468
|
/** Print (variant) ids, up to 100. At least one of `ids`/`variants` is required. */
|
|
410
469
|
variants?: string[];
|
|
470
|
+
/** Catalogue to read; defaults to `en` when `ids` is absent. Each id is otherwise priced in its own catalogue. */
|
|
471
|
+
catalog?: CardCatalog;
|
|
411
472
|
source?: CardPriceSource | CardPriceSource[];
|
|
412
473
|
};
|
|
413
474
|
type RankingParams = {
|
|
475
|
+
/** Card catalogue; defaults to `en`. Rankings rank one catalogue only. */
|
|
476
|
+
catalog?: CardCatalog;
|
|
414
477
|
limit?: number;
|
|
415
478
|
offset?: number;
|
|
416
479
|
/** Narrow to one CardDex set id. */
|
|
@@ -425,11 +488,18 @@ type BargainsParams = RankingParams & {
|
|
|
425
488
|
minPrice?: number;
|
|
426
489
|
};
|
|
427
490
|
type PriceHistoryParams = {
|
|
491
|
+
/** Optional on keyed reads: the catalogue is inferred from the id (`ja-`, `pl-` prefix). An id of another catalogue answers as unknown. */
|
|
492
|
+
catalog?: CardCatalog;
|
|
428
493
|
days?: number;
|
|
429
494
|
/** Print (variant) id; defaults to the base card. */
|
|
430
495
|
variant?: string;
|
|
431
496
|
source?: CardPriceSource | CardPriceSource[];
|
|
432
497
|
};
|
|
498
|
+
/** `GET /v1/cards/random` and `GET /v1/cards/rarities`. */
|
|
499
|
+
type CatalogParams = {
|
|
500
|
+
/** Card catalogue; defaults to `en`. */
|
|
501
|
+
catalog?: CardCatalog;
|
|
502
|
+
};
|
|
433
503
|
|
|
434
504
|
declare class CardsResource {
|
|
435
505
|
private readonly http;
|
|
@@ -446,8 +516,10 @@ declare class CardsResource {
|
|
|
446
516
|
* ```
|
|
447
517
|
*/
|
|
448
518
|
listAll(params?: Omit<CardListParams, 'page'>): AsyncGenerator<Card, void, void>;
|
|
449
|
-
/** `GET /v1/cards/random` */
|
|
450
|
-
random(): Promise<CardWithRelations>;
|
|
519
|
+
/** `GET /v1/cards/random` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */
|
|
520
|
+
random(params?: CatalogParams): Promise<CardWithRelations>;
|
|
521
|
+
/** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */
|
|
522
|
+
rarities(params?: CatalogParams): Promise<string[]>;
|
|
451
523
|
/** `GET /v1/cards/{id}` */
|
|
452
524
|
get(id: string, params?: CardGetParams): Promise<CardWithRelations>;
|
|
453
525
|
/** `GET /v1/cards/{id}/prices` — the latest price row(s) for a card. */
|
|
@@ -493,7 +565,7 @@ declare class SealedResource {
|
|
|
493
565
|
declare class SetsResource {
|
|
494
566
|
private readonly http;
|
|
495
567
|
constructor(http: HttpClient);
|
|
496
|
-
/** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
|
|
568
|
+
/** `GET /v1/sets` — every set of one catalogue (`catalog`, default `en`). `lang` adds `localized_name`. */
|
|
497
569
|
list(params?: SetGetParams): Promise<CardDexSet[]>;
|
|
498
570
|
/** `GET /v1/sets/{id}` — `lang` adds `localized_name`. */
|
|
499
571
|
get(id: string, params?: SetGetParams): Promise<CardDexSet>;
|
|
@@ -610,4 +682,4 @@ declare class CardDexError extends Error {
|
|
|
610
682
|
*/
|
|
611
683
|
declare function paginate<T>(fetchPage: (page: number) => Promise<PaginatedResponse<T>>, startPage?: number): AsyncGenerator<T, void, void>;
|
|
612
684
|
|
|
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 };
|
|
685
|
+
export { type ApiErrorBody, type BargainCardPrice, type BargainsParams, type BulkPricesParams, type Card, type CardAbility, type CardAttack, type CardCatalog, 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 CatalogParams, type HealthResponse, type LocalizedCardImage, 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
|
@@ -213,9 +213,14 @@ var CardsResource = class {
|
|
|
213
213
|
listAll(params) {
|
|
214
214
|
return paginate((page) => this.list({ ...params, page }));
|
|
215
215
|
}
|
|
216
|
-
/** `GET /v1/cards/random` */
|
|
217
|
-
async random() {
|
|
218
|
-
const res = await this.http.get("/v1/cards/random");
|
|
216
|
+
/** `GET /v1/cards/random` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */
|
|
217
|
+
async random(params) {
|
|
218
|
+
const res = await this.http.get("/v1/cards/random", params);
|
|
219
|
+
return res.data;
|
|
220
|
+
}
|
|
221
|
+
/** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */
|
|
222
|
+
async rarities(params) {
|
|
223
|
+
const res = await this.http.get("/v1/cards/rarities", params);
|
|
219
224
|
return res.data;
|
|
220
225
|
}
|
|
221
226
|
/** `GET /v1/cards/{id}` */
|
|
@@ -328,7 +333,7 @@ var SetsResource = class {
|
|
|
328
333
|
this.http = http;
|
|
329
334
|
}
|
|
330
335
|
http;
|
|
331
|
-
/** `GET /v1/sets` — every set. `lang` adds `localized_name`. */
|
|
336
|
+
/** `GET /v1/sets` — every set of one catalogue (`catalog`, default `en`). `lang` adds `localized_name`. */
|
|
332
337
|
async list(params) {
|
|
333
338
|
const res = await this.http.get("/v1/sets", params);
|
|
334
339
|
return res.data;
|
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, 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":[]}
|
|
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 CatalogParams,\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` — `catalog: 'ja'` or `catalog: 'pl'` draws a card from that catalogue. */\n async random(params?: CatalogParams): Promise<CardWithRelations> {\n const res = await this.http.get<SingleResponse<CardWithRelations>>('/v1/cards/random', params);\n return res.data;\n }\n\n /** `GET /v1/cards/rarities` — every distinct rarity of one catalogue. */\n async rarities(params?: CatalogParams): Promise<string[]> {\n const res = await this.http.get<SingleResponse<string[]>>('/v1/cards/rarities', params);\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 of one catalogue (`catalog`, default `en`). `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;;;ACRO,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,OAAO,QAAoD;AAC/D,UAAM,MAAM,MAAM,KAAK,KAAK,IAAuC,oBAAoB,MAAM;AAC7F,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,SAAS,QAA2C;AACxD,UAAM,MAAM,MAAM,KAAK,KAAK,IAA8B,sBAAsB,MAAM;AACtF,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;;;AClEO,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":[]}
|