Added ESLint

Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2021-06-22 19:54:38 +02:00
parent b951f6d2d1
commit 7014e0c511
Signed by: Florian Bouillon
GPG Key ID: 50BD648F12C86AB6
9 changed files with 2993 additions and 845 deletions

6
.eslintignore Normal file
View File

@ -0,0 +1,6 @@
dist/
src/tcgdex.browser.ts
__tests__
.eslintrc.js
webpack.config.js
tsconfig.json

322
.eslintrc.js Normal file
View File

@ -0,0 +1,322 @@
/**
* ESLint custom configuration v1.0.0
* packages needed:
* eslint
* for Typescript
* @typescript-eslint/parser
* @typescript-eslint/eslint-plugin
*/
module.exports = {
env: {
browser: true,
es6: true,
node: true
},
extends: [
"eslint:all",
"plugin:@typescript-eslint/recommended",
],
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly"
},
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json"
},
plugins: [
"@typescript-eslint"
],
root: true,
rules: {
// Tab indent and force switch to have one too
indent: [
"error",
"tab",
{SwitchCase: 1}
],
// \n linebreak
"linebreak-style": [
"error",
"unix"
],
// Disable eslint default quote because Typescript replace it
quotes: "off",
"@typescript-eslint/quotes": [
"error",
"single",
{ avoidEscape: true }
],
// Simply diallow using ';' unless mandatory
semi: "off",
"@typescript-eslint/semi": [
"error",
"never",
{ "beforeStatementContinuationChars": "always"}
],
// Disallow things that do nothing in the end
"no-unused-expressions": "off",
"@typescript-eslint/no-unused-expressions": [
"error",
{ "enforceForJSX": true,}
],
// force overloads to be next to one another
"@typescript-eslint/adjacent-overload-signatures": "error",
// Force to use `Array<thing>
"@typescript-eslint/array-type": [
"error",
{ default: 'generic' }
],
// Warn when no return type is specified
"@typescript-eslint/explicit-module-boundary-types": "warn",
// disallow certain types not safe
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"{}": false
}
}
],
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/consistent-type-definitions": "error",
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
accessibility: "explicit"
}
],
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/member-delimiter-style": [
"error",
{
multiline: {
delimiter: "none",
requireLast: true
},
singleline: {
delimiter: "comma",
requireLast: false
}
}
],
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-parameter-properties": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/triple-slash-reference": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unified-signatures": "error",
"arrow-body-style": "error",
"arrow-parens": [
"error",
"always"
],
camelcase: "error",
complexity: "off",
"constructor-super": "error",
curly: "error",
"dot-notation": "error",
"eol-last": "error",
eqeqeq: [
"error",
"smart"
],
"guard-for-in": "warn",
"id-blacklist": [
"error",
"any",
"Number",
"number",
"String",
"string",
"Boolean",
"boolean",
"Undefined"
],
"id-match": "error",
"max-classes-per-file": [
"error",
1
],
"max-len": [
"warn",
{
code: 200
}
],
"@typescript-eslint/no-inferrable-types": "off",
"new-parens": "error",
"no-bitwise": "error",
"no-caller": "error",
"no-cond-assign": "error",
"no-debugger": "error",
"no-empty": "error",
"no-eval": "error",
"no-fallthrough": "off",
"no-invalid-this": "off",
"no-multiple-empty-lines": "error",
"no-new-wrappers": "error",
"no-shadow": [
"error",
{
hoist: "all"
}
],
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-underscore-dangle": "error",
"no-unsafe-finally": "error",
"no-unused-labels": "error",
"no-unused-vars": "off",
"no-var": "error",
"object-shorthand": "error",
"one-var": [
"error",
"never"
],
"prefer-const": "error",
"quote-props": [
"error",
"consistent-as-needed"
],
"radix": "error",
"space-before-function-paren": "off",
"@typescript-eslint/space-before-function-paren": ["error", {
asyncArrow: "always",
anonymous: "never",
named: "never"
}],
"spaced-comment": "error",
"use-isnan": "error",
"valid-typeof": "off",
// some tests from eslint:all
"no-tabs": "off",
"padded-blocks": [
"error",
{
"blocks": "never",
"classes": "always",
"switches": "never"
}
],
"sort-imports": "off",
"no-console": "off",
"function-call-argument-newline": [
"error",
"consistent"
],
"dot-location": [
"error",
"property"
],
"object-curly-spacing": [
"error",
"always"
],
"array-element-newline": [
"error",
"consistent"
],
"function-paren-newline": [
"error",
"consistent"
],
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "error",
"capitalized-comments": "off",
"multiline-comment-style": "off",
"no-extra-parens": "off",
"@typescript-eslint/no-extra-parens": [
"error",
"all",
{ "ignoreJSX": "multi-line" }
],
"func-style": [
"error",
"declaration",
{ "allowArrowFunctions": true }
],
"no-ternary": "off",
"multiline-ternary": "off",
"no-magic-numbers": "off",
"max-lines-per-function": [
"warn",
{
"skipBlankLines": true,
"skipComments": true
}
],
"prefer-promise-reject-errors": "warn",
"object-property-newline": [
"error",
{ "allowAllPropertiesOnSameLine": true }
],
"no-await-in-loop": "warn",
"no-undefined": "off",
"id-length": "warn",
"class-methods-use-this": "off",
"array-bracket-newline": [
"error",
"consistent"
],
"no-confusing-arrow": "off",
"no-nested-ternary": "off",
"no-mixed-operators": "off",
"max-statements": [
"warn",
15
],
"semi-style": [
"error",
"first"
],
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "error",
"lines-between-class-members": "off",
"@typescript-eslint/lines-between-class-members": "error",
"max-lines": [
"warn",
{
"max": 500,
"skipBlankLines": true,
"skipComments": true
}
],
"no-plusplus": "off",
"id-length": [
"warn",
{ "exceptions": ["_"] }
],
"default-param-last": "off",
// "@typescript-eslint/default-param-last": "error",
// Temporary OFF
"@typescript-eslint/default-param-last": "off",
"no-continue": "off",
"require-atomic-updates": "off",
"require-await": "off",
"prefer-destructuring": "off",
"max-params": ["warn", 5]
}
};

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
# Dev Files # Dev Files
node_modules node_modules
test.ts test.ts
coverage
# Dist files # Dist files
dist dist

View File

@ -6,3 +6,4 @@ webpack.config.js
tsconfig.* tsconfig.*
yarn.lock yarn.lock
CHANGELOG.md CHANGELOG.md
coverage

View File

@ -7,6 +7,9 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node-fetch": "^2.5.10", "@types/node-fetch": "^2.5.10",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"eslint": "^7.29.0",
"jest": "^27.0.5", "jest": "^27.0.5",
"ts-loader": "^9.2.3", "ts-loader": "^9.2.3",
"ts-node": "^10.0.0", "ts-node": "^10.0.0",

View File

@ -1,26 +1,19 @@
// Temporary disable this as it will be rebuilt to make it like the php-sdk one
// eslint-disable-next-line max-classes-per-file
import TCGdex from './tcgdex' import TCGdex from './tcgdex'
export default class RequestWrapper {
private static cache: Array<Request<any>> = []
public static getRequest<T>(url: string) {
let req = this.cache.find((req) => req.url === url) as Request<T>|undefined
if (!req) {
req = new Request<T>(url)
this.cache.push(req)
}
return req
}
}
export class Request<T = any> { export class Request<T = any> {
public static ttl = 1000 * 60 * 60 // 1 hour
// 1 hour of TTL by default
public static ttl = 1000 * 60 * 60
private response?: T private response?: T
private fetched?: Date private fetched?: Date
public constructor( public constructor(
public url: string // url is public for quick url test // url is public for quick url test
public url: string
) {} ) {}
public async get(): Promise<T | undefined> { public async get(): Promise<T | undefined> {
@ -48,4 +41,20 @@ export class Request<T = any> {
this.fetched = now this.fetched = now
return this.response return this.response
} }
}
export default class RequestWrapper {
private static cache: Array<Request<any>> = []
public static getRequest<T>(url: string): Request<T> {
let request = this.cache.find((req) => req.url === url) as Request<T>|undefined
if (!request) {
request = new Request<T>(url)
this.cache.push(request)
}
return request
}
} }

View File

@ -28,10 +28,12 @@ export interface SetResume {
logo?: string logo?: string
symbol?: string symbol?: string
cardCount: { cardCount: {
/** /**
* total of number of cards * total of number of cards
*/ */
total: number total: number
/** /**
* number of cards officialy (on the bottom of each cards) * number of cards officialy (on the bottom of each cards)
*/ */
@ -53,6 +55,7 @@ export interface Set extends SetResume {
* card is banned from the set it will still be true * card is banned from the set it will still be true
*/ */
legal: { legal: {
/** /**
* Ability to play in standard tournaments * Ability to play in standard tournaments
*/ */
@ -65,26 +68,32 @@ export interface Set extends SetResume {
} }
cardCount: { cardCount: {
/** /**
* total of number of cards * total of number of cards
*/ */
total: number total: number
/** /**
* number of cards officialy (on the bottom of each cards) * number of cards officialy (on the bottom of each cards)
*/ */
official: number official: number
/** /**
* number of cards having a normal version * number of cards having a normal version
*/ */
normal: number normal: number
/** /**
* number of cards having an reverse version * number of cards having an reverse version
*/ */
reverse: number reverse: number
/** /**
* number of cards having an holo version * number of cards having an holo version
*/ */
holo: number holo: number
/** /**
* Number of possible cards * Number of possible cards
*/ */
@ -159,8 +168,9 @@ export interface Card<SetType extends SetResume = SetResume> extends CardResume
/** /**
* Pokemon Types * Pokemon Types
* ex for multiple https://www.tcgdex.net/database/ex/ex13/17
*/ */
types?: Array<string> // ex for multiple https://www.tcgdex.net/database/ex/ex13/17 types?: Array<string>
/** /**
* Pokemon Sub Evolution * Pokemon Sub Evolution
@ -257,7 +267,7 @@ export interface Card<SetType extends SetResume = SetResume> extends CardResume
retreat?: number retreat?: number
//Trainer/Energy // Trainer/Energy
effect?: string effect?: string
// Trainer Only // Trainer Only
@ -277,6 +287,7 @@ export interface Card<SetType extends SetResume = SetResume> extends CardResume
* Note: all cards are avaialable to play in unlimited tournaments * Note: all cards are avaialable to play in unlimited tournaments
*/ */
legal: { legal: {
/** /**
* Ability to play in standard tournaments * Ability to play in standard tournaments
*/ */

View File

@ -8,16 +8,16 @@ export default class TCGdex {
public static fetch: typeof fetch public static fetch: typeof fetch
public static readonly VERSION = "2.2.0" public static readonly VERSION = '2.2.0'
/** /**
* @deprecated to change the lang use `this.lang` * @deprecated to change the lang use `this.lang`
*/ */
public static defaultLang: SupportedLanguages = "en" public static defaultLang: SupportedLanguages = 'en'
public constructor(public lang?: SupportedLanguages) {} public constructor(public lang?: SupportedLanguages) {}
public getLang() { public getLang(): SupportedLanguages {
return this.lang ?? TCGdex.defaultLang ?? 'en' return this.lang ?? TCGdex.defaultLang ?? 'en'
} }
@ -49,7 +49,7 @@ export default class TCGdex {
/** /**
* @deprecated use `this.fetch('sets', set)` * @deprecated use `this.fetch('sets', set)`
*/ */
public async fetchSet(set: string) { public async fetchSet(set: string): Promise<Set | undefined> {
return this.fetch('sets', set) return this.fetch('sets', set)
} }
@ -86,11 +86,13 @@ export default class TCGdex {
* @param endpoint_1 {string} the card global ID * @param endpoint_1 {string} the card global ID
*/ */
public async fetch(...type: ['cards', string]): Promise<Card | undefined> public async fetch(...type: ['cards', string]): Promise<Card | undefined>
/** /**
* Fetch every cards in the database * Fetch every cards in the database
* @param endpoint_0 'cards' * @param endpoint_0 'cards'
*/ */
public async fetch(type: 'cards'): Promise<Array<CardResume> | undefined> public async fetch(type: 'cards'): Promise<Array<CardResume> | undefined>
/** /**
* Fetch a card using its local id and its set * Fetch a card using its local id and its set
* @param endpoint_0 'sets' * @param endpoint_0 'sets'
@ -98,28 +100,33 @@ export default class TCGdex {
* @param endpoint_2 {string} the card local ID * @param endpoint_2 {string} the card local ID
*/ */
public async fetch(...endpoint: ['sets', string, string]): Promise<Card | undefined> public async fetch(...endpoint: ['sets', string, string]): Promise<Card | undefined>
/** /**
* Fetch a set * Fetch a set
* @param endpoint_0 'sets' * @param endpoint_0 'sets'
* @param endpoint_1 {string} the set name or ID * @param endpoint_1 {string} the set name or ID
*/ */
public async fetch(...endpoint: ['sets', string]): Promise<Set | undefined> public async fetch(...endpoint: ['sets', string]): Promise<Set | undefined>
/** /**
* Fetch every sets * Fetch every sets
* @param endpoint_0 'sets' * @param endpoint_0 'sets'
*/ */
public async fetch(endpoint: 'sets'): Promise<SetList | undefined> public async fetch(endpoint: 'sets'): Promise<SetList | undefined>
/** /**
* Fetch a serie * Fetch a serie
* @param endpoint_0 'series' * @param endpoint_0 'series'
* @param endpoint_1 {string} the serie name or ID * @param endpoint_1 {string} the serie name or ID
*/ */
public async fetch(...endpoint: ['series', string]): Promise<Serie | undefined> public async fetch(...endpoint: ['series', string]): Promise<Serie | undefined>
/** /**
* Fetch every series * Fetch every series
* @param endpoint_0 'series' * @param endpoint_0 'series'
*/ */
public async fetch(endpoint: 'series'): Promise<SerieList | undefined> public async fetch(endpoint: 'series'): Promise<SerieList | undefined>
/** /**
* Fetch cards depending on a specific filter * Fetch cards depending on a specific filter
* @param endpoint_0 {'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types'} * @param endpoint_0 {'categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types'}
@ -127,6 +134,7 @@ export default class TCGdex {
* @param endpoint_1 {string} the value set while fetching the index * @param endpoint_1 {string} the value set while fetching the index
*/ */
public async fetch(...endpoint: ['categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types', string]): Promise<StringEndpoint | undefined> public async fetch(...endpoint: ['categories' | 'hp' | 'illustrators' | 'rarities' | 'retreats' | 'types', string]): Promise<StringEndpoint | undefined>
/** /**
* Fetch cards depending on a specific filter * Fetch cards depending on a specific filter
* @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'} * @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'}
@ -134,6 +142,7 @@ export default class TCGdex {
* @param endpoint_1 {string} Fetch the possible values to use depending on the endpoint * @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<Array<string> | undefined> public async fetch(endpoint: 'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'): Promise<Array<string> | undefined>
/** /**
* Fetch The differents endpoints depending on the first argument * Fetch The differents endpoints depending on the first argument
* @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'} * @param endpoint_0 {'hp' | 'retreats' | 'categories' | 'illustrators' | 'rarities' | 'types'}
@ -143,7 +152,7 @@ export default class TCGdex {
*/ */
public async fetch(...endpoint: Array<Endpoint | string>): Promise<any | undefined> { public async fetch(...endpoint: Array<Endpoint | string>): Promise<any | undefined> {
if (endpoint.length === 0) { if (endpoint.length === 0) {
throw new Error(`endpoint to fetch is empty!`) throw new Error('endpoint to fetch is empty!')
} }
// @ts-expect-error with the precedent check, we KNOW that type is not empty // @ts-expect-error with the precedent check, we KNOW that type is not empty
const baseEndpoint = endpoint.shift().toLowerCase() as Endpoint const baseEndpoint = endpoint.shift().toLowerCase() as Endpoint
@ -158,8 +167,8 @@ export default class TCGdex {
*/ */
private makeRequest<T = any>(...url: Array<string | number>) { private makeRequest<T = any>(...url: Array<string | number>) {
// Normalize path // Normalize path
const path = url.map((v) => encodeURI( const path = url.map((subPath) => encodeURI(
v subPath
// Transform numbers to string // Transform numbers to string
.toString() .toString()
// replace this special character with an escaped one // replace this special character with an escaped one
@ -167,10 +176,12 @@ export default class TCGdex {
// normalize the string // normalize the string
.normalize('NFC') .normalize('NFC')
// remove some special chars by nothing // remove some special chars by nothing
.replace(/["'\u0300-\u036f]/g, "") // eslint-disable-next-line no-misleading-character-class
.replace(/["'\u0300-\u036f]/gu, '')
)).join('/') )).join('/')
return RequestWrapper.getRequest<T>(`${BASE_URL}/${this.getLang()}/${path}`).get() return RequestWrapper.getRequest<T>(`${BASE_URL}/${this.getLang()}/${path}`).get()
} }
} }
export * from './interfaces' export * from './interfaces'

3418
yarn.lock

File diff suppressed because it is too large Load Diff