diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a0270fb --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules +dist \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..2e0bab8 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,31 @@ +module.exports = { + plugins: ["prettier", "import"], + extends: ["airbnb-base", "prettier", "plugin:import/recommended"], + env: { + node: true, + jest: true, + }, + rules: { + "prettier/prettier": "error", + "max-len": [ + "error", + { + code: 120, + comments: 120, + tabWidth: 4, + ignoreUrls: false, + ignoreTrailingComments: false, + ignoreComments: false, + }, + ], + indent: [ + "error", + 4, + { + SwitchCase: 1, + }, + ], + "import/extensions": 0, + "import/no-extraneous-dependencies": 0, + }, +}; diff --git a/.husky/pre-commit b/.husky/pre-commit index bfc028b..3117a0b 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" +yarn lint yarn test diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index c61da12..0000000 --- a/.prettierrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "tabWidth": 4, - "endOfLine": "lf", - "printWidth": 120, - "singleQuote": false -} diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..baee980 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,6 @@ +module.exports = { + tabWidth: 4, + endOfLine: "lf", + printWidth: 120, + singleQuote: false, +}; diff --git a/package.json b/package.json index 4ac8212..f177a37 100644 --- a/package.json +++ b/package.json @@ -45,13 +45,20 @@ "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.2.1", + "eslint": "^8.34.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^4.2.1", "husky": "^8.0.0", "jest": "^29.3.1", + "prettier": "^2.8.4", "rollup": "^3.8.1", "rollup-plugin-node-externals": "^5.0.3" }, "scripts": { "prepare": "husky install", + "lint": "eslint .", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "build": "yarn rollup --config rollup.config.js" } diff --git a/rollup.config.js b/rollup.config.js index 635e107..fde4a48 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,91 +1,112 @@ -import resolve from "@rollup/plugin-node-resolve"; -import commonjs from "@rollup/plugin-commonjs"; -import externals from "rollup-plugin-node-externals"; -import alias from "@rollup/plugin-alias"; -import { getBabelOutputPlugin } from "@rollup/plugin-babel"; -import terser from "@rollup/plugin-terser"; -import json from "@rollup/plugin-json"; - -// CommonJS build -const cjs = { - input: "./src/index.js", - output: [ - { - file: `./dist/ecsstree.cjs`, - format: "cjs", - exports: "auto", - sourcemap: false, - }, - ], - plugins: [json(), externals(), commonjs({ sourceMap: false }), resolve({ preferBuiltins: false })], -}; - -// ECMAScript build -const esm = { - input: "./src/index.js", - output: [ - { - file: `./dist/ecsstree.esm.js`, - format: "esm", - sourcemap: false, - }, - ], - plugins: [json(), externals(), commonjs({ sourceMap: false }), resolve({ preferBuiltins: false })], -}; - -const browserPlugins = [ - json(), - commonjs({ sourceMap: false }), - resolve({ preferBuiltins: false, browser: true }), - alias({ - entries: [ - { - find: "css-tree", - replacement: "node_modules/css-tree/dist/csstree.esm.js", - }, - ], - }), - getBabelOutputPlugin({ - presets: [ - [ - "@babel/preset-env", - { - targets: ["> 1%", "not dead"], - }, - ], - ], - allowAllFormats: true, - }), - terser(), -]; - -// Browser-friendly UMD build -const umd = { - input: "./src/index.js", - output: [ - { - file: `./dist/ecsstree.umd.min.js`, - name: "ECSSTree", - format: "umd", - sourcemap: false, - }, - ], - plugins: browserPlugins, -}; - -// Browser-friendly IIFE build -const iife = { - input: "./src/index.js", - output: [ - { - file: `./dist/ecsstree.iife.min.js`, - name: "ECSSTree", - format: "iife", - sourcemap: false, - }, - ], - plugins: browserPlugins, -}; - -// Export build configs for Rollup -export default [cjs, esm, umd, iife]; +/* eslint-disable prettier/prettier */ +import alias from "@rollup/plugin-alias"; +import commonjs from "@rollup/plugin-commonjs"; +import externals from "rollup-plugin-node-externals"; +import json from "@rollup/plugin-json"; +import resolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import { getBabelOutputPlugin } from "@rollup/plugin-babel"; + +const commonPlugins = [ + json(), + commonjs({ sourceMap: false }), +]; + +// CommonJS build +const cjs = { + input: "./src/index.js", + output: [ + { + file: "./dist/ecsstree.cjs", + format: "cjs", + exports: "auto", + sourcemap: false, + }, + ], + plugins: [ + ...commonPlugins, + externals(), + resolve({ preferBuiltins: false }) + ], +}; + +// ECMAScript build +const esm = { + input: "./src/index.js", + output: [ + { + file: "./dist/ecsstree.esm.js", + format: "esm", + sourcemap: false, + }, + ], + plugins: [ + ...commonPlugins, + externals(), + resolve({ preferBuiltins: false }), + ], +}; + +const browserPlugins = [ + ...commonPlugins, + resolve({ + preferBuiltins: false, + browser: true + }), + alias({ + entries: [ + { + find: "css-tree", + replacement: "node_modules/css-tree/dist/csstree.esm.js", + }, + ], + }), + getBabelOutputPlugin({ + presets: [ + [ + "@babel/preset-env", + { + targets: ["> 1%", "not dead"], + }, + ], + ], + allowAllFormats: true, + }), + terser(), +]; + +// Browser-friendly UMD build +const umd = { + input: "./src/index.js", + output: [ + { + file: "./dist/ecsstree.umd.min.js", + name: "ECSSTree", + format: "umd", + sourcemap: false, + }, + ], + plugins: browserPlugins, +}; + +// Browser-friendly IIFE build +const iife = { + input: "./src/index.js", + output: [ + { + file: "./dist/ecsstree.iife.min.js", + name: "ECSSTree", + format: "iife", + sourcemap: false, + }, + ], + plugins: browserPlugins, +}; + +// Export build configs for Rollup +export default [ + cjs, + esm, + umd, + iife +]; diff --git a/src/index.js b/src/index.js index da1d05e..2d37e8e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,40 +1,40 @@ -import syntax from "./syntax/index.js"; - -// Fork API doesn't export everything, so we need to export the rest of -// the API manually. See the original source code: -// https://github.com/csstree/csstree/blob/master/lib/index.js - -export * from "./version.js"; - -export { - createSyntax, - List, - Lexer, - tokenTypes, - tokenNames, - TokenStream, - definitionSyntax, - clone, - ident, - string, - url, -} from "css-tree"; - -// Export the forked syntax (comes from the Fork API) -export const { - tokenize, - parse, - generate, - lexer, - createLexer, - - walk, - find, - findLast, - findAll, - - toPlainObject, - fromPlainObject, - - fork, -} = syntax; +import syntax from "./syntax/index.js"; + +// Fork API doesn't export everything, so we need to export the rest of +// the API manually. See the original source code: +// https://github.com/csstree/csstree/blob/master/lib/index.js + +export { default as version } from "./version.js"; + +export { + createSyntax, + List, + Lexer, + tokenTypes, + tokenNames, + TokenStream, + definitionSyntax, + clone, + ident, + string, + url, +} from "css-tree"; + +// Export the forked syntax (comes from the Fork API) +export const { + tokenize, + parse, + generate, + lexer, + createLexer, + + walk, + find, + findLast, + findAll, + + toPlainObject, + fromPlainObject, + + fork, +} = syntax; diff --git a/src/syntax/index.js b/src/syntax/index.js index 9baeb53..60f9c9c 100644 --- a/src/syntax/index.js +++ b/src/syntax/index.js @@ -1,341 +1,341 @@ -/** - * CSSTree syntax fork for "Adblock Extended CSS" syntax. - * - * This library supports various CSS extensions from AdGuard and uBlock Origin. - * - * @see {@link https://github.com/AdguardTeam/ExtendedCss} - * @see {@link https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters} - */ - -import { fork, tokenize, tokenTypes } from "css-tree"; -import { CLOSING_PARENTHESIS, DOUBLE_QUOTE, ESCAPE, OPENING_PARENTHESIS, SPACE } from "../utils/constants.js"; - -const CONTAINS_PSEUDO_CLASSES = ["contains(", "-abp-contains(", "has-text("]; - -const selector = { - parse() { - return this.createSingleNodeList(this.Selector()); - }, -}; - -const selectorList = { - parse() { - return this.createSingleNodeList(this.SelectorList()); - }, -}; - -const mediaQueryList = { - parse() { - return this.createSingleNodeList(this.MediaQueryList()); - }, -}; - -const numberOrSelector = { - parse() { - return this.createSingleNodeList(this.parseWithFallback(this.Number, this.Selector)); - }, -}; - -const number = { - parse() { - return this.createSingleNodeList(this.Number()); - }, -}; - -const style = { - parse() { - // Empty style - if (this.tokenType === tokenTypes.RightParenthesis) { - this.error("No style specified"); - } - - // Create a list for children - const children = this.createList(); - - // Get the current token's balance from the token stream. Balance pair map allows - // to determinate when the current function ends. - const balance = this.balance[this.tokenIndex]; - - // In order to avoid infinite loop we also need to track the current token index - while (this.balance[this.tokenIndex] === balance && this.tokenIndex < this.tokenCount) { - switch (this.tokenType) { - // Skip whitespaces, comments and semicolons - case tokenTypes.WhiteSpace: - case tokenTypes.Comment: - case tokenTypes.Semicolon: - this.next(); - break; - - // At this point we can assume that we have a declaration - default: - children.push( - // Parse declaration with fallback to Raw node - this.parseWithFallback(this.Declaration, (startToken) => { - // Parse until the next semicolon (this handles if we have multiple declarations in the - // same style, so we not parse all of them as a single Raw rule because of this) - return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true); - }) - ); - } - } - - // Create a DeclarationList node - const declarationList = { - type: "DeclarationList", - loc: this.getLocationFromList(children), - children, - }; - - return this.createSingleNodeList(declarationList); - }, -}; - -const extCssContains = { - /** - * Adblock Extended CSS allows using contains() without quote marks, so the tokenization maybe - * turns wrong at this point. - * - * Here is an example why and how it can happen. Let's assume that the input is - * ```css - * :contains(aaa'bbb) - * ``` - * - * The tokenizer will tokenize it as - * : colon-token - * contains( function-token - * aaa ident-token - * 'bbb) string-token - * - * So, at quote mark (') tokenizer will think that a string is starting, and it tokenizes - * the rest of the input as a string. This is the normal behavior for the tokenizer, but - * it is wrong for us, since the parser will fail with an ")" is expected error, because - * it cannot find the closing balance pair for the opening parenthesis. So, we need to - * fix the token stream here to avoid this error. - */ - parse() { - // Get the current token stream - const tokens = this.dump(); - - // Note: CSSTree removes the whitespace token after the function name before calling this function - // So if we have :contains( something), our tokenIndex here points to "something" and not to the - // whitespace token. - - // :contains() case, but not :contains( something) case, so we check if the previous token is not a whitespace - if (this.tokenType === tokenTypes.RightParenthesis && tokens[this.tokenIndex - 1].type !== "whitespace-token") { - this.error("Empty parameter specified"); - } - - // Find the "real" start position of the contains() function's argument - let startPosition = -1; - - // Save the current position within the token stream (we will need to restore it later) - let prevTokenIndex = this.tokenIndex; - - for (let i = this.tokenIndex; i >= 0; i--) { - // Check token name to avoid :contains(join('')) case, where join( is also a function token - if (tokens[i].type === "function-token" && CONTAINS_PSEUDO_CLASSES.includes(tokens[i].chunk)) { - // Token after the function name is the first token of the argument - startPosition = this.getTokenStart(i + 1); - prevTokenIndex = i + 1; - break; - } - } - - // Theoretically, this should never happen, but we check it anyway - if (startPosition === -1) { - this.error("Cannot find the start position of the contains() function's argument"); - } - - // Create a list for children - const children = this.createList(); - - // Find the real end index of the contains() function's argument - const sourceCode = this.source; - - let endPosition = -1; - - // Parenthesis balance - let balance = 0; - - // Contains can contain any character, such as parentheses, quotes, etc, - // so a bit tricky to find the end position of the pseudo-class - for (let i = startPosition; i < sourceCode.length; i++) { - const char = sourceCode[i]; - - if (char === OPENING_PARENTHESIS && sourceCode[i - 1] !== ESCAPE) { - balance++; - } else if (char === CLOSING_PARENTHESIS && sourceCode[i - 1] !== ESCAPE) { - balance--; - - if (balance === -1) { - endPosition = i; - break; - } - } - } - - // If we cannot find the closing parenthesis, we cannot fix the token stream, so we - // just return the children list as is. In this case, the parser will fail with an - // error (which is correct behavior). - if (endPosition === -1) { - return children; - } - - // Empty parameter - if (endPosition === startPosition) { - this.error('No parameter specified for "contains()" pseudo-class'); - } - - // Push content to children list - children.push({ - type: "Raw", - // Give positions, if enabled (CSSTree will handle it) - loc: this.getLocation(startPosition, endPosition), - value: sourceCode.substring(startPosition, endPosition), - }); - - // Create a new source code, where fill the contains() function's argument with whitespaces, - // but keep the length of the source code the same. This will fix the token stream, so the - // parser will not fail with an error, and positions remain the same. - const newSourceCode = - sourceCode.substring(0, startPosition) + - new Array(endPosition - startPosition + 1).join(SPACE) + - sourceCode.substring(endPosition); - - // Modify the parsed source code. This will reset the token stream, so we need to restore - // the position within the token stream later. - // Theoretically this "trick" doesn't cause problems, because we parsed the argument of the - // contains() function as a Raw node, so we don't need to parse it again, but the parser will - // continue its work from the correct position. - this.setSource(newSourceCode, tokenize); - - // Restore the position within the token stream. - while (this.tokenIndex < prevTokenIndex) { - this.next(); - } - - // CSSTree will skip insterted whitespaces - - // Return the children list which contains the contains() function's argument as a Raw node - return children; - }, -}; - -const xpath = { - parse() { - // Empty pseudo-class - if (this.tokenType === tokenTypes.RightParenthesis) { - this.error('No parameter specified for "xpath()" pseudo-class'); - } - - // Create a list for children - const children = this.createList(); - - // Save the current position within the token stream (we will need to restore it later) - const prevTokenIndex = this.tokenIndex; - - // Find the real end index of the xpath() function's argument - const sourceCode = this.source; - - const startPosition = this.getTokenStart(this.tokenIndex); - - // Find the end of the xpath() function's argument. It is a quite complex task, because - // the argument can contain any characters, including parentheses, quotes, etc. - // We will use a simple heuristic: checking parentheses balance. Maybe not the best - // solution, but it works in most cases. - let endPosition = -1; - - // Parentheses balance - let balance = 0; - - // Whether we are inside a string - let inString = false; - - // Iterate over the corresponding part of the source code - for (let i = startPosition; i < sourceCode.length; i++) { - if (sourceCode[i] == DOUBLE_QUOTE && sourceCode[i - 1] != ESCAPE) { - inString = !inString; - } - - // If we are inside a string, we don't care about parentheses - if (inString) { - continue; - } - - // Check parentheses balance - if (sourceCode[i] == OPENING_PARENTHESIS) { - balance++; - } else if (sourceCode[i] == CLOSING_PARENTHESIS) { - balance--; - - // If the parentheses balance is -1, it means that we have found the closing, - // because this closing breaks the parentheses balance, which means it is not - // belongs to the xpath expression. - if (balance === -1) { - endPosition = i; - break; - } - } - } - - // If we cannot find the closing parenthesis, we cannot fix the token stream, so we - // just return the children list as is. In this case, the parser will fail with an - // error (which is correct behavior). - if (endPosition === -1) { - return children; - } - - // Push content to children list - children.push({ - type: "Raw", - loc: this.getLocation(startPosition, endPosition), - value: sourceCode.substring(startPosition, endPosition), - }); - - // Create a new source code, where fill the xpath() function's argument with whitespace, - // but keep the length of the source code the same. This will fix the token stream, so the - // parser will not fail with an error, and positions remain consistent. - const newSourceCode = - sourceCode.substring(0, startPosition) + - new Array(endPosition - startPosition + 1).join(SPACE) + - sourceCode.substring(endPosition); - - // Modify the parsed source code. This will reset the token stream, so we need to restore - // the position within the token stream later. - // Theoretically this "trick" doesn't cause problems, because we parsed the argument of the - // xpath() function as a Raw node, so we don't need to parse it again, but the parser will - // continue its work from the correct position. - this.setSource(newSourceCode, tokenize); - - // Restore the position within the token stream. - while (this.tokenIndex < prevTokenIndex) { - this.next(); - } - - // CSSTree will skip insterted whitespaces - - // Return the children list which contains the xpath() function's argument as a Raw node - return children; - }, -}; - -/** - * Extended CSS syntax for css-tree (forked from css-tree) - */ -const extendedCssSyntax = fork({ - pseudo: { - "-abp-has": selectorList, - "if-not": selector, - upward: numberOrSelector, - "nth-ancestor": number, - "min-text-length": number, - "matches-media": mediaQueryList, - style: style, - contains: extCssContains, - "has-text": extCssContains, - "-abp-contains": extCssContains, - xpath: xpath, - }, -}); - -export default extendedCssSyntax; +/** + * CSSTree syntax fork for "Adblock Extended CSS" syntax. + * + * This library supports various CSS extensions from AdGuard and uBlock Origin. + * + * @see {@link https://github.com/AdguardTeam/ExtendedCss} + * @see {@link https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters} + */ + +import { fork, tokenize, tokenTypes } from "css-tree"; +import { CLOSING_PARENTHESIS, DOUBLE_QUOTE, ESCAPE, OPENING_PARENTHESIS, SPACE } from "../utils/constants.js"; + +const CONTAINS_PSEUDO_CLASSES = ["contains(", "-abp-contains(", "has-text("]; + +const selector = { + parse() { + return this.createSingleNodeList(this.Selector()); + }, +}; + +const selectorList = { + parse() { + return this.createSingleNodeList(this.SelectorList()); + }, +}; + +const mediaQueryList = { + parse() { + return this.createSingleNodeList(this.MediaQueryList()); + }, +}; + +const numberOrSelector = { + parse() { + return this.createSingleNodeList(this.parseWithFallback(this.Number, this.Selector)); + }, +}; + +const number = { + parse() { + return this.createSingleNodeList(this.Number()); + }, +}; + +const style = { + parse() { + // Empty style + if (this.tokenType === tokenTypes.RightParenthesis) { + this.error("No style specified"); + } + + // Create a list for children + const children = this.createList(); + + // Get the current token's balance from the token stream. Balance pair map allows + // to determinate when the current function ends. + const balance = this.balance[this.tokenIndex]; + + // In order to avoid infinite loop we also need to track the current token index + while (this.balance[this.tokenIndex] === balance && this.tokenIndex < this.tokenCount) { + switch (this.tokenType) { + // Skip whitespaces, comments and semicolons + case tokenTypes.WhiteSpace: + case tokenTypes.Comment: + case tokenTypes.Semicolon: + this.next(); + break; + + // At this point we can assume that we have a declaration + default: + children.push( + // Parse declaration with fallback to Raw node + // We need arrow function here, because we need to use the current context + // eslint-disable-next-line arrow-body-style + this.parseWithFallback(this.Declaration, (startToken) => { + // Parse until the next semicolon (this handles if we have multiple declarations in the + // same style, so we not parse all of them as a single Raw rule because of this) + return this.Raw(startToken, this.consumeUntilSemicolonIncluded, true); + }) + ); + } + } + + // Create a DeclarationList node + const declarationList = { + type: "DeclarationList", + loc: this.getLocationFromList(children), + children, + }; + + return this.createSingleNodeList(declarationList); + }, +}; + +const extCssContains = { + /** + * Adblock Extended CSS allows using contains() without quote marks, so the tokenization maybe + * turns wrong at this point. + * + * Here is an example why and how it can happen. Let's assume that the input is + * ```css + * :contains(aaa'bbb) + * ``` + * + * The tokenizer will tokenize it as + * : colon-token + * contains( function-token + * aaa ident-token + * 'bbb) string-token + * + * So, at quote mark (') tokenizer will think that a string is starting, and it tokenizes + * the rest of the input as a string. This is the normal behavior for the tokenizer, but + * it is wrong for us, since the parser will fail with an ")" is expected error, because + * it cannot find the closing balance pair for the opening parenthesis. So, we need to + * fix the token stream here to avoid this error. + */ + parse() { + // Get the current token stream + const tokens = this.dump(); + + // Note: CSSTree removes the whitespace token after the function name before calling this function + // So if we have :contains( something), our tokenIndex here points to "something" and not to the + // whitespace token. + + // :contains() case, but not :contains( something) case, so we check if the previous token is not a whitespace + if (this.tokenType === tokenTypes.RightParenthesis && tokens[this.tokenIndex - 1].type !== "whitespace-token") { + this.error("Empty parameter specified"); + } + + // Find the "real" start position of the contains() function's argument + let startPosition = -1; + + // Save the current position within the token stream (we will need to restore it later) + let prevTokenIndex = this.tokenIndex; + + for (let i = this.tokenIndex; i >= 0; i -= 1) { + // Check token name to avoid :contains(join('')) case, where join( is also a function token + if (tokens[i].type === "function-token" && CONTAINS_PSEUDO_CLASSES.includes(tokens[i].chunk)) { + // Token after the function name is the first token of the argument + startPosition = this.getTokenStart(i + 1); + prevTokenIndex = i + 1; + break; + } + } + + // Theoretically, this should never happen, but we check it anyway + if (startPosition === -1) { + this.error("Cannot find the start position of the contains() function's argument"); + } + + // Create a list for children + const children = this.createList(); + + // Find the real end index of the contains() function's argument + const sourceCode = this.source; + + let endPosition = -1; + + // Parenthesis balance + let balance = 0; + + // Contains can contain any character, such as parentheses, quotes, etc, + // so a bit tricky to find the end position of the pseudo-class + for (let i = startPosition; i < sourceCode.length; i += 1) { + const char = sourceCode[i]; + + if (char === OPENING_PARENTHESIS && sourceCode[i - 1] !== ESCAPE) { + balance += 1; + } else if (char === CLOSING_PARENTHESIS && sourceCode[i - 1] !== ESCAPE) { + balance -= 1; + + if (balance === -1) { + endPosition = i; + break; + } + } + } + + // If we cannot find the closing parenthesis, we cannot fix the token stream, so we + // just return the children list as is. In this case, the parser will fail with an + // error (which is correct behavior). + if (endPosition === -1) { + return children; + } + + // Empty parameter + if (endPosition === startPosition) { + this.error('No parameter specified for "contains()" pseudo-class'); + } + + // Push content to children list + children.push({ + type: "Raw", + // Give positions, if enabled (CSSTree will handle it) + loc: this.getLocation(startPosition, endPosition), + value: sourceCode.substring(startPosition, endPosition), + }); + + // Create a new source code, where fill the contains() function's argument with whitespaces, + // but keep the length of the source code the same. This will fix the token stream, so the + // parser will not fail with an error, and positions remain the same. + const newSourceCode = + sourceCode.substring(0, startPosition) + + new Array(endPosition - startPosition + 1).join(SPACE) + + sourceCode.substring(endPosition); + + // Modify the parsed source code. This will reset the token stream, so we need to restore + // the position within the token stream later. + // Theoretically this "trick" doesn't cause problems, because we parsed the argument of the + // contains() function as a Raw node, so we don't need to parse it again, but the parser will + // continue its work from the correct position. + this.setSource(newSourceCode, tokenize); + + // Restore the position within the token stream. + while (this.tokenIndex < prevTokenIndex) { + this.next(); + } + + // CSSTree will skip insterted whitespaces + + // Return the children list which contains the contains() function's argument as a Raw node + return children; + }, +}; + +const xpath = { + parse() { + // Empty pseudo-class + if (this.tokenType === tokenTypes.RightParenthesis) { + this.error('No parameter specified for "xpath()" pseudo-class'); + } + + // Create a list for children + const children = this.createList(); + + // Save the current position within the token stream (we will need to restore it later) + const prevTokenIndex = this.tokenIndex; + + // Find the real end index of the xpath() function's argument + const sourceCode = this.source; + + const startPosition = this.getTokenStart(this.tokenIndex); + + // Find the end of the xpath() function's argument. It is a quite complex task, because + // the argument can contain any characters, including parentheses, quotes, etc. + // We will use a simple heuristic: checking parentheses balance. Maybe not the best + // solution, but it works in most cases. + let endPosition = -1; + + // Parentheses balance + let balance = 0; + + // Whether we are inside a string + let inString = false; + + // Iterate over the corresponding part of the source code + for (let i = startPosition; i < sourceCode.length; i += 1) { + if (sourceCode[i] === DOUBLE_QUOTE && sourceCode[i - 1] !== ESCAPE) { + inString = !inString; + } + + // If we are not inside a string, we can check parentheses balance + if (!inString) { + // Check parentheses balance + if (sourceCode[i] === OPENING_PARENTHESIS) { + balance += 1; + } else if (sourceCode[i] === CLOSING_PARENTHESIS) { + balance -= 1; + + // If the parentheses balance is -1, it means that we have found the closing, + // because this closing breaks the parentheses balance, which means it is not + // belongs to the xpath expression. + if (balance === -1) { + endPosition = i; + break; + } + } + } + } + + // If we cannot find the closing parenthesis, we cannot fix the token stream, so we + // just return the children list as is. In this case, the parser will fail with an + // error (which is correct behavior). + if (endPosition === -1) { + return children; + } + + // Push content to children list + children.push({ + type: "Raw", + loc: this.getLocation(startPosition, endPosition), + value: sourceCode.substring(startPosition, endPosition), + }); + + // Create a new source code, where fill the xpath() function's argument with whitespace, + // but keep the length of the source code the same. This will fix the token stream, so the + // parser will not fail with an error, and positions remain consistent. + const newSourceCode = + sourceCode.substring(0, startPosition) + + new Array(endPosition - startPosition + 1).join(SPACE) + + sourceCode.substring(endPosition); + + // Modify the parsed source code. This will reset the token stream, so we need to restore + // the position within the token stream later. + // Theoretically this "trick" doesn't cause problems, because we parsed the argument of the + // xpath() function as a Raw node, so we don't need to parse it again, but the parser will + // continue its work from the correct position. + this.setSource(newSourceCode, tokenize); + + // Restore the position within the token stream. + while (this.tokenIndex < prevTokenIndex) { + this.next(); + } + + // CSSTree will skip insterted whitespaces + + // Return the children list which contains the xpath() function's argument as a Raw node + return children; + }, +}; + +/** + * Extended CSS syntax for css-tree (forked from css-tree) + */ +const extendedCssSyntax = fork({ + pseudo: { + "-abp-has": selectorList, + "if-not": selector, + upward: numberOrSelector, + "nth-ancestor": number, + "min-text-length": number, + "matches-media": mediaQueryList, + style, + contains: extCssContains, + "has-text": extCssContains, + "-abp-contains": extCssContains, + xpath, + }, +}); + +export default extendedCssSyntax; diff --git a/src/utils/constants.js b/src/utils/constants.js index 561ef37..aafa72c 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -1,7 +1,7 @@ -export const OPENING_PARENTHESIS = '('; -export const CLOSING_PARENTHESIS = ')'; -export const SPACE = ' '; -export const ESCAPE = '\\'; -export const DOUBLE_QUOTE = '"'; -export const SINGLE_QUOTE = "'"; -export const COMMA = ','; +export const OPENING_PARENTHESIS = "("; +export const CLOSING_PARENTHESIS = ")"; +export const SPACE = " "; +export const ESCAPE = "\\"; +export const DOUBLE_QUOTE = '"'; +export const SINGLE_QUOTE = "'"; +export const COMMA = ","; diff --git a/src/version.js b/src/version.js index 72e3692..3300540 100644 --- a/src/version.js +++ b/src/version.js @@ -1,3 +1,3 @@ -import pkg from "../package.json"; - -export const { version } = pkg; +import pkg from "../package.json"; + +export default pkg.version; diff --git a/test/syntax/-abp-has.test.js b/test/syntax/-abp-has.test.js index d985196..4127bfa 100644 --- a/test/syntax/-abp-has.test.js +++ b/test/syntax/-abp-has.test.js @@ -1,826 +1,826 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":-abp-has()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:-abp-has()`, parserConfig)).toThrow(); - expect(() => parse(`:-abp-has( )`, parserConfig)).toThrow(); - - expect(() => parse(`:-abp-has($$)`, parserConfig)).toThrow(); - expect(() => parse(`:-abp-has(.)`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Simple selector - expect(toPlainObject(parse(`:-abp-has(div)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - name: "-abp-has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - name: "div", - }, - ], - }, - ], - }, - ], - }, - ], - }); - - // Complex selector - expect(toPlainObject(parse(`:-abp-has(div:has(> a[href*="tracker"]))`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 40, - line: 1, - column: 41, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 40, - line: 1, - column: 41, - }, - }, - name: "-abp-has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 39, - line: 1, - column: 40, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 39, - line: 1, - column: 40, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 13, - line: 1, - column: 14, - }, - end: { - offset: 39, - line: 1, - column: 40, - }, - }, - name: "has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 38, - line: 1, - column: 39, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 38, - line: 1, - column: 39, - }, - }, - children: [ - { - type: "Combinator", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 19, - line: 1, - column: 20, - }, - }, - name: ">", - }, - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 20, - line: 1, - column: 21, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - name: "a", - }, - { - type: "AttributeSelector", - loc: { - source: "", - start: { - offset: 21, - line: 1, - column: 22, - }, - end: { - offset: 38, - line: 1, - column: 39, - }, - }, - name: { - type: "Identifier", - loc: { - source: "", - start: { - offset: 22, - line: 1, - column: 23, - }, - end: { - offset: 26, - line: 1, - column: 27, - }, - }, - name: "href", - }, - matcher: "*=", - value: { - type: "String", - loc: { - source: "", - start: { - offset: 28, - line: 1, - column: 29, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - value: "tracker", - }, - flags: null, - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }); - - // Simple selector list - expect(toPlainObject(parse(`:-abp-has(div, div)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 19, - line: 1, - column: 20, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 19, - line: 1, - column: 20, - }, - }, - name: "-abp-has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - name: "div", - }, - ], - }, - { - type: "Selector", - loc: { - source: "", - start: { - offset: 15, - line: 1, - column: 16, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 15, - line: 1, - column: 16, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - name: "div", - }, - ], - }, - ], - }, - ], - }, - ], - }); - - // Complex selector list - expect( - toPlainObject(parse(`:-abp-has(div, div:has(> a[href*="tracker"]) + section:contains(ads))`, parserConfig)) - ).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 69, - line: 1, - column: 70, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 69, - line: 1, - column: 70, - }, - }, - name: "-abp-has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 68, - line: 1, - column: 69, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - name: "div", - }, - ], - }, - { - type: "Selector", - loc: { - source: "", - start: { - offset: 15, - line: 1, - column: 16, - }, - end: { - offset: 68, - line: 1, - column: 69, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 15, - line: 1, - column: 16, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 44, - line: 1, - column: 45, - }, - }, - name: "has", - children: [ - { - type: "SelectorList", - loc: { - source: "", - start: { - offset: 23, - line: 1, - column: 24, - }, - end: { - offset: 43, - line: 1, - column: 44, - }, - }, - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 23, - line: 1, - column: 24, - }, - end: { - offset: 43, - line: 1, - column: 44, - }, - }, - children: [ - { - type: "Combinator", - loc: { - source: "", - start: { - offset: 23, - line: 1, - column: 24, - }, - end: { - offset: 24, - line: 1, - column: 25, - }, - }, - name: ">", - }, - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 25, - line: 1, - column: 26, - }, - end: { - offset: 26, - line: 1, - column: 27, - }, - }, - name: "a", - }, - { - type: "AttributeSelector", - loc: { - source: "", - start: { - offset: 26, - line: 1, - column: 27, - }, - end: { - offset: 43, - line: 1, - column: 44, - }, - }, - name: { - type: "Identifier", - loc: { - source: "", - start: { - offset: 27, - line: 1, - column: 28, - }, - end: { - offset: 31, - line: 1, - column: 32, - }, - }, - name: "href", - }, - matcher: "*=", - value: { - type: "String", - loc: { - source: "", - start: { - offset: 33, - line: 1, - column: 34, - }, - end: { - offset: 42, - line: 1, - column: 43, - }, - }, - value: "tracker", - }, - flags: null, - }, - ], - }, - ], - }, - ], - }, - { - type: "Combinator", - loc: { - source: "", - start: { - offset: 45, - line: 1, - column: 46, - }, - end: { - offset: 46, - line: 1, - column: 47, - }, - }, - name: "+", - }, - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 47, - line: 1, - column: 48, - }, - end: { - offset: 54, - line: 1, - column: 55, - }, - }, - name: "section", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 54, - line: 1, - column: 55, - }, - end: { - offset: 68, - line: 1, - column: 69, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 64, - line: 1, - column: 65, - }, - end: { - offset: 67, - line: 1, - column: 68, - }, - }, - value: "ads", - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`:-abp-has(div)`, parserConfig))).toEqual(`:-abp-has(div)`); - expect(generate(parse(`:-abp-has(div:has(> a[href*="tracker"]))`, parserConfig))).toEqual( - `:-abp-has(div:has(>a[href*="tracker"]))` - ); - expect(generate(parse(`:-abp-has(div:has(> a[href*='tracker']))`, parserConfig))).toEqual( - `:-abp-has(div:has(>a[href*="tracker"]))` - ); - - // Selector lists - expect(generate(parse(`:-abp-has(div, div)`, parserConfig))).toEqual(`:-abp-has(div,div)`); - expect( - generate(parse(`:-abp-has(div, div:has(> a[href*="tracker"]) + section:contains(ads))`, parserConfig)) - ).toEqual(`:-abp-has(div,div:has(>a[href*="tracker"])+section:contains(ads))`); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":-abp-has()", () => { + test("throws on invalid input", () => { + expect(() => parse(":-abp-has()", parserConfig)).toThrow(); + expect(() => parse(":-abp-has( )", parserConfig)).toThrow(); + + expect(() => parse(":-abp-has($$)", parserConfig)).toThrow(); + expect(() => parse(":-abp-has(.)", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Simple selector + expect(toPlainObject(parse(":-abp-has(div)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + name: "-abp-has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + name: "div", + }, + ], + }, + ], + }, + ], + }, + ], + }); + + // Complex selector + expect(toPlainObject(parse(':-abp-has(div:has(> a[href*="tracker"]))', parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 40, + line: 1, + column: 41, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 40, + line: 1, + column: 41, + }, + }, + name: "-abp-has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 39, + line: 1, + column: 40, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 39, + line: 1, + column: 40, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 13, + line: 1, + column: 14, + }, + end: { + offset: 39, + line: 1, + column: 40, + }, + }, + name: "has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 38, + line: 1, + column: 39, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 38, + line: 1, + column: 39, + }, + }, + children: [ + { + type: "Combinator", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 19, + line: 1, + column: 20, + }, + }, + name: ">", + }, + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 20, + line: 1, + column: 21, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + name: "a", + }, + { + type: "AttributeSelector", + loc: { + source: "", + start: { + offset: 21, + line: 1, + column: 22, + }, + end: { + offset: 38, + line: 1, + column: 39, + }, + }, + name: { + type: "Identifier", + loc: { + source: "", + start: { + offset: 22, + line: 1, + column: 23, + }, + end: { + offset: 26, + line: 1, + column: 27, + }, + }, + name: "href", + }, + matcher: "*=", + value: { + type: "String", + loc: { + source: "", + start: { + offset: 28, + line: 1, + column: 29, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + value: "tracker", + }, + flags: null, + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }); + + // Simple selector list + expect(toPlainObject(parse(":-abp-has(div, div)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 19, + line: 1, + column: 20, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 19, + line: 1, + column: 20, + }, + }, + name: "-abp-has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + name: "div", + }, + ], + }, + { + type: "Selector", + loc: { + source: "", + start: { + offset: 15, + line: 1, + column: 16, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 15, + line: 1, + column: 16, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + name: "div", + }, + ], + }, + ], + }, + ], + }, + ], + }); + + // Complex selector list + expect( + toPlainObject(parse(':-abp-has(div, div:has(> a[href*="tracker"]) + section:contains(ads))', parserConfig)) + ).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 69, + line: 1, + column: 70, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 69, + line: 1, + column: 70, + }, + }, + name: "-abp-has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 68, + line: 1, + column: 69, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + name: "div", + }, + ], + }, + { + type: "Selector", + loc: { + source: "", + start: { + offset: 15, + line: 1, + column: 16, + }, + end: { + offset: 68, + line: 1, + column: 69, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 15, + line: 1, + column: 16, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 44, + line: 1, + column: 45, + }, + }, + name: "has", + children: [ + { + type: "SelectorList", + loc: { + source: "", + start: { + offset: 23, + line: 1, + column: 24, + }, + end: { + offset: 43, + line: 1, + column: 44, + }, + }, + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 23, + line: 1, + column: 24, + }, + end: { + offset: 43, + line: 1, + column: 44, + }, + }, + children: [ + { + type: "Combinator", + loc: { + source: "", + start: { + offset: 23, + line: 1, + column: 24, + }, + end: { + offset: 24, + line: 1, + column: 25, + }, + }, + name: ">", + }, + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 25, + line: 1, + column: 26, + }, + end: { + offset: 26, + line: 1, + column: 27, + }, + }, + name: "a", + }, + { + type: "AttributeSelector", + loc: { + source: "", + start: { + offset: 26, + line: 1, + column: 27, + }, + end: { + offset: 43, + line: 1, + column: 44, + }, + }, + name: { + type: "Identifier", + loc: { + source: "", + start: { + offset: 27, + line: 1, + column: 28, + }, + end: { + offset: 31, + line: 1, + column: 32, + }, + }, + name: "href", + }, + matcher: "*=", + value: { + type: "String", + loc: { + source: "", + start: { + offset: 33, + line: 1, + column: 34, + }, + end: { + offset: 42, + line: 1, + column: 43, + }, + }, + value: "tracker", + }, + flags: null, + }, + ], + }, + ], + }, + ], + }, + { + type: "Combinator", + loc: { + source: "", + start: { + offset: 45, + line: 1, + column: 46, + }, + end: { + offset: 46, + line: 1, + column: 47, + }, + }, + name: "+", + }, + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 47, + line: 1, + column: 48, + }, + end: { + offset: 54, + line: 1, + column: 55, + }, + }, + name: "section", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 54, + line: 1, + column: 55, + }, + end: { + offset: 68, + line: 1, + column: 69, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 64, + line: 1, + column: 65, + }, + end: { + offset: 67, + line: 1, + column: 68, + }, + }, + value: "ads", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse(":-abp-has(div)", parserConfig))).toEqual(":-abp-has(div)"); + expect(generate(parse(':-abp-has(div:has(> a[href*="tracker"]))', parserConfig))).toEqual( + ':-abp-has(div:has(>a[href*="tracker"]))' + ); + expect(generate(parse(":-abp-has(div:has(> a[href*='tracker']))", parserConfig))).toEqual( + ':-abp-has(div:has(>a[href*="tracker"]))' + ); + + // Selector lists + expect(generate(parse(":-abp-has(div, div)", parserConfig))).toEqual(":-abp-has(div,div)"); + expect( + generate(parse(':-abp-has(div, div:has(> a[href*="tracker"]) + section:contains(ads))', parserConfig)) + ).toEqual(':-abp-has(div,div:has(>a[href*="tracker"])+section:contains(ads))'); + }); +}); diff --git a/test/syntax/contains.test.js b/test/syntax/contains.test.js index 956fcd8..ab8b6cb 100644 --- a/test/syntax/contains.test.js +++ b/test/syntax/contains.test.js @@ -1,1054 +1,1055 @@ -// Tests for :contains(), :-abp-contains() and :has-text() pseudo-classes - -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":contains()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:contains()`, parserConfig)).toThrow("Empty parameter specified"); - - expect(() => parse(`:contains(a`, parserConfig)).toThrow(); - expect(() => parse(`:contains(a'`, parserConfig)).toThrow(); - - // :-abp-contains alias - expect(() => parse(`:-abp-contains()`, parserConfig)).toThrow("Empty parameter specified"); - - expect(() => parse(`:-abp-contains(a`, parserConfig)).toThrow(); - expect(() => parse(`:-abp-contains(a'`, parserConfig)).toThrow(); - - // :has-text alias - expect(() => parse(`:has-text()`, parserConfig)).toThrow("Empty parameter specified"); - - expect(() => parse(`:has-text(a`, parserConfig)).toThrow(); - expect(() => parse(`:has-text(a'`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // One whitespace - expect(toPlainObject(parse(`:contains( )`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 12, - line: 1, - column: 13, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 12, - line: 1, - column: 13, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 11, - line: 1, - column: 12, - }, - }, - value: " ", - }, - ], - }, - ], - }); - - // Two whitespaces - expect(toPlainObject(parse(`:contains( )`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 12, - line: 1, - column: 13, - }, - }, - value: " ", - }, - ], - }, - ], - }); - - // Very simple input - expect(toPlainObject(parse(`:contains(aaa)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - value: "aaa", - }, - ], - }, - ], - }); - - // Space before input - expect(toPlainObject(parse(`:contains( aaa)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - value: " aaa", - }, - ], - }, - ], - }); - - // Space after input - expect(toPlainObject(parse(`:contains(aaa )`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - value: "aaa ", - }, - ], - }, - ], - }); - - // Space before and after input - expect(toPlainObject(parse(`:contains( aaa )`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - value: " aaa ", - }, - ], - }, - ], - }); - - // Space before and after input, with space in input - expect(toPlainObject(parse(`:contains( aaa bbb )`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - value: " aaa bbb ", - }, - ], - }, - ], - }); - - // Space in input - expect(toPlainObject(parse(`:contains(aaa bbb ccc)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - value: "aaa bbb ccc", - }, - ], - }, - ], - }); - - // Parenthesis in input - expect(toPlainObject(parse(`:contains((aaa))`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - value: "(aaa)", - }, - ], - }, - ], - }); - - // Parenthesis in input, but a bit more complex - expect(toPlainObject(parse(`:contains((aaa)(bbb)\\)\\()`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 25, - line: 1, - column: 26, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 25, - line: 1, - column: 26, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 24, - line: 1, - column: 25, - }, - }, - value: "(aaa)(bbb)\\)\\(", - }, - ], - }, - ], - }); - - // Regular expression - expect(toPlainObject(parse(`:contains(/aaa/)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 15, - line: 1, - column: 16, - }, - }, - value: "/aaa/", - }, - ], - }, - ], - }); - - // Regular expression with flags - expect(toPlainObject(parse(`:contains(/aaa/i)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 17, - line: 1, - column: 18, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 17, - line: 1, - column: 18, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 16, - line: 1, - column: 17, - }, - }, - value: "/aaa/i", - }, - ], - }, - ], - }); - - // Regular expression with parentheses - expect(toPlainObject(parse(`:contains(/^(a|b){3,}$/)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 24, - line: 1, - column: 25, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 24, - line: 1, - column: 25, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - value: "/^(a|b){3,}$/", - }, - ], - }, - ], - }); - - // Regular expression with escaped parentheses - expect(toPlainObject(parse(`:contains(/aaa\\(\\)/i)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - value: "/aaa\\(\\)/i", - }, - ], - }, - ], - }); - - // Single quote mark within the string - expect(toPlainObject(parse(`:contains(aaa'bbb)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 17, - line: 1, - column: 18, - }, - }, - value: "aaa'bbb", - }, - ], - }, - ], - }); - - // Double quote mark within the string - expect(toPlainObject(parse(`:contains(aaa"bbb)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 18, - line: 1, - column: 19, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 17, - line: 1, - column: 18, - }, - }, - value: 'aaa"bbb', - }, - ], - }, - ], - }); - - // Functions - expect(toPlainObject(parse(`:contains(function(another('')))`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - name: "contains", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 31, - line: 1, - column: 32, - }, - }, - value: "function(another(''))", - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`:contains( )`, parserConfig))).toEqual(`:contains( )`); - expect(generate(parse(`:contains( )`, parserConfig))).toEqual(`:contains( )`); - - expect(generate(parse(`:contains(aaa)`, parserConfig))).toEqual(`:contains(aaa)`); - expect(generate(parse(`:contains( aaa)`, parserConfig))).toEqual(`:contains( aaa)`); - expect(generate(parse(`:contains(aaa )`, parserConfig))).toEqual(`:contains(aaa )`); - expect(generate(parse(`:contains( aaa )`, parserConfig))).toEqual(`:contains( aaa )`); - expect(generate(parse(`:contains( aaa bbb )`, parserConfig))).toEqual(`:contains( aaa bbb )`); - expect(generate(parse(`:contains( aaa bbb )`, parserConfig))).toEqual(`:contains( aaa bbb )`); - expect(generate(parse(`:contains( aaa bbb ccc )`, parserConfig))).toEqual(`:contains( aaa bbb ccc )`); - - expect(generate(parse(`:contains((aaa))`, parserConfig))).toEqual(`:contains((aaa))`); - // TODO: "(aaa)(bbb)\\)\\("" is generated as "(aaa)(bbb) \\)\\(", but it should be "(aaa)(bbb)\\)\\(" - CSSTree related issue - // expect(generate(parse(`:contains((aaa)(bbb)\\)\\()`, parserConfig))).toEqual(`:contains((aaa)(bbb)\\)\\()`); - - expect(generate(parse(`:contains(/aaa/)`, parserConfig))).toEqual(`:contains(/aaa/)`); - expect(generate(parse(`:contains(/aaa/i)`, parserConfig))).toEqual(`:contains(/aaa/i)`); - expect(generate(parse(`:contains(/^(a|b){3,}$/)`, parserConfig))).toEqual(`:contains(/^(a|b){3,}$/)`); - expect(generate(parse(`:contains(/aaa\\(\\)/i)`, parserConfig))).toEqual(`:contains(/aaa\\(\\)/i)`); - - expect(generate(parse(`:contains(aaa'bbb)`, parserConfig))).toEqual(`:contains(aaa'bbb)`); - expect(generate(parse(`:contains(aaa"bbb)`, parserConfig))).toEqual(`:contains(aaa"bbb)`); - - // :-abp-contains alias - expect(generate(parse(`:-abp-contains( )`, parserConfig))).toEqual(`:-abp-contains( )`); - expect(generate(parse(`:-abp-contains( )`, parserConfig))).toEqual(`:-abp-contains( )`); - - expect(generate(parse(`:-abp-contains(aaa)`, parserConfig))).toEqual(`:-abp-contains(aaa)`); - expect(generate(parse(`:-abp-contains( aaa)`, parserConfig))).toEqual(`:-abp-contains( aaa)`); - expect(generate(parse(`:-abp-contains(aaa )`, parserConfig))).toEqual(`:-abp-contains(aaa )`); - expect(generate(parse(`:-abp-contains( aaa )`, parserConfig))).toEqual(`:-abp-contains( aaa )`); - expect(generate(parse(`:-abp-contains( aaa bbb )`, parserConfig))).toEqual(`:-abp-contains( aaa bbb )`); - expect(generate(parse(`:-abp-contains( aaa bbb )`, parserConfig))).toEqual(`:-abp-contains( aaa bbb )`); - expect(generate(parse(`:-abp-contains( aaa bbb ccc )`, parserConfig))).toEqual( - `:-abp-contains( aaa bbb ccc )` - ); - - expect(generate(parse(`:-abp-contains((aaa))`, parserConfig))).toEqual(`:-abp-contains((aaa))`); - - expect(generate(parse(`:-abp-contains(/aaa/)`, parserConfig))).toEqual(`:-abp-contains(/aaa/)`); - expect(generate(parse(`:-abp-contains(/aaa/i)`, parserConfig))).toEqual(`:-abp-contains(/aaa/i)`); - expect(generate(parse(`:-abp-contains(/^(a|b){3,}$/)`, parserConfig))).toEqual(`:-abp-contains(/^(a|b){3,}$/)`); - expect(generate(parse(`:-abp-contains(/aaa\\(\\)/i)`, parserConfig))).toEqual(`:-abp-contains(/aaa\\(\\)/i)`); - - expect(generate(parse(`:-abp-contains(aaa'bbb)`, parserConfig))).toEqual(`:-abp-contains(aaa'bbb)`); - expect(generate(parse(`:-abp-contains(aaa"bbb)`, parserConfig))).toEqual(`:-abp-contains(aaa"bbb)`); - - // :has-text alias - expect(generate(parse(`:has-text( )`, parserConfig))).toEqual(`:has-text( )`); - expect(generate(parse(`:has-text( )`, parserConfig))).toEqual(`:has-text( )`); - - expect(generate(parse(`:has-text(aaa)`, parserConfig))).toEqual(`:has-text(aaa)`); - expect(generate(parse(`:has-text( aaa)`, parserConfig))).toEqual(`:has-text( aaa)`); - expect(generate(parse(`:has-text(aaa )`, parserConfig))).toEqual(`:has-text(aaa )`); - expect(generate(parse(`:has-text( aaa )`, parserConfig))).toEqual(`:has-text( aaa )`); - expect(generate(parse(`:has-text( aaa bbb )`, parserConfig))).toEqual(`:has-text( aaa bbb )`); - expect(generate(parse(`:has-text( aaa bbb )`, parserConfig))).toEqual(`:has-text( aaa bbb )`); - expect(generate(parse(`:has-text( aaa bbb ccc )`, parserConfig))).toEqual(`:has-text( aaa bbb ccc )`); - - expect(generate(parse(`:has-text((aaa))`, parserConfig))).toEqual(`:has-text((aaa))`); - - expect(generate(parse(`:has-text(/aaa/)`, parserConfig))).toEqual(`:has-text(/aaa/)`); - expect(generate(parse(`:has-text(/aaa/i)`, parserConfig))).toEqual(`:has-text(/aaa/i)`); - expect(generate(parse(`:has-text(/^(a|b){3,}$/)`, parserConfig))).toEqual(`:has-text(/^(a|b){3,}$/)`); - expect(generate(parse(`:has-text(/aaa\\(\\)/i)`, parserConfig))).toEqual(`:has-text(/aaa\\(\\)/i)`); - - expect(generate(parse(`:has-text(aaa'bbb)`, parserConfig))).toEqual(`:has-text(aaa'bbb)`); - expect(generate(parse(`:has-text(aaa"bbb)`, parserConfig))).toEqual(`:has-text(aaa"bbb)`); - }); -}); +// Tests for :contains(), :-abp-contains() and :has-text() pseudo-classes + +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":contains()", () => { + test("throws on invalid input", () => { + expect(() => parse(":contains()", parserConfig)).toThrow("Empty parameter specified"); + + expect(() => parse(":contains(a", parserConfig)).toThrow(); + expect(() => parse(":contains(a'", parserConfig)).toThrow(); + + // :-abp-contains alias + expect(() => parse(":-abp-contains()", parserConfig)).toThrow("Empty parameter specified"); + + expect(() => parse(":-abp-contains(a", parserConfig)).toThrow(); + expect(() => parse(":-abp-contains(a'", parserConfig)).toThrow(); + + // :has-text alias + expect(() => parse(":has-text()", parserConfig)).toThrow("Empty parameter specified"); + + expect(() => parse(":has-text(a", parserConfig)).toThrow(); + expect(() => parse(":has-text(a'", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // One whitespace + expect(toPlainObject(parse(":contains( )", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 12, + line: 1, + column: 13, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 12, + line: 1, + column: 13, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 11, + line: 1, + column: 12, + }, + }, + value: " ", + }, + ], + }, + ], + }); + + // Two whitespaces + expect(toPlainObject(parse(":contains( )", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 12, + line: 1, + column: 13, + }, + }, + value: " ", + }, + ], + }, + ], + }); + + // Very simple input + expect(toPlainObject(parse(":contains(aaa)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + value: "aaa", + }, + ], + }, + ], + }); + + // Space before input + expect(toPlainObject(parse(":contains( aaa)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + value: " aaa", + }, + ], + }, + ], + }); + + // Space after input + expect(toPlainObject(parse(":contains(aaa )", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + value: "aaa ", + }, + ], + }, + ], + }); + + // Space before and after input + expect(toPlainObject(parse(":contains( aaa )", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + value: " aaa ", + }, + ], + }, + ], + }); + + // Space before and after input, with space in input + expect(toPlainObject(parse(":contains( aaa bbb )", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + value: " aaa bbb ", + }, + ], + }, + ], + }); + + // Space in input + expect(toPlainObject(parse(":contains(aaa bbb ccc)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + value: "aaa bbb ccc", + }, + ], + }, + ], + }); + + // Parenthesis in input + expect(toPlainObject(parse(":contains((aaa))", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + value: "(aaa)", + }, + ], + }, + ], + }); + + // Parenthesis in input, but a bit more complex + expect(toPlainObject(parse(":contains((aaa)(bbb)\\)\\()", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 25, + line: 1, + column: 26, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 25, + line: 1, + column: 26, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 24, + line: 1, + column: 25, + }, + }, + value: "(aaa)(bbb)\\)\\(", + }, + ], + }, + ], + }); + + // Regular expression + expect(toPlainObject(parse(":contains(/aaa/)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 15, + line: 1, + column: 16, + }, + }, + value: "/aaa/", + }, + ], + }, + ], + }); + + // Regular expression with flags + expect(toPlainObject(parse(":contains(/aaa/i)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 17, + line: 1, + column: 18, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 17, + line: 1, + column: 18, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 16, + line: 1, + column: 17, + }, + }, + value: "/aaa/i", + }, + ], + }, + ], + }); + + // Regular expression with parentheses + expect(toPlainObject(parse(":contains(/^(a|b){3,}$/)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 24, + line: 1, + column: 25, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 24, + line: 1, + column: 25, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + value: "/^(a|b){3,}$/", + }, + ], + }, + ], + }); + + // Regular expression with escaped parentheses + expect(toPlainObject(parse(":contains(/aaa\\(\\)/i)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + value: "/aaa\\(\\)/i", + }, + ], + }, + ], + }); + + // Single quote mark within the string + expect(toPlainObject(parse(":contains(aaa'bbb)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 17, + line: 1, + column: 18, + }, + }, + value: "aaa'bbb", + }, + ], + }, + ], + }); + + // Double quote mark within the string + expect(toPlainObject(parse(':contains(aaa"bbb)', parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 18, + line: 1, + column: 19, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 17, + line: 1, + column: 18, + }, + }, + value: 'aaa"bbb', + }, + ], + }, + ], + }); + + // Functions + expect(toPlainObject(parse(":contains(function(another('')))", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + name: "contains", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 31, + line: 1, + column: 32, + }, + }, + value: "function(another(''))", + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse(":contains( )", parserConfig))).toEqual(":contains( )"); + expect(generate(parse(":contains( )", parserConfig))).toEqual(":contains( )"); + + expect(generate(parse(":contains(aaa)", parserConfig))).toEqual(":contains(aaa)"); + expect(generate(parse(":contains( aaa)", parserConfig))).toEqual(":contains( aaa)"); + expect(generate(parse(":contains(aaa )", parserConfig))).toEqual(":contains(aaa )"); + expect(generate(parse(":contains( aaa )", parserConfig))).toEqual(":contains( aaa )"); + expect(generate(parse(":contains( aaa bbb )", parserConfig))).toEqual(":contains( aaa bbb )"); + expect(generate(parse(":contains( aaa bbb )", parserConfig))).toEqual(":contains( aaa bbb )"); + expect(generate(parse(":contains( aaa bbb ccc )", parserConfig))).toEqual(":contains( aaa bbb ccc )"); + + expect(generate(parse(":contains((aaa))", parserConfig))).toEqual(":contains((aaa))"); + // eslint-disable-next-line max-len + // TODO: "(aaa)(bbb)\\)\\("" is generated as "(aaa)(bbb) \\)\\(", but it should be "(aaa)(bbb)\\)\\(" - CSSTree related issue + // expect(generate(parse(`:contains((aaa)(bbb)\\)\\()`, parserConfig))).toEqual(`:contains((aaa)(bbb)\\)\\()`); + + expect(generate(parse(":contains(/aaa/)", parserConfig))).toEqual(":contains(/aaa/)"); + expect(generate(parse(":contains(/aaa/i)", parserConfig))).toEqual(":contains(/aaa/i)"); + expect(generate(parse(":contains(/^(a|b){3,}$/)", parserConfig))).toEqual(":contains(/^(a|b){3,}$/)"); + expect(generate(parse(":contains(/aaa\\(\\)/i)", parserConfig))).toEqual(":contains(/aaa\\(\\)/i)"); + + expect(generate(parse(":contains(aaa'bbb)", parserConfig))).toEqual(":contains(aaa'bbb)"); + expect(generate(parse(':contains(aaa"bbb)', parserConfig))).toEqual(':contains(aaa"bbb)'); + + // :-abp-contains alias + expect(generate(parse(":-abp-contains( )", parserConfig))).toEqual(":-abp-contains( )"); + expect(generate(parse(":-abp-contains( )", parserConfig))).toEqual(":-abp-contains( )"); + + expect(generate(parse(":-abp-contains(aaa)", parserConfig))).toEqual(":-abp-contains(aaa)"); + expect(generate(parse(":-abp-contains( aaa)", parserConfig))).toEqual(":-abp-contains( aaa)"); + expect(generate(parse(":-abp-contains(aaa )", parserConfig))).toEqual(":-abp-contains(aaa )"); + expect(generate(parse(":-abp-contains( aaa )", parserConfig))).toEqual(":-abp-contains( aaa )"); + expect(generate(parse(":-abp-contains( aaa bbb )", parserConfig))).toEqual(":-abp-contains( aaa bbb )"); + expect(generate(parse(":-abp-contains( aaa bbb )", parserConfig))).toEqual(":-abp-contains( aaa bbb )"); + expect(generate(parse(":-abp-contains( aaa bbb ccc )", parserConfig))).toEqual( + ":-abp-contains( aaa bbb ccc )" + ); + + expect(generate(parse(":-abp-contains((aaa))", parserConfig))).toEqual(":-abp-contains((aaa))"); + + expect(generate(parse(":-abp-contains(/aaa/)", parserConfig))).toEqual(":-abp-contains(/aaa/)"); + expect(generate(parse(":-abp-contains(/aaa/i)", parserConfig))).toEqual(":-abp-contains(/aaa/i)"); + expect(generate(parse(":-abp-contains(/^(a|b){3,}$/)", parserConfig))).toEqual(":-abp-contains(/^(a|b){3,}$/)"); + expect(generate(parse(":-abp-contains(/aaa\\(\\)/i)", parserConfig))).toEqual(":-abp-contains(/aaa\\(\\)/i)"); + + expect(generate(parse(":-abp-contains(aaa'bbb)", parserConfig))).toEqual(":-abp-contains(aaa'bbb)"); + expect(generate(parse(':-abp-contains(aaa"bbb)', parserConfig))).toEqual(':-abp-contains(aaa"bbb)'); + + // :has-text alias + expect(generate(parse(":has-text( )", parserConfig))).toEqual(":has-text( )"); + expect(generate(parse(":has-text( )", parserConfig))).toEqual(":has-text( )"); + + expect(generate(parse(":has-text(aaa)", parserConfig))).toEqual(":has-text(aaa)"); + expect(generate(parse(":has-text( aaa)", parserConfig))).toEqual(":has-text( aaa)"); + expect(generate(parse(":has-text(aaa )", parserConfig))).toEqual(":has-text(aaa )"); + expect(generate(parse(":has-text( aaa )", parserConfig))).toEqual(":has-text( aaa )"); + expect(generate(parse(":has-text( aaa bbb )", parserConfig))).toEqual(":has-text( aaa bbb )"); + expect(generate(parse(":has-text( aaa bbb )", parserConfig))).toEqual(":has-text( aaa bbb )"); + expect(generate(parse(":has-text( aaa bbb ccc )", parserConfig))).toEqual(":has-text( aaa bbb ccc )"); + + expect(generate(parse(":has-text((aaa))", parserConfig))).toEqual(":has-text((aaa))"); + + expect(generate(parse(":has-text(/aaa/)", parserConfig))).toEqual(":has-text(/aaa/)"); + expect(generate(parse(":has-text(/aaa/i)", parserConfig))).toEqual(":has-text(/aaa/i)"); + expect(generate(parse(":has-text(/^(a|b){3,}$/)", parserConfig))).toEqual(":has-text(/^(a|b){3,}$/)"); + expect(generate(parse(":has-text(/aaa\\(\\)/i)", parserConfig))).toEqual(":has-text(/aaa\\(\\)/i)"); + + expect(generate(parse(":has-text(aaa'bbb)", parserConfig))).toEqual(":has-text(aaa'bbb)"); + expect(generate(parse(':has-text(aaa"bbb)', parserConfig))).toEqual(':has-text(aaa"bbb)'); + }); +}); diff --git a/test/syntax/if-not.test.js b/test/syntax/if-not.test.js index bdb3ded..798ba5a 100644 --- a/test/syntax/if-not.test.js +++ b/test/syntax/if-not.test.js @@ -1,148 +1,148 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":if-not()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:if-not()`, parserConfig)).toThrow(); - expect(() => parse(`:if-not( )`, parserConfig)).toThrow(); - - expect(() => parse(`:if-not($$)`, parserConfig)).toThrow(); - expect(() => parse(`:if-not(.)`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - expect(toPlainObject(parse(`div:if-not(.something + #another)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 33, - line: 1, - column: 34, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 33, - line: 1, - column: 34, - }, - }, - name: "if-not", - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 11, - line: 1, - column: 12, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - children: [ - { - type: "ClassSelector", - loc: { - source: "", - start: { - offset: 11, - line: 1, - column: 12, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - name: "something", - }, - { - type: "Combinator", - loc: { - source: "", - start: { - offset: 22, - line: 1, - column: 23, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - name: "+", - }, - { - type: "IdSelector", - loc: { - source: "", - start: { - offset: 24, - line: 1, - column: 25, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - name: "another", - }, - ], - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:if-not(.something + #another)`, parserConfig))).toEqual( - `div:if-not(.something+#another)` - ); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":if-not()", () => { + test("throws on invalid input", () => { + expect(() => parse(":if-not()", parserConfig)).toThrow(); + expect(() => parse(":if-not( )", parserConfig)).toThrow(); + + expect(() => parse(":if-not($$)", parserConfig)).toThrow(); + expect(() => parse(":if-not(.)", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + expect(toPlainObject(parse("div:if-not(.something + #another)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 33, + line: 1, + column: 34, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 33, + line: 1, + column: 34, + }, + }, + name: "if-not", + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 11, + line: 1, + column: 12, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + children: [ + { + type: "ClassSelector", + loc: { + source: "", + start: { + offset: 11, + line: 1, + column: 12, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + name: "something", + }, + { + type: "Combinator", + loc: { + source: "", + start: { + offset: 22, + line: 1, + column: 23, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + name: "+", + }, + { + type: "IdSelector", + loc: { + source: "", + start: { + offset: 24, + line: 1, + column: 25, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + name: "another", + }, + ], + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:if-not(.something + #another)", parserConfig))).toEqual( + "div:if-not(.something+#another)" + ); + }); +}); diff --git a/test/syntax/matches-media.test.js b/test/syntax/matches-media.test.js index da35067..1f4c619 100644 --- a/test/syntax/matches-media.test.js +++ b/test/syntax/matches-media.test.js @@ -1,371 +1,371 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":matches-media()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:matches-media()`, parserConfig)).toThrow(); - expect(() => parse(`:matches-media( )`, parserConfig)).toThrow(); - - expect(() => parse(`:matches-media($$)`, parserConfig)).toThrow(); - expect(() => parse(`:matches-media(.)`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Simple media query - expect(toPlainObject(parse(`div:matches-media((min-width: 720px))`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - name: "matches-media", - children: [ - { - type: "MediaQueryList", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 36, - line: 1, - column: 37, - }, - }, - children: [ - { - type: "MediaQuery", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 36, - line: 1, - column: 37, - }, - }, - children: [ - { - type: "MediaFeature", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 36, - line: 1, - column: 37, - }, - }, - name: "min-width", - value: { - type: "Dimension", - loc: { - source: "", - start: { - offset: 30, - line: 1, - column: 31, - }, - end: { - offset: 35, - line: 1, - column: 36, - }, - }, - value: "720", - unit: "px", - }, - }, - ], - }, - ], - }, - ], - }, - ], - }); - - // Complex media query - expect( - toPlainObject( - parse(`div:matches-media((min-height: 680px), screen and (orientation: portrait))`, parserConfig) - ) - ).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 74, - line: 1, - column: 75, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 74, - line: 1, - column: 75, - }, - }, - name: "matches-media", - children: [ - { - type: "MediaQueryList", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 73, - line: 1, - column: 74, - }, - }, - children: [ - { - type: "MediaQuery", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - children: [ - { - type: "MediaFeature", - loc: { - source: "", - start: { - offset: 18, - line: 1, - column: 19, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - name: "min-height", - value: { - type: "Dimension", - loc: { - source: "", - start: { - offset: 31, - line: 1, - column: 32, - }, - end: { - offset: 36, - line: 1, - column: 37, - }, - }, - value: "680", - unit: "px", - }, - }, - ], - }, - { - type: "MediaQuery", - loc: { - source: "", - start: { - offset: 39, - line: 1, - column: 40, - }, - end: { - offset: 73, - line: 1, - column: 74, - }, - }, - children: [ - { - type: "Identifier", - loc: { - source: "", - start: { - offset: 39, - line: 1, - column: 40, - }, - end: { - offset: 45, - line: 1, - column: 46, - }, - }, - name: "screen", - }, - { - type: "Identifier", - loc: { - source: "", - start: { - offset: 46, - line: 1, - column: 47, - }, - end: { - offset: 49, - line: 1, - column: 50, - }, - }, - name: "and", - }, - { - type: "MediaFeature", - loc: { - source: "", - start: { - offset: 50, - line: 1, - column: 51, - }, - end: { - offset: 73, - line: 1, - column: 74, - }, - }, - name: "orientation", - value: { - type: "Identifier", - loc: { - source: "", - start: { - offset: 64, - line: 1, - column: 65, - }, - end: { - offset: 72, - line: 1, - column: 73, - }, - }, - name: "portrait", - }, - }, - ], - }, - ], - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:matches-media((min-width: 720px))`, parserConfig))).toEqual( - `div:matches-media((min-width:720px))` - ); - expect( - generate(parse(`div:matches-media((min-height: 680px), screen and (orientation: portrait))`, parserConfig)) - ).toEqual(`div:matches-media((min-height:680px),screen and (orientation:portrait))`); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":matches-media()", () => { + test("throws on invalid input", () => { + expect(() => parse(":matches-media()", parserConfig)).toThrow(); + expect(() => parse(":matches-media( )", parserConfig)).toThrow(); + + expect(() => parse(":matches-media($$)", parserConfig)).toThrow(); + expect(() => parse(":matches-media(.)", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Simple media query + expect(toPlainObject(parse("div:matches-media((min-width: 720px))", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + name: "matches-media", + children: [ + { + type: "MediaQueryList", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 36, + line: 1, + column: 37, + }, + }, + children: [ + { + type: "MediaQuery", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 36, + line: 1, + column: 37, + }, + }, + children: [ + { + type: "MediaFeature", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 36, + line: 1, + column: 37, + }, + }, + name: "min-width", + value: { + type: "Dimension", + loc: { + source: "", + start: { + offset: 30, + line: 1, + column: 31, + }, + end: { + offset: 35, + line: 1, + column: 36, + }, + }, + value: "720", + unit: "px", + }, + }, + ], + }, + ], + }, + ], + }, + ], + }); + + // Complex media query + expect( + toPlainObject( + parse("div:matches-media((min-height: 680px), screen and (orientation: portrait))", parserConfig) + ) + ).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 74, + line: 1, + column: 75, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 74, + line: 1, + column: 75, + }, + }, + name: "matches-media", + children: [ + { + type: "MediaQueryList", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 73, + line: 1, + column: 74, + }, + }, + children: [ + { + type: "MediaQuery", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + children: [ + { + type: "MediaFeature", + loc: { + source: "", + start: { + offset: 18, + line: 1, + column: 19, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + name: "min-height", + value: { + type: "Dimension", + loc: { + source: "", + start: { + offset: 31, + line: 1, + column: 32, + }, + end: { + offset: 36, + line: 1, + column: 37, + }, + }, + value: "680", + unit: "px", + }, + }, + ], + }, + { + type: "MediaQuery", + loc: { + source: "", + start: { + offset: 39, + line: 1, + column: 40, + }, + end: { + offset: 73, + line: 1, + column: 74, + }, + }, + children: [ + { + type: "Identifier", + loc: { + source: "", + start: { + offset: 39, + line: 1, + column: 40, + }, + end: { + offset: 45, + line: 1, + column: 46, + }, + }, + name: "screen", + }, + { + type: "Identifier", + loc: { + source: "", + start: { + offset: 46, + line: 1, + column: 47, + }, + end: { + offset: 49, + line: 1, + column: 50, + }, + }, + name: "and", + }, + { + type: "MediaFeature", + loc: { + source: "", + start: { + offset: 50, + line: 1, + column: 51, + }, + end: { + offset: 73, + line: 1, + column: 74, + }, + }, + name: "orientation", + value: { + type: "Identifier", + loc: { + source: "", + start: { + offset: 64, + line: 1, + column: 65, + }, + end: { + offset: 72, + line: 1, + column: 73, + }, + }, + name: "portrait", + }, + }, + ], + }, + ], + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:matches-media((min-width: 720px))", parserConfig))).toEqual( + "div:matches-media((min-width:720px))" + ); + expect( + generate(parse("div:matches-media((min-height: 680px), screen and (orientation: portrait))", parserConfig)) + ).toEqual("div:matches-media((min-height:680px),screen and (orientation:portrait))"); + }); +}); diff --git a/test/syntax/min-text-length.test.js b/test/syntax/min-text-length.test.js index b9bf8e2..1de2633 100644 --- a/test/syntax/min-text-length.test.js +++ b/test/syntax/min-text-length.test.js @@ -1,99 +1,99 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":min-text-length()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:min-text-length()`, parserConfig)).toThrow(); - expect(() => parse(`:min-text-length( )`, parserConfig)).toThrow(); - - expect(() => parse(`:min-text-length($$)`, parserConfig)).toThrow(); - expect(() => parse(`:min-text-length(.)`, parserConfig)).toThrow(); - - // Selector - expect(() => parse(`:min-text-length(div)`, parserConfig)).toThrow(); - expect(() => parse(`:min-text-length(div + section[class^="something"])`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Number - expect(toPlainObject(parse(`div:min-text-length(42)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - name: "min-text-length", - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 20, - line: 1, - column: 21, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - value: "42", - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:min-text-length(42)`, parserConfig))).toEqual(`div:min-text-length(42)`); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":min-text-length()", () => { + test("throws on invalid input", () => { + expect(() => parse(":min-text-length()", parserConfig)).toThrow(); + expect(() => parse(":min-text-length( )", parserConfig)).toThrow(); + + expect(() => parse(":min-text-length($$)", parserConfig)).toThrow(); + expect(() => parse(":min-text-length(.)", parserConfig)).toThrow(); + + // Selector + expect(() => parse(":min-text-length(div)", parserConfig)).toThrow(); + expect(() => parse(':min-text-length(div + section[class^="something"])', parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Number + expect(toPlainObject(parse("div:min-text-length(42)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + name: "min-text-length", + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 20, + line: 1, + column: 21, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + value: "42", + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:min-text-length(42)", parserConfig))).toEqual("div:min-text-length(42)"); + }); +}); diff --git a/test/syntax/nth-ancestor.test.js b/test/syntax/nth-ancestor.test.js index f34dbfe..f8da29a 100644 --- a/test/syntax/nth-ancestor.test.js +++ b/test/syntax/nth-ancestor.test.js @@ -1,99 +1,99 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":nth-ancestor()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:nth-ancestor()`, parserConfig)).toThrow(); - expect(() => parse(`:nth-ancestor( )`, parserConfig)).toThrow(); - - expect(() => parse(`:nth-ancestor($$)`, parserConfig)).toThrow(); - expect(() => parse(`:nth-ancestor(.)`, parserConfig)).toThrow(); - - // Selector - expect(() => parse(`:nth-ancestor(div)`, parserConfig)).toThrow(); - expect(() => parse(`:nth-ancestor(div + section[class^="something"])`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Number - expect(toPlainObject(parse(`div:nth-ancestor(42)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - name: "nth-ancestor", - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 17, - line: 1, - column: 18, - }, - end: { - offset: 19, - line: 1, - column: 20, - }, - }, - value: "42", - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:nth-ancestor(42)`, parserConfig))).toEqual(`div:nth-ancestor(42)`); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":nth-ancestor()", () => { + test("throws on invalid input", () => { + expect(() => parse(":nth-ancestor()", parserConfig)).toThrow(); + expect(() => parse(":nth-ancestor( )", parserConfig)).toThrow(); + + expect(() => parse(":nth-ancestor($$)", parserConfig)).toThrow(); + expect(() => parse(":nth-ancestor(.)", parserConfig)).toThrow(); + + // Selector + expect(() => parse(":nth-ancestor(div)", parserConfig)).toThrow(); + expect(() => parse(':nth-ancestor(div + section[class^="something"])', parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Number + expect(toPlainObject(parse("div:nth-ancestor(42)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + name: "nth-ancestor", + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 17, + line: 1, + column: 18, + }, + end: { + offset: 19, + line: 1, + column: 20, + }, + }, + value: "42", + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:nth-ancestor(42)", parserConfig))).toEqual("div:nth-ancestor(42)"); + }); +}); diff --git a/test/syntax/style.test.js b/test/syntax/style.test.js index 2d3b245..881a566 100644 --- a/test/syntax/style.test.js +++ b/test/syntax/style.test.js @@ -1,643 +1,643 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":style()", () => { - test("throws on invalid input", () => { - // Empty declaration - expect(() => parse("div:style()", parserConfig)).toThrow(); - expect(() => parse("div:style( )", parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Simple style - expect(toPlainObject(parse("div:style(padding: 0)", parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - name: "style", - children: [ - { - type: "DeclarationList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - children: [ - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - important: false, - property: "padding", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - value: "0", - }, - ], - }, - }, - ], - }, - ], - }, - ], - }); - - // Semicolon at the end - expect(toPlainObject(parse("div:style(padding: 0;)", parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 22, - line: 1, - column: 23, - }, - }, - name: "style", - children: [ - { - type: "DeclarationList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - children: [ - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - important: false, - property: "padding", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - value: "0", - }, - ], - }, - }, - ], - }, - ], - }, - ], - }); - - // Important style - expect(toPlainObject(parse("div:style(padding: 0 !important)", parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - name: "style", - children: [ - { - type: "DeclarationList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 31, - line: 1, - column: 32, - }, - }, - children: [ - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 31, - line: 1, - column: 32, - }, - }, - important: true, - property: "padding", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - value: "0", - }, - ], - }, - }, - ], - }, - ], - }, - ], - }); - - // Complex style - expect( - toPlainObject(parse("div:style(padding: 0 !important; margin: 0; color: black !important)", parserConfig)) - ).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 68, - line: 1, - column: 69, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 68, - line: 1, - column: 69, - }, - }, - name: "style", - children: [ - { - type: "DeclarationList", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 67, - line: 1, - column: 68, - }, - }, - children: [ - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 10, - line: 1, - column: 11, - }, - end: { - offset: 31, - line: 1, - column: 32, - }, - }, - important: true, - property: "padding", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 19, - line: 1, - column: 20, - }, - end: { - offset: 20, - line: 1, - column: 21, - }, - }, - value: "0", - }, - ], - }, - }, - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 33, - line: 1, - column: 34, - }, - end: { - offset: 42, - line: 1, - column: 43, - }, - }, - important: false, - property: "margin", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 41, - line: 1, - column: 42, - }, - end: { - offset: 42, - line: 1, - column: 43, - }, - }, - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 41, - line: 1, - column: 42, - }, - end: { - offset: 42, - line: 1, - column: 43, - }, - }, - value: "0", - }, - ], - }, - }, - { - type: "Declaration", - loc: { - source: "", - start: { - offset: 44, - line: 1, - column: 45, - }, - end: { - offset: 67, - line: 1, - column: 68, - }, - }, - important: true, - property: "color", - value: { - type: "Value", - loc: { - source: "", - start: { - offset: 51, - line: 1, - column: 52, - }, - end: { - offset: 57, - line: 1, - column: 58, - }, - }, - children: [ - { - type: "Identifier", - loc: { - source: "", - start: { - offset: 51, - line: 1, - column: 52, - }, - end: { - offset: 56, - line: 1, - column: 57, - }, - }, - name: "black", - }, - ], - }, - }, - ], - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:style(padding: 0)`, parserConfig))).toEqual(`div:style(padding:0)`); - expect(generate(parse(`div:style(padding: 0;)`, parserConfig))).toEqual(`div:style(padding:0)`); - expect(generate(parse(`div:style(padding: 0 !important)`, parserConfig))).toEqual( - `div:style(padding:0!important)` - ); - expect( - generate(parse(`div:style(padding: 0 !important; margin: 0; color: black !important)`, parserConfig)) - ).toEqual(`div:style(padding:0!important;margin:0;color:black!important)`); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":style()", () => { + test("throws on invalid input", () => { + // Empty declaration + expect(() => parse("div:style()", parserConfig)).toThrow(); + expect(() => parse("div:style( )", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Simple style + expect(toPlainObject(parse("div:style(padding: 0)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + name: "style", + children: [ + { + type: "DeclarationList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + children: [ + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + important: false, + property: "padding", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + value: "0", + }, + ], + }, + }, + ], + }, + ], + }, + ], + }); + + // Semicolon at the end + expect(toPlainObject(parse("div:style(padding: 0;)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 22, + line: 1, + column: 23, + }, + }, + name: "style", + children: [ + { + type: "DeclarationList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + children: [ + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + important: false, + property: "padding", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + value: "0", + }, + ], + }, + }, + ], + }, + ], + }, + ], + }); + + // Important style + expect(toPlainObject(parse("div:style(padding: 0 !important)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + name: "style", + children: [ + { + type: "DeclarationList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 31, + line: 1, + column: 32, + }, + }, + children: [ + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 31, + line: 1, + column: 32, + }, + }, + important: true, + property: "padding", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + value: "0", + }, + ], + }, + }, + ], + }, + ], + }, + ], + }); + + // Complex style + expect( + toPlainObject(parse("div:style(padding: 0 !important; margin: 0; color: black !important)", parserConfig)) + ).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 68, + line: 1, + column: 69, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 68, + line: 1, + column: 69, + }, + }, + name: "style", + children: [ + { + type: "DeclarationList", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 67, + line: 1, + column: 68, + }, + }, + children: [ + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 10, + line: 1, + column: 11, + }, + end: { + offset: 31, + line: 1, + column: 32, + }, + }, + important: true, + property: "padding", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 19, + line: 1, + column: 20, + }, + end: { + offset: 20, + line: 1, + column: 21, + }, + }, + value: "0", + }, + ], + }, + }, + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 33, + line: 1, + column: 34, + }, + end: { + offset: 42, + line: 1, + column: 43, + }, + }, + important: false, + property: "margin", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 41, + line: 1, + column: 42, + }, + end: { + offset: 42, + line: 1, + column: 43, + }, + }, + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 41, + line: 1, + column: 42, + }, + end: { + offset: 42, + line: 1, + column: 43, + }, + }, + value: "0", + }, + ], + }, + }, + { + type: "Declaration", + loc: { + source: "", + start: { + offset: 44, + line: 1, + column: 45, + }, + end: { + offset: 67, + line: 1, + column: 68, + }, + }, + important: true, + property: "color", + value: { + type: "Value", + loc: { + source: "", + start: { + offset: 51, + line: 1, + column: 52, + }, + end: { + offset: 57, + line: 1, + column: 58, + }, + }, + children: [ + { + type: "Identifier", + loc: { + source: "", + start: { + offset: 51, + line: 1, + column: 52, + }, + end: { + offset: 56, + line: 1, + column: 57, + }, + }, + name: "black", + }, + ], + }, + }, + ], + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:style(padding: 0)", parserConfig))).toEqual("div:style(padding:0)"); + expect(generate(parse("div:style(padding: 0;)", parserConfig))).toEqual("div:style(padding:0)"); + expect(generate(parse("div:style(padding: 0 !important)", parserConfig))).toEqual( + "div:style(padding:0!important)" + ); + expect( + generate(parse("div:style(padding: 0 !important; margin: 0; color: black !important)", parserConfig)) + ).toEqual("div:style(padding:0!important;margin:0;color:black!important)"); + }); +}); diff --git a/test/syntax/upward.test.js b/test/syntax/upward.test.js index 4988157..edae6c2 100644 --- a/test/syntax/upward.test.js +++ b/test/syntax/upward.test.js @@ -1,223 +1,223 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":upward()", () => { - test("throws on invalid input", () => { - expect(() => parse(`:upward()`, parserConfig)).toThrow(); - expect(() => parse(`:upward( )`, parserConfig)).toThrow(); - - expect(() => parse(`:upward($$)`, parserConfig)).toThrow(); - expect(() => parse(`:upward(.)`, parserConfig)).toThrow(); - }); - - test("parses valid input properly", () => { - // Number - expect(toPlainObject(parse("div:upward(42)", parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - name: "upward", - children: [ - { - type: "Number", - loc: { - source: "", - start: { - offset: 11, - line: 1, - column: 12, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - value: "42", - }, - ], - }, - ], - }); - - // Selector - expect(toPlainObject(parse("div:upward(.something + #another)", parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 33, - line: 1, - column: 34, - }, - }, - children: [ - { - type: "TypeSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 3, - line: 1, - column: 4, - }, - }, - name: "div", - }, - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 3, - line: 1, - column: 4, - }, - end: { - offset: 33, - line: 1, - column: 34, - }, - }, - name: "upward", - children: [ - { - type: "Selector", - loc: { - source: "", - start: { - offset: 11, - line: 1, - column: 12, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - children: [ - { - type: "ClassSelector", - loc: { - source: "", - start: { - offset: 11, - line: 1, - column: 12, - }, - end: { - offset: 21, - line: 1, - column: 22, - }, - }, - name: "something", - }, - { - type: "Combinator", - loc: { - source: "", - start: { - offset: 22, - line: 1, - column: 23, - }, - end: { - offset: 23, - line: 1, - column: 24, - }, - }, - name: "+", - }, - { - type: "IdSelector", - loc: { - source: "", - start: { - offset: 24, - line: 1, - column: 25, - }, - end: { - offset: 32, - line: 1, - column: 33, - }, - }, - name: "another", - }, - ], - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`div:upward(42)`, parserConfig))).toEqual(`div:upward(42)`); - expect(generate(parse(`div:upward(.something + #another)`, parserConfig))).toEqual( - `div:upward(.something+#another)` - ); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":upward()", () => { + test("throws on invalid input", () => { + expect(() => parse(":upward()", parserConfig)).toThrow(); + expect(() => parse(":upward( )", parserConfig)).toThrow(); + + expect(() => parse(":upward($$)", parserConfig)).toThrow(); + expect(() => parse(":upward(.)", parserConfig)).toThrow(); + }); + + test("parses valid input properly", () => { + // Number + expect(toPlainObject(parse("div:upward(42)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + name: "upward", + children: [ + { + type: "Number", + loc: { + source: "", + start: { + offset: 11, + line: 1, + column: 12, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + value: "42", + }, + ], + }, + ], + }); + + // Selector + expect(toPlainObject(parse("div:upward(.something + #another)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 33, + line: 1, + column: 34, + }, + }, + children: [ + { + type: "TypeSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 3, + line: 1, + column: 4, + }, + }, + name: "div", + }, + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 3, + line: 1, + column: 4, + }, + end: { + offset: 33, + line: 1, + column: 34, + }, + }, + name: "upward", + children: [ + { + type: "Selector", + loc: { + source: "", + start: { + offset: 11, + line: 1, + column: 12, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + children: [ + { + type: "ClassSelector", + loc: { + source: "", + start: { + offset: 11, + line: 1, + column: 12, + }, + end: { + offset: 21, + line: 1, + column: 22, + }, + }, + name: "something", + }, + { + type: "Combinator", + loc: { + source: "", + start: { + offset: 22, + line: 1, + column: 23, + }, + end: { + offset: 23, + line: 1, + column: 24, + }, + }, + name: "+", + }, + { + type: "IdSelector", + loc: { + source: "", + start: { + offset: 24, + line: 1, + column: 25, + }, + end: { + offset: 32, + line: 1, + column: 33, + }, + }, + name: "another", + }, + ], + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse("div:upward(42)", parserConfig))).toEqual("div:upward(42)"); + expect(generate(parse("div:upward(.something + #another)", parserConfig))).toEqual( + "div:upward(.something+#another)" + ); + }); +}); diff --git a/test/syntax/xpath.test.js b/test/syntax/xpath.test.js index 54ce2a2..370290d 100644 --- a/test/syntax/xpath.test.js +++ b/test/syntax/xpath.test.js @@ -1,129 +1,129 @@ -import { parse, generate, toPlainObject } from "../../src/index.js"; - -const parserConfig = { - context: "selector", - positions: true, -}; - -describe(":xpath()", () => { - test("parses valid input properly", () => { - // Very simple test, just to make sure it's working - expect(toPlainObject(parse(`:xpath(//test)`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 14, - line: 1, - column: 15, - }, - }, - name: "xpath", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 7, - line: 1, - column: 8, - }, - end: { - offset: 13, - line: 1, - column: 14, - }, - }, - value: "//test", - }, - ], - }, - ], - }); - - // Test with a more complex expression, which contains a lot of special cases - expect(toPlainObject(parse(`:xpath(//*[contains(text(),"()(cc")])`, parserConfig))).toMatchObject({ - type: "Selector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - children: [ - { - type: "PseudoClassSelector", - loc: { - source: "", - start: { - offset: 0, - line: 1, - column: 1, - }, - end: { - offset: 37, - line: 1, - column: 38, - }, - }, - name: "xpath", - children: [ - { - type: "Raw", - loc: { - source: "", - start: { - offset: 7, - line: 1, - column: 8, - }, - end: { - offset: 36, - line: 1, - column: 37, - }, - }, - value: '//*[contains(text(),"()(cc")]', - }, - ], - }, - ], - }); - }); - - test("generates valid input properly", () => { - expect(generate(parse(`:xpath(//test)`, parserConfig))).toEqual(`:xpath(//test)`); - expect(generate(parse(`:xpath(//*[contains(text(),"()(cc")])`, parserConfig))).toEqual( - `:xpath(//*[contains(text(),"()(cc")])` - ); - }); -}); +import { parse, generate, toPlainObject } from "../../src/index.js"; + +const parserConfig = { + context: "selector", + positions: true, +}; + +describe(":xpath()", () => { + test("parses valid input properly", () => { + // Very simple test, just to make sure it's working + expect(toPlainObject(parse(":xpath(//test)", parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 14, + line: 1, + column: 15, + }, + }, + name: "xpath", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 7, + line: 1, + column: 8, + }, + end: { + offset: 13, + line: 1, + column: 14, + }, + }, + value: "//test", + }, + ], + }, + ], + }); + + // Test with a more complex expression, which contains a lot of special cases + expect(toPlainObject(parse(':xpath(//*[contains(text(),"()(cc")])', parserConfig))).toMatchObject({ + type: "Selector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + children: [ + { + type: "PseudoClassSelector", + loc: { + source: "", + start: { + offset: 0, + line: 1, + column: 1, + }, + end: { + offset: 37, + line: 1, + column: 38, + }, + }, + name: "xpath", + children: [ + { + type: "Raw", + loc: { + source: "", + start: { + offset: 7, + line: 1, + column: 8, + }, + end: { + offset: 36, + line: 1, + column: 37, + }, + }, + value: '//*[contains(text(),"()(cc")]', + }, + ], + }, + ], + }); + }); + + test("generates valid input properly", () => { + expect(generate(parse(":xpath(//test)", parserConfig))).toEqual(":xpath(//test)"); + expect(generate(parse(':xpath(//*[contains(text(),"()(cc")])', parserConfig))).toEqual( + ':xpath(//*[contains(text(),"()(cc")])' + ); + }); +}); diff --git a/yarn.lock b/yarn.lock index 6ebbcd4..1d9caea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -936,6 +936,40 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@eslint/eslintrc@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e" + integrity sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.4.0" + 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" + +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== + 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== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1192,6 +1226,27 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@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": + 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.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" + "@rollup/plugin-alias@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-4.0.2.tgz#fec6c6aff8dd6fce580ae6bc5345084cd702bb62" @@ -1339,6 +1394,11 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + "@types/node@*": version "18.11.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" @@ -1371,11 +1431,31 @@ dependencies: "@types/yargs-parser" "*" +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@^8.5.0: version "8.8.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.8.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +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-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -1422,6 +1502,47 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + is-string "^1.0.7" + +array.prototype.flat@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + babel-jest@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.3.1.tgz#05c83e0d128cd48c453eea851482a38782249f44" @@ -1560,6 +1681,14 @@ builtin-modules@^3.3.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1670,6 +1799,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +confusing-browser-globals@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== + convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" @@ -1687,7 +1821,7 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.4" -cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1704,7 +1838,14 @@ css-tree@^2.3.1: mdn-data "2.0.30" source-map-js "^1.0.1" -debug@^4.1.0, debug@^4.1.1: +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1716,11 +1857,24 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +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== + deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +define-properties@^1.1.3, define-properties@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1731,6 +1885,20 @@ diff-sequences@^29.3.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +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" + electron-to-chromium@^1.4.251: version "1.4.284" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" @@ -1753,6 +1921,70 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.21.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" + integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.4" + is-array-buffer "^3.0.1" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1768,11 +2000,173 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-airbnb-base@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" + integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.5" + semver "^6.3.0" + +eslint-config-prettier@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz#dec1d29ab728f4fa63061774e1672ac4e363d207" + integrity sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA== + +eslint-import-resolver-node@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== + dependencies: + debug "^3.2.7" + is-core-module "^2.11.0" + resolve "^1.22.1" + +eslint-module-utils@^2.7.4: + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@^2.27.5: + version "2.27.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.7.4" + has "^1.0.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.6" + resolve "^1.22.1" + semver "^6.3.0" + tsconfig-paths "^3.14.1" + +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@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.34.0: + version "8.34.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.34.0.tgz#fe0ab0ef478104c1f9ebc5537e303d25a8fb22d6" + integrity sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg== + dependencies: + "@eslint/eslintrc" "^1.4.1" + "@humanwhocodes/config-array" "^0.11.8" + "@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.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.4.0" + esquery "^1.4.0" + 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" + grapheme-splitter "^1.0.4" + 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-sdsl "^4.1.4" + 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" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" + integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.2.tgz#c6d3fee05dd665808e2ad870631f221f5617b1d1" + integrity sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng== + 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@^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== + estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" @@ -1814,11 +2208,33 @@ expect@^29.3.1: jest-message-util "^29.3.1" jest-util "^29.3.1" -fast-json-stable-stringify@^2.1.0: +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-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity 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" + fb-watchman@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" @@ -1826,6 +2242,13 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +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" @@ -1841,6 +2264,34 @@ find-up@^4.0.0, find-up@^4.1.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" + +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== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1856,6 +2307,21 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -1866,6 +2332,15 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -1876,6 +2351,21 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.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, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -1904,11 +2394,42 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +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" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +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== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1919,6 +2440,30 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1941,6 +2486,19 @@ husky@^8.0.0: resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== +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== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -1967,11 +2525,44 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +internal-slot@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + +is-array-buffer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" + integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-typed-array "^1.1.10" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-builtin-module@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.0.tgz#bb0310dfe881f144ca83f30100ceb10cf58835e0" @@ -1979,13 +2570,30 @@ is-builtin-module@^3.2.0: dependencies: builtin-modules "^3.3.0" -is-core-module@^2.9.0: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== dependencies: has "^1.0.3" +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +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" @@ -1996,16 +2604,40 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@^4.0.0, 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-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + 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-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-reference@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" @@ -2013,11 +2645,58 @@ is-reference@1.2.1: dependencies: "@types/estree" "*" +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2426,6 +3105,11 @@ jest@^29.3.1: import-local "^3.0.2" jest-cli "^29.3.1" +js-sdsl@^4.1.4: + version "4.3.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" + integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2439,6 +3123,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -2454,6 +3145,23 @@ 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@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + json5@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.2.tgz#64471c5bdcc564c18f7c1d4df2e2297f2457c5ab" @@ -2469,6 +3177,14 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +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" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -2481,11 +3197,23 @@ 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.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -2544,7 +3272,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, 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== @@ -2558,11 +3286,21 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2590,6 +3328,44 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +object-inspect@^1.12.2, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -2604,6 +3380,18 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +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" + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2611,7 +3399,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== @@ -2625,11 +3413,25 @@ 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" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -2682,6 +3484,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== + +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.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== + pretty-format@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" @@ -2699,6 +3518,16 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +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== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -2735,6 +3564,20 @@ regenerator-transform@^0.15.1: dependencies: "@babel/runtime" "^7.8.4" +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + regexpu-core@^5.2.1: version "5.2.2" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.2.tgz#3e4e5d12103b64748711c3aad69934d7718e75fc" @@ -2771,6 +3614,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -2790,6 +3638,18 @@ resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +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" + rollup-plugin-node-externals@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/rollup-plugin-node-externals/-/rollup-plugin-node-externals-5.0.3.tgz#77522654ddbae6f28f6ae15a849d54427d5a637d" @@ -2802,11 +3662,27 @@ rollup@^3.8.1: optionalDependencies: fsevents "~2.3.2" +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" + safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -2838,6 +3714,15 @@ shebang-regex@^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" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -2918,6 +3803,24 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2925,6 +3828,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -2935,7 +3843,7 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.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== @@ -2985,6 +3893,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +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== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -3002,16 +3915,57 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tsconfig-paths@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.6" + strip-bom "^3.0.0" + +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-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +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" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -3043,6 +3997,13 @@ update-browserslist-db@^1.0.9: 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" + v8-to-istanbul@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" @@ -3059,6 +4020,29 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3066,6 +4050,11 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"