diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..abffba4 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +node_modules +dist +examples +scripts +tests/env +coverage diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..a8d61dc --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,61 @@ +module.exports = { + env: { + browser: true, + es6: true, + es2020: true, + 'jest/globals': true, + node: true, + jasmine: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:prettier/recommended', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2019, + project: ['tsconfig.eslint.json'], + sourceType: 'module', + projectFolderIgnoreList: ['dist'], + }, + plugins: ['@typescript-eslint', 'prettier', 'jest'], + rules: { + 'no-dupe-class-members': 'off', // Off due to conflict with typescript overload functions + 'prettier/prettier': [ + 'error', + { + singleQuote: true, + arrowParens: 'always', + semi: false, + bracketSpacing: true, + trailingComma: 'es5', + tsdoc: true, + printWidth: 80, + }, + ], + '@typescript-eslint/array-type': ['warn', { default: 'array-simple' }], + '@typescript-eslint/return-await': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/member-delimiter-style': [ + 'error', + { + multiline: { + delimiter: 'none', // 'none' or 'semi' or 'comma' + requireLast: true, + }, + singleline: { + delimiter: 'semi', // 'semi' or 'comma' + requireLast: false, + }, + }, + ], + 'comma-dangle': 'off', + '@typescript-eslint/ban-ts-ignore': 'off', + '@typescript-eslint/no-misused-promises': ['off'], + '@typescript-eslint/no-unsafe-member-access': ['off'], + '@typescript-eslint/no-unsafe-argument': 'off', + }, +} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..d77df03 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,40 @@ +name: Tests + +on: + pull_request: + push: + # trying and staging branches are for BORS config + branches: + - trying + - staging + - main + +jobs: + lint_tests: + runs-on: ubuntu-latest + name: lint tests + steps: + - uses: actions/checkout@v3 + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'yarn' + - name: Install dependencies + run: yarn + - name: Run JS/TS linter + run: yarn lint + build_test: + runs-on: ubuntu-latest + name: types-check + steps: + - uses: actions/checkout@v3 + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'yarn' + - name: Install dependencies + run: yarn + - name: Build project + run: yarn build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3ae0bf6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Run linting tests + +```sh +yarn lint # to test +yarn lint:fix # to fix errors +``` + diff --git a/package.json b/package.json index cb939a2..b1fe7d7 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,11 @@ "yargs": "^17.7.2" }, "scripts": { + "build": "tsc", "start": "tsc && node dist/src/index.js", "serve": "tsc && node dist/src/server.js", + "lint": "eslint .", + "lint:fix": "eslint . --fix", "test": "echo \"Error: oops, the actor has no tests yet, sad!\" && exit 1" }, "author": "It's not you it's me", @@ -29,6 +32,12 @@ "@types/prettier": "^2.7.3", "@types/uuid": "^9.0.2", "@types/yargs": "^17.0.24", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint": "^8.43.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-jest": "^27.2.2", + "eslint-plugin-prettier": "^4.2.1", "typescript": "^5.1.3" } } diff --git a/src/crawler.ts b/src/crawler.ts index 69094d9..3e91f68 100644 --- a/src/crawler.ts +++ b/src/crawler.ts @@ -1,14 +1,20 @@ -import { createPuppeteerRouter, PuppeteerCrawler, Router, PuppeteerCrawlingContext } from "crawlee"; -import { minimatch } from "minimatch"; -import DefaultScraper from "./scrapers/default.js"; -import DocsearchScraper from "./scrapers/docsearch.js"; -import CustomScraper from "./scrapers/custom.js"; -import SchemaScraper from "./scrapers/schema.js"; -import { Sender } from "./sender.js"; -import { Config, Scraper } from "./types.js"; - - -type DefaultHandler = Parameters['addDefaultHandler']>[0]>[0] +import { + createPuppeteerRouter, + PuppeteerCrawler, + Router, + PuppeteerCrawlingContext, +} from 'crawlee' +import { minimatch } from 'minimatch' +import DefaultScraper from './scrapers/default.js' +import DocsearchScraper from './scrapers/docsearch.js' +import CustomScraper from './scrapers/custom.js' +import SchemaScraper from './scrapers/schema.js' +import { Sender } from './sender.js' +import { Config, Scraper } from './types.js' + +type DefaultHandler = Parameters< + Parameters['addDefaultHandler']>[0] +>[0] // Crawler class // This class is responsible for crawling the urls and extract content to send to Meilisearch @@ -23,26 +29,26 @@ export default class Crawler { crawler: PuppeteerCrawler constructor(sender: Sender, config: Config) { - console.info("Crawler::constructor"); - this.sender = sender; - this.config = config; - this.urls = config.crawled_urls; - this.custom_crawler = config.custom_crawler; + console.info('Crawler::constructor') + this.sender = sender + this.config = config + this.urls = config.crawled_urls + this.custom_crawler = config.custom_crawler // init the custome scraper depending on if config.strategy is docsearch, custom or default this.scraper = - config.strategy == "docsearch" + config.strategy == 'docsearch' ? new DocsearchScraper(this.sender) - : config.strategy == "custom" + : config.strategy == 'custom' ? new CustomScraper(this.sender, config) - : config.strategy == "schema" + : config.strategy == 'schema' ? new SchemaScraper(this.sender, config) - : new DefaultScraper(this.sender, config); + : new DefaultScraper(this.sender, config) //Create the router - let router = createPuppeteerRouter(); + const router = createPuppeteerRouter() // type DefaultHandler = Parameters[0]; - router.addDefaultHandler(this.defaultHandler.bind(this)); + router.addDefaultHandler(this.defaultHandler.bind(this)) // create the crawler this.crawler = new PuppeteerCrawler({ @@ -51,31 +57,31 @@ export default class Crawler { launchContext: { launchOptions: { headless: config.headless || true, - args: ["--no-sandbox", "--disable-setuid-sandbox"], - ignoreDefaultArgs: ["--disable-extensions"], + args: ['--no-sandbox', '--disable-setuid-sandbox'], + ignoreDefaultArgs: ['--disable-extensions'], }, }, - }); + }) } async run() { - await this.crawler.run(this.urls); + await this.crawler.run(this.urls) } // Should we use `log` - async defaultHandler({ request , enqueueLinks, page }: DefaultHandler ) { - const title = await page.title(); - console.log(`${title}`, { url: request.loadedUrl }); - const crawled_globs = this.__generate_globs(this.urls); + async defaultHandler({ request, enqueueLinks, page }: DefaultHandler) { + const title = await page.title() + console.log(`${title}`, { url: request.loadedUrl }) + const crawled_globs = this.__generate_globs(this.urls) const excluded_crawled_globs = this.__generate_globs( this.config.exclude_crawled_urls || [] - ); + ) const indexed_globs = this.__generate_globs( this.config.indexed_urls || this.urls - ); + ) const excluded_indexed_globs = this.__generate_globs( this.config.exclude_indexed_urls || [] - ); + ) if (request.loadedUrl && !this.__is_paginated_url(request.loadedUrl)) { //check if the url is in the list of urls to scrap @@ -83,7 +89,7 @@ export default class Crawler { this.__match_globs(request.loadedUrl, indexed_globs) && !this.__match_globs(request.loadedUrl, excluded_indexed_globs) ) { - await this.scraper.get(request.loadedUrl, page); + await this.scraper.get(request.loadedUrl, page) } } @@ -93,78 +99,78 @@ export default class Crawler { transformRequestFunction: (req) => { // exclude all links that are files not parsable by puppeteer if (this.__is_file_url(req.url)) { - return false; + return false } // remove all query params to avoid duplicates - const urlObject = new URL(req.url); - urlObject.search = ""; - req.url = urlObject.toString(); + const urlObject = new URL(req.url) + urlObject.search = '' + req.url = urlObject.toString() - return req; + return req }, - }); + }) } __generate_globs(urls: string[]) { return urls.map((url) => { - if (url.endsWith("/")) { - return url + "**"; + if (url.endsWith('/')) { + return url + '**' } - return url + "/**"; - }); + return url + '/**' + }) } __match_globs(url: string, globs: string[]) { - return globs.some((glob) => minimatch(url, glob)); + return globs.some((glob) => minimatch(url, glob)) } __is_file_url(url: string) { const fileExtensions = [ - ".zip", - ".pdf", - ".doc", - ".docx", - ".xls", - ".xlsx", - ".ppt", - ".pptx", - ".rar", - ".tar", - ".gz", - ".tgz", - ".7z", - ".bz2", - ".jpg", - ".jpeg", - ".png", - ".gif", - ".svg", - ".css", - ".js", - ".xml", - ".txt", - ".csv", - ".rtf", - ".mp3", - ".wav", - ".mp4", - ".avi", - ".mkv", - ".mov", - ".flv", - ".wmv", - ".m4v", - ".ogg", - ".mpg", - ".mpeg", - ".swf", - ]; - return fileExtensions.some((extension) => url.endsWith(extension)); + '.zip', + '.pdf', + '.doc', + '.docx', + '.xls', + '.xlsx', + '.ppt', + '.pptx', + '.rar', + '.tar', + '.gz', + '.tgz', + '.7z', + '.bz2', + '.jpg', + '.jpeg', + '.png', + '.gif', + '.svg', + '.css', + '.js', + '.xml', + '.txt', + '.csv', + '.rtf', + '.mp3', + '.wav', + '.mp4', + '.avi', + '.mkv', + '.mov', + '.flv', + '.wmv', + '.m4v', + '.ogg', + '.mpg', + '.mpeg', + '.swf', + ] + return fileExtensions.some((extension) => url.endsWith(extension)) } __is_paginated_url(url: string) { - const urlObject = new URL(url); - const pathname = urlObject.pathname; - return /\/\d+\//.test(pathname); + const urlObject = new URL(url) + const pathname = urlObject.pathname + return /\/\d+\//.test(pathname) } } diff --git a/src/crawler_process.ts b/src/crawler_process.ts index 5075c1b..d286112 100644 --- a/src/crawler_process.ts +++ b/src/crawler_process.ts @@ -1,21 +1,21 @@ -import { Sender } from "./sender.js"; -import Crawler from "./crawler.js"; -import { Config } from "./types.js"; +import { Sender } from './sender.js' +import Crawler from './crawler.js' +import { Config } from './types.js' async function startCrawling(config: Config) { - const sender = new Sender(config); - await sender.init(); + const sender = new Sender(config) + await sender.init() - const crawler = new Crawler(sender, config); + const crawler = new Crawler(sender, config) - await crawler.run(); - await sender.finish(); + await crawler.run() + await sender.finish() } // Listen for messages from the parent thread -process.on("message", async (message: Config) => { - await startCrawling(message); +process.on('message', async (message: Config) => { + await startCrawling(message) if (process.send) { - process.send("Crawling finished"); + process.send('Crawling finished') } -}); +}) diff --git a/src/index.ts b/src/index.ts index b674b0f..053829b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,26 +1,29 @@ -import * as dotenv from "dotenv"; -dotenv.config(); +import * as dotenv from 'dotenv' +dotenv.config() -import fs from "fs"; -import yargs from "yargs"; -import { hideBin } from "yargs/helpers"; -import { Sender } from "./sender.js"; -import Crawler from "./crawler.js"; +import fs from 'fs' +import yargs from 'yargs' +import { hideBin } from 'yargs/helpers' +import { Sender } from './sender.js' +import Crawler from './crawler.js' +import { Config } from './types.js' // Parse command line arguments and get a configuration file path -const argv = await yargs(hideBin(process.argv)).option("config", { - alias: "c", - describe: "Path to configuration file", +const argv = await yargs(hideBin(process.argv)).option('config', { + alias: 'c', + describe: 'Path to configuration file', demandOption: true, - type: "string", -}).argv; + type: 'string', +}).argv -const config = JSON.parse(fs.readFileSync(argv.config, {encoding: 'utf-8'})); +const config: Config = JSON.parse( + fs.readFileSync(argv.config, { encoding: 'utf-8' }) +) as Config -const sender = new Sender(config); -await sender.init(); +const sender = new Sender(config) +await sender.init() -const crawler = new Crawler(sender, config); +const crawler = new Crawler(sender, config) -await crawler.run(); -await sender.finish(); +await crawler.run() +await sender.finish() diff --git a/src/scrapers/custom.js b/src/scrapers/custom.js index a19bbe8..8491974 100644 --- a/src/scrapers/custom.js +++ b/src/scrapers/custom.js @@ -1,46 +1,47 @@ +/* eslint-disable */ // TODO: file should be removed -import prettier from "prettier"; -import { v4 as uuidv4 } from "uuid"; +import prettier from 'prettier' +import { v4 as uuidv4 } from 'uuid' export default class CustomScaper { constructor(sender, config) { - console.info("CustomScaper::constructor"); - this.sender = sender; - this.config = config; + console.info('CustomScaper::constructor') + this.sender = sender + this.config = config if (config.custom_settings) { - this.sender.updateSettings(config.custom_settings); + this.sender.updateSettings(config.custom_settings) } } async get(url, page) { - let data = {}; + let data = {} if (this.custom_crawler.get_title || false) { - data.title = await page.title(); + data.title = await page.title() } - data.uid = uuidv4(); + data.uid = uuidv4() if (this.custom_crawler.get_meta || false) { const meta = await page.evaluate(() => { - const metas = document.getElementsByTagName("meta"); - const meta = {}; + const metas = document.getElementsByTagName('meta') + const meta = {} for (let i = 0; i < metas.length; i++) { - const name = metas[i].getAttribute("name"); - const content = metas[i].getAttribute("content"); + const name = metas[i].getAttribute('name') + const content = metas[i].getAttribute('content') if (name && content) { - meta[name] = content; + meta[name] = content } } - return meta; - }); - data.meta = meta; + return meta + }) + data.meta = meta } if (this.custom_crawler.get_url || false) { - data.url = url; + data.url = url } - await this.sender.add(data); + await this.sender.add(data) } } diff --git a/src/scrapers/default.ts b/src/scrapers/default.ts index b03c13c..f36776a 100644 --- a/src/scrapers/default.ts +++ b/src/scrapers/default.ts @@ -1,140 +1,143 @@ -import prettier from "prettier"; -import { v4 as uuidv4 } from "uuid"; -import { Sender } from "../sender"; -import { Config, Meta } from "../types"; -import { Page } from "puppeteer"; -import { DefaultData } from "../types"; - +import prettier from 'prettier' +import { v4 as uuidv4 } from 'uuid' +import { Sender } from '../sender' +import { Config, Meta } from '../types' +import { Page } from 'puppeteer' +import { DefaultData } from '../types' export default class DefaultScraper { - sender: Sender; - settings: Config["custom_settings"]; + sender: Sender + settings: Config['custom_settings'] constructor(sender: Sender, config: Config) { - console.info("DefaultScraper::constructor"); - this.sender = sender; + console.info('DefaultScraper::constructor') + this.sender = sender this.settings = config.custom_settings || { searchableAttributes: [ - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "p", - "title", - "meta.description", + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'p', + 'title', + 'meta.description', ], - filterableAttributes: ["urls_tags"], - distinctAttribute: "url", - }; - this.sender.updateSettings(this.settings); + filterableAttributes: ['urls_tags'], + distinctAttribute: 'url', + } + void this.sender.updateSettings(this.settings) } async get(url: string, page: Page) { - const title = await page.title(); + const title = await page.title() //get the meta of the page - const meta = await this._extract_metadata_from_page(page); + const meta = await this._extract_metadata_from_page(page) //for each page create dataset of consecutive h1, h2, h3, p. at each header after a paragraph, create a new dataset - let data: DefaultData = {} as DefaultData; + let data: DefaultData = {} as DefaultData let elems = await page.$$( - "main h1, main h2, main h3, main h4, main h5, main h6, main p, main td, main li, main span" - ); + 'main h1, main h2, main h3, main h4, main h5, main h6, main p, main td, main li, main span' + ) if (elems.length === 0) { - elems = await page.$$("h1, h2, h3, h4, h5, h6, p, td, li, span"); + elems = await page.$$('h1, h2, h3, h4, h5, h6, p, td, li, span') } - let page_block = 0; + let page_block = 0 for (let i = 0; i < elems.length; i++) { - let elem = elems[i]; - let tag = await elem.evaluate((el) => el.tagName); - let text = await elem.evaluate((el) => el.textContent) || ''; - text = this._clean_text(text); - data.uid = uuidv4(); - data.url = url; - data.title = title; - data.meta = meta; - data.image_url = this._get_image_url_from_meta(meta); - data.page_block = page_block; - let urls_tags = new URL(url).pathname.split("/"); - data.urls_tags = urls_tags.slice(1, urls_tags.length - 1); + const elem = elems[i] + const tag = await elem.evaluate((el) => el.tagName) + let text = (await elem.evaluate((el) => el.textContent)) || '' + text = this._clean_text(text) + data.uid = uuidv4() + data.url = url + data.title = title + data.meta = meta + data.image_url = this._get_image_url_from_meta(meta) + data.page_block = page_block + const urls_tags = new URL(url).pathname.split('/') + data.urls_tags = urls_tags.slice(1, urls_tags.length - 1) - let id = await elem.evaluate((el) => el.id); - if (tag === "H1") { - if (data["h1"]) { - await this.sender.add(data); - page_block++; - data = {} as DefaultData; + const id = await elem.evaluate((el) => el.id) + if (tag === 'H1') { + if (data['h1']) { + await this.sender.add(data) + page_block++ + data = {} as DefaultData } - data["h1"] = text; - data.anchor = "#" + id; - } else if (tag === "H2") { - if (data["h2"]) { - await this.sender.add(data); - page_block++; - data = { h1: data["h1"] } as DefaultData; + data['h1'] = text + data.anchor = '#' + id + } else if (tag === 'H2') { + if (data['h2']) { + await this.sender.add(data) + page_block++ + data = { h1: data['h1'] } as DefaultData } - data.anchor = "#" + id; - data["h2"] = text; - } else if (tag === "H3") { - if (data["h3"]) { - await this.sender.add(data); - page_block++; - data = { h1: data["h1"], h2: data["h2"] } as DefaultData; + data.anchor = '#' + id + data['h2'] = text + } else if (tag === 'H3') { + if (data['h3']) { + await this.sender.add(data) + page_block++ + data = { h1: data['h1'], h2: data['h2'] } as DefaultData } - data.anchor = "#" + id; - data["h3"] = text; - } else if (tag === "H4") { - if (data["h4"]) { - await this.sender.add(data); - page_block++; - data = { h1: data["h1"], h2: data["h2"], h3: data["h3"] } as DefaultData; + data.anchor = '#' + id + data['h3'] = text + } else if (tag === 'H4') { + if (data['h4']) { + await this.sender.add(data) + page_block++ + data = { + h1: data['h1'], + h2: data['h2'], + h3: data['h3'], + } as DefaultData } - data.anchor = "#" + id; - data["h4"] = text; - } else if (tag === "H5") { - if (data["h5"]) { - await this.sender.add(data); - page_block++; + data.anchor = '#' + id + data['h4'] = text + } else if (tag === 'H5') { + if (data['h5']) { + await this.sender.add(data) + page_block++ data = { - h1: data["h1"], - h2: data["h2"], - h3: data["h3"], - h4: data["h4"], - } as DefaultData; + h1: data['h1'], + h2: data['h2'], + h3: data['h3'], + h4: data['h4'], + } as DefaultData } - data.anchor = "#" + id; - data["h5"] = text; - } else if (tag === "H6") { - if (data["h6"]) { - await this.sender.add(data); - page_block++; + data.anchor = '#' + id + data['h5'] = text + } else if (tag === 'H6') { + if (data['h6']) { + await this.sender.add(data) + page_block++ data = { - h1: data["h1"], - h2: data["h2"], - h3: data["h3"], - h4: data["h4"], - h5: data["h5"], - } as DefaultData; + h1: data['h1'], + h2: data['h2'], + h3: data['h3'], + h4: data['h4'], + h5: data['h5'], + } as DefaultData } - data.anchor = "#" + id; - data["h6"] = text; + data.anchor = '#' + id + data['h6'] = text } else if ( - tag === "P" || - tag === "TD" || - tag === "LI" || - tag === "SPAN" + tag === 'P' || + tag === 'TD' || + tag === 'LI' || + tag === 'SPAN' ) { - if (!data["p"]) { - data["p"] = []; + if (!data['p']) { + data['p'] = [] } // TODO: should we leave `null` values in the `p` array? - if (text && !data["p"].includes(text)) { - data["p"].push(text); + if (text && !data['p'].includes(text)) { + data['p'].push(text) } } if (i === elems.length - 1) { - await this.sender.add(data); + await this.sender.add(data) } } } @@ -142,72 +145,71 @@ export default class DefaultScraper { // Remove from a text all multiple spaces, new lines, and leading and trailing spaces, and // remove '# ' from the beginning of the text _clean_text(text: string) { - text = text.replace(/[\r\n]+/gm, " "); + text = text.replace(/[\r\n]+/gm, ' ') ///remove multiple spaces - text = text.replace(/\s+/g, " "); + text = text.replace(/\s+/g, ' ') ///remove '# ' - text = text.replace("# ", ""); + text = text.replace('# ', '') /// Trim leading and trailing spaces - text = text.replace(/^\s+|\s+$/g, ""); - return text; + text = text.replace(/^\s+|\s+$/g, '') + return text } - // Extract the meta of a page async _extract_metadata_from_page(page: Page) { return await page.evaluate(() => { - const metas = document.getElementsByTagName("meta"); - const meta: Meta = {} as Meta; + const metas = document.getElementsByTagName('meta') + const meta: Meta = {} as Meta for (let i = 0; i < metas.length; i++) { - const name = metas[i].getAttribute("name"); - const content = metas[i].getAttribute("content"); + const name = metas[i].getAttribute('name') + const content = metas[i].getAttribute('content') if (name && content) { - meta[name] = content; + meta[name] = content } } - return meta; - }); + return meta + }) } // Extract the image url from the meta of a page _get_image_url_from_meta(meta: Meta) { - if (meta["og:image"]) { - return meta["og:image"]; - } else if (meta["twitter:image"]) { - return meta["twitter:image"]; - } else if (meta["image"]) { - return meta["image"]; + if (meta['og:image']) { + return meta['og:image'] + } else if (meta['twitter:image']) { + return meta['twitter:image'] + } else if (meta['image']) { + return meta['image'] } - return; + return } // A function that retro-engineer the hljs generated html to extract the code async _extract_code_from_page(page: Page) { - let code = await page.evaluate(() => { - let code = ""; - let pre = document.getElementsByTagName("pre"); + const code = await page.evaluate(() => { + let code = '' + const pre = document.getElementsByTagName('pre') for (let i = 0; i < pre.length; i++) { - let code_elem = pre[i].getElementsByTagName("code"); + const code_elem = pre[i].getElementsByTagName('code') if (code_elem.length > 0) { - code += code_elem[0].innerText; + code += code_elem[0].innerText } } - return code; - }); - return this._format_code(code); + return code + }) + return this._format_code(code) } // A function that use prettier to format the code that has been extracted in a html page. // Format only if the language is supported by prettier _format_code(code: string) { - let formatted_code = ""; + let formatted_code = '' try { formatted_code = prettier.format(code, { - parser: "babel", - }); + parser: 'babel', + }) } catch (e) { - console.log("Error while formatting code", e); - return code; + console.log('Error while formatting code', e) + return code } - return formatted_code; + return formatted_code } } diff --git a/src/scrapers/docsearch.ts b/src/scrapers/docsearch.ts index f18c95d..898057a 100644 --- a/src/scrapers/docsearch.ts +++ b/src/scrapers/docsearch.ts @@ -1,126 +1,125 @@ -import { v4 as uuidv4 } from "uuid"; -import { Sender } from "../sender"; -import { Page } from "puppeteer"; -import { DocsSearchData } from "../types"; +import { v4 as uuidv4 } from 'uuid' +import { Sender } from '../sender' +import { Page } from 'puppeteer' +import { DocsSearchData } from '../types' export default class DocsearchScaper { - sender: Sender; + sender: Sender - // constructor(sender: Sender) { - console.info("DocsearchScaper::constructor"); - this.sender = sender; + console.info('DocsearchScaper::constructor') + this.sender = sender - this.sender.updateSettings({ + void this.sender.updateSettings({ searchableAttributes: [ - "hierarchy_lvl0", - "hierarchy_lvl1", - "hierarchy_lvl2", - "hierarchy_lvl3", - "hierarchy_lvl4", - "hierarchy_lvl5", - "content", + 'hierarchy_lvl0', + 'hierarchy_lvl1', + 'hierarchy_lvl2', + 'hierarchy_lvl3', + 'hierarchy_lvl4', + 'hierarchy_lvl5', + 'content', ], - }); + }) } async get(url: string, page: Page) { //for each page create dataset of consecutive h1, h2, h3, p. at each header after a paragraph, create a new dataset - let data = {} as DocsSearchData; + let data = {} as DocsSearchData let elems = await page.$$( - "main h1, main h2, main h3, main h4, main h5, main p, main td, main li, main span" - ); + 'main h1, main h2, main h3, main h4, main h5, main p, main td, main li, main span' + ) if (elems.length === 0) { - elems = await page.$$("h1, h2, h3, h4, h5, p, td, li, span"); + elems = await page.$$('h1, h2, h3, h4, h5, p, td, li, span') } - let page_block = 0; + let page_block = 0 // TODO: why is this usefull? for (let i = 0; i < elems.length; i++) { - let elem = elems[i]; - let tag = await elem.evaluate((el) => el.tagName); - let text = await elem.evaluate((el) => el.textContent) || ''; - text = this._clean_text(text); - data.uid = uuidv4(); - data.url = url; - let urls_tags = new URL(url).pathname.split("/"); - let only_urls_tags = urls_tags.slice(1, urls_tags.length - 1); - data.hierarchy_lvl0 = only_urls_tags[0]; + const elem = elems[i] + const tag = await elem.evaluate((el) => el.tagName) + let text = (await elem.evaluate((el) => el.textContent)) || '' + text = this._clean_text(text) + data.uid = uuidv4() + data.url = url + const urls_tags = new URL(url).pathname.split('/') + const only_urls_tags = urls_tags.slice(1, urls_tags.length - 1) + data.hierarchy_lvl0 = only_urls_tags[0] - let id = await elem.evaluate((el) => el.id); - if (tag === "H1") { - if (data["hierarchy_lvl1"]) { - await this.sender.add(data); - page_block++; - data = {} as DocsSearchData; + const id = await elem.evaluate((el) => el.id) + if (tag === 'H1') { + if (data['hierarchy_lvl1']) { + await this.sender.add(data) + page_block++ + data = {} as DocsSearchData } - data["hierarchy_lvl1"] = text; - data.anchor = "#" + id; - } else if (tag === "H2") { - if (data["hierarchy_lvl2"]) { - await this.sender.add(data); - page_block++; - data = { hierarchy_lvl1: data["hierarchy_lvl1"] } as DocsSearchData; + data['hierarchy_lvl1'] = text + data.anchor = '#' + id + } else if (tag === 'H2') { + if (data['hierarchy_lvl2']) { + await this.sender.add(data) + page_block++ + data = { hierarchy_lvl1: data['hierarchy_lvl1'] } as DocsSearchData } - data.anchor = "#" + id; - data["hierarchy_lvl2"] = text; - } else if (tag === "H3") { - if (data["hierarchy_lvl3"]) { - await this.sender.add(data); - page_block++; + data.anchor = '#' + id + data['hierarchy_lvl2'] = text + } else if (tag === 'H3') { + if (data['hierarchy_lvl3']) { + await this.sender.add(data) + page_block++ data = { - hierarchy_lvl1: data["hierarchy_lvl1"], - hierarchy_lvl2: data["hierarchy_lvl2"], - } as DocsSearchData; + hierarchy_lvl1: data['hierarchy_lvl1'], + hierarchy_lvl2: data['hierarchy_lvl2'], + } as DocsSearchData } - data.anchor = "#" + id; - data["hierarchy_lvl3"] = text; - } else if (tag === "H4") { - if (data["hierarchy_lvl4"]) { - await this.sender.add(data); - page_block++; + data.anchor = '#' + id + data['hierarchy_lvl3'] = text + } else if (tag === 'H4') { + if (data['hierarchy_lvl4']) { + await this.sender.add(data) + page_block++ data = { - hierarchy_lvl1: data["hierarchy_lvl1"], - hierarchy_lvl2: data["hierarchy_lvl2"], - hierarchy_lvl3: data["hierarchy_lvl3"], - } as DocsSearchData; + hierarchy_lvl1: data['hierarchy_lvl1'], + hierarchy_lvl2: data['hierarchy_lvl2'], + hierarchy_lvl3: data['hierarchy_lvl3'], + } as DocsSearchData } - data.anchor = "#" + id; - data["hierarchy_lvl4"] = text; - } else if (tag === "H5") { - if (data["hierarchy_lvl5"]) { - await this.sender.add(data); - page_block++; + data.anchor = '#' + id + data['hierarchy_lvl4'] = text + } else if (tag === 'H5') { + if (data['hierarchy_lvl5']) { + await this.sender.add(data) + page_block++ data = { - hierarchy_lvl1: data["hierarchy_lvl1"], - hierarchy_lvl2: data["hierarchy_lvl2"], - hierarchy_lvl3: data["hierarchy_lvl3"], - hierarchy_lvl4: data["hierarchy_lvl4"], - } as DocsSearchData; + hierarchy_lvl1: data['hierarchy_lvl1'], + hierarchy_lvl2: data['hierarchy_lvl2'], + hierarchy_lvl3: data['hierarchy_lvl3'], + hierarchy_lvl4: data['hierarchy_lvl4'], + } as DocsSearchData } - data.anchor = "#" + id; - data["hierarchy_lvl5"] = text; + data.anchor = '#' + id + data['hierarchy_lvl5'] = text } else if ( - tag === "P" || - tag === "TD" || - tag === "LI" || - tag === "SPAN" + tag === 'P' || + tag === 'TD' || + tag === 'LI' || + tag === 'SPAN' ) { - if (!data["content"]) { - data["content"] = []; + if (!data['content']) { + data['content'] = [] } - if (text !== null && !data["content"].includes(text)) { - data["content"].push(text); + if (text !== null && !data['content'].includes(text)) { + data['content'].push(text) } } if (i === elems.length - 1) { - data.hierarchy_radio_lvl0 = null; - data.hierarchy_radio_lvl1 = data.hierarchy_lvl1; - data.hierarchy_radio_lvl2 = data.hierarchy_lvl2; - data.hierarchy_radio_lvl3 = data.hierarchy_lvl3; - data.hierarchy_radio_lvl4 = data.hierarchy_lvl4; - data.hierarchy_radio_lvl5 = data.hierarchy_lvl5; - data.url = data.url + "#" + data.anchor; - data.anchor = data.anchor.substring(1); - await this.sender.add(data); + data.hierarchy_radio_lvl0 = null + data.hierarchy_radio_lvl1 = data.hierarchy_lvl1 + data.hierarchy_radio_lvl2 = data.hierarchy_lvl2 + data.hierarchy_radio_lvl3 = data.hierarchy_lvl3 + data.hierarchy_radio_lvl4 = data.hierarchy_lvl4 + data.hierarchy_radio_lvl5 = data.hierarchy_lvl5 + data.url = data.url + '#' + data.anchor + data.anchor = data.anchor.substring(1) + await this.sender.add(data) } } } @@ -128,13 +127,13 @@ export default class DocsearchScaper { // Remove from a text all multiple spaces, new lines, and leading and trailing spaces, and // remove '# ' from the beginning of the text _clean_text(text: string) { - text = text.replace(/[\r\n]+/gm, " "); + text = text.replace(/[\r\n]+/gm, ' ') ///remove multiple spaces - text = text.replace(/\s+/g, " "); + text = text.replace(/\s+/g, ' ') ///remove '# ' - text = text.replace("# ", ""); + text = text.replace('# ', '') /// Trim leading and trailing spaces - text = text.replace(/^\s+|\s+$/g, ""); - return text; + text = text.replace(/^\s+|\s+$/g, '') + return text } } diff --git a/src/scrapers/schema.ts b/src/scrapers/schema.ts index 6bc7c88..6a16246 100644 --- a/src/scrapers/schema.ts +++ b/src/scrapers/schema.ts @@ -1,74 +1,76 @@ -import { v4 as uuidv4 } from "uuid"; -import { Page } from "puppeteer"; -import { Sender } from "../sender"; -import { Config, SchemaData } from "../types"; +import { v4 as uuidv4 } from 'uuid' +import { Page } from 'puppeteer' +import { Sender } from '../sender' +import { Config, SchemaData } from '../types' export default class SchemaScaper { - sender: Sender; - config: Config; - settings_sent: boolean; + sender: Sender + config: Config + settings_sent: boolean constructor(sender: Sender, config: Config) { - console.info("SchemaScaper::constructor"); - this.sender = sender; - this.config = config; - this.settings_sent = false; + console.info('SchemaScaper::constructor') + this.sender = sender + this.config = config + this.settings_sent = false if (this.config.custom_settings) { - this.sender.updateSettings(this.config.custom_settings); - this.settings_sent = true; + void this.sender.updateSettings(this.config.custom_settings) + this.settings_sent = true } } async get(url: string, page: Page) { - console.log("__extractContent", url); + console.log('__extractContent', url) // Get the schema.org data - const data = await page.evaluate(() => { + const data = (await page.evaluate((): Record => { const schema = document.querySelector( "script[type='application/ld+json']" - ); + ) if (schema) { - return JSON.parse(schema.innerText); + return JSON.parse(schema.innerText) as Record } - return {}; - }); + return {} // TODO: raise error + })) as SchemaData - if (data.length === 0) return; + // TODO: use zod here instead of forcing `as SchemaData`? + + if (data.length === 0) return if (this.config.schema?.only_type) { - if (data["@type"] !== this.config.schema?.only_type) return; + if (data['@type'] !== this.config.schema?.only_type) return } - this._clean_schema(data); + this._clean_schema(data) if (this.config.schema?.convert_dates) { // convert dates to timestamps Object.keys(data).forEach((key) => { - if (typeof data[key] === "string") { + if (typeof data[key] === 'string') { // check if it is a date if (Date.parse(data[key])) { - data[key] = Date.parse(data[key]); + data[key] = Date.parse(data[key]) } } - }); + }) } - data.uid = uuidv4(); + data.uid = uuidv4() - await this.sender.add(data); + await this.sender.add(data) } _clean_schema(data: SchemaData) { - if (data["@context"]) { - delete data["@context"]; + if (data['@context']) { + delete data['@context'] } - if (data["@type"]) { - delete data["@type"]; + if (data['@type']) { + delete data['@type'] } Object.keys(data).forEach((key) => { - if (typeof data[key] === "object") { - this._clean_schema(data[key]); + if (typeof data[key] === 'object') { + this._clean_schema(data[key]) } - }); + }) } } diff --git a/src/sender.ts b/src/sender.ts index 25dd70f..88aa102 100644 --- a/src/sender.ts +++ b/src/sender.ts @@ -1,116 +1,116 @@ -import { MeiliSearch, Settings } from "meilisearch"; -import { Config, DocsSearchData, DefaultData } from "./types"; +import { MeiliSearch, Settings } from 'meilisearch' +import { Config, DocsSearchData, DefaultData, SchemaData } from './types' //Create a class called Sender that will queue the json data and batch it to a Meilisearch instance export class Sender { config: Config - queue: Array + queue: Array origin_index_name: string index_name: string batch_size: number client: MeiliSearch constructor(config: Config) { - console.info("Sender::constructor"); - this.queue = []; - this.config = config; - this.origin_index_name = config.meilisearch_index_name; - this.index_name = this.origin_index_name; - this.batch_size = config.batch_size || 100; + console.info('Sender::constructor') + this.queue = [] + this.config = config + this.origin_index_name = config.meilisearch_index_name + this.index_name = this.origin_index_name + this.batch_size = config.batch_size || 100 //Create a Meilisearch client this.client = new MeiliSearch({ host: config.meilisearch_host, apiKey: config.meilisearch_api_key, - }); + }) } async init() { - console.log("Sender::init"); + console.log('Sender::init') try { - const index = await this.client.getIndex(this.origin_index_name); + const index = await this.client.getIndex(this.origin_index_name) if (index) { - this.index_name = this.origin_index_name + "_tmp"; + this.index_name = this.origin_index_name + '_tmp' - const tmp_index = await this.client.getIndex(this.index_name); + const tmp_index = await this.client.getIndex(this.index_name) if (tmp_index) { - const task = await this.client.deleteIndex(this.index_name); - await this.client.waitForTask(task.taskUid); + const task = await this.client.deleteIndex(this.index_name) + await this.client.waitForTask(task.taskUid) } } } catch (e) { - console.log("try to delete a tmp index if it exists"); + console.log('try to delete a tmp index if it exists') } if (this.config.primary_key) { try { await this.client .index(this.index_name) - .update({ primaryKey: this.config.primary_key }); + .update({ primaryKey: this.config.primary_key }) } catch (e) { - console.log("try to create or update the index with the primary key"); + console.log('try to create or update the index with the primary key') await this.client.createIndex(this.index_name, { primaryKey: this.config.primary_key, - }); + }) } } } //Add a json object to the queue - async add(data: DocsSearchData | DefaultData) { - console.log("Sender::add"); + async add(data: DocsSearchData | DefaultData | SchemaData) { + console.log('Sender::add') if (this.config.primary_key) { - delete data["uid"]; + delete data['uid'] } if (this.batch_size) { - this.queue.push(data); + this.queue.push(data) if (this.queue.length >= this.batch_size) { - await this.__batchSend(); + await this.__batchSend() } } else { - await this.client.index(this.index_name).addDocuments([data]); + await this.client.index(this.index_name).addDocuments([data]) } } async updateSettings(settings: Settings) { - console.log("Sender::updateSettings"); - let task = await this.client + console.log('Sender::updateSettings') + const task = await this.client .index(this.index_name) - .updateSettings(settings); - await this.client.waitForTask(task.taskUid); + .updateSettings(settings) + await this.client.waitForTask(task.taskUid) } async finish() { - console.log("Sender::finish"); + console.log('Sender::finish') if (this.index_name !== this.origin_index_name) { - await this.__batchSend(); + await this.__batchSend() // If the new index have more than 0 document we swap the index - const index = await this.client.getIndex(this.index_name); - const stats = await index.getStats(); - console.log("stats", stats); + const index = await this.client.getIndex(this.index_name) + const stats = await index.getStats() + console.log('stats', stats) if (stats.numberOfDocuments > 0) { - await this.__swapIndex(); + await this.__swapIndex() } } } async __batchSend() { - console.log("Sender::__batchSend - size:" + this.queue.length); + console.log(`Sender::__batchSend - size: ${this.queue.length}`) const task = await this.client .index(this.index_name) - .addDocuments(this.queue); - this.queue = []; - await this.client.waitForTask(task.taskUid); + .addDocuments(this.queue) + this.queue = [] + await this.client.waitForTask(task.taskUid) } async __swapIndex() { - console.log("Sender::__swapIndex"); - let task = await this.client.swapIndexes([ + console.log('Sender::__swapIndex') + const task = await this.client.swapIndexes([ { indexes: [this.origin_index_name, this.index_name] }, - ]); - await this.client.index(this.index_name).waitForTask(task.taskUid); + ]) + await this.client.index(this.index_name).waitForTask(task.taskUid) } } diff --git a/src/server.ts b/src/server.ts index d9bd0f4..688c46c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,46 +1,46 @@ -import * as dotenv from "dotenv"; -dotenv.config(); +import * as dotenv from 'dotenv' +dotenv.config() -import express from "express"; -import TaskQueue from "./taskQueue.js"; -import { Sender } from "./sender.js"; -import Crawler from "./crawler.js"; +import express from 'express' +import TaskQueue from './taskQueue.js' +import { Sender } from './sender.js' +import Crawler from './crawler.js' -const port = process.env.PORT || 3000; +const port = process.env.PORT || 3000 class Server { - taskQueue: TaskQueue; - app: express.Application; + taskQueue: TaskQueue + app: express.Application constructor() { - this.taskQueue = new TaskQueue(); - this.app = express(); - this.app.use(express.json()); - this.app.post("/crawl", this.__crawl.bind(this)); - this.app.post("/crawl/async", this.__crawl.bind(this)); - this.app.post("/crawl/sync", this.__syncCrawl.bind(this)); + this.taskQueue = new TaskQueue() + this.app = express() + this.app.use(express.json()) + this.app.post('/crawl', this.__crawl.bind(this)) + this.app.post('/crawl/async', this.__crawl.bind(this)) + this.app.post('/crawl/sync', this.__syncCrawl.bind(this)) this.app.listen(port, () => console.log(`Example app listening on port ${port}!`) - ); + ) } - async __crawl(req: express.Request, res: express.Response) { - this.taskQueue.add(req.body); - console.log("Crawling started"); - res.send("Crawling started"); + __crawl(req: express.Request, res: express.Response) { + this.taskQueue.add(req.body) + console.log('Crawling started') + res.send('Crawling started') } async __syncCrawl(req: express.Request, res: express.Response) { - const sender = new Sender(req.body); - await sender.init(); + const sender = new Sender(req.body) + await sender.init() - const crawler = new Crawler(sender, req.body); + const crawler = new Crawler(sender, req.body) - await crawler.run(); - await sender.finish(); - res.send("Crawling finished"); + await crawler.run() + await sender.finish() + res.send('Crawling finished') } } -new Server(); +new Server() diff --git a/src/taskQueue.ts b/src/taskQueue.ts index 65b81c5..2608012 100644 --- a/src/taskQueue.ts +++ b/src/taskQueue.ts @@ -1,83 +1,82 @@ -import Queue, { Job, DoneCallback } from "bull"; -import { MeiliSearch } from "meilisearch"; -import { fork } from "child_process"; -import { Config } from "./types"; +import Queue, { Job, DoneCallback } from 'bull' +import { MeiliSearch } from 'meilisearch' +import { fork } from 'child_process' +import { Config } from './types' -const redis_url = process.env.REDIS_URL; +const redis_url = process.env.REDIS_URL export default class TaskQueue { - queue: Queue.Queue; + queue: Queue.Queue constructor() { - console.info("TaskQueue::constructor"); + console.info('TaskQueue::constructor') console.log(redis_url) - if (redis_url ) { - this.queue = new Queue("crawling", redis_url); + if (redis_url) { + this.queue = new Queue('crawling', redis_url) + } else { + this.queue = new Queue('crawling') } - else { - this.queue = new Queue("crawling"); - } - this.queue.process(this.__process.bind(this)); - this.queue.on("added", this.__jobAdded.bind(this)); - this.queue.on("completed", this.__jobCompleted.bind(this)); - this.queue.on("failed", this.__jobFailed.bind(this)); - this.queue.on("active", this.__jobActive.bind(this)); - this.queue.on("wait", this.__jobWaiting.bind(this)); - this.queue.on("delayed", this.__jobDelayed.bind(this)); + void this.queue.process(this.__process.bind(this)) + this.queue.on('added', this.__jobAdded.bind(this)) + this.queue.on('completed', this.__jobCompleted.bind(this)) + this.queue.on('failed', this.__jobFailed.bind(this)) + this.queue.on('active', this.__jobActive.bind(this)) + this.queue.on('wait', this.__jobWaiting.bind(this)) + this.queue.on('delayed', this.__jobDelayed.bind(this)) } add(data: Config) { - this.queue.add(data); + void this.queue.add(data) } - async __process(job: Job, done: DoneCallback) { - console.log("Job process", job.id); - const childProcess = fork("./dist/src/crawler_process.js"); - childProcess.send(job.data); - childProcess.on("message", (message) => { - console.log(message); - done(); - }); + __process(job: Job, done: DoneCallback) { + console.log('Job process', job.id) + const childProcess = fork('./dist/src/crawler_process.js') + childProcess.send(job.data) + childProcess.on('message', (message) => { + console.log(message) + done() + }) } - async __jobAdded(job: Job) { - console.log("Job added", job.id); + __jobAdded(job: Job) { + console.log('Job added', job.id) } - async __jobCompleted(job: Job) { - console.log("Job completed", job.id); + __jobCompleted(job: Job) { + console.log('Job completed', job.id) } - async __jobFailed(job: Job) { - console.log("Job failed", job.id); - let client = new MeiliSearch({ + async __jobFailed(job: Job) { + console.log('Job failed', job.id) + const client = new MeiliSearch({ host: job.data.meilisearch_host, apiKey: job.data.meilisearch_api_key, - }); + }) //check if the tmp index exists - const tmp_index_name = job.data.meilisearch_index_name + "_tmp"; + const tmp_index_name = job.data.meilisearch_index_name + '_tmp' try { - const index = await client.getIndex(tmp_index_name); + const index = await client.getIndex(tmp_index_name) if (index) { - const task = await client.deleteIndex(tmp_index_name); - await client.waitForTask(task.taskUid); + const task = await client.deleteIndex(tmp_index_name) + await client.waitForTask(task.taskUid) } } catch (e) { - console.error(e); + console.error(e) } } - async __jobActive(job: Job) { + __jobActive(job: Job) { console.log({ job }) - console.log("Job active", job.id); + console.log('Job active', job.id) } - async __jobWaiting(job: Job) { - console.log("Job waiting", job.id); + __jobWaiting(job: Job) { + console.log('Job waiting', job.id) } - async __jobDelayed(job: Job) { - console.log("Job delayed", job.id); + __jobDelayed(job: Job) { + console.log('Job delayed', job.id) } } diff --git a/src/types.ts b/src/types.ts index 1effafd..c2432fe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,8 +1,8 @@ -import { Settings } from "meilisearch"; -import DocsearchScraper from "./scrapers/docsearch"; -import DefaultScraper from "./scrapers/default"; -import CustomScraper from "./scrapers/custom"; -import SchemaScraper from "./scrapers/schema"; +import { Settings } from 'meilisearch' +import DocsearchScraper from './scrapers/docsearch' +import DefaultScraper from './scrapers/default' +import CustomScraper from './scrapers/custom' +import SchemaScraper from './scrapers/schema' export type Config = { meilisearch_index_name: string @@ -20,7 +20,6 @@ export type Config = { indexed_urls?: string[] exclude_indexed_urls?: string[] schema?: SchemaConfig - } export type SchemaConfig = { @@ -28,7 +27,13 @@ export type SchemaConfig = { only_type: string } -export type Scraper = DocsearchScraper | DefaultScraper | CustomScraper | SchemaScraper +export type Scraper = + | DocsearchScraper + | DefaultScraper + | CustomScraper + | SchemaScraper + +export type DocumentTypes = DocsSearchData | DefaultData | SchemaData export type DocsSearchData = { url: string @@ -47,7 +52,6 @@ export type DocsSearchData = { hierarchy_radio_lvl3: string | null hierarchy_radio_lvl4: string | null hierarchy_radio_lvl5: string | null - } export type DefaultData = { @@ -71,9 +75,8 @@ export type DefaultData = { export type SchemaData = { uid: string [key: string]: any - } export type Meta = { - [name: string]: string; + [name: string]: string } diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 0000000..bc5cc00 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,12 @@ +{ + // extend your base config so you don't have to redefine your compilerOptions + "extends": "./tsconfig.json", + "compilerOptions": { + "allowJs": false, + "module": "esnext", + }, + "include": [ + "src/**/*.ts", + ".eslintrc.cjs" + ] +} diff --git a/yarn.lock b/yarn.lock index c00eaac..64e5876 100644 --- a/yarn.lock +++ b/yarn.lock @@ -315,6 +315,57 @@ ow "^0.28.1" tslib "^2.4.0" +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.43.0": + version "8.43.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" + integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@ioredis/commands@^1.1.1": version "1.2.0" resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" @@ -350,6 +401,27 @@ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz#0f164b726869f71da3c594171df5ebc1c4b0a407" integrity sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@puppeteer/browsers@1.4.1": version "1.4.1" resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.4.1.tgz#9c8ba163c3ef77ae3fc9708ad1f5787263f7290e" @@ -442,6 +514,11 @@ "@types/tough-cookie" "*" parse5 "^7.0.0" +"@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" @@ -479,6 +556,11 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + "@types/send@*": version "0.17.1" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" @@ -524,6 +606,90 @@ dependencies: "@types/node" "*" +"@typescript-eslint/eslint-plugin@^5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz#2f4bea6a3718bed2ba52905358d0f45cd3620d31" + integrity sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/type-utils" "5.60.0" + "@typescript-eslint/utils" "5.60.0" + debug "^4.3.4" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.0.tgz#08f4daf5fc6548784513524f4f2f359cebb4068a" + integrity sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ== + dependencies: + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/typescript-estree" "5.60.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz#ae511967b4bd84f1d5e179bb2c82857334941c1c" + integrity sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ== + dependencies: + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/visitor-keys" "5.60.0" + +"@typescript-eslint/type-utils@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz#69b09087eb12d7513d5b07747e7d47f5533aa228" + integrity sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g== + dependencies: + "@typescript-eslint/typescript-estree" "5.60.0" + "@typescript-eslint/utils" "5.60.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.0.tgz#3179962b28b4790de70e2344465ec97582ce2558" + integrity sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA== + +"@typescript-eslint/typescript-estree@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz#4ddf1a81d32a850de66642d9b3ad1e3254fb1600" + integrity sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ== + dependencies: + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/visitor-keys" "5.60.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.60.0", "@typescript-eslint/utils@^5.10.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.0.tgz#4667c5aece82f9d4f24a667602f0f300864b554c" + integrity sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/typescript-estree" "5.60.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz#b48b29da3f5f31dd1656281727004589d2722a66" + integrity sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw== + dependencies: + "@typescript-eslint/types" "5.60.0" + eslint-visitor-keys "^3.3.0" + "@vladfrangu/async_event_emitter@^2.0.0": version "2.2.2" resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz#84c5a3f8d648842cec5cc649b88df599af32ed88" @@ -542,6 +708,11 @@ accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + acorn-walk@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" @@ -552,6 +723,11 @@ acorn@^8.7.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.8.0: + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + adm-zip@^0.5.9: version "0.5.10" resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.10.tgz#4a51d5ab544b1f5ce51e1b9043139b639afff45b" @@ -571,6 +747,16 @@ agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +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" + ansi-colors@^4.1.1, ansi-colors@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" @@ -622,6 +808,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +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== + ast-types@^0.13.2: version "0.13.4" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" @@ -681,6 +872,14 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" @@ -688,6 +887,13 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +braces@^3.0.2: + 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" + browserslist@^4.21.1: version "4.21.8" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.8.tgz#db2498e1f4b80ed199c076248a094935860b6017" @@ -786,7 +992,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0, chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -920,6 +1126,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -985,6 +1196,15 @@ cross-fetch@3.1.6, cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.11" +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" + css-select@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" @@ -1039,7 +1259,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1063,7 +1283,7 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -1120,6 +1340,20 @@ devtools-protocol@0.0.1135028: resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1135028.tgz#b2c667c301cb6da9ba3ed0989fe1fb88b660ee0a" integrity sha512-jEcNGrh6lOXNRJvZb9RjeevtZGrgugPKSMJZxfyxWQnhlKawMPhMtk/dfC+Z/6xNXExlzTKlY5LzIAK/fRpQIw== +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" + dom-serializer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" @@ -1228,6 +1462,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +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== + escape-string-regexp@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" @@ -1245,16 +1484,129 @@ escodegen@^1.8.1: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + +eslint-plugin-jest@^27.2.2: + version "27.2.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.2.tgz#be4ded5f91905d9ec89aa8968d39c71f3b072c0c" + integrity sha512-euzbp06F934Z7UDl5ZUaRPLAc9MKjh0rMPERrHT7UhlCEwgb25kBj37TvMgWeHZVkR5I9CayswrpoaqZU1RImw== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + +eslint-plugin-prettier@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +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-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.43.0: + version "8.43.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" + integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.43.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -estraverse@^4.2.0: +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + 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, estraverse@^4.2.0: 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.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -1335,16 +1687,44 @@ extract-zip@2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -fast-deep-equal@^3.1.3: +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-levenshtein@~2.0.6: +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +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, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -1372,6 +1752,20 @@ figures@^5.0.0: escape-string-regexp "^5.0.0" is-unicode-supported "^1.2.0" +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" + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" @@ -1393,6 +1787,14 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + fingerprint-generator@^2.0.6, fingerprint-generator@^2.1.30: version "2.1.30" resolved "https://registry.yarnpkg.com/fingerprint-generator/-/fingerprint-generator-2.1.30.tgz#8d7ae69e878524ac2cf2dab61f05f633b784ce05" @@ -1410,6 +1812,19 @@ fingerprint-injector@^2.0.5: fingerprint-generator "^2.1.30" tslib "^2.4.0" +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.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + form-data-encoder@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" @@ -1462,6 +1877,11 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -1517,6 +1937,51 @@ get-uri@^6.0.1: debug "^4.3.4" fs-extra "^8.1.0" +glob-parent@^5.1.2: + 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-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + got-cjs@12.5.4: version "12.5.4" resolved "https://registry.yarnpkg.com/got-cjs/-/got-cjs-12.5.4.tgz#b46419c0e8e5fb5503b926941807408049ae2e11" @@ -1553,6 +2018,16 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1705,7 +2180,12 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -import-fresh@^3.2.1: +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +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== @@ -1721,7 +2201,20 @@ import-local@^3.1.0: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1803,21 +2296,43 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + 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, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +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== + is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -1833,6 +2348,11 @@ is-unicode-supported@^1.2.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + jquery@^3.6.0: version "3.7.0" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.0.tgz#fe2c01a05da500709006d8790fe21c8a39d75612" @@ -1889,6 +2409,16 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +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-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 sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -1917,6 +2447,14 @@ keyv@^4.0.0: dependencies: json-buffer "3.0.1" +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" + levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1948,6 +2486,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -2025,11 +2570,24 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -2062,6 +2620,13 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimatch@^9.0.0, minimatch@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" @@ -2130,6 +2695,16 @@ nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -2186,7 +2761,7 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" -once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -2212,6 +2787,18 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" +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" + ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" @@ -2255,7 +2842,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.1.0: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -2269,6 +2856,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2343,6 +2937,16 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +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 sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +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-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -2370,6 +2974,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -2377,11 +2986,23 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +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== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + prettier@^2.8.4: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -2448,7 +3069,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.1, punycode@^2.3.0: +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== @@ -2486,6 +3107,11 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +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== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -2579,6 +3205,18 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== +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" + rrweb-cssom@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" @@ -2594,6 +3232,13 @@ run-async@^3.0.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== +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" + rxjs@^7.5.5, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" @@ -2625,6 +3270,13 @@ semver@^7.3.2: dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.5.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" + integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== + dependencies: + lru-cache "^6.0.0" + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -2659,6 +3311,18 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +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== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -2673,6 +3337,11 @@ signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -2766,6 +3435,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +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@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -2811,6 +3485,11 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -2840,6 +3519,13 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +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" + toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" @@ -2867,11 +3553,30 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +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== + tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0: version "2.5.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +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" + +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-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -2879,6 +3584,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +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.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -2943,6 +3653,13 @@ update-browserslist-db@^1.0.11: escalade "^3.1.1" picocolors "^1.0.0" +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" + url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" @@ -3041,7 +3758,14 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -word-wrap@~1.2.3: +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, 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==