├── .eslintrc.json ├── .github └── workflows │ └── jest.yml ├── .gitignore ├── .prettierrc.yaml ├── .vscode ├── extensions.json ├── helpers.code-snippets └── settings.json ├── LICENSE ├── README.md ├── index.ts ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── __tests__ │ └── objects │ │ └── Catalog │ │ └── Catalog.test.ts ├── index.ts ├── objects │ ├── Card │ │ ├── Card.ts │ │ ├── CardFace.ts │ │ ├── CardFields.ts │ │ ├── RelatedCard.ts │ │ ├── index.ts │ │ └── values │ │ │ ├── BorderColor.ts │ │ │ ├── Color.ts │ │ │ ├── Finish.ts │ │ │ ├── Format.ts │ │ │ ├── Frame.ts │ │ │ ├── FrameEffect.ts │ │ │ ├── Game.ts │ │ │ ├── ImageSize.ts │ │ │ ├── ImageStatus.ts │ │ │ ├── ImageUris.ts │ │ │ ├── LanguageCode.ts │ │ │ ├── Layout.ts │ │ │ ├── LegalitiesField.ts │ │ │ ├── Legality.ts │ │ │ ├── ManaType.ts │ │ │ ├── Prices.ts │ │ │ ├── PromoType.ts │ │ │ ├── PurchaseUris.ts │ │ │ ├── Rarity.ts │ │ │ ├── RelatedUris.ts │ │ │ ├── SecurityStamp.ts │ │ │ └── index.ts │ ├── Catalog │ │ ├── Catalog.ts │ │ └── index.ts │ ├── Error │ │ ├── Error.ts │ │ └── index.ts │ ├── List │ │ ├── List.ts │ │ └── index.ts │ ├── Migration │ │ ├── Migration.ts │ │ └── index.ts │ ├── Object │ │ ├── Object.ts │ │ └── index.ts │ ├── Ruling │ │ ├── Ruling.ts │ │ └── index.ts │ ├── Set │ │ ├── Set.ts │ │ ├── index.ts │ │ └── values │ │ │ ├── SetType.ts │ │ │ └── index.ts │ ├── Symbology │ │ ├── CardSymbol.ts │ │ ├── ManaCost.ts │ │ └── index.ts │ └── index.ts └── validators │ ├── BaseValidator.ts │ ├── index.ts │ └── objects │ └── Catalog │ └── CatalogValidator.ts ├── tsconfig.json ├── tsconfig.lib.json └── tsconfig.test.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 5 | "plugins": ["@typescript-eslint"], 6 | "overrides": [ 7 | { 8 | "files": [ 9 | "src/**/*.ts" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/no-namespace": "off" 13 | } 14 | }, 15 | { 16 | "files": [ 17 | "**/__test__/**/*.ts" 18 | ], 19 | "rules": { 20 | "@typescript-eslint/no-unused-vars": "off" 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/jest.yml: -------------------------------------------------------------------------------- 1 | name: Jest CI 2 | on: push 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Install modules 9 | run: npm i 10 | - name: Run tests 11 | run: npm run test 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | tabWidth: 2 2 | tabs: false 3 | semi: true 4 | endOfLine: lf 5 | printWidth: 120 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/helpers.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Enumlike": { 3 | "scope": "typescript", 4 | "prefix": "enumlike", 5 | "body": [ 6 | "export type $1Like = $1 | `${$1}`;", 7 | ], 8 | "description": "Create an enum-like field corresponding to the values of a string enum." 9 | }, 10 | "New Scryfall object declaration": { 11 | "scope": "typescript", 12 | "prefix": "scryfall:object", 13 | "body": [ 14 | "ScryfallObject.Object" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.insertSpaces": true, 4 | "editor.rulers": [140], 5 | "editor.tabSize": 2, 6 | "editor.trimAutoWhitespace": true, 7 | "files.eol": "\n", 8 | "files.insertFinalNewline": true, 9 | "files.trimTrailingWhitespace": true, 10 | "prettier.endOfLine": "lf", 11 | "[json]": { 12 | "editor.defaultFormatter": "esbenp.prettier-vscode", 13 | "editor.formatOnSave": true, 14 | }, 15 | "[typescript]": { 16 | "editor.formatOnSave": true 17 | }, 18 | "files.exclude": { 19 | "node_modules": true 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Scryfall 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scryfall API types 2 | 3 | This library documents the definitive comprehensive typings of [the Scryfall API][api] for use in Typescript & Javascript projects. 4 | 5 | This library uses [semver] for versioning. These versions only describe this library, not the Scryfall API as a whole. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @scryfall/api-types 11 | ``` 12 | 13 | ## Examples 14 | 15 | ### Fetching a card 16 | 17 | ```ts 18 | // CommonJS module syntax 19 | const { ScryfallCard } = require("@scryfall/api-types"); 20 | 21 | // ES module syntax 22 | import { ScryfallCard } from "@scryfall/api-types"; 23 | 24 | // Fetch a card 25 | const response = await fetch("https://api.scryfall.com/cards/iko/275"); 26 | const godzilla: ScryfallCard.Any = await response.json(); 27 | ``` 28 | 29 | ### Fetching the list of sets 30 | 31 | ```ts 32 | // CommonJS module syntax 33 | const { ScryfallList } = require("@scryfall/api-types"); 34 | 35 | // ES module syntax 36 | import { ScryfallList } from "@scryfall/api-types"; 37 | 38 | // Fetch the list of all setss 39 | const response = await fetch("https://api.scryfall.com/sets"); 40 | const sets: ScryfallList.Sets = await response.json(); 41 | ``` 42 | 43 | ### Type narrowing on a card 44 | 45 | ```ts 46 | import { ScryfallCard, ScryfallLayout } from "@scryfall/api-types"; 47 | 48 | // This card might be of any type. 49 | // You cannot access `mysteryCard.card_faces`, because it might not have that property. 50 | const mysteryCard: ScryfallCard.Any = getCard(); 51 | 52 | // You can narrow by layout: 53 | if (mysteryCard.layout === ScryfallLayout.Transform) { 54 | // It's a transforming DFC! 55 | // You can access transform-specific fields in this scope, or assign it to a variable. 56 | const faces = anyCard.card_faces; 57 | const transform: ScryfallCard.Transform = mysteryCard; 58 | } 59 | 60 | // You can also narrow by property: 61 | if ("card_faces" in anyCard) { 62 | // It's *some* kind of multi-faced card. 63 | // You can now access the card_faces property. 64 | // You'll need to do some further type narrowing to know more about what's in the card. 65 | const faces = anyCard.card_faces; 66 | const multifaced: ScryfallCard.AnyMultiFaced = anyCard; 67 | } else { 68 | const sfc: ScryfallCard.AnySingleFaced = anyCard; 69 | } 70 | ``` 71 | 72 | ## Usage 73 | 74 | Each type and enum exported by this library corresponds to a Scryfall API object and its values. 75 | 76 | Points of interest: 77 | 78 | - [ScryfallCard](src/objects/Card/Card.ts) describes [Cards](https://scryfall.com/docs/api/cards) and their faces. Each individual card layout is managed via type narrowing on the `layout` field. 79 | - [ScryfallCatalog](src/objects/Catalog/Catalog.ts) describes [the catalogs](https://scryfall.com/docs/api/catalogs). 80 | - [ScryfallError](src/objects/Error/Error.ts) describes [error responses](https://scryfall.com/docs/api/errors). 81 | - [ScryfallList](src/objects/List/List.ts) describes [lists](https://scryfall.com/docs/api/lists), and provides shortcuts to describe the common types of lists. 82 | - [ScryfallMigration](src/objects/Migration/Migration.ts) describes [migrations](https://scryfall.com/docs/api/migrations). 83 | - [ScryfallSet](src/objects/Set/Set.ts) describes [card sets](https://scryfall.com/docs/api/sets). 84 | 85 | If the API provides an object, this library provides it as well. (If it doesn't, please [tell us][issues]!) 86 | 87 | All primary types and values are prefixed with `Scryfall` to avoid conflict with the standard library (e.g. `Object`, `Error`, `Set`) and to minimise conflict with your other libraries and dependencies (e.g. `Color`, `LanguageCode`). If we didn't have the prefix you'd be forced to append one yourself one on import, so we've defaulted to including it. 88 | 89 | Enum fields are described both in terms of an enum and a set of strings in order to give you the option of interacting with that field with either one. 90 | 91 | [semver]: https://semver.org/ 92 | [api]: https://scryfall.com/docs/api 93 | [issues]: https://github.com/scryfall/api-types/issues 94 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export * from "./src"; 2 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | modulePaths: [""], 6 | }; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@scryfall/api-types", 3 | "version": "1.0.0-alpha.4", 4 | "description": "Type definitions for the Scryfall API", 5 | "main": "index.ts", 6 | "scripts": { 7 | "qa": "npm run check:types && npm run lint && npm run test", 8 | "lint": "eslint", 9 | "test": "jest", 10 | "check:types": "tsc --noEmit" 11 | }, 12 | "files": [ 13 | "index.ts", 14 | "src/**/*" 15 | ], 16 | "author": "scarletcs", 17 | "license": "MIT", 18 | "homepage": "https://github.com/scryfall/api-types#readme", 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/scryfall/api-types.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/scryfall/api-types/issues" 25 | }, 26 | "keywords": [ 27 | "scryfall", 28 | "api", 29 | "types", 30 | "typescript" 31 | ], 32 | "devDependencies": { 33 | "@types/jest": "^29.5.12", 34 | "@typescript-eslint/eslint-plugin": "^6.7.4", 35 | "@typescript-eslint/parser": "^6.7.4", 36 | "eslint": "^8.51.0", 37 | "jest": "^29.7.0", 38 | "prettier": "^3.0.3", 39 | "ts-jest": "^29.1.5", 40 | "tslib": "^2.6.2", 41 | "typescript": "^5.2.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/__tests__/objects/Catalog/Catalog.test.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallCatalog } from "src/objects"; 2 | import CatalogValidator from "src/validators/objects/Catalog/CatalogValidator"; 3 | 4 | const cardNamesRequest: Promise = fetch("https://api.scryfall.com/catalog/card-names").then((resp) => 5 | resp.json(), 6 | ); 7 | 8 | describe("Catalog", () => { 9 | test("has expected fields", async () => { 10 | const cardNamesCatalog = await cardNamesRequest; 11 | const goodValidator = new CatalogValidator(cardNamesCatalog); 12 | 13 | expect(goodValidator.validKeys).toBe(true); 14 | }); 15 | 16 | test("expected fields are expected type", async () => { 17 | const cardNamesCatalog = await cardNamesRequest; 18 | const validator = new CatalogValidator(cardNamesCatalog); 19 | expect(validator.validKeyType).toBe(true); 20 | }); 21 | 22 | test("has no unexpected fields", async () => { 23 | const cardNamesCatalog = await cardNamesRequest; 24 | const mockKeyUpdates = { ...cardNamesCatalog, notAKey: true }; 25 | const validator = new CatalogValidator(mockKeyUpdates); 26 | expect(validator.validKeys).toBe(false); 27 | }); 28 | 29 | test("total_values matches data length", async () => { 30 | const cardNamesCatalog = await cardNamesRequest; 31 | const validator = new CatalogValidator(cardNamesCatalog); 32 | const dataLength = validator.validDataLength; 33 | expect(dataLength).toBe(true); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./objects"; 2 | export * from "./validators"; 3 | -------------------------------------------------------------------------------- /src/objects/Card/Card.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { ScryfallLayout, ScryfallLayoutGroup } from "./values"; 3 | import { ScryfallCardFace } from "./CardFace"; 4 | import { ScryfallCardFields } from "./CardFields"; 5 | 6 | type Layout = Pick & { 7 | layout: `${T}`; 8 | }; 9 | 10 | /** 11 | * A collection of types representing Scryfall cards of each possible layout. 12 | * 13 | * This collection is focused around four core varieties of cards: 14 | * - {@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}. 15 | * - {@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}. 16 | * - {@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. 23 | * 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. 27 | * 28 | * @example // Type narrowing by layout 29 | * const mysteryCard: ScryfallCard.Any = getCard(); 30 | * 31 | * if (mysteryCard.layout === ScryfallLayout.Transform) { 32 | * const transform: ScryfallCard.Transform = mysteryCard; 33 | * } 34 | * 35 | * @example // Type narrowing by property 36 | * const mysteryCard: ScryfallCard.Any = getCard(); 37 | * 38 | * if ("card_faces" in mysteryCard) { 39 | * const mfc: ScryfallCard.AnyMultiFaced = mysteryCard; 40 | * } else { 41 | * const sfc: ScryfallCard.AnySingleFaced = mysteryCard; 42 | * } 43 | * 44 | * 45 | * @see {@link https://scryfall.com/docs/api/cards} 46 | * @see {@link https://scryfall.com/docs/api/layouts} 47 | */ 48 | export namespace ScryfallCard { 49 | /** The abstract root implementation of cards. */ 50 | export type AbstractCard = ScryfallObject.Object & ScryfallCardFields.Core.All; 51 | } 52 | 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 & 61 | ScryfallCardFields.Gameplay.RootProperties & 62 | ScryfallCardFields.Gameplay.CardSpecific & 63 | ScryfallCardFields.Gameplay.CardFaceSpecific & 64 | ScryfallCardFields.Gameplay.CardSideSpecific & 65 | ScryfallCardFields.Print.RootProperties & 66 | ScryfallCardFields.Print.SingleSideOnly & 67 | ScryfallCardFields.Print.CardSpecific & 68 | ScryfallCardFields.Print.CardSideSpecific & 69 | ScryfallCardFields.Print.CardFaceSpecific; 70 | 71 | /** A card with the Normal layout. */ 72 | export type Normal = AnySingleFaced & Layout; 73 | 74 | /** A card with the Meld layout. */ 75 | export type Meld = AnySingleFaced & Layout; 76 | 77 | /** A card with the Leveler layout. */ 78 | export type Leveler = AnySingleFaced & Layout; 79 | 80 | /** A card with the Class layout. */ 81 | export type Class = AnySingleFaced & Layout; 82 | 83 | /** A card with the Saga layout. */ 84 | export type Saga = AnySingleFaced & Layout; 85 | 86 | /** A card with the Mutate layout. */ 87 | export type Mutate = AnySingleFaced & Layout; 88 | 89 | /** A card with the Prototype layout. */ 90 | export type Prototype = AnySingleFaced & Layout; 91 | 92 | /** A card with the Battle layout. */ 93 | export type Battle = AnySingleFaced & Layout; 94 | 95 | /** A card with the Planar layout. */ 96 | export type Planar = AnySingleFaced & Layout; 97 | 98 | /** A card with the Scheme layout. */ 99 | export type Scheme = AnySingleFaced & Layout; 100 | 101 | /** A card with the Vanguard layout. */ 102 | export type Vanguard = AnySingleFaced & Layout; 103 | 104 | /** A card with the Token layout. */ 105 | export type Token = AnySingleFaced & Layout; 106 | 107 | /** A card with the Emblem layout. */ 108 | export type Emblem = AnySingleFaced & Layout; 109 | 110 | /** A card with the Augment layout. */ 111 | export type Augment = AnySingleFaced & Layout; 112 | 113 | /** A card with the Host layout. */ 114 | export type Host = AnySingleFaced & Layout; 115 | } 116 | 117 | export namespace ScryfallCard { 118 | type MultiFace = AbstractCard & 119 | ScryfallCardFields.Gameplay.RootProperties & 120 | ScryfallCardFields.Gameplay.CardSpecific & 121 | ScryfallCardFields.Gameplay.CardFaces & 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 & 136 | Layout & 137 | ScryfallCardFields.Gameplay.CardSideSpecific & 138 | ScryfallCardFields.Gameplay.CombatStats & 139 | ScryfallCardFields.Print.CardSideSpecific & 140 | ScryfallCardFields.Print.SingleSideOnly; 141 | 142 | /** A card with the Split layout. */ 143 | export type Split = AnySingleSidedSplit & Layout; 144 | 145 | /** A card with the Flip layout. */ 146 | export type Flip = AnySingleSidedSplit & Layout; 147 | 148 | /** A card with the Adventure layout. */ 149 | export type Adventure = AnySingleSidedSplit & Layout; 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 & 157 | Layout; 158 | 159 | /** A card with the Transform layout. */ 160 | export type Transform = AnyDoubleSidedSplit & Layout; 161 | 162 | /** A card with the ModalDfc layout. */ 163 | export type ModalDfc = AnyDoubleSidedSplit & Layout; 164 | 165 | /** A card with the DoubleFacedToken layout. */ 166 | export type DoubleFacedToken = AnyDoubleSidedSplit & Layout; 167 | 168 | /** A card with the ArtSeries layout. */ 169 | export type ArtSeries = AnyDoubleSidedSplit & Layout; 170 | } 171 | 172 | export namespace ScryfallCard { 173 | /** A card with the ReversibleCard layout. */ 174 | export type ReversibleCard = Layout & 175 | Omit & 176 | ScryfallCardFields.Gameplay.RootProperties & 177 | Omit & 178 | ScryfallCardFields.Gameplay.CardFaces & 179 | ScryfallCardFields.Print.RootProperties & 180 | ScryfallCardFields.Print.CardSpecific; 181 | } 182 | 183 | export namespace ScryfallCard { 184 | /** 185 | * A card with an indeterminate layout. 186 | * 187 | * An object of this value may be any card at all. 188 | * 189 | * 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 190 | */ 191 | export type Any = AnySingleFaced | AnySingleSidedSplit | AnyDoubleSidedSplit | ReversibleCard; 192 | 193 | /** 194 | * Any card that is multifaced: either a single or double sided split layout, or a reversible card. 195 | */ 196 | export type AnyMultiFaced = AnySingleSidedSplit | AnyDoubleSidedSplit | ReversibleCard; 197 | } 198 | -------------------------------------------------------------------------------- /src/objects/Card/CardFace.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { ScryfallCardFields } from "./CardFields"; 3 | 4 | /** 5 | * A collection of types representing card faces of each possible type. 6 | * 7 | * @see {@link https://scryfall.com/docs/api/layouts#card-faces} 8 | */ 9 | export namespace ScryfallCardFace { 10 | /** 11 | * The abstract root implementation of card faces. 12 | */ 13 | export type AbstractCardFace = ScryfallObject.Object; 14 | 15 | /** 16 | * A card face found on split cards that are single-sided. 17 | * 18 | * E.g. Fuse or Adventure cards, NOT transform cards. 19 | */ 20 | export type Split = AbstractCardFace & 21 | ScryfallCardFields.Gameplay.CardFaceSpecific & 22 | ScryfallCardFields.Print.CardFaceSpecific & 23 | ScryfallCardFields.Print.CardFaceOnly; 24 | 25 | /** 26 | * A card face found on double-sided cards. 27 | * 28 | * E.g. Transform and MDFC cards. 29 | */ 30 | export type DoubleSided = AbstractCardFace & 31 | ScryfallCardFields.Gameplay.CardFaceSpecific & 32 | ScryfallCardFields.Gameplay.CardSideSpecific & 33 | ScryfallCardFields.Print.CardFaceSpecific & 34 | ScryfallCardFields.Print.CardFaceOnly & 35 | ScryfallCardFields.Print.CardSideSpecific; 36 | 37 | /** 38 | * A card face found on reversible cards. 39 | */ 40 | export type Reversible = AbstractCardFace & 41 | Pick & 42 | Omit & 43 | ScryfallCardFields.Gameplay.CardSideSpecific & 44 | ScryfallCardFields.Gameplay.CardFaceSpecific & 45 | ScryfallCardFields.Print.CardSideSpecific & 46 | ScryfallCardFields.Print.CardFaceSpecific & 47 | ScryfallCardFields.Print.CardFaceOnly; 48 | 49 | export type Any = Split | DoubleSided | Reversible; 50 | } 51 | -------------------------------------------------------------------------------- /src/objects/Card/CardFields.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ScryfallBorderColor, 3 | ScryfallColors, 4 | ScryfallFinish, 5 | ScryfallFrame, 6 | ScryfallFrameEffect, 7 | ScryfallGame, 8 | ScryfallImageStatus, 9 | ScryfallImageUris, 10 | ScryfallLanguageCode, 11 | ScryfallLayout, 12 | ScryfallLegalitiesField, 13 | ScryfallPrices, 14 | ScryfallPromoType, 15 | ScryfallPurchaseUris, 16 | ScryfallRarity, 17 | ScryfallRelatedUris, 18 | ScryfallSecurityStamp, 19 | } from "./values"; 20 | import { ScryfallCardFace } from "./CardFace"; 21 | import { ScryfallRelatedCard } from "./RelatedCard"; 22 | import { ScryfallManaTypes } from "./values/ManaType"; 23 | import { SetType } from "../Set/values"; 24 | 25 | /** 26 | * A collection of types related to each possible card field. 27 | */ 28 | export namespace ScryfallCardFields {} 29 | 30 | export namespace ScryfallCardFields.Core { 31 | export type ScryfallReferences = { 32 | /** 33 | * A unique ID for this card in Scryfall’s database. 34 | * 35 | * @type UUID 36 | */ 37 | id: string; 38 | /** 39 | * A unique ID for this card’s oracle identity. 40 | * This value is consistent across reprinted card editions, and unique among different cards with the same name (tokens, Unstable variants, etc). 41 | * Always present except for the reversible_card layout where it will be absent; oracle_id will be found on each face instead. 42 | * 43 | * @type UUID 44 | */ 45 | oracle_id: string; 46 | /** 47 | * A language code for this printing. 48 | */ 49 | lang: `${ScryfallLanguageCode}`; 50 | /** 51 | * A code for this card’s layout. 52 | * 53 | * @see {@link https://scryfall.com/docs/api/layouts} 54 | */ 55 | layout: `${ScryfallLayout}`; 56 | /** 57 | * A link to where you can begin paginating all re/prints for this card on Scryfall’s API. 58 | * 59 | * @type URI 60 | */ 61 | prints_search_uri: string; 62 | /** 63 | * A link to this card’s rulings list on Scryfall’s API. 64 | * 65 | * @type URI 66 | */ 67 | rulings_uri: string; 68 | /** 69 | * A link to this card’s permapage on Scryfall’s website. 70 | * 71 | * @type URI 72 | */ 73 | scryfall_uri: string; 74 | /** 75 | * A link to this card object on Scryfall’s API. 76 | * 77 | * @type URI 78 | */ 79 | uri: string; 80 | }; 81 | 82 | export type VendorReferences = { 83 | /** 84 | * This card’s Arena ID, if any. A large percentage of cards are not available on Arena and do not have this ID. 85 | * 86 | * @type Integer 87 | */ 88 | arena_id?: number; 89 | /** 90 | * This card’s Magic Online ID (also known as the Catalog ID), if any. A large percentage of cards are not available on Magic Online and do not have this ID. 91 | * 92 | * @type Integer 93 | */ 94 | mtgo_id?: number; 95 | /** 96 | * This card’s foil Magic Online ID (also known as the Catalog ID), if any. A large percentage of cards are not available on Magic Online and do not have this ID. 97 | * 98 | * @type Integer 99 | */ 100 | mtgo_foil_id?: number; 101 | /** 102 | * This card’s multiverse IDs on Gatherer, if any, as an array of integers. Note that Scryfall includes many promo cards, tokens, and other esoteric objects that do not have these identifiers. 103 | * 104 | * @type Integer 105 | */ 106 | multiverse_ids?: number[]; 107 | /** 108 | * This card’s ID on TCGplayer’s API, also known as the productId. 109 | * 110 | * @type Integer 111 | */ 112 | tcgplayer_id?: number; 113 | /** 114 | * This card’s ID on TCGplayer’s API, for its etched version if that version is a separate product. 115 | * 116 | * @type Integer 117 | */ 118 | tcgplayer_etched_id?: number; 119 | /** 120 | * This card’s ID on Cardmarket’s API, also known as the idProduct. 121 | * 122 | * @type Integer 123 | */ 124 | cardmarket_id?: number; 125 | }; 126 | 127 | export type All = ScryfallReferences & VendorReferences; 128 | } 129 | 130 | export namespace ScryfallCardFields.Gameplay { 131 | /** 132 | * These fields are always at the root level for every layout. 133 | */ 134 | export type RootProperties = { 135 | /** 136 | * If this card is closely related to other cards, this property will be an array with Related Card Objects. 137 | */ 138 | all_parts?: ScryfallRelatedCard[]; 139 | /** 140 | * An object describing the legality of this card across play formats. Possible legalities are legal, not_legal, restricted, and banned. 141 | */ 142 | legalities: ScryfallLegalitiesField; 143 | }; 144 | 145 | /** 146 | * The card faces field. The faces will be of type T. 147 | */ 148 | export type CardFaces = { 149 | /** 150 | * An array of Card Face objects, if this card is multifaced. 151 | */ 152 | card_faces: T[]; 153 | }; 154 | 155 | /** 156 | * These fields are present only for Vanguards. 157 | */ 158 | export type VanguardStats = { 159 | /** 160 | * This card’s hand modifier, if it is Vanguard card. This value will contain a delta, such as -1. 161 | */ 162 | hand_modifier?: string; 163 | /** 164 | * This card’s life modifier, if it is Vanguard card. This value will contain a delta, such as +2. 165 | */ 166 | life_modifier?: string; 167 | }; 168 | 169 | /** 170 | * Combat stats: power, toughness, loyalty, and defense. 171 | */ 172 | export type CombatStats = { 173 | /** 174 | * This card's defense, if any. 175 | */ 176 | defense?: string; 177 | /** 178 | * This loyalty if any. Note that some cards have loyalties that are not numeric, such as X. 179 | */ 180 | loyalty?: string; 181 | /** 182 | * This card’s power, if any. Note that some cards have powers that are not numeric, such as `"*"`. 183 | */ 184 | power?: string; 185 | /** 186 | * This card’s toughness, if any. Note that some cards have toughnesses that are not numeric, such as `"*"`. 187 | */ 188 | toughness?: string; 189 | }; 190 | 191 | /** 192 | * On multi-face cards, these fields are duplicated at the card and print level. 193 | */ 194 | type AllFacesAndSides = { 195 | name: string; 196 | type_line: string; 197 | mana_cost?: string; 198 | }; 199 | 200 | /** 201 | * These fields are specific for a card face. 202 | * 203 | * - Root level for a single-face card. 204 | * - Card face level for a multi-face card. 205 | */ 206 | export type CardFaceSpecific = AllFacesAndSides & { 207 | /** 208 | * The colors in this card’s color indicator, if any. A null value for this field indicates the card does not have one. 209 | */ 210 | color_indicator?: ScryfallColors; 211 | /** 212 | * Nullable The mana cost for this card. This value will be any empty string "" if the cost is absent. Remember that per the game rules, a missing mana cost and a mana cost of {0} are different Multi-faced cards will report this value in card faces. 213 | */ 214 | mana_cost?: string; 215 | /** 216 | * The name of this card. 217 | */ 218 | name: string; 219 | /** 220 | * The type line of this card. 221 | */ 222 | type_line: string; 223 | /** 224 | * The Oracle text for this card, if any. 225 | */ 226 | oracle_text: string; 227 | } & CombatStats & 228 | VanguardStats; 229 | 230 | export type CardSideSpecific = AllFacesAndSides & { 231 | /** 232 | * The name of this card. 233 | */ 234 | name: string; 235 | /** 236 | * The type line of this card. 237 | */ 238 | type_line: string; 239 | /** 240 | * This card’s colors, if the overall card has colors defined by the rules. Otherwise the colors will be on the card_faces objects. 241 | */ 242 | colors: ScryfallColors; 243 | }; 244 | 245 | /** 246 | * These fields are specific for a card. 247 | * - Root level for most layouts. 248 | * - Card face level for reversible layouts. 249 | */ 250 | export type CardSpecific = AllFacesAndSides & { 251 | /** 252 | * The card’s mana value. Note that some funny cards have fractional mana costs. 253 | * 254 | * @type Decimal 255 | */ 256 | cmc: number; 257 | /** 258 | * This card’s color identity. 259 | */ 260 | color_identity: ScryfallColors; 261 | /** 262 | * This card’s overall rank/popularity on EDHREC. Not all cards are ranked. 263 | * 264 | * @type Integer 265 | */ 266 | edhrec_rank?: number; 267 | /** 268 | * An array of keywords that this card uses, such as 'Flying' and 'Cumulative upkeep'. 269 | */ 270 | keywords: string[]; 271 | /** 272 | * The name of this card. If this card has multiple faces, this field will contain both names separated by ␣//␣. 273 | */ 274 | name: string; 275 | /** 276 | * This card’s rank/popularity on Penny Dreadful. Not all cards are ranked. 277 | * 278 | * @type Integer 279 | */ 280 | penny_rank?: number; 281 | /** 282 | * Colors of mana that this card could produce. 283 | */ 284 | produced_mana?: ScryfallManaTypes; 285 | /** 286 | * True if this card is on the Reserved List. 287 | */ 288 | reserved: boolean; 289 | /** 290 | * The type line of this card. 291 | */ 292 | type_line: string; 293 | }; 294 | } 295 | 296 | export namespace ScryfallCardFields.Print { 297 | type PreviewInfo = { 298 | /** 299 | * The date this card was previewed. 300 | * 301 | * @type IsoDate 302 | */ 303 | previewed_at: string; 304 | /** 305 | * A link to the preview for this card. 306 | * 307 | * @type URI 308 | */ 309 | source_uri: string; 310 | /** 311 | * The name of the source that previewed this card. 312 | */ 313 | source: string; 314 | }; 315 | 316 | export type RootProperties = { 317 | /** 318 | * Whether the card is foil. 319 | * @deprecated Use {@link CardSpecific.Finishes} instead. 320 | */ 321 | foil?: boolean; 322 | /** 323 | * Whether the card is nonfoil. 324 | * @deprecated Use {@link CardSpecific.Finishes} instead. 325 | */ 326 | nonfoil?: boolean; 327 | }; 328 | 329 | /** 330 | * These print fields are specific for a card. 331 | * 332 | * - Root level for a non-reversible card. 333 | * - Card face level for a reversible card. 334 | */ 335 | export type CardSpecific = { 336 | /** 337 | * The name of the illustrator of this card. Newly spoiled cards may not have this field yet. 338 | */ 339 | artist?: string; 340 | /** 341 | * The IDs of the artists that illustrated this card. Newly spoiled cards may not have this field yet. 342 | * 343 | * @type UUID 344 | */ 345 | artist_ids?: string[]; 346 | /** 347 | * The lit Unfinity attractions lights on this card, if any. 348 | * 349 | * This will be an array of numbers ranging from 1 to 6 inclusive. 350 | */ 351 | attraction_lights?: number[]; 352 | /** 353 | * Whether this card is found in boosters. 354 | */ 355 | booster: boolean; 356 | /** 357 | * This card’s border color: black, white, borderless, silver, or gold. 358 | */ 359 | border_color: `${ScryfallBorderColor}`; 360 | /** 361 | * This card’s collector number. Note that collector numbers can contain non-numeric characters, such as letters or ★. 362 | */ 363 | collector_number: string; 364 | /** 365 | * True if you should consider avoiding use of this print downstream. 366 | */ 367 | content_warning?: boolean; 368 | /** 369 | * True if this card was only released in a video game. 370 | */ 371 | digital: boolean; 372 | /** 373 | * An array of computer-readable flags that indicate if this card can come in foil, nonfoil, or etched finishes. 374 | */ 375 | finishes: `${ScryfallFinish}`[]; 376 | /** 377 | * This card’s frame effects, if any. 378 | */ 379 | frame_effects?: `${ScryfallFrameEffect}`[]; 380 | /** 381 | * This card’s frame layout. 382 | */ 383 | frame: `${ScryfallFrame}`; 384 | /** 385 | * True if this card’s artwork is larger than normal. 386 | */ 387 | full_art: boolean; 388 | /** 389 | * A list of games that this card print is available in, paper, arena, and/or mtgo. 390 | */ 391 | games: `${ScryfallGame}`[]; 392 | /** 393 | * True if this card’s imagery is high resolution. 394 | */ 395 | highres_image: boolean; 396 | /** 397 | * A unique identifier for the card artwork that remains consistent across reprints. Newly spoiled cards may not have this field yet. 398 | * 399 | * @type UUID 400 | */ 401 | illustration_id?: string; 402 | /** 403 | * A computer-readable indicator for the state of this card’s image, one of missing, placeholder, lowres, or highres_scan. 404 | */ 405 | image_status: `${ScryfallImageStatus}`; 406 | /** 407 | * True if this card is oversized. 408 | */ 409 | oversized: boolean; 410 | /** 411 | * An object containing daily price information for this card, including usd, usd_foil, usd_etched, eur, eur_foil, eur_etched, and tix prices, as strings. 412 | */ 413 | prices: ScryfallPrices; 414 | /** 415 | * True if this card is a promotional print. 416 | */ 417 | promo: boolean; 418 | /** 419 | * An array of strings describing what categories of promo cards this card falls into. 420 | */ 421 | promo_types?: ScryfallPromoType[]; 422 | /** 423 | * An object providing URIs to this card’s listing on major marketplaces. Omitted if the card is unpurchaseable. 424 | */ 425 | purchase_uris?: ScryfallPurchaseUris; 426 | /** 427 | * This card’s rarity. 428 | */ 429 | rarity: `${ScryfallRarity}`; 430 | /** 431 | * An object providing URIs to this card’s listing on other Magic: The Gathering online resources. 432 | */ 433 | related_uris: ScryfallRelatedUris; 434 | /** 435 | * The date this card was first released. 436 | * 437 | * @type IsoDate 438 | */ 439 | released_at: string; 440 | /** 441 | * True if this card is a reprint. 442 | */ 443 | reprint: boolean; 444 | /** 445 | * A link to this card’s set on Scryfall’s website. 446 | * 447 | * @type URI 448 | */ 449 | scryfall_set_uri: string; 450 | /** 451 | * This card’s full set name. 452 | */ 453 | set_name: string; 454 | /** 455 | * A link to where you can begin paginating this card’s set on the Scryfall API. 456 | * 457 | * @type URI 458 | */ 459 | set_search_uri: string; 460 | /** 461 | * The type of set this printing is in. 462 | */ 463 | set_type: `${SetType}`; 464 | /** 465 | * A link to this card’s set object on Scryfall’s API. 466 | * 467 | * @type URI 468 | */ 469 | set_uri: string; 470 | /** 471 | * This card’s set code. 472 | */ 473 | set: string; 474 | /** 475 | * This card’s Set object UUID. 476 | * 477 | * @type UUID 478 | */ 479 | set_id: string; 480 | /** 481 | * True if this card is a Story Spotlight. 482 | */ 483 | story_spotlight: boolean; 484 | /** 485 | * True if the card is printed without text. 486 | */ 487 | textless: boolean; 488 | /** 489 | * The security stamp on this card, if any. 490 | */ 491 | security_stamp?: `${ScryfallSecurityStamp}`; 492 | /** 493 | * Preview information for this print, if any. 494 | */ 495 | preview?: PreviewInfo; 496 | } & VariationInfo; 497 | 498 | /** 499 | * These print fields only show up when a card is single-sided. 500 | */ 501 | export type SingleSideOnly = { 502 | /** 503 | * The Scryfall ID for the card back design present on this card. 504 | * 505 | * @type UUID 506 | */ 507 | card_back_id: string; 508 | }; 509 | 510 | /** 511 | * These print fields are specific for the side of a card. 512 | * 513 | * - Root level for single-sided cards, whether with single-part or multi-part. 514 | * - Card face level for cards with two sides, e.g. a DFC or a reversible card. 515 | */ 516 | export type CardSideSpecific = { 517 | /** 518 | * An object listing available imagery for this card. See the Card Imagery article for more information. 519 | */ 520 | image_uris?: ScryfallImageUris; 521 | }; 522 | 523 | /** 524 | * These print fields are specific for a card face. 525 | * 526 | * - Root level for a single-faced card. 527 | * - Card face level for a multi-faced card. 528 | */ 529 | export type CardFaceSpecific = { 530 | /** 531 | * The just-for-fun name printed on the card (such as for Godzilla series cards). 532 | */ 533 | flavor_name?: string; 534 | /** 535 | * The flavor text, if any. 536 | */ 537 | flavor_text?: string; 538 | /** 539 | * This card’s watermark, if any. 540 | */ 541 | watermark?: string; 542 | } & Localization; 543 | 544 | /** 545 | * These print fields only ever show up on a card face. 546 | */ 547 | export type CardFaceOnly = { 548 | /** 549 | * The name of the illustrator of this card face. Newly spoiled cards may not have this field yet. 550 | */ 551 | artist?: string; 552 | /** 553 | * The ID of the illustrator of this card face. Newly spoiled cards may not have this field yet. 554 | * 555 | * @type UUID 556 | */ 557 | artist_id?: string; 558 | /** 559 | * A unique identifier for the card face artwork that remains consistent across reprints. Newly spoiled cards may not have this field yet. 560 | * 561 | * @type UUID 562 | */ 563 | illustration_id?: string; 564 | }; 565 | 566 | /** 567 | * Printed data for localized cards. 568 | */ 569 | export type Localization = { 570 | /** 571 | * The localized name printed on this card, if any. 572 | */ 573 | printed_name?: string; 574 | /** 575 | * The localized text printed on this card, if any. 576 | */ 577 | printed_text?: string; 578 | /** 579 | * The localized type line printed on this card, if any. 580 | */ 581 | printed_type_line?: string; 582 | }; 583 | 584 | type VariationInfo = { 585 | /** 586 | * Whether this card is a variation of another printing. 587 | */ 588 | variation: boolean; 589 | /** 590 | * The printing ID of the printing this card is a variation of. 591 | * 592 | * This will only exist if the `variation` field is true. 593 | * 594 | * @type UUID 595 | */ 596 | variation_of?: string; 597 | }; 598 | } 599 | -------------------------------------------------------------------------------- /src/objects/Card/RelatedCard.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | 3 | /** 4 | * A related card entry. 5 | */ 6 | export type ScryfallRelatedCard = ScryfallObject.Object & { 7 | /** 8 | * An unique ID for this card in Scryfall’s database. 9 | * 10 | * @type UUID 11 | */ 12 | id: string; 13 | /** 14 | * A field explaining what role this card plays in this relationship. 15 | */ 16 | component: "token" | "meld_part" | "meld_result" | "combo_piece"; 17 | /** 18 | * The name of this particular related card. 19 | */ 20 | name: string; 21 | /** 22 | * The type line of this card. 23 | */ 24 | type_line: string; 25 | /** 26 | * A URI where you can retrieve a full object describing this card on Scryfall’s API. 27 | * 28 | * @type URI 29 | */ 30 | uri: string; 31 | }; 32 | -------------------------------------------------------------------------------- /src/objects/Card/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Card"; 2 | export * from "./CardFace"; 3 | export * from "./CardFields"; 4 | export * from "./RelatedCard"; 5 | 6 | export * from "./values"; 7 | -------------------------------------------------------------------------------- /src/objects/Card/values/BorderColor.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The border color of a print. 3 | * 4 | * Note this is a physical description of the border, not a reference to “black border” or “silver border” gameplay. 5 | */ 6 | export enum ScryfallBorderColor { 7 | Black = "black", 8 | White = "white", 9 | Borderless = "borderless", 10 | Silver = "silver", 11 | Gold = "gold", 12 | } 13 | -------------------------------------------------------------------------------- /src/objects/Card/values/Color.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallColor { 2 | White = "W", 3 | Blue = "U", 4 | Black = "B", 5 | Red = "R", 6 | Green = "G", 7 | /** Colorless is not a color, but sometimes this API uses it as one. */ 8 | Colorless = "C", 9 | } 10 | 11 | export type ScryfallColors = `${ScryfallColor}`[]; 12 | -------------------------------------------------------------------------------- /src/objects/Card/values/Finish.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallFinish { 2 | Nonfoil = "nonfoil", 3 | Foil = "foil", 4 | Etched = "etched", 5 | } 6 | -------------------------------------------------------------------------------- /src/objects/Card/values/Format.ts: -------------------------------------------------------------------------------- 1 | export type ScryfallFormat = 2 | | "standard" 3 | | "future" 4 | | "historic" 5 | | "gladiator" 6 | | "pioneer" 7 | | "explorer" 8 | | "modern" 9 | | "legacy" 10 | | "pauper" 11 | | "vintage" 12 | | "penny" 13 | | "commander" 14 | | "oathbreaker" 15 | | "brawl" 16 | | "alchemy" 17 | | "paupercommander" 18 | | "duel" 19 | | "oldschool" 20 | | "premodern" 21 | | "predh" 22 | | "timeless" 23 | | "standardbrawl"; 24 | -------------------------------------------------------------------------------- /src/objects/Card/values/Frame.ts: -------------------------------------------------------------------------------- 1 | // TODO 2 | export type ScryfallFrame = string; 3 | export type ScryfallFrameLike = string; 4 | -------------------------------------------------------------------------------- /src/objects/Card/values/FrameEffect.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallFrameEffect { 2 | /** The cards have a legendary crown */ 3 | Legendary = "legendary", 4 | /** The miracle frame effect */ 5 | Miracle = "miracle", 6 | /** The Nyx-touched frame effect */ 7 | Nyxtouched = "nyxtouched", 8 | /** The draft-matters frame effect */ 9 | Draft = "draft", 10 | /** The Devoid frame effect */ 11 | Devoid = "devoid", 12 | /** The Odyssey tombstone mark */ 13 | Tombstone = "tombstone", 14 | /** A colorshifted frame */ 15 | Colorshifted = "colorshifted", 16 | /** The FNM-style inverted frame */ 17 | Inverted = "inverted", 18 | /** The sun and moon transform marks */ 19 | SunMoonDfc = "sunmoondfc", 20 | /** The compass and land transform marks */ 21 | CompassLandDfc = "compasslanddfc", 22 | /** The Origins and planeswalker transform marks */ 23 | OriginPwDfc = "originpwdfc", 24 | /** The moon and Eldrazi transform marks */ 25 | MoonEldraziDfc = "mooneldrazidfc", 26 | /** The waxing and waning crescent moon transform marks */ 27 | WaxingAndWaningMoonDfc = "waxingandwaningmoondfc", 28 | /** A custom Showcase frame */ 29 | Showcase = "showcase", 30 | /** An extended art frame */ 31 | ExtendedArt = "extendedart", 32 | /** The cards have a companion frame */ 33 | Companion = "companion", 34 | /** The cards have an etched foil treatment */ 35 | Etched = "etched", 36 | /** The cards have the snowy frame effect */ 37 | Snow = "snow", 38 | /** The cards have the Lesson frame effect */ 39 | Lesson = "lesson", 40 | /** The cards have the Shattered Glass frame effect */ 41 | ShatteredGlass = "shatteredglass", 42 | /** The cards have More Than Meets the Eye™ marks */ 43 | ConvertDfc = "convertdfc", 44 | /** The cards have fan transforming marks */ 45 | FanDfc = "fandfc", 46 | /** The cards have the Upside Down transforming marks */ 47 | UpsidedownDfc = "upsidedowndfc", 48 | } 49 | -------------------------------------------------------------------------------- /src/objects/Card/values/Game.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallGame { 2 | /** 3 | * The printed paper game. 4 | * Released in 1993. 5 | */ 6 | Paper = "paper", 7 | /** 8 | * Magic: the Gathering Online 9 | * Released in 2002. 10 | */ 11 | Mtgo = "mtgo", 12 | /** 13 | * Magic: the Gathering: Arena 14 | * Released in 2018. 15 | */ 16 | Arena = "arena", 17 | /** 18 | * Magic: the Gathering (MicroProse) 19 | * Released in 1997. 20 | * 21 | * This game included an expansion named Astral that included some unique cards. 22 | */ 23 | Astral = "astral", 24 | /** 25 | * Magic: the Gathering (Sega Dreamcast) 26 | * Released in 2001. 27 | */ 28 | Sega = "sega", 29 | } 30 | -------------------------------------------------------------------------------- /src/objects/Card/values/ImageSize.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallImageSize { 2 | /** 3 | * A small image. 4 | * 5 | * Dimensions: 146 x 204 6 | * Size: Approx 10kb 7 | * Filetype: JPG 8 | */ 9 | Small = "small", 10 | /** 11 | * A normal image. 12 | * 13 | * Dimensions: 488 x 680 14 | * Size: Approx 60kb 15 | * Filetype: JPG 16 | */ 17 | Normal = "normal", 18 | /** 19 | * A large image. 20 | * 21 | * Dimensions: 672 x 936 22 | * Size: Approx 100kb 23 | * Filetype: JPG 24 | */ 25 | Large = "large", 26 | /** 27 | * A large PNG with transparent corners. 28 | * 29 | * This is the highest quality image with the largest dimensions. 30 | * 31 | * Dimensions: 745 x 1040 32 | * Size: Approx 1mb 33 | * Filetype: PNG 34 | */ 35 | Png = "png", 36 | /** 37 | * A crop from the PNG representing just the artwork portion of the card. 38 | * 39 | * Dimensions: Varies 40 | * Size: Approx 50kb-100kb 41 | * Filetype: JPG 42 | */ 43 | ArtCrop = "art_crop", 44 | /** 45 | * A version of the image that crops off a precise amount around the edges to omit the border. 46 | * 47 | * Cards receive identical cropping regardless of how thick their actual border is. Even borderless cards will receive the same crop. 48 | * 49 | * This image size exists for backwards compatibility with MagicCards.info. 50 | * Some systems will use this and illustrate their own border around the edge in CSS. 51 | * 52 | * Dimensions: 480 x 680 53 | * Size: Approx 60kb 54 | * Filetype: JPG 55 | */ 56 | BorderCrop = "border_crop", 57 | } 58 | -------------------------------------------------------------------------------- /src/objects/Card/values/ImageStatus.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallImageStatus { 2 | /** 3 | * This card's image is missing. It has not been added yet. 4 | * This is usually an error Scryfall will catch quickly, but some cases involve uploading cards that simply do not yet have images available at all, such as unsigned art cards. 5 | */ 6 | Missing = "missing", 7 | /** 8 | * This card's image is a placeholder Scryfall has generated and visibly marked as such. 9 | * This is most commonly seen for languages where no real images are yet available to us. 10 | */ 11 | Placeholder = "placeholder", 12 | /** 13 | * This card's image is low resolution. 14 | * This will most commonly be seen on recently previewed cards. 15 | */ 16 | LowRes = "lowres", 17 | /** 18 | * This card's image is high resolution and/or a scan. 19 | * In theory this should be a scan, in practice it might be tripped by other large imagery. 20 | */ 21 | HighResScan = "highres_scan", 22 | } 23 | -------------------------------------------------------------------------------- /src/objects/Card/values/ImageUris.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallImageSize } from "./ImageSize"; 2 | 3 | /** 4 | * URIs for various image sizes of this card. 5 | */ 6 | export type ScryfallImageUris = Record; 7 | -------------------------------------------------------------------------------- /src/objects/Card/values/LanguageCode.ts: -------------------------------------------------------------------------------- 1 | /** The language code for cards as used by Scryfall. 2 | * Note this might differ from the printed code found on the card. 3 | * See: https://scryfall.com/docs/api/languages 4 | */ 5 | 6 | export enum ScryfallLanguageCode { 7 | /** English */ 8 | English = "en", 9 | /** Spanish */ 10 | Spanish = "es", 11 | /** French */ 12 | French = "fr", 13 | /** German */ 14 | German = "de", 15 | /** Italian */ 16 | Italian = "it", 17 | /** Portuguese */ 18 | Portuguese = "pt", 19 | /** Japanese */ 20 | Japanese = "ja", 21 | /** Korean */ 22 | Korean = "ko", 23 | /** Russian */ 24 | Russian = "ru", 25 | /** Simplified Chinese */ 26 | SimplifiedChinese = "zhs", 27 | /** Traditional Chinese */ 28 | TraditionalChinese = "zht", 29 | /** Hebrew */ 30 | Hebrew = "he", 31 | /** Latin */ 32 | Latin = "la", 33 | /** Ancient Greek */ 34 | AncientGreek = "grc", 35 | /** Arabic */ 36 | Arabic = "ar", 37 | /** Sanskrit */ 38 | Sanskrit = "sa", 39 | /** Phyrexian */ 40 | Phyrexian = "ph", 41 | } 42 | -------------------------------------------------------------------------------- /src/objects/Card/values/Layout.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The set of card layouts. 3 | */ 4 | export enum ScryfallLayout { 5 | /** A standard Magic card with one face */ 6 | Normal = "normal", 7 | /** A split-faced card */ 8 | Split = "split", 9 | /** Cards that invert vertically with the flip keyword */ 10 | Flip = "flip", 11 | /** Double-sided cards that transform */ 12 | Transform = "transform", 13 | /** Double-sided cards that can be played either-side */ 14 | ModalDfc = "modal_dfc", 15 | /** Cards with meld parts printed on the back */ 16 | Meld = "meld", 17 | /** Cards with Level Up */ 18 | Leveler = "leveler", 19 | /** Class-type enchantment cards */ 20 | Class = "class", 21 | /** Saga-type cards */ 22 | Saga = "saga", 23 | /** Cards with an Adventure spell part */ 24 | Adventure = "adventure", 25 | /** Cards with Mutate */ 26 | Mutate = "mutate", 27 | /** Cards with Prototype */ 28 | Prototype = "prototype", 29 | /** Battle-type cards */ 30 | Battle = "battle", 31 | /** Plane and Phenomenon-type cards */ 32 | Planar = "planar", 33 | /** Scheme-type cards */ 34 | Scheme = "scheme", 35 | /** Vanguard-type cards */ 36 | Vanguard = "vanguard", 37 | /** Token cards */ 38 | Token = "token", 39 | /** Tokens with another token printed on the back */ 40 | DoubleFacedToken = "double_faced_token", 41 | /** Emblem cards */ 42 | Emblem = "emblem", 43 | /** Cards with Augment */ 44 | Augment = "augment", 45 | /** Host-type cards */ 46 | Host = "host", 47 | /** Art Series collectable double-faced cards */ 48 | ArtSeries = "art_series", 49 | /** A Magic card with two sides that are unrelated */ 50 | ReversibleCard = "reversible_card", 51 | /** A special type of multi-part enchantment from Murders at Karlov Manor */ 52 | Case = "case", 53 | } 54 | 55 | /** 56 | * Groupings of layouts. 57 | */ 58 | export namespace ScryfallLayoutGroup { 59 | /** 60 | * All layouts that represent a single-faced card, i.e. one with no card_faces property. 61 | * 62 | * @see {@link SingleFacedType} for the type of this group. 63 | */ 64 | export const SingleFaced = [ 65 | `${ScryfallLayout.Normal}`, 66 | `${ScryfallLayout.Meld}`, 67 | `${ScryfallLayout.Leveler}`, 68 | `${ScryfallLayout.Class}`, 69 | `${ScryfallLayout.Saga}`, 70 | `${ScryfallLayout.Mutate}`, 71 | `${ScryfallLayout.Prototype}`, 72 | `${ScryfallLayout.Battle}`, 73 | `${ScryfallLayout.Planar}`, 74 | `${ScryfallLayout.Scheme}`, 75 | `${ScryfallLayout.Vanguard}`, 76 | `${ScryfallLayout.Token}`, 77 | `${ScryfallLayout.Emblem}`, 78 | `${ScryfallLayout.Augment}`, 79 | `${ScryfallLayout.Host}`, 80 | ] as const; 81 | 82 | /** 83 | * A type for all layouts that represent a single-faced card, i.e. one with no card_faces property. 84 | * 85 | * @see {@link SingleFaced} for an array version. 86 | */ 87 | export type SingleFacedType = (typeof SingleFaced)[number]; 88 | 89 | /** 90 | * All layouts that represent a multi-faced card where both faces are on the front. 91 | * 92 | * @see {@link SingleSidedSplitType} for the type of this group. 93 | */ 94 | export const SingleSidedSplit = [ 95 | `${ScryfallLayout.Split}`, 96 | `${ScryfallLayout.Flip}`, 97 | `${ScryfallLayout.Adventure}`, 98 | ] as const; 99 | 100 | /** 101 | * A type for all layouts that represent a multi-faced card where both faces are on the front. 102 | * 103 | * @see {@link SingleSidedSplit} for an array version. 104 | * 105 | */ 106 | export type SingleSidedSplitType = (typeof SingleSidedSplit)[number]; 107 | 108 | /** 109 | * All layouts that represent a multi-faced card where the faces are on the front and back of the card. 110 | * 111 | * @see {@link DoubleSidedSplitType} for the type of this group. 112 | */ 113 | export const DoubleSidedSplit = [ 114 | `${ScryfallLayout.Transform}`, 115 | `${ScryfallLayout.ModalDfc}`, 116 | `${ScryfallLayout.DoubleFacedToken}`, 117 | `${ScryfallLayout.ArtSeries}`, 118 | ] as const; 119 | 120 | /** 121 | * A type for all layouts that represent a multi-faced card where the faces are on the front and back of the card. 122 | * 123 | * @see {@link DoubleSidedSplit} for an array version. 124 | * 125 | */ 126 | export type DoubleSidedSplitType = (typeof DoubleSidedSplit)[number]; 127 | } 128 | -------------------------------------------------------------------------------- /src/objects/Card/values/LegalitiesField.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallFormat } from "./Format"; 2 | import { ScryfallLegality } from "./Legality"; 3 | 4 | export type ScryfallLegalitiesField = Record<`${ScryfallFormat}`, `${ScryfallLegality}`>; 5 | -------------------------------------------------------------------------------- /src/objects/Card/values/Legality.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallLegality { 2 | Legal = "legal", 3 | NotLegal = "not_legal", 4 | Restricted = "restricted", 5 | Banned = "banned", 6 | } 7 | -------------------------------------------------------------------------------- /src/objects/Card/values/ManaType.ts: -------------------------------------------------------------------------------- 1 | enum ScryfallManaType { 2 | White = "W", 3 | Blue = "U", 4 | Black = "B", 5 | Red = "R", 6 | Green = "G", 7 | Colorless = "C", 8 | } 9 | 10 | export type ScryfallManaTypes = `${ScryfallManaType}`[]; 11 | -------------------------------------------------------------------------------- /src/objects/Card/values/Prices.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prices for a card in various treatments. 3 | */ 4 | export type ScryfallPrices = { 5 | usd: string | null; 6 | usd_foil: string | null; 7 | usd_etched: string | null; 8 | eur: string | null; 9 | eur_foil: string | null; 10 | tix: string | null; 11 | }; 12 | -------------------------------------------------------------------------------- /src/objects/Card/values/PromoType.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallFrameAppearance { 2 | /** 3 | * A Lord of the Rings appearance that made the card name, type line and oracle text area appear as scrolls. 4 | */ 5 | Scroll = "scroll", 6 | /** 7 | * Cards with the appearance of a poster, e.g. the horror movie secret lairs. 8 | */ 9 | Poster = "poster", 10 | /** 11 | * The showcase finish style from Murders at Karlov Manor. 12 | */ 13 | Dossier = "dossier", 14 | /** 15 | * A special treatment applied to certain guild leader cards. 16 | */ 17 | RavnicaCity = "ravnicacity", 18 | /** 19 | * Another showcase style from Murders at Karlov Manor. 20 | */ 21 | Magnified = "magnified", 22 | } 23 | 24 | export enum ScryfallExtendedFinish { 25 | /** 26 | * A glossy finish. 27 | */ 28 | Glossy = "glossy", 29 | /** 30 | * The silverfoil finish. 31 | */ 32 | SilverFoil = "silverfoil", 33 | /** 34 | * The confetti foil finish. This looks glimmery like confetti laying on top of the card. 35 | */ 36 | ConfettiFoil = "confettifoil", 37 | /** 38 | * Galaxy foil. 39 | */ 40 | GalaxyFoil = "galaxyfoil", 41 | /** 42 | * Halo foil. 43 | */ 44 | HaloFoil = "halofoil", 45 | /** 46 | * Surge foil 47 | */ 48 | SurgeFoil = "surgefoil", 49 | /** 50 | * Double the rainbow vs normal cards. 51 | */ 52 | DoubleRainbow = "doublerainbow", 53 | /** 54 | * A textured foil finish. 55 | */ 56 | Textured = "textured", 57 | /** 58 | * A Phyrexian finish that involved dark cards embossed with shiny black gloss. 59 | */ 60 | Oilslick = "oilslick", 61 | /** 62 | * Neon ink embossd on the card frame and art. 63 | */ 64 | NeonInk = "neonink", 65 | /** 66 | * A Capenna foil style that embosses the art deco frame with shininess. 67 | */ 68 | Gilded = "gilded", 69 | /** 70 | * Rainbow phyrexian symbols patterned over the card face. 71 | * @trivia The name was a reference to "step and repeat", a style of pattern used in printing banners. 72 | */ 73 | StepAndCompleat = "stepandcompleat", 74 | /** 75 | * A glossy finish with an emblem embossed on it. 76 | * 77 | * Examples include the D&D Ampersand logo or REX Jurassic Park logo. 78 | */ 79 | Embossed = "embossed", 80 | /** 81 | * The Dungeons & Dragons glossy finish that superimposed an ampersand over the card. 82 | * 83 | * @deprecated This is replaced by {@link Embossed} instead. 84 | */ 85 | Ampersand = "ampersand", 86 | /** 87 | * Special dossier cards from Murders at Karlov Manor with extra handwritten flavor text and imagery. 88 | */ 89 | InvisibleInk = "invisibleink", 90 | } 91 | 92 | export enum ScryfallCardStock { 93 | /** 94 | * Cards printed on extra-thick cardstock. 95 | */ 96 | Thick = "thick", 97 | /** 98 | * Cards printed on plastic stock. 99 | */ 100 | Plastic = "plastic", 101 | } 102 | 103 | type ScryfallPrintAttribute = 104 | /** 105 | * Cards exclusive to the Alchemy format in Arena. 106 | */ 107 | | "alchemy" 108 | /** 109 | * Arena League prize cards. 110 | * 111 | * No relation to the video game. 112 | * 113 | * @trivia Arena League was a competitive event that ran from 1996 to 2007. 114 | */ 115 | | "arenaleague" 116 | /** 117 | * Project Booster Fun cards. 118 | */ 119 | | "boosterfun" 120 | /** 121 | * Box topper promotional cards found in some sets' booster boxes. 122 | */ 123 | | "boxtopper" 124 | /** 125 | * Prints exclusive to brawl decks. 126 | */ 127 | | "brawldeck" 128 | /** 129 | * Bring-a-friend store event promos. 130 | */ 131 | | "bringafriend" 132 | /** 133 | * Bundle promos. 134 | */ 135 | | "bundle" 136 | /** 137 | * Buyabox promos. 138 | */ 139 | | "buyabox" 140 | /** 141 | * Commander party promos. 142 | */ 143 | | "commanderparty" 144 | /** 145 | * Concept praetors. 146 | */ 147 | | "concept" 148 | /** 149 | * Convention promos. 150 | */ 151 | | "convention" 152 | /** 153 | * Cards datestamped in the corner of the art frame. 154 | */ 155 | | "datestamped" 156 | /** 157 | * Dracula series cards. 158 | */ 159 | | "draculaseries" 160 | /** 161 | * Draft weekend event promo cards. 162 | */ 163 | | "draftweekend" 164 | /** 165 | * Duels of the Planeswalkers promos. 166 | */ 167 | | "duels" 168 | /** 169 | * Event promos. 170 | */ 171 | | "event" 172 | /** 173 | * FNM promos. 174 | */ 175 | | "fnm" 176 | /** 177 | * Game day promos. 178 | */ 179 | | "gameday" 180 | /** 181 | * Gift box promos. 182 | */ 183 | | "giftbox" 184 | /** 185 | * Godzilla series cards. 186 | */ 187 | | "godzillaseries" 188 | /** 189 | * Instore event promos. 190 | */ 191 | | "instore" 192 | /** 193 | * Prints exclusive to intro packs/decks. 194 | */ 195 | | "intropack" 196 | /** 197 | * Cards in the Japanese planeswalker series. 198 | */ 199 | | "jpwalker" 200 | /** 201 | * Judge program gift cards. 202 | */ 203 | | "judgegift" 204 | /** 205 | * Miscellaneous promos marked as League promos, e.g. APAC league. 206 | */ 207 | | "league" 208 | /** 209 | * Media inserts, e.g. prints given out packaged with magazines or books. 210 | */ 211 | | "mediainsert" 212 | /** 213 | * Cards in the moonlit land series. 214 | */ 215 | | "moonlitland" 216 | /** 217 | * Openhouse promos. 218 | */ 219 | | "openhouse" 220 | /** 221 | * Prints exclusive to planeswalker decks. 222 | */ 223 | | "planeswalkerdeck" 224 | /** 225 | * Player rewards promos. 226 | */ 227 | | "playerrewards" 228 | /** 229 | * Play promos. 230 | */ 231 | | "playpromo" 232 | /** 233 | * Premier e-Shop promos. 234 | */ 235 | | "premiereshop" 236 | /** 237 | * Prerelease event datestamped cards. 238 | */ 239 | | "prerelease" 240 | /** 241 | * Cards found in promo packs. 242 | * 243 | * @see "stamped" Promop pack cards are usualy also stamped. 244 | */ 245 | | "promopack" 246 | /** 247 | * Cards that are rebalanced versions for the Alchemy format in Arena. 248 | */ 249 | | "rebalanced" 250 | /** 251 | * Release event promos. 252 | */ 253 | | "release" 254 | /** 255 | * Simplified chinese alt-art cards. 256 | * 257 | * Due to Chinese censorship rules, some cards receive alternate art in Chinese releases. 258 | */ 259 | | "schinesealtart" 260 | /** 261 | * Serialized cards. (001/500, etc.) 262 | */ 263 | | "serialized" 264 | /** 265 | * Set Extension cards. 266 | * 267 | * E.g.: Rafiq of the Many had a gilded showcase released in SNC boosters. 268 | * It was given the collector info ALA 250, extending the original Alara set code. 269 | * Scryfall records this in the ALA sert because that's the set code, but we mark it as an “extension” of that set. 270 | */ 271 | | "setextension" 272 | /** 273 | * (TODO) 274 | */ 275 | | "setpromo" 276 | /** 277 | * Cards stamped with a planeswalker symbol in the corner of the art frame released in store boosters. 278 | * 279 | * Not to be confused with The List cards, which have a small planeswalker symbol in the bottom left corner of the card. 280 | */ 281 | | "stamped" 282 | /** 283 | * Prints found exclusively in a starter deck. 284 | */ 285 | | "starterdeck" 286 | /** 287 | * Store championship participation and prize cards. 288 | */ 289 | | "storechampionship" 290 | /** 291 | * Prints found exclusively in theme boosters. 292 | */ 293 | | "themepack" 294 | /** 295 | * Tournament promo cards. 296 | */ 297 | | "tourney" 298 | /** 299 | * Wizards play network promo cards. 300 | */ 301 | | "wizardsplaynetwork"; 302 | 303 | export type ScryfallPromoType = 304 | | ScryfallPrintAttribute 305 | | `${ScryfallFrameAppearance}` 306 | | `${ScryfallExtendedFinish}` 307 | | `${ScryfallCardStock}`; 308 | -------------------------------------------------------------------------------- /src/objects/Card/values/PurchaseUris.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Possible purchase URIs for a card. 3 | */ 4 | export type ScryfallPurchaseUris = { 5 | /** 6 | * This card's purchase page on TCGPlayer. 7 | * 8 | * @type URI 9 | */ 10 | tcgplayer: string; 11 | /** 12 | * This card's purchase page on Cardmarket. Often inexact due to how Cardmarket links work. 13 | * 14 | * @type URI 15 | */ 16 | cardmarket: string; 17 | /** 18 | * This card's purchase page on Cardhoarder. 19 | * 20 | * @type URI 21 | */ 22 | cardhoarder: string; 23 | }; 24 | -------------------------------------------------------------------------------- /src/objects/Card/values/Rarity.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallRarity { 2 | Common = "common", 3 | Uncommon = "uncommon", 4 | Rare = "rare", 5 | Special = "special", 6 | Mythic = "mythic", 7 | Bonus = "bonus", 8 | } 9 | -------------------------------------------------------------------------------- /src/objects/Card/values/RelatedUris.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Related URIs for a card. 3 | */ 4 | export type ScryfallRelatedUris = { 5 | /** 6 | * This card's Gatherer page. 7 | * 8 | * @type URI 9 | */ 10 | gatherer?: string; 11 | /** 12 | * TCGPlayer Infinite articles related to this card. 13 | * 14 | * @type URI 15 | */ 16 | tcgplayer_infinite_articles?: string; 17 | /** 18 | * TCGPlayer Infinite decks with this card. 19 | * 20 | * @type URI 21 | */ 22 | tcgplayer_infinite_decks?: string; 23 | /** 24 | * EDHREC's page for this card. 25 | * 26 | * @type URI 27 | */ 28 | edhrec?: string; 29 | }; 30 | -------------------------------------------------------------------------------- /src/objects/Card/values/SecurityStamp.ts: -------------------------------------------------------------------------------- 1 | export enum ScryfallSecurityStamp { 2 | Oval = "oval", 3 | Triangle = "triangle", 4 | Acorn = "acorn", 5 | Circle = "circle", 6 | Arena = "arena", 7 | Heart = "heart", 8 | } 9 | -------------------------------------------------------------------------------- /src/objects/Card/values/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./BorderColor"; 2 | export * from "./Color"; 3 | export * from "./Finish"; 4 | export * from "./Format"; 5 | export * from "./Frame"; 6 | export * from "./FrameEffect"; 7 | export * from "./Game"; 8 | export * from "./ImageSize"; 9 | export * from "./ImageStatus"; 10 | export * from "./ImageUris"; 11 | export * from "./LegalitiesField"; 12 | export * from "./LanguageCode"; 13 | export * from "./Layout"; 14 | export * from "./Legality"; 15 | export * from "./ManaType"; 16 | export * from "./Prices"; 17 | export * from "./PromoType"; 18 | export * from "./PurchaseUris"; 19 | export * from "./Rarity"; 20 | export * from "./RelatedUris"; 21 | export * from "./SecurityStamp"; 22 | -------------------------------------------------------------------------------- /src/objects/Catalog/Catalog.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | 3 | /** 4 | * A catalog of values. 5 | * 6 | * @see {@link https://scryfall.com/docs/api/catalogs} 7 | */ 8 | export type ScryfallCatalog = ScryfallObject.Object & { 9 | /** 10 | * A link to the current catalog on Scryfall’s API 11 | * 12 | * @type URI 13 | */ 14 | uri: string; 15 | /** 16 | * The number of items in the `data` array 17 | * 18 | * @type Integer 19 | */ 20 | total_values: number; 21 | /** 22 | * An array of datapoints, as strings 23 | */ 24 | data: string[]; 25 | }; 26 | -------------------------------------------------------------------------------- /src/objects/Catalog/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Catalog"; 2 | -------------------------------------------------------------------------------- /src/objects/Error/Error.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | 3 | /** 4 | * An error response from the Scryfall API. 5 | * 6 | * Scryfall API responses may return this if something goes wrong. 7 | * 8 | * @see {@link https://scryfall.com/docs/api/errors} 9 | */ 10 | export type ScryfallError = ScryfallObject.Object & { 11 | /** 12 | * An integer HTTP status code for this error. 13 | * 14 | * @type Integer 15 | */ 16 | status: number; 17 | /** 18 | * A computer-friendly string representing the appropriate HTTP status code. 19 | */ 20 | code: string; 21 | /** 22 | * A human-readable string explaining the error. 23 | */ 24 | details: string; 25 | /** 26 | * A computer-friendly string that provides additional context for the main error. 27 | * For example, an endpoint many generate HTTP 404 errors for different kinds of input. 28 | * This field will provide a label for the specific kind of 404 failure, such as ambiguous. 29 | */ 30 | type?: string; 31 | /** 32 | * If your input also generated non-failure warnings, they will be provided as human-readable strings in this array. 33 | */ 34 | warnings?: string[]; 35 | }; 36 | -------------------------------------------------------------------------------- /src/objects/Error/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Error"; 2 | -------------------------------------------------------------------------------- /src/objects/List/List.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { ScryfallCard } from "../Card"; 3 | import { ScryfallMigration } from "../Migration"; 4 | import { ScryfallRuling } from "../Ruling"; 5 | import { ScryfallSet } from "../Set"; 6 | import { ScryfallCardSymbol } from "../Symbology"; 7 | 8 | /** 9 | * A list of Scryfall objects. 10 | * 11 | * @see {@link https://scryfall.com/docs/api/lists} 12 | */ 13 | export namespace ScryfallList { 14 | /** 15 | * A list of objects of type T. 16 | * 17 | * Lists of cards have an additional property, {@link List.total_cards}, not found on other lists. 18 | */ 19 | export type List = ScryfallObject.Object & { 20 | /** 21 | * An array of the requested objects, in a specific order. 22 | */ 23 | data: T[]; 24 | /** 25 | * True if this List is paginated and there is a page beyond the current page. 26 | */ 27 | has_more: boolean; 28 | /** 29 | * If there is a page beyond the current page, this field will contain a full API URI to that page. You may submit a HTTP GET request to that URI to continue paginating forward on this List. 30 | * 31 | * This is only defined when `has_more` is true. 32 | * 33 | * @type URI 34 | */ 35 | next_page?: string; 36 | /** 37 | * If this is a list of Card objects, this field will contain the total number of cards found across all pages. 38 | * Otherwise this field will be undefined. 39 | * 40 | * @type Integer 41 | */ 42 | total_cards?: number; 43 | /** 44 | * An array of human-readable warnings issued when generating this list, as strings. 45 | * 46 | * Warnings are non-fatal issues that the API discovered with your input. 47 | * In general, they indicate that the List will not contain the all of the information you requested. 48 | * You should fix the warnings and re-submit your request. 49 | */ 50 | warnings?: string[]; 51 | }; 52 | 53 | /** 54 | * A list of cards. 55 | * 56 | * @see {@link ScryfallCard} 57 | */ 58 | export type Cards = List; 59 | 60 | /** 61 | * A list of sets. 62 | * 63 | * @see {@link ScryfallSet} 64 | */ 65 | export type Sets = List; 66 | 67 | /** 68 | * A list of rulings. 69 | * 70 | * @see {@link ScryfallRuling} 71 | */ 72 | export type Rulings = List; 73 | 74 | /** 75 | * A list of card symbols. 76 | * 77 | * @see {@link ScryfallCardSymbol} 78 | */ 79 | export type CardSymbols = List; 80 | 81 | /** 82 | * A list of migrations. 83 | * 84 | * @see {@link ScryfallMigration} 85 | */ 86 | export type Migrations = List; 87 | } 88 | -------------------------------------------------------------------------------- /src/objects/List/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./List"; 2 | -------------------------------------------------------------------------------- /src/objects/Migration/Migration.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | 3 | export enum ScryfallMigrationStrategy { 4 | Merge = "merge", 5 | Delete = "delete", 6 | } 7 | 8 | /** 9 | * A data migration. 10 | * 11 | * @see {@link https://scryfall.com/docs/api/migrations} 12 | */ 13 | export type ScryfallMigration = ScryfallObject.Object & { 14 | /** 15 | * A link to the current object on Scryfall's API 16 | * 17 | * @type URI 18 | */ 19 | uri: string; 20 | /** 21 | * This migration's unique UUID 22 | * 23 | * @type UUID 24 | */ 25 | id: string; 26 | /** 27 | * The date this migration was performed 28 | * 29 | * @type IsoDate 30 | */ 31 | performed_at: string; 32 | /** 33 | * A computer-readable indicator of the migration strategy. 34 | */ 35 | migration_strategy: `${ScryfallMigrationStrategy}`; 36 | /** 37 | * The `id` of the affected API Card object 38 | * 39 | * @type UUID 40 | */ 41 | old_scryfall_id: string; 42 | /** 43 | * The replacement `id` of the API Card object if this is a `merge` 44 | * 45 | * @type UUID 46 | */ 47 | new_scryfall_id?: string; 48 | /** 49 | * A note left by the Scryfall team about this migration 50 | */ 51 | note?: string; 52 | /** 53 | * Additional context Scryfall has provided for this migration, designed to be human-read only 54 | */ 55 | metadata?: object; 56 | }; 57 | -------------------------------------------------------------------------------- /src/objects/Migration/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Migration"; 2 | -------------------------------------------------------------------------------- /src/objects/Object/Object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This namespace defines the abstract base object property of all Scryfall objects. 3 | */ 4 | export namespace ScryfallObject { 5 | /** 6 | * The type of object. 7 | */ 8 | export enum ObjectType { 9 | /** 10 | * A card. 11 | */ 12 | Card = "card", 13 | /** 14 | * A card face, featured in the card_faces section of {@link ObjectType.Card} objects. 15 | */ 16 | CardFace = "card_face", 17 | /** 18 | * A card symbol. 19 | */ 20 | CardSymbol = "card_symbol", 21 | /** 22 | * A catalog of objects. 23 | */ 24 | Catalog = "catalog", 25 | /** 26 | * An error response. 27 | */ 28 | Error = "error", 29 | /** 30 | * A list (of cards, sets, etc). 31 | */ 32 | List = "list", 33 | /** 34 | * A mana cost. 35 | */ 36 | ManaCost = "mana_cost", 37 | /** 38 | * A data migration. 39 | */ 40 | Migration = "migration", 41 | /** 42 | * A related card, featured in the all_parts section of a {@link ObjectType.Card} object. 43 | */ 44 | RelatedCard = "related_card", 45 | /** 46 | * A card ruling. 47 | */ 48 | Ruling = "ruling", 49 | /** 50 | * A set. 51 | */ 52 | Set = "set", 53 | } 54 | 55 | /** 56 | * The abstract base type of Scryfall objects. 57 | */ 58 | export type Object = { 59 | /** 60 | * A content type for this object. 61 | */ 62 | object: T | `${T}`; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/objects/Object/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Object"; 2 | -------------------------------------------------------------------------------- /src/objects/Ruling/Ruling.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | 3 | /** 4 | * Rulings made on a card by the rules manager. 5 | * 6 | * @see {@link https://scryfall.com/docs/api/rulings} 7 | */ 8 | export type ScryfallRuling = ScryfallObject.Object & { 9 | /** 10 | * The Oracle ID of the card this ruling is associated with. 11 | * 12 | * @type UUID 13 | */ 14 | oracle_id: string; 15 | /** 16 | * A computer-readable string indicating which company produced this ruling, either `wotc` or `scryfall` 17 | */ 18 | source: "wotc" | "scryfall"; 19 | /** 20 | * The date when the ruling or note was published 21 | * 22 | * @type IsoDate 23 | */ 24 | published_at: string; 25 | /** 26 | * The text of the ruling 27 | */ 28 | comment: string; 29 | }; 30 | -------------------------------------------------------------------------------- /src/objects/Ruling/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Ruling"; 2 | -------------------------------------------------------------------------------- /src/objects/Set/Set.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { SetType } from "./values"; 3 | 4 | /** 5 | * Description of a Magic card set. 6 | * 7 | * @see {@link https://scryfall.com/docs/api/sets} 8 | */ 9 | export type ScryfallSet = ScryfallObject.Object & { 10 | /** 11 | * A unique ID for this set on Scryfall that will not change. 12 | * 13 | * @type UUID 14 | */ 15 | id: string; 16 | /** 17 | * The unique three to five-letter code for this set. 18 | */ 19 | code: string; 20 | /** 21 | * The unique code for this set on MTGO, which may differ from the regular code. 22 | */ 23 | mtgo_code?: string; 24 | /** 25 | * The unique code for this set on Arena, which may differ from the regular code. 26 | */ 27 | arena_code?: string; 28 | /** 29 | * This set’s ID on TCGplayer’s API, also known as the groupId. 30 | * 31 | * @type Integer 32 | */ 33 | tcgplayer_id?: number; 34 | /** 35 | * The English name of the set. 36 | */ 37 | name: string; 38 | /** 39 | * A computer-readable classification for this set. See below. 40 | */ 41 | set_type: `${SetType}`; 42 | /** 43 | * The date the set was released or the first card was printed in the set (in GMT-8 Pacific time). 44 | * 45 | * @type IsoDate 46 | */ 47 | released_at?: string; 48 | /** 49 | * The block code for this set, if any. 50 | */ 51 | block_code?: string; 52 | /** 53 | * The block or group name code for this set, if any. 54 | */ 55 | block?: string; 56 | /** 57 | * The set code for the parent set, if any. promo and token sets often have a parent set. 58 | */ 59 | parent_set_code?: string; 60 | /** 61 | * The number of cards in this set. 62 | * 63 | * @type Integer 64 | */ 65 | card_count: number; 66 | /** 67 | * The denominator for the set’s printed collector numbers. 68 | * 69 | * @type Integer 70 | */ 71 | printed_size?: number; 72 | /** 73 | * True if this set was only released in a video game. 74 | */ 75 | digital: boolean; 76 | /** 77 | * True if this set contains only foil cards. 78 | */ 79 | foil_only: boolean; 80 | /** 81 | * True if this set contains only nonfoil cards. 82 | */ 83 | nonfoil_only: boolean; 84 | /** 85 | * A link to this set’s permapage on Scryfall’s website. 86 | * 87 | * @type URI 88 | */ 89 | scryfall_uri: string; 90 | /** 91 | * A link to this set object on Scryfall’s API. 92 | * 93 | * @type URI 94 | */ 95 | uri: string; 96 | /** 97 | * A URI to an SVG file for this set’s icon on Scryfall’s CDN. Hotlinking this image isn’t recommended, because it may change slightly over time. You should download it and use it locally for your particular user interface needs. 98 | * 99 | * @type URI 100 | */ 101 | icon_svg_uri: string; 102 | /** 103 | * A Scryfall API URI that you can request to begin paginating over the cards in this set. 104 | * 105 | * @type URI 106 | */ 107 | search_uri: string; 108 | }; 109 | -------------------------------------------------------------------------------- /src/objects/Set/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Set"; 2 | 3 | export * from "./values"; 4 | -------------------------------------------------------------------------------- /src/objects/Set/values/SetType.ts: -------------------------------------------------------------------------------- 1 | export enum SetType { 2 | /** A yearly Magic core set (Tenth Edition, etc) */ 3 | Core = "core", 4 | 5 | /** A rotational expansion set in a block (Zendikar, etc) */ 6 | Expansion = "expansion", 7 | 8 | /** A reprint set that contains no new cards (Modern Masters, etc) */ 9 | Masters = "masters", 10 | 11 | /** An Arena set designed for Alchemy */ 12 | Alchemy = "alchemy", 13 | 14 | /** Masterpiece Series premium foil cards */ 15 | Masterpiece = "masterpiece", 16 | 17 | /** A Commander-oriented gift set */ 18 | Arsenal = "arsenal", 19 | 20 | /** From the Vault gift sets */ 21 | FromTheVault = "from_the_vault", 22 | 23 | /** Spellbook series gift sets */ 24 | Spellbook = "spellbook", 25 | 26 | /** Premium Deck Series decks */ 27 | PremiumDeck = "premium_deck", 28 | 29 | /** Duel Decks */ 30 | DuelDeck = "duel_deck", 31 | 32 | /** Special draft sets, like Conspiracy and Battlebond */ 33 | DraftInnovation = "draft_innovation", 34 | 35 | /** Magic Online treasure chest prize sets */ 36 | TreasureChest = "treasure_chest", 37 | 38 | /** Commander preconstructed decks */ 39 | Commander = "commander", 40 | 41 | /** Planechase sets */ 42 | Planechase = "planechase", 43 | 44 | /** Archenemy sets */ 45 | Archenemy = "archenemy", 46 | 47 | /** Vanguard card sets */ 48 | Vanguard = "vanguard", 49 | 50 | /** A funny un-set or set with funny promos (Unglued, Happy Holidays, etc) */ 51 | Funny = "funny", 52 | 53 | /** A starter/introductory set (Portal, etc) */ 54 | Starter = "starter", 55 | 56 | /** A gift box set */ 57 | Box = "box", 58 | 59 | /** A set that contains purely promotional cards */ 60 | Promo = "promo", 61 | 62 | /** A set made up of tokens and emblems. */ 63 | Token = "token", 64 | 65 | /** A set made up of gold-bordered, oversize, or trophy cards that are not legal */ 66 | Memorabilia = "memorabilia", 67 | 68 | /** A set that contains minigame card inserts from booster packs */ 69 | Minigame = "minigame", 70 | } 71 | -------------------------------------------------------------------------------- /src/objects/Set/values/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./SetType"; 2 | -------------------------------------------------------------------------------- /src/objects/Symbology/CardSymbol.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { ScryfallColors } from "../Card/values"; 3 | 4 | /** 5 | * Description of a card symbol. 6 | * 7 | * @see {@link https://scryfall.com/docs/api/card-symbols} 8 | */ 9 | export type ScryfallCardSymbol = ScryfallObject.Object & { 10 | /** 11 | * The plaintext symbol. Often surrounded with curly braces {}. Note that not all symbols are ASCII text (for example, {∞}). 12 | */ 13 | symbol: string; 14 | /** 15 | * An alternate version of this symbol, if it is possible to write it without curly braces. 16 | */ 17 | loose_variant?: string | null; 18 | /** 19 | * An English snippet that describes this symbol. Appropriate for use in alt text or other accessible communication formats. 20 | */ 21 | english: string; 22 | /** 23 | * True if it is possible to write this symbol “backwards”. For example, the official symbol {U/P} is sometimes written as {P/U} or {P\U} in informal settings. Note that the Scryfall API never writes symbols backwards in other responses. This field is provided for informational purposes. 24 | */ 25 | transposable: boolean; 26 | /** 27 | * True if this is a mana symbol. 28 | */ 29 | represents_mana: boolean; 30 | /** 31 | * A decimal number representing this symbol’s mana value (also knowns as the converted mana cost). Note that mana symbols from funny sets can have fractional mana values. 32 | * 33 | * @type Decimal 34 | */ 35 | mana_value?: number | null; 36 | /** 37 | * @deprecated Use {@link ScryfallCardSymbol.mana_value} instead. 38 | * 39 | * @type Decimal 40 | */ 41 | cmc?: number | null; 42 | /** 43 | * True if this symbol appears in a mana cost on any Magic card. For example {20} has this field set to false because {20} only appears in Oracle text, not mana costs. 44 | */ 45 | appears_in_mana_costs: boolean; 46 | /** 47 | * True if this symbol is only used on funny cards or Un-cards. 48 | */ 49 | funny: boolean; 50 | /** 51 | * An array of colors that this symbol represents. 52 | */ 53 | colors: ScryfallColors; 54 | /** 55 | * True if the symbol is a hybrid mana symbol. Note that monocolor Phyrexian symbols aren’t considered hybrid. 56 | */ 57 | hybrid: boolean; 58 | /** 59 | * True if the symbol is a Phyrexian mana symbol, i.e. it can be paid with 2 life. 60 | */ 61 | phyrexian: boolean; 62 | /** 63 | * An array of plaintext versions of this symbol that Gatherer uses on old cards to describe original printed text. For example: {W} has ["oW", "ooW"] as alternates. 64 | */ 65 | gatherer_alternates?: string[] | null; 66 | /** 67 | * A URI to an SVG image of this symbol on Scryfall’s CDNs. 68 | * 69 | * @type URI 70 | */ 71 | svg_uri?: string; 72 | }; 73 | -------------------------------------------------------------------------------- /src/objects/Symbology/ManaCost.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallObject } from "../Object"; 2 | import { ScryfallColors } from "../Card/values"; 3 | 4 | /** 5 | * Description of a mana cost. 6 | * 7 | * @see {@link https://scryfall.com/docs/api/card-symbols/parse-mana} 8 | */ 9 | export type ScryfallManaCost = ScryfallObject.Object & { 10 | /** 11 | * The normalized cost, with correctly-ordered and wrapped mana symbols 12 | */ 13 | cost: string; 14 | /** 15 | * The mana value. If you submit Un-set mana symbols, this decimal could include fractional parts 16 | * 17 | * @type Decimal 18 | */ 19 | cmc: number; 20 | /** 21 | * The colors of the given cost 22 | */ 23 | colors: ScryfallColors; 24 | /** 25 | * True if the cost is colorless 26 | */ 27 | colorless: boolean; 28 | /** 29 | * True if the cost is monocolored 30 | */ 31 | monocolored: boolean; 32 | /** 33 | * True if the cost is multicolored 34 | */ 35 | multicolored: boolean; 36 | }; 37 | -------------------------------------------------------------------------------- /src/objects/Symbology/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./CardSymbol"; 2 | export * from "./ManaCost"; 3 | -------------------------------------------------------------------------------- /src/objects/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Card"; 2 | export * from "./Catalog"; 3 | export * from "./Error"; 4 | export * from "./List"; 5 | export * from "./Migration"; 6 | export * from "./Object"; 7 | export * from "./Ruling"; 8 | export * from "./Set"; 9 | export * from "./Symbology"; 10 | -------------------------------------------------------------------------------- /src/validators/BaseValidator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the most basic needs for a Validator class. 3 | * @abstract 4 | * @class BaseValidator 5 | */ 6 | export default abstract class BaseValidator = Record> { 7 | /** The object passed to the Validator */ 8 | object: T; 9 | /** A list of keys we expect to exist in a given object. */ 10 | abstract expectedKeys: string[]; 11 | 12 | /** 13 | * @constructor 14 | * @param {object} object The object to test against. 15 | */ 16 | constructor(object: T) { 17 | this.object = object; 18 | } 19 | 20 | /** The keys of the object */ 21 | get keys(): Array { 22 | return Object.keys(this.object); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/validators/index.ts: -------------------------------------------------------------------------------- 1 | export { default as BaseValidator } from "./BaseValidator"; 2 | -------------------------------------------------------------------------------- /src/validators/objects/Catalog/CatalogValidator.ts: -------------------------------------------------------------------------------- 1 | import { ScryfallCatalog } from "src/objects"; 2 | import { BaseValidator } from "src/validators"; 3 | 4 | /** 5 | * CatalogValidator 6 | * 7 | * @extends BaseValidator 8 | */ 9 | export default class CatalogValidator extends BaseValidator { 10 | expectedKeys: string[] = >["object", "uri", "total_values", "data"]; 11 | 12 | /** 13 | * @static 14 | * @param {object} obj An object to check 15 | * @returns {boolean} true if the object passes all expected checks 16 | */ 17 | static isCatalogObject(obj: Record): obj is ScryfallCatalog { 18 | const validator = new CatalogValidator(obj); 19 | 20 | return validator.validKeys && validator.validKeyType && validator.validDataType; 21 | } 22 | 23 | /** 24 | * true if the object matches all expected keys 25 | * @type {boolean} 26 | */ 27 | get validKeys(): boolean { 28 | return this.keys.every((val) => this.expectedKeys.includes(val)); 29 | } 30 | 31 | /** 32 | * true if the all keys are of the expected type 33 | * @type {boolean} 34 | * */ 35 | get validKeyType(): boolean { 36 | const objectIsCatalog = this.object.object === "catalog"; 37 | const uriIsString = typeof this.object.uri === "string"; 38 | const totalValsIsNumber = typeof this.object.total_values === "number"; 39 | const dataIsStringArray = this.validDataType; 40 | return objectIsCatalog && uriIsString && totalValsIsNumber && dataIsStringArray; 41 | } 42 | 43 | /** 44 | * true if the 'data' field is the correct type 45 | * @type {boolean} 46 | */ 47 | get validDataType(): boolean { 48 | if (!Array.isArray(this.object.data)) throw new Error("data is not an array"); 49 | 50 | const isJSObject = typeof this.object.data === "object"; 51 | const isArray = Array.isArray(this.object.data); 52 | const onlyHasStrings = this.object.data.every((val) => typeof val === "string"); 53 | return isJSObject && isArray && onlyHasStrings; 54 | } 55 | 56 | /** 57 | * true if the 'data' field length matches the 'total_values' number 58 | * @type {boolean} 59 | */ 60 | get validDataLength(): boolean { 61 | if (!Array.isArray(this.object.data)) throw new Error("data is not an array"); 62 | 63 | return this.object.data.length === this.object.total_values; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 16 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 17 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 18 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 19 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 20 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 21 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 22 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 23 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 24 | 25 | /* Modules */ 26 | "module": "commonjs", /* Specify what module code is generated. */ 27 | // "rootDir": "./", /* Specify the root folder within your source files. */ 28 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 29 | "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 30 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 31 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 32 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 33 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 34 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 35 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 36 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 37 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 38 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 39 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 40 | // "resolveJsonModule": true, /* Enable importing .json files. */ 41 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 42 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 43 | 44 | /* JavaScript Support */ 45 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 46 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 47 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 48 | 49 | /* Emit */ 50 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 51 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 52 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 53 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 54 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 55 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 56 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 57 | // "removeComments": true, /* Disable emitting comments. */ 58 | // "noEmit": true, /* Disable emitting files from a compilation. */ 59 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 60 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 61 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 62 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 63 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 64 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 65 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 66 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 67 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 68 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 69 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 70 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 71 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 72 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 73 | 74 | /* Interop Constraints */ 75 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 76 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 77 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 78 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 79 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 80 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 81 | 82 | /* Type Checking */ 83 | "strict": true, /* Enable all strict type-checking options. */ 84 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 85 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 86 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 87 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 88 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 89 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 90 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 91 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 92 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 93 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 94 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 95 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 96 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 97 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 98 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 99 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 100 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 101 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 102 | 103 | /* Completeness */ 104 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 105 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "files": ["src/index.ts"], 4 | "include": ["src/**/*"], 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["./**/__test__/**/*", "src/**/*"], 4 | } 5 | --------------------------------------------------------------------------------