@pfdev/api-types 3.0.6 → 3.0.11

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/v3.ts +293 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pfdev/api-types",
3
- "version": "3.0.6",
3
+ "version": "3.0.11",
4
4
  "description": "TypeScript types for PF API V3",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",
package/v3.ts CHANGED
@@ -7,10 +7,9 @@ import { Static, Type } from '@sinclair/typebox';
7
7
  // ============= CARDS =============
8
8
 
9
9
 
10
- const VariantPriceSchema = Type.Object(
10
+ const PriceStatsSchema = Type.Object(
11
11
  {
12
- variant: Type.String({ description: 'Variant name' }),
13
- current_price: Type.Optional(Type.Number({ description: 'Current price for this variant' })),
12
+ current_price: Type.Optional(Type.Number({ description: 'Current price' })),
14
13
  change_1d: Type.Optional(Type.Number({ description: '1-day price change as a percentage' })),
15
14
  change_7d: Type.Optional(Type.Number({ description: '7-day price change as a percentage' })),
16
15
  change_1m: Type.Optional(Type.Number({ description: '30-day price change as a percentage' })),
@@ -18,7 +17,7 @@ const VariantPriceSchema = Type.Object(
18
17
  change_6m: Type.Optional(Type.Number({ description: '180-day price change as a percentage' })),
19
18
  change_1y: Type.Optional(Type.Number({ description: '1-year price change as a percentage' }))
20
19
  },
21
- { title: 'VariantPrice' }
20
+ { title: 'PriceStats' }
22
21
  );
23
22
 
24
23
  const CardImagesSchema = Type.Object(
@@ -77,6 +76,33 @@ export const CardListQuerySchema = Type.Object(
77
76
 
78
77
  export type CardListQuery = Static<typeof CardListQuerySchema>;
79
78
 
79
+ export const CardSearchSortSchema = Type.Union([
80
+ Type.Literal('number_asc'),
81
+ Type.Literal('number_desc'),
82
+ Type.Literal('name_asc'),
83
+ Type.Literal('name_desc'),
84
+ Type.Literal('price_asc'),
85
+ Type.Literal('price_desc')
86
+ ]);
87
+
88
+ export type CardSearchSort = Static<typeof CardSearchSortSchema>;
89
+
90
+ export const CardSearchQuerySchema = Type.Object({
91
+ q: Type.String({ minLength: 1, description: 'Search query. Tokens with digits match card number; other tokens match card name.' }),
92
+ sort: Type.Optional(Type.Union([
93
+ Type.Literal('number_asc'),
94
+ Type.Literal('number_desc'),
95
+ Type.Literal('name_asc'),
96
+ Type.Literal('name_desc'),
97
+ Type.Literal('price_asc'),
98
+ Type.Literal('price_desc')
99
+ ], { default: 'number_asc', description: 'Sort order. Defaults to number_asc.' })),
100
+ limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 25, description: 'Max results to return' })),
101
+ offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: 'Pagination offset' }))
102
+ });
103
+
104
+ export type CardSearchQuery = Static<typeof CardSearchQuerySchema>;
105
+
80
106
  export const CardDetailSchema = Type.Object(
81
107
  {
82
108
  cardid: Type.String({ description: 'Unique card identifier' }),
@@ -109,7 +135,16 @@ export const CardDetailSchema = Type.Object(
109
135
  change_1d: Type.Optional(Type.Number({ description: '1-day price change as a percentage' })),
110
136
  change_1d_value: Type.Optional(Type.Number({ description: '1-day price change in dollars' })),
111
137
  variants: Type.Optional(Type.Array(Type.String(), { description: 'Available variants for this card' })),
112
- variant_prices: Type.Optional(Type.Array(VariantPriceSchema, { description: 'Per-variant prices with extended period changes' }))
138
+ variant_prices: Type.Optional(
139
+ Type.Record(Type.String(), PriceStatsSchema, { description: 'Prices and period changes keyed by variant name' })
140
+ ),
141
+ graded_variants_prices: Type.Optional(
142
+ Type.Record(
143
+ Type.String(),
144
+ Type.Record(Type.String(), PriceStatsSchema),
145
+ { description: 'Graded prices and period changes keyed by variant then grade' }
146
+ )
147
+ )
113
148
  },
114
149
  {
115
150
  title: 'CardDetail',
@@ -125,6 +160,197 @@ export const CardDetailParamSchema = Type.Object({
125
160
 
126
161
  export type CardDetailParam = Static<typeof CardDetailParamSchema>;
127
162
 
163
+ const PricePointSchema = Type.Object(
164
+ {
165
+ date: Type.String({ description: 'Date of the price point' }),
166
+ price: Type.Number({ description: 'Price on this date' }),
167
+ variant: Type.String({ description: 'Card variant' }),
168
+ grade: Type.Optional(Type.String({ description: 'Grade (graded cards only)' }))
169
+ },
170
+ { title: 'PricePoint' }
171
+ );
172
+
173
+ export const CardPricesQuerySchema = Type.Object({
174
+ interval: Type.Number({ minimum: 1, maximum: 1825, default: 30, description: 'Number of days of price history to return' }),
175
+ variant: Type.Optional(Type.String({ description: 'Variant name. If omitted, returns all variants.' })),
176
+ grade: Type.Optional(Type.String({ description: 'Grade (e.g. "PSA 10", "BGS 9.5"). Omit or use "RAW" for ungraded.' })),
177
+ source: Type.Optional(Type.Union(
178
+ [Type.Literal('tcgplayer'), Type.Literal('ebay')],
179
+ { description: 'Price source. Inferred from grade if omitted: RAW → tcgplayer, graded → ebay.' }
180
+ ))
181
+ });
182
+
183
+ export type CardPricesQuery = Static<typeof CardPricesQuerySchema>;
184
+
185
+ export const CardPricesResponseSchema = Type.Object(
186
+ {
187
+ cardid: Type.String({ description: 'Card ID' }),
188
+ variant: Type.Optional(Type.String({ description: 'Filtered variant, if specified' })),
189
+ grade: Type.String({ description: 'Resolved grade used for the query' }),
190
+ source: Type.String({ description: 'Resolved price source used for the query' }),
191
+ interval: Type.Number({ description: 'Number of days of history returned' }),
192
+ data: Type.Array(PricePointSchema, { description: 'Price history data points, ordered by date ascending' })
193
+ },
194
+ {
195
+ title: 'CardPricesResponse',
196
+ description: 'Price history for a card, suitable for charting'
197
+ }
198
+ );
199
+
200
+ export type CardPricesResponse = Static<typeof CardPricesResponseSchema>;
201
+
202
+ const SaleRecordSchema = Type.Object(
203
+ {
204
+ sold_date: Type.String({ description: 'Date the card was sold' }),
205
+ price: Type.Number({ description: 'Sale price' }),
206
+ grade: Type.String({ description: 'Grade at time of sale' }),
207
+ variant: Type.String({ description: 'Card variant' }),
208
+ title: Type.Optional(Type.String({ description: 'eBay listing title' })),
209
+ url: Type.Optional(Type.String({ description: 'eBay listing URL' })),
210
+ image_url: Type.Optional(Type.String({ description: 'Listing image URL' })),
211
+ seller_username: Type.Optional(Type.String({ description: 'eBay seller username' }))
212
+ },
213
+ { title: 'SaleRecord' }
214
+ );
215
+
216
+ export const CardSalesQuerySchema = Type.Object({
217
+ grade: Type.Optional(Type.String({ description: 'Filter by grade (e.g. "PSA 10"). Returns all grades if omitted.' })),
218
+ variant: Type.Optional(Type.String({ description: 'Filter by variant. Returns all variants if omitted.' })),
219
+ limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100, default: 25, description: 'Max results to return' })),
220
+ offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: 'Pagination offset' }))
221
+ });
222
+
223
+ export type CardSalesQuery = Static<typeof CardSalesQuerySchema>;
224
+
225
+ export const CardSalesResponseSchema = Type.Object(
226
+ {
227
+ cardid: Type.String({ description: 'Card ID' }),
228
+ grade: Type.Optional(Type.String({ description: 'Filtered grade, if specified' })),
229
+ variant: Type.Optional(Type.String({ description: 'Filtered variant, if specified' })),
230
+ data: Type.Array(SaleRecordSchema, { description: 'Individual eBay sold listings, most recent first' }),
231
+ total: Type.Number({ description: 'Total matching sales records' }),
232
+ count: Type.Number({ description: 'Records returned in this response' })
233
+ },
234
+ {
235
+ title: 'CardSalesResponse',
236
+ description: 'Individual eBay sold listings for a graded card'
237
+ }
238
+ );
239
+
240
+ export type CardSalesResponse = Static<typeof CardSalesResponseSchema>;
241
+
242
+ // ============= CURRENCY =============
243
+
244
+
245
+ export const CurrencyResponseSchema = Type.Object({
246
+ success: Type.Boolean(),
247
+ timestamp: Type.Number(),
248
+ date: Type.String(),
249
+ base: Type.String(),
250
+ rates: Type.Record(Type.String(), Type.Number())
251
+ });
252
+
253
+ export type CurrencyResponse = Static<typeof CurrencyResponseSchema>;
254
+
255
+ // ============= SEALED =============
256
+
257
+
258
+ export const SealedItemSchema = Type.Object(
259
+ {
260
+ sealedid: Type.String({ format: 'uuid', description: 'Unique sealed product identifier' }),
261
+ name: Type.String({ description: 'Product name' }),
262
+ setid: Type.String({ description: 'Set this product belongs to' }),
263
+ set_name: Type.Optional(Type.String({ description: 'Name of the set' })),
264
+ product_slug: Type.Optional(Type.String({ description: 'Product URL slug' })),
265
+ set_slug: Type.Optional(Type.String({ description: 'Set URL slug' })),
266
+ image: Type.Optional(Type.String({ description: 'Product image URL' })),
267
+ tcgp_id: Type.Optional(Type.Number({ description: 'TCGPlayer product ID' })),
268
+ language: Type.Optional(Type.String({ description: 'Product language' })),
269
+ price: Type.Optional(Type.Number({ description: 'Current market price' })),
270
+ change_1d: Type.Optional(Type.Number({ description: '1-day price change %' })),
271
+ change_7d: Type.Optional(Type.Number({ description: '7-day price change %' })),
272
+ change_1m: Type.Optional(Type.Number({ description: '30-day price change %' })),
273
+ change_3m: Type.Optional(Type.Number({ description: '90-day price change %' })),
274
+ change_6m: Type.Optional(Type.Number({ description: '180-day price change %' })),
275
+ change_1y: Type.Optional(Type.Number({ description: '1-year price change %' })),
276
+ change_1d_value: Type.Optional(Type.Number({ description: '1-day price change in dollars' })),
277
+ change_7d_value: Type.Optional(Type.Number({ description: '7-day price change in dollars' })),
278
+ change_1m_value: Type.Optional(Type.Number({ description: '30-day price change in dollars' })),
279
+ change_3m_value: Type.Optional(Type.Number({ description: '90-day price change in dollars' })),
280
+ change_6m_value: Type.Optional(Type.Number({ description: '180-day price change in dollars' })),
281
+ change_1y_value: Type.Optional(Type.Number({ description: '1-year price change in dollars' })),
282
+ price_updated: Type.Optional(Type.String({ description: 'Timestamp of last price update' }))
283
+ },
284
+ {
285
+ title: 'SealedItem',
286
+ description: 'A sealed Pokemon product'
287
+ }
288
+ );
289
+
290
+ export type SealedItem = Static<typeof SealedItemSchema>;
291
+
292
+ export const SealedListResponseSchema = Type.Object(
293
+ {
294
+ data: Type.Array(SealedItemSchema, { description: 'Array of sealed products' }),
295
+ total: Type.Number({ description: 'Total number of products matching query' }),
296
+ count: Type.Number({ description: 'Number of products returned in this response' })
297
+ },
298
+ {
299
+ title: 'SealedListResponse',
300
+ description: 'Paginated list of sealed Pokemon products'
301
+ }
302
+ );
303
+
304
+ export type SealedListResponse = Static<typeof SealedListResponseSchema>;
305
+
306
+ export const SealedListQuerySchema = Type.Object(
307
+ {
308
+ setid: Type.Optional(Type.String({ description: 'Filter by set ID' })),
309
+ name: Type.Optional(Type.String({ description: 'Search by product name' })),
310
+ limit: Type.Optional(Type.Number({ minimum: 1, maximum: 250, default: 50, description: 'Max results to return' })),
311
+ offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: 'Pagination offset' }))
312
+ },
313
+ { description: 'At least one of setid or name must be provided' }
314
+ );
315
+
316
+ export type SealedListQuery = Static<typeof SealedListQuerySchema>;
317
+
318
+ // Path parameters
319
+ export const SealedDetailParamSchema = Type.Object({
320
+ sealedid: Type.String({ format: 'uuid', description: 'Sealed product ID' })
321
+ });
322
+
323
+ export type SealedDetailParam = Static<typeof SealedDetailParamSchema>;
324
+
325
+ // Prices endpoint
326
+ const SealedPricePointSchema = Type.Object(
327
+ {
328
+ date: Type.String({ description: 'Date of the price point' }),
329
+ price: Type.Number({ description: 'Price on this date' })
330
+ },
331
+ { title: 'SealedPricePoint' }
332
+ );
333
+
334
+ export const SealedPricesQuerySchema = Type.Object({
335
+ interval: Type.Optional(Type.Number({ minimum: 1, maximum: 1825, default: 30, description: 'Number of days of price history to return' }))
336
+ });
337
+
338
+ export type SealedPricesQuery = Static<typeof SealedPricesQuerySchema>;
339
+
340
+ export const SealedPricesResponseSchema = Type.Object(
341
+ {
342
+ sealedid: Type.String({ format: 'uuid', description: 'Sealed product ID' }),
343
+ interval: Type.Number({ description: 'Number of days of history returned' }),
344
+ data: Type.Array(SealedPricePointSchema, { description: 'Price history data points, ordered by date ascending' })
345
+ },
346
+ {
347
+ title: 'SealedPricesResponse',
348
+ description: 'Price history for a sealed product, suitable for charting'
349
+ }
350
+ );
351
+
352
+ export type SealedPricesResponse = Static<typeof SealedPricesResponseSchema>;
353
+
128
354
  // ============= SETS =============
129
355
 
130
356
 
@@ -219,3 +445,65 @@ export const SetDetailParamSchema = Type.Object({
219
445
  });
220
446
 
221
447
  export type SetDetailParam = Static<typeof SetDetailParamSchema>;
448
+
449
+ // ============= VISION =============
450
+
451
+
452
+ const VariantPriceSchema = Type.Object(
453
+ {
454
+ variant: Type.String(),
455
+ current_price: Type.Optional(Type.Number()),
456
+ change_1d: Type.Optional(Type.Number()),
457
+ change_7d: Type.Optional(Type.Number()),
458
+ change_1m: Type.Optional(Type.Number()),
459
+ change_3m: Type.Optional(Type.Number()),
460
+ change_6m: Type.Optional(Type.Number()),
461
+ change_1y: Type.Optional(Type.Number())
462
+ },
463
+ { title: 'VisionVariantPrice' }
464
+ );
465
+
466
+ const DetectedCardSchema = Type.Object(
467
+ {
468
+ name: Type.String({ description: 'Card name from image recognition' }),
469
+ number: Type.Optional(Type.String({ description: 'Card number from image recognition' })),
470
+ releaseName: Type.Optional(Type.String({ description: 'Set/release name from image recognition' })),
471
+ setName: Type.Optional(Type.String({ description: 'Sub-set name from image recognition' })),
472
+ year: Type.Optional(Type.String({ description: 'Release year from image recognition' })),
473
+ manufacturer: Type.Optional(Type.String({ description: 'Card manufacturer' }))
474
+ },
475
+ { title: 'DetectedCard' }
476
+ );
477
+
478
+ const MatchedCardSchema = Type.Intersect(
479
+ [
480
+ CardSchema,
481
+ Type.Object({
482
+ score: Type.Number({ description: 'Fuzzy match score — higher is a better match' }),
483
+ variant_prices: Type.Array(VariantPriceSchema, { description: 'Per-variant prices with extended period changes' })
484
+ })
485
+ ],
486
+ { title: 'MatchedCard' }
487
+ );
488
+
489
+ export const VisionBodySchema = Type.Object(
490
+ {
491
+ file: Type.Any({ description: 'Card image file to identify', format: 'binary' })
492
+ },
493
+ { title: 'VisionBody' }
494
+ );
495
+
496
+ export type VisionBody = Static<typeof VisionBodySchema>;
497
+
498
+ export const VisionResponseSchema = Type.Object(
499
+ {
500
+ detection: Type.Union([DetectedCardSchema, Type.Null()], { description: 'Raw detection result from image recognition' }),
501
+ cards: Type.Optional(Type.Array(MatchedCardSchema, { description: 'Matched cards from database, ordered by score descending' }))
502
+ },
503
+ {
504
+ title: 'VisionResponse',
505
+ description: 'Card image recognition result with matched database cards'
506
+ }
507
+ );
508
+
509
+ export type VisionResponse = Static<typeof VisionResponseSchema>;