UNPKG

@tcgdex/sdk

Version:

Communicate with the Open Source TCGdex API in Javascript/Typescript using the SDK

532 lines (516 loc) 14.5 kB
// src/tcgdex.ts import MemoryCache from "@cachex/memory"; import LocalStorageCache from "@cachex/web-storage"; // src/Query.ts var Query = class _Query { constructor() { this.params = []; this.not = { equal: (key, value) => { this.params.push({ key, value: `neq:${value}` }); return this; }, contains: (key, value) => { this.params.push({ key, value: `not:${value}` }); return this; }, includes: (key, value) => this.not.contains(key, value), like: (key, value) => this.not.contains(key, value), isNull: (key) => { this.params.push({ key, value: "notnull:" }); return this; } }; } static create() { return new _Query(); } includes(key, value) { return this.contains(key, value); } like(key, value) { return this.contains(key, value); } contains(key, value) { this.params.push({ key, value }); return this; } equal(key, value) { this.params.push({ key, value: `eq:${value}` }); return this; } sort(key, order) { this.params.push({ key: "sort:field", value: key }); this.params.push({ key: "sort:order", value: order }); return this; } greaterOrEqualThan(key, value) { this.params.push({ key, value: `gte:${value}` }); return this; } lesserOrEqualThan(key, value) { this.params.push({ key, value: `lte:${value}` }); return this; } greaterThan(key, value) { this.params.push({ key, value: `gt:${value}` }); return this; } lesserThan(key, value) { this.params.push({ key, value: `lt:${value}` }); return this; } isNull(key) { this.params.push({ key, value: "null:" }); return this; } paginate(page, itemsPerPage) { this.params.push({ key: "pagination:page", value: page }); this.params.push({ key: "pagination:itemsPerPage", value: itemsPerPage }); return this; } }; // src/models/Model.ts import { objectLoop } from "@dzeio/object-util"; var Model = class { constructor(sdk) { this.sdk = sdk; } /** * build a model depending on the data given * @param model the model to build * @param data the data to fill it with */ static build(model, data) { if (!data) { throw new Error("data is necessary."); } model.fill(data); return model; } fill(obj) { objectLoop(obj, (value, key) => { this[key] = value; }); } }; // src/endpoints/Endpoint.ts var Endpoint = class { constructor(tcgdex, itemModel, listModel, endpoint) { this.tcgdex = tcgdex; this.itemModel = itemModel; this.listModel = listModel; this.endpoint = endpoint; } async get(id) { const res = await this.tcgdex.fetch(this.endpoint, id); if (!res) { return null; } return Model.build(new this.itemModel(this.tcgdex), res); } async list(query) { const res = await this.tcgdex.fetchWithQuery([this.endpoint], query == null ? void 0 : query.params); return (res != null ? res : []).map((it) => Model.build(new this.listModel(this.tcgdex), it)); } }; // src/endpoints/SimpleEndpoint.ts var SimpleEndpoint = class { constructor(tcgdex, itemModel, endpoint) { this.tcgdex = tcgdex; this.itemModel = itemModel; this.endpoint = endpoint; } async get(id) { const res = await this.tcgdex.fetch(this.endpoint, id); if (!res) { return null; } return Model.build(new this.itemModel(this.tcgdex), res); } async list(query) { var _a; return (_a = await this.tcgdex.fetchWithQuery([this.endpoint], query == null ? void 0 : query.params)) != null ? _a : []; } }; // src/models/CardResume.ts var CardResume = class extends Model { /** * the the Card Image full URL * * @param {Quality} quality the quality you want your image to be in * @param {Extension} extension extension you want you image to be * @return the full card URL */ getImageURL(quality = "high", extension = "png") { return `${this.image}/${quality}.${extension}`; } /** * Get the full Card * * @return the full card if available */ async getCard() { return await this.sdk.card.get(this.id); } }; // src/models/Card.ts var Card = class extends CardResume { async getCard() { return this; } async getSet() { return await this.sdk.set.get(this.set.id); } }; // src/models/Serie.ts import { objectLoop as objectLoop2 } from "@dzeio/object-util"; // src/models/SerieResume.ts var SerieResume = class extends Model { /** * the the Card Image full URL * * @param {Quality} quality the quality you want your image to be in * @param {Extension} extension extension you want you image to be * @return the full card URL */ getImageURL(extension = "png") { return `${this.logo}.${extension}`; } async getSerie() { return await this.sdk.serie.get(this.id); } }; // src/models/SetResume.ts var SetResume = class extends Model { async getSet() { return await this.sdk.set.get(this.id); } }; // src/models/Serie.ts var Serie = class extends SerieResume { fill(obj) { objectLoop2(obj, (value, key) => { switch (key) { case "sets": this.sets = value.map((it) => Model.build(new SetResume(this.sdk), it)); break; default: this[key] = value; break; } }); } }; // src/models/Set.ts import { objectLoop as objectLoop3 } from "@dzeio/object-util"; var Set = class extends Model { async getSerie() { return this.sdk.serie.get(this.serie.id); } fill(obj) { objectLoop3(obj, (value, key) => { switch (key) { case "cards": this.cards = value.map((it) => Model.build(new CardResume(this.sdk), it)); break; default: this[key] = value; break; } }); } }; // src/models/StringEndpoint.ts import { objectLoop as objectLoop4 } from "@dzeio/object-util"; var StringEndpoint = class extends Model { fill(obj) { objectLoop4(obj, (value, key) => { switch (key) { case "cards": this.cards = value.map((it) => Model.build(new CardResume(this.sdk), it)); break; default: this[key] = value; break; } }); } }; // src/utils.ts function detectContext() { try { const isBrowser = !!window; return isBrowser ? "browser" : "server"; } catch { return "server"; } } var ENDPOINTS = [ "cards", "categories", "dex-ids", "energy-types", "hp", "illustrators", "rarities", "regulation-marks", "retreats", "series", "sets", "stages", "suffixes", "trainer-types", "types", "variants", "random" ]; // src/version.js var version = "2.7.1"; // src/tcgdex.ts var _TCGdex = class _TCGdex { constructor(lang = "en") { /** * the previously hidden caching system used by TCGdex to not kill the API */ this.cache = detectContext() === "browser" ? new LocalStorageCache("tcgdex-cache") : new MemoryCache(); /** * the default cache TTL, only subsequent requests will have their ttl changed */ this.cacheTTL = 60 * 60; // random card/set/serie endpoints this.random = { card: async () => { const res = await this.fetch("random", "card"); return Model.build(new Card(this), res); }, set: async () => { const res = await this.fetch("random", "set"); return Model.build(new Set(this), res); }, serie: async () => { const res = await this.fetch("random", "serie"); return Model.build(new Serie(this), res); } }; this.card = new Endpoint(this, Card, CardResume, "cards"); this.set = new Endpoint(this, Set, SetResume, "sets"); this.serie = new Endpoint(this, Serie, SerieResume, "series"); this.type = new SimpleEndpoint(this, StringEndpoint, "types"); this.retreat = new SimpleEndpoint(this, StringEndpoint, "retreats"); this.rarity = new SimpleEndpoint(this, StringEndpoint, "rarities"); this.illustrator = new SimpleEndpoint(this, StringEndpoint, "illustrators"); this.hp = new SimpleEndpoint(this, StringEndpoint, "hp"); this.categorie = new SimpleEndpoint(this, StringEndpoint, "categories"); this.dexID = new SimpleEndpoint(this, StringEndpoint, "dex-ids"); this.energyType = new SimpleEndpoint(this, StringEndpoint, "energy-types"); this.regulationMark = new SimpleEndpoint(this, StringEndpoint, "regulation-marks"); this.stage = new SimpleEndpoint(this, StringEndpoint, "stages"); this.suffixe = new SimpleEndpoint(this, StringEndpoint, "suffixes"); this.trainerType = new SimpleEndpoint(this, StringEndpoint, "trainer-types"); this.variant = new SimpleEndpoint(this, StringEndpoint, "variants"); this.lang = "en"; this.endpointURL = "https://api.tcgdex.net/v2"; this.setLang(lang); } /** * @deprecated use the constructor parameter or {@link TCGdex.setLang} when in an instance */ static setDefaultLang(lang) { _TCGdex.defaultLang = lang; } /** * @deprecated use {@link TCGdex.setLang} when in an instance */ static getDefaultLang() { return _TCGdex.defaultLang; } /** * the endpoint URL * ex: `https://api.tcgdex.net/v2` * @param endpoint the url */ setEndpoint(endpoint) { this.endpointURL = endpoint; } getEndpoint() { return this.endpointURL; } /** * set the current cache methodology * @param cache the cache to use */ setCache(cache) { this.cache = cache; } /** * get the current cache methodology * @param cache the cache to use */ getCache() { return this.cache; } /** * the endpoint URL * ex: `https://api.tcgdex.net/v2` * @param endpoint the url */ setCacheTTL(seconds) { this.cacheTTL = seconds; } /** * get the current useed cache ttl in seconds * @returns the cache ttl in seconds */ getCacheTTL() { return this.cacheTTL; } getLang() { var _a, _b; return (_b = (_a = this.lang) != null ? _a : _TCGdex.defaultLang) != null ? _b : "en"; } setLang(lang) { this.lang = lang; } /** * Shortcut to easily fetch a card using both it's global id and it's local ID * @param id the card global/local ID * @param set the card set name/ID (optionnal) * @returns the card object */ async fetchCard(id, set) { const path = set ? ["sets", set] : ["cards"]; return this.fetch(...path, id); } /** * Shortcut to easily fetch cards using an optionnal set name/ID * @param set the card set name/ID (optionnal) * @returns a card list */ async fetchCards(set) { if (set) { const fSet = await this.fetch("sets", set); return fSet ? fSet.cards : void 0; } return this.fetch("cards"); } /** * @deprecated use `this.fetch('sets', set)` */ async fetchSet(set) { return this.fetch("sets", set); } /** * @deprecated use `this.fetch('series', serie)` */ async fetchSerie(serie) { return this.fetch("series", serie); } /** * @deprecated use `this.fetch('series')` */ async fetchSeries() { return this.fetch("series"); } /** * Shortcut to easily fetch sets using an optionnal serie name/ID * @param serie the card set name/ID (optionnal) * @returns a card list */ async fetchSets(serie) { if (serie) { const fSerie = await this.fetch("series", serie); return fSerie ? fSerie.sets : void 0; } return this.fetch("sets"); } /** * Fetch The differents endpoints depending on the first argument * @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'} * Possible value 'cards' | 'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'series' | 'sets' | 'types' * @param endpoint_1 {string} (Optionnal) some details to go from the index file to the item file (mostly the ID/name) * @param endpoint_2 {string} (Optionnal) only for sets the card local ID to fetch the card through the set */ async fetch(...endpoint) { if (endpoint.length === 0) { throw new Error("endpoint to fetch is empty!"); } const baseEndpoint = endpoint.shift().toLowerCase(); if (!ENDPOINTS.includes(baseEndpoint)) { throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`); } return this.actualFetch(this.getFullURL([baseEndpoint, ...endpoint])); } /** * @param endpoint the endpoint to fetch * @param query the query */ async fetchWithQuery(endpoint, query) { if (endpoint.length === 0) { throw new Error("endpoint to fetch is empty!"); } const baseEndpoint = endpoint[0].toLowerCase(); if (!ENDPOINTS.includes(baseEndpoint)) { throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`); } return this.actualFetch(this.getFullURL(endpoint, query)); } /** * format the final URL */ getFullURL(path, searchParams) { const url = new URL(`${this.getEndpoint()}/${this.getLang()}`); url.pathname = `${url.pathname}/${path.join("/")}`; for (const param of searchParams != null ? searchParams : []) { url.searchParams.append(param.key, param.value.toString()); } return url.toString(); } async actualFetch(path) { const cached = this.cache.get(path); if (cached) { return cached; } const resp = await _TCGdex.fetch(path, { headers: { "user-agent": `@tcgdex/javascript-sdk/${version}` } }); if (resp.status >= 500) { try { const json2 = JSON.stringify(await resp.json()); throw new Error(json2); } catch { throw new Error("TCGdex Server responded with an invalid error :("); } } if (resp.status !== 200) { return void 0; } const json = await resp.json(); this.cache.set(path, json, this.cacheTTL); return json; } }; /** * How the remote data is going to be fetched */ _TCGdex.fetch = detectContext() === "browser" ? (...params) => window.fetch(...params) : fetch; /** * @deprecated to change the lang use {@link TCGdex.getLang} and {@link TCGdex.setLang} */ _TCGdex.defaultLang = "en"; var TCGdex = _TCGdex; export { Card as CardModel, CardResume as CardResumeModel, Endpoint, Model, Query, Serie as SerieModel, SerieResume as SerieResumeModel, Set as SetModel, SetResume as SetResumeModel, SimpleEndpoint, TCGdex as default };