From 96bc9149c94ef95225e4d8b7d04cc0934f5c82f1 Mon Sep 17 00:00:00 2001 From: Avior Date: Tue, 22 Jun 2021 21:40:28 +0200 Subject: [PATCH] Added a version script It automaticly update the version number without importing package.json Signed-off-by: Avior --- .gitignore | 15 +- package.json | 3 +- scripts/export-version-number.js | 4 + src/Request.ts | 61 ++--- src/tcgdex.ts | 372 +++++++++++++++---------------- 5 files changed, 230 insertions(+), 225 deletions(-) create mode 100644 scripts/export-version-number.js diff --git a/.gitignore b/.gitignore index fa42e4b..bd4aed0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -# Dev Files -node_modules -test.ts -coverage - -# Dist files -dist +# Dev Files +node_modules +test.ts +coverage + +# Dist files +dist +src/version.json diff --git a/package.json b/package.json index fd1ec40..e4d4f2d 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "unfetch": "^4.2.0" }, "scripts": { - "build": "yarn build:cjs && yarn build:browser && yarn build:es2015", + "prebuild": "node scripts/export-version-number.js", + "build": "yarn prebuild && yarn build:cjs && yarn build:browser && yarn build:es2015", "build:cjs": "tsc --project tsconfig.json", "build:es2015": "tsc --project tsconfig.es2015.json", "build:browser": "wp --config webpack.config.js", diff --git a/scripts/export-version-number.js b/scripts/export-version-number.js new file mode 100644 index 0000000..0bc87e0 --- /dev/null +++ b/scripts/export-version-number.js @@ -0,0 +1,4 @@ +const { version } = require('../package.json') +const fs = require('fs') + +fs.writeFileSync('./src/version.json', JSON.stringify({version})) diff --git a/src/Request.ts b/src/Request.ts index 95ed48c..8760278 100644 --- a/src/Request.ts +++ b/src/Request.ts @@ -1,30 +1,31 @@ -import TCGdex from './tcgdex' - -export default class Request { - - // 1 hour of TTL by default - public static ttl = 1000 * 60 * 60 - - private static cache: Record = {} - - public static async fetch(url: string): Promise { - let request = this.cache[url] - const now = new Date().getTime() - if (!request || now - request.time > this.ttl) { - const unfetch = TCGdex.fetch - const resp = await unfetch(url, { - headers: { - 'user-agent': `@tcgdex/javascript-sdk/${TCGdex.VERSION}` - } - }) - if (resp.status !== 200) { - return undefined - } - - this.cache[url] = { response: await resp.json(), time: now } - request = this.cache[url] - } - return request.response - } - -} +import TCGdex from './tcgdex' +import { version } from './version.json' + +export default class Request { + + // 1 hour of TTL by default + public static ttl = 1000 * 60 * 60 + + private static cache: Record = {} + + public static async fetch(url: string): Promise { + let request = this.cache[url] + const now = new Date().getTime() + if (!request || now - request.time > this.ttl) { + const unfetch = TCGdex.fetch + const resp = await unfetch(url, { + headers: { + 'user-agent': `@tcgdex/javascript-sdk/${version}` + } + }) + if (resp.status !== 200) { + return undefined + } + + this.cache[url] = { response: await resp.json(), time: now } + request = this.cache[url] + } + return request.response + } + +} diff --git a/src/tcgdex.ts b/src/tcgdex.ts index e958d9d..ae4b379 100644 --- a/src/tcgdex.ts +++ b/src/tcgdex.ts @@ -1,187 +1,185 @@ -import RequestWrapper from './Request' -import { Serie, Set, Card, CardResume, SerieList, SetList, SupportedLanguages, StringEndpoint } from './interfaces' -type Endpoint = 'cards' | 'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'series' | 'sets' | 'types' - -const ENDPOINTS: Array = ['cards', 'categories', 'hp', 'illustrators', 'rarities', 'retreats', 'series', 'sets', 'types'] -const BASE_URL = 'https://api.tcgdex.net/v2' -export default class TCGdex { - - public static fetch: typeof fetch - - public static readonly VERSION = '2.2.0' - - /** - * @deprecated to change the lang use `this.lang` - */ - public static defaultLang: SupportedLanguages = 'en' - - public constructor(public lang?: SupportedLanguages) {} - - public getLang(): SupportedLanguages { - return this.lang ?? TCGdex.defaultLang ?? 'en' - } - - /** - * 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 - */ - public async fetchCard(id: string | number, set?: string): Promise { - const path = set ? ['sets', set] : ['cards'] - // @ts-expect-error the base endpoint is 'sets' or '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 - */ - public async fetchCards(set?: string): Promise | undefined> { - if (set) { - const fSet = await this.fetch('sets', set) - return fSet ? fSet.cards : undefined - } - return this.fetch('cards') - } - - /** - * @deprecated use `this.fetch('sets', set)` - */ - public async fetchSet(set: string): Promise { - return this.fetch('sets', set) - } - - /** - * @deprecated use `this.fetch('series', serie)` - */ - public async fetchSerie(serie: string): Promise { - return this.fetch('series', serie) - } - - /** - * @deprecated use `this.fetch('series')` - */ - public async fetchSeries(): Promise { - 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 - */ - public async fetchSets(serie?: string): Promise { - if (serie) { - const fSerie = await this.fetch('series', serie) - return fSerie ? fSerie.sets : undefined - } - return this.fetch('sets') - } - - /** - * Fetch a card using its global id - * @param endpoint_0 'cards' - * @param endpoint_1 {string} the card global ID - */ - public async fetch(...type: ['cards', string]): Promise - - /** - * Fetch every cards in the database - * @param endpoint_0 'cards' - */ - public async fetch(type: 'cards'): Promise | undefined> - - /** - * Fetch a card using its local id and its set - * @param endpoint_0 'sets' - * @param endpoint_1 {string} the set name or ID - * @param endpoint_2 {string} the card local ID - */ - public async fetch(...endpoint: ['sets', string, string]): Promise - - /** - * Fetch a set - * @param endpoint_0 'sets' - * @param endpoint_1 {string} the set name or ID - */ - public async fetch(...endpoint: ['sets', string]): Promise - - /** - * Fetch every sets - * @param endpoint_0 'sets' - */ - public async fetch(endpoint: 'sets'): Promise - - /** - * Fetch a serie - * @param endpoint_0 'series' - * @param endpoint_1 {string} the serie name or ID - */ - public async fetch(...endpoint: ['series', string]): Promise - - /** - * Fetch every series - * @param endpoint_0 'series' - */ - public async fetch(endpoint: 'series'): Promise - - /** - * Fetch cards depending on a specific filter - * @param endpoint_0 {'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types'} - * Possible value 'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types' - * @param endpoint_1 {string} the value set while fetching the index - */ - public async fetch(...endpoint: ['categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types', string]): Promise - - /** - * Fetch cards depending on a specific filter - * @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'} - * Possible value 'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types' - * @param endpoint_1 {string} Fetch the possible values to use depending on the endpoint - */ - public async fetch(endpoint: 'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'): Promise | undefined> - - /** - * 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 - */ - public async fetch(...endpoint: Array): Promise { - if (endpoint.length === 0) { - throw new Error('endpoint to fetch is empty!') - } - // @ts-expect-error with the precedent check, we KNOW that type is not empty - const baseEndpoint = endpoint.shift().toLowerCase() as Endpoint - if (!ENDPOINTS.includes(baseEndpoint)) { - throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`) - } - return this.makeRequest(baseEndpoint, ...endpoint) - } - - /** - * Function to make the request and normalize the whole path - */ - private makeRequest(...url: Array) { - // Normalize path - const path = url.map((subPath) => encodeURI( - subPath - // Transform numbers to string - .toString() - // replace this special character with an escaped one - .replace('?', '%3F') - // normalize the string - .normalize('NFC') - // remove some special chars by nothing - // eslint-disable-next-line no-misleading-character-class - .replace(/["'\u0300-\u036f]/gu, '') - )).join('/') - return RequestWrapper.fetch(`${BASE_URL}/${this.getLang()}/${path}`) - } - -} - -export * from './interfaces' +import RequestWrapper from './Request' +import { Serie, Set, Card, CardResume, SerieList, SetList, SupportedLanguages, StringEndpoint } from './interfaces' +type Endpoint = 'cards' | 'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'series' | 'sets' | 'types' + +const ENDPOINTS: Array = ['cards', 'categories', 'hp', 'illustrators', 'rarities', 'retreats', 'series', 'sets', 'types'] +const BASE_URL = 'https://api.tcgdex.net/v2' +export default class TCGdex { + + public static fetch: typeof fetch + + /** + * @deprecated to change the lang use `this.lang` + */ + public static defaultLang: SupportedLanguages = 'en' + + public constructor(public lang?: SupportedLanguages) {} + + public getLang(): SupportedLanguages { + return this.lang ?? TCGdex.defaultLang ?? 'en' + } + + /** + * 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 + */ + public async fetchCard(id: string | number, set?: string): Promise { + const path = set ? ['sets', set] : ['cards'] + // @ts-expect-error the base endpoint is 'sets' or '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 + */ + public async fetchCards(set?: string): Promise | undefined> { + if (set) { + const fSet = await this.fetch('sets', set) + return fSet ? fSet.cards : undefined + } + return this.fetch('cards') + } + + /** + * @deprecated use `this.fetch('sets', set)` + */ + public async fetchSet(set: string): Promise { + return this.fetch('sets', set) + } + + /** + * @deprecated use `this.fetch('series', serie)` + */ + public async fetchSerie(serie: string): Promise { + return this.fetch('series', serie) + } + + /** + * @deprecated use `this.fetch('series')` + */ + public async fetchSeries(): Promise { + 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 + */ + public async fetchSets(serie?: string): Promise { + if (serie) { + const fSerie = await this.fetch('series', serie) + return fSerie ? fSerie.sets : undefined + } + return this.fetch('sets') + } + + /** + * Fetch a card using its global id + * @param endpoint_0 'cards' + * @param endpoint_1 {string} the card global ID + */ + public async fetch(...type: ['cards', string]): Promise + + /** + * Fetch every cards in the database + * @param endpoint_0 'cards' + */ + public async fetch(type: 'cards'): Promise | undefined> + + /** + * Fetch a card using its local id and its set + * @param endpoint_0 'sets' + * @param endpoint_1 {string} the set name or ID + * @param endpoint_2 {string} the card local ID + */ + public async fetch(...endpoint: ['sets', string, string]): Promise + + /** + * Fetch a set + * @param endpoint_0 'sets' + * @param endpoint_1 {string} the set name or ID + */ + public async fetch(...endpoint: ['sets', string]): Promise + + /** + * Fetch every sets + * @param endpoint_0 'sets' + */ + public async fetch(endpoint: 'sets'): Promise + + /** + * Fetch a serie + * @param endpoint_0 'series' + * @param endpoint_1 {string} the serie name or ID + */ + public async fetch(...endpoint: ['series', string]): Promise + + /** + * Fetch every series + * @param endpoint_0 'series' + */ + public async fetch(endpoint: 'series'): Promise + + /** + * Fetch cards depending on a specific filter + * @param endpoint_0 {'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types'} + * Possible value 'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types' + * @param endpoint_1 {string} the value set while fetching the index + */ + public async fetch(...endpoint: ['categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types', string]): Promise + + /** + * Fetch cards depending on a specific filter + * @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'} + * Possible value 'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types' + * @param endpoint_1 {string} Fetch the possible values to use depending on the endpoint + */ + public async fetch(endpoint: 'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'): Promise | undefined> + + /** + * 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 + */ + public async fetch(...endpoint: Array): Promise { + if (endpoint.length === 0) { + throw new Error('endpoint to fetch is empty!') + } + // @ts-expect-error with the precedent check, we KNOW that type is not empty + const baseEndpoint = endpoint.shift().toLowerCase() as Endpoint + if (!ENDPOINTS.includes(baseEndpoint)) { + throw new Error(`unknown endpoint to fetch! (${baseEndpoint})`) + } + return this.makeRequest(baseEndpoint, ...endpoint) + } + + /** + * Function to make the request and normalize the whole path + */ + private makeRequest(...url: Array) { + // Normalize path + const path = url.map((subPath) => encodeURI( + subPath + // Transform numbers to string + .toString() + // replace this special character with an escaped one + .replace('?', '%3F') + // normalize the string + .normalize('NFC') + // remove some special chars by nothing + // eslint-disable-next-line no-misleading-character-class + .replace(/["'\u0300-\u036f]/gu, '') + )).join('/') + return RequestWrapper.fetch(`${BASE_URL}/${this.getLang()}/${path}`) + } + +} + +export * from './interfaces'