@pfdev/api-types 3.0.27 → 3.0.30
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/package.json +1 -1
- package/v3.ts +343 -5
package/package.json
CHANGED
package/v3.ts
CHANGED
|
@@ -457,7 +457,7 @@ export const SealedItemSchema = Type.Object(
|
|
|
457
457
|
set_name: Type.Optional(Type.String({ description: 'Name of the set' })),
|
|
458
458
|
product_slug: Type.Optional(Type.String({ description: 'Product URL slug' })),
|
|
459
459
|
set_slug: Type.Optional(Type.String({ description: 'Set URL slug' })),
|
|
460
|
-
image: Type.Optional(Type.String({ description: 'Product image URL' })),
|
|
460
|
+
image: Type.Optional(Type.String({ description: 'Product image URL (WebP on the Pokefolio CDN). Not every product has an image there yet.' })),
|
|
461
461
|
tcgp_id: Type.Optional(Type.Number({ description: 'TCGPlayer product ID' })),
|
|
462
462
|
language: Type.Optional(Type.String({ description: 'Product language' })),
|
|
463
463
|
price: Type.Optional(Type.Number({ description: 'Current market price' })),
|
|
@@ -473,7 +473,7 @@ export const SealedItemSchema = Type.Object(
|
|
|
473
473
|
change_3m_value: Type.Optional(Type.Number({ description: '90-day price change in dollars' })),
|
|
474
474
|
change_6m_value: Type.Optional(Type.Number({ description: '180-day price change in dollars' })),
|
|
475
475
|
change_1y_value: Type.Optional(Type.Number({ description: '1-year price change in dollars' })),
|
|
476
|
-
price_updated: Type.Optional(Type.String({ description: '
|
|
476
|
+
price_updated: Type.Optional(Type.String({ description: 'Date (YYYY-MM-DD) the price was last updated' }))
|
|
477
477
|
},
|
|
478
478
|
{
|
|
479
479
|
title: 'SealedItem',
|
|
@@ -497,18 +497,89 @@ export const SealedListResponseSchema = Type.Object(
|
|
|
497
497
|
|
|
498
498
|
export type SealedListResponse = Static<typeof SealedListResponseSchema>;
|
|
499
499
|
|
|
500
|
+
export const SealedListSortSchema = Type.Union([
|
|
501
|
+
Type.Literal('name_asc'),
|
|
502
|
+
Type.Literal('name_desc'),
|
|
503
|
+
Type.Literal('price_asc'),
|
|
504
|
+
Type.Literal('price_desc'),
|
|
505
|
+
Type.Literal('change_asc'),
|
|
506
|
+
Type.Literal('change_desc'),
|
|
507
|
+
Type.Literal('release_desc'),
|
|
508
|
+
Type.Literal('release_asc'),
|
|
509
|
+
Type.Literal('release_desc_price_desc')
|
|
510
|
+
], {
|
|
511
|
+
default: 'name_asc',
|
|
512
|
+
description: 'Sort order. change_* sorts by 1-day percentage price change. release_asc/desc sort by set release date, then name. release_desc_price_desc sorts by newest set, then price descending. Products with no price come last in every price and change sort. Defaults to name_asc.'
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
export type SealedListSort = Static<typeof SealedListSortSchema>;
|
|
516
|
+
|
|
517
|
+
// Filters shared by /sealed and /sealed/facets. Each is a comma-separated list:
|
|
518
|
+
// values within one param match with OR, different params combine with AND.
|
|
519
|
+
const SealedListFilterFields = {
|
|
520
|
+
setid: Type.Optional(Type.String({ description: 'Comma-separated set IDs (max 500)' })),
|
|
521
|
+
language: Type.Optional(Type.String({ description: 'Comma-separated language codes (EN, JP; max 50)' })),
|
|
522
|
+
search: Type.Optional(Type.String({ minLength: 1, description: 'Search by product name. Every word must match.' })),
|
|
523
|
+
name: Type.Optional(Type.String({ minLength: 1, description: 'Alias for search. Ignored when search is sent.' }))
|
|
524
|
+
};
|
|
525
|
+
|
|
500
526
|
export const SealedListQuerySchema = Type.Object(
|
|
501
527
|
{
|
|
502
|
-
|
|
503
|
-
|
|
528
|
+
...SealedListFilterFields,
|
|
529
|
+
sort: Type.Optional(SealedListSortSchema),
|
|
504
530
|
limit: Type.Optional(Type.Number({ minimum: 1, maximum: 250, default: 50, description: 'Max results to return' })),
|
|
505
531
|
offset: Type.Optional(Type.Number({ minimum: 0, default: 0, description: 'Pagination offset' }))
|
|
506
532
|
},
|
|
507
|
-
{ description: '
|
|
533
|
+
{ description: 'With no search or filters, lists every published product' }
|
|
508
534
|
);
|
|
509
535
|
|
|
510
536
|
export type SealedListQuery = Static<typeof SealedListQuerySchema>;
|
|
511
537
|
|
|
538
|
+
export const SealedFacetsQuerySchema = Type.Object(
|
|
539
|
+
SealedListFilterFields,
|
|
540
|
+
{ description: 'Same search and filters as /sealed. With none, returns the facets for every published product' }
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
export type SealedFacetsQuery = Static<typeof SealedFacetsQuerySchema>;
|
|
544
|
+
|
|
545
|
+
export const SealedFacetGroupSchema = Type.Object(
|
|
546
|
+
{
|
|
547
|
+
value: Type.String({ description: 'Group id, e.g. the series name' }),
|
|
548
|
+
label: Type.String({ description: 'Heading to show users' })
|
|
549
|
+
},
|
|
550
|
+
{ title: 'SealedFacetGroup' }
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
export const SealedFacetOptionSchema = Type.Object(
|
|
554
|
+
{
|
|
555
|
+
value: Type.String({ description: 'Value to send back in the matching filter param' }),
|
|
556
|
+
label: Type.String({ description: 'Label to show users' }),
|
|
557
|
+
count: Type.Integer({ description: 'Products this option matches, ignoring this facet\'s own selection' }),
|
|
558
|
+
order: Type.Optional(Type.Integer({ description: 'Display order, ascending: sets by release date, newest first (0 = newest); languages English first.' })),
|
|
559
|
+
group: Type.Optional(SealedFacetGroupSchema),
|
|
560
|
+
language: Type.Optional(Type.String({ description: 'Language code of the set (EN, JP). Set options only.' }))
|
|
561
|
+
},
|
|
562
|
+
{ title: 'SealedFacetOption' }
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
export type SealedFacetOption = Static<typeof SealedFacetOptionSchema>;
|
|
566
|
+
|
|
567
|
+
export const SealedFacetsResponseSchema = Type.Object(
|
|
568
|
+
{
|
|
569
|
+
total: Type.Integer({ description: 'Products matching search and all filters' }),
|
|
570
|
+
facets: Type.Object({
|
|
571
|
+
language: Type.Array(SealedFacetOptionSchema, { description: 'Value is the language code, label its name (e.g. JP, Japanese)' }),
|
|
572
|
+
set: Type.Array(SealedFacetOptionSchema, { description: 'Each option carries its series in group, omitted when the set has no series' })
|
|
573
|
+
})
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
title: 'SealedFacetsResponse',
|
|
577
|
+
description: 'Filter options for a sealed product search, with counts'
|
|
578
|
+
}
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
export type SealedFacetsResponse = Static<typeof SealedFacetsResponseSchema>;
|
|
582
|
+
|
|
512
583
|
// Path parameters
|
|
513
584
|
export const SealedDetailParamSchema = Type.Object({
|
|
514
585
|
sealedid: Type.String({ format: 'uuid', description: 'Sealed product ID' })
|
|
@@ -640,6 +711,192 @@ export const SetDetailParamSchema = Type.Object({
|
|
|
640
711
|
|
|
641
712
|
export type SetDetailParam = Static<typeof SetDetailParamSchema>;
|
|
642
713
|
|
|
714
|
+
// ============= COLLECTION =============
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
export const CollectionRangeSchema = Type.Union(
|
|
718
|
+
[
|
|
719
|
+
Type.Literal('1W'),
|
|
720
|
+
Type.Literal('1M'),
|
|
721
|
+
Type.Literal('3M'),
|
|
722
|
+
Type.Literal('6M'),
|
|
723
|
+
Type.Literal('1Y'),
|
|
724
|
+
Type.Literal('ALL')
|
|
725
|
+
],
|
|
726
|
+
{ description: 'Chart window and comparison period' }
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
export type CollectionRange = Static<typeof CollectionRangeSchema>;
|
|
730
|
+
|
|
731
|
+
export const CollectionGainersRangeSchema = Type.Union(
|
|
732
|
+
[
|
|
733
|
+
Type.Literal('1D'),
|
|
734
|
+
Type.Literal('1W'),
|
|
735
|
+
Type.Literal('1M'),
|
|
736
|
+
Type.Literal('3M'),
|
|
737
|
+
Type.Literal('6M'),
|
|
738
|
+
Type.Literal('1Y'),
|
|
739
|
+
Type.Literal('ALL')
|
|
740
|
+
],
|
|
741
|
+
{ description: 'Comparison period' }
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
export type CollectionGainersRange = Static<typeof CollectionGainersRangeSchema>;
|
|
745
|
+
|
|
746
|
+
const ComparisonRangeSchema = Type.Union(
|
|
747
|
+
[
|
|
748
|
+
Type.Literal('1D'),
|
|
749
|
+
Type.Literal('1W'),
|
|
750
|
+
Type.Literal('1M'),
|
|
751
|
+
Type.Literal('3M'),
|
|
752
|
+
Type.Literal('6M'),
|
|
753
|
+
Type.Literal('1Y')
|
|
754
|
+
],
|
|
755
|
+
{ description: 'Period the change was measured over. ALL is measured over 1Y, the longest past price available.' }
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
const AllocationFields = {
|
|
759
|
+
value: Type.Number({ description: 'Market value in USD' }),
|
|
760
|
+
items: Type.Integer({ description: 'Items owned, counting each copy' }),
|
|
761
|
+
no_price_count: Type.Integer({ description: 'Copies with no current price, counted in items but adding nothing to value' })
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
export const CollectionAllocationSchema = Type.Object(AllocationFields, { title: 'CollectionAllocation' });
|
|
765
|
+
|
|
766
|
+
export const CollectionCardAllocationSchema = Type.Object(
|
|
767
|
+
{
|
|
768
|
+
...AllocationFields,
|
|
769
|
+
assumed_raw_count: Type.Integer({
|
|
770
|
+
description: 'Graded copies valued at the raw price because their grade has no current price'
|
|
771
|
+
})
|
|
772
|
+
},
|
|
773
|
+
{ title: 'CollectionCardAllocation' }
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
export const CollectionSummaryResponseSchema = Type.Object(
|
|
777
|
+
{
|
|
778
|
+
total_value: Type.Number({ description: 'Market value of everything owned, in USD' }),
|
|
779
|
+
items: Type.Integer({ description: 'Items owned, counting each copy' }),
|
|
780
|
+
allocation: Type.Object({
|
|
781
|
+
cards: CollectionCardAllocationSchema,
|
|
782
|
+
sealed: CollectionAllocationSchema
|
|
783
|
+
})
|
|
784
|
+
},
|
|
785
|
+
{ title: 'CollectionSummaryResponse' }
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
export type CollectionSummaryResponse = Static<typeof CollectionSummaryResponseSchema>;
|
|
789
|
+
|
|
790
|
+
export const CollectionGainerSchema = Type.Object(
|
|
791
|
+
{
|
|
792
|
+
cardid: Type.String(),
|
|
793
|
+
variant_id: Type.Union([Type.Integer(), Type.Null()], { description: 'Variant id (pfdata_variant_definitions.id); matches variants[].id on cards. Null when the variant has no definition.' }),
|
|
794
|
+
grade: Type.Union([Type.String(), Type.Null()], { description: 'Null for ungraded copies' }),
|
|
795
|
+
quantity: Type.Integer({ description: 'Copies owned of this card, variant and grade' }),
|
|
796
|
+
name: Type.String(),
|
|
797
|
+
number: Type.Union([Type.String(), Type.Null()]),
|
|
798
|
+
image: Type.Union([Type.String(), Type.Null()], { description: 'Small card image URL' }),
|
|
799
|
+
setid: Type.Union([Type.String(), Type.Null()]),
|
|
800
|
+
setname: Type.Union([Type.String(), Type.Null()]),
|
|
801
|
+
current_price: Type.Number({ description: 'Current market price of one copy, in USD' }),
|
|
802
|
+
past_price: Type.Number({ description: 'Market price of one copy at the start of the period, in USD' }),
|
|
803
|
+
change_value: Type.Number({ description: 'Price change of one copy over the period, in USD' }),
|
|
804
|
+
change_percent: Type.Number({ description: 'Price change over the period, as a percentage of past_price' })
|
|
805
|
+
},
|
|
806
|
+
{ title: 'CollectionGainer' }
|
|
807
|
+
);
|
|
808
|
+
|
|
809
|
+
export type CollectionGainer = Static<typeof CollectionGainerSchema>;
|
|
810
|
+
|
|
811
|
+
export const CollectionChartPointSchema = Type.Object(
|
|
812
|
+
{
|
|
813
|
+
date: Type.String({ description: 'YYYY-MM-DD' }),
|
|
814
|
+
value: Type.Number({ description: 'Collection value in USD' })
|
|
815
|
+
},
|
|
816
|
+
{ title: 'CollectionChartPoint' }
|
|
817
|
+
);
|
|
818
|
+
|
|
819
|
+
export type CollectionChartPoint = Static<typeof CollectionChartPointSchema>;
|
|
820
|
+
|
|
821
|
+
export const CollectionPerformanceQuerySchema = Type.Object({
|
|
822
|
+
range: Type.Optional(Type.Union(CollectionRangeSchema.anyOf, { default: '1M', description: 'Chart window and comparison period' }))
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
export type CollectionPerformanceQuery = Static<typeof CollectionPerformanceQuerySchema>;
|
|
826
|
+
|
|
827
|
+
export const CollectionPerformanceResponseSchema = Type.Object(
|
|
828
|
+
{
|
|
829
|
+
range: CollectionRangeSchema,
|
|
830
|
+
comparison_range: ComparisonRangeSchema,
|
|
831
|
+
current_value: Type.Number({ description: 'Market value of everything owned, in USD' }),
|
|
832
|
+
change_value: Type.Number({ description: 'Market price change of what is owned now, in USD. Adding or removing items does not move it.' }),
|
|
833
|
+
change_percent: Type.Union([Type.Number(), Type.Null()], { description: 'change_value as a percentage of the items\' past value. Null when no item has a past price.' }),
|
|
834
|
+
points: Type.Array(CollectionChartPointSchema, { description: 'Collection value over time, oldest first, at most 180 points. The last point is the current value.' }),
|
|
835
|
+
gainers: Type.Array(CollectionGainerSchema, { description: 'Top 4 cards by price change in USD' })
|
|
836
|
+
},
|
|
837
|
+
{ title: 'CollectionPerformanceResponse' }
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
export type CollectionPerformanceResponse = Static<typeof CollectionPerformanceResponseSchema>;
|
|
841
|
+
|
|
842
|
+
export const CollectionGainersSortSchema = Type.Union(
|
|
843
|
+
[Type.Literal('value'), Type.Literal('percent')],
|
|
844
|
+
{ description: 'value = largest USD change first, percent = largest percentage change first' }
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
export type CollectionGainersSort = Static<typeof CollectionGainersSortSchema>;
|
|
848
|
+
|
|
849
|
+
export const CollectionGainersQuerySchema = Type.Object({
|
|
850
|
+
range: Type.Optional(Type.Union(CollectionGainersRangeSchema.anyOf, { default: '1M', description: 'Comparison period' })),
|
|
851
|
+
sort: Type.Optional(Type.Union(CollectionGainersSortSchema.anyOf, { default: 'value', description: 'value = largest USD change first, percent = largest percentage change first' })),
|
|
852
|
+
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 100, default: 25, description: 'Max results to return' })),
|
|
853
|
+
offset: Type.Optional(Type.Integer({ minimum: 0, default: 0 }))
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
export type CollectionGainersQuery = Static<typeof CollectionGainersQuerySchema>;
|
|
857
|
+
|
|
858
|
+
export const CollectionGainersResponseSchema = Type.Object(
|
|
859
|
+
{
|
|
860
|
+
range: CollectionGainersRangeSchema,
|
|
861
|
+
comparison_range: ComparisonRangeSchema,
|
|
862
|
+
total: Type.Integer({ description: 'Cards that gained over the period, across all pages' }),
|
|
863
|
+
items: Type.Array(CollectionGainerSchema)
|
|
864
|
+
},
|
|
865
|
+
{ title: 'CollectionGainersResponse' }
|
|
866
|
+
);
|
|
867
|
+
|
|
868
|
+
export type CollectionGainersResponse = Static<typeof CollectionGainersResponseSchema>;
|
|
869
|
+
|
|
870
|
+
export const CollectionSetsQuerySchema = Type.Object({
|
|
871
|
+
limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 250, default: 3, description: 'Max results to return' })),
|
|
872
|
+
offset: Type.Optional(Type.Integer({ minimum: 0, default: 0 }))
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
export type CollectionSetsQuery = Static<typeof CollectionSetsQuerySchema>;
|
|
876
|
+
|
|
877
|
+
export const CollectionSetSchema = Type.Object(
|
|
878
|
+
{
|
|
879
|
+
setid: Type.String(),
|
|
880
|
+
name: Type.String(),
|
|
881
|
+
slug: Type.Union([Type.String(), Type.Null()]),
|
|
882
|
+
imglogo: Type.Union([Type.String(), Type.Null()]),
|
|
883
|
+
imgsymbol: Type.Union([Type.String(), Type.Null()]),
|
|
884
|
+
total: Type.Integer({ description: 'Cards in the set' }),
|
|
885
|
+
collected: Type.Integer({ description: 'Distinct cards of this set the user owns' }),
|
|
886
|
+
percent: Type.Number({ description: 'collected as a percentage of total, at most 100' })
|
|
887
|
+
},
|
|
888
|
+
{ title: 'CollectionSet' }
|
|
889
|
+
);
|
|
890
|
+
|
|
891
|
+
export type CollectionSet = Static<typeof CollectionSetSchema>;
|
|
892
|
+
|
|
893
|
+
export const CollectionSetsResponseSchema = Type.Array(CollectionSetSchema, {
|
|
894
|
+
title: 'CollectionSetsResponse',
|
|
895
|
+
description: 'Sets the user has started, most collected cards first.'
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
export type CollectionSetsResponse = Static<typeof CollectionSetsResponseSchema>;
|
|
899
|
+
|
|
643
900
|
// ============= LISTS =============
|
|
644
901
|
|
|
645
902
|
|
|
@@ -882,6 +1139,9 @@ export const InventorySummaryItemSchema = Type.Object(
|
|
|
882
1139
|
status: Type.Union([Type.Number(), Type.Null()], {
|
|
883
1140
|
description: 'Numeric status code. <100 = active, >=100 = sold/past. Null when no details row exists yet.'
|
|
884
1141
|
}),
|
|
1142
|
+
grade: Type.Union([Type.String(), Type.Null()], {
|
|
1143
|
+
description: 'Grade of this copy (e.g. "PSA 10"), matching a key of variants[].graded. Null when ungraded or no details row exists yet.'
|
|
1144
|
+
}),
|
|
885
1145
|
acquired: Type.Union([Type.String(), Type.Null()], {
|
|
886
1146
|
description: 'User-entered acquired date. Null when not set or no details row exists yet.'
|
|
887
1147
|
}),
|
|
@@ -1014,6 +1274,84 @@ export const InventoryPatchRequestSchema = Type.Object(
|
|
|
1014
1274
|
|
|
1015
1275
|
export type InventoryPatchRequest = Static<typeof InventoryPatchRequestSchema>;
|
|
1016
1276
|
|
|
1277
|
+
// ============= SEALED =============
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
export const SealedQuantitiesQuerySchema = Type.Object({
|
|
1281
|
+
setid: Type.Optional(Type.String({ minLength: 1, description: 'Only products in this set. If omitted, returns every product the user owns.' }))
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1284
|
+
export type SealedQuantitiesQuery = Static<typeof SealedQuantitiesQuerySchema>;
|
|
1285
|
+
|
|
1286
|
+
export const SealedQuantitySchema = Type.Object(
|
|
1287
|
+
{
|
|
1288
|
+
sealedid: Type.String({ format: 'uuid', description: 'Sealed product ID' }),
|
|
1289
|
+
quantity: Type.Integer({ description: 'Copies the user currently owns. Sold copies are not counted.' })
|
|
1290
|
+
},
|
|
1291
|
+
{ title: 'SealedQuantity' }
|
|
1292
|
+
);
|
|
1293
|
+
|
|
1294
|
+
export const SealedQuantitiesResponseSchema = Type.Array(SealedQuantitySchema, {
|
|
1295
|
+
title: 'SealedQuantitiesResponse',
|
|
1296
|
+
description: 'One entry per product the user owns. Products they don\'t own are left out.'
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
export const SealedInventoryAddRequestSchema = Type.Object(
|
|
1300
|
+
{
|
|
1301
|
+
sealedid: Type.String({ format: 'uuid', description: 'Published sealed product to add one copy of' })
|
|
1302
|
+
},
|
|
1303
|
+
{ title: 'SealedInventoryAddRequest' }
|
|
1304
|
+
);
|
|
1305
|
+
|
|
1306
|
+
export type SealedInventoryAddRequest = Static<typeof SealedInventoryAddRequestSchema>;
|
|
1307
|
+
|
|
1308
|
+
export const SealedInventoryRowSchema = Type.Object(
|
|
1309
|
+
{
|
|
1310
|
+
uuid: Type.String({ format: 'uuid', description: 'Unique ID of this copy' }),
|
|
1311
|
+
sealedid: Type.String({ format: 'uuid', description: 'Sealed product this copy belongs to' }),
|
|
1312
|
+
status: Type.Union([Type.Number(), Type.Null()], {
|
|
1313
|
+
description: 'Numeric status code. <100 = active, >=100 = sold/past. Null when not set.'
|
|
1314
|
+
}),
|
|
1315
|
+
acquired: Type.Union([Type.String(), Type.Null()], {
|
|
1316
|
+
description: 'User-entered acquired date (YYYY-MM-DD). Null when not set.'
|
|
1317
|
+
}),
|
|
1318
|
+
created_at: Type.String({ description: 'When this copy was added' })
|
|
1319
|
+
},
|
|
1320
|
+
{ title: 'SealedInventoryRow' }
|
|
1321
|
+
);
|
|
1322
|
+
|
|
1323
|
+
export const SealedInventoryItemsQuerySchema = Type.Object({
|
|
1324
|
+
sealedid: Type.String({ format: 'uuid', description: 'Sealed product to fetch copies for' })
|
|
1325
|
+
});
|
|
1326
|
+
|
|
1327
|
+
export type SealedInventoryItemsQuery = Static<typeof SealedInventoryItemsQuerySchema>;
|
|
1328
|
+
|
|
1329
|
+
export const SealedInventoryItemSchema = Type.Object(
|
|
1330
|
+
{
|
|
1331
|
+
...SealedInventoryRowSchema.properties,
|
|
1332
|
+
notes: Type.Union([Type.String(), Type.Null()]),
|
|
1333
|
+
total_cost_usd: Type.Number(),
|
|
1334
|
+
total_income_usd: Type.Number(),
|
|
1335
|
+
profit_loss_usd: Type.Number(),
|
|
1336
|
+
transactions: Type.Array(InventoryTransactionSchema)
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
title: 'SealedInventoryItem',
|
|
1340
|
+
description: 'One owned copy of a sealed product, including transactions and aggregated totals.'
|
|
1341
|
+
}
|
|
1342
|
+
);
|
|
1343
|
+
|
|
1344
|
+
export const SealedInventoryItemsResponseSchema = Type.Array(SealedInventoryItemSchema, {
|
|
1345
|
+
title: 'SealedInventoryItemsResponse',
|
|
1346
|
+
description: 'Copies the user currently owns of one product, newest first. Sold copies are left out, so the length matches quantity.'
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1349
|
+
export const SealedInventoryDeleteParamSchema = Type.Object({
|
|
1350
|
+
uuid: Type.String({ format: 'uuid', description: 'UUID of the copy to delete' })
|
|
1351
|
+
});
|
|
1352
|
+
|
|
1353
|
+
export type SealedInventoryDeleteParam = Static<typeof SealedInventoryDeleteParamSchema>;
|
|
1354
|
+
|
|
1017
1355
|
// ============= VISION =============
|
|
1018
1356
|
|
|
1019
1357
|
|