Commander Spellbook
An unofficial wrapper for the Commander Spellbook API.
Installation
npm install --save commander-spellbook
The module is a singleton object that can look up combos from the Commander Spellbook API.
var spellbook = require("commander-spellbook");
Why?
The API that Commander Spellbook provides is a JSON version of the underlying Google spreadsheet that they use to host the combo data. While convenient that the data is available to use, the actual method for looking up combos could be easier. This module aims to simplify the lookup process.
Usage
Overview
The methods in this module typically resolve with an object or an array of objects representing the data of the combo(s). The object(s) typically have this shape:
{
commanderSpellbookId: number;
permalink: "https://commanderspellbook.com/?id=" + commanderSpellbookId;
cards: Card[];
colorIdentity: ColorIdentity;
prerequisites: SpellbookList;
steps: SpellbookList;
results: SpellbookList;
hasBannedCard: boolean;
hasSpoiledCard: boolean;
}
commanderSpellbookId
is the id in the commander spellbook database as a string.permalink
is the link available to view the combo on the commander spellbook website.cards
is an array of Card objects.colorIdentity
is a ColorIdentity object indicating the color identity of the comboprerequisites
is a SpellbookList object that contains the things required before doing the combo.steps
is a SpellbookList object that contains steps to do the combo.result
is a SpellbookList object that contains the results from doing the combo.hasBannedCard
is true when at least one card in the combo is banned in the Commander format.hasSpoiledCard
is true when at least one card uses a newly previewed card that is technically not yet legal in the Commander format.
See the Models section for more information on the custom classes.
findById
Look up a specific combo by the combos id
spellbook.findById("123").then((combo) => {
combo;
});
If a number is passed as the id, it will automatically be converted to a string:
spellbook.findById(123).then((combo) => {
combo;
});
If a combo with the specified id does not exist, the promise will reject.
spellbook.findById("not-an-id").catch((err) => {
err.message;
});
Search
Look up all the combos with the search
method:
spellbook.search().then((result) => {
result.combos;
});
In addition, search
takes an optional query string to filter the results.
spellbook.search("sydri scepter").then((result) => {
result.combos;
});
Full or partial card names can also be used.
spellbook
.search("card:'Arjun, the Shifting Flame' card:\"Thought Reflection\"")
.then((result) => {
result.combos;
});
You can also query by color identity using ci
or coloridentity
.
spellbook.search("Kiki ci:wbr").then((result) => {
result.combos;
});
The :
, =
, >
, >=
, <
, and <=
operators are supported.
spellbook.search("Kiki ci=wbr").then((result) => {
result.combos;
});
Using numbers to restrict the number of colors is also supported:
spellbook.search("Kiki ci>2").then((result) => {
result.combos;
});
You can also query by the prequisites, steps and results in the combo.
spellbook
.search(
"prequisites:'all permanents' steps:'Untap all' results:'infinite' results:'mana'"
)
.then((result) => {
result.combos;
});
Errors in search can be found in an array of errors:
spellbook.search("unknownkey:value card:Arjun").then((result) => {
const error = result.errors[0];
error.key;
error.value;
error.message;
});
A human readable explanation of the search query can be found on the message
property.
spellbook.search("card:breath result:infinite").then((result) => {
result.message;
});
The way the combos were sorted and ordered can be found on the sort
and order
properties. By default, sort
will be colors
and order
will be ascending
.
spellbook.search("Aetherflux").then((result) => {
result.sort;
result.order;
});
You can override the default sort
and order
:
spellbook.search("Aetherflux sort:results order:descending").then((result) => {
result.sort;
result.order;
});
Autocomplete
Look up possible values for card names, results, or colors
spellbook.autocomplete("cards", "dream").then((cards) => {
cards;
cards[0].value;
cards[0].label;
});
spellbook.autocomplete("results", "infinite").then((results) => {
results;
results[0].value;
results[0].label;
});
spellbook.autocomplete("colors", "wu").then((colors) => {
colors;
colors[0].value;
colors[0].label;
});
Random
Look up a random combo using the random
method:
spellbook.random().then((combo) => {
combo;
});
Get All Combos
Look up a all combos using the getAllCombos
method:
spellbook.getAllCombos().then((combos) => {
combos;
});
Make Fake Combo
A utility for using the module within a test environment to create a combo object that fulfills the type requirements in a Typescript environemnt.
const combo = spellbook.makeFakeCombo();
combo;
Any of the attributes can be overwritten:
const combo = spellbook.makeFakeCombo({
commanderSpellbookId: "custom-id",
cards: ["Arjun", "Sydri"],
colorIdentity: "URWB",
prerquisites: ["a", "b", "c"],
steps: ["a", "b", "c"],
results: ["a", "b", "c"],
});
combo;
Models
The methods provided in the module typically return a combo object with with some special classes. The special classes are documented here:
Card
An object that has a few convenience methods for rendering the card.
The name of the card can accessed via the name
property. The Scryfall URI can be accessed via the scryfallURI
property;
card.name;
card.scryfallURI;
getScryfallData
Resolves a promise with the Scryfall object from the scryfall-client
module for the card.
card.getScryfallData().then((cardData) => {
});
getScryfallImageUrl
Returns a url that can be used to display the card using an image from Scryfall.
const url = card.getScryfallImageUrl();
A string may be passed as an argument to specify what kind of image you would like. See the Scryfyall version
documentation for more details. The possible values are:
- small
- normal
- large
- png
- art_crop
- border_crop
const url = card.getScryfallImageUrl("art_crop");
toString
Returns the raw result from the Commander Spellbook API.
card.toString();
ColorIdentity
An object that has a few convenience methods for rendering the color identity.
The raw spellbook API gives the color identity in the form of a string. For a white/blue identity, the string would look like: "w,u".
The colors can be accessed with the colors
array.
ci.colors;
toString
Returns the raw result from the Commander Spellbook API.
ci.toString();
SpellbookList
An Array-like object that has a few convenience methods for rendering the data.
The raw spellbook API gives the prerquisites, steps and results data in the form of a single string deliminated by .
.
For the following examples, we'll assume that the raw Spellbook API gave us this information:
Step 1. Step 2. Step 3.
The SpellbookList
model has various methods to access the data:
Array Methods
You can use any Array methods to access the data:
list.length;
list[0];
list[1];
list[2];
list.forEach((step) => {
});
toString
Provides the raw string given to us by the Spellbook API.
list.toString();
This method will be envoked when it is interpolated:
const text = `Here are the steps: ${list}`;
// Here are the steps: Step 1. Step 2. Step 3.
Browser Support
The source code is written in Typescript and transpiled to ES5.
The module makes use of the Promise object, so if this SDK is used in a browser that does not support promises, it will need to be polyfilled in your script.
Contributing Guidelines
Code Style
The code base uses Prettier. Run:
npm run pretty
Testing
To lint and run all the tests, simply run:
npm test
To run just the unit tests, run:
npm run test:unit
To run just the linting command, run:
npm run lint
To run the integration tests, run:
npm run test:integration
To run the publishing test, run:
npm run test:publishing
Bugs
If you find a bug, feel free to open an issue or a Pull Request.