diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..ba78697 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +db/ +dist/ +*.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..3416756 --- /dev/null +++ b/.eslintrc.js @@ -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 + "@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] + } +}; diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 9dae690..637a226 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -16,6 +16,27 @@ on: pull_request: jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + + - uses: actions/checkout@v2 + with: + repository: tcgdex/cards-database + path: ./db + persist-credentials: false + + - name: Setup NodeJS + uses: actions/setup-node@v2 + with: + node-version: '14.x' + + - name: Lint + run: yarn && yarn lint + build: runs-on: ubuntu-latest diff --git a/SFTPPromise.ts b/SFTPPromise.ts index 6d259a2..ef41e69 100644 --- a/SFTPPromise.ts +++ b/SFTPPromise.ts @@ -1,4 +1,4 @@ -import { ConnectConfig, Client, SFTPWrapper } from "ssh2"; +import { ConnectConfig, Client, SFTPWrapper } from 'ssh2' import { Stats, InputAttributes } from 'ssh2-streams' import { promises as fs } from 'fs' import { posix as pathJS } from 'path' @@ -7,14 +7,25 @@ import Logger from '@dzeio/logger' const logger = new Logger('SFTPPromise') export default class SFTPPromise { - private sftp?: SFTPWrapper - private conn: Client = new Client() public debug = false + public tmpFolder?: string + private sftp?: SFTPWrapper + + private conn: Client = new Client() + + private queue = new Queue(50, 10) + + private filesToUpload = 0 + + private filesUploaded = 0 + + private lastTimeDiff: Array = Array.from(new Array(900), () => 0) + public constructor(public config: ConnectConfig) {} - public connect() { + public connect(): Promise { return new Promise((res, rej) => { this.conn.on('ready', () => { this.conn.sftp((err, sftpLocal) => { @@ -25,7 +36,7 @@ export default class SFTPPromise { }) } - public async makeTemporaryFolder() { + public async makeTemporaryFolder(): Promise { this.l('Making temporary Folder') this.tmpFolder = await fs.mkdtemp('tcgdex-generator') } @@ -51,25 +62,25 @@ export default class SFTPPromise { } } - public async mkdir(path: string, recursive = false, attributes?: InputAttributes, ) { + public async mkdir(path: string, recursive = false, attributes?: InputAttributes): Promise { this.l('Creating remote folder', path) if (recursive) { this.l('Making temporary Folder') const folders = path.split('/') let current = '' - for (const item of folders) { - current += '/' + item - if (!(await this.exists(current))) { + await Promise.all(folders.map(async (item) => { + current += `/${item}` + if (!await this.exists(current)) { await this.mkdir(current) } - } + })) return } if (await this.exists(path)) { return } const sftp = this.getSFTP() - return new Promise((res, rej) => { + await new Promise((res, rej) => { const result = (err?: any) => { if (err) { rej(err) @@ -81,66 +92,68 @@ export default class SFTPPromise { } else { sftp.mkdir(path, result) } - }) } - public async upload(localFile: Buffer|string, path: string) { + public async upload(localFile: Buffer|string, path: string): Promise { const sftp = this.getSFTP() - if (typeof localFile !== 'string') { + let file = localFile + if (typeof file !== 'string') { if (!this.tmpFolder) { await this.makeTemporaryFolder() } - const tmpFile = pathJS.join(this.tmpFolder as string, Math.random().toString().replace('.', '')) - // this.l('Writing to temporary Folder') - await fs.writeFile(tmpFile, localFile) - localFile = tmpFile + const tmpFile = pathJS.join( + this.tmpFolder as string, + Math.random() + .toString() + .replace('.', '') + ) + await fs.writeFile(tmpFile, file) + // IDK there is no race condition + // eslint-disable-next-line require-atomic-updates + file = tmpFile } - const remoteFolder = pathJS.dirname(path).replace(/\\/g, '/') - if (!(await this.exists(remoteFolder))) { + const remoteFolder = pathJS.dirname(path).replace(/\\/gu, '/') + if (!await this.exists(remoteFolder)) { await this.mkdir(remoteFolder, true) } - return new Promise((result, rej) => { + await new Promise((result, rej) => { this.l('Sending file', path) - sftp.fastPut(localFile as string, path, { + sftp.fastPut(file as string, path, { concurrency: 1, - step: (uploaded, u, total) => { - this.l(path.substr(path.lastIndexOf('/')), Math.round(uploaded*100/total),'%', '/', 100, '%') + step: (uploaded, _, total) => { + this.l(path.substr(path.lastIndexOf('/')), Math.round(uploaded * 100 / total), '%', '/', 100, '%') } }, (err) => { if (err) { - this.l('Error fastPutting file', localFile, 'to', path) + this.l('Error fastPutting file', file, 'to', path) rej(err) } this.l('Done') result() - return }) }) } - private queue = new Queue(50, 10) - private filesToUpload = 0 - private filesUploaded = 0 - public async listDir(path: string, exclude?: RegExp): Promise> { const files = await fs.readdir(path) logger.log('Reading', path) - let res: Array = [] - for (const file of files) { - if (exclude?.test(file)) {continue} + const res: Array = [] + await Promise.all(files.map(async (file) => { + if (exclude?.test(file)) { + return + } const filePath = `${path}/${file}` const stat = await fs.stat(filePath) if (stat.isDirectory()) { - res = res.concat(await this.listDir(filePath)) + res.push(...await this.listDir(filePath)) } else { res.push(filePath) } - } + })) return res } - private lastTimeDiff: Array = Array.from(new Array(900), () => 0) public async uploadDir(localPath: string, remotePath: string, exclude?: RegExp, root = true) { if (root) { this.filesToUpload = 0 @@ -154,20 +167,24 @@ export default class SFTPPromise { this.queue.start() for (const file of files) { // console.log('t1') - if (exclude?.test(file)) {continue} + if (exclude?.test(file)) { + continue + } // console.log('t1') const filePath = file const remoteFilePath = `${remotePath}/${file.replace(localPath, '')}` // console.log('t1') const now = new Date().getTime() await this.queue.add( - this.upload(filePath, remoteFilePath).then(() => { - this.filesUploaded++ - this.lastTimeDiff.push(new Date().getTime() - now) - this.lastTimeDiff.shift() - const time = ((this.filesToUpload-this.filesUploaded)*(this.lastTimeDiff.reduce((p, c) => p + c, 0)/this.lastTimeDiff.length)/10000) - console.log(`Files uploaded ${(this.filesUploaded * 100 / this.filesToUpload).toFixed(0)}% ${time > 60 ? `${(time/60).toFixed(0)}m` : `${time.toFixed(0)}s`} ${this.filesUploaded}/${this.filesToUpload}`) - }).catch((err) => logger.log(err, 'Error uploading', filePath, 'to', remoteFilePath)) + this.upload(filePath, remoteFilePath) + .then(() => { + this.filesUploaded++ + this.lastTimeDiff.push(new Date().getTime() - now) + this.lastTimeDiff.shift() + const time = (this.filesToUpload - this.filesUploaded) * (this.lastTimeDiff.reduce((p, c) => p + c, 0) / this.lastTimeDiff.length) / 10000 + console.log(`Files uploaded ${(this.filesUploaded * 100 / this.filesToUpload).toFixed(0)}% ${time > 60 ? `${(time/60).toFixed(0)}m` : `${time.toFixed(0)}s`} ${this.filesUploaded}/${this.filesToUpload}`) + }) + .catch((err) => logger.log(err, 'Error uploading', filePath, 'to', remoteFilePath)) ) } if (root) { @@ -188,4 +205,5 @@ export default class SFTPPromise { logger.log(...messages) } } + } diff --git a/endpoints/cards.ts b/endpoints/cards.ts index 3d9f0f4..e2f7a1d 100644 --- a/endpoints/cards.ts +++ b/endpoints/cards.ts @@ -3,24 +3,26 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, cardToCardSingle, getCards } from '../utils/cardUtil' -export default class implements Endpoint> { +export default class implements Endpoint, Array<[string, Card]>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Array<[string, Card]>) { + public async index(common: Array<[string, Card]>): Promise { return Promise.all(common.map((c) => cardToCardSimple(c[0], c[1], this.lang))) } - public async item(common: Array<[string, Card]>) { + public async item(common: Array<[string, Card]>): Promise> { const items: Record = {} - for (const card of common) { + for await (const card of common) { items[`${card[1].set.id}-${card[0]}`] = await cardToCardSingle(card[0], card[1], this.lang) } return items } - public async common() { + public async common(): Promise> { return getCards(this.lang) } + } diff --git a/endpoints/categories.ts b/endpoints/categories.ts index e74988c..417e633 100644 --- a/endpoints/categories.ts +++ b/endpoints/categories.ts @@ -4,32 +4,35 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} - for (const key of Object.keys(common)) { + for await (const key of Object.keys(common)) { const val = common[key] const it = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } items[key] = it } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { const category = translate('category', c[1].category, this.lang) - if (!category) return p + if (!category) { + return p + } if (!p[category]) { p[category] = [] } @@ -37,4 +40,5 @@ export default class implements Endpoint>) } + } diff --git a/endpoints/hp.ts b/endpoints/hp.ts index fe01eda..18cc5ba 100644 --- a/endpoints/hp.ts +++ b/endpoints/hp.ts @@ -3,31 +3,34 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} for (const key of Object.keys(common)) { const val = common[key] items[key] = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { - const hp = c[1].hp - if (!hp) return p + const { hp } = c[1] + if (!hp) { + return p + } if (!p[hp]) { p[hp] = [] } @@ -35,4 +38,5 @@ export default class implements Endpoint>) } + } diff --git a/endpoints/illustrators.ts b/endpoints/illustrators.ts index 51e1eff..96f8b42 100644 --- a/endpoints/illustrators.ts +++ b/endpoints/illustrators.ts @@ -3,31 +3,34 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} - for (const key of Object.keys(common)) { + for await (const key of Object.keys(common)) { const val = common[key] items[key] = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { - const illustrator = c[1].illustrator - if (!illustrator) return p + const { illustrator } = c[1] + if (!illustrator) { + return p + } if (!p[illustrator]) { p[illustrator] = [] } @@ -35,4 +38,5 @@ export default class implements Endpoint>) } + } diff --git a/endpoints/rarities.ts b/endpoints/rarities.ts index 0b63a5f..8b1e599 100644 --- a/endpoints/rarities.ts +++ b/endpoints/rarities.ts @@ -4,31 +4,34 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} - for (const key of Object.keys(common)) { + for await (const key of Object.keys(common)) { const val = common[key] items[key] = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { const rarity = translate('rarity', c[1].rarity, this.lang) - if (!rarity) return p + if (!rarity) { + return p + } if (!p[rarity]) { p[rarity] = [] } @@ -36,4 +39,5 @@ export default class implements Endpoint>) } + } diff --git a/endpoints/retreats.ts b/endpoints/retreats.ts index e10320a..bcf7cb7 100644 --- a/endpoints/retreats.ts +++ b/endpoints/retreats.ts @@ -3,31 +3,34 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} - for (const key of Object.keys(common)) { + for await (const key of Object.keys(common)) { const val = common[key] items[key] = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { - const retreat = c[1].retreat - if (!retreat) return p + const { retreat } = c[1] + if (!retreat) { + return p + } if (!p[retreat]) { p[retreat] = [] } @@ -35,4 +38,5 @@ export default class implements Endpoint>) } + } diff --git a/endpoints/series.ts b/endpoints/series.ts index db3b282..0fe964d 100644 --- a/endpoints/series.ts +++ b/endpoints/series.ts @@ -1,21 +1,21 @@ -import { Serie as SerieSingle, SerieList } from '@tcgdex/sdk/interfaces' +import { Serie as SerieSingle, SerieList, SerieResume } from '@tcgdex/sdk/interfaces' import { Languages, Serie } from '../db/interfaces' import { Endpoint } from '../interfaces' import { getSeries, serieToSerieSimple, serieToSerieSingle } from '../utils/serieUtil' -export default class implements Endpoint> { +export default class implements Endpoint, Array> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Array) { + public async index(common: Array): Promise> { return Promise.all(common.map((s) => serieToSerieSimple(s, this.lang))) } - public async item(common: Array) { + public async item(common: Array): Promise> { const items: Record = {} - for (let key = 0; key < common.length; key++) { - const val = common[key]; + for await (const val of common) { const gen = await serieToSerieSingle(val, this.lang) const name = val.name[this.lang] as string items[name] = gen @@ -24,7 +24,8 @@ export default class implements Endpoint> { return getSeries(this.lang) } + } diff --git a/endpoints/sets.ts b/endpoints/sets.ts index 47541e8..336b00c 100644 --- a/endpoints/sets.ts +++ b/endpoints/sets.ts @@ -1,15 +1,16 @@ import { SetList, Set as SetSingle, Card as CardSingle } from '@tcgdex/sdk/interfaces' -import { getSet, getSets, isSetAvailable, setToSetSimple, setToSetSingle } from "../utils/setUtil" +import { getSets, isSetAvailable, setToSetSimple, setToSetSingle } from '../utils/setUtil' import { Languages, Set } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSingle, getCards } from '../utils/cardUtil' export default class implements Endpoint> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Array) { + public async index(common: Array): Promise { const sets = common .sort((a, b) => a.releaseDate > b.releaseDate ? 1 : -1) @@ -18,8 +19,8 @@ export default class implements Endpoint) { - const sets= await Promise.all(common + public async item(common: Array): Promise> { + const sets = await Promise.all(common .map((set) => setToSetSingle(set, this.lang))) const res: Record = {} @@ -31,21 +32,24 @@ export default class implements Endpoint> { + return getSets(undefined, this.lang) } - public async sub(common: Array, item: string) { + public async sub(common: Array, item: string): Promise | undefined> { const set = common.find((s) => s.name[this.lang] === item || s.id === item) - if (!set || !isSetAvailable(set, this.lang)) return undefined - - const lit = await getCards(this.lang, set) - const l: Record = {} - for (let i of lit) { - l[i[0]] = await cardToCardSingle(i[0], i[1], this.lang) + if (!set || !isSetAvailable(set, this.lang)) { + return undefined } - return l + const lit = await getCards(this.lang, set) + const list: Record = {} + for await (const card of lit) { + list[card[0]] = await cardToCardSingle(card[0], card[1], this.lang) + } + + return list } + } diff --git a/endpoints/types.ts b/endpoints/types.ts index b64927f..9cc1b45 100644 --- a/endpoints/types.ts +++ b/endpoints/types.ts @@ -4,31 +4,34 @@ import { Card, Languages } from '../db/interfaces' import { Endpoint } from '../interfaces' import { cardToCardSimple, getCards } from '../utils/cardUtil' -export default class implements Endpoint>> { +export default class implements Endpoint, Record>> { + public constructor( private lang: keyof Languages ) {} - public async index(common: Record>) { + public async index(common: Record>): Promise { return Object.keys(common) } - public async item(common: Record>) { + public async item(common: Record>): Promise> { const items: Record = {} - for (const key of Object.keys(common)) { + for await (const key of Object.keys(common)) { const val = common[key] items[key] = { - name: key, - cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))) + cards: await Promise.all(val.map(([id, card]) => cardToCardSimple(id, card, this.lang))), + name: key } } return items } - public async common() { + public async common(): Promise>> { return (await getCards(this.lang)).reduce((p, c) => { const types = c[1].types?.map((t) => translate('types', t, this.lang) as string) - if (!types) return p + if (!types) { + return p + } for (const type of types) { if (!p[type]) { p[type] = [] @@ -38,4 +41,5 @@ export default class implements Endpoint>) } + } diff --git a/main.ts b/main.ts index 84a5aa7..f1315d4 100644 --- a/main.ts +++ b/main.ts @@ -15,10 +15,9 @@ const VERSION = 'v2' const paths = (await fs.readdir('./endpoints')).filter((f) => f.endsWith('.ts')) console.log('Prefetching pictures') - await fetchRemoteFile(`https://assets.tcgdex.net/datas.json`) + await fetchRemoteFile('https://assets.tcgdex.net/datas.json') await fs.rm(`./dist/${VERSION}/${lang}`, {recursive: true, force: true}) - console.log('Let\'s GO !') for (const file of paths) { const path = `./endpoints/${file}` diff --git a/package.json b/package.json index b06ce6e..c9475e0 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,15 @@ "name": "@tcgdex/compiler", "version": "2.0.0", "repository": "https://github.com/tcgdex/compiler.git", - "author": "Avior ", + "author": "Avior ", "license": "MIT", "private": false, "scripts": { "db:compile": "cd db && tsc --project tsconfig.json", "db:test": "cd db && tsc --noEmit --project tsconfig.json", "start": "node --require ts-node/register --unhandled-rejections=strict main.ts", - "upload": "node --require ts-node/register --unhandled-rejections=strict upload.ts" + "upload": "node --require ts-node/register --unhandled-rejections=strict upload.ts", + "lint": "eslint ./utils ./endpoints ./*.ts --ext .ts" }, "dependencies": { "@dzeio/logger": "^2.0.0-alpha.0", @@ -26,5 +27,10 @@ "ssh2": "^0.8.9", "ts-node": "^9.1.1", "typescript": "^4.2.3" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", + "eslint": "^7.27.0" } } diff --git a/upload.ts b/upload.ts index 7964a10..f6e18d1 100644 --- a/upload.ts +++ b/upload.ts @@ -1,5 +1,4 @@ import { config } from 'dotenv' -import path from 'path' import { ConnectConfig } from 'ssh2' import SFTPPromise from './SFTPPromise' @@ -7,26 +6,17 @@ config() const sshConfig: ConnectConfig = { host: process.env.UPLOAD_REMOTE, - username: process.env.UPLOAD_USERNAME, - password: process.env.UPLOAD_PASSWORD , - port: 22 -}; - -async function main() { + password: process.env.UPLOAD_PASSWORD, + port: 22, + username: process.env.UPLOAD_USERNAME } -main().then(msg => { - console.log(msg); -}).catch(err => { - console.log(`main error: ${err.message}`); -}); - ;(async () => { const client = new SFTPPromise(sshConfig) // client.debug = true await client.connect() const src = `${__dirname}/dist` const dst = process.env.UPLOAD_DIST as string - await client.uploadDir(src, dst, /\.git/g) + await client.uploadDir(src, dst, /\.git/gu) process.exit(0) })() diff --git a/utils/cardUtil.ts b/utils/cardUtil.ts index b2af796..93228f0 100644 --- a/utils/cardUtil.ts +++ b/utils/cardUtil.ts @@ -1,12 +1,22 @@ -import { setToSetSimple } from "./setUtil" -import { cardIsLegal, fetchRemoteFile, smartGlob } from "./util" +/* eslint-disable sort-keys */ +import { setToSetSimple } from './setUtil' +import { cardIsLegal, fetchRemoteFile, smartGlob } from './util' import { Set, SupportedLanguages, Card, Types } from 'db/interfaces' import { Card as CardSingle, CardResume } from '@tcgdex/sdk/interfaces' import translate from './translationUtil' -type ObjectList = Partial> - -type RemoteData = ObjectList>>> +export async function getCardPictures(cardId: string, card: Card, lang: SupportedLanguages): Promise { + try { + const file = await fetchRemoteFile('https://assets.tcgdex.net/datas.json') + const fileExists = Boolean(file[lang]?.[card.set.serie.id]?.[card.set.id]?.[cardId]) + if (fileExists) { + return `https://assets.tcgdex.net/${lang}/${card.set.serie.id}/${card.set.id}/${cardId}` + } + } catch { + return undefined + } + return undefined +} export async function cardToCardSimple(id: string, card: Card, lang: SupportedLanguages): Promise { const cardName = card.name[lang] @@ -16,26 +26,14 @@ export async function cardToCardSimple(id: string, card: Card, lang: SupportedLa const img = await getCardPictures(id, card, lang) return { id: `${card.set.id}-${id}`, + image: img, localId: id, - name: cardName, - image: img - } -} - -export async function getCardPictures(cardId: string, card: Card, lang: SupportedLanguages): Promise { - try { - const file = await fetchRemoteFile(`https://assets.tcgdex.net/datas.json`) - const fileExists = !!file[lang]?.[card.set.serie.id]?.[card.set.id]?.[cardId] - if (fileExists) { - return `https://assets.tcgdex.net/${lang}/${card.set.serie.id}/${card.set.id}/${cardId}` - } - } catch { - return undefined + name: cardName } } +// eslint-disable-next-line max-lines-per-function export async function cardToCardSingle(localId: string, card: Card, lang: SupportedLanguages): Promise { - const image = await getCardPictures(localId, card, lang) if (!card.name[lang]) { @@ -43,22 +41,22 @@ export async function cardToCardSingle(localId: string, card: Card, lang: Suppor } return { - id: `${card.set.id}-${localId}`, - localId: localId, - name: card.name[lang] as string, - image: image, - - illustrator: card.illustrator, - rarity: translate('rarity', card.rarity, lang) as any, category: translate('category', card.category, lang) as any, + id: `${card.set.id}-${localId}`, + illustrator: card.illustrator, + image, + localId, + name: card.name[lang] as string, + + rarity: translate('rarity', card.rarity, lang) as any, + set: await setToSetSimple(card.set, lang), variants: { - normal: typeof card.variants?.normal === 'boolean' ? card.variants.normal : typeof card.set.variants?.normal === 'boolean' ? card.set.variants.normal : true, - reverse: typeof card.variants?.reverse === 'boolean' ? card.variants.reverse : typeof card.set.variants?.reverse === 'boolean' ? card.set.variants.reverse : true, - holo: typeof card.variants?.holo === 'boolean' ? card.variants.holo : typeof card.set.variants?.holo === 'boolean' ? card.set.variants.holo : true, firstEdition: typeof card.variants?.firstEdition === 'boolean' ? card.variants.firstEdition : typeof card.set.variants?.firstEdition === 'boolean' ? card.set.variants.firstEdition : false, + holo: typeof card.variants?.holo === 'boolean' ? card.variants.holo : typeof card.set.variants?.holo === 'boolean' ? card.set.variants.holo : true, + normal: typeof card.variants?.normal === 'boolean' ? card.variants.normal : typeof card.set.variants?.normal === 'boolean' ? card.set.variants.normal : true, + reverse: typeof card.variants?.reverse === 'boolean' ? card.variants.reverse : typeof card.set.variants?.reverse === 'boolean' ? card.set.variants.reverse : true }, - set: await setToSetSimple(card.set, lang), dexId: card.dexId, hp: card.hp, @@ -86,7 +84,6 @@ export async function cardToCardSingle(localId: string, card: Card, lang: Suppor effect: el.effect ? el.effect[lang] : undefined, damage: el.damage })), - weaknesses: card.weaknesses?.map((el) => ({ type: translate('types', el.type, lang) as Types, value: el.value @@ -124,7 +121,7 @@ export async function getCard(serie: string, setName: string, id: string): Promi } export async function getCards(lang: SupportedLanguages, set?: Set): Promise> { - const cards = (await smartGlob(`./db/data/${(set && set.serie.name.en) ?? '*'}/${(set && set.name.en) ?? '*'}/*.js`)) + const cards = await smartGlob(`./db/data/${(set && set.serie.name.en) ?? '*'}/${(set && set.name.en) ?? '*'}/*.js`) const list: Array<[string, Card]> = [] for (const path of cards) { const id = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.')) @@ -146,12 +143,11 @@ export async function getCards(lang: SupportedLanguages, set?: Set): Promise { - const ra = parseInt(a) - const rb = parseInt(b) + const ra = parseInt(a, 10) + const rb = parseInt(b, 10) if (!isNaN(ra) && !isNaN(rb)) { return ra - rb - } else { - return a >= b ? 1 : -1 } + return a >= b ? 1 : -1 }) } diff --git a/utils/serieUtil.ts b/utils/serieUtil.ts index d2535d6..ac0e53d 100644 --- a/utils/serieUtil.ts +++ b/utils/serieUtil.ts @@ -1,44 +1,43 @@ -import { smartGlob } from "./util" -import { setToSetSimple, getSets, getSet, isSetAvailable } from "./setUtil" +import { smartGlob } from './util' +import { setToSetSimple, getSets } from './setUtil' import { Serie, SupportedLanguages, Set } from 'db/interfaces' import { Serie as SerieSingle, SerieResume } from '@tcgdex/sdk/interfaces' +export async function getSerie(name: string): Promise { + return (await import(`../db/data/${name}.js`)).default +} + +export async function isSerieAvailable(serie: Serie, lang: SupportedLanguages): Promise { + if (!serie.name[lang]) { + return false + } + const sets = await getSets(serie.name.en, lang) + return sets.length > 0 +} + export async function getSeries(lang: SupportedLanguages): Promise> { let series: Array = (await Promise.all((await smartGlob('./db/data/*.js')) - //Find Serie's name + // Find Serie's name .map((it) => it.substring(it.lastIndexOf('/') + 1, it.length - 3)) // Fetch the Serie .map((it) => getSerie(it)))) // Filter the serie if no name's exists in the selected lang - .filter((serie) => !!serie.name[lang]) + .filter((serie) => Boolean(serie.name[lang])) // Filter available series const isAvailable = await Promise.all(series.map((serie) => isSerieAvailable(serie, lang))) series = series.filter((_, index) => isAvailable[index]) // Sort series by the first set release date - const tmp: Array<[Serie, Set | undefined]> = await Promise.all(series.map(async (it) => { - return [ - it, - (await getSets(it.name.en, lang)) - .reduce((p, c) => p ? p.releaseDate < c.releaseDate ? p : c : c, undefined) as Set] as [Serie, Set] - })) + const tmp: Array<[Serie, Set | undefined]> = await Promise.all(series.map(async (it) => [ + it, + (await getSets(it.name.en, lang)) + .reduce((p, c) => p ? p.releaseDate < c.releaseDate ? p : c : c, undefined) as Set + ] as [Serie, Set])) return tmp.sort((a, b) => (a[1] ? a[1].releaseDate : '0') > (b[1] ? b[1].releaseDate : '0') ? 1 : -1).map((it) => it[0]) } -export async function getSerie(name: string): Promise { - return (await import(`../db/data/${name}.js`)).default -} - -export async function isSerieAvailable(serie: Serie, lang: SupportedLanguages) { - if (!serie.name[lang]) { - return false - } - const sets = (await getSets(serie.name.en, lang)) - return sets.length > 0 -} - export async function serieToSerieSimple(serie: Serie, lang: SupportedLanguages): Promise { return { id: serie.id, @@ -49,10 +48,8 @@ export async function serieToSerieSimple(serie: Serie, lang: SupportedLanguages) export async function serieToSerieSingle(serie: Serie, lang: SupportedLanguages): Promise { const setsTmp = await getSets(serie.name.en, lang) const sets = await Promise.all(setsTmp - .sort((a, b) => { - return a.releaseDate > b.releaseDate ? 1 : -1 - }) - .map(el => setToSetSimple(el, lang))) + .sort((a, b) => a.releaseDate > b.releaseDate ? 1 : -1) + .map((el) => setToSetSimple(el, lang))) return { id: serie.id, name: serie.name[lang] as string, diff --git a/utils/setUtil.ts b/utils/setUtil.ts index 65850b0..2cc4498 100644 --- a/utils/setUtil.ts +++ b/utils/setUtil.ts @@ -1,5 +1,5 @@ -import { Set, SupportedLanguages } from "db/interfaces" -import { fetchRemoteFile, setIsLegal, smartGlob } from "./util" +import { Set, SupportedLanguages } from 'db/interfaces' +import { fetchRemoteFile, setIsLegal, smartGlob } from './util' import { cardToCardSimple, getCards } from './cardUtil' import { SetResume, Set as SetSingle } from '@tcgdex/sdk/interfaces' @@ -9,52 +9,46 @@ interface t { const setCache: t = {} -// Dont use cache as it wont necessary have them all -export async function getSets(serie = '*', lang: SupportedLanguages): Promise> { - // list sets names - const rawSets = (await smartGlob(`./db/data/${serie}/*.js`)).map((set) => set.substring(set.lastIndexOf('/')+1, set.lastIndexOf('.'))) - // Fetch sets - const sets = (await Promise.all(rawSets.map((set) => getSet(set, serie, lang)))) - // Filter sets - .filter((set) => isSetAvailable(set, lang)) - // Sort sets by release date - .sort((a, b) => { - return a.releaseDate > b.releaseDate ? 1 : -1 - }) - return sets +export function isSetAvailable(set: Set, lang: SupportedLanguages): boolean { + return lang in set.name } /** * Return the set * @param name the name of the set (don't include.js/.ts) */ -export async function getSet(name: string, serie = '*', lang: SupportedLanguages): Promise { +export async function getSet(name: string, serie = '*'): Promise { if (!setCache[name]) { try { const [path] = await smartGlob(`./db/data/${serie}/${name}.js`) setCache[name] = (await import(path.replace('./', '../'))).default - } catch (e) { - const set = (await getSets(undefined, lang)).find((s) => s.id === name) - if (set) { - return set - } - console.error(e) - console.error(`Error trying to import importing (${`db/data/*/${name}.js`})`) + } catch (error) { + console.error(error) + console.error(`Error trying to import importing (${`db/data/${serie}/${name}.js`})`) process.exit(1) } } return setCache[name] } -export function isSetAvailable(set: Set, lang: SupportedLanguages): boolean { - return lang in set.name && lang in set.serie.name +// Dont use cache as it wont necessary have them all +export async function getSets(serie = '*', lang: SupportedLanguages): Promise> { + // list sets names + const rawSets = (await smartGlob(`./db/data/${serie}/*.js`)).map((set) => set.substring(set.lastIndexOf('/') + 1, set.lastIndexOf('.'))) + // Fetch sets + const sets = (await Promise.all(rawSets.map((set) => getSet(set, serie)))) + // Filter sets + .filter((set) => isSetAvailable(set, lang)) + // Sort sets by release date + .sort((a, b) => a.releaseDate > b.releaseDate ? 1 : -1) + return sets } export async function getSetPictures(set: Set, lang: SupportedLanguages): Promise<[string | undefined, string | undefined]> { try { - const file = await fetchRemoteFile(`https://assets.tcgdex.net/datas.json`) - const logoExists = !!file[lang]?.[set.serie.id]?.[set.id]?.logo ? `https://assets.tcgdex.net/${lang}/${set.serie.id}/${set.id}/logo` : undefined - const symbolExists = !!file.univ?.[set.serie.id]?.[set.id]?.symbol ? `https://assets.tcgdex.net/univ/${set.serie.id}/${set.id}/symbol` : undefined + const file = await fetchRemoteFile('https://assets.tcgdex.net/datas.json') + const logoExists = file[lang]?.[set.serie.id]?.[set.id]?.logo ? `https://assets.tcgdex.net/${lang}/${set.serie.id}/${set.id}/logo` : undefined + const symbolExists = file.univ?.[set.serie.id]?.[set.id]?.symbol ? `https://assets.tcgdex.net/univ/${set.serie.id}/${set.id}/symbol` : undefined return [ logoExists, symbolExists @@ -68,14 +62,14 @@ export async function setToSetSimple(set: Set, lang: SupportedLanguages): Promis const cards = await getCards(lang, set) const pics = await getSetPictures(set, lang) return { + cardCount: { + official: set.cardCount.official, + total: Math.max(set.cardCount.official, cards.length) + }, id: set.id, logo: pics[0], - symbol: pics[1], name: set.name[lang] as string, - cardCount: { - total: Math.max(set.cardCount.official, cards.length), - official: set.cardCount.official - }, + symbol: pics[1] } } @@ -83,28 +77,28 @@ export async function setToSetSingle(set: Set, lang: SupportedLanguages): Promis const cards = await getCards(lang, set) const pics = await getSetPictures(set, lang) return { - name: set.name[lang] as string, + cardCount: { + firstEd: cards.reduce((count, card) => count + (card[1].variants?.firstEdition ?? set.variants?.firstEdition ? 1 : 0), 0), + holo: cards.reduce((count, card) => count + (card[1].variants?.holo ?? set.variants?.holo ? 1 : 0), 0), + normal: cards.reduce((count, card) => count + (card[1].variants?.normal ?? set.variants?.normal ? 1 : 0), 0), + official: set.cardCount.official, + reverse: cards.reduce((count, card) => count + (card[1].variants?.reverse ?? set.variants?.reverse ? 1 : 0), 0), + total: Math.max(set.cardCount.official, cards.length) + }, + cards: await Promise.all(cards.map(([id, card]) => cardToCardSimple(id, card, lang))), id: set.id, + legal: { + expanded: setIsLegal('expanded', set), + standard: setIsLegal('standard', set) + }, + logo: pics[0], + name: set.name[lang] as string, + releaseDate: set.releaseDate, serie: { id: set.serie.id, name: set.serie.name[lang] as string }, - tcgOnline: set.tcgOnline, - cardCount: { - total: Math.max(set.cardCount.official, cards.length), - official: set.cardCount.official, - normal: cards.reduce((count, card) => count + (card[1].variants?.normal ?? set.variants?.normal ? 1 : 0), 0), - reverse: cards.reduce((count, card) => count + (card[1].variants?.reverse ?? set.variants?.reverse ? 1 : 0), 0), - holo: cards.reduce((count, card) => count + (card[1].variants?.holo ?? set.variants?.holo ? 1 : 0), 0), - firstEd: cards.reduce((count, card) => count + (card[1].variants?.firstEdition ?? set.variants?.firstEdition ? 1 : 0), 0), - }, - releaseDate: set.releaseDate, - legal: { - standard: setIsLegal('standard', set), - expanded: setIsLegal('expanded', set) - }, - logo: pics[0], symbol: pics[1], - cards: await Promise.all(cards.map(([id, card]) => cardToCardSimple(id, card, lang))) + tcgOnline: set.tcgOnline } } diff --git a/utils/translationUtil.ts b/utils/translationUtil.ts index c48546d..5fb1cd1 100644 --- a/utils/translationUtil.ts +++ b/utils/translationUtil.ts @@ -4,72 +4,73 @@ type translatable = 'types' | 'rarity' | 'stage' | 'category' | 'suffix' | 'abil const translations: Record>> = { fr: { - types: { - 'Colorless': 'Incolore', - 'Darkness': 'Obscurité', - 'Dragon': 'Dragon', - 'Fairy': 'Fée', - 'Fighting': 'Combat', - 'Fire': 'Feu', - 'Grass': 'Plante', - 'Lightning': 'Électrique', - 'Metal': 'Métal', - 'Psychic': 'Psy', - 'Water': 'Eau' - }, - rarity: { - 'None': 'Rien', - 'Common': 'Commune', - 'Uncommon': 'Non Commune', - 'Rare': 'Rare', - 'Ultra Rare': 'Ultra Rare', - 'Secret Rare': 'Magnifique rare' - }, - stage: { - "Basic": 'Base', - "BREAK": 'TURBO', - "LEVEL-UP": 'Niveau Sup', - "MEGA": 'MÉGA', - "RESTORED": 'RECRÉE', - "Stage1": 'Niveau1', - "Stage2": 'Biveau2', - "VMAX": 'VMAX' - }, - category: { - Pokemon: 'Pokémon', - Trainer: 'Dresseur', - Energy: 'Énergie' - }, - suffix: { - 'EX': 'EX', - 'GX': 'GX', - 'V': 'V', - 'Legend': 'LÉGENDE', - 'Prime': 'Prime', - 'SP': 'SP', - 'TAG TEAM-GX': 'TAG TEAM-GX', - }, abilityType: { - 'Pokemon Power': 'Pouvoir Pokémon', + 'Ability': 'Talent', + 'Ancient Trait': 'Trait Antique', 'Poke-BODY': 'Poké-BODY', 'Poke-POWER': 'Poké-POWER', - 'Ability': 'Talent', - 'Ancient Trait': 'Trait Antique' + 'Pokemon Power': 'Pouvoir Pokémon' }, - trainerType: { - 'Supporter': 'Supporter', - 'Item': 'Objet', - 'Stadium': 'Stade', - 'Tool': 'Outil', - 'Ace Spec': 'High-Tech', - 'Technical Machine': 'Machine Technique', - 'Goldenred Game Corner': 'Salle de jeu de Doublonville', - 'Rocket\'s Secret Machine': 'Machine secrète des Rocket' + category: { + Energy: 'Énergie', + Pokemon: 'Pokémon', + Trainer: 'Dresseur' }, energyType: { Normal: 'Normal', Special: 'Spécial' }, + rarity: { + 'Common': 'Commune', + 'None': 'Rien', + 'Rare': 'Rare', + 'Secret Rare': 'Magnifique rare', + 'Ultra Rare': 'Ultra Rare', + 'Uncommon': 'Non Commune' + }, + stage: { + 'BREAK': 'TURBO', + 'Basic': 'Base', + 'LEVEL-UP': 'Niveau Sup', + 'MEGA': 'MÉGA', + 'RESTORED': 'RECRÉE', + 'Stage1': 'Niveau1', + 'Stage2': 'Niveau2', + 'VMAX': 'VMAX' + }, + suffix: { + 'EX': 'EX', + 'GX': 'GX', + 'Legend': 'LÉGENDE', + 'Prime': 'Prime', + 'SP': 'SP', + 'TAG TEAM-GX': 'TAG TEAM-GX', + 'V': 'V' + }, + trainerType: { + 'Ace Spec': 'High-Tech', + 'Goldenred Game Corner': 'Salle de jeu de Doublonville', + 'Item': 'Objet', + 'Rocket\'s Secret Machine': 'Machine secrète des Rocket', + 'Stadium': 'Stade', + 'Supporter': 'Supporter', + 'Technical Machine': 'Machine Technique', + 'Tool': 'Outil' + }, + types: { + Colorless: 'Incolore', + Darkness: 'Obscurité', + Dragon: 'Dragon', + Fairy: 'Fée', + Fighting: 'Combat', + Fire: 'Feu', + Grass: 'Plante', + Lightning: 'Électrique', + Metal: 'Métal', + Psychic: 'Psy', + Water: 'Eau' + } + } } @@ -82,7 +83,7 @@ export default function translate(item: translatable, key: string | undefined, l } const res = translations[lang]?.[item]?.[key] if (!res) { - throw new Error(`Could not find translation for ${lang}${item}.${key}`); + throw new Error(`Could not find translation for ${lang}${item}.${key}`) } return res } diff --git a/utils/util.ts b/utils/util.ts index e9867ff..b50705e 100644 --- a/utils/util.ts +++ b/utils/util.ts @@ -4,7 +4,11 @@ import fetch from 'node-fetch' import * as legals from '../db/legals' export function urlize(str: string): string { - return str.replace('?', '%3F').normalize('NFC').replace(/["'\u0300-\u036f]/g, "") + return str + .replace('?', '%3F') + .normalize('NFC') + // eslint-disable-next-line no-misleading-character-class + .replace(/["'\u0300-\u036f]/gu, '') } interface fileCacheInterface { @@ -25,19 +29,21 @@ export async function fetchRemoteFile(url: string): Promise { const globCache: Record> = {} -export async function smartGlob(query: string) { +export async function smartGlob(query: string): Promise> { if (!globCache[query]) { - globCache[query] = await new Promise((res) => glob(query, (err, matches) => res(matches))) + globCache[query] = await new Promise((res) => { + glob(query, (err, matches) => res(matches)) + }) } return globCache[query] } -export function cardIsLegal(type: 'standard' | 'expanded', card: Card, localId: string) { +export function cardIsLegal(type: 'standard' | 'expanded', card: Card, localId: string): boolean { const legal = legals[type] if ( legal.includes.series.includes(card.set.serie.id) || legal.includes.sets.includes(card.set.id) || - (card.regulationMark && legal.includes.regulationMark.includes(card.regulationMark)) + card.regulationMark && legal.includes.regulationMark.includes(card.regulationMark) ) { return !( legal.excludes.sets.includes(card.set.id) || @@ -47,7 +53,7 @@ export function cardIsLegal(type: 'standard' | 'expanded', card: Card, localId: return false } -export function setIsLegal(type: 'standard' | 'expanded', set: Set) { +export function setIsLegal(type: 'standard' | 'expanded', set: Set): boolean { const legal = legals[type] if ( legal.includes.series.includes(set.serie.id) || diff --git a/yarn.lock b/yarn.lock index 10b6ec1..161ff6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,27 @@ # yarn lockfile v1 +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/highlight@^7.10.4": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@dzeio/logger@^2.0.0-alpha.0": version "2.0.4" resolved "https://registry.yarnpkg.com/@dzeio/logger/-/logger-2.0.4.tgz#a8761a057198376fad768e604e370f5cb3415107" @@ -19,6 +40,41 @@ resolved "https://registry.yarnpkg.com/@dzeio/queue/-/queue-1.2.0.tgz#cc61133f182f4b15267f974c63a7a9e4591365f5" integrity sha512-YCDgMy41bYH7Rn5nIuH5T3W30Up69LhVqKm5IbK0ybjqyf90Sb9qeRpyqbtG+CV6kQnakhpkcr8ZqtRQWCVtrQ== +"@eslint/eslintrc@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== + dependencies: + "@nodelib/fs.stat" "2.0.4" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + dependencies: + "@nodelib/fs.scandir" "2.1.4" + fastq "^1.6.0" "@tcgdex/sdk@^2.2.0-beta": version "2.2.0-beta" resolved "https://registry.yarnpkg.com/@tcgdex/sdk/-/sdk-2.2.0-beta.tgz#7fd9708ab438d839f31d3ba929da4e8a74376bf7" @@ -34,6 +90,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/json-schema@^7.0.7": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + "@types/minimatch@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" @@ -67,16 +128,147 @@ "@types/node" "*" "@types/ssh2-streams" "*" +"@typescript-eslint/eslint-plugin@^4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz#12bbd6ebd5e7fabd32e48e1e60efa1f3554a3242" + integrity sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg== + dependencies: + "@typescript-eslint/experimental-utils" "4.26.0" + "@typescript-eslint/scope-manager" "4.26.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + lodash "^4.17.21" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.0.tgz#ba7848b3f088659cdf71bce22454795fc55be99a" + integrity sha512-TH2FO2rdDm7AWfAVRB5RSlbUhWxGVuxPNzGT7W65zVfl8H/WeXTk1e69IrcEVsBslrQSTDKQSaJD89hwKrhdkw== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.26.0" + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/typescript-estree" "4.26.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.0.tgz#31b6b732c9454f757b020dab9b6754112aa5eeaf" + integrity sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg== + dependencies: + "@typescript-eslint/scope-manager" "4.26.0" + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/typescript-estree" "4.26.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.0.tgz#60d1a71df162404e954b9d1c6343ff3bee496194" + integrity sha512-G6xB6mMo4xVxwMt5lEsNTz3x4qGDt0NSGmTBNBPJxNsrTXJSm21c6raeYroS2OwQsOyIXqKZv266L/Gln1BWqg== + dependencies: + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/visitor-keys" "4.26.0" + +"@typescript-eslint/types@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.0.tgz#7c6732c0414f0a69595f4f846ebe12616243d546" + integrity sha512-rADNgXl1kS/EKnDr3G+m7fB9yeJNnR9kF7xMiXL6mSIWpr3Wg5MhxyfEXy/IlYthsqwBqHOr22boFbf/u6O88A== + +"@typescript-eslint/typescript-estree@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.0.tgz#aea17a40e62dc31c63d5b1bbe9a75783f2ce7109" + integrity sha512-GHUgahPcm9GfBuy3TzdsizCcPjKOAauG9xkz9TR8kOdssz2Iz9jRCSQm6+aVFa23d5NcSpo1GdHGSQKe0tlcbg== + dependencies: + "@typescript-eslint/types" "4.26.0" + "@typescript-eslint/visitor-keys" "4.26.0" + 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@4.26.0": + version "4.26.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.0.tgz#26d2583169222815be4dcd1da4fe5459bc3bcc23" + integrity sha512-cw4j8lH38V1ycGBbF+aFiLUls9Z0Bw8QschP3mkth50BbWzgFS33ISIgBzUMuQ2IdahoEv/rXstr8Zhlz4B1Zg== + dependencies: + "@typescript-eslint/types" "4.26.0" + eslint-visitor-keys "^2.0.0" + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" + integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + asn1@~0.2.0: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -84,6 +276,11 @@ asn1@~0.2.0: dependencies: safer-buffer "~2.1.0" +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -109,11 +306,64 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -131,6 +381,27 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -141,11 +412,228 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.27.0: + version "7.27.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.27.0.tgz#665a1506d8f95655c9274d84bd78f7166b07e9c7" + integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.1" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + form-data@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" @@ -160,6 +648,30 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +glob-parent@^5.0.0, glob-parent@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -172,6 +684,65 @@ glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globals@^13.6.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -185,6 +756,33 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + isomorphic-unfetch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" @@ -193,11 +791,87 @@ isomorphic-unfetch@^3.1.0: node-fetch "^2.6.1" unfetch "^4.2.0" +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + mime-db@1.47.0: version "1.47.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" @@ -217,6 +891,16 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -229,16 +913,137 @@ once@^1.3.0: dependencies: wrappy "1" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver@^7.2.1, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + source-map-support@^0.5.17: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" @@ -252,6 +1057,11 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + ssh2-streams@~0.4.10: version "0.4.10" resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34" @@ -273,6 +1083,65 @@ streamsearch@~0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= +string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + ts-node@^9.1.1: version "9.1.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" @@ -285,11 +1154,40 @@ ts-node@^9.1.1: source-map-support "^0.5.17" yn "3.1.1" +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + tweetnacl@^0.14.3: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + typescript@^4.2.3: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" @@ -300,11 +1198,40 @@ unfetch@^4.2.0: resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"