yugipedia-gql v0.4.4
Yugipedia GQL Wrapper
A GraphQL wrapper around the MediaWiki API for Yugipedia. Designed to make the queries and results more intuitive and simple.
β οΈ This wrapper is in its very early stages. As new requirements are set and the full design/structure is realized, be prepared for drastic, breaking changes on a regular basis. See the change log for info on recent updates.
Installation
You'll need to have NodeJS installed on your computer. It's best to have the most up-to-date LTS version installed. Installing NodeJS should also install NPM as a command line interface by default.
You can verify both NodeJS and NPM are installed properly by running the following command in your terminal/emulator of choice:
node -v
npm -v
Finally, cd into your directory of choice and create a new npm project:
cd "YOUR\\PREFERED\\DIRECTORY"
touch index.js
npm init -y
npm pkg set type="module"
npm i yugipedia-gql
Usage
A general understanding of the GraphQL language is highly recommended before attempting to use this API wrapper.
π‘ There is no need to roll your own rate limiter as all queries are rate limited to one page per second maximum to align with the wishes of the API devs. (See: Request limit).
Signature
class Yugipedia {
constructor(
userAgent: {
name: string,
contact: string,
reason?: string,
},
options: {
hydratePrototype?: boolean,
}
)
query(
gqlQueryString: string,
variables?: {
[key: string]: unknown,
}
): Promise<{
[key: string]: unknown
}>
}
Constructor Arguments
userAgent.name
- The best thing to refer to you asuserAgent.contact
- The contact details to get a hold of you in case the devs have a question or need to reach out[userAgent.reason]
- The reason you're using the API (defaults to "Data Collection for Personal Use Yugipedia-GQL)[options.hydratePrototype]
- The returned data's prototype is rehydrated as the GraphQL library nullifies it. This is mostly aesthetic, so if it causes issues, set this to false
Basic Usage
import Yugipedia from "yugipedia-gql"
const api = new Yugipedia({
name: "YOUR_NAME",
contact: "YOUR_CONTACT_INFO",
reason: "Testing the GraphQL wrapper for Yugipedia"
})
const queryString = `#graphql
query($searchTerm: String!) {
card(searchTerm: $searchTerm) {
name {
english
korean {
html
}
}
stats {
attribute
}
types
}
}
`
const variables = { searchTerm: "Dark Magician" }
const result = await api.query(queryString, variables)
console.dir(result, { depth: null })
The above should produce:
{
data: {
query: {
card: {
name: {
english: 'Dark Magician',
korean: {
html: 'λΈλ 맀μ§μ
'
}
},
stats: {
attribute: 'Dark'
},
types: [ 'Spellcaster', 'Normal' ]
}
}
},
errors: null,
warnings: null
}
Explanation
Currently, there are only two root queries
card(searchTerm: String!): Card
set(searchTerm: String!): Set
The searchTerm
for each root query can be anything you think will match a page of that type on Yugipedia. So, that means if Yugipedia recognizes it and can redirect to it, you're probably in business. For example, let's say we wanted info on the Legend of Blue Eyes White Dragon set. We could use the set
root query with the following searchTerm
's:
"LOB"
"LDD"
"LOB-EN"
"Legend of Blue Eyes White Dragon"
All of these should end up querying the correct set we were looking for. And for the Blue-Eyes White Dragon card, for example, we could query the card
root query with the following searchTerm
's and we could expect accurate results:
"BEWD"
"Blue-Eyes White Dragon"
"LOB-EN001"
"89631139"
(the card's password)"...etc."
The wrapper will do its best to take the searchTerm
you provide and resolve it to the page it thinks you want, but be assured it will not make any assumptions should it find ambiguous results. It strictly relies on the underlying API's ability to resolve page name redirects, but will make some case and symbol adjustments to help find things should there be a slight discrepancy. More on how redirects are handled can be found below.
The basic structure of a query result will have the following shape:
{
data: {
[key: queryTitle]: {
[key: rootQueryName]: {
...any // whatever your requested data shape looks like
}
}
},
errors: null | [{ code: number, log: { message: string, payload?: unknown } }],
warnings: null | [{ code: number, log: { message: string, payload?: unknown } }],
}
Stay tuned, more details and explanations to come...
Redirects
This wrapper will make an attempt to resolve redirects as best as possible. It does so by coercing lowercase, uppercase, propercase, titlecase, and sentencecase variations of your provided details and querying them all against the API efficiently. To test this, you can try a set
query with each of the following set names for the Legend of Blue Eyes White Dragon set; they should all succeed.
"lob"
"Lob"
"LOB"
"Legend of Blue Eyes White Dragon"
"legend of blue eyes white dragon"
"legend_of_blue_eyes_white_dragon"
"leGEND Of Blue eyeS whitE DRaGON"
It's not infallible, unfortunately, so do try your best to make sure you spell things correctly.
Errors/Warnings
Errors have recently been overhauled to be more reliable and informative. The errors and warnings keys are nullable, meaning they will be null
if nothing populated them. If something exists, they will be an array of errors or warnings respectively.
Basic Categories:
3xx
- These are reserved for warnings4xx
- These are reserved for errors originating from data collection, such as scraping and/or API errors5xx
- These are reserved for internal errors, such as GQL query syntax errors or fatal errors (usually my fault; sorry in advance!)
Breakdown - 3xx:
300 <Missing Data>
- Describes data that is missing when it was expected by a parser or formatter.301 <Missing/Corrupted Data>
- Describes data that is missing or corrupted as a resource on the fetched endpoint. (to be clear, it's data that should exist, but for some reason doesn't)
Breakdown - 4xx:
400 <Bad Request>
- The data that was requested doesn't match the data that was found. For instance, if a name you provided for thecard
query matches a set instead, etc.402 <Scrape Failed>
- A scraping request failed. Most likely this will be caused by Yugipedia not being in good health for one reason or another.403 <API Error>
- The underlying SMW/MW API produced an error.404 <Data Not Found>
- The data you requested doesn't exist as a resource on the providing server. This will most likely occur due to spelling errors.
Breakdown - 5xx:
500 <GQL Error>
- These errors are produced by the underlying GraphQL interpreter, usually denoting syntax errors or issues.501 <Unknown Error>
- The errors that was raised is known to be unknown. These will be random, uncaught and untested errors that are thrown by anyone from anywhere down the chain. These shouldn't be common, but still might occur.
Schema
Below are some helpful descriptions of various fields found on root types. The entire schema definition can be found here.
card(searchTerm: String!): Card <RootQuery>
Card.actions <Actions>
- specific actions this card takesCard.anti <AntiOrPro>
- cards that are targeted by this cardCard.appearsIn <[String!]>
- titles of media in which this card has appearedCard.cardType <String>
- this card's type (monster, spell, trap, etc.)Card.charactersDepicted <[String!]>
- what characters are seen in the art of this cardCard.debutDate <DebutDate>
- the dates this card debuted for specific formatsCard.deckType <String>
- which deck type this card belongs to (main, side, etc.)Card.description <CardText>
- 'lore' or description box text of this cardCard.effectTypes <[String!]>
- what types of effects this card performsCard.image <CardImage>
- details on images, including names and linksCard.isReal <Boolean>
- denotes if the card exists in the physical ocg/tcgCard.konamiID <String>
- the database ID Konami uses for this cardCard.limitation <String>
- limitation text provided by this cardCard.materials <Materials>
- materials required or used for this card in its lifetimeCard.mediums <[String!]>
- the formats in which this card exists (ogc, tcg, games, etc.) (different with releases in that this is more general)Card.mentions <[Card!]>
- the cards mentioned by this cardCard.miscTags <[String!]>
- tags/search properties that don't have their own specific categoryCard.name <CardText>
- the name of this cardCard.page <WikiPage>
- meta details on the wiki page for this cardCard.password <String>
- the password of this cardCard.pendulum <Pendulum>
- pendulum details on this cardCard.print <PrintDetails>
- print details on the card, such as notes and type (new, reprint, etc.) (only available when queried through a set)Card.pro <AntiOrPro>
- cards that are supported by this cardCard.rarity <String>
- the rarity of this card (only available when queried through a set)Card.related <Related>
- page names representing pages that are related to this cardCard.releases <[String!]>
- the specific release titles this card is associated with (different with mediums in that this is more specific)Card.setCategory <String>
- the category of this card in relation to its set (Variant card, Booster pack, etc.) (only available when queried through a set)Card.setCode <String>
- the set code of this card (only available when queried through a set)Card.stats <Stats>
- stats on this card, such as attack, defense, level, etc.Card.status <Status>
- the status given a card in official formats (limited, forbidden, etc.)Card.summonedBy <[Card!]>
- the cards that summon this card, typically used on token cardsCard.types <[String!]>
- the types (warrior/effect/etc.) or spell/trap properties (continuous/equip/etc.) this card hasCard.usedBy <[String!]>
- characters and their decks in which this card were used
π‘ The
card
API is mainly focused on physical cards. It shouldn't throw an error (untested) when retrieving non-physical cards, such as video game cards, anime cards, etc., but the properties specific to those pages have been neglected for now. There is currently no plan to implement these properties as it would require many, many hours to scrape the"All cards"
category members' properties to compile a complete and accurate list.
set(searchTerm: String!): Set <RootQuery>
Set.cards <CardList>
- the cards that are part of this set's setlist (previous versions of this field were quite slow but have now been heavily optimized. what took 2.5 minutes before for a query to LOB now takes less than 20 seconds. have fun!)Set.code <ProductCode>
- the product codes for this set (ISBN, etc.)Set.coverCards <[Card!]>
- the cards that appear on the packaging for this setSet.format <String>
- the format in regards to forbidden and limited lists (not common on sets, but does exist here and there)Set.image <String>
- the main image used in the wiki for this setSet.konamiID <SetKonamiDatabaseID>
- the database ID used by Konami for this setSet.mediums <[String!]>
- the formats in which this set exists (ogc, tcg, games, etc.)Set.name <LocaleText>
- the name of this setSet.page <WikiPage>
- meta details on the wiki page for this setSet.parent <Set>
- the parent set to this setSet.prefix <Prefix>
- the prefixes for this setSet.promotionalSeries <String>
- the promotional series this set belongs to (core boosters, etc.)Set.regionalPrefix <Prefix>
- the region-specific prefixes for this setSet.releaseDate <SetReleaseDate>
- this set's release dateSet.type <String>
- the type of set this set is (booster, tin, etc.)