Skip to content

Commit 6a32011

Browse files
committed
mv layout, type narrowing tests
1 parent 3896158 commit 6a32011

File tree

8 files changed

+258
-47
lines changed

8 files changed

+258
-47
lines changed

README.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
# Scryfall API types
22

3-
This library documents the definitive comprehensive typings of the Scryfall API for use in Typescript & Javascript projects.
3+
This library documents the definitive comprehensive typings of [the Scryfall API][api] for use in Typescript & Javascript projects.
44

55
This library uses [semver] for versioning. These versions only describe this library, not the Scryfall API as a whole.
66

77
[semver]: https://semver.org/
8+
[api]: https://scryfall.com/docs/api
9+
10+
## Usage
11+
12+
Each object or type exported by this library corresponds to a Scryfall API object.
13+
14+
-
815

916
## Details
1017

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { ScryfallCard, ScryfallLayout } from "src";
2+
3+
const anyCard = {} as ScryfallCard.Any;
4+
5+
if (anyCard.layout === ScryfallLayout.Normal) {
6+
const specific: ScryfallCard.Normal = anyCard;
7+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
8+
}
9+
if (anyCard.layout === ScryfallLayout.Meld) {
10+
const specific: ScryfallCard.Meld = anyCard;
11+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
12+
}
13+
if (anyCard.layout === ScryfallLayout.Leveler) {
14+
const specific: ScryfallCard.Leveler = anyCard;
15+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
16+
}
17+
if (anyCard.layout === ScryfallLayout.Class) {
18+
const specific: ScryfallCard.Class = anyCard;
19+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
20+
}
21+
if (anyCard.layout === ScryfallLayout.Saga) {
22+
const specific: ScryfallCard.Saga = anyCard;
23+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
24+
}
25+
if (anyCard.layout === ScryfallLayout.Mutate) {
26+
const specific: ScryfallCard.Mutate = anyCard;
27+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
28+
}
29+
if (anyCard.layout === ScryfallLayout.Prototype) {
30+
const specific: ScryfallCard.Prototype = anyCard;
31+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
32+
}
33+
if (anyCard.layout === ScryfallLayout.Battle) {
34+
const specific: ScryfallCard.Battle = anyCard;
35+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
36+
}
37+
if (anyCard.layout === ScryfallLayout.Planar) {
38+
const specific: ScryfallCard.Planar = anyCard;
39+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
40+
}
41+
if (anyCard.layout === ScryfallLayout.Scheme) {
42+
const specific: ScryfallCard.Scheme = anyCard;
43+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
44+
}
45+
if (anyCard.layout === ScryfallLayout.Vanguard) {
46+
const specific: ScryfallCard.Vanguard = anyCard;
47+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
48+
}
49+
if (anyCard.layout === ScryfallLayout.Token) {
50+
const specific: ScryfallCard.Token = anyCard;
51+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
52+
}
53+
if (anyCard.layout === ScryfallLayout.Emblem) {
54+
const specific: ScryfallCard.Emblem = anyCard;
55+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
56+
}
57+
if (anyCard.layout === ScryfallLayout.Augment) {
58+
const specific: ScryfallCard.Augment = anyCard;
59+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
60+
}
61+
if (anyCard.layout === ScryfallLayout.Host) {
62+
const specific: ScryfallCard.Host = anyCard;
63+
const grouped: ScryfallCard.AnySingleFaced = anyCard;
64+
}
65+
66+
if (anyCard.layout === ScryfallLayout.Split) {
67+
const specific: ScryfallCard.Split = anyCard;
68+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
69+
const anySingleSidedSplit: ScryfallCard.AnySingleSidedSplit = anyCard;
70+
}
71+
if (anyCard.layout === ScryfallLayout.Flip) {
72+
const specific: ScryfallCard.Flip = anyCard;
73+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
74+
const anySingleSidedSplit: ScryfallCard.AnySingleSidedSplit = anyCard;
75+
}
76+
if (anyCard.layout === ScryfallLayout.Adventure) {
77+
const specific: ScryfallCard.Adventure = anyCard;
78+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
79+
const anySingleSidedSplit: ScryfallCard.AnySingleSidedSplit = anyCard;
80+
}
81+
82+
if (anyCard.layout === ScryfallLayout.Transform) {
83+
const specific: ScryfallCard.Transform = anyCard;
84+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
85+
const anyDoubleSidedSplit: ScryfallCard.AnyDoubleSidedSplit = anyCard;
86+
}
87+
if (anyCard.layout === ScryfallLayout.ModalDfc) {
88+
const specific: ScryfallCard.ModalDfc = anyCard;
89+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
90+
const anyDoubleSidedSplit: ScryfallCard.AnyDoubleSidedSplit = anyCard;
91+
}
92+
if (anyCard.layout === ScryfallLayout.DoubleFacedToken) {
93+
const specific: ScryfallCard.DoubleFacedToken = anyCard;
94+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
95+
const anyDoubleSidedSplit: ScryfallCard.AnyDoubleSidedSplit = anyCard;
96+
}
97+
if (anyCard.layout === ScryfallLayout.ArtSeries) {
98+
const specific: ScryfallCard.ArtSeries = anyCard;
99+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
100+
const anyDoubleSidedSplit: ScryfallCard.AnyDoubleSidedSplit = anyCard;
101+
}
102+
103+
if (anyCard.layout === ScryfallLayout.ReversibleCard) {
104+
const specific: ScryfallCard.ReversibleCard = anyCard;
105+
const anyMultiFaced: ScryfallCard.AnyMultiFaced = anyCard;
106+
}

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"name": "api-types",
3-
"version": "1.0.0",
2+
"name": "@scryfall/api-types",
3+
"version": "0.0.1-rc.0",
44
"description": "Type definitions for the Scryfall API",
5-
"main": "index.d.ts",
5+
"main": "index.ts",
66
"scripts": {
77
"test": "npm run test:lib && npm run test:tests",
88
"test:lib": "tsc -p tsconfig.lib.json --noEmit",
@@ -14,7 +14,7 @@
1414
"types",
1515
"typescript"
1616
],
17-
"author": "Sammy",
17+
"author": "scarletcs",
1818
"license": "MIT",
1919
"devDependencies": {
2020
"@typescript-eslint/eslint-plugin": "^6.7.4",

src/objects/Card/Card.ts

+95-37
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import { ScryfallObject } from "../Object";
2-
import { ScryfallCardLayout } from "./values/CardLayout";
2+
import { ScryfallLayout, ScryfallLayoutGroup } from "./values";
33
import { ScryfallCardFace } from "./CardFace";
44
import { ScryfallCardFields } from "./CardFields";
55

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

10+
/**
11+
*
12+
*/
1013
export namespace ScryfallCard {
14+
/** The abstract root implementation of cards. */
1115
export type AbstractCard = ScryfallObject.Object<ScryfallObject.ObjectType.Card> & ScryfallCardFields.Core.All;
1216

1317
type SingleFace = AbstractCard &
18+
Layout<ScryfallLayoutGroup.SingleFaceType> &
1419
ScryfallCardFields.Gameplay.RootProperties &
1520
ScryfallCardFields.Gameplay.CardSpecific &
1621
ScryfallCardFields.Gameplay.CardFaceSpecific &
@@ -22,73 +27,96 @@ export namespace ScryfallCard {
2227
ScryfallCardFields.Print.CardFaceSpecific;
2328

2429
type MultiFace<T extends ScryfallCardFace.AbstractCardFace> = AbstractCard &
30+
Layout<ScryfallLayoutGroup.MultiFaceType> &
2531
ScryfallCardFields.Gameplay.RootProperties &
2632
ScryfallCardFields.Gameplay.CardSpecific &
2733
ScryfallCardFields.Gameplay.CardFaces<T> &
2834
ScryfallCardFields.Print.RootProperties &
2935
ScryfallCardFields.Print.CardSpecific;
3036

3137
type SingleSidedSplit = MultiFace<ScryfallCardFace.Split> &
38+
Layout<ScryfallLayoutGroup.SingleSidedSplitType> &
3239
ScryfallCardFields.Gameplay.CardSideSpecific &
3340
ScryfallCardFields.Print.CardSideSpecific &
3441
ScryfallCardFields.Print.SingleSideOnly;
3542

36-
type DoubleSidedSplit = MultiFace<ScryfallCardFace.DoubleSided>;
43+
type DoubleSidedSplit = MultiFace<ScryfallCardFace.DoubleSided> & Layout<ScryfallLayoutGroup.DoubleSidedSplitType>;
3744

3845
type AlwaysOversized = {
3946
oversized: true;
4047
};
4148

42-
export type Normal = LayoutType<ScryfallCardLayout.Normal> & SingleFace;
49+
/** A card with the Normal layout. */
50+
export type Normal = Layout<ScryfallLayout.Normal> & SingleFace;
4351

44-
export type Split = LayoutType<ScryfallCardLayout.Split> & SingleSidedSplit;
52+
/** A card with the Meld layout. */
53+
export type Meld = Layout<ScryfallLayout.Meld> & SingleFace;
4554

46-
export type Flip = LayoutType<ScryfallCardLayout.Flip> & SingleSidedSplit & ScryfallCardFields.Gameplay.CombatStats;
55+
/** A card with the Leveler layout. */
56+
export type Leveler = Layout<ScryfallLayout.Leveler> & SingleFace;
4757

48-
export type Transform = LayoutType<ScryfallCardLayout.Transform> & DoubleSidedSplit;
58+
/** A card with the Class layout. */
59+
export type Class = Layout<ScryfallLayout.Class> & SingleFace;
4960

50-
export type ModalDfc = LayoutType<ScryfallCardLayout.ModalDfc> & DoubleSidedSplit;
61+
/** A card with the Saga layout. */
62+
export type Saga = Layout<ScryfallLayout.Saga> & SingleFace;
5163

52-
export type Meld = LayoutType<ScryfallCardLayout.Meld> & SingleFace;
64+
/** A card with the Mutate layout. */
65+
export type Mutate = Layout<ScryfallLayout.Mutate> & SingleFace;
5366

54-
export type Leveler = LayoutType<ScryfallCardLayout.Leveler> & SingleFace;
67+
/** A card with the Prototype layout. */
68+
export type Prototype = Layout<ScryfallLayout.Prototype> & SingleFace;
5569

56-
export type Class = LayoutType<ScryfallCardLayout.Class> & SingleFace;
70+
/** A card with the Battle layout. */
71+
export type Battle = Layout<ScryfallLayout.Battle> & SingleFace;
5772

58-
export type Saga = LayoutType<ScryfallCardLayout.Saga> & SingleFace;
73+
/** A card with the Planar layout. */
74+
export type Planar = Layout<ScryfallLayout.Planar> & SingleFace & AlwaysOversized;
5975

60-
export type Adventure = LayoutType<ScryfallCardLayout.Adventure> &
61-
SingleSidedSplit &
62-
ScryfallCardFields.Gameplay.CombatStats;
76+
/** A card with the Scheme layout. */
77+
export type Scheme = Layout<ScryfallLayout.Scheme> & SingleFace & AlwaysOversized;
6378

64-
export type Mutate = LayoutType<ScryfallCardLayout.Mutate> & SingleFace;
79+
/** A card with the Vanguard layout. */
80+
export type Vanguard = Layout<ScryfallLayout.Vanguard> &
81+
SingleFace &
82+
ScryfallCardFields.Gameplay.VanguardStats &
83+
ScryfallCardFields.Gameplay.NoCombatStats;
6584

66-
export type Prototype = LayoutType<ScryfallCardLayout.Prototype> & SingleFace;
85+
/** A card with the Token layout. */
86+
export type Token = Layout<ScryfallLayout.Token> & SingleFace;
6787

68-
export type Battle = LayoutType<ScryfallCardLayout.Battle> & SingleFace;
88+
/** A card with the Emblem layout. */
89+
export type Emblem = Layout<ScryfallLayout.Emblem> & SingleFace;
6990

70-
export type Planar = LayoutType<ScryfallCardLayout.Planar> & SingleFace & AlwaysOversized;
91+
/** A card with the Augment layout. */
92+
export type Augment = Layout<ScryfallLayout.Augment> & SingleFace;
7193

72-
export type Scheme = LayoutType<ScryfallCardLayout.Scheme> & SingleFace & AlwaysOversized;
94+
/** A card with the Host layout. */
95+
export type Host = Layout<ScryfallLayout.Host> & SingleFace;
7396

74-
export type Vanguard = LayoutType<ScryfallCardLayout.Vanguard> &
75-
SingleFace &
76-
ScryfallCardFields.Gameplay.VanguardStats &
77-
ScryfallCardFields.Gameplay.NoCombatStats;
97+
/** A card with the Split layout. */
98+
export type Split = Layout<ScryfallLayout.Split> & SingleSidedSplit;
7899

79-
export type Token = LayoutType<ScryfallCardLayout.Token> & SingleFace;
100+
/** A card with the Flip layout. */
101+
export type Flip = Layout<ScryfallLayout.Flip> & SingleSidedSplit & ScryfallCardFields.Gameplay.CombatStats;
80102

81-
export type DoubleFacedToken = LayoutType<ScryfallCardLayout.DoubleFacedToken> & DoubleSidedSplit;
103+
/** A card with the Adventure layout. */
104+
export type Adventure = Layout<ScryfallLayout.Adventure> & SingleSidedSplit & ScryfallCardFields.Gameplay.CombatStats;
82105

83-
export type Emblem = LayoutType<ScryfallCardLayout.Emblem> & SingleFace;
106+
/** A card with the Transform layout. */
107+
export type Transform = Layout<ScryfallLayout.Transform> & DoubleSidedSplit;
84108

85-
export type Augment = LayoutType<ScryfallCardLayout.Augment> & SingleFace;
109+
/** A card with the ModalDfc layout. */
110+
export type ModalDfc = Layout<ScryfallLayout.ModalDfc> & DoubleSidedSplit;
86111

87-
export type Host = LayoutType<ScryfallCardLayout.Host> & SingleFace;
112+
/** A card with the DoubleFacedToken layout. */
113+
export type DoubleFacedToken = Layout<ScryfallLayout.DoubleFacedToken> & DoubleSidedSplit;
88114

89-
export type ArtSeries = LayoutType<ScryfallCardLayout.ArtSeries> & DoubleSidedSplit;
115+
/** A card with the ArtSeries layout. */
116+
export type ArtSeries = Layout<ScryfallLayout.ArtSeries> & DoubleSidedSplit;
90117

91-
export type ReversibleCard = LayoutType<ScryfallCardLayout.ReversibleCard> &
118+
/** A card with the ReversibleCard layout. */
119+
export type ReversibleCard = Layout<ScryfallLayout.ReversibleCard> &
92120
Omit<AbstractCard, "oracle_id"> &
93121
ScryfallCardFields.Gameplay.RootProperties &
94122
Omit<ScryfallCardFields.Gameplay.CardSpecific, "type_line" | "cmc"> &
@@ -98,26 +126,56 @@ export namespace ScryfallCard {
98126

99127
export type Any =
100128
| Normal
101-
| Split
102-
| Flip
103-
| Transform
104-
| ModalDfc
105129
| Meld
106130
| Leveler
107131
| Class
108132
| Saga
109-
| Adventure
110133
| Mutate
111134
| Prototype
112135
| Battle
113136
| Planar
114137
| Scheme
115138
| Vanguard
116139
| Token
117-
| DoubleFacedToken
118140
| Emblem
119141
| Augment
120142
| Host
143+
| Split
144+
| Flip
145+
| Adventure
146+
| Transform
147+
| ModalDfc
148+
| DoubleFacedToken
121149
| ArtSeries
122150
| ReversibleCard;
151+
152+
/**
153+
* Any card with a single-faced layout. These all have a .
154+
*
155+
* Examples: {@link Normal}, {@link Mutate}, {@link Token}.
156+
*/
157+
export type AnySingleFaced = Any & Layout<ScryfallLayoutGroup.SingleFaceType>;
158+
159+
/**
160+
* Any multi-faced layout, which is any that would have a `card_faces` field.
161+
*
162+
* @see {@link AnySingleSidedSplit} is in this group.
163+
* @see {@link AnyDoubleSidedSplit} is in this group.
164+
* @see {@link ReversibleCard} is in this group.
165+
*/
166+
export type AnyMultiFaced = Any & Layout<ScryfallLayoutGroup.MultiFaceType>;
167+
168+
/**
169+
* Any single-sided split card. These all have `card_faces`, and the faces are both on the front.
170+
*
171+
* Examples: {@link Split}, {@link Flip}, {@link Adventure}.
172+
*/
173+
export type AnySingleSidedSplit = Any & Layout<ScryfallLayoutGroup.SingleSidedSplitType>;
174+
175+
/**
176+
* Any double-sided split card. These all have `card_faces`, and the faces are on the obverse and reverse of the card.
177+
*
178+
* Examples: {@link Transform}, {@link ModalDfc}, {@link DoubleFacedToken}.
179+
*/
180+
export type AnyDoubleSidedSplit = Any & Layout<ScryfallLayoutGroup.DoubleSidedSplitType>;
123181
}

src/objects/Card/CardFields.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
ScryfallFormat,
33
ScryfallLegalityLike,
44
ScryfallLanguageCodeLike,
5-
ScryfallCardLayoutLike,
5+
ScryfallLayoutLike,
66
ScryfallColors,
77
ScryfallImageSize,
88
ScryfallBorderColorLike,
@@ -33,7 +33,7 @@ export namespace ScryfallCardFields.Core {
3333
/** A language code for this printing. */
3434
lang: ScryfallLanguageCodeLike;
3535
/** A code for this card’s layout. */
36-
layout: ScryfallCardLayoutLike;
36+
layout: ScryfallLayoutLike;
3737
/** A link to where you can begin paginating all re/prints for this card on Scryfall’s API. */
3838
prints_search_uri: Uri;
3939
/** A link to this card’s rulings list on Scryfall’s API. */

src/objects/Card/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ export * from "./Card";
22
export * from "./CardFace";
33
export * from "./CardFields";
44
export * from "./RelatedCard";
5+
6+
export * from "./values";

0 commit comments

Comments
 (0)