Skip to content

Commit 9d653a4

Browse files
authored
Simpler card model (#34)
* newlines for doc comments * drop primitives * revise attraction lights * drop EnumLike fields * reduce constants * revise card model * fix legalities entry * revise doc * revise doc * cleanup: rm primitives.ts * finish merging in root types for single/double sided split cards * restore AnyMultiFaced * update doc * revise group definitions * further revise groups * revise doc * use a link here too * improve card doc * trim whitespace
1 parent 11284c7 commit 9d653a4

33 files changed

+722
-471
lines changed

src/internal/Primitives.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/internal/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/objects/Card/Card.ts

Lines changed: 84 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,27 @@ import { ScryfallLayout, ScryfallLayoutGroup } from "./values";
33
import { ScryfallCardFace } from "./CardFace";
44
import { ScryfallCardFields } from "./CardFields";
55

6-
type Layout<T extends ScryfallLayout> = Pick<ScryfallCardFields.Core.All, "layout"> & {
7-
layout: T | `${T}`;
6+
type Layout<T extends `${ScryfallLayout}`> = Pick<ScryfallCardFields.Core.All, "layout"> & {
7+
layout: `${T}`;
88
};
99

1010
/**
1111
* A collection of types representing Scryfall cards of each possible layout.
1212
*
13-
*
14-
* An individual type exists for each possible layout: {@link ScryfallCard.Normal}, {@link ScryfallCard.Transform}, etc.
15-
*
16-
* Then various groups exist to help describe cards of indeterminate layout:
17-
* - {@link ScryfallCard.Any} describes any card at all. Think of it as like `any` but for cards.
13+
* This collection is focused around four core varieties of cards:
1814
* - {@link ScryfallCard.AnySingleFaced} describes any card with one face and no `card_faces` property, e.g. {@link ScryfallCard.Normal Normal} or {@link ScryfallCard.Saga Saga}.
19-
* - {@link ScryfallCard.AnyMultiFaced} describes any card with multiple faces. It may be a split card with both "faces" on the front, or a double-sided card with faces on the front and back of the card. It also collects the next two groups on this list.
2015
* - {@link ScryfallCard.AnySingleSidedSplit} describes any card with multiple faces where both faces are on the front, e.g. {@link ScryfallCard.Adventure Adventure}, {@link ScryfallCard.Flip Flip}, or {@link ScryfallCard.Split Split}.
2116
* - {@link ScryfallCard.AnyDoubleSidedSplit} describes any card with multiple faces where the faces are on the front and back of the card, e.g. {@link ScryfallCard.Transform Transform}, {@link ScryfallCard.ModalDfc ModalDfc}, or {@link ScryfallCard.ReversibleCard ReversibleCard}.
17+
* - {@link ScryfallCard.ReversibleCard} describes solely reversible cards.
18+
*
19+
* It also provides broader groupings:
20+
* - {@link ScryfallCard.Any} describes any card at all. Think of it as like `any` but for cards.
21+
* - {@link ScryfallCard.AnySplit} is an alias for either AnySingleSidedSplit or AnyDoubleSidedSplit.
22+
* - {@link ScryfallCard.AnyMultiFaced} is an alias for AnySingleSidedSplit, AnyDoubleSidedSplit, or Reversible. This describes all layouts that can have a `card_faces` field.
2223
*
23-
* We recommend starting from `ScryfallCard.Any` to describe generic API responses, and you will need to do type narrowing to access more specific fields.
24+
* There is also an alias for each possible layout: {@link ScryfallCard.Normal}, {@link ScryfallCard.Transform}, etc.
25+
*
26+
* We recommend starting from {@link ScryfallCard.Any} to describe generic API responses, and you will need to do type narrowing to access more specific fields.
2427
*
2528
* @example // Type narrowing by layout
2629
* const mysteryCard: ScryfallCard.Any = getCard();
@@ -45,9 +48,16 @@ type Layout<T extends ScryfallLayout> = Pick<ScryfallCardFields.Core.All, "layou
4548
export namespace ScryfallCard {
4649
/** The abstract root implementation of cards. */
4750
export type AbstractCard = ScryfallObject.Object<ScryfallObject.ObjectType.Card> & ScryfallCardFields.Core.All;
51+
}
4852

49-
type SingleFace = AbstractCard &
50-
Layout<ScryfallLayoutGroup.SingleFaceType> &
53+
export namespace ScryfallCard {
54+
/**
55+
* Any card with a single-faced layout.
56+
*
57+
* Examples: {@link ScryfallLayout.Normal}, {@link ScryfallLayout.Mutate}, {@link ScryfallLayout.Token}.
58+
*/
59+
export type AnySingleFaced = AbstractCard &
60+
Layout<ScryfallLayoutGroup.SingleFacedType> &
5161
ScryfallCardFields.Gameplay.RootProperties &
5262
ScryfallCardFields.Gameplay.CardSpecific &
5363
ScryfallCardFields.Gameplay.CardFaceSpecific &
@@ -58,95 +68,108 @@ export namespace ScryfallCard {
5868
ScryfallCardFields.Print.CardSideSpecific &
5969
ScryfallCardFields.Print.CardFaceSpecific;
6070

61-
type MultiFace<T extends ScryfallCardFace.AbstractCardFace> = AbstractCard &
62-
Layout<ScryfallLayoutGroup.MultiFaceType> &
63-
ScryfallCardFields.Gameplay.RootProperties &
64-
ScryfallCardFields.Gameplay.CardSpecific &
65-
ScryfallCardFields.Gameplay.CardFaces<T> &
66-
ScryfallCardFields.Print.RootProperties &
67-
ScryfallCardFields.Print.CardSpecific;
68-
69-
type SingleSidedSplit = MultiFace<ScryfallCardFace.Split> &
70-
Layout<ScryfallLayoutGroup.SingleSidedSplitType> &
71-
ScryfallCardFields.Gameplay.CardSideSpecific &
72-
ScryfallCardFields.Print.CardSideSpecific &
73-
ScryfallCardFields.Print.SingleSideOnly;
74-
75-
type DoubleSidedSplit = MultiFace<ScryfallCardFace.DoubleSided> & Layout<ScryfallLayoutGroup.DoubleSidedSplitType>;
76-
77-
type AlwaysOversized = {
78-
oversized: true;
79-
};
80-
8171
/** A card with the Normal layout. */
82-
export type Normal = Layout<ScryfallLayout.Normal> & SingleFace;
72+
export type Normal = AnySingleFaced & Layout<ScryfallLayout.Normal>;
8373

8474
/** A card with the Meld layout. */
85-
export type Meld = Layout<ScryfallLayout.Meld> & SingleFace;
75+
export type Meld = AnySingleFaced & Layout<ScryfallLayout.Meld>;
8676

8777
/** A card with the Leveler layout. */
88-
export type Leveler = Layout<ScryfallLayout.Leveler> & SingleFace;
78+
export type Leveler = AnySingleFaced & Layout<ScryfallLayout.Leveler>;
8979

9080
/** A card with the Class layout. */
91-
export type Class = Layout<ScryfallLayout.Class> & SingleFace;
81+
export type Class = AnySingleFaced & Layout<ScryfallLayout.Class>;
9282

9383
/** A card with the Saga layout. */
94-
export type Saga = Layout<ScryfallLayout.Saga> & SingleFace;
84+
export type Saga = AnySingleFaced & Layout<ScryfallLayout.Saga>;
9585

9686
/** A card with the Mutate layout. */
97-
export type Mutate = Layout<ScryfallLayout.Mutate> & SingleFace;
87+
export type Mutate = AnySingleFaced & Layout<ScryfallLayout.Mutate>;
9888

9989
/** A card with the Prototype layout. */
100-
export type Prototype = Layout<ScryfallLayout.Prototype> & SingleFace;
90+
export type Prototype = AnySingleFaced & Layout<ScryfallLayout.Prototype>;
10191

10292
/** A card with the Battle layout. */
103-
export type Battle = Layout<ScryfallLayout.Battle> & SingleFace;
93+
export type Battle = AnySingleFaced & Layout<ScryfallLayout.Battle>;
10494

10595
/** A card with the Planar layout. */
106-
export type Planar = Layout<ScryfallLayout.Planar> & SingleFace & AlwaysOversized;
96+
export type Planar = AnySingleFaced & Layout<ScryfallLayout.Planar>;
10797

10898
/** A card with the Scheme layout. */
109-
export type Scheme = Layout<ScryfallLayout.Scheme> & SingleFace & AlwaysOversized;
99+
export type Scheme = AnySingleFaced & Layout<ScryfallLayout.Scheme>;
110100

111101
/** A card with the Vanguard layout. */
112-
export type Vanguard = Layout<ScryfallLayout.Vanguard> &
113-
SingleFace &
114-
ScryfallCardFields.Gameplay.VanguardStats &
115-
ScryfallCardFields.Gameplay.NoCombatStats;
102+
export type Vanguard = AnySingleFaced & Layout<ScryfallLayout.Vanguard>;
116103

117104
/** A card with the Token layout. */
118-
export type Token = Layout<ScryfallLayout.Token> & SingleFace;
105+
export type Token = AnySingleFaced & Layout<ScryfallLayout.Token>;
119106

120107
/** A card with the Emblem layout. */
121-
export type Emblem = Layout<ScryfallLayout.Emblem> & SingleFace;
108+
export type Emblem = AnySingleFaced & Layout<ScryfallLayout.Emblem>;
122109

123110
/** A card with the Augment layout. */
124-
export type Augment = Layout<ScryfallLayout.Augment> & SingleFace;
111+
export type Augment = AnySingleFaced & Layout<ScryfallLayout.Augment>;
125112

126113
/** A card with the Host layout. */
127-
export type Host = Layout<ScryfallLayout.Host> & SingleFace;
114+
export type Host = AnySingleFaced & Layout<ScryfallLayout.Host>;
115+
}
116+
117+
export namespace ScryfallCard {
118+
type MultiFace<Face extends ScryfallCardFace.AbstractCardFace> = AbstractCard &
119+
ScryfallCardFields.Gameplay.RootProperties &
120+
ScryfallCardFields.Gameplay.CardSpecific &
121+
ScryfallCardFields.Gameplay.CardFaces<Face> &
122+
ScryfallCardFields.Print.RootProperties &
123+
ScryfallCardFields.Print.CardSpecific;
124+
125+
/**
126+
* Any split layout, either single sided or double sided. These will both have `card_faces`.
127+
*/
128+
export type AnySplit = AnySingleSidedSplit | AnyDoubleSidedSplit;
129+
130+
/**
131+
* Any single-sided split card. These all have `card_faces`, and the faces are both on the front.
132+
*
133+
* Examples: {@link ScryfallLayout.Split}, {@link ScryfallLayout.Flip}, {@link ScryfallLayout.Adventure}.
134+
*/
135+
export type AnySingleSidedSplit = MultiFace<ScryfallCardFace.Split> &
136+
Layout<ScryfallLayoutGroup.SingleSidedSplitType> &
137+
ScryfallCardFields.Gameplay.CardSideSpecific &
138+
ScryfallCardFields.Gameplay.CombatStats &
139+
ScryfallCardFields.Print.CardSideSpecific &
140+
ScryfallCardFields.Print.SingleSideOnly;
128141

129142
/** A card with the Split layout. */
130-
export type Split = Layout<ScryfallLayout.Split> & SingleSidedSplit;
143+
export type Split = AnySingleSidedSplit & Layout<ScryfallLayout.Split>;
131144

132145
/** A card with the Flip layout. */
133-
export type Flip = Layout<ScryfallLayout.Flip> & SingleSidedSplit & ScryfallCardFields.Gameplay.CombatStats;
146+
export type Flip = AnySingleSidedSplit & Layout<ScryfallLayout.Flip>;
134147

135148
/** A card with the Adventure layout. */
136-
export type Adventure = Layout<ScryfallLayout.Adventure> & SingleSidedSplit & ScryfallCardFields.Gameplay.CombatStats;
149+
export type Adventure = AnySingleSidedSplit & Layout<ScryfallLayout.Adventure>;
150+
151+
/**
152+
* Any double-sided split card. These all have `card_faces`, and the faces are on the obverse and reverse of the card.
153+
*
154+
* Examples: {@link ScryfallLayout.Transform}, {@link ScryfallLayout.ModalDfc}, {@link ScryfallLayout.DoubleFacedToken}.
155+
*/
156+
export type AnyDoubleSidedSplit = MultiFace<ScryfallCardFace.DoubleSided> &
157+
Layout<ScryfallLayoutGroup.DoubleSidedSplitType>;
137158

138159
/** A card with the Transform layout. */
139-
export type Transform = Layout<ScryfallLayout.Transform> & DoubleSidedSplit;
160+
export type Transform = AnyDoubleSidedSplit & Layout<ScryfallLayout.Transform>;
140161

141162
/** A card with the ModalDfc layout. */
142-
export type ModalDfc = Layout<ScryfallLayout.ModalDfc> & DoubleSidedSplit;
163+
export type ModalDfc = AnyDoubleSidedSplit & Layout<ScryfallLayout.ModalDfc>;
143164

144165
/** A card with the DoubleFacedToken layout. */
145-
export type DoubleFacedToken = Layout<ScryfallLayout.DoubleFacedToken> & DoubleSidedSplit;
166+
export type DoubleFacedToken = AnyDoubleSidedSplit & Layout<ScryfallLayout.DoubleFacedToken>;
146167

147168
/** A card with the ArtSeries layout. */
148-
export type ArtSeries = Layout<ScryfallLayout.ArtSeries> & DoubleSidedSplit;
169+
export type ArtSeries = AnyDoubleSidedSplit & Layout<ScryfallLayout.ArtSeries>;
170+
}
149171

172+
export namespace ScryfallCard {
150173
/** A card with the ReversibleCard layout. */
151174
export type ReversibleCard = Layout<ScryfallLayout.ReversibleCard> &
152175
Omit<AbstractCard, "oracle_id"> &
@@ -155,66 +178,20 @@ export namespace ScryfallCard {
155178
ScryfallCardFields.Gameplay.CardFaces<ScryfallCardFace.Reversible> &
156179
ScryfallCardFields.Print.RootProperties &
157180
ScryfallCardFields.Print.CardSpecific;
181+
}
158182

183+
export namespace ScryfallCard {
159184
/**
160185
* A card with an indeterminate layout.
161186
*
162187
* An object of this value may be any card at all.
163188
*
164189
* Since this may be of any layout, common fields are available, but layout-specific fields (e.g. card_faces) will be unavailable until you perform type narrowing on
165190
*/
166-
export type Any =
167-
| Normal
168-
| Meld
169-
| Leveler
170-
| Class
171-
| Saga
172-
| Mutate
173-
| Prototype
174-
| Battle
175-
| Planar
176-
| Scheme
177-
| Vanguard
178-
| Token
179-
| Emblem
180-
| Augment
181-
| Host
182-
| Split
183-
| Flip
184-
| Adventure
185-
| Transform
186-
| ModalDfc
187-
| DoubleFacedToken
188-
| ArtSeries
189-
| ReversibleCard;
190-
191-
/**
192-
* Any card with a single-faced layout. These all have a .
193-
*
194-
* Examples: {@link Normal}, {@link Mutate}, {@link Token}.
195-
*/
196-
export type AnySingleFaced = Any & Layout<ScryfallLayoutGroup.SingleFaceType>;
197-
198-
/**
199-
* Any multi-faced layout, which is any that would have a `card_faces` field.
200-
*
201-
* @see {@link AnySingleSidedSplit} is in this group.
202-
* @see {@link AnyDoubleSidedSplit} is in this group.
203-
* @see {@link ReversibleCard} is in this group.
204-
*/
205-
export type AnyMultiFaced = Any & Layout<ScryfallLayoutGroup.MultiFaceType>;
206-
207-
/**
208-
* Any single-sided split card. These all have `card_faces`, and the faces are both on the front.
209-
*
210-
* Examples: {@link Split}, {@link Flip}, {@link Adventure}.
211-
*/
212-
export type AnySingleSidedSplit = Any & Layout<ScryfallLayoutGroup.SingleSidedSplitType>;
191+
export type Any = AnySingleFaced | AnySingleSidedSplit | AnyDoubleSidedSplit | ReversibleCard;
213192

214193
/**
215-
* Any double-sided split card. These all have `card_faces`, and the faces are on the obverse and reverse of the card.
216-
*
217-
* Examples: {@link Transform}, {@link ModalDfc}, {@link DoubleFacedToken}.
194+
* Any card that is multifaced: either a single or double sided split layout, or a reversible card.
218195
*/
219-
export type AnyDoubleSidedSplit = Any & Layout<ScryfallLayoutGroup.DoubleSidedSplitType>;
196+
export type AnyMultiFaced = AnySingleSidedSplit | AnyDoubleSidedSplit | ReversibleCard;
220197
}

0 commit comments

Comments
 (0)