diff --git a/.eslintrc.js b/.eslintrc.js index 3416756..10125df 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,322 +1,5 @@ -/** - * 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 - }, +module.exports = { 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 - "@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] - } -}; + "./node_modules/@dzeio/config/eslint/typescript" + ] +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/CHANGELOG.md b/CHANGELOG.md index 17cdaab..bd7211c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## 2.4.1 - 2021-07-11 + +## Deprecated + +- Deprecated `Languages` Type + +## 2.4.0 - 2021-06-29 + +## Added + +- Support for new languages + ## 2.3.1 - 2021-06-22 ### Fixed @@ -201,6 +213,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [Unreleased]: https://github.com/tcgdex/javascript-sdk/compare/v2.3.1...HEAD +[2.4.0]: https://github.com/tcgdex/javascript-sdk/releases/tag/v2.4.0 [2.3.1]: https://github.com/tcgdex/javascript-sdk/releases/tag/v2.3.1 [2.3.0]: https://github.com/tcgdex/javascript-sdk/releases/tag/v2.3.0 [2.2.0]: https://github.com/tcgdex/javascript-sdk/releases/tag/v2.2.0 diff --git a/package-lock.json b/package-lock.json index eadb32a..ff434a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@babel/core": "^7.14.6", "@babel/preset-env": "^7.14.7", "@babel/preset-typescript": "^7.14.5", + "@dzeio/config": "^1.0.0", "@types/node-fetch": "^2.5.10", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", @@ -1722,6 +1723,28 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@dzeio/config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@dzeio/config/-/config-1.0.0.tgz", + "integrity": "sha512-duA7YVa4UPQl66heZptmofxFWqA+WYyDsMFh6Ud856rvkiqbgWSCMCL2slHo/vlaw5JkQlrAnxJMUlmIWktQlQ==", + "dev": true, + "peerDependencies": { + "@typescript-eslint/parser": "^4.28.2", + "next": "^11.0.1", + "next-pre-css": "^1.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/parser": { + "optional": true + }, + "next": { + "optional": true + }, + "next-pre-css": { + "optional": true + } + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", @@ -2355,14 +2378,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.0.tgz", - "integrity": "sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", "debug": "^4.3.1" }, "engines": { @@ -2381,6 +2404,95 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.28.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", @@ -3210,9 +3322,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.0.tgz", - "integrity": "sha512-8X6lWsG+s7IfOKzV93a7fRYfWRZobOfjw5V5rrq43Vh/W+V6qYxl7Akalsvgab4PFT/4L/pjQbdBUEM36NXKrw==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz", + "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==", "dev": true, "dependencies": { "browserslist": "^4.16.6", @@ -8320,6 +8432,13 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@dzeio/config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@dzeio/config/-/config-1.0.0.tgz", + "integrity": "sha512-duA7YVa4UPQl66heZptmofxFWqA+WYyDsMFh6Ud856rvkiqbgWSCMCL2slHo/vlaw5JkQlrAnxJMUlmIWktQlQ==", + "dev": true, + "requires": {} + }, "@eslint/eslintrc": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", @@ -8841,15 +8960,67 @@ } }, "@typescript-eslint/parser": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.0.tgz", - "integrity": "sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", "debug": "^4.3.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" + } + }, + "@typescript-eslint/types": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.28.2", + "eslint-visitor-keys": "^2.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/scope-manager": { @@ -9512,9 +9683,9 @@ } }, "core-js-compat": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.0.tgz", - "integrity": "sha512-8X6lWsG+s7IfOKzV93a7fRYfWRZobOfjw5V5rrq43Vh/W+V6qYxl7Akalsvgab4PFT/4L/pjQbdBUEM36NXKrw==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz", + "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==", "dev": true, "requires": { "browserslist": "^4.16.6", diff --git a/package.json b/package.json index 159f08f..e465529 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "2.4.0", "main": "./dist/cjs/tcgdex.node.js", "types": "./dist/types/tcgdex.d.ts", + "description": "Communicate with the Open Source TCGdex API in Javascript/Typescript using the SDK", "repository": "https://github.com/tcgdex/javascript-sdk.git", "homepage": "https://github.com/tcgdex/javascript-sdk", "author": "Aviortheking", @@ -23,6 +24,7 @@ "@babel/core": "^7.14.6", "@babel/preset-env": "^7.14.7", "@babel/preset-typescript": "^7.14.5", + "@dzeio/config": "^1.0.0", "@types/node-fetch": "^2.5.10", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", diff --git a/src/Request.ts b/src/Request.ts index 8760278..c733b1b 100644 --- a/src/Request.ts +++ b/src/Request.ts @@ -1,31 +1,31 @@ -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 - } - -} +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/interfaces.ts b/src/interfaces.ts index ffe3156..9c19292 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,5 +1,8 @@ export type SupportedLanguages = 'en' | 'fr' | 'es' | 'it' | 'pt' | 'de' +/** + * @deprecated This is not used anymore in the API V2 + */ export type Languages = Partial> export interface SerieResume { diff --git a/src/tcgdex.ts b/src/tcgdex.ts index ae4b379..5482dc3 100644 --- a/src/tcgdex.ts +++ b/src/tcgdex.ts @@ -1,185 +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 - - /** - * @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' diff --git a/tsconfig.es2015.json b/tsconfig.es2015.json index e7c0e6d..6670264 100644 --- a/tsconfig.es2015.json +++ b/tsconfig.es2015.json @@ -7,5 +7,5 @@ "declaration": false, /* Generates corresponding '.d.ts' file. */ "declarationDir": null, "outDir": "./dist/modules", /* Redirect output structure to the directory. */ - } + } } diff --git a/tsconfig.json b/tsconfig.json index 2d55f38..93bee6d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,66 +1,13 @@ { + "extends": "./node_modules/@dzeio/config/tsconfig.base", "include": ["./src/tcgdex.node.ts"], "compilerOptions": { - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - "declarationDir": "./dist/types", /* Folder where the declarations are*/ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist/cjs", /* Redirect output structure to the directory. */ - "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* Enable strict null checks. */ - "strictFunctionTypes": true, /* Enable strict checking of function types. */ - "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ - "noUnusedLocals": true, /* Report errors on unused locals. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ - "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationDir": "./dist/types", - "resolveJsonModule": true, - /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "outDir": "./dist/cjs", + "rootDir": "./src", - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */ } }