tcgpriser 0.5.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 +151 -51
- package/dist/index.cjs +64 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +244 -337
- package/dist/index.d.ts +244 -337
- package/dist/index.js +64 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -36,7 +36,12 @@ import { TcgPriser } from 'tcgpriser';
|
|
|
36
36
|
const tcgpriser = new TcgPriser();
|
|
37
37
|
|
|
38
38
|
const card = await tcgpriser.cards.get('mega-evolution-ascended-heroes-fezandipiti-ex');
|
|
39
|
-
console.log(card.
|
|
39
|
+
console.log(card.name, card.expansion?.name);
|
|
40
|
+
|
|
41
|
+
// Content (name, images, expansion, ...) and pricing (retailPrice, lowestShopOffer, ...) are
|
|
42
|
+
// separate, differently-cached calls — see "Pricing" below.
|
|
43
|
+
const pricing = await tcgpriser.cards.pricing('mega-evolution-ascended-heroes-fezandipiti-ex');
|
|
44
|
+
console.log(pricing.retailPrice, pricing.lowestShopOffer?.shop.name);
|
|
40
45
|
|
|
41
46
|
const { data: bargains } = await tcgpriser.bargains.list({ type: 'card' });
|
|
42
47
|
```
|
|
@@ -63,9 +68,30 @@ await tcgpriser.products.matches('scarlet-violet-booster-pack');
|
|
|
63
68
|
|
|
64
69
|
### Expansions
|
|
65
70
|
|
|
71
|
+
Cards and sealed products are never merged into one response — fetch each separately.
|
|
72
|
+
|
|
66
73
|
```typescript
|
|
67
74
|
await tcgpriser.expansions.list();
|
|
68
|
-
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
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Pricing
|
|
81
|
+
|
|
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
|
|
85
|
+
admin edit or catalog import, pricing refreshes daily, so each is cached at the TTL its own
|
|
86
|
+
freshness supports.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
await tcgpriser.cards.pricing('fezandipiti-ex'); // id or technicalName
|
|
90
|
+
await tcgpriser.products.pricing('scarlet-violet-booster-pack');
|
|
91
|
+
|
|
92
|
+
// Batch form, up to 200 ids at once — ids only, not technicalNames.
|
|
93
|
+
const { data: cards } = await tcgpriser.cards.list({ search: 'pikachu' });
|
|
94
|
+
await tcgpriser.cards.pricingBatch(cards.map((card) => card.id));
|
|
69
95
|
```
|
|
70
96
|
|
|
71
97
|
### Shops
|
|
@@ -95,33 +121,33 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
95
121
|
|
|
96
122
|
### `cards`
|
|
97
123
|
|
|
98
|
-
| Method | Description |
|
|
99
|
-
|
|
100
|
-
| `list(params)` | Search or list cards |
|
|
101
|
-
| `get(id)` | Fetch one card by id or technicalName |
|
|
102
|
-
| `matches(id, params)` | Current shop listings matched to this card |
|
|
103
|
-
| `prices(id, params)` 🔒 | Individual marketplace sale records |
|
|
104
|
-
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / eBay / Tradera price history |
|
|
105
|
-
| `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 |
|
|
106
132
|
|
|
107
133
|
### `products`
|
|
108
134
|
|
|
109
|
-
| Method | Description |
|
|
110
|
-
|
|
111
|
-
| `list(params)` | Search or list sealed products |
|
|
112
|
-
| `get(id)` | Fetch one product by id or technicalName |
|
|
113
|
-
| `matches(id, params)` | Current shop listings matched to this product |
|
|
114
|
-
| `prices(id, params)` 🔒 | Individual marketplace sale records |
|
|
115
|
-
| `referencePrices(id, params)` 🔒 | Cardmarket / TCGplayer / Tradera price history |
|
|
116
|
-
| `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 |
|
|
117
143
|
|
|
118
144
|
### `expansions`
|
|
119
145
|
|
|
120
|
-
| Method | Description |
|
|
121
|
-
|
|
122
|
-
| `list()` | Every expansion |
|
|
123
|
-
| `products(technicalName)` | Every card and sealed product in one expansion |
|
|
124
|
-
| `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 |
|
|
125
151
|
|
|
126
152
|
### `shops`
|
|
127
153
|
|
|
@@ -140,33 +166,33 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
140
166
|
|
|
141
167
|
### `shopMatchStats` 🔒
|
|
142
168
|
|
|
143
|
-
| Method | Description |
|
|
144
|
-
|
|
145
|
-
| `forProduct(id, params)` | One product's price history, broken out per shop |
|
|
146
|
-
| `forShop(shop, params)` | One shop's price history, broken out per product |
|
|
147
|
-
| `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 |
|
|
148
174
|
|
|
149
175
|
### `priceStats`
|
|
150
176
|
|
|
151
|
-
| Method | Description |
|
|
152
|
-
|
|
153
|
-
| `daily(params)` | Daily average price history |
|
|
154
|
-
| `estimatedValues(params)` | Current estimated market value |
|
|
155
|
-
| `topProducts(params)` | Items ranked by shop availability |
|
|
156
|
-
| `product(id)` 🔒 | Daily history, estimate and variant summary for one product |
|
|
157
|
-
| `productFull(id)` 🔒 | `product()` plus the item's current shop matches |
|
|
158
|
-
| `productDaily(id, params)` 🔒 | Daily history for one product, custom window |
|
|
159
|
-
| `productDailyLast30(id)` 🔒 | Daily history, fixed to the last 30 days |
|
|
160
|
-
| `productEstimatedValue(id)` 🔒 | Current estimated value only |
|
|
161
|
-
| `productByVariant(id, params)` 🔒 | Price stats per card condition/grade |
|
|
162
|
-
| `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 |
|
|
163
189
|
|
|
164
190
|
### `bargains`
|
|
165
191
|
|
|
166
|
-
| Method | Description |
|
|
167
|
-
|
|
168
|
-
| `list(params)` | Current listings priced below their reference price |
|
|
169
|
-
| `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 |
|
|
170
196
|
|
|
171
197
|
### `packRates`
|
|
172
198
|
|
|
@@ -188,14 +214,16 @@ await tcgpriser.packRates.get(expansionId);
|
|
|
188
214
|
|---|---|
|
|
189
215
|
| `platform()` | Platform-wide overview counts |
|
|
190
216
|
|
|
191
|
-
🔒 = premium, needs
|
|
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).
|
|
192
220
|
|
|
193
221
|
## Authentication
|
|
194
222
|
|
|
195
|
-
Public methods work with no setup. Premium methods (marked 🔒 above) need a
|
|
223
|
+
Public methods work with no setup. Premium methods (marked 🔒 above) need a Premium subscriber's API token, generated from **tcgpriser.se/account/api-token**. Unlike the site's own session login, which is OAuth-based and can't be driven headlessly, the API token is a long-lived, revocable secret made specifically for scripts and other programmatic callers. Generate it once from your account page and pass it in:
|
|
196
224
|
|
|
197
225
|
```typescript
|
|
198
|
-
const tcgpriser = new TcgPriser(
|
|
226
|
+
const tcgpriser = new TcgPriser(myApiToken); // shorthand for { authToken: myApiToken }
|
|
199
227
|
await tcgpriser.cards.livePricing('fezandipiti-ex');
|
|
200
228
|
```
|
|
201
229
|
|
|
@@ -203,7 +231,7 @@ Or set no default and pass a token per call, which fits better when one client i
|
|
|
203
231
|
|
|
204
232
|
```typescript
|
|
205
233
|
const tcgpriser = new TcgPriser();
|
|
206
|
-
await tcgpriser.cards.livePricing('fezandipiti-ex', { authToken:
|
|
234
|
+
await tcgpriser.cards.livePricing('fezandipiti-ex', { authToken: requestUserApiToken });
|
|
207
235
|
```
|
|
208
236
|
|
|
209
237
|
A missing or invalid token gets `401 unauthorized`. A valid token without an active subscription gets `403 premiumRequired`. Both come back as `TcgPriserError`:
|
|
@@ -220,14 +248,39 @@ try {
|
|
|
220
248
|
}
|
|
221
249
|
```
|
|
222
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
|
+
|
|
223
276
|
## Options
|
|
224
277
|
|
|
225
278
|
```typescript
|
|
226
|
-
new TcgPriser(
|
|
227
|
-
new TcgPriser();
|
|
279
|
+
new TcgPriser(myApiToken); // shorthand for { authToken: myApiToken }
|
|
280
|
+
new TcgPriser(); // no token, public methods only
|
|
228
281
|
|
|
229
282
|
new TcgPriser({
|
|
230
|
-
authToken:
|
|
283
|
+
authToken: myApiToken,
|
|
231
284
|
|
|
232
285
|
// Local dev, self-hosting or tests only. Leave this out for normal use.
|
|
233
286
|
advanced: {
|
|
@@ -256,6 +309,47 @@ type CardSchema = components['schemas']['CardWithPricing'];
|
|
|
256
309
|
|
|
257
310
|
Most types in `tcgpriser` are direct aliases onto that generated schema, so a field in your code and a field in the API docs are the same field, always.
|
|
258
311
|
|
|
312
|
+
## Images
|
|
313
|
+
|
|
314
|
+
`imageUrl`, `logoUrl` and `symbolUrl` fields point at tcgpriser.se's own CDN, which is sized for
|
|
315
|
+
tcgpriser.se's own traffic, not for hotlinking from other sites and apps. **For best performance,
|
|
316
|
+
rehost these images on your own storage/CDN and cache them there** instead of linking to them
|
|
317
|
+
directly — one less hop, tuned to your own traffic and geography, and no dependency on
|
|
318
|
+
infrastructure that isn't yours.
|
|
319
|
+
|
|
320
|
+
A simple way to do this: fetch the image once, save it under the URL's path (e.g.
|
|
321
|
+
`products/eng-scarlet-violet-booster-pack.png`) as a stable local key, serve it from your own
|
|
322
|
+
storage from then on, and periodically re-fetch (a nightly job is plenty) using a conditional
|
|
323
|
+
`GET` so you only pay for images that actually changed:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
327
|
+
import { dirname, join } from 'node:path';
|
|
328
|
+
|
|
329
|
+
const etags = new Map<string, string>(); // persist this however you persist anything else
|
|
330
|
+
|
|
331
|
+
async function rehostImage(imageUrl: string, cacheDir: string): Promise<string> {
|
|
332
|
+
const key = new URL(imageUrl).pathname.replace(/^\/[^/]+\//, ''); // "products/....webp"
|
|
333
|
+
const localPath = join(cacheDir, key);
|
|
334
|
+
const knownEtag = etags.get(key);
|
|
335
|
+
|
|
336
|
+
const res = await fetch(imageUrl, { headers: knownEtag ? { 'If-None-Match': knownEtag } : {} });
|
|
337
|
+
if (res.status === 304) return localPath; // unchanged since last sync
|
|
338
|
+
|
|
339
|
+
if (!res.ok) throw new Error(`Failed to fetch ${imageUrl}: ${res.status}`);
|
|
340
|
+
await mkdir(dirname(localPath), { recursive: true });
|
|
341
|
+
await writeFile(localPath, Buffer.from(await res.arrayBuffer()));
|
|
342
|
+
|
|
343
|
+
const etag = res.headers.get('etag');
|
|
344
|
+
if (etag) etags.set(key, etag);
|
|
345
|
+
return localPath;
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Swap the `fs`/`mkdir`/`writeFile` calls for your own storage's SDK (S3, R2, Cloudflare Images, ...)
|
|
350
|
+
if you're not caching to local disk. See `examples/rehost-images.ts` for a runnable version of this
|
|
351
|
+
against a live `tcgpriser` response.
|
|
352
|
+
|
|
259
353
|
## Scripts
|
|
260
354
|
|
|
261
355
|
### Build
|
|
@@ -290,6 +384,12 @@ yarn example
|
|
|
290
384
|
|
|
291
385
|
Runs `examples/basic.ts` against a local dev API. Set `TCGPRISER_AUTH_TOKEN` to see the premium call succeed instead of the expected 401.
|
|
292
386
|
|
|
387
|
+
```bash
|
|
388
|
+
yarn example:rehost-images
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Runs `examples/rehost-images.ts` — the "Images" section's rehosting pattern against a handful of real product images. Run it twice to see the second pass come back as `304`s.
|
|
392
|
+
|
|
293
393
|
## Scope
|
|
294
394
|
|
|
295
395
|
Covers the API's full documented surface: public catalog, price and bargain reads, plus the premium endpoints above. Not covered: the admin/scraper/auth surface, which isn't part of any published contract.
|
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) {
|
|
@@ -169,6 +171,21 @@ var CardsResource = class {
|
|
|
169
171
|
livePricing(idOrTechnicalName, options = {}) {
|
|
170
172
|
return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);
|
|
171
173
|
}
|
|
174
|
+
/** `GET /cards/{id}/pricing`: this card's current pricing snapshot — `retailPrice`,
|
|
175
|
+
* `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day
|
|
176
|
+
* by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,
|
|
177
|
+
* shorter-cached call for the part of a card that actually changes day to day. */
|
|
178
|
+
pricing(idOrTechnicalName) {
|
|
179
|
+
return this.http.get(`/cards/${encodeURIComponent(idOrTechnicalName)}/pricing`);
|
|
180
|
+
}
|
|
181
|
+
/** `GET /cards/pricing`: pricing for up to 200 cards in one request, keyed by `id` — the batch
|
|
182
|
+
* counterpart to `pricing()`, for a page of results (a search page, an expansion's contents) that
|
|
183
|
+
* needs pricing for many items at once. Unlike `get()`/`pricing()`, this only accepts `id`s, not
|
|
184
|
+
* technicalNames — pass the `id`s already on the cards you fetched. Ids with no match are
|
|
185
|
+
* silently omitted from the result rather than causing an error. */
|
|
186
|
+
pricingBatch(ids) {
|
|
187
|
+
return this.http.get(`/cards/pricing?ids=${ids.map(encodeURIComponent).join(",")}`);
|
|
188
|
+
}
|
|
172
189
|
};
|
|
173
190
|
|
|
174
191
|
// src/resources/expansions.ts
|
|
@@ -182,14 +199,38 @@ var ExpansionsResource = class {
|
|
|
182
199
|
const res = await this.http.get("/expansions");
|
|
183
200
|
return res.data;
|
|
184
201
|
}
|
|
185
|
-
/** `GET /expansions/{technicalName}
|
|
186
|
-
*
|
|
187
|
-
|
|
188
|
-
|
|
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
|
+
);
|
|
189
230
|
}
|
|
190
|
-
/** `GET /expansions/{technicalName}/products/live-pricing`: computed fresh for every
|
|
191
|
-
* this expansion, not read from the last stats job. Premium. */
|
|
192
|
-
|
|
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 = {}) {
|
|
193
234
|
return this.http.get(
|
|
194
235
|
`/expansions/${encodeURIComponent(technicalName)}/products/live-pricing`,
|
|
195
236
|
options
|
|
@@ -331,6 +372,21 @@ var ProductsResource = class {
|
|
|
331
372
|
livePricing(idOrTechnicalName, options = {}) {
|
|
332
373
|
return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing/live`, options);
|
|
333
374
|
}
|
|
375
|
+
/** `GET /product/{id}/pricing`: this product's current pricing snapshot — `retailPrice`,
|
|
376
|
+
* `estimatedValue`, `lowestShopOffer`, `referencePriceSnapshotsByProvider` — refreshed once a day
|
|
377
|
+
* by the nightly pricing/scraper jobs. `get()` returns content only; this is the separate,
|
|
378
|
+
* shorter-cached call for the part of a product that actually changes day to day. */
|
|
379
|
+
pricing(idOrTechnicalName) {
|
|
380
|
+
return this.http.get(`/product/${encodeURIComponent(idOrTechnicalName)}/pricing`);
|
|
381
|
+
}
|
|
382
|
+
/** `GET /product/pricing`: pricing for up to 200 sealed products in one request, keyed by `id` —
|
|
383
|
+
* the batch counterpart to `pricing()`, for a page of results (a search page, an expansion's
|
|
384
|
+
* contents) that needs pricing for many items at once. Unlike `get()`/`pricing()`, this only
|
|
385
|
+
* accepts `id`s, not technicalNames — pass the `id`s already on the products you fetched. Ids with
|
|
386
|
+
* no match are silently omitted from the result rather than causing an error. */
|
|
387
|
+
pricingBatch(ids) {
|
|
388
|
+
return this.http.get(`/product/pricing?ids=${ids.map(encodeURIComponent).join(",")}`);
|
|
389
|
+
}
|
|
334
390
|
};
|
|
335
391
|
|
|
336
392
|
// src/resources/shopMatchStats.ts
|
|
@@ -448,7 +504,7 @@ var TcgPriser = class {
|
|
|
448
504
|
packRates;
|
|
449
505
|
stats;
|
|
450
506
|
/**
|
|
451
|
-
* @param optionsOrAuthToken A subscriber
|
|
507
|
+
* @param optionsOrAuthToken A subscriber's API token (`new TcgPriser(myApiToken)`), a full
|
|
452
508
|
* `TcgPriserOptions` object, or omit it entirely for an anonymous, public-only client.
|
|
453
509
|
*/
|
|
454
510
|
constructor(optionsOrAuthToken) {
|