tcgpriser 0.7.0 → 0.10.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 +78 -47
- package/dist/index.cjs +34 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -52
- package/dist/index.d.ts +35 -52
- package/dist/index.js +34 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -68,16 +68,20 @@ await tcgpriser.products.matches('scarlet-violet-booster-pack');
|
|
|
68
68
|
|
|
69
69
|
### Expansions
|
|
70
70
|
|
|
71
|
+
Cards and sealed products are never merged into one response — fetch each separately.
|
|
72
|
+
|
|
71
73
|
```typescript
|
|
72
74
|
await tcgpriser.expansions.list();
|
|
73
|
-
await tcgpriser.expansions.
|
|
75
|
+
await tcgpriser.expansions.get('eng-scarlet-violet-journey-together'); // metadata only
|
|
76
|
+
await tcgpriser.expansions.cards('eng-scarlet-violet-journey-together'); // content only
|
|
77
|
+
await tcgpriser.expansions.sealedProducts('eng-scarlet-violet-journey-together'); // content only
|
|
74
78
|
```
|
|
75
79
|
|
|
76
80
|
### Pricing
|
|
77
81
|
|
|
78
|
-
`list()`/`get()`/`expansions.
|
|
79
|
-
expansion, rarity. Pricing (`retailPrice`, `estimatedValue`,
|
|
80
|
-
`referencePriceSnapshotsByProvider`) is a separate, shorter-cached call: content changes on an
|
|
82
|
+
`list()`/`get()`/`expansions.cards()`/`expansions.sealedProducts()` all return catalog content
|
|
83
|
+
only — name, images, brand, expansion, rarity. Pricing (`retailPrice`, `estimatedValue`,
|
|
84
|
+
`lowestShopOffer`, `referencePriceSnapshotsByProvider`) is a separate, shorter-cached call: content changes on an
|
|
81
85
|
admin edit or catalog import, pricing refreshes daily, so each is cached at the TTL its own
|
|
82
86
|
freshness supports.
|
|
83
87
|
|
|
@@ -117,33 +121,33 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
117
121
|
|
|
118
122
|
### `cards`
|
|
119
123
|
|
|
120
|
-
| Method | Description |
|
|
121
|
-
|
|
122
|
-
| `list(params)` | Search or list cards |
|
|
123
|
-
| `get(id)` | Fetch one card by id or technicalName |
|
|
124
|
-
| `matches(id, params)` | Current shop listings matched to this card |
|
|
125
|
-
| `prices(id, params)` 🔒 | Individual marketplace sale records |
|
|
126
|
-
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / eBay / Tradera price history |
|
|
127
|
-
| `livePricing(id)` 🔒 | Pricing computed fresh for this request |
|
|
124
|
+
| Method | Description | Credits |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `list(params)` | Search or list cards | — |
|
|
127
|
+
| `get(id)` | Fetch one card by id or technicalName | — |
|
|
128
|
+
| `matches(id, params)` | Current shop listings matched to this card | — |
|
|
129
|
+
| `prices(id, params)` 🔒 | Individual marketplace sale records | 2 |
|
|
130
|
+
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / eBay / Tradera price history | 2 |
|
|
131
|
+
| `livePricing(id)` 🔒 | Pricing computed fresh for this request | 3 |
|
|
128
132
|
|
|
129
133
|
### `products`
|
|
130
134
|
|
|
131
|
-
| Method | Description |
|
|
132
|
-
|
|
133
|
-
| `list(params)` | Search or list sealed products |
|
|
134
|
-
| `get(id)` | Fetch one product by id or technicalName |
|
|
135
|
-
| `matches(id, params)` | Current shop listings matched to this product |
|
|
136
|
-
| `prices(id, params)` 🔒 | Individual marketplace sale records |
|
|
137
|
-
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / Tradera price history |
|
|
138
|
-
| `livePricing(id)` 🔒 | Pricing computed fresh for this request |
|
|
135
|
+
| Method | Description | Credits |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| `list(params)` | Search or list sealed products | — |
|
|
138
|
+
| `get(id)` | Fetch one product by id or technicalName | — |
|
|
139
|
+
| `matches(id, params)` | Current shop listings matched to this product | — |
|
|
140
|
+
| `prices(id, params)` 🔒 | Individual marketplace sale records | 2 |
|
|
141
|
+
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / Tradera price history | 2 |
|
|
142
|
+
| `livePricing(id)` 🔒 | Pricing computed fresh for this request | 3 |
|
|
139
143
|
|
|
140
144
|
### `expansions`
|
|
141
145
|
|
|
142
|
-
| Method | Description |
|
|
143
|
-
|
|
144
|
-
| `list()` | Every expansion |
|
|
145
|
-
| `products(technicalName)` | Every card and sealed product in one expansion |
|
|
146
|
-
| `livePricing(technicalName)` 🔒 | Fresh pricing for every item in one expansion |
|
|
146
|
+
| Method | Description | Credits |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `list()` | Every expansion | — |
|
|
149
|
+
| `products(technicalName)` | Every card and sealed product in one expansion | — |
|
|
150
|
+
| `livePricing(technicalName)` 🔒 | Fresh pricing for every item in one expansion | 8 |
|
|
147
151
|
|
|
148
152
|
### `shops`
|
|
149
153
|
|
|
@@ -162,33 +166,33 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
162
166
|
|
|
163
167
|
### `shopMatchStats` 🔒
|
|
164
168
|
|
|
165
|
-
| Method | Description |
|
|
166
|
-
|
|
167
|
-
| `forProduct(id, params)` | One product's price history, broken out per shop |
|
|
168
|
-
| `forShop(shop, params)` | One shop's price history, broken out per product |
|
|
169
|
-
| `compare(params)` | One product's price at every shop that carries it |
|
|
169
|
+
| Method | Description | Credits |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| `forProduct(id, params)` | One product's price history, broken out per shop | 3 |
|
|
172
|
+
| `forShop(shop, params)` | One shop's price history, broken out per product | 3 |
|
|
173
|
+
| `compare(params)` | One product's price at every shop that carries it | 3 |
|
|
170
174
|
|
|
171
175
|
### `priceStats`
|
|
172
176
|
|
|
173
|
-
| Method | Description |
|
|
174
|
-
|
|
175
|
-
| `daily(params)` | Daily average price history |
|
|
176
|
-
| `estimatedValues(params)` | Current estimated market value |
|
|
177
|
-
| `topProducts(params)` | Items ranked by shop availability |
|
|
178
|
-
| `product(id)` 🔒 | Daily history, estimate and variant summary for one product |
|
|
179
|
-
| `productFull(id)` 🔒 | `product()` plus the item's current shop matches |
|
|
180
|
-
| `productDaily(id, params)` 🔒 | Daily history for one product, custom window |
|
|
181
|
-
| `productDailyLast30(id)` 🔒 | Daily history, fixed to the last 30 days |
|
|
182
|
-
| `productEstimatedValue(id)` 🔒 | Current estimated value only |
|
|
183
|
-
| `productByVariant(id, params)` 🔒 | Price stats per card condition/grade |
|
|
184
|
-
| `productDailyByVariant(id, params)` 🔒 | Daily history for one condition/grade |
|
|
177
|
+
| Method | Description | Credits |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `daily(params)` | Daily average price history | — |
|
|
180
|
+
| `estimatedValues(params)` | Current estimated market value | — |
|
|
181
|
+
| `topProducts(params)` | Items ranked by shop availability | — |
|
|
182
|
+
| `product(id)` 🔒 | Daily history, estimate and variant summary for one product | 2 |
|
|
183
|
+
| `productFull(id)` 🔒 | `product()` plus the item's current shop matches | 5 |
|
|
184
|
+
| `productDaily(id, params)` 🔒 | Daily history for one product, custom window | 1 |
|
|
185
|
+
| `productDailyLast30(id)` 🔒 | Daily history, fixed to the last 30 days | 1 |
|
|
186
|
+
| `productEstimatedValue(id)` 🔒 | Current estimated value only | 2 |
|
|
187
|
+
| `productByVariant(id, params)` 🔒 | Price stats per card condition/grade | 3 |
|
|
188
|
+
| `productDailyByVariant(id, params)` 🔒 | Daily history for one condition/grade | 1 |
|
|
185
189
|
|
|
186
190
|
### `bargains`
|
|
187
191
|
|
|
188
|
-
| Method | Description |
|
|
189
|
-
|
|
190
|
-
| `list(params)` | Current listings priced below their reference price |
|
|
191
|
-
| `search(params)` 🔒 | Same, with real pagination and filters |
|
|
192
|
+
| Method | Description | Credits |
|
|
193
|
+
|---|---|---|
|
|
194
|
+
| `list(params)` | Current listings priced below their reference price | — |
|
|
195
|
+
| `search(params)` 🔒 | Same, with real pagination and filters | 5 |
|
|
192
196
|
|
|
193
197
|
### `packRates`
|
|
194
198
|
|
|
@@ -210,7 +214,9 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
210
214
|
|---|---|
|
|
211
215
|
| `platform()` | Platform-wide overview counts |
|
|
212
216
|
|
|
213
|
-
🔒 = premium, needs an API token. See below.
|
|
217
|
+
🔒 = premium, needs an API token. See below. The Credits column applies only to methods that draw
|
|
218
|
+
from your weekly credit allowance when called with an API token. A session login (not available to
|
|
219
|
+
this client) and `shopUrls` are exempt. See [Credits](#credits).
|
|
214
220
|
|
|
215
221
|
## Authentication
|
|
216
222
|
|
|
@@ -242,6 +248,31 @@ try {
|
|
|
242
248
|
}
|
|
243
249
|
```
|
|
244
250
|
|
|
251
|
+
## Credits
|
|
252
|
+
|
|
253
|
+
Methods marked with a credit count in the tables above draw from your account's weekly credit
|
|
254
|
+
allowance when called with an API token (Premium: 1500/week, Business: 6000/week, both reset Monday
|
|
255
|
+
00:00 UTC). Cost is weighted by how much work the call does server-side: a cached single-item lookup
|
|
256
|
+
costs less than a whole-expansion recompute. `expansions.livePricing` is the most expensive call in
|
|
257
|
+
the API at 8 credits, since it recomputes pricing for every card or product in the set.
|
|
258
|
+
|
|
259
|
+
Once the week's credits run out, further calls reject with `429 creditsExhausted`, surfaced the same
|
|
260
|
+
way as any other error:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
try {
|
|
264
|
+
await tcgpriser.cards.livePricing('fezandipiti-ex');
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (error instanceof TcgPriserError && error.code === 'creditsExhausted') {
|
|
267
|
+
console.log('Out of credits for this week:', error.message);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
This client doesn't currently surface the `X-Credits-Remaining` response header. To track your
|
|
273
|
+
remaining balance mid-week, read it off the raw HTTP response yourself outside this SDK, or poll
|
|
274
|
+
`GET /subscription` on the main API.
|
|
275
|
+
|
|
245
276
|
## Options
|
|
246
277
|
|
|
247
278
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,8 @@ var KNOWN_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
44
44
|
"readOnlyField",
|
|
45
45
|
"rateLimited",
|
|
46
46
|
"premiumRequired",
|
|
47
|
+
"businessRequired",
|
|
48
|
+
"creditsExhausted",
|
|
47
49
|
"internalError"
|
|
48
50
|
]);
|
|
49
51
|
async function toApiError(res, url) {
|
|
@@ -197,17 +199,38 @@ var ExpansionsResource = class {
|
|
|
197
199
|
const res = await this.http.get("/expansions");
|
|
198
200
|
return res.data;
|
|
199
201
|
}
|
|
200
|
-
/** `GET /expansions/{technicalName}
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
*
|
|
210
|
-
|
|
202
|
+
/** `GET /expansions/{technicalName}`: metadata only — no cards or sealed products. Returns the
|
|
203
|
+
* smaller `ExpansionRef`, not the full `Expansion`: this is a plain lookup by technicalName, not
|
|
204
|
+
* the aggregation `list()` runs, so `sealedCount`/`cardCount`/`productCount` aren't available
|
|
205
|
+
* here. See `cards()` and `sealedProducts()` for this expansion's contents. */
|
|
206
|
+
get(technicalName) {
|
|
207
|
+
return this.http.get(`/expansions/${encodeURIComponent(technicalName)}`);
|
|
208
|
+
}
|
|
209
|
+
/** `GET /expansions/{technicalName}/cards`: every card in this expansion. Content only, no
|
|
210
|
+
* pricing fields — pass the `id`s from the result to `client.cards.pricingBatch()` if you need
|
|
211
|
+
* pricing too. Sealed products are a separate call — see `sealedProducts()` — never merged into
|
|
212
|
+
* this one. */
|
|
213
|
+
cards(technicalName) {
|
|
214
|
+
return this.http.get(`/expansions/${encodeURIComponent(technicalName)}/cards`);
|
|
215
|
+
}
|
|
216
|
+
/** `GET /expansions/{technicalName}/products`: every sealed product in this expansion. Content
|
|
217
|
+
* only, no pricing fields — pass the `id`s from the result to `client.products.pricingBatch()`
|
|
218
|
+
* if you need pricing too. Cards are a separate call — see `cards()` — never merged into this
|
|
219
|
+
* one. */
|
|
220
|
+
sealedProducts(technicalName) {
|
|
221
|
+
return this.http.get(`/expansions/${encodeURIComponent(technicalName)}/products`);
|
|
222
|
+
}
|
|
223
|
+
/** `GET /expansions/{technicalName}/cards/live-pricing`: computed fresh for every card in this
|
|
224
|
+
* expansion, not read from the last stats job. Premium. */
|
|
225
|
+
cardsLivePricing(technicalName, options = {}) {
|
|
226
|
+
return this.http.get(
|
|
227
|
+
`/expansions/${encodeURIComponent(technicalName)}/cards/live-pricing`,
|
|
228
|
+
options
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
/** `GET /expansions/{technicalName}/products/live-pricing`: computed fresh for every sealed
|
|
232
|
+
* product in this expansion, not read from the last stats job. Premium. */
|
|
233
|
+
productsLivePricing(technicalName, options = {}) {
|
|
211
234
|
return this.http.get(
|
|
212
235
|
`/expansions/${encodeURIComponent(technicalName)}/products/live-pricing`,
|
|
213
236
|
options
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/bargains.ts","../src/resources/cards.ts","../src/resources/expansions.ts","../src/resources/packRates.ts","../src/resources/priceStats.ts","../src/resources/products.ts","../src/resources/shopMatchStats.ts","../src/resources/shopMatches.ts","../src/resources/shopUrls.ts","../src/resources/shops.ts","../src/resources/stats.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/** The stable error codes the API's `error.code` field can hold. */\nexport type TcgPriserErrorCode =\n | 'validationFailed'\n | 'unauthorized'\n | 'forbidden'\n | 'notFound'\n | 'conflict'\n | 'readOnlyField'\n | 'rateLimited'\n | 'premiumRequired'\n | 'internalError'\n /** Response body wasn't the `{ error: { code, message } }` shape. Probably a proxy or gateway\n * error in front of the API. */\n | 'unknown';\n\n/** Thrown for any non-2xx response. Carries the parsed `{ code, message }` when the body matched\n * the API's error envelope, plus the raw status/body regardless so nothing gets lost. */\nexport class TcgPriserError extends Error {\n readonly statusCode: number;\n readonly statusText: string;\n readonly url: string;\n readonly code: TcgPriserErrorCode;\n readonly details: unknown;\n /** The raw response body, for debugging when `code`/`details` don't cover what you need. */\n readonly body: string;\n\n constructor(params: {\n statusCode: number;\n statusText: string;\n url: string;\n code: TcgPriserErrorCode;\n message: string;\n details?: unknown;\n body: string;\n }) {\n super(`tcgpriser: ${params.statusCode} ${params.code} - ${params.message} (${params.url})`);\n this.name = 'TcgPriserError';\n this.statusCode = params.statusCode;\n this.statusText = params.statusText;\n this.url = params.url;\n this.code = params.code;\n this.details = params.details;\n this.body = params.body;\n }\n}\n","import { TcgPriserError, type TcgPriserErrorCode } from './errors.js';\n\nexport type QueryValue = string | number | boolean | undefined | null;\n\n/**\n * Builds a query string from a params object, dropping `undefined`/`null` entries so callers can\n * pass params straight through without filtering first.\n *\n * Takes a generic `object` instead of `Record<string, QueryValue>` on purpose. The params\n * interfaces (`ListCardsParams` etc.) intentionally have no index signature, otherwise any string\n * key would type-check.\n */\nexport function toQueryString<T extends object>(params: T): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params) as [string, QueryValue][]) {\n if (value === undefined || value === null) continue;\n search.set(key, String(value));\n }\n const query = search.toString();\n return query ? `?${query}` : '';\n}\n\n/** Splits `authToken` off a params object so it goes on the `Authorization` header, not through\n * `toQueryString`. A bearer token has no business in a URL: query strings end up in server logs,\n * browser history, `Referer` headers. */\nexport function splitAuthToken<T extends { authToken?: string }>(\n params: T,\n): [Omit<T, 'authToken'>, string | undefined] {\n const { authToken, ...rest } = params;\n return [rest, authToken];\n}\n\nconst KNOWN_ERROR_CODES: ReadonlySet<string> = new Set([\n 'validationFailed',\n 'unauthorized',\n 'forbidden',\n 'notFound',\n 'conflict',\n 'readOnlyField',\n 'rateLimited',\n 'premiumRequired',\n 'internalError',\n]);\n\nasync function toApiError(res: Response, url: string): Promise<TcgPriserError> {\n const body = await res.text();\n let code: TcgPriserErrorCode = 'unknown';\n let message = res.statusText || 'Request failed';\n let details: unknown;\n\n try {\n const parsed = JSON.parse(body) as { error?: { code?: string; message?: string; details?: unknown } };\n if (parsed.error?.code && KNOWN_ERROR_CODES.has(parsed.error.code)) {\n code = parsed.error.code as TcgPriserErrorCode;\n }\n if (parsed.error?.message) message = parsed.error.message;\n details = parsed.error?.details;\n } catch {\n // Not the standard error envelope, maybe a proxy's HTML error page. Fall back to the status\n // text and leave `body` for anyone who wants to dig in.\n }\n\n return new TcgPriserError({ statusCode: res.status, statusText: res.statusText, url, code, message, details, body });\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch: typeof fetch;\n headers?: Record<string, string>;\n /** Default bearer token for premium endpoints, used when a call doesn't pass its own `authToken`. */\n authToken?: string;\n}\n\n/** Per-call auth override for a premium endpoint, on top of the client's default `authToken`.\n * Every premium method takes one of these, either standalone or merged into its params object via\n * `splitAuthToken`. */\nexport interface PremiumOptions {\n /** Overrides the client's default `authToken` for this call. Pass `undefined` explicitly to\n * force an anonymous request even when the client has a default token. */\n authToken?: string;\n}\n\n/** Thin wrapper around `fetch`: joins the base URL, adds default headers, turns non-2xx responses\n * into a `TcgPriserError`. Every resource method goes through this instead of calling `fetch`\n * directly. */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly defaultAuthToken: string | undefined;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch;\n this.defaultHeaders = options.headers ?? {};\n this.defaultAuthToken = options.authToken;\n }\n\n get<T>(path: string, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('GET', path, undefined, requestOptions);\n }\n\n post<T>(path: string, body: unknown, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('POST', path, body, requestOptions);\n }\n\n patch<T>(path: string, body: unknown, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('PATCH', path, body, requestOptions);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n requestOptions?: PremiumOptions,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const authToken = requestOptions && 'authToken' in requestOptions ? requestOptions.authToken : this.defaultAuthToken;\n\n const headers: Record<string, string> = { Accept: 'application/json', ...this.defaultHeaders };\n if (authToken) headers.Authorization = `Bearer ${authToken}`;\n if (body !== undefined) headers['Content-Type'] = 'application/json';\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n\n if (!res.ok) throw await toApiError(res, url);\n if (res.status === 204) return undefined as T;\n return nullsToUndefined(await res.json()) as T;\n }\n}\n\n/** JSON has no `undefined`, so every optional field the API omits comes back over the wire as\n * `null`. Recurses through the parsed response and turns those into `undefined` so callers work\n * with idiomatic `foo?.bar` / `foo ?? fallback` instead of `foo !== null`, and so responses match\n * the `T | undefined` types in `generated/openapi.d.ts` (see `scripts/generate-types.mjs`). */\nfunction nullsToUndefined<T>(value: T): T {\n if (value === null) return undefined as T;\n if (Array.isArray(value)) return value.map(nullsToUndefined) as T;\n if (typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) result[key] = nullsToUndefined(v);\n return result as T;\n }\n return value;\n}\n","import type { HttpClient } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n Bargain,\n BargainReferenceSource,\n CardType,\n GradingCompany,\n ItemCondition,\n ListResponse,\n PaginationParams,\n} from '../types/index.js';\n\nexport interface ListBargainsParams {\n type?: 'sealed' | 'card' | 'all';\n}\n\nexport interface SearchBargainsParams extends PaginationParams {\n authToken?: string;\n type?: 'sealed' | 'card' | 'all';\n /** Filter by shop technicalName. */\n shop?: string;\n /** Filter by which reference price source qualified the bargain. */\n referenceSource?: BargainReferenceSource;\n /** Minimum discount percentage. Default 10. */\n minDiscount?: number;\n /** Default `true`. */\n inStock?: boolean;\n cardType?: CardType;\n itemCondition?: ItemCondition;\n gradingCompany?: GradingCompany;\n grade?: number;\n /** Free-text search on product name / technicalName. */\n search?: string;\n}\n\nexport class BargainsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /bargains`: current shop listings priced notably below their reference price. Result\n * count is fixed by the API (no `limit`/`skip` on the public tier); `pagination.hasMore` tells\n * you if more exist. */\n list(params: ListBargainsParams = {}): Promise<ListResponse<Bargain>> {\n return this.http.get(`/bargains${toQueryString(params)}`);\n }\n\n /** `GET /bargains/search`: like `list()`, but with real pagination and filters (shop, discount\n * threshold, card condition/grade, free-text search). Premium. */\n search(params: SearchBargainsParams = {}): Promise<ListResponse<Bargain>> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/bargains/search${toQueryString(query)}`, { authToken });\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n Card,\n CardType,\n CatalogItemPricing,\n ItemReferencePrices,\n ItemShopMatches,\n ItemSoldPrices,\n ListResponse,\n LivePricingForItem,\n PaginationParams,\n ReferencePriceCardVariant,\n ReferencePriceProvider,\n} from '../types/index.js';\n\nexport interface ListCardsParams extends PaginationParams {\n /** Free-text search over card and set names. */\n search?: string;\n}\n\nexport interface CardMatchesParams extends PaginationParams {\n /** Keep only matches whose shop currently has stock. */\n inStock?: boolean;\n}\n\nexport interface CardReferencePricesParams {\n /** Bearer token for this call. Overrides the client's default `authToken`. */\n authToken?: string;\n /** Rolling window ending today, in days. Ignored when `from`/`to` are supplied. Default 90. */\n days?: number;\n /** `YYYY-MM-DD` */\n from?: string;\n /** `YYYY-MM-DD` */\n to?: string;\n provider?: ReferencePriceProvider;\n cardType?: CardType;\n variant?: ReferencePriceCardVariant;\n}\n\nexport interface CardPricesParams extends PaginationParams {\n authToken?: string;\n}\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /cards`: search or list cards. */\n list(params: ListCardsParams = {}): Promise<ListResponse<Card>> {\n return this.http.get(`/cards${toQueryString(params)}`);\n }\n\n /** `GET /cards/{id}`: fetch one card by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<Card> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}`);\n }\n\n /** `GET /cards/{id}/matches`: current shop listings matched to this card (latest per shop). */\n matches(idOrTechnicalName: string, params: CardMatchesParams = {}): Promise<ItemShopMatches> {\n return this.http.get(\n `/cards/${encodeURIComponent(idOrTechnicalName)}/matches${toQueryString(params)}`,\n );\n }\n\n /** `GET /cards/{id}/reference-prices`: Cardmarket/TCGplayer/eBay/Tradera price history. Premium. */\n referencePrices(\n idOrTechnicalName: string,\n params: CardReferencePricesParams = {},\n ): Promise<ItemReferencePrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/cards/${encodeURIComponent(idOrTechnicalName)}/reference-prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /cards/{id}/prices`: individual marketplace sale records. Premium. */\n prices(idOrTechnicalName: string, params: CardPricesParams = {}): Promise<ItemSoldPrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/prices${toQueryString(query)}`, {\n authToken,\n });\n }\n\n /** `GET /cards/{id}/pricing/live`: computed fresh for this request, not read from the last\n * stats job. Premium. */\n livePricing(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<LivePricingForItem> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);\n }\n\n /** `GET /cards/{id}/pricing`: this card's current pricing snapshot — `retailPrice`,\n * `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day\n * by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,\n * shorter-cached call for the part of a card that actually changes day to day. */\n pricing(idOrTechnicalName: string): Promise<CatalogItemPricing> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing`);\n }\n\n /** `GET /cards/pricing`: pricing for up to 200 cards in one request, keyed by `id` — the batch\n * counterpart to `pricing()`, for a page of results (a search page, an expansion's contents) that\n * needs pricing for many items at once. Unlike `get()`/`pricing()`, this only accepts `id`s, not\n * technicalNames — pass the `id`s already on the cards you fetched. Ids with no match are\n * silently omitted from the result rather than causing an error. */\n pricingBatch(ids: string[]): Promise<ListResponse<CatalogItemPricing>> {\n return this.http.get(`/cards/pricing?ids=${ids.map(encodeURIComponent).join(',')}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport type { Expansion, ExpansionContents, ExpansionLivePricing } from '../types/index.js';\n\nexport class ExpansionsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /expansions`: every expansion. Unwrapped to a plain array, nothing to paginate here. */\n async list(): Promise<Expansion[]> {\n const res = await this.http.get<{ data: Expansion[] }>('/expansions');\n return res.data;\n }\n\n /** `GET /expansions/{technicalName}/products`: every card and sealed product in one\n * expansion, kept as separate `cards`/`sealed` groups. Content only, no pricing fields — pass the\n * `id`s from the result to `client.cards.pricingBatch()` / `client.products.pricingBatch()` if you\n * need pricing too. This mirrors the API 1:1 rather than fetching pricing for you, since pricing\n * for every item in an expansion is a second, separately-cached call the caller may not want. */\n products(technicalName: string): Promise<ExpansionContents> {\n return this.http.get(`/expansions/${encodeURIComponent(technicalName)}/products?grouped=true`);\n }\n\n /** `GET /expansions/{technicalName}/products/live-pricing`: computed fresh for every item in\n * this expansion, not read from the last stats job. Premium. */\n livePricing(technicalName: string, options: PremiumOptions = {}): Promise<ExpansionLivePricing> {\n return this.http.get(\n `/expansions/${encodeURIComponent(technicalName)}/products/live-pricing`,\n options,\n );\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { PackRate } from '../types/index.js';\n\nexport class PackRatesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /pack-rates`: pull-rate odds for every expansion that has them. Unwrapped to a plain\n * array, nothing to paginate here. */\n async list(): Promise<PackRate[]> {\n const res = await this.http.get<{ data: PackRate[] }>('/pack-rates');\n return res.data;\n }\n\n /** `GET /pack-rates/{expansionId}`: pull-rate odds for one expansion. */\n get(expansionId: string): Promise<PackRate> {\n return this.http.get(`/pack-rates/${encodeURIComponent(expansionId)}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n CardType,\n GradingCompany,\n ItemCondition,\n ItemDailyStats,\n ItemEstimatedValue,\n ItemFullStats,\n ItemStats,\n ItemVariantDailyStats,\n ItemVariantStats,\n ListResponse,\n TopItem,\n} from '../types/index.js';\n\n/** Filters shared by `daily()` and `estimatedValues()`: all narrow which product(s) the stats\n * cover; combine as many as you like. */\nexport interface ProductFilterParams {\n productName?: string;\n technicalName?: string;\n priceChartingId?: string;\n modelNumber?: string;\n /** Category technicalName. */\n category?: string;\n /** Expansion technicalName. */\n expansion?: string;\n}\n\nexport interface DailyPriceStatsParams extends ProductFilterParams {\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Expansion id (ObjectId), an alternative to `expansion` (technicalName). */\n expansionId?: string;\n /** Category id (ObjectId), an alternative to `category` (technicalName). */\n categoryId?: string;\n}\n\nexport interface EstimatedValuesParams extends ProductFilterParams {\n page?: number;\n limit?: number;\n}\n\nexport interface TopProductsParams {\n limit?: number;\n}\n\nexport interface ProductDailyStatsParams {\n authToken?: string;\n /** Number of days to retrieve, from today backwards. Default 30. */\n days?: number;\n}\n\nexport interface ProductByVariantParams {\n authToken?: string;\n /** Number of days to include in the average calculation. Default 30. */\n days?: number;\n}\n\nexport interface ProductDailyByVariantParams {\n authToken?: string;\n cardType: CardType;\n /** Required when `cardType` is `'loose'`. */\n condition?: ItemCondition;\n /** Required when `cardType` is `'graded'`. */\n gradingCompany?: GradingCompany;\n /** Required when `cardType` is `'graded'`. */\n grade?: number;\n /** Number of days to retrieve. Default 30. */\n days?: number;\n}\n\nexport class PriceStatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /price-stats/daily`: daily average price history, filtered to matching product(s). */\n daily(params: DailyPriceStatsParams = {}): Promise<ListResponse<ItemDailyStats>> {\n return this.http.get(`/price-stats/daily${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/estimated-values`: current estimated market value, filtered to matching\n * product(s). */\n estimatedValues(params: EstimatedValuesParams = {}): Promise<ListResponse<ItemEstimatedValue>> {\n return this.http.get(`/price-stats/estimated-values${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/top-products`: items ranked by shop availability (how many shops carry\n * them), not by price. */\n topProducts(params: TopProductsParams = {}): Promise<ListResponse<TopItem>> {\n return this.http.get(`/price-stats/top-products${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/product/{id}`: daily price history, current estimate, and a variant-count\n * summary for one product. Premium. */\n product(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemStats> {\n return this.http.get(`/price-stats/product/${encodeURIComponent(idOrTechnicalName)}`, options);\n }\n\n /** `GET /price-stats/product/{id}/full`: everything `product()` has, plus the item's current\n * shop matches. Premium. */\n productFull(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemFullStats> {\n return this.http.get(`/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/full`, options);\n }\n\n /** `GET /price-stats/product/{id}/daily`: daily price history for one product, with a\n * caller-chosen window. Premium. */\n productDaily(\n idOrTechnicalName: string,\n params: ProductDailyStatsParams = {},\n ): Promise<ItemDailyStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /price-stats/product/{id}/daily-last-30`: daily price history for the last 30 days\n * exactly (no window param, for callers that want a stable cache key). Premium. */\n productDailyLast30(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemDailyStats> {\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily-last-30`,\n options,\n );\n }\n\n /** `GET /price-stats/product/{id}/estimated-value`: current estimated value only. Premium. */\n productEstimatedValue(\n idOrTechnicalName: string,\n options: PremiumOptions = {},\n ): Promise<ItemEstimatedValue> {\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/estimated-value`,\n options,\n );\n }\n\n /** `GET /price-stats/product/{id}/by-variant`: price stats broken out per card condition/grade.\n * Premium. */\n productByVariant(\n idOrTechnicalName: string,\n params: ProductByVariantParams = {},\n ): Promise<ItemVariantStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/by-variant${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /price-stats/product/{id}/daily-by-variant`: daily price history for one specific\n * condition/grade. `condition` is required for `cardType: 'loose'`; `gradingCompany` and `grade`\n * are required for `cardType: 'graded'`. Premium. */\n productDailyByVariant(\n idOrTechnicalName: string,\n params: ProductDailyByVariantParams,\n ): Promise<ItemVariantDailyStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily-by-variant${toQueryString(query)}`,\n { authToken },\n );\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n CardType,\n CatalogItemPricing,\n GradingCompany,\n ItemCondition,\n ItemReferencePrices,\n ItemShopMatches,\n ItemSoldPrices,\n ListResponse,\n LivePricingForItem,\n PaginationParams,\n ReferencePriceProvider,\n SealedProduct,\n} from '../types/index.js';\n\nexport interface ListProductsParams extends PaginationParams {\n /** Whitespace-separated tokens, each matched against the start of a word. */\n search?: string;\n}\n\nexport interface ProductMatchesParams extends PaginationParams {\n /** Keep only matches whose shop currently has stock. */\n inStock?: boolean;\n cardType?: CardType;\n condition?: ItemCondition;\n gradingCompany?: GradingCompany;\n grade?: number;\n}\n\nexport interface ProductReferencePricesParams {\n authToken?: string;\n /** Rolling window ending today, in days. Ignored when `from`/`to` are supplied. Default 90. */\n days?: number;\n /** `YYYY-MM-DD` */\n from?: string;\n /** `YYYY-MM-DD` */\n to?: string;\n provider?: ReferencePriceProvider;\n}\n\nexport interface ProductPricesParams extends PaginationParams {\n authToken?: string;\n}\n\n/** Sealed products: booster boxes, ETBs, tins, and the like. Single cards live under\n * `client.cards` instead. */\nexport class ProductsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /product`: search or list sealed products. */\n list(params: ListProductsParams = {}): Promise<ListResponse<SealedProduct>> {\n return this.http.get(`/product${toQueryString(params)}`);\n }\n\n /** `GET /product/{id}`: fetch one sealed product by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<SealedProduct> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}`);\n }\n\n /** `GET /product/{id}/matches`: current shop listings matched to this product (latest per shop). */\n matches(idOrTechnicalName: string, params: ProductMatchesParams = {}): Promise<ItemShopMatches> {\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/matches${toQueryString(params)}`,\n );\n }\n\n /** `GET /product/{id}/reference-prices`: Cardmarket/TCGplayer/Tradera price history. Premium. */\n referencePrices(\n idOrTechnicalName: string,\n params: ProductReferencePricesParams = {},\n ): Promise<ItemReferencePrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/reference-prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /product/{id}/prices`: individual marketplace sale records. Premium. */\n prices(idOrTechnicalName: string, params: ProductPricesParams = {}): Promise<ItemSoldPrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /product/{id}/pricing/live`: computed fresh for this request, not read from the last\n * stats job. Premium. */\n livePricing(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<LivePricingForItem> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);\n }\n\n /** `GET /product/{id}/pricing`: this product's current pricing snapshot — `retailPrice`,\n * `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day\n * by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,\n * shorter-cached call for the part of a product that actually changes day to day. */\n pricing(idOrTechnicalName: string): Promise<CatalogItemPricing> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing`);\n }\n\n /** `GET /product/pricing`: pricing for up to 200 sealed products in one request, keyed by `id` —\n * the batch counterpart to `pricing()`, for a page of results (a search page, an expansion's\n * contents) that needs pricing for many items at once. Unlike `get()`/`pricing()`, this only\n * accepts `id`s, not technicalNames — pass the `id`s already on the products you fetched. Ids with\n * no match are silently omitted from the result rather than causing an error. */\n pricingBatch(ids: string[]): Promise<ListResponse<CatalogItemPricing>> {\n return this.http.get(`/product/pricing?ids=${ids.map(encodeURIComponent).join(',')}`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type { ItemPriceComparison, ItemShopPriceHistory, ShopPriceHistoryList } from '../types/index.js';\n\nexport interface ShopMatchStatsForProductParams {\n authToken?: string;\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Filter to one shop's technicalName. */\n shop?: string;\n}\n\nexport interface ShopMatchStatsForShopParams {\n authToken?: string;\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Maximum products to return. Default 100. */\n limit?: number;\n}\n\nexport interface CompareShopPricesParams {\n authToken?: string;\n /** Product/card id or technicalName. */\n productId: string;\n /** `YYYY-MM-DD`: defaults to the latest date with data. */\n date?: string;\n}\n\n/** Historical shop-vs-price data, distinct from `client.shopMatches` (which is the current/latest\n * match state). Everything here is premium. */\nexport class ShopMatchStatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shop-match-stats/product/{productId}`: one product's price history, broken out per shop. */\n forProduct(\n productId: string,\n params: ShopMatchStatsForProductParams = {},\n ): Promise<ItemShopPriceHistory> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/shop-match-stats/product/${encodeURIComponent(productId)}${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /shop-match-stats/shop/{shop}`: one shop's price history, broken out per product. */\n forShop(shop: string, params: ShopMatchStatsForShopParams = {}): Promise<ShopPriceHistoryList> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/shop-match-stats/shop/${encodeURIComponent(shop)}${toQueryString(query)}`, {\n authToken,\n });\n }\n\n /** `GET /shop-match-stats/compare`: one product's price at every shop that carries it, as of\n * one date (defaults to the latest). */\n compare(params: CompareShopPricesParams): Promise<ItemPriceComparison> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/shop-match-stats/compare${toQueryString(query)}`, { authToken });\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { toQueryString } from '../http.js';\nimport type { ListResponse, PaginationParams, ShopMatch, ShopMatchesForShop, ShopMatchStats } from '../types/index.js';\n\nexport interface ListShopMatchesParams extends PaginationParams {\n /** Filter to one shop's technicalName. */\n shop?: string;\n inStock?: boolean;\n /** Filter by whether the listing has been resolved to a catalog item. */\n linked?: boolean;\n}\n\nexport interface ShopMatchesForShopParams extends PaginationParams {\n inStock?: boolean;\n}\n\n/** Raw shop-to-catalog match data: what's currently listed where, independent of which item or\n * shop you start from. For \"what does this card cost at each shop\" or \"what's in stock at this\n * shop\", prefer `client.cards.matches()` / `client.products.matches()` /\n * `client.shopMatches.forShop()`. */\nexport class ShopMatchesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shop-matches`: every current match across every shop (latest record per url+shop). */\n list(params: ListShopMatchesParams = {}): Promise<ListResponse<ShopMatch>> {\n return this.http.get(`/shop-matches${toQueryString(params)}`);\n }\n\n /** `GET /shop-matches/{shop}`: every current match at one shop (latest record per url). */\n forShop(technicalName: string, params: ShopMatchesForShopParams = {}): Promise<ShopMatchesForShop> {\n return this.http.get(`/shop-matches/${encodeURIComponent(technicalName)}${toQueryString(params)}`);\n }\n\n /** `GET /shop-matches/shops`: match counts per shop (based on latest records only). */\n shopStats(params: PaginationParams = {}): Promise<ListResponse<ShopMatchStats>> {\n return this.http.get(`/shop-matches/shops${toQueryString(params)}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport type { ShopUrlMutationResult } from '../types/index.js';\n\nexport interface SubmitShopUrlParams extends PremiumOptions {\n url: string;\n /** Shop technicalName. Auto-created if it doesn't exist yet. */\n shop: string;\n}\n\nexport interface AssignShopUrlProductParams extends PremiumOptions {\n /** Product/card id to link, or `null` to unlink and let auto-matching resume. */\n productId: string | null;\n}\n\n/** Lets a signed-in subscriber contribute to the catalog: submit a shop URL for scraping, or\n * manually correct which product/card a URL resolves to. Both premium, both mutating. */\nexport class ShopUrlsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `POST /shop-urls/submit`: submit a shop URL for scraping. */\n submit(params: SubmitShopUrlParams): Promise<ShopUrlMutationResult> {\n const { authToken, url, shop } = params;\n return this.http.post('/shop-urls/submit', { url, shop }, { authToken });\n }\n\n /** `PATCH /shop-urls/{id}/product`: manually assign (or clear) the product a shop URL resolves to. */\n assignProduct(\n shopUrlId: string,\n params: AssignShopUrlProductParams,\n ): Promise<ShopUrlMutationResult> {\n const { authToken, productId } = params;\n return this.http.patch(\n `/shop-urls/${encodeURIComponent(shopUrlId)}/product`,\n { productId },\n { authToken },\n );\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { toQueryString } from '../http.js';\nimport type { Shop } from '../types/index.js';\n\nexport interface ListShopsParams {\n active?: boolean;\n}\n\nexport class ShopsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shops`: every tracked shop. Unwrapped to a plain array, nothing to paginate here. */\n async list(params: ListShopsParams = {}): Promise<Shop[]> {\n const res = await this.http.get<{ data: Shop[] }>(`/shops${toQueryString(params)}`);\n return res.data;\n }\n\n /** `GET /shops/{id}`: fetch one shop by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<Shop> {\n return this.http.get(`/shops/${encodeURIComponent(idOrTechnicalName)}`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { PlatformStats } from '../types/index.js';\n\nexport class StatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /stats`: platform-wide overview counts (shops, expansions, products, prices tracked). */\n platform(): Promise<PlatformStats> {\n return this.http.get('/stats');\n }\n}\n","import { HttpClient } from './http.js';\nimport { BargainsResource } from './resources/bargains.js';\nimport { CardsResource } from './resources/cards.js';\nimport { ExpansionsResource } from './resources/expansions.js';\nimport { PackRatesResource } from './resources/packRates.js';\nimport { PriceStatsResource } from './resources/priceStats.js';\nimport { ProductsResource } from './resources/products.js';\nimport { ShopMatchStatsResource } from './resources/shopMatchStats.js';\nimport { ShopMatchesResource } from './resources/shopMatches.js';\nimport { ShopUrlsResource } from './resources/shopUrls.js';\nimport { ShopsResource } from './resources/shops.js';\nimport { StatsResource } from './resources/stats.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.tcgpriser.se';\n\n/** Local dev, self-hosting and testing overrides. Most integrations never touch these. */\nexport interface TcgPriserAdvancedOptions {\n /** Point at a local dev server or a self-hosted instance. Defaults to production. */\n baseUrl?: string;\n /** Extra headers sent on every request, e.g. a custom `User-Agent`. */\n headers?: Record<string, string>;\n /** Swap in a different `fetch` (older Node, testing, a proxying agent). Defaults to global `fetch`. */\n fetch?: typeof fetch;\n}\n\nexport interface TcgPriserOptions {\n /**\n * A per-account API token, generated from your account page at tcgpriser.se/account/api-token.\n * Only needed for premium methods (`cards.prices()`, `priceStats.product()`,\n * `bargains.search()` etc.); public methods work fine without it. This client has no login flow\n * of its own, and doesn't need one: the API token is a long-lived, revocable secret made for\n * exactly this, so there's no OAuth dance to drive.\n *\n * Every premium method also accepts its own `authToken` to override this per call. Useful when\n * one server-side client is shared across requests for several different signed-in users.\n */\n authToken?: string;\n /** Local dev / self-hosting / testing overrides. Leave unset unless you know you need it. */\n advanced?: TcgPriserAdvancedOptions;\n}\n\n/**\n * Client for the tcgpriser.se API: Pokémon TCG price data, catalog, shop matches and bargains for\n * shops tracked in Sweden.\n *\n * ```ts\n * import { TcgPriser } from 'tcgpriser';\n *\n * const tcgpriser = new TcgPriser();\n * const card = await tcgpriser.cards.get('mega-evolution-ascended-heroes-fezandipiti-ex');\n * console.log(card.retailPrice, card.lowestShopOffer?.shop.name);\n * ```\n *\n * That example needs no token. Most of the API is public (https://api.tcgpriser.se/docs). A\n * smaller set of premium methods (live pricing, per-condition history, shop comparison, bargain\n * search, shop-URL submission) need a Premium subscriber's API token\n * (https://api.tcgpriser.se/premium-docs), generated from tcgpriser.se/account/api-token:\n *\n * ```ts\n * const tcgpriser = new TcgPriser(myApiToken); // shorthand for { authToken: myApiToken }\n * await tcgpriser.cards.livePricing('fezandipiti-ex');\n * ```\n */\nexport class TcgPriser {\n readonly cards: CardsResource;\n readonly products: ProductsResource;\n readonly expansions: ExpansionsResource;\n readonly shops: ShopsResource;\n readonly shopMatches: ShopMatchesResource;\n readonly shopMatchStats: ShopMatchStatsResource;\n readonly shopUrls: ShopUrlsResource;\n readonly priceStats: PriceStatsResource;\n readonly bargains: BargainsResource;\n readonly packRates: PackRatesResource;\n readonly stats: StatsResource;\n\n /**\n * @param optionsOrAuthToken A subscriber's API token (`new TcgPriser(myApiToken)`), a full\n * `TcgPriserOptions` object, or omit it entirely for an anonymous, public-only client.\n */\n constructor(optionsOrAuthToken?: string | TcgPriserOptions) {\n const options: TcgPriserOptions =\n typeof optionsOrAuthToken === 'string' ? { authToken: optionsOrAuthToken } : (optionsOrAuthToken ?? {});\n const advanced = options.advanced ?? {};\n\n if (!advanced.fetch && typeof fetch === 'undefined') {\n throw new Error(\n 'tcgpriser: no global fetch found. Pass { advanced: { fetch } } explicitly on Node < 18, or run on Node 18+.',\n );\n }\n\n const http = new HttpClient({\n baseUrl: advanced.baseUrl ?? DEFAULT_BASE_URL,\n // Bound to globalThis: both browsers and Node's undici implement fetch as a method that\n // checks its receiver, so an unbound reference throws \"Illegal invocation\" the moment it's\n // called through anything other than `window.fetch(...)`/`globalThis.fetch(...)` — which is\n // exactly what happens once HttpClient stores it and calls `this.fetchImpl(...)`.\n fetch: advanced.fetch ?? fetch.bind(globalThis),\n headers: advanced.headers,\n authToken: options.authToken,\n });\n\n this.cards = new CardsResource(http);\n this.products = new ProductsResource(http);\n this.expansions = new ExpansionsResource(http);\n this.shops = new ShopsResource(http);\n this.shopMatches = new ShopMatchesResource(http);\n this.shopMatchStats = new ShopMatchStatsResource(http);\n this.shopUrls = new ShopUrlsResource(http);\n this.priceStats = new PriceStatsResource(http);\n this.bargains = new BargainsResource(http);\n this.packRates = new PackRatesResource(http);\n this.stats = new StatsResource(http);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/bargains.ts","../src/resources/cards.ts","../src/resources/expansions.ts","../src/resources/packRates.ts","../src/resources/priceStats.ts","../src/resources/products.ts","../src/resources/shopMatchStats.ts","../src/resources/shopMatches.ts","../src/resources/shopUrls.ts","../src/resources/shops.ts","../src/resources/stats.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/** The stable error codes the API's `error.code` field can hold. */\nexport type TcgPriserErrorCode =\n | 'validationFailed'\n | 'unauthorized'\n | 'forbidden'\n | 'notFound'\n | 'conflict'\n | 'readOnlyField'\n | 'rateLimited'\n | 'premiumRequired'\n | 'businessRequired'\n | 'creditsExhausted'\n | 'internalError'\n /** Response body wasn't the `{ error: { code, message } }` shape. Probably a proxy or gateway\n * error in front of the API. */\n | 'unknown';\n\n/** Thrown for any non-2xx response. Carries the parsed `{ code, message }` when the body matched\n * the API's error envelope, plus the raw status/body regardless so nothing gets lost. */\nexport class TcgPriserError extends Error {\n readonly statusCode: number;\n readonly statusText: string;\n readonly url: string;\n readonly code: TcgPriserErrorCode;\n readonly details: unknown;\n /** The raw response body, for debugging when `code`/`details` don't cover what you need. */\n readonly body: string;\n\n constructor(params: {\n statusCode: number;\n statusText: string;\n url: string;\n code: TcgPriserErrorCode;\n message: string;\n details?: unknown;\n body: string;\n }) {\n super(`tcgpriser: ${params.statusCode} ${params.code} - ${params.message} (${params.url})`);\n this.name = 'TcgPriserError';\n this.statusCode = params.statusCode;\n this.statusText = params.statusText;\n this.url = params.url;\n this.code = params.code;\n this.details = params.details;\n this.body = params.body;\n }\n}\n","import { TcgPriserError, type TcgPriserErrorCode } from './errors.js';\n\nexport type QueryValue = string | number | boolean | undefined | null;\n\n/**\n * Builds a query string from a params object, dropping `undefined`/`null` entries so callers can\n * pass params straight through without filtering first.\n *\n * Takes a generic `object` instead of `Record<string, QueryValue>` on purpose. The params\n * interfaces (`ListCardsParams` etc.) intentionally have no index signature, otherwise any string\n * key would type-check.\n */\nexport function toQueryString<T extends object>(params: T): string {\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params) as [string, QueryValue][]) {\n if (value === undefined || value === null) continue;\n search.set(key, String(value));\n }\n const query = search.toString();\n return query ? `?${query}` : '';\n}\n\n/** Splits `authToken` off a params object so it goes on the `Authorization` header, not through\n * `toQueryString`. A bearer token has no business in a URL: query strings end up in server logs,\n * browser history, `Referer` headers. */\nexport function splitAuthToken<T extends { authToken?: string }>(\n params: T,\n): [Omit<T, 'authToken'>, string | undefined] {\n const { authToken, ...rest } = params;\n return [rest, authToken];\n}\n\nconst KNOWN_ERROR_CODES: ReadonlySet<string> = new Set([\n 'validationFailed',\n 'unauthorized',\n 'forbidden',\n 'notFound',\n 'conflict',\n 'readOnlyField',\n 'rateLimited',\n 'premiumRequired',\n 'businessRequired',\n 'creditsExhausted',\n 'internalError',\n]);\n\nasync function toApiError(res: Response, url: string): Promise<TcgPriserError> {\n const body = await res.text();\n let code: TcgPriserErrorCode = 'unknown';\n let message = res.statusText || 'Request failed';\n let details: unknown;\n\n try {\n const parsed = JSON.parse(body) as { error?: { code?: string; message?: string; details?: unknown } };\n if (parsed.error?.code && KNOWN_ERROR_CODES.has(parsed.error.code)) {\n code = parsed.error.code as TcgPriserErrorCode;\n }\n if (parsed.error?.message) message = parsed.error.message;\n details = parsed.error?.details;\n } catch {\n // Not the standard error envelope, maybe a proxy's HTML error page. Fall back to the status\n // text and leave `body` for anyone who wants to dig in.\n }\n\n return new TcgPriserError({ statusCode: res.status, statusText: res.statusText, url, code, message, details, body });\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch: typeof fetch;\n headers?: Record<string, string>;\n /** Default bearer token for premium endpoints, used when a call doesn't pass its own `authToken`. */\n authToken?: string;\n}\n\n/** Per-call auth override for a premium endpoint, on top of the client's default `authToken`.\n * Every premium method takes one of these, either standalone or merged into its params object via\n * `splitAuthToken`. */\nexport interface PremiumOptions {\n /** Overrides the client's default `authToken` for this call. Pass `undefined` explicitly to\n * force an anonymous request even when the client has a default token. */\n authToken?: string;\n}\n\n/** Thin wrapper around `fetch`: joins the base URL, adds default headers, turns non-2xx responses\n * into a `TcgPriserError`. Every resource method goes through this instead of calling `fetch`\n * directly. */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: Record<string, string>;\n private readonly defaultAuthToken: string | undefined;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.fetchImpl = options.fetch;\n this.defaultHeaders = options.headers ?? {};\n this.defaultAuthToken = options.authToken;\n }\n\n get<T>(path: string, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('GET', path, undefined, requestOptions);\n }\n\n post<T>(path: string, body: unknown, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('POST', path, body, requestOptions);\n }\n\n patch<T>(path: string, body: unknown, requestOptions?: PremiumOptions): Promise<T> {\n return this.request<T>('PATCH', path, body, requestOptions);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n requestOptions?: PremiumOptions,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const authToken = requestOptions && 'authToken' in requestOptions ? requestOptions.authToken : this.defaultAuthToken;\n\n const headers: Record<string, string> = { Accept: 'application/json', ...this.defaultHeaders };\n if (authToken) headers.Authorization = `Bearer ${authToken}`;\n if (body !== undefined) headers['Content-Type'] = 'application/json';\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n\n if (!res.ok) throw await toApiError(res, url);\n if (res.status === 204) return undefined as T;\n return nullsToUndefined(await res.json()) as T;\n }\n}\n\n/** JSON has no `undefined`, so every optional field the API omits comes back over the wire as\n * `null`. Recurses through the parsed response and turns those into `undefined` so callers work\n * with idiomatic `foo?.bar` / `foo ?? fallback` instead of `foo !== null`, and so responses match\n * the `T | undefined` types in `generated/openapi.d.ts` (see `scripts/generate-types.mjs`). */\nfunction nullsToUndefined<T>(value: T): T {\n if (value === null) return undefined as T;\n if (Array.isArray(value)) return value.map(nullsToUndefined) as T;\n if (typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) result[key] = nullsToUndefined(v);\n return result as T;\n }\n return value;\n}\n","import type { HttpClient } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n Bargain,\n BargainReferenceSource,\n CardType,\n GradingCompany,\n ItemCondition,\n ListResponse,\n PaginationParams,\n} from '../types/index.js';\n\nexport interface ListBargainsParams {\n type?: 'sealed' | 'card' | 'all';\n}\n\nexport interface SearchBargainsParams extends PaginationParams {\n authToken?: string;\n type?: 'sealed' | 'card' | 'all';\n /** Filter by shop technicalName. */\n shop?: string;\n /** Filter by which reference price source qualified the bargain. */\n referenceSource?: BargainReferenceSource;\n /** Minimum discount percentage. Default 10. */\n minDiscount?: number;\n /** Default `true`. */\n inStock?: boolean;\n cardType?: CardType;\n itemCondition?: ItemCondition;\n gradingCompany?: GradingCompany;\n grade?: number;\n /** Free-text search on product name / technicalName. */\n search?: string;\n}\n\nexport class BargainsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /bargains`: current shop listings priced notably below their reference price. Result\n * count is fixed by the API (no `limit`/`skip` on the public tier); `pagination.hasMore` tells\n * you if more exist. */\n list(params: ListBargainsParams = {}): Promise<ListResponse<Bargain>> {\n return this.http.get(`/bargains${toQueryString(params)}`);\n }\n\n /** `GET /bargains/search`: like `list()`, but with real pagination and filters (shop, discount\n * threshold, card condition/grade, free-text search). Premium. */\n search(params: SearchBargainsParams = {}): Promise<ListResponse<Bargain>> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/bargains/search${toQueryString(query)}`, { authToken });\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n Card,\n CardType,\n CatalogItemPricing,\n ItemReferencePrices,\n ItemShopMatches,\n ItemSoldPrices,\n ListResponse,\n LivePricingForItem,\n PaginationParams,\n ReferencePriceCardVariant,\n ReferencePriceProvider,\n} from '../types/index.js';\n\nexport interface ListCardsParams extends PaginationParams {\n /** Free-text search over card and set names. */\n search?: string;\n}\n\nexport interface CardMatchesParams extends PaginationParams {\n /** Keep only matches whose shop currently has stock. */\n inStock?: boolean;\n}\n\nexport interface CardReferencePricesParams {\n /** Bearer token for this call. Overrides the client's default `authToken`. */\n authToken?: string;\n /** Rolling window ending today, in days. Ignored when `from`/`to` are supplied. Default 90. */\n days?: number;\n /** `YYYY-MM-DD` */\n from?: string;\n /** `YYYY-MM-DD` */\n to?: string;\n provider?: ReferencePriceProvider;\n cardType?: CardType;\n variant?: ReferencePriceCardVariant;\n}\n\nexport interface CardPricesParams extends PaginationParams {\n authToken?: string;\n}\n\nexport class CardsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /cards`: search or list cards. */\n list(params: ListCardsParams = {}): Promise<ListResponse<Card>> {\n return this.http.get(`/cards${toQueryString(params)}`);\n }\n\n /** `GET /cards/{id}`: fetch one card by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<Card> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}`);\n }\n\n /** `GET /cards/{id}/matches`: current shop listings matched to this card (latest per shop). */\n matches(idOrTechnicalName: string, params: CardMatchesParams = {}): Promise<ItemShopMatches> {\n return this.http.get(\n `/cards/${encodeURIComponent(idOrTechnicalName)}/matches${toQueryString(params)}`,\n );\n }\n\n /** `GET /cards/{id}/reference-prices`: Cardmarket/TCGplayer/eBay/Tradera price history. Premium. */\n referencePrices(\n idOrTechnicalName: string,\n params: CardReferencePricesParams = {},\n ): Promise<ItemReferencePrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/cards/${encodeURIComponent(idOrTechnicalName)}/reference-prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /cards/{id}/prices`: individual marketplace sale records. Premium. */\n prices(idOrTechnicalName: string, params: CardPricesParams = {}): Promise<ItemSoldPrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/prices${toQueryString(query)}`, {\n authToken,\n });\n }\n\n /** `GET /cards/{id}/pricing/live`: computed fresh for this request, not read from the last\n * stats job. Premium. */\n livePricing(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<LivePricingForItem> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);\n }\n\n /** `GET /cards/{id}/pricing`: this card's current pricing snapshot — `retailPrice`,\n * `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day\n * by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,\n * shorter-cached call for the part of a card that actually changes day to day. */\n pricing(idOrTechnicalName: string): Promise<CatalogItemPricing> {\n return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing`);\n }\n\n /** `GET /cards/pricing`: pricing for up to 200 cards in one request, keyed by `id` — the batch\n * counterpart to `pricing()`, for a page of results (a search page, an expansion's contents) that\n * needs pricing for many items at once. Unlike `get()`/`pricing()`, this only accepts `id`s, not\n * technicalNames — pass the `id`s already on the cards you fetched. Ids with no match are\n * silently omitted from the result rather than causing an error. */\n pricingBatch(ids: string[]): Promise<ListResponse<CatalogItemPricing>> {\n return this.http.get(`/cards/pricing?ids=${ids.map(encodeURIComponent).join(',')}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport type {\n Card,\n Expansion,\n ExpansionLivePricing,\n ExpansionRef,\n ListResponse,\n SealedProduct,\n} from '../types/index.js';\n\nexport class ExpansionsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /expansions`: every expansion. Unwrapped to a plain array, nothing to paginate here. */\n async list(): Promise<Expansion[]> {\n const res = await this.http.get<{ data: Expansion[] }>('/expansions');\n return res.data;\n }\n\n /** `GET /expansions/{technicalName}`: metadata only — no cards or sealed products. Returns the\n * smaller `ExpansionRef`, not the full `Expansion`: this is a plain lookup by technicalName, not\n * the aggregation `list()` runs, so `sealedCount`/`cardCount`/`productCount` aren't available\n * here. See `cards()` and `sealedProducts()` for this expansion's contents. */\n get(technicalName: string): Promise<ExpansionRef> {\n return this.http.get(`/expansions/${encodeURIComponent(technicalName)}`);\n }\n\n /** `GET /expansions/{technicalName}/cards`: every card in this expansion. Content only, no\n * pricing fields — pass the `id`s from the result to `client.cards.pricingBatch()` if you need\n * pricing too. Sealed products are a separate call — see `sealedProducts()` — never merged into\n * this one. */\n cards(technicalName: string): Promise<ListResponse<Card>> {\n return this.http.get(`/expansions/${encodeURIComponent(technicalName)}/cards`);\n }\n\n /** `GET /expansions/{technicalName}/products`: every sealed product in this expansion. Content\n * only, no pricing fields — pass the `id`s from the result to `client.products.pricingBatch()`\n * if you need pricing too. Cards are a separate call — see `cards()` — never merged into this\n * one. */\n sealedProducts(technicalName: string): Promise<ListResponse<SealedProduct>> {\n return this.http.get(`/expansions/${encodeURIComponent(technicalName)}/products`);\n }\n\n /** `GET /expansions/{technicalName}/cards/live-pricing`: computed fresh for every card in this\n * expansion, not read from the last stats job. Premium. */\n cardsLivePricing(\n technicalName: string,\n options: PremiumOptions = {},\n ): Promise<ExpansionLivePricing> {\n return this.http.get(\n `/expansions/${encodeURIComponent(technicalName)}/cards/live-pricing`,\n options,\n );\n }\n\n /** `GET /expansions/{technicalName}/products/live-pricing`: computed fresh for every sealed\n * product in this expansion, not read from the last stats job. Premium. */\n productsLivePricing(\n technicalName: string,\n options: PremiumOptions = {},\n ): Promise<ExpansionLivePricing> {\n return this.http.get(\n `/expansions/${encodeURIComponent(technicalName)}/products/live-pricing`,\n options,\n );\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { PackRate } from '../types/index.js';\n\nexport class PackRatesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /pack-rates`: pull-rate odds for every expansion that has them. Unwrapped to a plain\n * array, nothing to paginate here. */\n async list(): Promise<PackRate[]> {\n const res = await this.http.get<{ data: PackRate[] }>('/pack-rates');\n return res.data;\n }\n\n /** `GET /pack-rates/{expansionId}`: pull-rate odds for one expansion. */\n get(expansionId: string): Promise<PackRate> {\n return this.http.get(`/pack-rates/${encodeURIComponent(expansionId)}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n CardType,\n GradingCompany,\n ItemCondition,\n ItemDailyStats,\n ItemEstimatedValue,\n ItemFullStats,\n ItemStats,\n ItemVariantDailyStats,\n ItemVariantStats,\n ListResponse,\n TopItem,\n} from '../types/index.js';\n\n/** Filters shared by `daily()` and `estimatedValues()`: all narrow which product(s) the stats\n * cover; combine as many as you like. */\nexport interface ProductFilterParams {\n productName?: string;\n technicalName?: string;\n priceChartingId?: string;\n modelNumber?: string;\n /** Category technicalName. */\n category?: string;\n /** Expansion technicalName. */\n expansion?: string;\n}\n\nexport interface DailyPriceStatsParams extends ProductFilterParams {\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Expansion id (ObjectId), an alternative to `expansion` (technicalName). */\n expansionId?: string;\n /** Category id (ObjectId), an alternative to `category` (technicalName). */\n categoryId?: string;\n}\n\nexport interface EstimatedValuesParams extends ProductFilterParams {\n page?: number;\n limit?: number;\n}\n\nexport interface TopProductsParams {\n limit?: number;\n}\n\nexport interface ProductDailyStatsParams {\n authToken?: string;\n /** Number of days to retrieve, from today backwards. Default 30. */\n days?: number;\n}\n\nexport interface ProductByVariantParams {\n authToken?: string;\n /** Number of days to include in the average calculation. Default 30. */\n days?: number;\n}\n\nexport interface ProductDailyByVariantParams {\n authToken?: string;\n cardType: CardType;\n /** Required when `cardType` is `'loose'`. */\n condition?: ItemCondition;\n /** Required when `cardType` is `'graded'`. */\n gradingCompany?: GradingCompany;\n /** Required when `cardType` is `'graded'`. */\n grade?: number;\n /** Number of days to retrieve. Default 30. */\n days?: number;\n}\n\nexport class PriceStatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /price-stats/daily`: daily average price history, filtered to matching product(s). */\n daily(params: DailyPriceStatsParams = {}): Promise<ListResponse<ItemDailyStats>> {\n return this.http.get(`/price-stats/daily${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/estimated-values`: current estimated market value, filtered to matching\n * product(s). */\n estimatedValues(params: EstimatedValuesParams = {}): Promise<ListResponse<ItemEstimatedValue>> {\n return this.http.get(`/price-stats/estimated-values${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/top-products`: items ranked by shop availability (how many shops carry\n * them), not by price. */\n topProducts(params: TopProductsParams = {}): Promise<ListResponse<TopItem>> {\n return this.http.get(`/price-stats/top-products${toQueryString(params)}`);\n }\n\n /** `GET /price-stats/product/{id}`: daily price history, current estimate, and a variant-count\n * summary for one product. Premium. */\n product(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemStats> {\n return this.http.get(`/price-stats/product/${encodeURIComponent(idOrTechnicalName)}`, options);\n }\n\n /** `GET /price-stats/product/{id}/full`: everything `product()` has, plus the item's current\n * shop matches. Premium. */\n productFull(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemFullStats> {\n return this.http.get(`/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/full`, options);\n }\n\n /** `GET /price-stats/product/{id}/daily`: daily price history for one product, with a\n * caller-chosen window. Premium. */\n productDaily(\n idOrTechnicalName: string,\n params: ProductDailyStatsParams = {},\n ): Promise<ItemDailyStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /price-stats/product/{id}/daily-last-30`: daily price history for the last 30 days\n * exactly (no window param, for callers that want a stable cache key). Premium. */\n productDailyLast30(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<ItemDailyStats> {\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily-last-30`,\n options,\n );\n }\n\n /** `GET /price-stats/product/{id}/estimated-value`: current estimated value only. Premium. */\n productEstimatedValue(\n idOrTechnicalName: string,\n options: PremiumOptions = {},\n ): Promise<ItemEstimatedValue> {\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/estimated-value`,\n options,\n );\n }\n\n /** `GET /price-stats/product/{id}/by-variant`: price stats broken out per card condition/grade.\n * Premium. */\n productByVariant(\n idOrTechnicalName: string,\n params: ProductByVariantParams = {},\n ): Promise<ItemVariantStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/by-variant${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /price-stats/product/{id}/daily-by-variant`: daily price history for one specific\n * condition/grade. `condition` is required for `cardType: 'loose'`; `gradingCompany` and `grade`\n * are required for `cardType: 'graded'`. Premium. */\n productDailyByVariant(\n idOrTechnicalName: string,\n params: ProductDailyByVariantParams,\n ): Promise<ItemVariantDailyStats> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/price-stats/product/${encodeURIComponent(idOrTechnicalName)}/daily-by-variant${toQueryString(query)}`,\n { authToken },\n );\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type {\n CardType,\n CatalogItemPricing,\n GradingCompany,\n ItemCondition,\n ItemReferencePrices,\n ItemShopMatches,\n ItemSoldPrices,\n ListResponse,\n LivePricingForItem,\n PaginationParams,\n ReferencePriceProvider,\n SealedProduct,\n} from '../types/index.js';\n\nexport interface ListProductsParams extends PaginationParams {\n /** Whitespace-separated tokens, each matched against the start of a word. */\n search?: string;\n}\n\nexport interface ProductMatchesParams extends PaginationParams {\n /** Keep only matches whose shop currently has stock. */\n inStock?: boolean;\n cardType?: CardType;\n condition?: ItemCondition;\n gradingCompany?: GradingCompany;\n grade?: number;\n}\n\nexport interface ProductReferencePricesParams {\n authToken?: string;\n /** Rolling window ending today, in days. Ignored when `from`/`to` are supplied. Default 90. */\n days?: number;\n /** `YYYY-MM-DD` */\n from?: string;\n /** `YYYY-MM-DD` */\n to?: string;\n provider?: ReferencePriceProvider;\n}\n\nexport interface ProductPricesParams extends PaginationParams {\n authToken?: string;\n}\n\n/** Sealed products: booster boxes, ETBs, tins, and the like. Single cards live under\n * `client.cards` instead. */\nexport class ProductsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /product`: search or list sealed products. */\n list(params: ListProductsParams = {}): Promise<ListResponse<SealedProduct>> {\n return this.http.get(`/product${toQueryString(params)}`);\n }\n\n /** `GET /product/{id}`: fetch one sealed product by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<SealedProduct> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}`);\n }\n\n /** `GET /product/{id}/matches`: current shop listings matched to this product (latest per shop). */\n matches(idOrTechnicalName: string, params: ProductMatchesParams = {}): Promise<ItemShopMatches> {\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/matches${toQueryString(params)}`,\n );\n }\n\n /** `GET /product/{id}/reference-prices`: Cardmarket/TCGplayer/Tradera price history. Premium. */\n referencePrices(\n idOrTechnicalName: string,\n params: ProductReferencePricesParams = {},\n ): Promise<ItemReferencePrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/reference-prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /product/{id}/prices`: individual marketplace sale records. Premium. */\n prices(idOrTechnicalName: string, params: ProductPricesParams = {}): Promise<ItemSoldPrices> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/product/${encodeURIComponent(idOrTechnicalName)}/prices${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /product/{id}/pricing/live`: computed fresh for this request, not read from the last\n * stats job. Premium. */\n livePricing(idOrTechnicalName: string, options: PremiumOptions = {}): Promise<LivePricingForItem> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);\n }\n\n /** `GET /product/{id}/pricing`: this product's current pricing snapshot — `retailPrice`,\n * `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day\n * by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,\n * shorter-cached call for the part of a product that actually changes day to day. */\n pricing(idOrTechnicalName: string): Promise<CatalogItemPricing> {\n return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing`);\n }\n\n /** `GET /product/pricing`: pricing for up to 200 sealed products in one request, keyed by `id` —\n * the batch counterpart to `pricing()`, for a page of results (a search page, an expansion's\n * contents) that needs pricing for many items at once. Unlike `get()`/`pricing()`, this only\n * accepts `id`s, not technicalNames — pass the `id`s already on the products you fetched. Ids with\n * no match are silently omitted from the result rather than causing an error. */\n pricingBatch(ids: string[]): Promise<ListResponse<CatalogItemPricing>> {\n return this.http.get(`/product/pricing?ids=${ids.map(encodeURIComponent).join(',')}`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { splitAuthToken, toQueryString } from '../http.js';\nimport type { ItemPriceComparison, ItemShopPriceHistory, ShopPriceHistoryList } from '../types/index.js';\n\nexport interface ShopMatchStatsForProductParams {\n authToken?: string;\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Filter to one shop's technicalName. */\n shop?: string;\n}\n\nexport interface ShopMatchStatsForShopParams {\n authToken?: string;\n /** `YYYY-MM-DD` */\n startDate?: string;\n /** `YYYY-MM-DD` */\n endDate?: string;\n /** Maximum products to return. Default 20, max 50. */\n limit?: number;\n}\n\nexport interface CompareShopPricesParams {\n authToken?: string;\n /** Product/card id or technicalName. */\n productId: string;\n /** `YYYY-MM-DD`: defaults to the latest date with data. */\n date?: string;\n}\n\n/** Historical shop-vs-price data, distinct from `client.shopMatches` (which is the current/latest\n * match state). Everything here is premium. */\nexport class ShopMatchStatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shop-match-stats/product/{productId}`: one product's price history, broken out per shop. */\n forProduct(\n productId: string,\n params: ShopMatchStatsForProductParams = {},\n ): Promise<ItemShopPriceHistory> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(\n `/shop-match-stats/product/${encodeURIComponent(productId)}${toQueryString(query)}`,\n { authToken },\n );\n }\n\n /** `GET /shop-match-stats/shop/{shop}`: one shop's price history, broken out per product. */\n forShop(shop: string, params: ShopMatchStatsForShopParams = {}): Promise<ShopPriceHistoryList> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/shop-match-stats/shop/${encodeURIComponent(shop)}${toQueryString(query)}`, {\n authToken,\n });\n }\n\n /** `GET /shop-match-stats/compare`: one product's price at every shop that carries it, as of\n * one date (defaults to the latest). */\n compare(params: CompareShopPricesParams): Promise<ItemPriceComparison> {\n const [query, authToken] = splitAuthToken(params);\n return this.http.get(`/shop-match-stats/compare${toQueryString(query)}`, { authToken });\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { toQueryString } from '../http.js';\nimport type { ListResponse, PaginationParams, ShopMatch, ShopMatchesForShop, ShopMatchStats } from '../types/index.js';\n\nexport interface ListShopMatchesParams extends PaginationParams {\n /** Filter to one shop's technicalName. */\n shop?: string;\n inStock?: boolean;\n /** Filter by whether the listing has been resolved to a catalog item. */\n linked?: boolean;\n}\n\nexport interface ShopMatchesForShopParams extends PaginationParams {\n inStock?: boolean;\n}\n\n/** Raw shop-to-catalog match data: what's currently listed where, independent of which item or\n * shop you start from. For \"what does this card cost at each shop\" or \"what's in stock at this\n * shop\", prefer `client.cards.matches()` / `client.products.matches()` /\n * `client.shopMatches.forShop()`. */\nexport class ShopMatchesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shop-matches`: every current match across every shop (latest record per url+shop). */\n list(params: ListShopMatchesParams = {}): Promise<ListResponse<ShopMatch>> {\n return this.http.get(`/shop-matches${toQueryString(params)}`);\n }\n\n /** `GET /shop-matches/{shop}`: every current match at one shop (latest record per url). */\n forShop(technicalName: string, params: ShopMatchesForShopParams = {}): Promise<ShopMatchesForShop> {\n return this.http.get(`/shop-matches/${encodeURIComponent(technicalName)}${toQueryString(params)}`);\n }\n\n /** `GET /shop-matches/shops`: match counts per shop (based on latest records only). */\n shopStats(params: PaginationParams = {}): Promise<ListResponse<ShopMatchStats>> {\n return this.http.get(`/shop-matches/shops${toQueryString(params)}`);\n }\n}\n","import type { HttpClient, PremiumOptions } from '../http.js';\nimport type { ShopUrlMutationResult } from '../types/index.js';\n\nexport interface SubmitShopUrlParams extends PremiumOptions {\n url: string;\n /** Shop technicalName. Auto-created if it doesn't exist yet. */\n shop: string;\n}\n\nexport interface AssignShopUrlProductParams extends PremiumOptions {\n /** Product/card id to link, or `null` to unlink and let auto-matching resume. */\n productId: string | null;\n}\n\n/** Lets a signed-in subscriber contribute to the catalog: submit a shop URL for scraping, or\n * manually correct which product/card a URL resolves to. Both premium, both mutating. */\nexport class ShopUrlsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `POST /shop-urls/submit`: submit a shop URL for scraping. */\n submit(params: SubmitShopUrlParams): Promise<ShopUrlMutationResult> {\n const { authToken, url, shop } = params;\n return this.http.post('/shop-urls/submit', { url, shop }, { authToken });\n }\n\n /** `PATCH /shop-urls/{id}/product`: manually assign (or clear) the product a shop URL resolves to. */\n assignProduct(\n shopUrlId: string,\n params: AssignShopUrlProductParams,\n ): Promise<ShopUrlMutationResult> {\n const { authToken, productId } = params;\n return this.http.patch(\n `/shop-urls/${encodeURIComponent(shopUrlId)}/product`,\n { productId },\n { authToken },\n );\n }\n}\n","import type { HttpClient } from '../http.js';\nimport { toQueryString } from '../http.js';\nimport type { Shop } from '../types/index.js';\n\nexport interface ListShopsParams {\n active?: boolean;\n}\n\nexport class ShopsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /shops`: every tracked shop. Unwrapped to a plain array, nothing to paginate here. */\n async list(params: ListShopsParams = {}): Promise<Shop[]> {\n const res = await this.http.get<{ data: Shop[] }>(`/shops${toQueryString(params)}`);\n return res.data;\n }\n\n /** `GET /shops/{id}`: fetch one shop by its id or technicalName. */\n get(idOrTechnicalName: string): Promise<Shop> {\n return this.http.get(`/shops/${encodeURIComponent(idOrTechnicalName)}`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { PlatformStats } from '../types/index.js';\n\nexport class StatsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** `GET /stats`: platform-wide overview counts (shops, expansions, products, prices tracked). */\n platform(): Promise<PlatformStats> {\n return this.http.get('/stats');\n }\n}\n","import { HttpClient } from './http.js';\nimport { BargainsResource } from './resources/bargains.js';\nimport { CardsResource } from './resources/cards.js';\nimport { ExpansionsResource } from './resources/expansions.js';\nimport { PackRatesResource } from './resources/packRates.js';\nimport { PriceStatsResource } from './resources/priceStats.js';\nimport { ProductsResource } from './resources/products.js';\nimport { ShopMatchStatsResource } from './resources/shopMatchStats.js';\nimport { ShopMatchesResource } from './resources/shopMatches.js';\nimport { ShopUrlsResource } from './resources/shopUrls.js';\nimport { ShopsResource } from './resources/shops.js';\nimport { StatsResource } from './resources/stats.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.tcgpriser.se';\n\n/** Local dev, self-hosting and testing overrides. Most integrations never touch these. */\nexport interface TcgPriserAdvancedOptions {\n /** Point at a local dev server or a self-hosted instance. Defaults to production. */\n baseUrl?: string;\n /** Extra headers sent on every request, e.g. a custom `User-Agent`. */\n headers?: Record<string, string>;\n /** Swap in a different `fetch` (older Node, testing, a proxying agent). Defaults to global `fetch`. */\n fetch?: typeof fetch;\n}\n\nexport interface TcgPriserOptions {\n /**\n * A per-account API token, generated from your account page at tcgpriser.se/account/api-token.\n * Only needed for premium methods (`cards.prices()`, `priceStats.product()`,\n * `bargains.search()` etc.); public methods work fine without it. This client has no login flow\n * of its own, and doesn't need one: the API token is a long-lived, revocable secret made for\n * exactly this, so there's no OAuth dance to drive.\n *\n * Every premium method also accepts its own `authToken` to override this per call. Useful when\n * one server-side client is shared across requests for several different signed-in users.\n */\n authToken?: string;\n /** Local dev / self-hosting / testing overrides. Leave unset unless you know you need it. */\n advanced?: TcgPriserAdvancedOptions;\n}\n\n/**\n * Client for the tcgpriser.se API: Pokémon TCG price data, catalog, shop matches and bargains for\n * shops tracked in Sweden.\n *\n * ```ts\n * import { TcgPriser } from 'tcgpriser';\n *\n * const tcgpriser = new TcgPriser();\n * const card = await tcgpriser.cards.get('mega-evolution-ascended-heroes-fezandipiti-ex');\n * console.log(card.retailPrice, card.lowestShopOffer?.shop.name);\n * ```\n *\n * That example needs no token. Most of the API is public (https://api.tcgpriser.se/docs). A\n * smaller set of premium methods (live pricing, per-condition history, shop comparison, bargain\n * search, shop-URL submission) need a Premium subscriber's API token\n * (https://api.tcgpriser.se/premium-docs), generated from tcgpriser.se/account/api-token:\n *\n * ```ts\n * const tcgpriser = new TcgPriser(myApiToken); // shorthand for { authToken: myApiToken }\n * await tcgpriser.cards.livePricing('fezandipiti-ex');\n * ```\n */\nexport class TcgPriser {\n readonly cards: CardsResource;\n readonly products: ProductsResource;\n readonly expansions: ExpansionsResource;\n readonly shops: ShopsResource;\n readonly shopMatches: ShopMatchesResource;\n readonly shopMatchStats: ShopMatchStatsResource;\n readonly shopUrls: ShopUrlsResource;\n readonly priceStats: PriceStatsResource;\n readonly bargains: BargainsResource;\n readonly packRates: PackRatesResource;\n readonly stats: StatsResource;\n\n /**\n * @param optionsOrAuthToken A subscriber's API token (`new TcgPriser(myApiToken)`), a full\n * `TcgPriserOptions` object, or omit it entirely for an anonymous, public-only client.\n */\n constructor(optionsOrAuthToken?: string | TcgPriserOptions) {\n const options: TcgPriserOptions =\n typeof optionsOrAuthToken === 'string' ? { authToken: optionsOrAuthToken } : (optionsOrAuthToken ?? {});\n const advanced = options.advanced ?? {};\n\n if (!advanced.fetch && typeof fetch === 'undefined') {\n throw new Error(\n 'tcgpriser: no global fetch found. Pass { advanced: { fetch } } explicitly on Node < 18, or run on Node 18+.',\n );\n }\n\n const http = new HttpClient({\n baseUrl: advanced.baseUrl ?? DEFAULT_BASE_URL,\n // Bound to globalThis: both browsers and Node's undici implement fetch as a method that\n // checks its receiver, so an unbound reference throws \"Illegal invocation\" the moment it's\n // called through anything other than `window.fetch(...)`/`globalThis.fetch(...)` — which is\n // exactly what happens once HttpClient stores it and calls `this.fetchImpl(...)`.\n fetch: advanced.fetch ?? fetch.bind(globalThis),\n headers: advanced.headers,\n authToken: options.authToken,\n });\n\n this.cards = new CardsResource(http);\n this.products = new ProductsResource(http);\n this.expansions = new ExpansionsResource(http);\n this.shops = new ShopsResource(http);\n this.shopMatches = new ShopMatchesResource(http);\n this.shopMatchStats = new ShopMatchStatsResource(http);\n this.shopUrls = new ShopUrlsResource(http);\n this.priceStats = new PriceStatsResource(http);\n this.bargains = new BargainsResource(http);\n this.packRates = new PackRatesResource(http);\n this.stats = new StatsResource(http);\n }\n}\n"]}
|