diff --git a/.eslintrc.js b/.eslintrc.js index a103982c..06edca50 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,18 +3,33 @@ /** @type {import('eslint').Linter.Config} */ const config = { extends: ['stylelint', 'plugin:node/recommended', 'prettier'], + parser: '@babel/eslint-parser', parserOptions: { ecmaVersion: 2020, sourceType: 'script', + requireConfigFile: false, + babelOptions: { + presets: [['@babel/preset-env', { targets: { node: '4' } }]], + }, }, env: { node: true, es2020: true, }, rules: { + strict: ['error', 'safe'], 'node/no-missing-require': ['error', { allowModules: ['vscode'] }], 'require-jsdoc': 'error', + 'no-warning-comments': ['warn', { terms: ['todo'], location: 'start' }], }, + overrides: [ + { + files: ['**/__tests__/**/*'], + rules: { + 'node/no-unpublished-require': 'off', + }, + }, + ], }; module.exports = config; diff --git a/.github/ISSUE_TEMPLATE/REPORT_A_BUG.md b/.github/ISSUE_TEMPLATE/REPORT_A_BUG.md index e5ab515c..97543849 100644 --- a/.github/ISSUE_TEMPLATE/REPORT_A_BUG.md +++ b/.github/ISSUE_TEMPLATE/REPORT_A_BUG.md @@ -36,7 +36,7 @@ e.g. "Yes" e.g. `0.84.0` -> Which version of stylelint are you using? +> Which version of Stylelint are you using? e.g. `13.2.0` @@ -52,4 +52,4 @@ e.g. "No warnings to be flagged." e.g. "The following warnings were flagged:" - + diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index ce1811a4..77688477 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -61,16 +61,16 @@ jobs: - name: Download VS Code run: npm run download-vscode - - name: Run lib tests - run: npm run test:lib -- --coverage - - name: Run unit tests run: npm run test:unit -- --coverage - - name: Run VS Code tests (Linux) + - name: Run integration tests + run: npm run test:integration -- --coverage + + - name: Run end-to-end tests (Linux) if: runner.os == 'Linux' - run: xvfb-run -a npm run test:workspace -- --silent + run: xvfb-run -a npm run test:e2e -- --silent - - name: Run VS Code tests (non-Linux) + - name: Run end-to-end tests (non-Linux) if: runner.os != 'Linux' - run: npm run test:workspace -- --silent + run: npm run test:e2e -- --silent diff --git a/.gitignore b/.gitignore index cd24498c..3d5f938f 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ eggs parts lib64 .sass-cache +*.tsbuildinfo # ------------------------------------------------- # Your own project's ignores diff --git a/.vscode/launch.json b/.vscode/launch.json index 113e8c14..974dde80 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,8 +5,14 @@ "name": "Launch Extension", "type": "extensionHost", "request": "launch", + "preLaunchTask": "Bundle Extension (Watch)", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}", "${workspaceRoot}/fixture.css"], + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}", + "${workspaceRoot}/fixture.css", + "--trace-warnings" + ], + "env": { "NODE_ENV": "development" }, "stopOnEntry": false }, { diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..9fd962a3 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,38 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Bundle Extension (Watch)", + "type": "shell", + "isBackground": true, + "command": "npm run bundle-watch", + "problemMatcher": [ + { + "source": "esbuild", + "applyTo": "closedDocuments", + "severity": "error", + "fileLocation": "relative", + "pattern": [ + { + "regexp": "> (.*?):([0-9]+):([0-9]+): (warning|error): (.+)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "\\[watch\\] build started" + }, + "endsPattern": { + "regexp": "\\[watch\\] build finished" + } + } + } + ] + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bde5034..19ce47eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Breaking Changes + +- Dropped support for Stylelint 13 and prior; only Stylelint 14 is supported now. See the [migration guide](README.md#%EF%B8%8F-stylelint-13x-and-prior-is-no-longer-supported) for more details. +- Removed bundled copy of Stylelint; local or global installation is now required. See the [migration guide](README.md#%EF%B8%8F-stylelint-is-no-longer-bundled) for more details. +- Validation and completion now only works for documents with language identifiers `css`, `less`, and `postcss` by default. See the [migration guide](README.md#%EF%B8%8F-only-css-and-postcss-are-validated-by-default) for more details. +- `stylelint.syntax` configuration option removed; use `stylelint.customSyntax` instead. See the [migration guide](README.md#%EF%B8%8F-only-css-and-postcss-are-validated-by-default) for more details. + +### Changes + +- Updated [vscode-languageserver](https://github.com/Microsoft/vscode-languageserver-node) to v7, conforming to LSP v3.16.0. + ## [0.87.6](https://github.com/stylelint/vscode-stylelint/compare/v0.87.5...v0.87.6) (2021-10-04) ### Fixed diff --git a/__mocks__/os.js b/__mocks__/os.js index dcf04eee..2678626e 100644 --- a/__mocks__/os.js +++ b/__mocks__/os.js @@ -1,6 +1,6 @@ 'use strict'; -const os = jest.createMockFromModule('os'); +const os = jest.requireActual('os'); /** * Mock platform. diff --git a/__mocks__/path.js b/__mocks__/path.js index e87cda18..0e6bda4f 100644 --- a/__mocks__/path.js +++ b/__mocks__/path.js @@ -4,35 +4,74 @@ const path = jest.requireActual('path'); /** * Mock platform. - * @type {'posix' | 'win32'} + * @type {'posix' | 'win32' | undefined} */ -let mockPlatform = 'posix'; +let mockPlatform = undefined; /** - * Sets the mock platform. - * @param {'posix' | 'win32'} platform + * Sets the mock platform. A value of `undefined` will use the actual platform. + * @param {'posix' | 'win32'} [platform] * @returns {void} */ const __mockPlatform = (platform) => { mockPlatform = platform; }; +/** + * @type {{ + * default: Record, + * posix: Record, + * win32: Record, + * }} + */ +const mockedFns = { + default: {}, + posix: {}, + win32: {}, +}; + const pathProxy = new Proxy(path, { get(_, name) { if (name === '__mockPlatform') { return __mockPlatform; } + if (!mockPlatform) { + if (typeof path[name] === 'function') { + if (mockedFns.default[name]) { + return mockedFns.default[name]; + } + + mockedFns.default[name] = jest.fn(path[name]); + + return mockedFns.default[name]; + } + + return path[name]; + } + if (mockPlatform === 'win32') { if (typeof path.win32[name] === 'function') { - return jest.fn(path.win32[name]); + if (mockedFns.win32[name]) { + return mockedFns.win32[name]; + } + + mockedFns.win32[name] = jest.fn(path.win32[name]); + + return mockedFns.win32[name]; } return path.win32[name]; } if (typeof path.posix[name] === 'function') { - return jest.fn(path.posix[name]); + if (mockedFns.posix[name]) { + return mockedFns.posix[name]; + } + + mockedFns.posix[name] = jest.fn(path.posix[name]); + + return mockedFns.posix[name]; } return path.posix[name]; diff --git a/__mocks__/vscode-languageserver/node.js b/__mocks__/vscode-languageserver/node.js new file mode 100644 index 00000000..8e6e0ffc --- /dev/null +++ b/__mocks__/vscode-languageserver/node.js @@ -0,0 +1,41 @@ +'use strict'; + +const nodeLSP = jest.createMockFromModule('vscode-languageserver/node'); + +/** @typedef {(globalModulesPath?: string, cwd?: string, trace?: TracerFn) => any} MockResolver */ + +/** @type {{[package: string]: MockResolver}} */ +let mockedResolutions = {}; + +/** + * Mocks module resolution for a package. + * @param {string} packageName + * @param {MockResolver} resolver + */ +nodeLSP.Files.__mockResolution = (packageName, resolver) => { + mockedResolutions[packageName] = resolver; +}; + +/** + * Resets all mocked resolutions. + */ +nodeLSP.Files.__resetMockedResolutions = () => { + mockedResolutions = {}; +}; + +/** @type {typeof import('vscode-languageserver/node').Files.resolve} */ +const mockResolve = async (packageName, globalPath, cwd, trace) => { + if (mockedResolutions[packageName]) { + const resolved = mockedResolutions[packageName](globalPath, cwd, trace); + + if (resolved) { + return resolved; + } + } + + throw Error(`Failed to resolve module: ${packageName}`); +}; + +nodeLSP.Files.resolve = jest.fn(mockResolve); + +module.exports = nodeLSP; diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..6071ce0f --- /dev/null +++ b/babel.config.js @@ -0,0 +1,14 @@ +'use strict'; + +const { engines } = require('./package.json'); + +// Get only the major and minor version +// e.g. ">=14.16.0" => "14.16" +const nodeVersion = engines.node.match(/(\d+\.\d+)(?:\.\d+)?/)?.[1]; + +/** @type {babel.TransformOptions} */ +const config = { + presets: [['@babel/preset-env', { targets: { node: nodeVersion } }]], +}; + +module.exports = config; diff --git a/jest.config.js b/jest.config.js index cab8e47e..351e524d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,9 +3,9 @@ /** @type {import('@jest/types').Config.InitialOptions} */ const config = { projects: [ - '/test/lib/jest.config.js', '/test/unit/jest.config.js', - '/test/workspace/jest.config.js', + '/test/integration/jest.config.js', + '/test/e2e/jest.config.js', ], }; diff --git a/package-lock.json b/package-lock.json index 37eb1f74..12327de7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,39 @@ { "name": "vscode-stylelint", - "version": "0.87.6", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-stylelint", - "version": "0.87.6", + "version": "1.0.0", "license": "MIT", "dependencies": { + "@types/triple-beam": "^1.3.2", "fast-diff": "^1.2.0", "path-is-inside": "^1.0.2", + "semver": "^7.3.5", + "triple-beam": "^1.3.0", "vscode-languageclient": "^7.0.0", "vscode-languageserver": "^7.0.0", + "vscode-languageserver-protocol": "^3.16.0", "vscode-languageserver-textdocument": "^1.0.2", "vscode-languageserver-types": "^3.16.0", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "winston": "^3.3.3", + "winston-transport": "^4.4.0" }, "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/eslint-parser": "^7.15.8", + "@babel/preset-env": "^7.15.8", "@stylelint/postcss-css-in-js": "^0.37.2", "@stylelint/prettier-config": "^2.0.0", "@types/eslint": "^7.28.1", "@types/fs-extra": "^9.0.13", "@types/jest": "^27.0.1", "@types/path-is-inside": "^1.0.0", + "@types/semver": "^7.3.9", "@types/vscode": "1.56.0", "@vscode/test-electron": "^1.6.2", "esbuild": "^0.13.4", @@ -39,7 +49,7 @@ "postcss-sass": "^0.5.0", "postcss-scss": "^4.0.1", "prettier": "^2.3.0", - "stylelint": "git+https://git@github.com/stylelint/stylelint#v14", + "stylelint": "^14.0.0", "stylelint-processor-glamorous": "^0.3.0", "stylelint-processor-styled-components": "^1.10.0", "typescript": "^4.4.3", @@ -69,20 +79,20 @@ } }, "node_modules/@babel/core": { - "version": "7.15.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", - "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", + "@babel/parser": "^7.15.8", "@babel/template": "^7.15.4", "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/types": "^7.15.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -99,9 +109,9 @@ } }, "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "dependencies": { "@babel/highlight": "^7.14.5" @@ -128,13 +138,40 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", - "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4", + "@babel/types": "^7.15.6", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -151,6 +188,31 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", + "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", + "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", + "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-compilation-targets": { "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", @@ -178,6 +240,82 @@ "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", + "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", + "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-function-name": { "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", @@ -241,9 +379,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", - "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.15.4", @@ -280,6 +418,20 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", + "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-wrap-function": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-replace-supers": { "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", @@ -307,6 +459,18 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", + "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", @@ -337,6 +501,21 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", + "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helpers": { "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", @@ -437,9 +616,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", - "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -448,145 +627,213 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", + "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", + "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", + "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", + "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { + "node_modules/@babel/plugin-proposal-optional-chaining": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -595,12 +842,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-typescript": { + "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", "dev": true, "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { @@ -610,2323 +858,4054 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { + "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", + "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { + "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", - "to-fast-properties": "^2.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@babel/helper-plugin-utils": "^7.8.3" }, - "engines": { - "node": ">=10.10.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/console": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.5.tgz", - "integrity": "sha512-smtlRF9vNKorRMCUtJ+yllIoiY8oFmfFG7xlzsAE76nKEwXNhjPOJIsc7Dv+AUitVt76t+KjIpUP9m98Crn2LQ==", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.2.5", - "jest-util": "^27.2.5", - "slash": "^3.0.0" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/core": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.5.tgz", - "integrity": "sha512-VR7mQ+jykHN4WO3OvusRJMk4xCa2MFLipMS+43fpcRGaYrN1KwMATfVEXif7ccgFKYGy5D1TVXTNE4mGq/KMMA==", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "dependencies": { - "@jest/console": "^27.2.5", - "@jest/reporters": "^27.2.5", - "@jest/test-result": "^27.2.5", - "@jest/transform": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.2.5", - "jest-config": "^27.2.5", - "jest-haste-map": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.2.5", - "jest-resolve-dependencies": "^27.2.5", - "jest-runner": "^27.2.5", - "jest-runtime": "^27.2.5", - "jest-snapshot": "^27.2.5", - "jest-util": "^27.2.5", - "jest-validate": "^27.2.5", - "jest-watcher": "^27.2.5", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/environment": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.5.tgz", - "integrity": "sha512-XvUW3q6OUF+54SYFCgbbfCd/BKTwm5b2MGLoc2jINXQLKQDTCS2P2IrpPOtQ08WWZDGzbhAzVhOYta3J2arubg==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.2.5" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/fake-timers": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.5.tgz", - "integrity": "sha512-ZGUb6jg7BgwY+nmO0TW10bc7z7Hl2G/UTAvmxEyZ/GgNFoa31tY9/cgXmqcxnnZ7o5Xs7RAOz3G1SKIj8IVDlg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.2.5", - "jest-mock": "^27.2.5", - "jest-util": "^27.2.5" + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/globals": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.5.tgz", - "integrity": "sha512-naRI537GM+enFVJQs6DcwGYPn/0vgJNb06zGVbzXfDfe/epDPV73hP1vqO37PqSKDeOXM2KInr6ymYbL1HTP7g==", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "dependencies": { - "@jest/environment": "^27.2.5", - "@jest/types": "^27.2.5", - "expect": "^27.2.5" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/reporters": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.5.tgz", - "integrity": "sha512-zYuR9fap3Q3mxQ454VWF8I6jYHErh368NwcKHWO2uy2fwByqBzRHkf9j2ekMDM7PaSTWcLBSZyd7NNxR1iHxzQ==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.2.5", - "@jest/test-result": "^27.2.5", - "@jest/transform": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.2.5", - "jest-resolve": "^27.2.5", - "jest-util": "^27.2.5", - "jest-worker": "^27.2.5", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "dev": true, "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/test-result": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.5.tgz", - "integrity": "sha512-ub7j3BrddxZ0BdSnM5JCF6cRZJ/7j3wgdX0+Dtwhw2Po+HKsELCiXUTvh+mgS4/89mpnU1CPhZxe2mTvuLPJJg==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", "dev": true, "dependencies": { - "@jest/console": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/test-sequencer": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.5.tgz", - "integrity": "sha512-8j8fHZRfnjbbdMitMAGFKaBZ6YqvFRFJlMJzcy3v75edTOqc7RY65S9JpMY6wT260zAcL2sTQRga/P4PglCu3Q==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", "dev": true, "dependencies": { - "@jest/test-result": "^27.2.5", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.2.5", - "jest-runtime": "^27.2.5" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/transform": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.5.tgz", - "integrity": "sha512-29lRtAHHYGALbZOx343v0zKmdOg4Sb0rsA1uSv0818bvwRhs3TyElOmTVXlrw0v1ZTqXJCAH/cmoDXimBhQOJQ==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.2.5", - "micromatch": "^4.0.4", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", + "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", + "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "globals": "^11.1.0" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", + "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@stylelint/postcss-css-in-js": { - "version": "0.37.2", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", - "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", "dev": true, "dependencies": { - "@babel/core": ">=7.9.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "postcss": ">=7.0.0", - "postcss-syntax": ">=0.36.2" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@stylelint/prettier-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stylelint/prettier-config/-/prettier-config-2.0.0.tgz", - "integrity": "sha512-CjOqoMNg/GcOekLY/3w5oxOVXX6xsoOCy+ZJeGpjLQUvMIxExy7p/AF87Pz9gkC+ngXYHM4gA0bnwKhWXMg2Pg==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", "dev": true, "dependencies": { - "prettier-plugin-packagejson": "^2.2.0" - } + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", + "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, "engines": { - "node": ">= 6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/eslint": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", - "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", + "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", "dev": true, "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.15.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true - }, - "node_modules/@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", + "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", "dev": true, "dependencies": { - "@types/node": "*" + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", "dev": true, "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", + "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", "dev": true, "dependencies": { - "@types/node": "*" + "@babel/helper-create-regexp-features-plugin": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", + "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/jest": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", - "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", "dev": true, "dependencies": { - "jest-diff": "^27.0.0", - "pretty-format": "^27.0.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@types/node": { - "version": "16.9.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", - "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", - "dev": true + "node_modules/@babel/plugin-transform-spread": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", + "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "node_modules/@types/path-is-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/path-is-inside/-/path-is-inside-1.0.0.tgz", - "integrity": "sha512-hfnXRGugz+McgX2jxyy5qz9sB21LRzlGn24zlwN2KEgoPtEvjzNRrLtUkOOebPDPZl3Rq7ywKxYvylVcEZDnEw==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "node_modules/@types/vscode": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz", - "integrity": "sha512-Q5VmQxOx+L1Y6lIJiGcJzwcyV3pQo/eiW8P+7sNLhFI16tJCwtua2DLjHRcpjbCLNVYpQM73kzfFo1Z0HyP9eQ==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", - "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.31.2", - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/typescript-estree": "4.31.2", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.9.0" }, "peerDependencies": { - "eslint": "*" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=6.9.0" }, "peerDependencies": { - "eslint": ">=5" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", - "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "@babel/helper-plugin-utils": "^7.14.5" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", - "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", - "dev": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", - "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "@typescript-eslint/visitor-keys": "4.31.2", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.9.0" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.31.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", - "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.2", - "eslint-visitor-keys": "^2.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@vscode/test-electron": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-1.6.2.tgz", - "integrity": "sha512-W01ajJEMx6223Y7J5yaajGjVs1QfW3YGkkOJHVKfAMEqNB1ZHN9wCcViehv5ZwVSSJnjhu6lYEYgwBdHtCxqhQ==", + "node_modules/@babel/preset-env": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", + "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", "dev": true, "dependencies": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "rimraf": "^3.0.2", - "unzipper": "^0.10.11" + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", + "@babel/plugin-proposal-async-generator-functions": "^7.15.8", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.15.4", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.15.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.15.3", + "@babel/plugin-transform-classes": "^7.15.4", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.15.4", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.15.4", + "@babel/plugin-transform-modules-systemjs": "^7.15.4", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.15.4", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.15.8", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.15.6", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.5", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.16.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=8.9.3" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "semver": "bin/semver.js" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "node_modules/@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, "engines": { - "node": ">=0.4.0" + "node": ">=6.9.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "dependencies": { - "debug": "4" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">=6.9.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "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" + "@babel/highlight": "^7.14.5" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, "engines": { - "node": ">=6" + "node": ">=6.9.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { - "type-fest": "^0.21.3" + "@babel/highlight": "^7.14.5" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6.9.0" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { - "node": ">= 8" + "node": ">=10.10.0" } }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/@jest/console": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.2.5.tgz", + "integrity": "sha512-smtlRF9vNKorRMCUtJ+yllIoiY8oFmfFG7xlzsAE76nKEwXNhjPOJIsc7Dv+AUitVt76t+KjIpUP9m98Crn2LQ==", "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.2.5", + "jest-util": "^27.2.5", + "slash": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/babel-jest": { + "node_modules/@jest/core": { "version": "27.2.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.5.tgz", - "integrity": "sha512-GC9pWCcitBhSuF7H3zl0mftoKizlswaF0E3qi+rPL417wKkCB0d+Sjjb0OfXvxj7gWiBf497ldgRMii68Xz+2g==", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.2.5.tgz", + "integrity": "sha512-VR7mQ+jykHN4WO3OvusRJMk4xCa2MFLipMS+43fpcRGaYrN1KwMATfVEXif7ccgFKYGy5D1TVXTNE4mGq/KMMA==", "dev": true, "dependencies": { + "@jest/console": "^27.2.5", + "@jest/reporters": "^27.2.5", + "@jest/test-result": "^27.2.5", "@jest/transform": "^27.2.5", "@jest/types": "^27.2.5", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "jest-changed-files": "^27.2.5", + "jest-config": "^27.2.5", + "jest-haste-map": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.5", + "jest-resolve-dependencies": "^27.2.5", + "jest-runner": "^27.2.5", + "jest-runtime": "^27.2.5", + "jest-snapshot": "^27.2.5", + "jest-util": "^27.2.5", + "jest-validate": "^27.2.5", + "jest-watcher": "^27.2.5", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "node_modules/@jest/environment": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.2.5.tgz", + "integrity": "sha512-XvUW3q6OUF+54SYFCgbbfCd/BKTwm5b2MGLoc2jINXQLKQDTCS2P2IrpPOtQ08WWZDGzbhAzVhOYta3J2arubg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" + "@jest/fake-timers": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.2.5" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "node_modules/@jest/fake-timers": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.2.5.tgz", + "integrity": "sha512-ZGUb6jg7BgwY+nmO0TW10bc7z7Hl2G/UTAvmxEyZ/GgNFoa31tY9/cgXmqcxnnZ7o5Xs7RAOz3G1SKIj8IVDlg==", "dev": true, "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.2.5", + "jest-mock": "^27.2.5", + "jest-util": "^27.2.5" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "node_modules/@jest/globals": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.2.5.tgz", + "integrity": "sha512-naRI537GM+enFVJQs6DcwGYPn/0vgJNb06zGVbzXfDfe/epDPV73hP1vqO37PqSKDeOXM2KInr6ymYbL1HTP7g==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.2.5", + "@jest/types": "^27.2.5", + "expect": "^27.2.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "node_modules/@jest/reporters": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.2.5.tgz", + "integrity": "sha512-zYuR9fap3Q3mxQ454VWF8I6jYHErh368NwcKHWO2uy2fwByqBzRHkf9j2ekMDM7PaSTWcLBSZyd7NNxR1iHxzQ==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.2.0", - "babel-preset-current-node-syntax": "^1.0.0" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.2.5", + "@jest/test-result": "^27.2.5", + "@jest/transform": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.2.5", + "jest-resolve": "^27.2.5", + "jest-util": "^27.2.5", + "jest-worker": "^27.2.5", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true, - "bin": { - "babylon": "bin/babylon.js" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/big-integer": { - "version": "1.6.49", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz", - "integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw==", + "node_modules/@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, "engines": { - "node": ">=0.6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "node_modules/@jest/test-result": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.2.5.tgz", + "integrity": "sha512-ub7j3BrddxZ0BdSnM5JCF6cRZJ/7j3wgdX0+Dtwhw2Po+HKsELCiXUTvh+mgS4/89mpnU1CPhZxe2mTvuLPJJg==", "dev": true, "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" + "@jest/console": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": "*" - } - }, - "node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@jest/test-sequencer": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.2.5.tgz", + "integrity": "sha512-8j8fHZRfnjbbdMitMAGFKaBZ6YqvFRFJlMJzcy3v75edTOqc7RY65S9JpMY6wT260zAcL2sTQRga/P4PglCu3Q==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "@jest/test-result": "^27.2.5", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.5", + "jest-runtime": "^27.2.5" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", - "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "node_modules/@jest/transform": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.2.5.tgz", + "integrity": "sha512-29lRtAHHYGALbZOx343v0zKmdOg4Sb0rsA1uSv0818bvwRhs3TyElOmTVXlrw0v1ZTqXJCAH/cmoDXimBhQOJQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001259", - "electron-to-chromium": "^1.3.846", - "escalade": "^3.1.1", - "nanocolors": "^0.1.5", - "node-releases": "^1.1.76" - }, - "bin": { - "browserslist": "cli.js" + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.2.5", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", "dev": true, "dependencies": { - "node-int64": "^0.4.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, "engines": { - "node": ">=0.10" + "node": ">= 8" } }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { - "node": ">=0.2.0" + "node": ">= 8" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 8" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "type-detect": "4.0.8" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "node_modules/@sinonjs/fake-timers": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", + "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001260", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001260.tgz", - "integrity": "sha512-Fhjc/k8725ItmrvW5QomzxLeojewxvqiYCKeFcfFEhut28IVLdpHU19dneOmltZQIE5HNbawj1HYD+1f2bM1Dg==", + "node_modules/@stylelint/postcss-css-in-js": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", + "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==", "dev": true, "dependencies": { - "nanocolors": "^0.1.0" + "@babel/core": ">=7.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" } }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "node_modules/@stylelint/prettier-config": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@stylelint/prettier-config/-/prettier-config-2.0.0.tgz", + "integrity": "sha512-CjOqoMNg/GcOekLY/3w5oxOVXX6xsoOCy+ZJeGpjLQUvMIxExy7p/AF87Pz9gkC+ngXYHM4gA0bnwKhWXMg2Pg==", "dev": true, "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" + "prettier-plugin-packagejson": "^2.2.0" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 6" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/@types/babel__core": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "@babel/types": "^7.0.0" } }, - "node_modules/clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { - "is-regexp": "^2.0.0" - }, - "engines": { - "node": ">=6" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "dependencies": { + "@babel/types": "^7.3.0" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/eslint": { + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", + "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "@types/node": "*" } }, - "node_modules/comment-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, - "engines": { - "node": ">= 12.0.0" + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.1" + "@types/node": "*" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, - "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "@types/istanbul-lib-report": "*" } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "node_modules/@types/jest": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", + "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" + "dependencies": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" } }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/path-is-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/path-is-inside/-/path-is-inside-1.0.0.tgz", + "integrity": "sha512-hfnXRGugz+McgX2jxyy5qz9sB21LRzlGn24zlwN2KEgoPtEvjzNRrLtUkOOebPDPZl3Rq7ywKxYvylVcEZDnEw==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/triple-beam": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", + "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" + }, + "node_modules/@types/vscode": { + "version": "1.56.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz", + "integrity": "sha512-Q5VmQxOx+L1Y6lIJiGcJzwcyV3pQo/eiW8P+7sNLhFI16tJCwtua2DLjHRcpjbCLNVYpQM73kzfFo1Z0HyP9eQ==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" + "@types/yargs-parser": "*" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", + "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", "dev": true, "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=6.0" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", + "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", "dev": true, "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2" }, "engines": { - "node": ">=0.10.0" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "node_modules/@typescript-eslint/types": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", + "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", + "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", + "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "@typescript-eslint/types": "4.31.2", + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/@vscode/test-electron": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-1.6.2.tgz", + "integrity": "sha512-W01ajJEMx6223Y7J5yaajGjVs1QfW3YGkkOJHVKfAMEqNB1ZHN9wCcViehv5ZwVSSJnjhu6lYEYgwBdHtCxqhQ==", "dev": true, + "dependencies": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + }, "engines": { - "node": ">=0.4.0" + "node": ">=8.9.3" } }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.4.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "debug": "4" }, "engines": { - "node": ">=8" + "node": ">= 6.0.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, "engines": { - "node": ">=6.0.0" + "node": ">=6" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { - "webidl-conversions": "^5.0.0" + "type-fest": "^0.21.3" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "readable-stream": "^2.0.2" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/electron-to-chromium": { - "version": "1.3.848", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.848.tgz", - "integrity": "sha512-wchRyBcdcmibioggdO7CbMT5QQ4lXlN/g7Mkpf1K2zINidnqij6EVu94UIZ+h5nB2S9XD4bykqFv9LonAWLFyw==", - "dev": true + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/babel-jest": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.2.5.tgz", + "integrity": "sha512-GC9pWCcitBhSuF7H3zl0mftoKizlswaF0E3qi+rPL417wKkCB0d+Sjjb0OfXvxj7gWiBf497ldgRMii68Xz+2g==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1" + "@jest/transform": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" }, "engines": { - "node": ">=8.6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, "dependencies": { - "is-arrayish": "^0.2.1" + "object.assign": "^4.1.0" } }, - "node_modules/es-abstract": { - "version": "1.18.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", - "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-string": "^1.0.7", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/babel-plugin-jest-hoist": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/esbuild": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.4.tgz", - "integrity": "sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg==", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" }, - "optionalDependencies": { - "esbuild-android-arm64": "0.13.4", - "esbuild-darwin-64": "0.13.4", - "esbuild-darwin-arm64": "0.13.4", - "esbuild-freebsd-64": "0.13.4", - "esbuild-freebsd-arm64": "0.13.4", - "esbuild-linux-32": "0.13.4", - "esbuild-linux-64": "0.13.4", - "esbuild-linux-arm": "0.13.4", - "esbuild-linux-arm64": "0.13.4", - "esbuild-linux-mips64le": "0.13.4", - "esbuild-linux-ppc64le": "0.13.4", - "esbuild-openbsd-64": "0.13.4", - "esbuild-sunos-64": "0.13.4", - "esbuild-windows-32": "0.13.4", - "esbuild-windows-64": "0.13.4", - "esbuild-windows-arm64": "0.13.4" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/esbuild-android-arm64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz", - "integrity": "sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/esbuild-darwin-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz", - "integrity": "sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA==", - "cpu": [ - "x64" - ], + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "optional": true, - "os": [ - "darwin" - ] + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/esbuild-darwin-arm64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz", - "integrity": "sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg==", - "cpu": [ - "arm64" - ], + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", + "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", "dev": true, - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.16.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/esbuild-freebsd-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz", - "integrity": "sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw==", - "cpu": [ - "x64" - ], + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ] + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz", - "integrity": "sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA==", - "cpu": [ - "arm64" - ], + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ] + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "node_modules/esbuild-linux-32": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz", - "integrity": "sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA==", - "cpu": [ - "ia32" - ], + "node_modules/babel-preset-jest": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "babel-plugin-jest-hoist": "^27.2.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } }, - "node_modules/esbuild-linux-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz", - "integrity": "sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ==", - "cpu": [ - "x64" - ], + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ] + "bin": { + "babylon": "bin/babylon.js" + } }, - "node_modules/esbuild-linux-arm": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz", - "integrity": "sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/esbuild-linux-arm64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz", - "integrity": "sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ==", - "cpu": [ - "arm64" - ], + "node_modules/big-integer": { + "version": "1.6.49", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz", + "integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw==", "dev": true, - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=0.6" + } }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz", - "integrity": "sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw==", - "cpu": [ - "mips64el" - ], + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true, - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz", - "integrity": "sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q==", - "cpu": [ - "ppc64" - ], + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "optional": true, - "os": [ - "linux" - ] + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/esbuild-openbsd-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz", - "integrity": "sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw==", - "cpu": [ - "x64" - ], + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", "dev": true, - "optional": true, - "os": [ - "openbsd" - ] + "dependencies": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, - "node_modules/esbuild-sunos-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz", - "integrity": "sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ==", - "cpu": [ - "x64" - ], + "node_modules/browserslist/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "optional": true, - "os": [ - "sunos" - ] + "dependencies": { + "node-int64": "^0.4.0" + } }, - "node_modules/esbuild-windows-32": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz", - "integrity": "sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg==", - "cpu": [ - "ia32" - ], + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", "dev": true, - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": ">=0.10" + } }, - "node_modules/esbuild-windows-64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz", - "integrity": "sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q==", - "cpu": [ - "x64" - ], + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true, - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": ">=0.2.0" + } }, - "node_modules/esbuild-windows-arm64": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz", - "integrity": "sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg==", - "cpu": [ - "arm64" - ], + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, - "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "node_modules/caniuse-lite": { + "version": "1.0.30001267", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001267.tgz", + "integrity": "sha512-r1mjTzAuJ9W8cPBGbbus8E0SKcUP7gn03R14Wk8FlAlqhH9hroy9nLqmpuXlfKEw/oILW+FGz47ipXV2O7x8lg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "dependencies": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "dependencies": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comment-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/core-js-compat": { + "version": "3.18.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", + "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", + "dev": true, + "dependencies": { + "browserslist": "^4.17.3", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.871", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", + "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.18.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.6.tgz", + "integrity": "sha512-kAeIT4cku5eNLNuUKhlmtuk1/TRZvQoYccn6TO0cSVdf1kzB0T7+dYuVK9MWM7l+/53W2Q8M7N2c6MQvhXFcUQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-string": "^1.0.7", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.4.tgz", + "integrity": "sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "esbuild-android-arm64": "0.13.4", + "esbuild-darwin-64": "0.13.4", + "esbuild-darwin-arm64": "0.13.4", + "esbuild-freebsd-64": "0.13.4", + "esbuild-freebsd-arm64": "0.13.4", + "esbuild-linux-32": "0.13.4", + "esbuild-linux-64": "0.13.4", + "esbuild-linux-arm": "0.13.4", + "esbuild-linux-arm64": "0.13.4", + "esbuild-linux-mips64le": "0.13.4", + "esbuild-linux-ppc64le": "0.13.4", + "esbuild-openbsd-64": "0.13.4", + "esbuild-sunos-64": "0.13.4", + "esbuild-windows-32": "0.13.4", + "esbuild-windows-64": "0.13.4", + "esbuild-windows-arm64": "0.13.4" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz", + "integrity": "sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/esbuild-darwin-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz", + "integrity": "sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz", + "integrity": "sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz", + "integrity": "sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz", + "integrity": "sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-linux-32": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz", + "integrity": "sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz", + "integrity": "sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz", + "integrity": "sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz", + "integrity": "sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz", + "integrity": "sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz", + "integrity": "sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz", + "integrity": "sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/esbuild-sunos-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz", + "integrity": "sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ] + }, + "node_modules/esbuild-windows-32": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz", + "integrity": "sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz", + "integrity": "sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz", + "integrity": "sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-stylelint": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-stylelint/-/eslint-config-stylelint-14.0.0.tgz", + "integrity": "sha512-/HAEjiNNVOvSAs4J+z9G/Ybk8G8/nLy8hjzISHDZU27Cnx2BwAGFdqXnStucER8rkVnaaFyEM7p+GIC2Zzp6dA==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-jest": "^24.4.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-regexp": "^1.1.0" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-eslint-comments": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", + "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "engines": { + "node": ">=6.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-plugin-eslint-comments/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "24.4.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", + "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^4.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": ">= 4", + "eslint": ">=5" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-regexp": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.2.0.tgz", + "integrity": "sha512-yHn5D8jTmT1gmPA4Dj2ut0aGg03CkgvpKu3kG/CEQ1OcUmkoykZsiXCysaENpq/BXs60WEpz+tN2n/h4lp+Q0Q==", + "dev": true, + "dependencies": { + "comment-parser": "^1.1.2", + "eslint-utils": "^3.0.0", + "grapheme-splitter": "^1.0.4", + "jsdoctypeparser": "^9.0.0", + "refa": "^0.9.0", + "regexp-ast-analysis": "^0.3.0", + "regexpp": "^3.2.0", + "scslre": "^0.1.6" + }, + "engines": { + "node": "^12 || >=14" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-regexp/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", + "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-regex-util": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "glob": "^7.1.3" }, "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "rimraf": "bin.js" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=6.9.0" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, "engines": { - "node": ">= 0.8.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" }, - "engines": { - "node": ">= 0.8.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=8.0.0" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, - "peerDependencies": { - "eslint": ">=7.0.0" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-config-stylelint": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-stylelint/-/eslint-config-stylelint-14.0.0.tgz", - "integrity": "sha512-/HAEjiNNVOvSAs4J+z9G/Ybk8G8/nLy8hjzISHDZU27Cnx2BwAGFdqXnStucER8rkVnaaFyEM7p+GIC2Zzp6dA==", + "node_modules/git-hooks-list": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", + "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", "dev": true, - "dependencies": { - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-jest": "^24.4.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-regexp": "^1.1.0" + "funding": { + "url": "https://github.com/fisker/git-hooks-list?sponsor=1" } }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=8.10.0" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-plugin-eslint-comments": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", - "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5", - "ignore": "^5.0.5" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=6.5.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" }, - "peerDependencies": { - "eslint": ">=4.19.1" + "engines": { + "node": ">=6" } }, - "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, "engines": { - "node": ">=0.8.0" + "node": ">=6" } }, - "node_modules/eslint-plugin-eslint-comments/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "node_modules/eslint-plugin-jest": { - "version": "24.4.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.2.tgz", - "integrity": "sha512-jNMnqwX75z0RXRMXkxwb/+9ylKJYJLJ8nT8nBT0XFM5qx4IQGxP4edMawa0qGkSbHae0BDPBmi8I2QF0/F04XQ==", + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">= 4", - "eslint": ">=5" + "node": ">=8" }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=10" }, - "peerDependencies": { - "eslint": ">=5.16.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-node/node_modules/ignore": { + "node_modules/globby/node_modules/ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", @@ -2935,549 +4914,543 @@ "node": ">= 4" } }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, "bin": { - "semver": "bin/semver.js" + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" } }, - "node_modules/eslint-plugin-regexp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.2.0.tgz", - "integrity": "sha512-yHn5D8jTmT1gmPA4Dj2ut0aGg03CkgvpKu3kG/CEQ1OcUmkoykZsiXCysaENpq/BXs60WEpz+tN2n/h4lp+Q0Q==", + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, - "dependencies": { - "comment-parser": "^1.1.2", - "eslint-utils": "^3.0.0", - "grapheme-splitter": "^1.0.4", - "jsdoctypeparser": "^9.0.0", - "refa": "^0.9.0", - "regexp-ast-analysis": "^0.3.0", - "regexpp": "^3.2.0", - "scslre": "^0.1.6" - }, "engines": { - "node": "^12 || >=14" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "node": ">=6" } }, - "node_modules/eslint-plugin-regexp/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "function-bind": "^1.1.1" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "whatwg-encoding": "^1.0.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/esprima": { + "node_modules/http-proxy-agent": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.10" + "node": ">= 6" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=10.17.0" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=4.0" + "node": ">=0.10.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">= 4" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, "engines": { - "node": ">=4.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, - "engines": { - "node": ">=10" + "bin": { + "import-local-fixture": "fixtures/cli.js" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "clone-regexp": "^2.1.0" + "find-up": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=0.8.19" } }, - "node_modules/expect": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", - "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-regex-util": "^27.0.6" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", "dev": true, "dependencies": { - "reusify": "^1.0.4" + "ci-info": "^3.1.1" + }, + "bin": { + "is-ci": "bin.js" } }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "node_modules/is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dev": true, "dependencies": { - "bser": "2.1.1" + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=6" } }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=0.12.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" + "node": ">= 0.4" }, - "bin": { - "rimraf": "bin.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=0.10.0" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=6" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3486,4765 +5459,5136 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/git-hooks-list": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", - "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true, - "funding": { - "url": "https://github.com/fisker/git-hooks-list?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "dev": true, "dependencies": { - "global-prefix": "^3.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "node_modules/istanbul-reports": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz", + "integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==", "dev": true, "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/jest": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.5.tgz", + "integrity": "sha512-vDMzXcpQN4Ycaqu+vO7LX8pZwNNoKMhc+gSp6q1D8S6ftRk8gNW8cni3YFxknP95jxzQo23Lul0BI2FrWgnwYQ==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "@jest/core": "^27.2.5", + "import-local": "^3.0.2", + "jest-cli": "^27.2.5" }, "bin": { - "which": "bin/which" + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "node_modules/jest-changed-files": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.2.5.tgz", + "integrity": "sha512-jfnNJzF89csUKRPKJ4MwZ1SH27wTmX2xiAIHUHrsb/OYd9Jbo4/SXxJ17/nnx6RIifpthk3Y+LEeOk+/dDeGdw==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.5.tgz", + "integrity": "sha512-eyL9IcrAxm3Saq3rmajFCwpaxaRMGJ1KJs+7hlTDinXpJmeR3P02bheM3CYohE7UfwOBmrFMJHjgo/WPcLTM+Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.2.5", + "@jest/test-result": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.2.5", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.2.5", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-runtime": "^27.2.5", + "jest-snapshot": "^27.2.5", + "jest-util": "^27.2.5", + "pretty-format": "^27.2.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "node_modules/jest-cli": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.5.tgz", + "integrity": "sha512-XzfcOXi5WQrXqFYsDxq5RDOKY4FNIgBgvgf3ZBz4e/j5/aWep5KnsAYH5OFPMdX/TP/LFsYQMRH7kzJUMh6JKg==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "@jest/core": "^27.2.5", + "@jest/test-result": "^27.2.5", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.2.5", + "jest-util": "^27.2.5", + "jest-validate": "^27.2.5", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "node_modules/jest-config": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.5.tgz", + "integrity": "sha512-QdENtn9b5rIIYGlbDNEcgY9LDL5kcokJnXrp7x8AGjHob/XFqw1Z6p+gjfna2sUulQsQ3ce2Fvntnv+7fKYDhQ==", "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.2.5", + "@jest/types": "^27.2.5", + "babel-jest": "^27.2.5", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "jest-circus": "^27.2.5", + "jest-environment-jsdom": "^27.2.5", + "jest-environment-node": "^27.2.5", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.5", + "jest-runner": "^27.2.5", + "jest-util": "^27.2.5", + "jest-validate": "^27.2.5", + "micromatch": "^4.0.4", + "pretty-format": "^27.2.5" + }, "engines": { - "node": ">= 4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", - "dev": true - }, - "node_modules/gonzales-pe": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", - "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "node_modules/jest-diff": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz", + "integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==", "dev": true, "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "gonzales": "bin/gonzales.js" + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.5" }, "engines": { - "node": ">=0.6.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "node_modules/jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/jest-each": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.5.tgz", + "integrity": "sha512-HUPWIbJT0bXarRwKu/m7lYzqxR4GM5EhKOsu0z3t0SKtbFN6skQhpAUADM4qFShBXb9zoOuag5lcrR1x/WM+Ag==", "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "jest-util": "^27.2.5", + "pretty-format": "^27.2.5" }, "engines": { - "node": ">= 0.4.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "node_modules/jest-environment-jsdom": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.5.tgz", + "integrity": "sha512-QtRpOh/RQKuXniaWcoFE2ElwP6tQcyxHu0hlk32880g0KczdonCs5P1sk5+weu/OVzh5V4Bt1rXuQthI01mBLg==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "@jest/environment": "^27.2.5", + "@jest/fake-timers": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.2.5", + "jest-util": "^27.2.5", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-environment-node": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.5.tgz", + "integrity": "sha512-0o1LT4grm7iwrS8fIoLtwJxb/hoa3GsH7pP10P02Jpj7Mi4BXy65u46m89vEM2WfD1uFJQ2+dfDiWZNA2e6bJg==", "dev": true, + "dependencies": { + "@jest/environment": "^27.2.5", + "@jest/fake-timers": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.2.5", + "jest-util": "^27.2.5" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/jest-haste-map": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.5.tgz", + "integrity": "sha512-pzO+Gw2WLponaSi0ilpzYBE0kuVJstoXBX8YWyUebR8VaXuX4tzzn0Zp23c/WaETo7XYTGv2e8KdnpiskAFMhQ==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.2.5", + "jest-worker": "^27.2.5", + "micromatch": "^4.0.4", + "walker": "^1.0.7" }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/jest-jasmine2": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.5.tgz", + "integrity": "sha512-hdxY9Cm/CjLqu2tXeAoQHPgA4vcqlweVXYOg1+S9FeFdznB9Rti+eEBKDDkmOy9iqr4Xfbq95OkC4NFbXXPCAQ==", "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.5" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.2.5", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.2.5", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.2.5", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-runtime": "^27.2.5", + "jest-snapshot": "^27.2.5", + "jest-util": "^27.2.5", + "pretty-format": "^27.2.5", + "throat": "^6.0.1" }, "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/html-tags": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", - "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", - "dev": true, - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "node_modules/jest-leak-detector": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.5.tgz", + "integrity": "sha512-HYsi3GUR72bYhOGB5C5saF9sPdxGzSjX7soSQS+BqDRysc7sPeBwPbhbuT8DnOpijnKjgwWQ8JqvbmReYnt3aQ==", "dev": true, "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.5" }, "engines": { - "node": ">= 6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "node_modules/jest-matcher-utils": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", + "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "chalk": "^4.0.0", + "jest-diff": "^27.2.5", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.5" }, "engines": { - "node": ">= 6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/jest-message-util": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.5.tgz", + "integrity": "sha512-ggXSLoPfIYcbmZ8glgEJZ8b+e0Msw/iddRmgkoO7lDAr9SmI65IIfv7VnvTnV4FGnIIUIjzM+fHRHO5RBvyAbQ==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.2.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, "engines": { - "node": ">=10.17.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@babel/highlight": "^7.14.5" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/jest-mock": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.2.5.tgz", + "integrity": "sha512-HiMB3LqE9RzmeMzZARi2Bz3NoymxyP0gCid4y42ca1djffNtYFKgI220aC1VP1mUZ8rbpqZbHZOJ15093bZV/Q==", "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "@types/node": "*" + }, "engines": { - "node": ">= 4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, "engines": { "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "node_modules/jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "node_modules/jest-resolve": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.5.tgz", + "integrity": "sha512-q5irwS3oS73SKy3+FM/HL2T7WJftrk9BRzrXF92f7net5HMlS7lJMg/ZwxLB4YohKqjSsdksEw7n/jvMxV7EKg==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "escalade": "^3.1.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.5", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.2.5", + "jest-validate": "^27.2.5", + "resolve": "^1.20.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/jest-resolve-dependencies": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.5.tgz", + "integrity": "sha512-BSjefped31bcvvCh++/pN9ueqqN1n0+p8/58yScuWfklLm2tbPbS9d251vJhAy0ZI2pL/0IaGhOTJrs9Y4FJlg==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.2.5" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/jest-runner": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.5.tgz", + "integrity": "sha512-n41vw9RLg5TKAnEeJK9d6pGOsBOpwE89XBniK+AD1k26oIIy3V7ogM1scbDjSheji8MUPC9pNgCrZ/FHLVDNgg==", "dev": true, + "dependencies": { + "@jest/console": "^27.2.5", + "@jest/environment": "^27.2.5", + "@jest/test-result": "^27.2.5", + "@jest/transform": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.2.5", + "jest-environment-node": "^27.2.5", + "jest-haste-map": "^27.2.5", + "jest-leak-detector": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-resolve": "^27.2.5", + "jest-runtime": "^27.2.5", + "jest-util": "^27.2.5", + "jest-worker": "^27.2.5", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, "engines": { - "node": ">=0.8.19" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/jest-runner-vscode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jest-runner-vscode/-/jest-runner-vscode-2.0.0.tgz", + "integrity": "sha512-nY8t6vxa+hd5XKm41XJnA4HwBzoc2UfgZ2rwo48UxR6dMjd2pgk+nhY1zx1DQerzFgJ2sTsbcv8yStEYNoFErQ==", "dev": true, + "dependencies": { + "@jest/core": "^27.2.1", + "@vscode/test-electron": "^1.6.2", + "cosmiconfig": "^7.0.1", + "jest-cli": "^27.2.1", + "jest-environment-node": "^27.2.0" + }, "engines": { - "node": ">=8" + "node": ">=14.16.0", + "vscode": ">=1.56.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/jest-runtime": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.5.tgz", + "integrity": "sha512-N0WRZ3QszKyZ3Dm27HTBbBuestsSd3Ud5ooVho47XZJ8aSKO/X1Ag8M1dNx9XzfGVRNdB/xCA3lz8MJwIzPLLA==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@jest/console": "^27.2.5", + "@jest/environment": "^27.2.5", + "@jest/fake-timers": "^27.2.5", + "@jest/globals": "^27.2.5", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.2.5", + "@jest/transform": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-mock": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.2.5", + "jest-snapshot": "^27.2.5", + "jest-util": "^27.2.5", + "jest-validate": "^27.2.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/jest-serializer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "@types/node": "*", + "graceful-fs": "^4.2.4" }, "engines": { - "node": ">= 0.4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "node_modules/jest-snapshot": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.5.tgz", + "integrity": "sha512-2/Jkn+VN6Abwz0llBltZaiJMnL8b1j5Bp/gRIxe9YR3FCEh9qp0TXVV0dcpTGZ8AcJV1SZGQkczewkI9LP5yGw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.2.5", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.2.5", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.2.5", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-resolve": "^27.2.5", + "jest-util": "^27.2.5", + "natural-compare": "^1.4.0", + "pretty-format": "^27.2.5", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/jest-util": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.5.tgz", + "integrity": "sha512-QRhDC6XxISntMzFRd/OQ6TGsjbzA5ONO0tlAj2ElHs155x1aEr0rkYJBEysG6H/gZVH3oGFzCdAB/GA8leh8NQ==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/jest-validate": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.5.tgz", + "integrity": "sha512-XgYtjS89nhVe+UfkbLgcm+GgXKWgL80t9nTcNeejyO3t0Sj/yHE8BtIJqjZu9NXQksYbGImoQRXmQ1gP+Guffw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "leven": "^3.1.0", + "pretty-format": "^27.2.5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "node_modules/jest-watcher": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.5.tgz", + "integrity": "sha512-umV4qGozg2Dn6DTTtqAh9puPw+DGLK9AQas7+mWjiK8t0fWMpxKg8ZXReZw7L4C88DqorsGUiDgwHNZ+jkVrkQ==", "dev": true, "dependencies": { - "ci-info": "^3.1.1" + "@jest/test-result": "^27.2.5", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.2.5", + "string-length": "^4.0.1" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "node_modules/jest-worker": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.5.tgz", + "integrity": "sha512-HTjEPZtcNKZ4LnhSp02NEH4vE+5OpJ0EsOWYvGQpHgUMLngydESAAMH5Wd/asPf29+XUDQZszxpLg1BkIIA2aw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 10.13.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "node_modules/jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", "dev": true, - "engines": { - "node": ">= 0.4" + "bin": { + "jsdoctypeparser": "bin/jsdoctypeparser" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { - "node": ">=0.12.0" + "node": ">=10" } }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "node_modules/jsdom/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/is-potential-custom-element-name": { + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/known-css-properties": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.23.0.tgz", + "integrity": "sha512-h9ivI88e1lFNmTT4HovBN33Ysn0OIJG7IPG2mkpx2uniQXFWqo35QdiX7w0TovlUFXfW8aPFblP5/q0jlOr2sA==", + "dev": true + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8.0" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", "dev": true }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=4" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/logform": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" + "colors": "^1.2.1", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", + "triple-beam": "^1.3.0" } }, - "node_modules/istanbul-reports": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz", - "integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==", - "dev": true, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jest": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.2.5.tgz", - "integrity": "sha512-vDMzXcpQN4Ycaqu+vO7LX8pZwNNoKMhc+gSp6q1D8S6ftRk8gNW8cni3YFxknP95jxzQo23Lul0BI2FrWgnwYQ==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "@jest/core": "^27.2.5", - "import-local": "^3.0.2", - "jest-cli": "^27.2.5" - }, - "bin": { - "jest": "bin/jest.js" + "semver": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">=8" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-changed-files": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.2.5.tgz", - "integrity": "sha512-jfnNJzF89csUKRPKJ4MwZ1SH27wTmX2xiAIHUHrsb/OYd9Jbo4/SXxJ17/nnx6RIifpthk3Y+LEeOk+/dDeGdw==", + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "tmpl": "1.0.x" } }, - "node_modules/jest-circus": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.2.5.tgz", - "integrity": "sha512-eyL9IcrAxm3Saq3rmajFCwpaxaRMGJ1KJs+7hlTDinXpJmeR3P02bheM3CYohE7UfwOBmrFMJHjgo/WPcLTM+Q==", + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, - "dependencies": { - "@jest/environment": "^27.2.5", - "@jest/test-result": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.2.5", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.2.5", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-runtime": "^27.2.5", - "jest-snapshot": "^27.2.5", - "jest-util": "^27.2.5", - "pretty-format": "^27.2.5", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-cli": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.2.5.tgz", - "integrity": "sha512-XzfcOXi5WQrXqFYsDxq5RDOKY4FNIgBgvgf3ZBz4e/j5/aWep5KnsAYH5OFPMdX/TP/LFsYQMRH7kzJUMh6JKg==", + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true, - "dependencies": { - "@jest/core": "^27.2.5", - "@jest/test-result": "^27.2.5", - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.2.5", - "jest-util": "^27.2.5", - "jest-validate": "^27.2.5", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">= 0.10.0" } }, - "node_modules/jest-config": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.2.5.tgz", - "integrity": "sha512-QdENtn9b5rIIYGlbDNEcgY9LDL5kcokJnXrp7x8AGjHob/XFqw1Z6p+gjfna2sUulQsQ3ce2Fvntnv+7fKYDhQ==", + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.2.5", - "@jest/types": "^27.2.5", - "babel-jest": "^27.2.5", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.2.5", - "jest-environment-jsdom": "^27.2.5", - "jest-environment-node": "^27.2.5", - "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.2.5", - "jest-runner": "^27.2.5", - "jest-util": "^27.2.5", - "jest-validate": "^27.2.5", - "micromatch": "^4.0.4", - "pretty-format": "^27.2.5" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-diff": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz", - "integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==", + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.2.5" + "lru-cache": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" } }, - "node_modules/jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" } }, - "node_modules/jest-each": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.2.5.tgz", - "integrity": "sha512-HUPWIbJT0bXarRwKu/m7lYzqxR4GM5EhKOsu0z3t0SKtbFN6skQhpAUADM4qFShBXb9zoOuag5lcrR1x/WM+Ag==", + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "jest-util": "^27.2.5", - "pretty-format": "^27.2.5" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-environment-jsdom": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.2.5.tgz", - "integrity": "sha512-QtRpOh/RQKuXniaWcoFE2ElwP6tQcyxHu0hlk32880g0KczdonCs5P1sk5+weu/OVzh5V4Bt1rXuQthI01mBLg==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "dependencies": { - "@jest/environment": "^27.2.5", - "@jest/fake-timers": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.2.5", - "jest-util": "^27.2.5", - "jsdom": "^16.6.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 8" } }, - "node_modules/jest-environment-node": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.2.5.tgz", - "integrity": "sha512-0o1LT4grm7iwrS8fIoLtwJxb/hoa3GsH7pP10P02Jpj7Mi4BXy65u46m89vEM2WfD1uFJQ2+dfDiWZNA2e6bJg==", + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { - "@jest/environment": "^27.2.5", - "@jest/fake-timers": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.2.5", - "jest-util": "^27.2.5" + "braces": "^3.0.1", + "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8.6" } }, - "node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.6" } }, - "node_modules/jest-haste-map": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.2.5.tgz", - "integrity": "sha512-pzO+Gw2WLponaSi0ilpzYBE0kuVJstoXBX8YWyUebR8VaXuX4tzzn0Zp23c/WaETo7XYTGv2e8KdnpiskAFMhQ==", + "node_modules/mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.2.5", - "jest-worker": "^27.2.5", - "micromatch": "^4.0.4", - "walker": "^1.0.7" + "mime-db": "1.50.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">= 0.6" } }, - "node_modules/jest-jasmine2": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.2.5.tgz", - "integrity": "sha512-hdxY9Cm/CjLqu2tXeAoQHPgA4vcqlweVXYOg1+S9FeFdznB9Rti+eEBKDDkmOy9iqr4Xfbq95OkC4NFbXXPCAQ==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.2.5", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.2.5", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.2.5", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-runtime": "^27.2.5", - "jest-snapshot": "^27.2.5", - "jest-util": "^27.2.5", - "pretty-format": "^27.2.5", - "throat": "^6.0.1" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" } }, - "node_modules/jest-leak-detector": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.2.5.tgz", - "integrity": "sha512-HYsi3GUR72bYhOGB5C5saF9sPdxGzSjX7soSQS+BqDRysc7sPeBwPbhbuT8DnOpijnKjgwWQ8JqvbmReYnt3aQ==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dependencies": { - "jest-get-type": "^27.0.6", - "pretty-format": "^27.2.5" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "*" } }, - "node_modules/jest-matcher-utils": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", - "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.2.5" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 6" } }, - "node_modules/jest-message-util": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.5.tgz", - "integrity": "sha512-ggXSLoPfIYcbmZ8glgEJZ8b+e0Msw/iddRmgkoO7lDAr9SmI65IIfv7VnvTnV4FGnIIUIjzM+fHRHO5RBvyAbQ==", + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "pretty-format": "^27.2.5", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "minimist": "^1.2.5" }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", + "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" } }, - "node_modules/jest-mock": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.2.5.tgz", - "integrity": "sha512-HiMB3LqE9RzmeMzZARi2Bz3NoymxyP0gCid4y42ca1djffNtYFKgI220aC1VP1mUZ8rbpqZbHZOJ15093bZV/Q==", + "node_modules/node-releases": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "bin": { + "semver": "bin/semver" } }, - "node_modules/jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-resolve": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.2.5.tgz", - "integrity": "sha512-q5irwS3oS73SKy3+FM/HL2T7WJftrk9BRzrXF92f7net5HMlS7lJMg/ZwxLB4YohKqjSsdksEw7n/jvMxV7EKg==", + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "escalade": "^3.1.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.2.5", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.2.5", - "jest-validate": "^27.2.5", - "resolve": "^1.20.0", - "slash": "^3.0.0" + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 4" } }, - "node_modules/jest-resolve-dependencies": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.2.5.tgz", - "integrity": "sha512-BSjefped31bcvvCh++/pN9ueqqN1n0+p8/58yScuWfklLm2tbPbS9d251vJhAy0ZI2pL/0IaGhOTJrs9Y4FJlg==", + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.2.5" + "color-convert": "^1.9.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/jest-runner": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.2.5.tgz", - "integrity": "sha512-n41vw9RLg5TKAnEeJK9d6pGOsBOpwE89XBniK+AD1k26oIIy3V7ogM1scbDjSheji8MUPC9pNgCrZ/FHLVDNgg==", + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { - "@jest/console": "^27.2.5", - "@jest/environment": "^27.2.5", - "@jest/test-result": "^27.2.5", - "@jest/transform": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.2.5", - "jest-environment-node": "^27.2.5", - "jest-haste-map": "^27.2.5", - "jest-leak-detector": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-resolve": "^27.2.5", - "jest-runtime": "^27.2.5", - "jest-util": "^27.2.5", - "jest-worker": "^27.2.5", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/jest-runner-vscode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jest-runner-vscode/-/jest-runner-vscode-2.0.0.tgz", - "integrity": "sha512-nY8t6vxa+hd5XKm41XJnA4HwBzoc2UfgZ2rwo48UxR6dMjd2pgk+nhY1zx1DQerzFgJ2sTsbcv8yStEYNoFErQ==", + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "@jest/core": "^27.2.1", - "@vscode/test-electron": "^1.6.2", - "cosmiconfig": "^7.0.1", - "jest-cli": "^27.2.1", - "jest-environment-node": "^27.2.0" - }, - "engines": { - "node": ">=14.16.0", - "vscode": ">=1.56.0" + "color-name": "1.1.3" } }, - "node_modules/jest-runtime": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.2.5.tgz", - "integrity": "sha512-N0WRZ3QszKyZ3Dm27HTBbBuestsSd3Ud5ooVho47XZJ8aSKO/X1Ag8M1dNx9XzfGVRNdB/xCA3lz8MJwIzPLLA==", + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "dependencies": { - "@jest/console": "^27.2.5", - "@jest/environment": "^27.2.5", - "@jest/fake-timers": "^27.2.5", - "@jest/globals": "^27.2.5", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.2.5", - "@jest/transform": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-mock": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.2.5", - "jest-snapshot": "^27.2.5", - "jest-util": "^27.2.5", - "jest-validate": "^27.2.5", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4.8" } }, - "node_modules/jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.8.0" } }, - "node_modules/jest-snapshot": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.2.5.tgz", - "integrity": "sha512-2/Jkn+VN6Abwz0llBltZaiJMnL8b1j5Bp/gRIxe9YR3FCEh9qp0TXVV0dcpTGZ8AcJV1SZGQkczewkI9LP5yGw==", + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.2.5", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.2.5", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-resolve": "^27.2.5", - "jest-util": "^27.2.5", - "natural-compare": "^1.4.0", - "pretty-format": "^27.2.5", - "semver": "^7.3.2" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/jest-util": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.2.5.tgz", - "integrity": "sha512-QRhDC6XxISntMzFRd/OQ6TGsjbzA5ONO0tlAj2ElHs155x1aEr0rkYJBEysG6H/gZVH3oGFzCdAB/GA8leh8NQ==", + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/jest-validate": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.5.tgz", - "integrity": "sha512-XgYtjS89nhVe+UfkbLgcm+GgXKWgL80t9nTcNeejyO3t0Sj/yHE8BtIJqjZu9NXQksYbGImoQRXmQ1gP+Guffw==", + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "leven": "^3.1.0", - "pretty-format": "^27.2.5" + "shebang-regex": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, "engines": { - "node": ">=10" + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, - "node_modules/jest-watcher": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.2.5.tgz", - "integrity": "sha512-umV4qGozg2Dn6DTTtqAh9puPw+DGLK9AQas7+mWjiK8t0fWMpxKg8ZXReZw7L4C88DqorsGUiDgwHNZ+jkVrkQ==", + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { - "@jest/test-result": "^27.2.5", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.2.5", - "string-length": "^4.0.1" + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" } }, - "node_modules/jest-worker": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.5.tgz", - "integrity": "sha512-HTjEPZtcNKZ4LnhSp02NEH4vE+5OpJ0EsOWYvGQpHgUMLngydESAAMH5Wd/asPf29+XUDQZszxpLg1BkIIA2aw==", + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, "engines": { - "node": ">= 10.13.0" + "node": ">= 0.4" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "wrappy": "1" } }, - "node_modules/jsdoctypeparser": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", - "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", - "dev": true, - "bin": { - "jsdoctypeparser": "bin/jsdoctypeparser" - }, - "engines": { - "node": ">=10" + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" } }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" + "node": ">=6" }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "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" }, "engines": { - "node": ">=0.4.0" + "node": ">= 0.8.0" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, "engines": { "node": ">=4" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" + "p-try": "^2.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "p-limit": "^2.2.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/known-css-properties": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.23.0.tgz", - "integrity": "sha512-h9ivI88e1lFNmTT4HovBN33Ysn0OIJG7IPG2mkpx2uniQXFWqo35QdiX7w0TovlUFXfW8aPFblP5/q0jlOr2sA==", - "dev": true - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/p-wait-for": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", + "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "p-timeout": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "node_modules/listenercount": { + "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", - "dev": true - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, "engines": { - "node": ">=8" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true, "bin": { - "semver": "bin/semver.js" + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" } }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, - "dependencies": { - "tmpl": "1.0.x" + "engines": { + "node": ">=4" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "node-modules-regexp": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 6" } }, - "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "node_modules/postcss": { + "version": "8.3.11", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", + "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", "dev": true, + "dependencies": { + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" } }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "node_modules/postcss-sass": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.5.0.tgz", + "integrity": "sha512-qtu8awh1NMF3o9j/x9j3EZnd+BlF66X6NZYl12BdKoG2Z4hmydOt/dZj2Nq+g0kfk2pQy3jeYFBmvG9DBwynGQ==", "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "postcss": "^8.2.14" + }, "engines": { - "node": ">= 0.10.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "node_modules/postcss-scss": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.1.tgz", + "integrity": "sha512-7QghUu2l07OyVFT5LyvU/QJ1f2s8IL0mfToN69Yu533PgMZm2B1S6hYd4bao8tFq70r3P5MmAbKhVrZ4wOADxg==", "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, "engines": { - "node": ">=10" + "node": ">=12.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" } }, - "node_modules/meow/node_modules/hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "node_modules/postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">=4" } }, - "node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/postcss-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" + "peer": true, + "peerDependencies": { + "postcss": ">=5.0.0" } }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", "dev": true, - "engines": { - "node": ">=10" + "bin": { + "nanoid": "bin/nanoid.cjs" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "node_modules/postcss/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { - "node": ">= 8" + "node": ">= 0.8.0" } }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "node_modules/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": ">=8.6" + "node": ">=10.13.0" } }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "node_modules/prettier-plugin-packagejson": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.12.tgz", + "integrity": "sha512-dmZatncTp1Ehn1pomiBBNgkhTBDsuTnuv9mne6a7bVALf2Z0EwYIfhJ3m1Suj5XJxH+OKWSy7sER7Ag+4Vq7gA==", "dev": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "sort-package-json": "1.51.0" + }, + "peerDependencies": { + "prettier": ">= 1.16.0" } }, - "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "node_modules/pretty-format": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz", + "integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==", "dev": true, "dependencies": { - "mime-db": "1.50.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 0.6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, "engines": { - "node": "*" + "node": ">=0.4.0" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", "dev": true, "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { "node": ">= 6" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanocolors": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz", - "integrity": "sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==", - "dev": true - }, - "node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/node-releases": { - "version": "1.1.76", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", - "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/normalize-selector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", - "dev": true + "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, "engines": { - "node": ">= 4" + "node": ">=8" } }, - "node_modules/npm-run-all/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "pify": "^3.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/npm-run-all/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/refa": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/refa/-/refa-0.9.1.tgz", + "integrity": "sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "regexpp": "^3.2.0" } }, - "node_modules/npm-run-all/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/regenerate-unicode-properties": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", + "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "regenerate": "^1.4.2" }, "engines": { - "node": ">=4.8" + "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", "dev": true, - "engines": { - "node": ">=0.8.0" + "dependencies": { + "@babel/runtime": "^7.8.4" } }, - "node_modules/npm-run-all/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/regexp-ast-analysis": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz", + "integrity": "sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==", + "dev": true, + "dependencies": { + "refa": "^0.9.0", + "regexpp": "^3.2.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "node_modules/regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, "engines": { "node": ">=4" } }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, "bin": { - "semver": "bin/semver" + "regjsparser": "bin/parser" } }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "bin": { + "jsesc": "bin/jsesc" } }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/npm-run-all/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "resolve-from": "^5.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { - "node": ">= 0.4" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" + "glob": "^7.1.3" }, - "engines": { - "node": ">= 0.4" + "bin": { + "rimraf": "bin.js" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "wrappy": "1" + "queue-microtask": "^1.2.2" } }, - "node_modules/onetime": { + "node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "xmlchars": "^2.2.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/scslre": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.1.6.tgz", + "integrity": "sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==", "dev": true, "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" - }, - "engines": { - "node": ">= 0.8.0" + "refa": "^0.9.0", + "regexp-ast-analysis": "^0.2.3", + "regexpp": "^3.2.0" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "node_modules/scslre/node_modules/regexp-ast-analysis": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz", + "integrity": "sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "refa": "^0.9.0", + "regexpp": "^3.2.0" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dependencies": { - "p-try": "^2.0.0" + "lru-cache": "^6.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "node_modules/shortid": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", + "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", + "dev": true, + "dependencies": { + "nanoid": "^2.1.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", + "dev": true + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/p-wait-for": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", - "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "p-timeout": "^3.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/sort-object-keys": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", + "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", + "dev": true + }, + "node_modules/sort-package-json": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.51.0.tgz", + "integrity": "sha512-+92YlWIDj2nlE4lbO2UPDwU3xEt9sKsk7mV7bOO6GjdEzBPC+i55U5lbyqotVQsUDM2qIwfD6b2sORdwb13iwg==", "dev": true, "dependencies": { - "callsites": "^3.0.0" + "detect-indent": "^6.0.0", + "detect-newline": "3.1.0", + "git-hooks-list": "1.0.3", + "globby": "10.0.0", + "is-plain-obj": "2.1.0", + "sort-object-keys": "^1.1.3" }, - "engines": { - "node": ">=6" + "bin": { + "sort-package-json": "cli.js" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/sort-package-json/node_modules/globby": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", + "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "node_modules/sort-package-json/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "node_modules/source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, - "node_modules/path-key": { + "node_modules/spdx-correct": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": "*" } }, - "node_modules/pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" + "dependencies": { + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=10" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { - "node-modules-regexp": "^1.0.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/postcss": { - "version": "8.3.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.9.tgz", - "integrity": "sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "nanoid": "^3.1.28", - "picocolors": "^0.2.1", - "source-map-js": "^0.6.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^10 || ^12 || >=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": ">=8" } }, - "node_modules/postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", - "dev": true - }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", - "dev": true - }, - "node_modules/postcss-sass": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.5.0.tgz", - "integrity": "sha512-qtu8awh1NMF3o9j/x9j3EZnd+BlF66X6NZYl12BdKoG2Z4hmydOt/dZj2Nq+g0kfk2pQy3jeYFBmvG9DBwynGQ==", + "node_modules/string.prototype.padend": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz", + "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==", "dev": true, "dependencies": { - "gonzales-pe": "^4.3.0", - "postcss": "^8.2.14" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-scss": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.1.tgz", - "integrity": "sha512-7QghUu2l07OyVFT5LyvU/QJ1f2s8IL0mfToN69Yu533PgMZm2B1S6hYd4bao8tFq70r3P5MmAbKhVrZ4wOADxg==", + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, - "engines": { - "node": ">=12.0" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, - "peerDependencies": { - "postcss": "^8.3.3" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/postcss-syntax": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", - "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "peer": true, - "peerDependencies": { - "postcss": ">=5.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.1.29", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz", - "integrity": "sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg==", + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "min-indent": "^1.0.0" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=8" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/stylelint": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.0.0.tgz", + "integrity": "sha512-//4Po+WlWImVaro2BiNJZMamBo0Enekb+3fp5cYYN5r08kaPTHlxM8bCi/yvnPl7G+zqyLqjZU+O22vr/SDW0w==", "dev": true, + "dependencies": { + "balanced-match": "^2.0.0", + "cosmiconfig": "^7.0.1", + "debug": "^4.3.2", + "execall": "^2.0.0", + "fast-glob": "^3.2.7", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.0.3", + "globjoin": "^0.1.4", + "html-tags": "^3.1.0", + "ignore": "^5.1.8", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.23.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "normalize-selector": "^0.2.0", + "picocolors": "^1.0.0", + "postcss": "^8.3.11", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.6", + "postcss-value-parser": "^4.1.0", + "resolve-from": "^5.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.2", + "strip-ansi": "^6.0.0", + "style-search": "^0.1.0", + "svg-tags": "^1.0.0", + "table": "^6.7.2", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^3.0.3" + }, "bin": { - "prettier": "bin-prettier.js" + "stylelint": "bin/stylelint.js" }, "engines": { - "node": ">=10.13.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" } }, - "node_modules/prettier-plugin-packagejson": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.12.tgz", - "integrity": "sha512-dmZatncTp1Ehn1pomiBBNgkhTBDsuTnuv9mne6a7bVALf2Z0EwYIfhJ3m1Suj5XJxH+OKWSy7sER7Ag+4Vq7gA==", + "node_modules/stylelint-processor-glamorous": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/stylelint-processor-glamorous/-/stylelint-processor-glamorous-0.3.0.tgz", + "integrity": "sha512-M7zSQvYH2fkBghzl9ZzR9i08X7ka4B7GIDIwq4JD+IPTUgGeR0oLDDtlOGmA3m/Bjhb/N+bbovTINDSjhVQ5KA==", "dev": true, "dependencies": { - "sort-package-json": "1.51.0" - }, - "peerDependencies": { - "prettier": ">= 1.16.0" + "@babel/generator": "^7.0.0-beta.40", + "@babel/traverse": "^7.0.0-beta.40", + "@babel/types": "^7.0.0-beta.40", + "babylon": "^6.18.0", + "json5": "^0.5.1", + "postcss": "^6.0.18", + "postcss-js": "^1.0.1", + "shortid": "^2.2.8" } }, - "node_modules/pretty-format": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz", - "integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==", + "node_modules/stylelint-processor-glamorous/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" + "color-convert": "^1.9.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=4" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/stylelint-processor-glamorous/node_modules/camelcase-css": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-1.0.1.tgz", + "integrity": "sha1-FXxCOCZfXPlKHf/ehkRlUsvz9wU=", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 0.10" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/stylelint-processor-glamorous/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "node_modules/stylelint-processor-glamorous/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, + "color-name": "1.1.3" + } + }, + "node_modules/stylelint-processor-glamorous/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/stylelint-processor-glamorous/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, "engines": { - "node": ">= 6" + "node": ">=0.8.0" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "node_modules/stylelint-processor-glamorous/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "node_modules/stylelint-processor-glamorous/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "bin": { + "json5": "lib/cli.js" + } }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "node_modules/stylelint-processor-glamorous/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "node_modules/stylelint-processor-glamorous/node_modules/postcss-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-1.0.1.tgz", + "integrity": "sha512-smhUUMF5o5W1ZCQSyh5A3lNOXFLdNrxqyhWbLsGolZH2AgVmlyhxhYbIixfsdKE6r1vG5i7O40DPcvEvE1mvjw==", + "dev": true, + "dependencies": { + "camelcase-css": "^1.0.1", + "postcss": "^6.0.11" + } }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "node_modules/stylelint-processor-glamorous/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/stylelint-processor-styled-components": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", + "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@babel/parser": "^7.8.3", + "@babel/traverse": "^7.8.3", + "micromatch": "^4.0.2", + "postcss": "^7.0.26" + } + }, + "node_modules/stylelint-processor-styled-components/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">=6.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" } }, - "node_modules/read-pkg-up/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/stylelint/node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/stylelint/node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "pify": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/refa": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/refa/-/refa-0.9.1.tgz", - "integrity": "sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==", - "dev": true, - "dependencies": { - "regexpp": "^3.2.0" - } + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true }, - "node_modules/regexp-ast-analysis": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz", - "integrity": "sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==", - "dev": true, - "dependencies": { - "refa": "^0.9.0", - "regexpp": "^3.2.0" - } + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/table": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, "dependencies": { - "resolve-from": "^5.0.0" + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, "engines": { "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true, "engines": { "node": ">=4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=8.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=6" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "dependencies": { - "xmlchars": "^2.2.0" + "punycode": "^2.1.1" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/scslre": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.1.6.tgz", - "integrity": "sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==", + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "dev": true, - "dependencies": { - "refa": "^0.9.0", - "regexp-ast-analysis": "^0.2.3", - "regexpp": "^3.2.0" + "engines": { + "node": "*" } }, - "node_modules/scslre/node_modules/regexp-ast-analysis": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz", - "integrity": "sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==", + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, - "dependencies": { - "refa": "^0.9.0", - "regexpp": "^3.2.0" - } - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "node_modules/triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "tslib": "^1.8.1" }, "engines": { - "node": ">=8" + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "node_modules/shortid": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz", - "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "dependencies": { - "nanoid": "^2.1.0" + "engines": { + "node": ">=4" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/signal-exit": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", - "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">=8" + "node": ">=4.2.0" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sort-object-keys": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", - "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", - "dev": true - }, - "node_modules/sort-package-json": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.51.0.tgz", - "integrity": "sha512-+92YlWIDj2nlE4lbO2UPDwU3xEt9sKsk7mV7bOO6GjdEzBPC+i55U5lbyqotVQsUDM2qIwfD6b2sORdwb13iwg==", + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, - "dependencies": { - "detect-indent": "^6.0.0", - "detect-newline": "3.1.0", - "git-hooks-list": "1.0.3", - "globby": "10.0.0", - "is-plain-obj": "2.1.0", - "sort-object-keys": "^1.1.3" - }, - "bin": { - "sort-package-json": "cli.js" + "engines": { + "node": ">=4" } }, - "node_modules/sort-package-json/node_modules/globby": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", - "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/sort-package-json/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=4" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/source-map-js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", - "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 10.0.0" } }, - "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" } }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "node_modules/unzipper/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/unzipper/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "safe-buffer": "~5.1.0" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true - }, - "node_modules/specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "bin": { - "specificity": "bin/specificity" + "dependencies": { + "punycode": "^2.1.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "node_modules/v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" }, "engines": { - "node": ">=10" + "node": ">=10.12.0" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", + "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", + "dependencies": { + "minimatch": "^3.0.4", + "semver": "^7.3.4", + "vscode-languageserver-protocol": "3.16.0" + }, "engines": { - "node": ">=8" + "vscode": "^1.52.0" } }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, + "node_modules/vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "vscode-languageserver-protocol": "3.16.0" }, - "engines": { - "node": ">=10" + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "node_modules/vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" } }, - "node_modules/string.prototype.padend": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz", - "integrity": "sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==", + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.2.tgz", + "integrity": "sha512-T7uPC18+f8mYE4lbVZwb3OSmvwTZm3cuFhrdx9Bn2l11lmp3SvSuSVjy2JtvrghzjAo4G6Trqny2m9XGnFnWVA==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + }, + "node_modules/vscode-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.2.tgz", + "integrity": "sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==" + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "browser-process-hrtime": "^1.0.0" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "xml-name-validator": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "makeerror": "1.0.x" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10.4" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "iconv-lite": "0.4.24" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "min-indent": "^1.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "engines": { - "node": ">=8" + "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" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", - "dev": true - }, - "node_modules/stylelint": { - "version": "13.13.1", - "resolved": "git+https://git@github.com/stylelint/stylelint.git#816b19a2245fbc170045b970dd0a6bb6fc684463", - "dev": true, - "license": "MIT", + "node_modules/winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", "dependencies": { - "balanced-match": "^2.0.0", - "cosmiconfig": "^7.0.1", - "debug": "^4.3.2", - "execall": "^2.0.0", - "fast-glob": "^3.2.7", - "fastest-levenshtein": "^1.0.12", - "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", - "global-modules": "^2.0.0", - "globby": "^11.0.3", - "globjoin": "^0.1.4", - "html-tags": "^3.1.0", - "ignore": "^5.1.8", - "import-lazy": "^4.0.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.23.0", - "mathml-tag-names": "^2.1.3", - "meow": "^9.0.0", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "normalize-selector": "^0.2.0", - "picocolors": "^0.2.1", - "postcss": "^8.3.6", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.6", - "postcss-value-parser": "^4.1.0", - "resolve-from": "^5.0.0", - "specificity": "^0.4.1", - "string-width": "^4.2.2", - "strip-ansi": "^6.0.0", - "style-search": "^0.1.0", - "svg-tags": "^1.0.0", - "table": "^6.7.2", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^3.0.3" - }, - "bin": { - "stylelint": "bin/stylelint.js" + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "dependencies": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "engines": { + "node": ">= 6.4.0" } }, - "node_modules/stylelint-processor-glamorous": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/stylelint-processor-glamorous/-/stylelint-processor-glamorous-0.3.0.tgz", - "integrity": "sha512-M7zSQvYH2fkBghzl9ZzR9i08X7ka4B7GIDIwq4JD+IPTUgGeR0oLDDtlOGmA3m/Bjhb/N+bbovTINDSjhVQ5KA==", - "dev": true, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dependencies": { - "@babel/generator": "^7.0.0-beta.40", - "@babel/traverse": "^7.0.0-beta.40", - "@babel/types": "^7.0.0-beta.40", - "babylon": "^6.18.0", - "json5": "^0.5.1", - "postcss": "^6.0.18", - "postcss-js": "^1.0.1", - "shortid": "^2.2.8" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/stylelint-processor-glamorous/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "node_modules/winston-transport/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "safe-buffer": "~5.1.0" } }, - "node_modules/stylelint-processor-glamorous/node_modules/camelcase-css": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-1.0.1.tgz", - "integrity": "sha1-FXxCOCZfXPlKHf/ehkRlUsvz9wU=", + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/stylelint-processor-glamorous/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/stylelint-processor-glamorous/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/stylelint-processor-glamorous/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/stylelint-processor-glamorous/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "node_modules/ws": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/stylelint-processor-glamorous/node_modules/has-flag": { + "node_modules/xml-name-validator": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true }, - "node_modules/stylelint-processor-glamorous/node_modules/json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true, - "bin": { - "json5": "lib/cli.js" - } + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true }, - "node_modules/stylelint-processor-glamorous/node_modules/postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" - }, "engines": { - "node": ">=4.0.0" + "node": ">=10" } }, - "node_modules/stylelint-processor-glamorous/node_modules/postcss-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-1.0.1.tgz", - "integrity": "sha512-smhUUMF5o5W1ZCQSyh5A3lNOXFLdNrxqyhWbLsGolZH2AgVmlyhxhYbIixfsdKE6r1vG5i7O40DPcvEvE1mvjw==", + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "dependencies": { - "camelcase-css": "^1.0.1", - "postcss": "^6.0.11" + "engines": { + "node": ">= 6" } }, - "node_modules/stylelint-processor-glamorous/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/stylelint-processor-styled-components": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", - "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "dependencies": { - "@babel/parser": "^7.8.3", - "@babel/traverse": "^7.8.3", - "micromatch": "^4.0.2", - "postcss": "^7.0.26" + "engines": { + "node": ">=10" } }, - "node_modules/stylelint-processor-styled-components/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "node_modules/zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", + "dev": true + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "requires": { + "@babel/highlight": "^7.10.4" } }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true }, - "node_modules/stylelint/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", "dev": true, - "engines": { - "node": ">= 4" + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "node_modules/stylelint/node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", "dev": true, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" }, - "peerDependencies": { - "postcss": "^8.3.3" + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/stylelint/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", + "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", + "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/helper-explode-assignable-expression": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" }, - "engines": { - "node": ">=10.0.0" + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", + "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "@babel/helper-create-regexp-features-plugin": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" }, - "engines": { - "node": ">=8" + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "@babel/helper-explode-assignable-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", + "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, - "engines": { - "node": ">= 4.0.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, - "engines": { - "node": "*" + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "@babel/helper-remap-async-to-generator": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", + "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-wrap-function": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", + "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "@babel/helper-wrap-function": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", + "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", "dev": true, - "engines": { - "node": ">= 10.0.0" + "requires": { + "@babel/helper-function-name": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/unzipper": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", - "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "node_modules/unzipper/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz", + "integrity": "sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog==", "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", + "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.15.4", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "@babel/plugin-proposal-class-static-block": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz", + "integrity": "sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } }, - "node_modules/v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", "dev": true, - "engines": { - "node": ">= 8" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "@babel/plugin-proposal-json-strings": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, - "node_modules/vscode-jsonrpc": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", - "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", - "engines": { - "node": ">=8.0.0 || >=10.0.0" + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, - "node_modules/vscode-languageclient": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", - "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", - "dependencies": { - "minimatch": "^3.0.4", - "semver": "^7.3.4", - "vscode-languageserver-protocol": "3.16.0" - }, - "engines": { - "vscode": "^1.52.0" + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, - "node_modules/vscode-languageserver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", - "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", - "dependencies": { - "vscode-languageserver-protocol": "3.16.0" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" + "@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", - "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", - "dependencies": { - "vscode-jsonrpc": "6.0.0", - "vscode-languageserver-types": "3.16.0" + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", + "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.15.4" } }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.2.tgz", - "integrity": "sha512-T7uPC18+f8mYE4lbVZwb3OSmvwTZm3cuFhrdx9Bn2l11lmp3SvSuSVjy2JtvrghzjAo4G6Trqny2m9XGnFnWVA==" + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } }, - "node_modules/vscode-languageserver-types": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", - "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + "@babel/plugin-proposal-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } }, - "node_modules/vscode-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.2.tgz", - "integrity": "sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==" + "@babel/plugin-proposal-private-methods": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", + "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "dependencies": { - "makeerror": "1.0.x" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "engines": { - "node": ">=10.4" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" } }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "engines": { - "node": ">= 6" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "dev": true - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true + "@babel/plugin-transform-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" + } }, - "@babel/core": { - "version": "7.15.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", - "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", - "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", + "@babel/plugin-transform-block-scoping": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", + "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", "dev": true, "requires": { - "@babel/types": "^7.15.4", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-compilation-targets": { + "@babel/plugin-transform-classes": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", + "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "globals": "^11.1.0" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true } } }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "@babel/plugin-transform-destructuring": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", + "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "@babel/plugin-transform-dotall-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "@babel/plugin-transform-duplicate-keys": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-module-imports": { + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-for-of": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", + "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-module-transforms": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", - "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", + "@babel/plugin-transform-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "@babel/plugin-transform-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-plugin-utils": { + "@babel/plugin-transform-member-expression-literals": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", - "dev": true + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "@babel/plugin-transform-modules-amd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helper-simple-access": { + "@babel/plugin-transform-modules-commonjs": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", + "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.15.4", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helper-split-export-declaration": { + "@babel/plugin-transform-modules-systemjs": { "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", + "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/helper-validator-option": { + "@babel/plugin-transform-modules-umd": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", + "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-create-regexp-features-plugin": "^7.14.5" } }, - "@babel/highlight": { + "@babel/plugin-transform-new-target": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/parser": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", - "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", - "dev": true + "@babel/plugin-transform-object-super": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "@babel/plugin-transform-parameters": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", + "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "@babel/plugin-transform-regenerator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "regenerator-transform": "^0.14.2" } }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "@babel/plugin-transform-reserved-words": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "@babel/plugin-transform-spread": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", + "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "@babel/plugin-transform-sticky-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "@babel/plugin-transform-unicode-escapes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "@babel/preset-env": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz", + "integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4", + "@babel/plugin-proposal-async-generator-functions": "^7.15.8", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.15.4", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.15.6", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.15.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.15.3", + "@babel/plugin-transform-classes": "^7.15.4", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.15.4", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.15.4", + "@babel/plugin-transform-modules-systemjs": "^7.15.4", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.9", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.15.4", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.15.8", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.15.6", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.5", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.16.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "regenerator-runtime": "^0.13.4" } }, "@babel/template": { @@ -8319,6 +10663,16 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@dabh/diagnostics": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", + "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -8806,12 +11160,23 @@ "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, + "@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/triple-beam": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", + "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" + }, "@types/vscode": { "version": "1.56.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz", @@ -9042,6 +11407,11 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "async": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -9064,6 +11434,15 @@ "slash": "^3.0.0" } }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, "babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -9089,6 +11468,44 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz", + "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.16.2" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + } + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -9177,16 +11594,24 @@ "dev": true }, "browserslist": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", - "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001259", - "electron-to-chromium": "^1.3.846", + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", "escalade": "^3.1.1", - "nanocolors": "^0.1.5", - "node-releases": "^1.1.76" + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + }, + "dependencies": { + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + } } }, "bser": { @@ -9250,13 +11675,10 @@ } }, "caniuse-lite": { - "version": "1.0.30001260", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001260.tgz", - "integrity": "sha512-Fhjc/k8725ItmrvW5QomzxLeojewxvqiYCKeFcfFEhut28IVLdpHU19dneOmltZQIE5HNbawj1HYD+1f2bM1Dg==", - "dev": true, - "requires": { - "nanocolors": "^0.1.0" - } + "version": "1.0.30001267", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001267.tgz", + "integrity": "sha512-r1mjTzAuJ9W8cPBGbbus8E0SKcUP7gn03R14Wk8FlAlqhH9hroy9nLqmpuXlfKEw/oILW+FGz47ipXV2O7x8lg==", + "dev": true }, "chainsaw": { "version": "0.1.0", @@ -9327,6 +11749,30 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -9339,8 +11785,30 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } }, "combined-stream": { "version": "1.0.8", @@ -9371,11 +11839,28 @@ "safe-buffer": "~5.1.1" } }, + "core-js-compat": { + "version": "3.18.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.3.tgz", + "integrity": "sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw==", + "dev": true, + "requires": { + "browserslist": "^4.17.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cosmiconfig": { "version": "7.0.1", @@ -9602,9 +12087,9 @@ } }, "electron-to-chromium": { - "version": "1.3.848", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.848.tgz", - "integrity": "sha512-wchRyBcdcmibioggdO7CbMT5QQ4lXlN/g7Mkpf1K2zINidnqij6EVu94UIZ+h5nB2S9XD4bykqFv9LonAWLFyw==", + "version": "1.3.871", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", + "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", "dev": true }, "emittery": { @@ -9619,6 +12104,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -10266,6 +12756,11 @@ "bser": "2.1.1" } }, + "fecha": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -10310,6 +12805,11 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, + "fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -10722,8 +13222,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", @@ -10885,8 +13384,7 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-string": { "version": "1.0.7", @@ -10915,8 +13413,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -11623,6 +14120,11 @@ "integrity": "sha512-h9ivI88e1lFNmTT4HovBN33Ysn0OIJG7IPG2mkpx2uniQXFWqo35QdiX7w0TovlUFXfW8aPFblP5/q0jlOr2sA==", "dev": true }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -11702,6 +14204,12 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -11714,6 +14222,18 @@ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, + "logform": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", + "requires": { + "colors": "^1.2.1", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", + "triple-beam": "^1.3.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -11909,14 +14429,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanocolors": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz", - "integrity": "sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nanoid": { "version": "2.1.11", @@ -11949,9 +14462,9 @@ "dev": true }, "node-releases": { - "version": "1.1.76", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", - "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", "dev": true }, "normalize-package-data": { @@ -12158,6 +14671,14 @@ "wrappy": "1" } }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, "onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -12325,20 +14846,26 @@ } }, "postcss": { - "version": "8.3.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.9.tgz", - "integrity": "sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw==", + "version": "8.3.11", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz", + "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==", "dev": true, "requires": { - "nanoid": "^3.1.28", - "picocolors": "^0.2.1", + "nanoid": "^3.1.30", + "picocolors": "^1.0.0", "source-map-js": "^0.6.2" }, "dependencies": { "nanoid": { - "version": "3.1.29", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz", - "integrity": "sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg==", + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true } } @@ -12440,8 +14967,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -12550,6 +15076,16 @@ } } }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -12569,6 +15105,36 @@ "regexpp": "^3.2.0" } }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", + "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "dev": true, + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, "regexp-ast-analysis": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz", @@ -12585,6 +15151,43 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "dev": true, + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12657,8 +15260,12 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" }, "safer-buffer": { "version": "2.1.2", @@ -12759,6 +15366,21 @@ "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", "dev": true }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -12892,6 +15514,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -12909,6 +15536,21 @@ } } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -13004,9 +15646,10 @@ "dev": true }, "stylelint": { - "version": "git+https://git@github.com/stylelint/stylelint.git#816b19a2245fbc170045b970dd0a6bb6fc684463", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.0.0.tgz", + "integrity": "sha512-//4Po+WlWImVaro2BiNJZMamBo0Enekb+3fp5cYYN5r08kaPTHlxM8bCi/yvnPl7G+zqyLqjZU+O22vr/SDW0w==", "dev": true, - "from": "stylelint@git+https://git@github.com/stylelint/stylelint#v14", "requires": { "balanced-match": "^2.0.0", "cosmiconfig": "^7.0.1", @@ -13030,8 +15673,8 @@ "micromatch": "^4.0.4", "normalize-path": "^3.0.0", "normalize-selector": "^0.2.0", - "picocolors": "^0.2.1", - "postcss": "^8.3.6", + "picocolors": "^1.0.0", + "postcss": "^8.3.11", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", @@ -13060,6 +15703,12 @@ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", @@ -13292,6 +15941,11 @@ "minimatch": "^3.0.4" } }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13365,6 +16019,11 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -13428,6 +16087,34 @@ "which-boxed-primitive": "^1.0.2" } }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "dev": true + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -13490,8 +16177,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "v8-compile-cache": { "version": "2.3.0", @@ -13656,6 +16342,55 @@ "is-symbol": "^1.0.3" } }, + "winston": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", + "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "async": "^3.1.0", + "is-stream": "^2.0.0", + "logform": "^2.2.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.4.0" + } + }, + "winston-transport": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", + "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", + "requires": { + "readable-stream": "^2.3.7", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 193f2e7f..8840d8d3 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "vscode-stylelint", - "version": "0.87.6", + "version": "1.0.0", "license": "MIT", "description": "Modern CSS/SCSS/Less linter", "main": "dist/index.js", - "displayName": "stylelint", + "displayName": "Stylelint", "publisher": "stylelint", "repository": "https://github.com/stylelint/vscode-stylelint", "homepage": "https://github.com/stylelint/vscode-stylelint#readme", @@ -47,7 +47,7 @@ "stylelint.enable": { "type": "boolean", "default": true, - "description": "Control whether stylelint is enabled for CSS/SCSS/Less files or not." + "description": "Control whether Stylelint is enabled for CSS/SCSS/Less files or not." }, "stylelint.config": { "type": [ @@ -55,7 +55,7 @@ "null" ], "default": null, - "description": "A stylelint configuration object." + "description": "A Stylelint configuration object." }, "stylelint.configFile": { "type": "string", @@ -90,7 +90,7 @@ "stylelint.stylelintPath": { "type": "string", "default": "", - "description": "Supply a custom path to the stylelint module." + "description": "Supply a custom path to the Stylelint module." }, "stylelint.packageManager": { "scope": "resource", @@ -152,21 +152,31 @@ ] }, "dependencies": { + "@types/triple-beam": "^1.3.2", "fast-diff": "^1.2.0", "path-is-inside": "^1.0.2", + "semver": "^7.3.5", + "triple-beam": "^1.3.0", "vscode-languageclient": "^7.0.0", "vscode-languageserver": "^7.0.0", + "vscode-languageserver-protocol": "^3.16.0", "vscode-languageserver-textdocument": "^1.0.2", "vscode-languageserver-types": "^3.16.0", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "winston": "^3.3.3", + "winston-transport": "^4.4.0" }, "devDependencies": { + "@babel/core": "^7.15.8", + "@babel/eslint-parser": "^7.15.8", + "@babel/preset-env": "^7.15.8", "@stylelint/postcss-css-in-js": "^0.37.2", "@stylelint/prettier-config": "^2.0.0", "@types/eslint": "^7.28.1", "@types/fs-extra": "^9.0.13", "@types/jest": "^27.0.1", "@types/path-is-inside": "^1.0.0", + "@types/semver": "^7.3.9", "@types/vscode": "1.56.0", "@vscode/test-electron": "^1.6.2", "esbuild": "^0.13.4", @@ -182,7 +192,7 @@ "postcss-sass": "^0.5.0", "postcss-scss": "^4.0.1", "prettier": "^2.3.0", - "stylelint": "git+https://git@github.com/stylelint/stylelint#v14", + "stylelint": "^14.0.0", "stylelint-processor-glamorous": "^0.3.0", "stylelint-processor-styled-components": "^1.10.0", "typescript": "^4.4.3", @@ -198,11 +208,12 @@ "lint": "run-s \"lint:*\"", "lint:formatting": "prettier . --check", "lint:js": "eslint --report-unused-disable-directives .", - "lint:types": "tsc", + "lint:types": "tsc -b", + "lint:unit-tests": "node scripts/enforce-unit-tests-per-file.js", "test": "npm run bundle && jest", - "test:lib": "jest --projects test/lib", + "test:e2e": "npm run bundle && jest --projects test/e2e", + "test:integration": "jest --projects test/integration", "test:unit": "jest --projects test/unit", - "test:workspace": "npm run bundle && jest --projects test/workspace", "vscode:prepublish": "npm run bundle-base -- --minify" }, "prettier": "@stylelint/prettier-config" diff --git a/scripts/bundle.js b/scripts/bundle.js index 1c5e7638..57b529d9 100644 --- a/scripts/bundle.js +++ b/scripts/bundle.js @@ -11,7 +11,7 @@ const args = new Set(process.argv.slice(2)); /** @returns {Promise} */ async function bundle() { - const entryPoints = ['src/index.js', 'src/server.js']; + const entryPoints = ['src/index.js', 'src/start-server.js']; for (const item of await glob('dist/*', { cwd: rootDir })) { await fs.remove(item); diff --git a/scripts/enforce-unit-tests-per-file.js b/scripts/enforce-unit-tests-per-file.js new file mode 100644 index 00000000..d2cc9e5f --- /dev/null +++ b/scripts/enforce-unit-tests-per-file.js @@ -0,0 +1,87 @@ +'use strict'; + +const fs = require('fs/promises'); +const path = require('path'); +const process = require('process'); +const glob = require('fast-glob'); + +/** + * @param {string} text + * @param {'red' | 'green' | 'yellow'} shade + * @returns {string} + */ +function colour(text, shade) { + if (!process.stdout.isTTY) { + return text; + } + + switch (shade) { + case 'red': + return `\x1b[31m${text}\x1b[0m`; + case 'green': + return `\x1b[32m${text}\x1b[0m`; + case 'yellow': + return `\x1b[33m${text}\x1b[0m`; + default: + return text; + } +} + +const tags = { + error: colour('[error]', 'red'), + success: colour('[success]', 'green'), +}; + +/** + * Checks if a file exists at the given path. + * @param {string} filePath + * @returns {Promise} + */ +async function fileExists(filePath) { + try { + return (await fs.stat(filePath)).isFile(); + } catch (err) { + return false; + } +} + +/** + * Traverses code in `src` directory and ensures that each file has a + * corresponding unit test file in the `__tests__` directory at the same level. + */ +async function enforceUnitTestsPerFile() { + const cwd = path.join(__dirname, '..'); + + const srcFiles = await glob('src/*/**/*.js', { + cwd, + absolute: true, + ignore: ['**/__tests__', '**/__mocks__', '**/index.js'], + }); + + let exitCode = 0; + + for (const srcFile of srcFiles) { + const testDir = path.join(path.dirname(srcFile), '__tests__'); + + if (!(await fileExists(path.join(testDir, path.basename(srcFile))))) { + exitCode = 1; + + const relativePath = path.relative(cwd, srcFile); + + console.error(`${tags.error} No unit test file found for ${colour(relativePath, 'yellow')}`); + } + } + + if (exitCode === 0) { + console.log(`${tags.success} All modules have a corresponding unit test file.`); + } else { + console.error(` +Found missing unit test files. Make sure any new modules have a corresponding +unit test file with the same name in the __tests__ directory adjacent to the +module.`); + } + + process.exit(exitCode); +} + +enforceUnitTestsPerFile(); diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..2a7d6b79 --- /dev/null +++ b/src/README.md @@ -0,0 +1,54 @@ +# `src` + +Only main entry points, whether for the client or server, should be in this directory. Modules should be organized in subdirectories. + +Subdirectories should have the following structure (see [`utils`](utils) for an example): + +- `src` + - `group` — Group of modules, organized by purpose or functionality. + - `__mocks__` — Optional, should contain mocks for any modules that need a more elaborate, reusable mock. + - `sub-module-a.js` + - … + - `__tests__` — Required, unit tests for each module. Each test should have the same filename as the module it tests. + - `sub-module-a.js` + - `sub-module-b.js` + - … + - `index.js` — Entry point for the group. Should not contain any logic. + - `sub-module-a.js` + - `sub-module-b.js` + - … + +Submodules should always export their functionality as a single object, like so: + + +```js +'use strict'; + +/** + * Parses Stylelint warnings into … + * @param {stylelint.Warning[]} warnings The warnings to parse. + * @returns {ParsedWarning[]} The parsed warnings. + */ +function parseWarnings(warnings) { + // … +} + +module.exports = { + parseWarnings, +}; +``` + +Group entry points should be named `index.js` and should export a single object, like so: + + +```js +'use strict'; + +module.exports = { + ...require('./sub-module-a'), + ...require('./sub-module-b'), + // … +}; +``` + +All modules should be documented using JSDoc comments, as seen in the example above. See [`server/server.js`](server/server.js) for a real-life example. diff --git a/src/index.js b/src/index.js index d27b1c03..98aa2f7a 100644 --- a/src/index.js +++ b/src/index.js @@ -6,12 +6,13 @@ const { ExecuteCommandRequest, } = require('vscode-languageclient/node'); const { workspace, commands: Commands, window: Window } = require('vscode'); +const { CommandId } = require('./utils/types'); /** * @param {vscode.ExtensionContext} context */ exports.activate = ({ subscriptions }) => { - const serverPath = require.resolve('./server.js'); + const serverPath = require.resolve('./start-server.js'); const client = new LanguageClient( 'stylelint', @@ -51,7 +52,8 @@ exports.activate = ({ subscriptions }) => { version: textEditor.document.version, }; const params = { - command: 'stylelint.applyAutoFix', + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released // https://github.com/microsoft/TypeScript/issues/43362 /* prettier-ignore */ 'arguments': [textDocument], @@ -59,7 +61,7 @@ exports.activate = ({ subscriptions }) => { await client.sendRequest(ExecuteCommandRequest.type, params).then(undefined, () => { Window.showErrorMessage( - 'Failed to apply stylelint fixes to the document. Please consider opening an issue with steps to reproduce.', + 'Failed to apply Stylelint fixes to the document. Please consider opening an issue with steps to reproduce.', ); }); }), diff --git a/src/server.js b/src/server.js deleted file mode 100644 index b4e34e93..00000000 --- a/src/server.js +++ /dev/null @@ -1,977 +0,0 @@ -'use strict'; - -const { join, parse, isAbsolute } = require('path'); - -const diff = require('fast-diff'); -const parseUri = require('vscode-uri').URI.parse; -const pathIsInside = require('path-is-inside'); -const { findPackageRoot } = require('./utils/packages'); -const stylelintVSCode = require('./stylelint-vscode'); -const { - createConnection, - ProposedFeatures, - TextDocuments, - TextDocumentSyncKind, - TextEdit, - Range, - Position, - WorkspaceChange, - CodeActionKind, - TextDocumentEdit, - CodeAction, - CompletionItemKind, - MarkupKind, - InsertTextFormat, - DocumentFormattingRequest, -} = require('vscode-languageserver/node'); -const { TextDocument } = require('vscode-languageserver-textdocument'); - -const CommandIds = { - applyAutoFix: 'stylelint.applyAutoFix', -}; - -const StylelintSourceFixAll = `${CodeActionKind.SourceFixAll}.stylelint`; - -/** @type {stylelint.Config} */ -let config; -/** @type {string} */ -let configFile; -/** @type {string} */ -let configBasedir; -/** @type {PackageManager} */ -let packageManager; -/** @type {string} */ -let customSyntax; -/** @type {boolean} */ -let ignoreDisables; -/** @type {boolean} */ -let reportNeedlessDisables; -/** @type {boolean} */ -let reportInvalidScopeDisables; -/** @type {string} */ -let stylelintPath; -/** @type {string[]} */ -let validateLanguages; -/** @type {string[]} */ -let snippetLanguages; - -const connection = createConnection(ProposedFeatures.all); -const documents = new TextDocuments(TextDocument); - -/** - * @type {Map} - */ -const documentDiagnostics = new Map(); -/** - * @type {Map} - */ -const needlessDisableReports = new Map(); -/** - * @type {Map} - */ -const invalidScopeDisableReports = new Map(); - -/** - * @param {TextDocument} document - * @param {Partial} baseOptions - * @returns {Promise>} - */ -async function buildStylelintOptions(document, baseOptions = {}) { - const options = { ...baseOptions }; - const workspaceFolder = await getWorkspaceFolder(document); - - if (config) { - options.config = config; - } - - if (configFile) { - options.configFile = workspaceFolder - ? configFile.replace(/\$\{workspaceFolder\}/gu, workspaceFolder) - : configFile; - } - - if (ignoreDisables) { - options.ignoreDisables = ignoreDisables; - } - - if (reportNeedlessDisables) { - options.reportNeedlessDisables = reportNeedlessDisables; - } - - if (reportInvalidScopeDisables) { - options.reportInvalidScopeDisables = reportInvalidScopeDisables; - } - - if (customSyntax) { - options.customSyntax = workspaceFolder - ? customSyntax.replace(/\$\{workspaceFolder\}/gu, workspaceFolder) - : customSyntax; - } - - if (configBasedir) { - if (isAbsolute(configBasedir)) { - options.configBasedir = configBasedir; - } else { - options.configBasedir = join(workspaceFolder || '', configBasedir); - } - } - - const documentPath = parseUri(document.uri).fsPath; - - if (documentPath) { - if (workspaceFolder && pathIsInside(documentPath, workspaceFolder)) { - options.ignorePath = join(workspaceFolder, '.stylelintignore'); - } - - if (options.ignorePath === undefined) { - options.ignorePath = join( - (await findPackageRoot(documentPath)) || parse(documentPath).root, - '.stylelintignore', - ); - } - } - - return options; -} - -/** - * @param {TextDocument} document - * @returns {Promise} - */ -async function buildStylelintVSCodeOptions(document) { - /** @type {StylelintVSCodeOptions} */ - const options = { connection, packageManager }; - - if (stylelintPath) { - if (isAbsolute(stylelintPath)) { - options.stylelintPath = stylelintPath; - } else { - const workspaceFolder = await getWorkspaceFolder(document); - - options.stylelintPath = join(workspaceFolder || '', stylelintPath); - } - } - - return options; -} - -/** - * @param {unknown} err - * @returns {void} - */ -function handleError(err) { - if (!(err instanceof Error)) { - connection.window.showErrorMessage(String(err).replace(/\n/gu, ' ')); - - return; - } - - if (/** @type {InvalidOptionError} */ (err)?.reasons) { - for (const reason of /** @type {InvalidOptionError} */ (err)?.reasons) { - connection.window.showErrorMessage(`stylelint: ${reason}`); - } - - return; - } - - // https://github.com/stylelint/stylelint/blob/551dcb5/lib/utils/configurationError.js#L12 - if (/** @type {ConfigurationError} */ (err)?.code === 78) { - connection.window.showErrorMessage(`stylelint: ${err.message}`); - - return; - } - - connection.window.showErrorMessage((err.stack || '').replace(/\n/gu, ' ')); -} - -/** - * @param {TextDocument} document - * @returns {Promise} - */ -async function validate(document) { - if (!isValidateOn(document)) { - return; - } - - const options = await buildStylelintOptions(document); - - try { - const result = await stylelintVSCode( - document, - options, - await buildStylelintVSCodeOptions(document), - ); - - connection.sendDiagnostics({ - uri: document.uri, - diagnostics: result.diagnostics, - }); - documentDiagnostics.set(document.uri, result.diagnostics); - - if (result.needlessDisables) { - needlessDisableReports.set(document.uri, result.needlessDisables); - } - - if (result.invalidScopeDisables) { - invalidScopeDisableReports.set(document.uri, result.invalidScopeDisables); - } - } catch (err) { - handleError(err); - } -} - -/** - * @param {TextDocument} document - * @param {lsp.FormattingOptions?} formattingOptions Formatting options to use. - * Overriden by stylelint configuration. - * @returns {Promise} - */ -async function getFixes(document, formattingOptions = null) { - /** @type {Partial} */ - const baseOptions = { fix: true }; - - // If formatting options were provided, translate them to their corresponding rules. - // NOTE: There is no equivalent rule for trimFinalNewlines, so it is not respected. - if (formattingOptions) { - const { insertSpaces, tabSize, insertFinalNewline, trimTrailingWhitespace } = formattingOptions; - - /** @type {Record} */ - const rules = { - indentation: [insertSpaces ? tabSize : 'tab'], - }; - - if (insertFinalNewline !== undefined) { - rules['no-missing-end-of-source-newline'] = insertFinalNewline; - } - - if (trimTrailingWhitespace !== undefined) { - rules['no-eol-whitespace'] = trimTrailingWhitespace; - } - - baseOptions.config = { rules }; - } - - const options = await buildStylelintOptions(document, baseOptions); - - try { - const result = await stylelintVSCode( - document, - options, - await buildStylelintVSCodeOptions(document), - ); - - if (typeof result.output !== 'string') { - return []; - } - - const code = document.getText(); - const fixedCode = result.output; - - if (fixedCode === code) { - return []; - } - - return replaceEdits(document, fixedCode); - } catch (err) { - handleError(err); - - return []; - } -} - -/** - * @returns {void} - */ -function validateAll() { - for (const document of documents.all()) { - validate(document); - } -} - -/** - * @param {TextDocument} document - * @returns {void} - */ -function clearDiagnostics(document) { - connection.sendDiagnostics({ - uri: document.uri, - diagnostics: [], - }); - documentDiagnostics.delete(document.uri); - needlessDisableReports.delete(document.uri); - invalidScopeDisableReports.delete(document.uri); -} - -/** - * @param {TextDocument} document - * @returns {boolean} - */ -function isValidateOn(document) { - return validateLanguages.includes(document.languageId); -} - -/** Whether or not dynamic registration for document formatting should be attempted. */ -let registerFormatterDynamically = false; - -/** - * A promise that resolves to the disposable for the dynamically registered document formatter. - * @type {Promise | undefined} - */ -let formatterRegistration; - -connection.onInitialize(({ capabilities }) => { - validateAll(); - - registerFormatterDynamically = Boolean( - capabilities.textDocument?.formatting?.dynamicRegistration, - ); - - return { - capabilities: { - textDocumentSync: { - openClose: true, - change: TextDocumentSyncKind.Full, - }, - executeCommandProvider: { - commands: [CommandIds.applyAutoFix], - }, - // Use static registration if dynamic registration is not supported by the client - documentFormattingProvider: !registerFormatterDynamically, - codeActionProvider: { codeActionKinds: [CodeActionKind.QuickFix, StylelintSourceFixAll] }, - completionProvider: {}, - }, - }; -}); -connection.onDidChangeConfiguration(({ settings }) => { - /** @type {string[]} */ - const oldValidateLanguages = validateLanguages || []; - - config = settings.stylelint.config; - configFile = settings.stylelint.configFile; - configBasedir = settings.stylelint.configBasedir; - customSyntax = settings.stylelint.customSyntax; - ignoreDisables = settings.stylelint.ignoreDisables; - reportNeedlessDisables = settings.stylelint.reportNeedlessDisables; - reportInvalidScopeDisables = settings.stylelint.reportInvalidScopeDisables; - stylelintPath = settings.stylelint.stylelintPath; - packageManager = settings.stylelint.packageManager || 'npm'; - validateLanguages = settings.stylelint.validate || []; - snippetLanguages = settings.stylelint.snippet || ['css', 'less', 'postcss', 'scss']; - - const validateLanguageSet = new Set(validateLanguages); - const oldValidateLanguageSet = new Set(oldValidateLanguages); - - /** Whether or not the list of languages that should be validated has changed. */ - let changed = validateLanguageSet.size !== oldValidateLanguageSet.size; - - /** The languages removed from the list of languages that should be validated */ - const removeLanguages = new Set(); - - // Check if the sets are unequal, which means that the list of languages that should be - // validated has changed. - for (const language of oldValidateLanguageSet) { - if (!validateLanguageSet.has(language)) { - removeLanguages.add(language); - changed = true; - } - } - - // If languages have been removed, clear diagnostics for documents of those languages. - if (removeLanguages.size > 0) { - for (const document of documents.all().filter((doc) => removeLanguages.has(doc.languageId))) { - clearDiagnostics(document); - } - } - - // If dynamic registration is supported and the list of languages that should be validated - // has changed, then (re-)register the formatter. - if (registerFormatterDynamically && changed) { - // Dispose the old formatter registration if it exists. - if (formatterRegistration) { - void formatterRegistration.then((disposable) => disposable.dispose()); - } - - // If there are languages that should be validated, register a formatter for those - // languages. - if (validateLanguages.length > 0) { - formatterRegistration = connection.client.register(DocumentFormattingRequest.type, { - documentSelector: validateLanguages.map((language) => ({ language })), - }); - } - } - - validateAll(); -}); -connection.onDidChangeWatchedFiles(validateAll); - -documents.onDidChangeContent(({ document }) => validate(document)); -documents.onDidClose(({ document }) => { - clearDiagnostics(document); -}); -connection.onExecuteCommand(async (params) => { - if (params.command === CommandIds.applyAutoFix) { - if (!params.arguments) { - return {}; - } - - /** @type { { version: number, uri: string } } */ - const identifier = params.arguments[0]; - const uri = identifier.uri; - const document = documents.get(uri); - - if (!document || !isValidateOn(document)) { - return {}; - } - - if (identifier.version !== document.version) { - return {}; - } - - const workspaceChange = new WorkspaceChange(); - const textChange = workspaceChange.getTextEditChange(identifier); - - const edits = await getFixes(document); - - edits.forEach((edit) => textChange.add(edit)); - - return connection.workspace.applyEdit(workspaceChange.edit).then( - (response) => { - if (!response.applied) { - connection.console.error(`Failed to apply command: ${params.command}`); - } - - return {}; - }, - () => { - connection.console.error(`Failed to apply command: ${params.command}`); - }, - ); - } - - return {}; -}); -connection.onDocumentFormatting((params) => { - if (!params.textDocument) { - return null; - } - - /** @type { { uri: string } } */ - const identifier = params.textDocument; - const uri = identifier.uri; - const document = documents.get(uri); - - if (!document || !isValidateOn(document)) { - return null; - } - - return getFixes(document, params.options); -}); -connection.onCodeAction(async (params) => { - const only = params.context.only !== undefined ? params.context.only[0] : undefined; - const isSource = only === CodeActionKind.Source; - const isSourceFixAll = only === StylelintSourceFixAll || only === CodeActionKind.SourceFixAll; - - if (isSourceFixAll || isSource) { - const uri = params.textDocument.uri; - const textDocument = documents.get(uri); - - if (!textDocument || !isValidateOn(textDocument)) { - return []; - } - - const textDocumentIdentifer = { uri: textDocument.uri, version: textDocument.version }; - const edits = await getFixes(textDocument); - - return [ - CodeAction.create( - `Fix all stylelint auto-fixable problems`, - { documentChanges: [TextDocumentEdit.create(textDocumentIdentifer, edits)] }, - StylelintSourceFixAll, - ), - ]; - } - - if (only === CodeActionKind.QuickFix) { - const uri = params.textDocument.uri; - const textDocument = documents.get(uri); - - if (!textDocument || !isValidateOn(textDocument)) { - return []; - } - - if (!textDocument) { - return []; - } - - const textDocumentIdentifer = { uri: textDocument.uri, version: textDocument.version }; - - const diagnostics = params.context.diagnostics; - const needlessDisables = needlessDisableReports.get(uri) || invalidScopeDisableReports.get(uri); - - if (!needlessDisables) { - return []; - } - - /** - * @type {CodeAction[]} - */ - const results = []; - - for (const diagnostic of diagnostics) { - const diagnosticKey = computeKey(diagnostic); - - for (const needlessDisable of needlessDisables) { - if (computeKey(needlessDisable.diagnostic) === diagnosticKey) { - const edits = createRemoveCommentDirectiveTextEdits(textDocument, needlessDisable.range); - - if (edits.length > 0) { - results.push( - CodeAction.create( - needlessDisable.range.rule !== 'all' - ? `Remove unused stylelint comment directive for ${needlessDisable.range.rule} rule` - : `Remove unused stylelint comment directive.`, - { documentChanges: [TextDocumentEdit.create(textDocumentIdentifer, edits)] }, - CodeActionKind.QuickFix, - ), - ); - } - - break; - } - } - } - - return results; - } -}); - -connection.onCompletion(onCompletion); - -documents.listen(connection); - -connection.listen(); - -/** - * @param {TextDocument} document - * @returns {Promise} - */ -async function getWorkspaceFolder(document) { - const documentPath = parseUri(document.uri).fsPath; - const workspaceFolders = await connection.workspace.getWorkspaceFolders(); - - if (documentPath) { - if (workspaceFolders) { - for (const { uri } of workspaceFolders) { - const workspacePath = parseUri(uri).fsPath; - - if (pathIsInside(documentPath, workspacePath)) { - return workspacePath; - } - } - } - } else if (workspaceFolders && workspaceFolders.length) { - const { uri } = workspaceFolders[0]; - - return parseUri(uri).fsPath; - } - - return undefined; -} - -/** - * If replace all of the document, the cursor will move to the last position. - * Apply diff only edits to keep the cursor position. - * @param {TextDocument} document - * @param {string} newText - * @returns {TextEdit[]} - */ -function replaceEdits(document, newText) { - const results = diff(document.getText(), newText); - - const edits = []; - let offset = 0; - - for (const result of results) { - const start = offset; - const op = result[0]; - const text = result[1]; - - switch (op) { - case diff.INSERT: - edits.push(TextEdit.insert(document.positionAt(start), text)); - break; - case diff.DELETE: - offset += text.length; - edits.push( - TextEdit.del(Range.create(document.positionAt(start), document.positionAt(offset))), - ); - break; - case diff.EQUAL: - offset += text.length; - break; - } - } - - return edits; -} - -/** - * @param {lsp.CompletionParams} params - * @returns {lsp.CompletionItem[]} - */ -function onCompletion(params) { - const uri = params.textDocument.uri; - const document = documents.get(uri); - - if (!document || !isValidateOn(document) || !snippetLanguages.includes(document.languageId)) { - return []; - } - - const diagnostics = documentDiagnostics.get(uri); - - if (!diagnostics) { - return [ - createDisableLineCompletionItem('stylelint-disable-line'), - createDisableLineCompletionItem('stylelint-disable-next-line'), - createDisableEnableCompletionItem(), - ]; - } - - /** @type {Set} */ - const needlessDisablesKeys = new Set(); - const needlessDisables = needlessDisableReports.get(uri); - - if (needlessDisables) { - for (const needlessDisable of needlessDisables) { - needlessDisablesKeys.add(computeKey(needlessDisable.diagnostic)); - } - } - - const thisLineRules = new Set(); - const nextLineRules = new Set(); - - for (const diagnostic of diagnostics) { - if (needlessDisablesKeys.has(computeKey(diagnostic))) { - continue; - } - - const start = diagnostic.range.start; - - const rule = diagnostic.code ?? ''; - - if (start.line === params.position.line) { - thisLineRules.add(rule); - } else if (start.line === params.position.line + 1) { - nextLineRules.add(rule); - } - } - - thisLineRules.delete(''); - thisLineRules.delete('CssSyntaxError'); - nextLineRules.delete(''); - nextLineRules.delete('CssSyntaxError'); - - /** @type {lsp.CompletionItem[]} */ - const results = []; - - const disableKind = getStyleLintDisableKind(document, params.position); - - if (disableKind) { - if (disableKind === 'stylelint-disable-line') { - for (const rule of thisLineRules) { - results.push({ - label: rule, - kind: CompletionItemKind.Snippet, - detail: `disable ${rule} rule. (stylelint)`, - }); - } - } else if ( - disableKind === 'stylelint-disable' || - disableKind === 'stylelint-disable-next-line' - ) { - for (const rule of nextLineRules) { - results.push({ - label: rule, - kind: CompletionItemKind.Snippet, - detail: `disable ${rule} rule. (stylelint)`, - }); - } - } - } else { - if (thisLineRules.size === 1) { - results.push( - createDisableLineCompletionItem('stylelint-disable-line', [...thisLineRules][0]), - ); - } else { - results.push(createDisableLineCompletionItem('stylelint-disable-line')); - } - - if (nextLineRules.size === 1) { - results.push( - createDisableLineCompletionItem('stylelint-disable-next-line', [...nextLineRules][0]), - ); - } else { - results.push(createDisableLineCompletionItem('stylelint-disable-next-line')); - } - - results.push(createDisableEnableCompletionItem()); - } - - return results; -} - -/** - * @param { 'stylelint-disable-line' | 'stylelint-disable-next-line' } kind - * @param {string} rule - * @returns {lsp.CompletionItem} - */ -function createDisableLineCompletionItem(kind, rule = '') { - return { - label: kind, - kind: CompletionItemKind.Snippet, - insertText: `/* ${kind} \${0:${rule || 'rule'}} */`, - insertTextFormat: InsertTextFormat.Snippet, - detail: - kind === 'stylelint-disable-line' - ? 'Turn off stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)' - : 'Turn off stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)', - documentation: { - kind: MarkupKind.Markdown, - value: `\`\`\`css\n/* ${kind} ${rule || 'rule'} */\n\`\`\``, - }, - }; -} - -/** - * @returns {lsp.CompletionItem} - */ -function createDisableEnableCompletionItem() { - return { - label: 'stylelint-disable', - kind: CompletionItemKind.Snippet, - insertText: `/* stylelint-disable \${0:rule} */\n/* stylelint-enable \${0:rule} */`, - insertTextFormat: InsertTextFormat.Snippet, - detail: - 'Turn off all stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)', - documentation: { - kind: MarkupKind.Markdown, - value: `\`\`\`css\n/* stylelint-disable rule */\n/* stylelint-enable rule */\n\`\`\``, - }, - }; -} - -/** - * Check if the given position is in the stylelint-disable comment. - * If inside a comment, return the kind of disable. - * @param {TextDocument} document - * @param {Position} position - */ -function getStyleLintDisableKind(document, position) { - const lineStartOffset = document.offsetAt(Position.create(position.line, 0)); - const lineEndOffset = document.offsetAt(Position.create(position.line + 1, 0)) - 1; - const line = document.getText().slice(lineStartOffset, lineEndOffset); - - const before = line.slice(0, position.character); - const after = line.slice(position.character); - - const disableKindResult = /\/\*\s*(stylelint-disable(?:(?:-next)?-line)?)\s[a-z\-/\s,]*$/i.exec( - before, - ); - - if (!disableKindResult) { - return null; - } - - if (/^[a-z\-/\s,]*\*\//i.test(after)) { - return disableKindResult[1]; - } - - return null; -} - -/** - * @param {TextDocument} document - * @param {stylelint.DisableReportRange} range - * @returns {TextEdit[]} - */ -function createRemoveCommentDirectiveTextEdits(document, range) { - const text = document.getText(); - const startLine = range.start - 1; - const startLineStartOffset = document.offsetAt(Position.create(startLine, 0)); - const startLineEndOffset = document.offsetAt(Position.create(startLine + 1, 0)) - 1; - - if (range.end !== undefined) { - if (range.start === range.end) { - // `/* stylelint-disable-line */` - const stylelintDisableLineText = text.slice(startLineStartOffset, startLineEndOffset); - const newStylelintDisableLineText = removeCommentDirective( - range, - stylelintDisableLineText, - 'stylelint-disable-line', - ); - - if (newStylelintDisableLineText !== stylelintDisableLineText) { - return [ - TextEdit.replace( - Range.create( - document.positionAt(startLineStartOffset), - document.positionAt(startLineEndOffset), - ), - newStylelintDisableLineText, - ), - ]; - } - - // `/* stylelint-disable-next-line */` - if (startLine > 0) { - const prevLineStartOffset = document.offsetAt(Position.create(startLine - 1, 0)); - const prevLineEndOffset = document.offsetAt(Position.create(startLine, 0)) - 1; - const stylelintDisableNextLineText = text.slice(prevLineStartOffset, prevLineEndOffset); - const newStylelintDisableNextLineText = removeCommentDirective( - range, - stylelintDisableNextLineText, - 'stylelint-disable-next-line', - ); - - if (newStylelintDisableNextLineText !== stylelintDisableNextLineText) { - return [ - TextEdit.replace( - Range.create( - document.positionAt(prevLineStartOffset), - document.positionAt(prevLineEndOffset), - ), - newStylelintDisableNextLineText, - ), - ]; - } - } - } - } - - // `/* stylelint-disable */` - const stylelintDisableText = text.slice(startLineStartOffset, startLineEndOffset); - const newStylelintDisableText = removeCommentDirective( - range, - stylelintDisableText, - 'stylelint-disable', - ); - - if (newStylelintDisableText !== stylelintDisableText) { - const stylelintDisableEdit = TextEdit.replace( - Range.create( - document.positionAt(startLineStartOffset), - document.positionAt(startLineEndOffset), - ), - newStylelintDisableText, - ); - - if (range.end === null || range.end === undefined) { - return [stylelintDisableEdit]; - } - - const endLine = range.end - 1; - const endLineStartOffset = document.offsetAt(Position.create(endLine, 0)); - const endLineEndOffset = document.offsetAt(Position.create(endLine + 1, 0)) - 1; - const stylelintEnableText = text.slice(endLineStartOffset, endLineEndOffset); - const newStylelintEnableText = removeCommentDirective( - range, - stylelintEnableText, - 'stylelint-enable', - ); - - if (newStylelintEnableText !== stylelintEnableText) { - return [ - stylelintDisableEdit, - TextEdit.replace( - Range.create( - document.positionAt(endLineStartOffset), - document.positionAt(endLineEndOffset), - ), - newStylelintEnableText, - ), - ]; - } - } - - return []; -} - -/** - * @param {lsp.Diagnostic} diagnostic - * @returns {string} - */ -function computeKey(diagnostic) { - const range = diagnostic.range; - - return `[${range.start.line},${range.start.character},${range.end.line},${range.end.character}]-${diagnostic.code}`; -} - -/** - * @param {string} value - * @returns {string} - */ -function escapeRegExp(value) { - return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); // $& means the whole matched string -} - -/** - * @param {stylelint.DisableReportRange} range - * @param {string} text - * @param {string} directive - * @returns {string} - */ -function removeCommentDirective(range, text, directive) { - if (range.rule !== 'all') { - // `/* directive rulename */` - let newText = text.replace( - new RegExp(`\\/\\*\\s*${directive}\\s+${escapeRegExp(range.rule)}\\s*\\*\\/`), - removesReplacer, - ); - - if (newText !== text) { - return newText; - } - - // `/* directive xxx, rulename */` - newText = text.replace( - new RegExp( - `(\\/\\*\\s*${directive}\\s+[\\s\\S]*)\\s*,\\s*${escapeRegExp( - range.rule, - )}([\\s\\S]*\\*\\/)`, - ), - removesReplacer, - ); - - if (newText !== text) { - return newText; - } - - // `/* directive rulename, xxx */` - newText = text.replace( - new RegExp( - `(\\/\\*\\s*${directive}\\s+[\\s\\S]*)${escapeRegExp( - range.rule, - )}\\s*,\\s*([\\s\\S]*\\*\\/)`, - ), - removesReplacer, - ); - - return newText; - } - - // `/* directive */` - return text.replace(new RegExp(`\\/\\*\\s*${directive}\\s*\\*\\`), removesReplacer); - - /** - * @param {string[]} args - */ - function removesReplacer(...args) { - let newText = ''; - - for (let index = 1; index < args.length - 2; index++) { - newText += args[index]; - } - - return newText; - } -} diff --git a/src/server/__tests__/__snapshots__/server.js.snap b/src/server/__tests__/__snapshots__/server.js.snap new file mode 100644 index 00000000..f60f872a --- /dev/null +++ b/src/server/__tests__/__snapshots__/server.js.snap @@ -0,0 +1,275 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`StylelintLanguageServer should accept server modules 1`] = ` +Object { + "context": Object { + "connection": Object { + "listen": [MockFunction], + "onDidChangeConfiguration": [MockFunction], + "onDidChangeWatchedFiles": [MockFunction], + "onInitialize": [MockFunction], + "sendDiagnostics": [MockFunction], + }, + "displayError": [Function], + "documents": TextDocuments { + "all": [MockFunction], + "get": [MockFunction], + "keys": [MockFunction], + "listen": [MockFunction], + "onWillSaveWaitUntil": [MockFunction], + }, + "getFixes": [Function], + "getModule": [Function], + "lintDocument": [Function], + "options": Object { + "packageManager": "npm", + "snippet": Array [ + "css", + "less", + "postcss", + ], + "validate": Array [ + "css", + "less", + "postcss", + ], + }, + "resolveStylelint": [Function], + "runner": StylelintRunner { + "lintDocument": [MockFunction], + }, + }, + "logger": Object { + "child": [MockFunction] { + "calls": Array [ + Array [ + Object { + "component": "language-server", + }, + ], + Array [ + Object { + "component": "language-server:test-module", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": [Circular], + }, + Object { + "type": "return", + "value": [Circular], + }, + ], + }, + "debug": [MockFunction], + "error": [MockFunction], + "info": [MockFunction] { + "calls": Array [ + Array [ + "Registering module", + Object { + "module": "test-module", + }, + ], + Array [ + "Module registered", + Object { + "module": "test-module", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "isDebugEnabled": [MockFunction], + "warn": [MockFunction], + }, +} +`; + +exports[`StylelintLanguageServer should allow modules to get fixes for documents using context.getFixes 1`] = ` +Array [ + Array [ + Object {}, + Object { + "uri": "file:///test.css", + }, + Object { + "maxWarnings": 1, + }, + Object { + "packageManager": "npm", + "snippet": Array [ + "css", + "less", + "postcss", + ], + "validate": Array [ + "css", + "less", + "postcss", + ], + }, + ], + Array [ + Object {}, + Object { + "uri": "file:///test.css", + }, + Object {}, + Object { + "packageManager": "npm", + "snippet": Array [ + "css", + "less", + "postcss", + ], + "validate": Array [ + "css", + "less", + "postcss", + ], + }, + ], +] +`; + +exports[`StylelintLanguageServer should allow modules to lint documents using context.lintDocument 1`] = ` +Array [ + Array [ + Object { + "uri": "file:///test.css", + }, + Object { + "maxWarnings": 1, + }, + Object { + "packageManager": "npm", + "snippet": Array [ + "css", + "less", + "postcss", + ], + "validate": Array [ + "css", + "less", + "postcss", + ], + }, + ], + Array [ + Object { + "uri": "file:///test.css", + }, + Object {}, + Object { + "packageManager": "npm", + "snippet": Array [ + "css", + "less", + "postcss", + ], + "validate": Array [ + "css", + "less", + "postcss", + ], + }, + ], +] +`; + +exports[`StylelintLanguageServer should combine initialization results from modules 1`] = ` +Object { + "capabilities": Object { + "callHierarchyProvider": true, + "textDocumentSync": Object { + "change": 1, + "openClose": true, + }, + "typeDefinitionProvider": true, + "workspace": Object { + "workspaceFolders": Object { + "supported": true, + }, + }, + }, +} +`; + +exports[`StylelintLanguageServer should fire onDidChangeValidateLanguages when validate option changes 1`] = ` +Object { + "config": undefined, + "configBasedir": undefined, + "configFile": undefined, + "customSyntax": undefined, + "ignoreDisables": undefined, + "packageManager": "npm", + "reportInvalidScopeDisables": undefined, + "reportNeedlessDisables": undefined, + "snippet": Array [ + "css", + "less", + "postcss", + ], + "stylelintPath": undefined, + "validate": Array [ + "css", + ], +} +`; + +exports[`StylelintLanguageServer should fire onDidChangeValidateLanguages when validate option changes 2`] = ` +Object { + "languages": Set { + "css", + }, + "removedLanguages": Set { + "less", + "postcss", + }, +} +`; + +exports[`StylelintLanguageServer should not accept modules with a non-string ID 1`] = `"Module IDs must be strings"`; + +exports[`StylelintLanguageServer should not accept modules with duplicate IDs 1`] = `"Module with ID \\"test-module\\" already registered"`; + +exports[`StylelintLanguageServer should not accept modules without an ID 1`] = `"Modules must have an ID"`; + +exports[`StylelintLanguageServer should prevent modules from modifying context properties 1`] = `"Cannot set read-only property"`; + +exports[`StylelintLanguageServer should receive settings from the client and pass them to modules with defaults 1`] = ` +Object { + "config": undefined, + "configBasedir": undefined, + "configFile": undefined, + "customSyntax": undefined, + "ignoreDisables": undefined, + "packageManager": "npm", + "reportInvalidScopeDisables": undefined, + "reportNeedlessDisables": undefined, + "snippet": Array [ + "css", + "less", + "postcss", + ], + "stylelintPath": undefined, + "validate": Array [ + "css", + "less", + "postcss", + ], +} +`; diff --git a/src/server/__tests__/server.js b/src/server/__tests__/server.js new file mode 100644 index 00000000..4e14f09b --- /dev/null +++ b/src/server/__tests__/server.js @@ -0,0 +1,867 @@ +'use strict'; + +jest.mock('../../utils/lsp'); +jest.mock('../../utils/stylelint'); +jest.mock('../../utils/documents'); +jest.mock('../../utils/packages'); + +const { displayError } = /** @type {jest.Mocked} */ ( + require('../../utils/lsp') +); + +const { StylelintRunner } = /** @type {jest.Mocked} */ ( + require('../../utils/stylelint') +); + +const { getFixes } = /** @type {jest.Mocked} */ ( + require('../../utils/documents') +); + +const { StylelintResolver } = /** @type {jest.Mocked} */ ( + require('../../utils/packages') +); + +const { StylelintLanguageServer } = require('../server'); + +const mockConnection = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + listen: jest.fn(), + onInitialize: jest.fn(), + onDidChangeConfiguration: jest.fn(), + onDidChangeWatchedFiles: jest.fn(), + sendDiagnostics: jest.fn(), + }) +); + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + error: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + isDebugEnabled: jest.fn(), + child: jest.fn(() => mockLogger), + }) +); + +describe('StylelintLanguageServer', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + const server = new StylelintLanguageServer({ + connection: mockConnection, + }); + + expect(server).toBeInstanceOf(StylelintLanguageServer); + }); + + test('should tag its own logger', () => { + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + }); + + expect(mockLogger.child).toHaveBeenCalledWith({ + component: 'language-server', + }); + }); + + test('should accept server modules', () => { + class TestModule { + /** + * @type {LanguageServerModuleConstructorParameters | undefined} + */ + static params; + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor(params) { + TestModule.params = params; + } + } + + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + expect(TestModule.params).toMatchSnapshot(); + expect(mockLogger.child).toHaveBeenCalledWith({ + component: 'language-server:test-module', + }); + }); + + test('should not accept modules with duplicate IDs', () => { + class TestModule { + static id = 'test-module'; + } + + class TestModule2 { + static id = 'test-module'; + } + + expect(() => { + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule, TestModule2], + }); + }).toThrowErrorMatchingSnapshot(); + }); + + test('should prevent modules from modifying context properties', () => { + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} context + */ + constructor({ context }) { + context.connection = /** @type {any} */ ({}); + } + } + + expect(() => { + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + }).toThrowErrorMatchingSnapshot(); + }); + + test('should not accept modules without an ID', () => { + class TestModule { + static id = undefined; + } + + expect(() => { + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [/** @type {any} */ (TestModule)], + }); + }).toThrowErrorMatchingSnapshot(); + }); + + test('should not accept modules with a non-string ID', () => { + class TestModule { + static id = 1; + } + + expect(() => { + new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [/** @type {any} */ (TestModule)], + }); + }).toThrowErrorMatchingSnapshot(); + }); + + test('should start successfully', async () => { + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + }); + + server.start(); + + expect(mockLogger.info).toHaveBeenCalledWith('Language server started'); + }); + + test('should combine initialization results from modules', () => { + class TestModuleA { + static id = 'module-a'; + + /** + * @returns {Partial} + */ + onInitialize() { + return { + capabilities: { callHierarchyProvider: true }, + }; + } + } + + class TestModuleB { + static id = 'module-b'; + + /** + * @returns {Partial} + */ + onInitialize() { + return { + capabilities: { + typeDefinitionProvider: true, + workspace: { + workspaceFolders: { + supported: true, + }, + }, + }, + }; + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModuleA, TestModuleB], + }); + + server.start(); + + const handler = mockConnection.onInitialize.mock.calls[0][0]; + + const result = handler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(result).toMatchSnapshot(); + }); + + test('should display and log errors thrown by module handlers', () => { + const error = new Error('Test error'); + + class TestModule { + static id = 'test-module'; + + /** + * @returns {Partial} + */ + onInitialize() { + throw error; + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const handler = mockConnection.onInitialize.mock.calls[0][0]; + + handler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(displayError).toHaveBeenCalledWith(mockConnection, error); + expect(mockLogger.error).toHaveBeenCalledWith('Error invoking onInitialize', { + module: 'test-module', + error, + }); + }); + + test('should allow modules to access sibling modules', () => { + /** + * @type {LanguageServerModule | undefined} + */ + let module; + + class TestModuleA { + static id = 'module-a'; + + constructor() { + this.value = 5; + } + } + + class TestModuleB { + static id = 'module-b'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + module = this.context.getModule('module-a'); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModuleA, TestModuleB], + }); + + server.start(); + + const handler = mockConnection.onInitialize.mock.calls[0][0]; + + handler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(module).toBeInstanceOf(TestModuleA); + expect(module?.value).toBe(5); + }); + + test('should receive settings from the client and pass them to modules with defaults', () => { + /** + * @type {LanguageServerOptions | undefined} + */ + let options; + + class TestModule { + static id = 'test-module'; + + /** + * @param {DidChangeConfigurationParams} params + */ + onDidChangeConfiguration({ settings }) { + options = settings; + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + const onDidChangeConfigurationHandler = + mockConnection.onDidChangeConfiguration.mock.calls[0][0]; + + onDidChangeConfigurationHandler({ settings: { stylelint: {} } }); + + expect(options).toMatchSnapshot(); + }); + + test('should fire onDidChangeValidateLanguages when validate option changes', () => { + /** + * @type {LanguageServerOptions | undefined} + */ + let options; + + /** + * @type {DidChangeValidateLanguagesParams | undefined} + */ + let languageParams; + + class TestModule { + static id = 'test-module'; + + /** + * @param {DidChangeConfigurationParams} params + */ + onDidChangeConfiguration({ settings }) { + options = settings; + } + + /** + * @param {DidChangeValidateLanguagesParams} params + */ + onDidChangeValidateLanguages(params) { + languageParams = params; + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + const onDidChangeConfigurationHandler = + mockConnection.onDidChangeConfiguration.mock.calls[0][0]; + + onDidChangeConfigurationHandler({ + settings: { + stylelint: { + validate: ['css'], + }, + }, + }); + + expect(options).toMatchSnapshot(); + expect(languageParams).toMatchSnapshot(); + }); + + test('with debug log level, should log changed languages', () => { + mockLogger.isDebugEnabled.mockReturnValue(true); + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + }); + + server.start(); + + const onDidChangeConfigurationHandler = + mockConnection.onDidChangeConfiguration.mock.calls[0][0]; + + onDidChangeConfigurationHandler({ + settings: { + stylelint: { + validate: ['css'], + }, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith('Languages that should be validated changed', { + languages: ['css'], + removedLanguages: ['less', 'postcss'], + }); + }); + + test('without debug log level, should not log changed languages', () => { + mockLogger.isDebugEnabled.mockReturnValue(false); + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + }); + + server.start(); + + const onDidChangeConfigurationHandler = + mockConnection.onDidChangeConfiguration.mock.calls[0][0]; + + onDidChangeConfigurationHandler({ + settings: { + stylelint: { + validate: ['css'], + }, + }, + }); + + expect(mockLogger.debug).not.toHaveBeenCalledWith( + 'Languages that should be validated changed', + { + languages: ['css'], + removedLanguages: ['less', 'postcss'], + }, + ); + }); + + test('should allow modules to lint documents using context.lintDocument', async () => { + /** @type {Promise | undefined} */ + let withOptions; + + /** @type {Promise | undefined} */ + let withoutOptions; + + const mockRunner = { + lintDocument: jest.fn(async () => ['test']), + }; + + StylelintRunner.mockImplementation(() => /** @type {any} */ (mockRunner)); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + withOptions = this.context.lintDocument(document, { maxWarnings: 1 }); + withoutOptions = this.context.lintDocument(document); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await withOptions).toStrictEqual(['test']); + expect(await withoutOptions).toStrictEqual(['test']); + + expect(mockRunner.lintDocument.mock.calls).toMatchSnapshot(); + }); + + test('should display and log errors thrown when linting', async () => { + const error = new Error('test'); + + /** @type {Promise | undefined} */ + let promise; + + StylelintRunner.mockImplementation( + () => + /** @type {any} */ ({ + lintDocument: async () => { + throw error; + }, + }), + ); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + promise = this.context.lintDocument(document, { maxWarnings: 1 }); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await promise).toBeUndefined(); + expect(displayError).toHaveBeenCalledWith(mockConnection, error); + expect(mockLogger.error).toHaveBeenCalledWith('Error running lint', { + uri: 'file:///test.css', + error, + }); + }); + + test('should allow modules to get fixes for documents using context.getFixes', async () => { + /** @type {Promise | undefined} */ + let withOptions; + + /** @type {Promise | undefined} */ + let withoutOptions; + + StylelintRunner.mockImplementation(() => /** @type {any} */ ({})); + + getFixes.mockImplementation(() => /** @type {any} */ (['test'])); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + withOptions = this.context.getFixes(document, { maxWarnings: 1 }); + withoutOptions = this.context.getFixes(document); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await withOptions).toStrictEqual(['test']); + expect(await withoutOptions).toStrictEqual(['test']); + expect(getFixes.mock.calls).toMatchSnapshot(); + }); + + test('should display and log errors thrown when getting fixes', async () => { + const error = new Error('test'); + + /** @type {Promise | undefined} */ + let promise; + + getFixes.mockImplementation(() => { + throw error; + }); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + promise = this.context.getFixes(document, { maxWarnings: 1 }); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await promise).toStrictEqual([]); + expect(displayError).toHaveBeenCalledWith(mockConnection, error); + expect(mockLogger.error).toHaveBeenCalledWith('Error getting fixes', { + uri: 'file:///test.css', + error, + }); + }); + + test('should allow modules to resolve the Stylelint package for a given document using context.resolveStylelintPackage', async () => { + /** @type {Promise | undefined} */ + let promise; + + StylelintResolver.mockImplementation( + () => + /** @type {any} */ ({ + resolve: async () => ({ + stylelint: { fake: 'package' }, + resolvedPath: 'fake/path', + }), + }), + ); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + promise = this.context.resolveStylelint(document); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await promise).toStrictEqual({ + stylelint: { fake: 'package' }, + resolvedPath: 'fake/path', + }); + }); + + test('should display and log errors thrown when resolving the Stylelint package', async () => { + const error = new Error('test'); + + /** @type {Promise | undefined} */ + let promise; + + StylelintResolver.mockImplementation( + () => + /** @type {any} */ ({ + resolve: async () => { + throw error; + }, + }), + ); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + promise = this.context.resolveStylelint(document); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await promise).toBeUndefined(); + expect(displayError).toHaveBeenCalledWith(mockConnection, error); + expect(mockLogger.error).toHaveBeenCalledWith('Error resolving Stylelint', { + uri: 'file:///test.css', + error, + }); + }); + + test('should log when Stylelint cannot be resolved', async () => { + /** @type {Promise | undefined} */ + let promise; + + StylelintResolver.mockImplementation( + () => + /** @type {any} */ ({ + resolve: async () => { + return undefined; + }, + }), + ); + + const document = /** @type {lsp.TextDocument} */ ( + /** @type {any} */ ({ + uri: 'file:///test.css', + }) + ); + + class TestModule { + static id = 'test-module'; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context }) { + this.context = context; + } + + onInitialize() { + promise = this.context.resolveStylelint(document); + } + } + + const server = new StylelintLanguageServer({ + connection: mockConnection, + logger: mockLogger, + modules: [TestModule], + }); + + server.start(); + + const onInitializeHandler = mockConnection.onInitialize.mock.calls[0][0]; + + onInitializeHandler( + /** @type {any} */ ({ capabilities: {} }), + /** @type {any} */ ({}), + /** @type {any} */ ({}), + ); + + expect(await promise).toBeUndefined(); + expect(mockLogger.warn).toHaveBeenCalledWith('Failed to resolve Stylelint', { + uri: 'file:///test.css', + }); + }); +}); diff --git a/src/server/index.js b/src/server/index.js new file mode 100644 index 00000000..0283c560 --- /dev/null +++ b/src/server/index.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = { + modules: require('./modules'), + ...require('./server'), +}; diff --git a/src/server/modules/__tests__/__snapshots__/auto-fix.js.snap b/src/server/modules/__tests__/__snapshots__/auto-fix.js.snap new file mode 100644 index 00000000..d99a0be3 --- /dev/null +++ b/src/server/modules/__tests__/__snapshots__/auto-fix.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AutoFixModule onInitialize should return results 1`] = ` +Object { + "capabilities": Object { + "executeCommandProvider": Object { + "commands": Array [ + "stylelint.applyAutoFix", + ], + }, + }, +} +`; + +exports[`AutoFixModule should auto-fix documents 1`] = ` +Array [ + Object { + "changeAnnotations": undefined, + "documentChanges": Array [ + Object { + "edits": Array [ + Object { + "newText": "text", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + }, + ], + "textDocument": Object { + "uri": "foo", + "version": 1, + }, + }, + ], + }, +] +`; diff --git a/src/server/modules/__tests__/__snapshots__/code-action.js.snap b/src/server/modules/__tests__/__snapshots__/code-action.js.snap new file mode 100644 index 00000000..24070cdd --- /dev/null +++ b/src/server/modules/__tests__/__snapshots__/code-action.js.snap @@ -0,0 +1,116 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CodeActionModule onInitialize should return results 1`] = ` +Object { + "capabilities": Object { + "codeActionProvider": Object { + "codeActionKinds": Array [ + "quickfix", + "source.fixAll.stylelint", + ], + }, + }, +} +`; + +exports[`CodeActionModule with action kind CodeActionKind.Source, should create code actions 1`] = ` +Array [ + Object { + "edit": Object { + "documentChanges": Array [ + Object { + "edits": Array [ + Object { + "newText": "text", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + }, + ], + "textDocument": Object { + "uri": "foo", + "version": undefined, + }, + }, + ], + }, + "kind": "source.fixAll.stylelint", + "title": "Fix all Stylelint auto-fixable problems", + }, +] +`; + +exports[`CodeActionModule with action kind CodeActionKind.SourceFixAll, should create code actions 1`] = ` +Array [ + Object { + "edit": Object { + "documentChanges": Array [ + Object { + "edits": Array [ + Object { + "newText": "text", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + }, + ], + "textDocument": Object { + "uri": "foo", + "version": undefined, + }, + }, + ], + }, + "kind": "source.fixAll.stylelint", + "title": "Fix all Stylelint auto-fixable problems", + }, +] +`; + +exports[`CodeActionModule with action kind StylelintCodeActionKind.StylelintSourceFixAll, should create code actions 1`] = ` +Array [ + Object { + "edit": Object { + "documentChanges": Array [ + Object { + "edits": Array [ + Object { + "newText": "text", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + }, + ], + "textDocument": Object { + "uri": "foo", + "version": undefined, + }, + }, + ], + }, + "kind": "source.fixAll.stylelint", + "title": "Fix all Stylelint auto-fixable problems", + }, +] +`; diff --git a/src/server/modules/__tests__/__snapshots__/completion.js.snap b/src/server/modules/__tests__/__snapshots__/completion.js.snap new file mode 100644 index 00000000..805b0dc8 --- /dev/null +++ b/src/server/modules/__tests__/__snapshots__/completion.js.snap @@ -0,0 +1,317 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CompletionModule onInitialize should return results 1`] = ` +Object { + "capabilities": Object { + "completionProvider": Object {}, + }, +} +`; + +exports[`CompletionModule with diagnostics at the next line and cursor in a disable comment, should return rule completions 1`] = ` +Array [ + Object { + "detail": "disable indentation rule. (stylelint)", + "kind": 15, + "label": "indentation", + }, +] +`; + +exports[`CompletionModule with diagnostics at the next line and cursor in a next-line disable comment, should return rule completions 1`] = ` +Array [ + Object { + "detail": "disable indentation rule. (stylelint)", + "kind": 15, + "label": "indentation", + }, +] +`; + +exports[`CompletionModule with diagnostics at the next line, should return disable comment completions for rule 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line indentation */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:indentation} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; + +exports[`CompletionModule with diagnostics at the same line and cursor in a line disable comment, should return rule completions 1`] = ` +Array [ + Object { + "detail": "disable indentation rule. (stylelint)", + "kind": 15, + "label": "indentation", + }, +] +`; + +exports[`CompletionModule with diagnostics at the same line, should return disable comment completions for rule 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line indentation */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:indentation} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; + +exports[`CompletionModule with needless disables reported for a diagnostic, should return generic completions 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; + +exports[`CompletionModule with no diagnostics at same or next line and cursor in a disable comment, should not return completions 1`] = `Array []`; + +exports[`CompletionModule with no diagnostics at the same or next line, should return generic completions 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; + +exports[`CompletionModule without diagnostics, should return generic completions 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; + +exports[`CompletionModule without the validator module, should return generic completions 1`] = ` +Array [ + Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", + }, + Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", + }, + Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", + }, +] +`; diff --git a/src/server/modules/__tests__/__snapshots__/formatter.js.snap b/src/server/modules/__tests__/__snapshots__/formatter.js.snap new file mode 100644 index 00000000..97260a58 --- /dev/null +++ b/src/server/modules/__tests__/__snapshots__/formatter.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FormatterModule should format documents 1`] = ` +Array [ + Object { + "newText": "text", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + }, +] +`; + +exports[`FormatterModule should format documents 2`] = ` +Array [ + Object { + "languageId": "bar", + "uri": "foo", + }, + Object { + "config": Object { + "rules": Object { + "indentation": Array [ + 2, + ], + "no-missing-end-of-source-newline": true, + }, + }, + }, +] +`; + +exports[`FormatterModule with client dynamic registration support, onInitialize should not request static registration 1`] = ` +Object { + "capabilities": Object { + "documentFormattingProvider": false, + }, +} +`; + +exports[`FormatterModule without client dynamic registration support, onInitialize should request static registration 1`] = ` +Object { + "capabilities": Object { + "documentFormattingProvider": true, + }, +} +`; diff --git a/src/server/modules/__tests__/__snapshots__/old-stylelint-warning.js.snap b/src/server/modules/__tests__/__snapshots__/old-stylelint-warning.js.snap new file mode 100644 index 00000000..44a6ec8e --- /dev/null +++ b/src/server/modules/__tests__/__snapshots__/old-stylelint-warning.js.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`OldStylelintWarningModule with openDocument support, if Stylelint version is less than 14.x and user clicks button, should warn and open URL 1`] = ` +Array [ + Object { + "external": true, + "uri": "https://github.com/stylelint/vscode-stylelint#migrating-from-vscode-stylelint-0xstylelint-13x", + }, +] +`; + +exports[`OldStylelintWarningModule without openDocument support, if Stylelint version is less than 14.x, should warn and provide link to migration guide 1`] = ` +Array [ + "Stylelint version 13.0.0 is no longer supported — you may encounter unexpected behavior. Please upgrade to version 14.0.0 or newer. See the migration guide for more information.", +] +`; diff --git a/src/server/modules/__tests__/auto-fix.js b/src/server/modules/__tests__/auto-fix.js new file mode 100644 index 00000000..cb3f5760 --- /dev/null +++ b/src/server/modules/__tests__/auto-fix.js @@ -0,0 +1,297 @@ +'use strict'; + +const { Position, TextEdit } = require('vscode-languageserver-types'); +const { CommandId } = require('../../../utils/types'); + +const { AutoFixModule } = require('../auto-fix'); + +const mockContext = { + connection: { + onExecuteCommand: jest.fn(), + workspace: { + applyEdit: jest.fn(), + }, + }, + documents: { get: jest.fn() }, + options: { validate: /** @type {string[]} */ ([]) }, + getFixes: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +describe('AutoFixModule', () => { + beforeEach(() => { + mockContext.options.validate = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new AutoFixModule(getParams())).not.toThrow(); + }); + + test('onInitialize should return results', () => { + const module = new AutoFixModule(getParams()); + + expect(module.onInitialize()).toMatchSnapshot(); + }); + + test('onDidRegisterHandlers should register an auto-fix command handler', () => { + const module = new AutoFixModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.connection.onExecuteCommand).toHaveBeenCalledTimes(1); + expect(mockContext.connection.onExecuteCommand).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('should auto-fix documents', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + version: 1, + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + mockContext.connection.workspace.applyEdit.mockResolvedValue({ applied: true }); + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo', version: 1 }], + }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).toHaveBeenCalledWith({ + languageId: 'bar', + uri: 'foo', + version: 1, + }); + expect(mockContext.connection.workspace.applyEdit.mock.calls[0]).toMatchSnapshot(); + }); + + test('with incorrect command, should not attempt to auto-fix', async () => { + const module = new AutoFixModule(getParams()); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ command: 'foo' }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + }); + + test('with no arguments, should not attempt to auto-fix', async () => { + const module = new AutoFixModule(getParams()); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ command: CommandId.ApplyAutoFix }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + }); + + test('if no matching document exists, should not attempt to auto-fix', async () => { + mockContext.documents.get.mockReturnValue(undefined); + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo' }], + }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unknown document, ignoring', { uri: 'foo' }); + }); + + test('if document language ID is not in options, should not attempt to auto-fix', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo' }], + }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document should not be auto-fixed, ignoring', + { + uri: 'foo', + language: 'bar', + }, + ); + }); + + test('with no debug log level and no valid document, should not attempt to log reason', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + mockLogger.isDebugEnabled.mockReturnValue(false); + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const handlerParams = { + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo' }], + }; + + const result = await handler(handlerParams); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Received onExecuteCommand', handlerParams); + }); + + test('if the document has been modified, should not attempt to auto-fix', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + version: 2, + }); + mockContext.options.validate = ['bar']; + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo', version: 1 }], + }); + + expect(result).toStrictEqual({}); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Document has been modified, ignoring', { + uri: 'foo', + }); + }); + + test('if fixes fail to apply, should log the response', async () => { + const response = { applied: false, failureReason: 'foo' }; + + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + version: 1, + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + mockContext.connection.workspace.applyEdit.mockResolvedValue(response); + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo', version: 1 }], + }); + + expect(result).toStrictEqual({}); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Failed to apply fixes', { + uri: 'foo', + response, + }); + }); + + test('if an error occurs while applying fixes, should log it', async () => { + const error = new Error('foo'); + + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + version: 1, + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + mockContext.connection.workspace.applyEdit.mockRejectedValue(error); + + const module = new AutoFixModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onExecuteCommand.mock.calls[0][0]; + + const result = await handler({ + command: CommandId.ApplyAutoFix, + // TODO: Remove once fix is released + // https://github.com/microsoft/TypeScript/issues/43362 + /* prettier-ignore */ + 'arguments': [{ uri: 'foo', version: 1 }], + }); + + expect(result).toStrictEqual({}); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Failed to apply fixes', { + uri: 'foo', + error, + }); + }); +}); diff --git a/src/server/modules/__tests__/code-action.js b/src/server/modules/__tests__/code-action.js new file mode 100644 index 00000000..ff8c99a4 --- /dev/null +++ b/src/server/modules/__tests__/code-action.js @@ -0,0 +1,248 @@ +'use strict'; + +const { CodeActionKind, Position, TextEdit } = require('vscode-languageserver-types'); +const { CodeActionKind: StylelintCodeActionKind } = require('../../../utils/types'); + +const { CodeActionModule } = require('../code-action'); + +const mockContext = { + connection: { onCodeAction: jest.fn() }, + documents: { get: jest.fn() }, + options: { validate: /** @type {string[]} */ ([]) }, + getFixes: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +describe('CodeActionModule', () => { + beforeEach(() => { + mockContext.options.validate = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new CodeActionModule(getParams())).not.toThrow(); + }); + + test('onInitialize should return results', () => { + const module = new CodeActionModule(getParams()); + + expect(module.onInitialize()).toMatchSnapshot(); + }); + + test('onDidRegisterHandlers should register a code action handler', () => { + const module = new CodeActionModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.connection.onCodeAction).toHaveBeenCalledTimes(1); + expect(mockContext.connection.onCodeAction).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('with action kind CodeActionKind.Source, should create code actions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [CodeActionKind.Source] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toMatchSnapshot(); + expect(mockContext.getFixes).toHaveBeenCalledWith({ + languageId: 'bar', + uri: 'foo', + }); + }); + + test('with action kind StylelintCodeActionKind.StylelintSourceFixAll, should create code actions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [StylelintCodeActionKind.StylelintSourceFixAll] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toMatchSnapshot(); + expect(mockContext.getFixes).toHaveBeenCalledWith({ + languageId: 'bar', + uri: 'foo', + }); + }); + + test('with action kind CodeActionKind.SourceFixAll, should create code actions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [CodeActionKind.SourceFixAll] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toMatchSnapshot(); + expect(mockContext.getFixes).toHaveBeenCalledWith({ + languageId: 'bar', + uri: 'foo', + }); + }); + + test('with no action kind, should not attempt to create actions', async () => { + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: {}, + textDocument: { uri: 'foo' }, + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unsupported code action kind, ignoring', { + kind: undefined, + }); + }); + + test('with incorrect action kind, should not attempt to create actions', async () => { + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { + only: ['foo'], + }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unsupported code action kind, ignoring', { + kind: 'foo', + }); + }); + + test('if no matching document exists, should not attempt to create actions', async () => { + mockContext.documents.get.mockReturnValue(undefined); + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [CodeActionKind.Source] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unknown document, ignoring', { uri: 'foo' }); + }); + + test('if document language ID is not in options, should not attempt to create actions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [CodeActionKind.Source] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document should not be validated, ignoring', + { + uri: 'foo', + language: 'bar', + }, + ); + }); + + test('with no debug log level and no valid document, should not attempt to log reason', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + mockLogger.isDebugEnabled.mockReturnValue(false); + + const module = new CodeActionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCodeAction.mock.calls[0][0]; + + const result = await handler({ + context: { only: [CodeActionKind.Source] }, + textDocument: { uri: 'foo' }, + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Received onCodeAction', { + context: { only: [CodeActionKind.Source] }, + uri: 'foo', + }); + }); +}); diff --git a/src/server/modules/__tests__/completion.js b/src/server/modules/__tests__/completion.js new file mode 100644 index 00000000..855dca08 --- /dev/null +++ b/src/server/modules/__tests__/completion.js @@ -0,0 +1,497 @@ +'use strict'; + +const { Position, Range } = require('vscode-languageserver-types'); +const { TextDocument } = require('vscode-languageserver-textdocument'); +const { DisableReportRuleNames } = require('../../../utils/types'); + +const { CompletionModule } = require('../completion'); + +const mockContext = { + connection: { onCompletion: jest.fn() }, + documents: { get: jest.fn() }, + options: { + validate: /** @type {string[]} */ ([]), + snippet: /** @type {string[]} */ ([]), + }, + getModule: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +/** + * @param {string} code + * @returns {TextDocument} + */ +const createDocument = (code) => TextDocument.create('file:///path/test.css', 'css', 0, code); + +/** + * @param {{rule: string, range: lsp.Range}} options + * @returns {lsp.Diagnostic} + */ +const createNeedlessDisableDiagnostic = ({ rule, range }) => ({ + message: `Needless disable for "${rule}"`, + range, + code: DisableReportRuleNames.Needless, +}); + +describe('CompletionModule', () => { + beforeEach(() => { + mockContext.options.validate = []; + mockContext.options.snippet = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new CompletionModule(getParams())).not.toThrow(); + }); + + test('onInitialize should return results', () => { + const module = new CompletionModule(getParams()); + + expect(module.onInitialize()).toMatchSnapshot(); + }); + + test('onDidRegisterHandlers should register a completion handler', () => { + const module = new CompletionModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.connection.onCompletion).toHaveBeenCalledTimes(1); + expect(mockContext.connection.onCompletion).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('if no matching document exists, should not return completions', async () => { + mockContext.documents.get.mockReturnValue(undefined); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getModule).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unknown document, ignoring', { uri: 'foo' }); + }); + + test('if document language ID is not in validate options, should not return completions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + mockContext.options.snippet = ['bar']; + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getModule).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Snippets or validation not enabled for language, ignoring', + { + uri: 'foo', + language: 'bar', + }, + ); + }); + + test('if document language ID is not in snippet options, should not return completions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.options.snippet = ['baz']; + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getModule).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Snippets or validation not enabled for language, ignoring', + { + uri: 'foo', + language: 'bar', + }, + ); + }); + + test('with no debug log level and no valid document, should not attempt to log reason', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.options.snippet = ['baz']; + mockLogger.isDebugEnabled.mockReturnValue(false); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(result).toStrictEqual([]); + expect(mockContext.getModule).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Received onCompletion', { + uri: 'foo', + position: Position.create(0, 0), + }); + }); + + test('without the validator module, should return generic completions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.options.snippet = ['bar']; + mockContext.getModule.mockReturnValue(undefined); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('without diagnostics, should return generic completions', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.options.snippet = ['bar']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + position: Position.create(0, 0), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with no diagnostics at the same or next line, should return generic completions', async () => { + mockContext.documents.get.mockReturnValue(createDocument('a {\n color: red;\n}')); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(3, 4, 3, 4), + }, + { + code: 5, + message: 'Not a Stylelint diagnostic', + range: Range.create(1, 2, 1, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 3), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with diagnostics at the same line, should return disable comment completions for rule', async () => { + mockContext.documents.get.mockReturnValue(createDocument('a {\n color: red;\n}')); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(1, 2, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 3), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with diagnostics at the next line, should return disable comment completions for rule', async () => { + mockContext.documents.get.mockReturnValue( + createDocument('a {\n font-weight: 400;\n color: red;\n}'), + ); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(2, 1, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 3), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with needless disables reported for a diagnostic, should return generic completions', async () => { + mockContext.documents.get.mockReturnValue(createDocument('a {\n color: red;\n}')); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(1, 2, 3, 4), + }, + createNeedlessDisableDiagnostic({ + rule: 'indentation', + range: Range.create(1, 2, 3, 4), + }), + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 3), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with diagnostics at the same line and cursor in a line disable comment, should return rule completions', async () => { + mockContext.documents.get.mockReturnValue( + createDocument(`a { + /* stylelint-disable-line */ + color: red; +}`), + ); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(1, 2, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 28), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with diagnostics at the next line and cursor in a next-line disable comment, should return rule completions', async () => { + mockContext.documents.get.mockReturnValue( + createDocument(`a { + /* stylelint-disable-next-line */ + color: red; +}`), + ); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(2, 2, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 33), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with diagnostics at the next line and cursor in a disable comment, should return rule completions', async () => { + mockContext.documents.get.mockReturnValue( + createDocument(`a { + /* stylelint-disable */ + color: red; +}`), + ); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(2, 2, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 23), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); + + test('with no diagnostics at same or next line and cursor in a disable comment, should not return completions', async () => { + mockContext.documents.get.mockReturnValue( + createDocument(`a { + /* stylelint-disable */ + color: red; + font-weight: 400; +}`), + ); + mockContext.options.validate = ['css']; + mockContext.options.snippet = ['css']; + mockContext.getModule.mockReturnValue({ + getDiagnostics: () => [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(3, 2, 3, 4), + }, + ], + }); + + const module = new CompletionModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onCompletion.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'file:///path/test.css' }, + position: Position.create(1, 25), + }); + + expect(mockContext.getModule).toHaveBeenCalledTimes(1); + expect(result).toMatchSnapshot(); + }); +}); diff --git a/src/server/modules/__tests__/formatter.js b/src/server/modules/__tests__/formatter.js new file mode 100644 index 00000000..1341f70c --- /dev/null +++ b/src/server/modules/__tests__/formatter.js @@ -0,0 +1,341 @@ +'use strict'; + +const { DocumentFormattingRequest } = require('vscode-languageserver-protocol'); +const { Position, TextEdit } = require('vscode-languageserver-types'); + +const { FormatterModule } = require('../formatter'); + +const mockContext = { + connection: { + onDocumentFormatting: jest.fn(), + client: { register: jest.fn() }, + }, + documents: { get: jest.fn() }, + options: { validate: /** @type {string[]} */ ([]) }, + getFixes: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +describe('FormatterModule', () => { + beforeEach(() => { + mockContext.options.validate = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new FormatterModule(getParams())).not.toThrow(); + }); + + test('without client dynamic registration support, onInitialize should request static registration', () => { + const module = new FormatterModule(getParams()); + + expect( + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: false }, + }, + }, + }), + ), + ).toMatchSnapshot(); + }); + + test('with client dynamic registration support, onInitialize should not request static registration', () => { + const module = new FormatterModule(getParams()); + + expect( + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: true }, + }, + }, + }), + ), + ).toMatchSnapshot(); + }); + + test('onDidRegisterHandlers should register a document formatting command handler', () => { + const module = new FormatterModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.connection.onDocumentFormatting).toHaveBeenCalledTimes(1); + expect(mockContext.connection.onDocumentFormatting).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('should format documents', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['bar']; + mockContext.getFixes.mockReturnValue([TextEdit.insert(Position.create(0, 0), 'text')]); + + const module = new FormatterModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + options: { + insertSpaces: true, + tabSize: 2, + insertFinalNewline: true, + trimFinalNewlines: false, + }, + }); + + expect(result).toMatchSnapshot(); + expect(mockContext.getFixes.mock.calls[0]).toMatchSnapshot(); + expect(mockContext.getFixes.mock.results[0].value).toStrictEqual(result); + }); + + test('with incorrect command, should not attempt to format', async () => { + const module = new FormatterModule(getParams()); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const result = await handler({ command: 'foo' }); + + expect(result).toBeNull(); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + }); + + test('with no text document, should not attempt to format', async () => { + const module = new FormatterModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const result = await handler({ options: {} }); + + expect(result).toBeNull(); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('No text document provided, ignoring'); + }); + + test('if no matching document exists, should not attempt to format', async () => { + mockContext.documents.get.mockReturnValue(undefined); + + const module = new FormatterModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + options: {}, + }); + + expect(result).toBeNull(); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Unknown document, ignoring', { uri: 'foo' }); + }); + + test('if document language ID is not in options, should not attempt to format', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + + const module = new FormatterModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const result = await handler({ + textDocument: { uri: 'foo' }, + options: {}, + }); + + expect(result).toBeNull(); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document should not be formatted, ignoring', + { + uri: 'foo', + language: 'bar', + }, + ); + }); + + test('with no debug log level and no valid document, should not attempt to log reason', async () => { + mockContext.documents.get.mockReturnValue({ + uri: 'foo', + languageId: 'bar', + }); + mockContext.options.validate = ['baz']; + mockLogger.isDebugEnabled.mockReturnValue(false); + + const module = new FormatterModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDocumentFormatting.mock.calls[0][0]; + + const handlerParams = { + textDocument: { uri: 'foo' }, + options: {}, + }; + + const result = await handler(handlerParams); + + expect(result).toBeNull(); + expect(mockContext.getFixes).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Received onDocumentFormatting', + handlerParams, + ); + }); + + test("with no debug log level, onDidChangeValidateLanguages shouldn't log languages", () => { + mockLogger.isDebugEnabled.mockReturnValue(false); + const module = new FormatterModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: true }, + }, + }, + }), + ); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + expect(mockLogger.debug).not.toHaveBeenCalledWith('Received onDidChangeValidateLanguages'); + expect(mockLogger.debug).not.toHaveBeenCalledWith('Registering formatter for languages'); + }); + + test("without client dynamic registration support, onDidChangeValidateLanguages shouldn't register a formatter", () => { + const module = new FormatterModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: false }, + }, + }, + }), + ); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + expect(mockContext.connection.client.register).not.toHaveBeenCalled(); + }); + + test('with client dynamic registration support, onDidChangeValidateLanguages should register a formatter', () => { + const module = new FormatterModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: true }, + }, + }, + }), + ); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + expect(mockContext.connection.client.register).toHaveBeenCalledWith( + DocumentFormattingRequest.type, + { documentSelector: [{ language: 'foo' }] }, + ); + }); + + test('without languages to validate, onDidChangeValidateLanguages should register a formatter', () => { + const module = new FormatterModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: true }, + }, + }, + }), + ); + + module.onDidChangeValidateLanguages({ + languages: new Set(), + removedLanguages: new Set(), + }); + + expect(mockContext.connection.client.register).not.toHaveBeenCalled(); + }); + + test('when a formatter was already registered, onDidChangeValidateLanguages should dispose the old registration', () => { + mockLogger.isDebugEnabled.mockReturnValue(true); + const fakePromise = (/** @type {any} */ resolutionValue) => ({ + then: (/** @type {Function} */ resolve) => resolve(resolutionValue), + }); + + const mockRegistration = { dispose: jest.fn(() => fakePromise()) }; + + mockContext.connection.client.register.mockReturnValueOnce(fakePromise(mockRegistration)); + + const module = new FormatterModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + textDocument: { + formatting: { dynamicRegistration: true }, + }, + }, + }), + ); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + module.onDidChangeValidateLanguages({ + languages: new Set(['bar']), + removedLanguages: new Set(['foo']), + }); + + expect(mockRegistration.dispose).toHaveBeenCalled(); + }); +}); diff --git a/src/server/modules/__tests__/old-stylelint-warning.js b/src/server/modules/__tests__/old-stylelint-warning.js new file mode 100644 index 00000000..41b888a2 --- /dev/null +++ b/src/server/modules/__tests__/old-stylelint-warning.js @@ -0,0 +1,473 @@ +'use strict'; + +jest.mock('../../../utils/documents'); +jest.mock('../../../utils/packages'); +jest.mock('fs/promises'); +jest.mock('path'); + +const { getWorkspaceFolder } = + /** @type {jest.Mocked} */ ( + require('../../../utils/documents') + ); + +const { findPackageRoot } = /** @type {jest.Mocked} */ ( + require('../../../utils/packages') +); + +const fs = /** @type {tests.mocks.FSPromisesModule} */ (require('fs/promises')); + +const path = /** @type {tests.mocks.PathModule} */ (require('path')); + +const { OldStylelintWarningModule } = require('../old-stylelint-warning'); + +const mockContext = { + connection: { + window: { + showWarningMessage: jest.fn(), + showDocument: jest.fn(), + }, + }, + documents: { onDidOpen: jest.fn() }, + options: { validate: /** @type {string[]} */ ([]) }, + displayError: jest.fn(), + resolveStylelint: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +describe('OldStylelintWarningModule', () => { + beforeEach(() => { + path.__mockPlatform('posix'); + mockContext.options.validate = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new OldStylelintWarningModule(getParams())).not.toThrow(); + }); + + test('onDidRegisterHandlers should register an onDidOpen handler', () => { + const module = new OldStylelintWarningModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.documents.onDidOpen).toHaveBeenCalledTimes(1); + expect(mockContext.documents.onDidOpen).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('if document language ID is not in options, should not warn', async () => { + mockContext.options.validate = ['baz']; + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).not.toHaveBeenCalled(); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document should not be validated, ignoring', + { uri: 'foo', language: 'bar' }, + ); + }); + + test('if document is not part of a workspace, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue(undefined); + mockContext.options.validate = ['bar']; + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).not.toHaveBeenCalled(); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document not part of a workspace, ignoring', + { uri: 'foo' }, + ); + }); + + test('if document has already been checked, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + mockContext.options.validate = ['bar']; + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document has already been checked, ignoring', + { uri: 'foo' }, + ); + }); + + test('if Stylelint package root cannot be determined, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue(undefined); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Stylelint package root not found', { + uri: 'foo', + }); + }); + + test('if Stylelint package manifest cannot be read, should not warn', async () => { + const error = new Error('foo'); + + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockRejectedValue(error); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Stylelint package manifest could not be read', + { uri: 'foo', manifestPath: '/path/node_modules/stylelint/package.json', error }, + ); + }); + + test('if Stylelint package manifest is malformed, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockResolvedValue('{'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Stylelint package manifest could not be read', + { + uri: 'foo', + manifestPath: '/path/node_modules/stylelint/package.json', + error: expect.any(Error), + }, + ); + }); + + test('if Stylelint package manifest does not contain a version, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockResolvedValue('{}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + }); + + test('if Stylelint version cannot be parsed, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockResolvedValue('{"version": "foo"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Stylelint version could not be parsed', { + uri: 'foo', + version: 'foo', + error: expect.any(Error), + }); + }); + + test('if Stylelint version is 14.x or greater, should not warn', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockResolvedValue('{"version": "14.0.0"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).not.toHaveBeenCalled(); + }); + + test('without openDocument support, if Stylelint version is less than 14.x, should warn and provide link to migration guide', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + fs.readFile.mockResolvedValue('{"version": "13.0.0"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize(/** @type {any} */ ({ capabilities: {} })); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage.mock.calls[0]).toMatchSnapshot(); + expect(mockContext.connection.window.showDocument).not.toHaveBeenCalled(); + }); + + test("with openDocument support, if Stylelint version is less than 14.x and user doesn't click button, should warn but not open URL", async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + mockContext.connection.window.showWarningMessage.mockResolvedValue(undefined); + fs.readFile.mockResolvedValue('{"version": "13.0.0"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + window: { + showDocument: { support: true }, + }, + }, + }), + ); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showDocument).not.toHaveBeenCalled(); + }); + + test('with openDocument support, if Stylelint version is less than 14.x and user clicks button, should warn and open URL', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + mockContext.connection.window.showWarningMessage.mockResolvedValue({ + title: 'Open migration guide', + }); + mockContext.connection.window.showDocument.mockResolvedValue({ + success: true, + }); + fs.readFile.mockResolvedValue('{"version": "13.0.0"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + window: { + showDocument: { support: true }, + }, + }, + }), + ); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showDocument).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showDocument.mock.calls[0]).toMatchSnapshot(); + expect(mockLogger.warn).not.toHaveBeenCalledWith('Failed to open migration guide'); + }); + + test('with openDocument support, if Stylelint version is less than 14.x and user clicks button, but fails to open URL, should warn and log', async () => { + getWorkspaceFolder.mockResolvedValue('/path'); + findPackageRoot.mockResolvedValue('/path/node_modules/stylelint'); + mockContext.resolveStylelint.mockResolvedValue({ + stylelint: {}, + resolvedPath: '/path/node_modules/stylelint', + }); + mockContext.options.validate = ['bar']; + mockContext.connection.window.showWarningMessage.mockResolvedValue({ + title: 'Open migration guide', + }); + mockContext.connection.window.showDocument.mockResolvedValue({ + success: false, + }); + fs.readFile.mockResolvedValue('{"version": "13.0.0"}'); + + const module = new OldStylelintWarningModule(getParams(true)); + + module.onInitialize( + /** @type {any} */ ({ + capabilities: { + window: { + showDocument: { support: true }, + }, + }, + }), + ); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidOpen.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.resolveStylelint).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showWarningMessage).toHaveBeenCalledTimes(1); + expect(mockContext.connection.window.showDocument).toHaveBeenCalledTimes(1); + expect(mockLogger.warn).toHaveBeenCalledWith('Failed to open migration guide'); + }); +}); diff --git a/src/server/modules/__tests__/validator.js b/src/server/modules/__tests__/validator.js new file mode 100644 index 00000000..ef0ed092 --- /dev/null +++ b/src/server/modules/__tests__/validator.js @@ -0,0 +1,534 @@ +'use strict'; + +const { Range } = require('vscode-languageserver-types'); +const { ValidatorModule } = require('../validator'); + +const mockContext = { + connection: { + onDidChangeWatchedFiles: jest.fn(), + sendDiagnostics: jest.fn(), + }, + documents: { + all: jest.fn(), + onDidChangeContent: jest.fn(), + onDidClose: jest.fn(), + }, + options: { validate: /** @type {string[]} */ ([]) }, + displayError: jest.fn(), + lintDocument: jest.fn(), +}; + +const mockLogger = /** @type {jest.Mocked} */ ( + /** @type {any} */ ({ + debug: jest.fn(), + error: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) +); + +const getParams = (passLogger = false) => + /** @type {LanguageServerModuleConstructorParameters} */ ( + /** @type {any} */ + ({ + context: mockContext, + logger: passLogger ? mockLogger : undefined, + }) + ); + +describe('ValidatorModule', () => { + beforeEach(() => { + mockContext.options.validate = []; + jest.clearAllMocks(); + }); + + test('should be constructable', () => { + expect(() => new ValidatorModule(getParams())).not.toThrow(); + }); + + test('onDidRegisterHandlers should register handlers', () => { + const module = new ValidatorModule(getParams()); + + module.onDidRegisterHandlers(); + + expect(mockContext.connection.onDidChangeWatchedFiles).toHaveBeenCalledTimes(1); + expect(mockContext.connection.onDidChangeWatchedFiles).toHaveBeenCalledWith( + expect.any(Function), + ); + expect(mockContext.documents.onDidChangeContent).toHaveBeenCalledTimes(1); + expect(mockContext.documents.onDidChangeContent).toHaveBeenCalledWith(expect.any(Function)); + expect(mockContext.documents.onDidClose).toHaveBeenCalledTimes(1); + expect(mockContext.documents.onDidClose).toHaveBeenCalledWith(expect.any(Function)); + }); + + test('if document language ID is not in options, should not validate', async () => { + mockContext.options.validate = ['baz']; + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.lintDocument).not.toHaveBeenCalled(); + expect(mockLogger.debug).toHaveBeenLastCalledWith( + 'Document should not be validated, ignoring', + { uri: 'foo', language: 'bar' }, + ); + }); + + test('if linting produces no results, should not validate', async () => { + mockContext.options.validate = ['bar']; + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(1); + expect(mockLogger.debug).toHaveBeenLastCalledWith('No lint result, ignoring', { uri: 'foo' }); + }); + + test('if linting produces results, should forward diagnostics to client', async () => { + mockContext.options.validate = ['bar']; + mockContext.lintDocument.mockResolvedValueOnce({ + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Diagnostics sent', { uri: 'foo' }); + }); + + test('if sending diagnostics fails, should display the error', async () => { + const error = new Error('foo'); + + mockContext.options.validate = ['bar']; + mockContext.lintDocument.mockResolvedValueOnce({ + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + mockContext.connection.sendDiagnostics.mockImplementationOnce(() => { + throw error; + }); + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockContext.displayError).toHaveBeenCalledTimes(1); + expect(mockContext.displayError).toHaveBeenCalledWith(error); + expect(mockLogger.error).toHaveBeenLastCalledWith('Failed to send diagnostics', { + uri: 'foo', + error, + }); + }); + + test('onInitialize should validate all documents', async () => { + mockContext.options.validate = ['baz']; + mockContext.lintDocument.mockImplementation((document) => { + return document.uri === 'foo' + ? { + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + } + : { + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }; + }); + mockContext.documents.all.mockReturnValueOnce([ + { uri: 'foo', languageId: 'baz' }, + { uri: 'bar', languageId: 'baz' }, + ]); + + const module = new ValidatorModule(getParams(true)); + + module.onInitialize(); + + // Wait for async validation to complete + await new Promise((resolve) => setImmediate(resolve)); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'bar', + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'foo' }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'bar' }); + }); + + test('onDidChangeWatchedFiles should validate all documents', async () => { + mockContext.options.validate = ['baz']; + mockContext.lintDocument.mockImplementation((document) => { + return document.uri === 'foo' + ? { + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + } + : { + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }; + }); + mockContext.documents.all.mockReturnValueOnce([ + { uri: 'foo', languageId: 'baz' }, + { uri: 'bar', languageId: 'baz' }, + ]); + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.connection.onDidChangeWatchedFiles.mock.calls[0][0]; + + await handler(); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'bar', + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'foo' }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'bar' }); + }); + + test('onDidChangeConfiguration should validate all documents', async () => { + mockContext.options.validate = ['baz']; + mockContext.lintDocument.mockImplementation((document) => { + return document.uri === 'foo' + ? { + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + } + : { + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }; + }); + mockContext.documents.all.mockReturnValueOnce([ + { uri: 'foo', languageId: 'baz' }, + { uri: 'bar', languageId: 'baz' }, + ]); + + const module = new ValidatorModule(getParams(true)); + + await module.onDidChangeConfiguration(); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'bar', + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'foo' }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics sent', { uri: 'bar' }); + }); + + test('getDiagnostics should return cached diagnostics per document', async () => { + mockContext.options.validate = ['bar']; + const diagnostics = [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ]; + + mockContext.lintDocument.mockResolvedValueOnce({ diagnostics }); + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const handler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + + await handler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + const cached = module.getDiagnostics('foo'); + + expect(cached).toStrictEqual(diagnostics); + expect(mockContext.lintDocument).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics, + }); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Diagnostics sent', { uri: 'foo' }); + }); + + test('onDidClose should clear diagnostics', async () => { + mockContext.options.validate = ['bar']; + const diagnostics = [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ]; + + mockContext.lintDocument.mockResolvedValueOnce({ diagnostics }); + + const module = new ValidatorModule(getParams(true)); + + module.onDidRegisterHandlers(); + + const onDidChangeContentHandler = mockContext.documents.onDidChangeContent.mock.calls[0][0]; + const onDidCloseHandler = mockContext.documents.onDidClose.mock.calls[0][0]; + + await onDidChangeContentHandler({ + document: { uri: 'foo', languageId: 'bar' }, + }); + + onDidCloseHandler({ document: { uri: 'foo', languageId: 'bar' } }); + + const cached = module.getDiagnostics('foo'); + + expect(cached).toStrictEqual([]); + expect(mockContext.lintDocument).toHaveBeenCalledTimes(1); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenNthCalledWith(1, { + uri: 'foo', + diagnostics, + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenLastCalledWith({ + uri: 'foo', + diagnostics: [], + }); + expect(mockLogger.debug).toHaveBeenLastCalledWith('Diagnostics cleared', { uri: 'foo' }); + }); + + test("with no debug log level, onDidChangeValidateLanguages shouldn't log languages", () => { + mockLogger.isDebugEnabled.mockReturnValue(false); + mockContext.documents.all.mockReturnValueOnce([]); + const module = new ValidatorModule(getParams(true)); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + expect(mockLogger.debug).not.toHaveBeenCalledWith('Received onDidChangeValidateLanguages'); + expect(mockLogger.debug).not.toHaveBeenCalledWith('Registering formatter for languages'); + }); + + test('with debug log level, onDidChangeValidateLanguages should log languages', () => { + mockLogger.isDebugEnabled.mockReturnValue(true); + mockContext.documents.all.mockReturnValueOnce([]); + const module = new ValidatorModule(getParams(true)); + + module.onDidChangeValidateLanguages({ + languages: new Set(['foo']), + removedLanguages: new Set(), + }); + + expect(mockLogger.debug).toHaveBeenLastCalledWith('Received onDidChangeValidateLanguages', { + removedLanguages: [], + }); + }); + + test('when languages are removed, onDidChangeValidateLanguages should clear diagnostics for documents of those languages', async () => { + mockContext.options.validate = ['baz', 'qux']; + mockContext.lintDocument.mockImplementation((document) => { + return document.uri === 'foo' + ? { + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + } + : { + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }; + }); + mockContext.documents.all.mockReturnValue([ + { uri: 'foo', languageId: 'baz' }, + { uri: 'bar', languageId: 'qux' }, + ]); + + const module = new ValidatorModule(getParams(true)); + + await module.onDidChangeConfiguration(); + + module.onDidChangeValidateLanguages({ + languages: new Set(['qux']), + removedLanguages: new Set(['baz']), + }); + + expect(mockContext.lintDocument).toHaveBeenCalledTimes(2); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledTimes(3); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(4, 5, 1, 4), + }, + ], + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'bar', + diagnostics: [ + { + code: 'color-hex-case', + message: 'Expected "#CCC" to be "#ccc"', + range: Range.create(2, 2, 2, 6), + }, + ], + }); + expect(mockContext.connection.sendDiagnostics).toHaveBeenCalledWith({ + uri: 'foo', + diagnostics: [], + }); + expect(mockLogger.debug).toHaveBeenCalledWith('Diagnostics cleared', { uri: 'foo' }); + }); +}); diff --git a/src/server/modules/auto-fix.js b/src/server/modules/auto-fix.js new file mode 100644 index 00000000..35fe4246 --- /dev/null +++ b/src/server/modules/auto-fix.js @@ -0,0 +1,120 @@ +'use strict'; + +const { WorkspaceChange } = require('vscode-languageserver-protocol'); +const { CommandId } = require('../../utils/types'); + +/** + * @implements {LanguageServerModule} + */ +class AutoFixModule { + static id = 'auto-fix'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @param {lsp.TextDocument} document + * @returns {boolean} + */ + #shouldAutoFix(document) { + return this.#context.options.validate.includes(document.languageId); + } + + /** + * @returns {Partial} + */ + onInitialize() { + return { + capabilities: { + executeCommandProvider: { + commands: [CommandId.ApplyAutoFix], + }, + }, + }; + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering onExecuteCommand handler'); + + this.#context.connection.onExecuteCommand(async ({ command, arguments: args }) => { + this.#logger?.debug('Received onExecuteCommand', { command, arguments: args }); + + if (command !== CommandId.ApplyAutoFix || !args) { + return {}; + } + + /** @type { { version: number, uri: string } } */ + const identifier = args[0]; + const uri = identifier.uri; + const document = this.#context.documents.get(uri); + + if (!document || !this.#shouldAutoFix(document)) { + if (this.#logger?.isDebugEnabled()) { + if (!document) { + this.#logger.debug('Unknown document, ignoring', { uri }); + } else { + this.#logger.debug('Document should not be auto-fixed, ignoring', { + uri, + language: document.languageId, + }); + } + } + + return {}; + } + + if (identifier.version !== document.version) { + this.#logger?.debug('Document has been modified, ignoring', { uri }); + + return {}; + } + + const workspaceChange = new WorkspaceChange(); + const textChange = workspaceChange.getTextEditChange(identifier); + + const edits = await this.#context.getFixes(document); + + edits.forEach((edit) => textChange.add(edit)); + + this.#logger?.debug('Applying fixes', { uri, edits }); + + try { + const response = await this.#context.connection.workspace.applyEdit(workspaceChange.edit); + + if (!response.applied) { + this.#logger?.debug('Failed to apply fixes', { uri, response }); + } + } catch (error) { + this.#logger?.debug('Failed to apply fixes', { uri, error }); + } + + return {}; + }); + + this.#logger?.debug('onExecuteCommand handler registered'); + } +} + +module.exports = { + AutoFixModule, +}; diff --git a/src/server/modules/code-action.js b/src/server/modules/code-action.js new file mode 100644 index 00000000..b0b0fbc5 --- /dev/null +++ b/src/server/modules/code-action.js @@ -0,0 +1,114 @@ +'use strict'; + +const { CodeActionKind, CodeAction, TextDocumentEdit } = require('vscode-languageserver-types'); +const { CodeActionKind: StylelintCodeActionKind } = require('../../utils/types'); + +/** + * @implements {LanguageServerModule} + */ +class CodeActionModule { + static id = 'code-action'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @param {lsp.TextDocument} document + * @returns {boolean} + */ + #shouldCodeAction(document) { + return this.#context.options.validate.includes(document.languageId); + } + + /** + * @returns {Partial} + */ + onInitialize() { + return { + capabilities: { + codeActionProvider: { + codeActionKinds: [CodeActionKind.QuickFix, StylelintCodeActionKind.StylelintSourceFixAll], + }, + }, + }; + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering onCodeAction handler'); + + this.#context.connection.onCodeAction(async ({ context, textDocument }) => { + this.#logger?.debug('Received onCodeAction', { context, uri: textDocument.uri }); + + const only = context.only !== undefined ? context.only[0] : undefined; + const isSource = only === CodeActionKind.Source; + const isSourceFixAll = + only === StylelintCodeActionKind.StylelintSourceFixAll || + only === CodeActionKind.SourceFixAll; + + if (!isSourceFixAll && !isSource) { + this.#logger?.debug('Unsupported code action kind, ignoring', { kind: only }); + + return []; + } + + const uri = textDocument.uri; + const document = this.#context.documents.get(uri); + + if (!document || !this.#shouldCodeAction(document)) { + if (this.#logger?.isDebugEnabled()) { + if (!document) { + this.#logger.debug('Unknown document, ignoring', { uri }); + } else { + this.#logger.debug('Document should not be validated, ignoring', { + uri, + language: document.languageId, + }); + } + } + + return []; + } + + const identifier = { uri: document.uri, version: document.version }; + const edits = await this.#context.getFixes(document); + + const actions = [ + CodeAction.create( + `Fix all Stylelint auto-fixable problems`, + { documentChanges: [TextDocumentEdit.create(identifier, edits)] }, + StylelintCodeActionKind.StylelintSourceFixAll, + ), + ]; + + this.#logger?.debug('Returning code actions', { actions }); + + return actions; + }); + + this.#logger?.debug('onCodeAction handler registered'); + } +} + +module.exports = { + CodeActionModule, +}; diff --git a/src/server/modules/completion.js b/src/server/modules/completion.js new file mode 100644 index 00000000..d3592c56 --- /dev/null +++ b/src/server/modules/completion.js @@ -0,0 +1,191 @@ +'use strict'; + +const { CompletionItemKind } = require('vscode-languageserver-types'); +const { getDisableType } = require('../../utils/documents'); +const { createDisableCompletionItem } = require('../../utils/lsp'); +const { DisableReportRuleNames } = require('../../utils/types'); +const { DisableMetadataLookupTable } = require('../../utils/stylelint'); + +/** + * @implements {LanguageServerModule} + */ +class CompletionModule { + static id = 'completion'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @returns {Partial} + */ + onInitialize() { + return { + capabilities: { + completionProvider: {}, + }, + }; + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering onCompletion handler'); + + this.#context.connection.onCompletion(this.#onCompletion.bind(this)); + + this.#logger?.debug('onCompletion handler registered'); + } + + /** + * @param {lsp.TextDocument} document + * @returns {boolean} + */ + #shouldComplete(document) { + return ( + this.#context.options.validate.includes(document.languageId) && + this.#context.options.snippet.includes(document.languageId) + ); + } + + /** + * @param {lsp.CompletionParams} params + * @returns {lsp.CompletionItem[]} + */ + #onCompletion({ textDocument, position }) { + const { uri } = textDocument; + + this.#logger?.debug('Received onCompletion', { uri, position }); + + const document = this.#context.documents.get(uri); + + if (!document || !this.#shouldComplete(document)) { + if (this.#logger?.isDebugEnabled()) { + if (!document) { + this.#logger.debug('Unknown document, ignoring', { uri }); + } else { + this.#logger.debug('Snippets or validation not enabled for language, ignoring', { + uri, + language: document.languageId, + }); + } + } + + return []; + } + + const validatorModule = /** @type {import('./validator').ValidatorModule | undefined} */ ( + this.#context.getModule('validator') + ); + + const diagnostics = validatorModule?.getDiagnostics(uri); + + if (!diagnostics || diagnostics.length === 0) { + const items = [ + createDisableCompletionItem('stylelint-disable-line'), + createDisableCompletionItem('stylelint-disable-next-line'), + createDisableCompletionItem('stylelint-disable'), + ]; + + this.#logger?.debug('No diagnostics for document, returning generic completion items', { + uri, + items, + }); + + return items; + } + + const thisLineRules = new Set(); + const nextLineRules = new Set(); + + const disableTable = new DisableMetadataLookupTable(diagnostics); + + for (const { code, range } of diagnostics) { + if ( + !code || + typeof code !== 'string' || + code === 'CssSyntaxError' || + disableTable.find({ + type: DisableReportRuleNames.Needless, + rule: code, + range, + }).size > 0 + ) { + continue; + } + + if (range.start.line === position.line) { + thisLineRules.add(code); + } else if (range.start.line === position.line + 1) { + nextLineRules.add(code); + } + } + + /** @type {lsp.CompletionItem[]} */ + const results = []; + + const disableType = getDisableType(document, position); + + if (disableType === 'stylelint-disable-line') { + for (const rule of thisLineRules) { + results.push({ + label: rule, + kind: CompletionItemKind.Snippet, + detail: `disable ${rule} rule. (stylelint)`, + }); + } + } else if ( + disableType === 'stylelint-disable' || + disableType === 'stylelint-disable-next-line' + ) { + for (const rule of nextLineRules) { + results.push({ + label: rule, + kind: CompletionItemKind.Snippet, + detail: `disable ${rule} rule. (stylelint)`, + }); + } + } else { + results.push( + createDisableCompletionItem( + 'stylelint-disable-line', + thisLineRules.size === 1 ? thisLineRules.values().next().value : undefined, + ), + ); + + results.push( + createDisableCompletionItem( + 'stylelint-disable-next-line', + nextLineRules.size === 1 ? nextLineRules.values().next().value : undefined, + ), + ); + + results.push(createDisableCompletionItem('stylelint-disable')); + } + + this.#logger?.debug('Returning completion items', { uri, results }); + + return results; + } +} + +module.exports = { + CompletionModule, +}; diff --git a/src/server/modules/formatter.js b/src/server/modules/formatter.js new file mode 100644 index 00000000..4395885e --- /dev/null +++ b/src/server/modules/formatter.js @@ -0,0 +1,170 @@ +'use strict'; + +const { DocumentFormattingRequest } = require('vscode-languageserver-protocol'); +const { formattingOptionsToRules } = require('../../utils/stylelint'); + +/** + * @implements {LanguageServerModule} + */ +class FormatterModule { + static id = 'formatter'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * Whether or not dynamic registration for document formatting should be + * attempted. + * @type {boolean} + */ + #registerDynamically = false; + + /** + * A promise that resolves to the disposable for the dynamically registered + * document formatter. + * @type {Promise | undefined} + */ + #registration = undefined; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @param {lsp.TextDocument} document + * @returns {boolean} + */ + #shouldFormat(document) { + return this.#context.options.validate.includes(document.languageId); + } + + /** + * @param {lsp.InitializeParams} params + * @returns {Partial} + */ + onInitialize({ capabilities }) { + this.#registerDynamically = Boolean(capabilities.textDocument?.formatting?.dynamicRegistration); + + return { + capabilities: { + // Use static registration if dynamic registration is not + // supported by the client + documentFormattingProvider: !this.#registerDynamically, + }, + }; + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering onDocumentFormatting handler'); + + this.#context.connection.onDocumentFormatting(({ textDocument, options }) => { + this.#logger?.debug('Received onDocumentFormatting', { textDocument, options }); + + if (!textDocument) { + this.#logger?.debug('No text document provided, ignoring'); + + return null; + } + + const { uri } = textDocument; + const document = this.#context.documents.get(uri); + + if (!document || !this.#shouldFormat(document)) { + if (this.#logger?.isDebugEnabled()) { + if (!document) { + this.#logger.debug('Unknown document, ignoring', { uri }); + } else { + this.#logger.debug('Document should not be formatted, ignoring', { + uri, + language: document.languageId, + }); + } + } + + return null; + } + + const linterOptions = { + config: { + rules: formattingOptionsToRules(options), + }, + }; + + this.#logger?.debug('Formatting document', { uri, linterOptions }); + + const fixes = this.#context.getFixes(document, linterOptions); + + this.#logger?.debug('Returning fixes', { uri, fixes }); + + return fixes; + }); + + this.#logger?.debug('onDocumentFormatting handler registered'); + } + + /** + * @param {DidChangeValidateLanguagesParams} params + * @returns {void} + */ + onDidChangeValidateLanguages({ languages }) { + if (this.#logger?.isDebugEnabled()) { + this.#logger?.debug('Received onDidChangeValidateLanguages', { languages: [...languages] }); + } + + // If dynamic registration is supported and the list of languages that should be validated + // has changed, then (re-)register the formatter. + if (this.#registerDynamically) { + // Dispose the old formatter registration if it exists. + if (this.#registration) { + this.#logger?.debug('Disposing old formatter registration'); + + void this.#registration + .then((disposable) => disposable.dispose()) + .then(() => { + this.#logger?.debug('Old formatter registration disposed'); + }); + } + + // If there are languages that should be validated, register a formatter for those + // languages. + if (languages.size > 0) { + const documentSelector = []; + + for (const language of languages) { + documentSelector.push({ language }); + } + + if (this.#logger?.isDebugEnabled()) { + this.#logger?.debug('Registering formatter for languages', { languages: [...languages] }); + } + + this.#registration = this.#context.connection.client.register( + DocumentFormattingRequest.type, + { documentSelector }, + ); + + this.#logger?.debug('Formatter registered'); + } + } + } +} + +module.exports = { + FormatterModule, +}; diff --git a/src/server/modules/index.js b/src/server/modules/index.js new file mode 100644 index 00000000..0f916259 --- /dev/null +++ b/src/server/modules/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = { + ...require('./auto-fix'), + ...require('./code-action'), + ...require('./completion'), + ...require('./formatter'), + ...require('./old-stylelint-warning'), + ...require('./validator'), +}; diff --git a/src/server/modules/old-stylelint-warning.js b/src/server/modules/old-stylelint-warning.js new file mode 100644 index 00000000..48637d20 --- /dev/null +++ b/src/server/modules/old-stylelint-warning.js @@ -0,0 +1,196 @@ +'use strict'; + +const path = require('path'); +const fs = require('fs/promises'); +const semver = require('semver'); +const { getWorkspaceFolder } = require('../../utils/documents'); +const { findPackageRoot } = require('../../utils/packages'); + +/** + * @implements {LanguageServerModule} + */ +class OldStylelintWarningModule { + static id = 'old-stylelint-warning'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * Set of workspaces for which Stylelint's version has already been checked. + * @type {Set} + */ + #checkedWorkspaces = new Set(); + + /** + * Whether or not to provide the URL to the migration guide. + * @type {boolean} + */ + #openMigrationGuide = false; + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @param {lsp.InitializeParams} params + * @returns {void} + */ + onInitialize({ capabilities }) { + this.#openMigrationGuide = capabilities.window?.showDocument?.support ?? false; + } + + /** + * @param {lsp.TextDocument} document + * @returns {Promise} + */ + async #getStylelintVersion(document) { + const result = await this.#context.resolveStylelint(document); + + if (!result) { + this.#logger?.debug('Stylelint not found', { + uri: document.uri, + }); + + return undefined; + } + + const packageDir = await findPackageRoot(result.resolvedPath); + + if (!packageDir) { + this.#logger?.debug('Stylelint package root not found', { + uri: document.uri, + }); + + return undefined; + } + + const manifestPath = path.join(packageDir, 'package.json'); + + try { + const rawManifest = await fs.readFile(manifestPath, 'utf8'); + + const manifest = JSON.parse(rawManifest); + + return manifest.version; + } catch (error) { + this.#logger?.debug('Stylelint package manifest could not be read', { + uri: document.uri, + manifestPath, + error, + }); + + return undefined; + } + } + + /** + * @param {lsp.TextDocument} document + * @returns {Promise} + */ + async #check(document) { + if (!this.#context.options.validate.includes(document.languageId)) { + this.#logger?.debug('Document should not be validated, ignoring', { + uri: document.uri, + language: document.languageId, + }); + + return undefined; + } + + const workspaceFolder = await getWorkspaceFolder(this.#context.connection, document); + + if (!workspaceFolder) { + this.#logger?.debug('Document not part of a workspace, ignoring', { + uri: document.uri, + }); + + return undefined; + } + + if (this.#checkedWorkspaces.has(workspaceFolder)) { + this.#logger?.debug('Document has already been checked, ignoring', { + uri: document.uri, + }); + + return undefined; + } + + this.#checkedWorkspaces.add(workspaceFolder); + + const stylelintVersion = await this.#getStylelintVersion(document); + + try { + return stylelintVersion && semver.lt(stylelintVersion, '14.0.0') + ? stylelintVersion + : undefined; + } catch (error) { + this.#logger?.debug('Stylelint version could not be parsed', { + uri: document.uri, + version: stylelintVersion, + error, + }); + + return undefined; + } + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering onDidOpen handler'); + + this.#context.documents.onDidOpen(async ({ document }) => { + const stylelintVersion = await this.#check(document); + + if (!stylelintVersion) { + return; + } + + this.#logger?.warn(`Found unsupported version of Stylelint: ${stylelintVersion}`); + + const message = `Stylelint version ${stylelintVersion} is no longer supported — you may encounter unexpected behavior. Please upgrade to version 14.0.0 or newer. See the migration guide for more information.`; + + if (!this.#openMigrationGuide) { + this.#context.connection.window.showWarningMessage(message); + + return; + } + + const warningResponse = await this.#context.connection.window.showWarningMessage(message, { + title: 'Open migration guide', + }); + + if (warningResponse?.title === 'Open migration guide') { + // Open URL in browser + const showURIResponse = await this.#context.connection.window.showDocument({ + uri: 'https://github.com/stylelint/vscode-stylelint#migrating-from-vscode-stylelint-0xstylelint-13x', + external: true, + }); + + if (!showURIResponse.success) { + this.#logger?.warn('Failed to open migration guide'); + } + } + }); + + this.#logger?.debug('onDidOpen handler registered'); + } +} + +module.exports = { + OldStylelintWarningModule, +}; diff --git a/src/server/modules/validator.js b/src/server/modules/validator.js new file mode 100644 index 00000000..15272ea6 --- /dev/null +++ b/src/server/modules/validator.js @@ -0,0 +1,174 @@ +'use strict'; + +/** + * @implements {LanguageServerModule} + */ +class ValidatorModule { + static id = 'validator'; + + /** + * The language server context. + * @type {LanguageServerContext} + */ + #context; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * Diagnostics for each document by URI. + * @type {Map} + */ + #documentDiagnostics = new Map(); + + /** + * @param {LanguageServerModuleConstructorParameters} params + */ + constructor({ context, logger }) { + this.#context = context; + this.#logger = logger; + } + + /** + * @param {lsp.TextDocument} document + * @returns {boolean} + */ + #shouldValidate(document) { + return this.#context.options.validate.includes(document.languageId); + } + + /** + * @param {lsp.TextDocument} document + * @returns {Promise} + */ + async #validate(document) { + if (!this.#shouldValidate(document)) { + this.#logger?.debug('Document should not be validated, ignoring', { + uri: document.uri, + language: document.languageId, + }); + + return; + } + + const result = await this.#context.lintDocument(document); + + if (!result) { + this.#logger?.debug('No lint result, ignoring', { uri: document.uri }); + + return; + } + + this.#logger?.debug('Sending diagnostics', { uri: document.uri, result }); + + try { + this.#context.connection.sendDiagnostics({ + uri: document.uri, + diagnostics: result.diagnostics, + }); + this.#documentDiagnostics.set(document.uri, result.diagnostics); + + this.#logger?.debug('Diagnostics sent', { uri: document.uri }); + } catch (error) { + this.#context.displayError(error); + + this.#logger?.error('Failed to send diagnostics', { uri: document.uri, error }); + } + } + + /** + * @returns {Promise} + */ + async #validateAll() { + await Promise.allSettled( + this.#context.documents.all().map((document) => this.#validate(document)), + ); + } + + /** + * @param {lsp.TextDocument} document + * @returns {void} + */ + #clearDiagnostics({ uri }) { + this.#logger?.debug('Clearing diagnostics for document', { uri }); + + this.#documentDiagnostics.delete(uri); + this.#context.connection.sendDiagnostics({ uri, diagnostics: [] }); + + this.#logger?.debug('Diagnostics cleared', { uri }); + } + + /** + * Returns the diagnostics for the given document. + * @param {string} uri + * @returns {lsp.Diagnostic[]} + */ + getDiagnostics(uri) { + return this.#documentDiagnostics.get(uri) ?? []; + } + + /** + * @returns {void} + */ + onInitialize() { + void this.#validateAll(); + } + + /** + * @returns {void} + */ + onDidRegisterHandlers() { + this.#logger?.debug('Registering handlers'); + + this.#context.connection.onDidChangeWatchedFiles(async () => await this.#validateAll()); + + this.#logger?.debug('onDidChangeWatchedFiles handler registered'); + + this.#context.documents.onDidChangeContent( + async ({ document }) => await this.#validate(document), + ); + + this.#logger?.debug('onDidChangeContent handler registered'); + + this.#context.documents.onDidClose(({ document }) => { + this.#clearDiagnostics(document); + }); + + this.#logger?.debug('onDidClose handler registered'); + this.#logger?.debug('Handlers registered'); + } + + /** + * @returns {Promise} + */ + async onDidChangeConfiguration() { + this.#logger?.debug('Received onDidChangeConfiguration'); + + await this.#validateAll(); + } + + /** + * @param {DidChangeValidateLanguagesParams} params + * @returns {void} + */ + onDidChangeValidateLanguages({ removedLanguages }) { + if (this.#logger?.isDebugEnabled()) { + this.#logger?.debug('Received onDidChangeValidateLanguages', { + removedLanguages: [...removedLanguages], + }); + } + + for (const document of this.#context.documents.all()) { + if (removedLanguages.has(document.languageId)) { + this.#clearDiagnostics(document); + } + } + } +} + +module.exports = { + ValidatorModule, +}; diff --git a/src/server/server.js b/src/server/server.js new file mode 100644 index 00000000..9e10548f --- /dev/null +++ b/src/server/server.js @@ -0,0 +1,399 @@ +'use strict'; + +const { TextDocument } = require('vscode-languageserver-textdocument'); +const { TextDocuments } = require('vscode-languageserver/node'); +const { TextDocumentSyncKind } = require('vscode-languageserver-protocol'); + +const { getFixes } = require('../utils/documents'); +const { displayError } = require('../utils/lsp'); +const { deepAssign } = require('../utils/objects'); +const { StylelintRunner } = require('../utils/stylelint'); +const { StylelintResolver } = require('../utils/packages'); + +/** @type {LanguageServerOptions} */ +const defaultOptions = { + packageManager: 'npm', + validate: ['css', 'less', 'postcss'], + snippet: ['css', 'less', 'postcss'], +}; + +/** + * Stylelint language server. + */ +class StylelintLanguageServer { + /** + * The language server connection. + * @type {lsp.Connection} + */ + #connection; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * The language server options. + * @type {LanguageServerOptions} + */ + #options; + + /** + * The resolver used to resolve the Stylelint package. + * @type {StylelintResolver} + */ + #resolver; + + /** + * The runner used to run Stylelint. + * @type {StylelintRunner} + */ + #runner; + + /** + * The text document manager. + * @type {lsp.TextDocuments} + */ + #documents; + + /** + * The language server context passed between modules. + * @type {LanguageServerContext} + */ + #context; + + /** + * Registered modules. + * @type {Map} + */ + #modules = new Map(); + + /** + * Creates a new Stylelint language server. + * @param {LanguageServerConstructorParameters} params + */ + constructor({ connection, logger, modules }) { + this.#connection = connection; + this.#logger = logger?.child({ component: 'language-server' }); + this.#options = defaultOptions; + this.#resolver = new StylelintResolver(connection, this.#logger); + this.#runner = new StylelintRunner(connection, this.#logger, this.#resolver); + this.#documents = new TextDocuments(TextDocument); + this.#context = { + connection: this.#connection, + documents: this.#documents, + options: this.#options, + runner: this.#runner, + getModule: this.#getModule.bind(this), + getFixes: this.#getFixes.bind(this), + displayError: this.#displayError.bind(this), + lintDocument: this.#lintDocument.bind(this), + resolveStylelint: this.#resolveStylelint.bind(this), + }; + + const contextReadOnlyProxy = new Proxy(this.#context, { + get(target, name) { + return target[/** @type {keyof typeof target} */ (name)]; + }, + + set() { + throw new Error('Cannot set read-only property'); + }, + }); + + if (modules) { + for (const Module of modules) { + this.#logger?.info('Registering module', { module: Module.id }); + + if (!Module.id) { + throw new Error('Modules must have an ID'); + } + + if (typeof Module.id !== 'string') { + throw new Error('Module IDs must be strings'); + } + + const module = new Module({ + context: contextReadOnlyProxy, + logger: logger?.child({ component: `language-server:${Module.id}` }), + }); + + if (this.#modules.has(Module.id)) { + throw new Error(`Module with ID "${Module.id}" already registered`); + } + + this.#modules.set(Module.id, module); + + this.#logger?.info('Module registered', { module: Module.id }); + } + } + } + + /** + * Starts the language server. + */ + start() { + this.#logger?.info('Starting language server'); + + this.#registerHandlers(); + + this.#documents.listen(this.#connection); + this.#connection.listen(); + + this.#logger?.info('Language server started'); + } + + /** + * @param {unknown} error + */ + #displayError(error) { + displayError(this.#connection, error); + } + + /** + * Resolves the Stylelint package for the given document. + * @param {lsp.TextDocument} document + * @returns {Promise} + */ + async #resolveStylelint(document) { + this.#logger?.debug('Resolving Stylelint', { uri: document.uri }); + + try { + const result = await this.#resolver.resolve(this.#options, document); + + if (result) { + this.#logger?.debug('Stylelint resolved', { + uri: document.uri, + resolvedPath: result.resolvedPath, + }); + } else { + this.#logger?.warn('Failed to resolve Stylelint', { uri: document.uri }); + } + + return result; + } catch (error) { + this.#displayError(error); + this.#logger?.error('Error resolving Stylelint', { uri: document.uri, error }); + + return undefined; + } + } + + /** + * Lints a document using Stylelint. + * @param {lsp.TextDocument} document + * @param {Partial} [linterOptions] + * @returns {Promise} + */ + async #lintDocument(document, linterOptions = {}) { + this.#logger?.debug('Linting document', { uri: document.uri, linterOptions }); + + try { + const results = await this.#runner.lintDocument(document, linterOptions, this.#options); + + this.#logger?.debug('Lint run complete', { uri: document.uri, results }); + + return results; + } catch (err) { + this.#displayError(err); + this.#logger?.error('Error running lint', { uri: document.uri, error: err }); + + return undefined; + } + } + + /** + * Gets text edits for fixes made by Stylelint. + * @param {lsp.TextDocument} document + * @param {stylelint.LinterOptions} [linterOptions] + * @returns {Promise} + */ + async #getFixes(document, linterOptions = {}) { + try { + const edits = await getFixes(this.#runner, document, linterOptions, this.#options); + + this.#logger?.debug('Fixes retrieved', { uri: document.uri, edits }); + + return edits; + } catch (error) { + this.#displayError(error); + this.#logger?.error('Error getting fixes', { uri: document.uri, error }); + + return []; + } + } + + /** + * Gets the registered module with the given ID if it exists. + * @param {string} id + * @returns {LanguageServerModule | undefined} + */ + #getModule(id) { + return this.#modules.get(id); + } + + /** + * Sets the language server options. + * @param {ExtensionOptions} options + */ + #setOptions(options) { + /** @type {LanguageServerOptions} */ + this.#options = { + config: options.config, + configBasedir: options.configBasedir, + configFile: options.configFile, + customSyntax: options.customSyntax, + ignoreDisables: options.ignoreDisables, + packageManager: options.packageManager || defaultOptions.packageManager, + reportInvalidScopeDisables: options.reportInvalidScopeDisables, + reportNeedlessDisables: options.reportNeedlessDisables, + snippet: options.snippet ?? defaultOptions.snippet, + stylelintPath: options.stylelintPath, + validate: options.validate ?? defaultOptions.validate, + }; + + Object.freeze(this.#options); + + this.#context.options = this.#options; + + this.#logger?.debug('Options updated', { options: this.#options }); + } + + /** + * Registers handlers on the language server connection, then invokes the + * `onDidRegisterHandlers` event for each registered module to allow them + * to register their handlers. + */ + #registerHandlers() { + this.#logger?.info('Registering handlers'); + + this.#connection.onInitialize(this.#onInitialize.bind(this)); + + this.#logger?.debug('onInitialize handler registered'); + + this.#connection.onDidChangeConfiguration(this.#onDidChangeConfiguration.bind(this)); + + this.#logger?.debug('onDidChangeConfiguration handler registered'); + + this.#invokeHandlers('onDidRegisterHandlers'); + + this.#logger?.info('Handlers registered'); + } + + /** + * Calls the given handler for all registered modules. + * @template {keyof LanguageServerHandlerParameters} K + * @template {LanguageServerHandlerParameters[K]} P + * @template {LanguageServerHandlerReturnValues[K]} R + * @param {K} handlerName + * @param {P} params + * @returns {{[moduleName: string]: R[]}} + */ + #invokeHandlers(handlerName, ...params) { + this.#logger?.debug(`Invoking ${handlerName}`); + /** @type {{[moduleName: string]: R[]}} */ + const returnValues = Object.create(null); + + for (const [id, module] of this.#modules) { + const handler = module[handlerName]; + + if (handler) { + try { + returnValues[id] = /** @type {(...args: P) => any} */ (handler).apply(module, params); + + this.#logger?.debug(`Invoked ${handlerName}`, { + module: id, + returnValue: returnValues[id], + }); + } catch (error) { + this.#displayError(error); + this.#logger?.error(`Error invoking ${handlerName}`, { + module: id, + error, + }); + } + } + } + + return returnValues; + } + + /** + * @param {lsp.InitializeParams} params + * @returns {lsp.InitializeResult} + */ + #onInitialize(params) { + this.#logger?.debug('received onInitialize', { params }); + + /** @type {lsp.InitializeResult} */ + const result = { + capabilities: { + textDocumentSync: { + openClose: true, + change: TextDocumentSyncKind.Full, + }, + }, + }; + + for (const [, moduleResult] of Object.entries(this.#invokeHandlers('onInitialize', params))) { + if (moduleResult) { + deepAssign(result, moduleResult); + } + } + + this.#logger?.debug('Returning initialization results', { result }); + + return result; + } + + /** + * @param {lsp.DidChangeConfigurationParams} params + * @returns {void} + */ + #onDidChangeConfiguration(params) { + this.#logger?.debug('received onDidChangeConfiguration', { params }); + + const oldOptions = this.#options; + + this.#setOptions(params.settings.stylelint); + + const validateLanguageSet = new Set(this.#options.validate); + const oldValidateLanguageSet = new Set(oldOptions.validate); + + /** Whether or not the list of languages that should be validated has changed. */ + let changed = validateLanguageSet.size !== oldValidateLanguageSet.size; + + /** The languages removed from the list of languages that should be validated */ + const removedLanguages = new Set(); + + // Check if the sets are unequal, which means that the list of languages that should be + // validated has changed. + for (const language of oldValidateLanguageSet) { + if (!validateLanguageSet.has(language)) { + removedLanguages.add(language); + changed = true; + } + } + + if (changed) { + if (this.#logger?.isDebugEnabled()) { + this.#logger?.debug('Languages that should be validated changed', { + languages: [...validateLanguageSet], + removedLanguages: [...removedLanguages], + }); + } + + this.#invokeHandlers('onDidChangeValidateLanguages', { + languages: validateLanguageSet, + removedLanguages, + }); + } + + this.#invokeHandlers('onDidChangeConfiguration', { settings: this.#options }); + } +} + +module.exports = { + StylelintLanguageServer, +}; diff --git a/src/start-server.js b/src/start-server.js new file mode 100644 index 00000000..4947338f --- /dev/null +++ b/src/start-server.js @@ -0,0 +1,44 @@ +'use strict'; + +const { createConnection, ProposedFeatures } = require('vscode-languageserver/node'); +const winston = require('winston'); +const { StylelintLanguageServer, modules } = require('./server'); + +const connection = createConnection(ProposedFeatures.all); + +const { LanguageServerTransport, LanguageServerFormatter } = require('./utils/logging'); + +const { NODE_ENV } = process.env; + +const level = NODE_ENV === 'development' ? 'debug' : 'info'; + +/** @type {winston.transport[]} */ +const transports = [ + new LanguageServerTransport({ + connection, + format: new LanguageServerFormatter({ + connection, + preferredKeyOrder: ['module', 'uri', 'command'], + }), + }), +]; + +if (level === 'debug') { + transports.push( + new winston.transports.File({ + filename: require('path').join(__dirname, '../stylelint-language-server.log'), + level, + format: winston.format.combine(winston.format.timestamp(), winston.format.json()), + }), + ); +} + +const logger = winston.createLogger({ level, transports }); + +const server = new StylelintLanguageServer({ + connection, + logger, + modules: Object.values(modules), +}); + +server.start(); diff --git a/src/stylelint-vscode.js b/src/stylelint-vscode.js deleted file mode 100644 index c184ede6..00000000 --- a/src/stylelint-vscode.js +++ /dev/null @@ -1,259 +0,0 @@ -'use strict'; - -const os = require('os'); -const path = require('path'); -const pathIsInside = require('path-is-inside'); -const { Files } = require('vscode-languageserver/node'); -const { URI } = require('vscode-uri'); -const { getGlobalPathResolver } = require('./utils/packages'); - -const stylelintWarningToVscodeDiagnostic = require('./warnings-to-diagnostics'); - -class InvalidOptionError extends Error { - /** - * @param {string[]} reasons - */ - constructor(reasons) { - super(reasons.join('\n')); - this.reasons = reasons; - } -} - -/** - * @param {stylelint.LinterResult} resultContainer - * @param {RuleDocUrlProvider} ruleDocUrlProvider - * @returns {StylelintVSCodeResult} - */ -function processResults(resultContainer, ruleDocUrlProvider) { - const { results } = resultContainer; - - if (results.length === 0) { - return { diagnostics: [] }; - } - - const [{ invalidOptionWarnings, warnings, ignored }] = results; - - if (ignored) { - return { diagnostics: [] }; - } - - if (invalidOptionWarnings.length !== 0) { - throw new InvalidOptionError(invalidOptionWarnings.map((warning) => warning.text)); - } - - const diagnostics = warnings.map((warning) => - stylelintWarningToVscodeDiagnostic(warning, ruleDocUrlProvider), - ); - - if (Object.prototype.hasOwnProperty.call(resultContainer, 'output') && resultContainer.output) { - return { - diagnostics, - output: resultContainer.output, - }; - } - - return { diagnostics }; -} - -/** - * @param {lsp.TextDocument} textDocument - * @param {stylelint.LinterOptions} options - * @param {StylelintVSCodeOptions} serverOptions - * @returns {Promise} - */ -module.exports = async function stylelintVSCode(textDocument, options = {}, serverOptions = {}) { - /** @type {stylelint.LinterOptions} */ - const priorOptions = { - code: textDocument.getText(), - formatter: () => '', - }; - const { fsPath } = URI.parse(textDocument.uri); - - // Workaround for Stylelint treating paths as case-sensitive on Windows - // If the drive letter is lowercase, we need to convert it to uppercase - // See https://github.com/stylelint/stylelint/issues/5594 - // TODO: Remove once fixed upstream - const codeFilename = - os.platform() === 'win32' ? fsPath.replace(/^[a-z]:/, (match) => match.toUpperCase()) : fsPath; - let resultContainer; - - if (codeFilename) { - priorOptions.codeFilename = codeFilename; - } else if (!options?.config?.rules) { - priorOptions.config = { rules: {} }; - } - - const stylelint = await resolveStylelint({ ...serverOptions, textDocument }); - - if (!stylelint) { - return { - diagnostics: [], - }; - } - - try { - resultContainer = await stylelint.lint({ ...options, ...priorOptions }); - } catch (err) { - if (!(err instanceof Error)) { - throw err; - } - - if ( - err.message.startsWith('No configuration provided for') || - err.message.includes('No rules found within configuration') - ) { - // Check only CSS syntax errors without applying any stylelint rules - return processResults( - await stylelint.lint({ - ...options, - ...priorOptions, - config: { - rules: {}, - }, - }), - createRuleDocUrlProvider(stylelint), - ); - } - - throw err; - } - - return processResults(resultContainer, createRuleDocUrlProvider(stylelint)); -}; - -/** @type {GlobalPathResolver | undefined} */ -let globalPathResolver; - -/** - * @param {StylelintVSCodeOptions & {textDocument: lsp.TextDocument} } options - * @returns {Promise} - */ -async function resolveStylelint({ - connection, - packageManager, - stylelintPath: customStylelintPath, - textDocument, -}) { - /** @type {TracerFn} */ - function trace(message, verbose) { - connection && connection.tracer.log(message, verbose); - } - - if (customStylelintPath) { - let stylelint; - - const errorMessage = `stylelint: cannot resolve "stylelintPath": ${customStylelintPath}`; - const consoleErrorMessage = `Failed to load stylelint from ${customStylelintPath}.`; - - try { - stylelint = require(customStylelintPath); - } catch (err) { - connection?.console.error(consoleErrorMessage); - connection?.window.showErrorMessage(errorMessage); - throw err; - } - - if (stylelint && typeof stylelint.lint === 'function') { - return stylelint; - } - - connection?.console.error(consoleErrorMessage); - connection?.window.showErrorMessage(errorMessage); - } - - let stylelint; - - try { - if (!globalPathResolver) { - globalPathResolver = getGlobalPathResolver(); - } - - /** @type {string | undefined} */ - const resolvedGlobalPackageManagerPath = packageManager - ? await globalPathResolver.resolve(packageManager, trace) - : undefined; - const uri = URI.parse(textDocument.uri); - - let cwd; - - if (uri.scheme === 'file') { - const file = uri.fsPath; - const directory = path.dirname(file); - - cwd = directory; - } else { - const workspaceFolder = await getWorkspaceFolder(textDocument, connection); - - cwd = workspaceFolder; - } - - const stylelintPath = await Files.resolve( - 'stylelint', - resolvedGlobalPackageManagerPath, - cwd, - trace, - ); - - stylelint = require(stylelintPath); - } catch { - // ignore - } - - if (!stylelint) { - connection?.console.error( - 'Failed to load stylelint either globally or from the current workspace.', - ); - - return undefined; - } - - if (typeof stylelint.lint !== 'function') { - const errorMessage = 'stylelint.lint is not a function.'; - - connection?.console.error(errorMessage); - connection?.window.showErrorMessage(errorMessage); - - return undefined; - } - - return stylelint; -} - -/** - * @param {stylelint.PublicApi} stylelint - * @returns {RuleDocUrlProvider} - */ -function createRuleDocUrlProvider(stylelint) { - return (rule) => { - if (stylelint.rules && stylelint.rules[rule]) { - return `https://stylelint.io/user-guide/rules/${rule}`; - } - - return null; - }; -} - -/** - * @param {lsp.TextDocument} document - * @param {lsp.Connection} [connection] - * @returns {Promise} - */ -async function getWorkspaceFolder(document, connection) { - const documentPath = URI.parse(document.uri).fsPath; - - if (documentPath) { - const workspaceFolders = connection && (await connection.workspace.getWorkspaceFolders()); - - if (workspaceFolders) { - for (const { uri } of workspaceFolders) { - const workspacePath = URI.parse(uri).fsPath; - - if (pathIsInside(documentPath, workspacePath)) { - return workspacePath; - } - } - } - } - - return undefined; -} diff --git a/src/stylelint-vscode.md b/src/stylelint-vscode.md deleted file mode 100644 index 84b9c1a2..00000000 --- a/src/stylelint-vscode.md +++ /dev/null @@ -1,135 +0,0 @@ -# stylelint-vscode - -> 🚧 Inlined dependency taken from [https://github.com/shinnn/stylelint-vscode](https://github.com/shinnn/stylelint-vscode). - ---- - -A [stylelint](https://github.com/stylelint/stylelint) wrapper to easily integrate with [Visual Studio Code](https://code.visualstudio.com/) [language server](https://github.com/Microsoft/vscode-languageserver-node) - -```javascript -const stylelintVSCode = require("stylelint-vscode"); -const { TextDocument } = require("vscode-languageserver-types"); - -(async () => { - await stylelintVSCode( - TextDocument.create( - "file:///Users/me/0.css", - "css", - 1, - ` -p { - line-height: .8; - color: red; -}` - ), - { - code, - config: { - rules: { - "number-leading-zero": "always", - "color-named": ["never", { severity: "warning" }] - } - } - } - ); /* => [{ - range: { - start: {line: 2, character: 14}, - end: {line: 2, character: 14} - }, - message: 'Expected a leading zero (number-leading-zero)', - severity: 1, - code: 'number-leading-zero', - source: 'stylelint' - }, { - range: { - start: {line: 3, character: 9}, - end: {line: 3, character: 9} - }, - message: 'Unexpected named color "red" (color-no-named)', - severity: 2, - code: 'color-no-named', - source: 'stylelint' - }] */ -})(); -``` - -## Installation - -[Use](https://docs.npmjs.com/cli/install) [npm](https://docs.npmjs.com/getting-started/what-is-npm). - -``` -npm install stylelint-vscode -``` - -## API - -```javascript -const stylelintVSCode = require("stylelint-vscode"); -``` - -### stylelintVSCode(_textDocument_ [, *options*]) - -_textDocument_: [`TextDocument`](https://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocument) -_options_: `Object` (directly passed to [`stylelint.lint`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#the-stylelint-nodejs-api)) -Return: `Promise>` - -It works like [`stylelint.lint()`](https://github.com/stylelint/stylelint/blob/10.0.1/lib/index.js#L31), except for: - -- [`code`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#code) and [`codeFilename`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#codefilename) option values are derived from a `TextDocument` passed to the first argument. -- It will be resolved with an `Array` of [VS Code `Diagnostic`](https://github.com/Microsoft/vscode-languageserver-node/blob/release/types/3.14/types/src/main.ts#L508-L546) instances. -- It will be _rejected_ (not resolved) when it takes invalid configs. - - In this case, it joins config errors into a single error object. -- It suppresses `No configuration found` error. - - Doing nothing when there is no configuration is a common behavior of editor plugins. -- [`files`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#files) and [`formatter`](https://github.com/stylelint/stylelint/blob/master/docs/user-guide/node-api.md#formatter) options are not supported. - -```javascript -const stylelintVSCode = require("stylelint-vscode"); - -async () => { - await stylelintVSCode( - TextDocument.create("file:///Users/me/1.css", "css", 1, "{foo}") - ); /*=> [{ - range: { - start: {line: 0, character: 1}, - end: {line: 0, character: 1} - }, - message: 'Unknown word (CssSyntaxError)', - severity: 1, - code: 'CssSyntaxError', - source: 'stylelint' - }] */ -}; -``` - -```javascript -(async () => { - try { - await stylelintVSCode( - TextDocument.create("file:///Users/me/2.css", "css", 1, "a {}"), - { - config: { - rules: { - indentation: 2, - "function-comma-space-before": "foo" - } - } - } - ); - } catch (err) { - err.name; - //=> 'SyntaxError' - - err.message; - //=> 'Expected option value for rule "indentation"\nInvalid option value "foo" for rule "function-comma-space-before"' - - err.reasons; - /* => - [ - 'Expected option value for rule "indentation"', - 'Invalid option value "foo" for rule "function-comma-space-before"' - ] - */ - } -})(); -``` diff --git a/src/utils/__tests__/objects.js b/src/utils/__tests__/objects.js new file mode 100644 index 00000000..e665e953 --- /dev/null +++ b/src/utils/__tests__/objects.js @@ -0,0 +1,77 @@ +'use strict'; + +const { deepAssign } = require('../objects'); + +describe('deepAssign', () => { + test('should return an object', () => { + expect(deepAssign({}, {})).toBeInstanceOf(Object); + }); + + test('for two objects, should return their union', () => { + const obj1 = { a: 1, b: { c: 2, d: { e: 3 } } }; + const obj2 = { a: undefined, b: { c: 3, d: { f: 4 } }, g: 5 }; + + expect(deepAssign(obj1, obj2)).toStrictEqual({ + a: undefined, + b: { + c: 3, + d: { + e: 3, + f: 4, + }, + }, + g: 5, + }); + }); + + test('for three objects, should return their union', () => { + const obj1 = { a: 1, b: { c: 2, d: { e: 3 } } }; + const obj2 = { a: undefined, b: { c: 3, d: { f: 4 } }, g: 5 }; + const obj3 = { b: { d: { g: 6 } }, h: 7 }; + + expect(deepAssign(obj1, obj2, obj3)).toStrictEqual({ + a: undefined, + b: { + c: 3, + d: { + e: 3, + f: 4, + g: 6, + }, + }, + g: 5, + h: 7, + }); + }); + + test('should ignore undefined parameters', () => { + expect(deepAssign({ a: 1 }, undefined, undefined)).toStrictEqual({ a: 1 }); + }); + + test('should overwrite arrays', () => { + const obj1 = { a: 1, b: [1, 2, 3] }; + const obj2 = { a: 2, b: [4, 5, 6] }; + + expect(deepAssign(obj1, obj2)).toStrictEqual({ a: 2, b: [4, 5, 6] }); + }); + + test('should combine objects with dissimilar properties', () => { + const obj1 = { a: 1, b: { c: 2, d: { e: 3 } } }; + const obj2 = { a: 2, b: { e: 3, f: { g: [4] } }, h: 5 }; + + expect(deepAssign(obj1, obj2)).toStrictEqual({ + a: 2, + b: { + c: 2, + d: { + e: 3, + }, + e: 3, + f: { + g: [4], + }, + }, + h: 5, + }); + }); +}); diff --git a/src/utils/__tests__/processes.js b/src/utils/__tests__/processes.js index 438c01d8..bf14a8fd 100644 --- a/src/utils/__tests__/processes.js +++ b/src/utils/__tests__/processes.js @@ -2,22 +2,15 @@ jest.mock('child_process'); -describe('runProcessFindLine', () => { - /** @type {typeof import('../processes').runProcessFindLine} */ - let runProcessFindLine; - - /** @type {tests.mocks.ChildProcessModule} */ - let mockedChildProcess; +const mockedChildProcess = /** @type {tests.mocks.ChildProcessModule} */ (require('child_process')); +const { runProcessFindLine } = require('../processes'); +describe('runProcessFindLine', () => { beforeAll(() => { - mockedChildProcess = /** @type {tests.mocks.ChildProcessModule} */ (require('child_process')); - mockedChildProcess.__mockProcess('foo', ['bar'], 0, 'from\nstdout'); mockedChildProcess.__mockProcess('foo', ['baz'], 0, 'multi\nline\noutput\n'); mockedChildProcess.__mockProcess('foo', ['qux'], 1, undefined, 'from\nstderr'); mockedChildProcess.__mockProcess('foo', ['quz'], 'SIGHUP', undefined, 'from\nstderr'); - - runProcessFindLine = require('../processes').runProcessFindLine; }); it('should run the process and return the line when it is found', async () => { diff --git a/src/utils/__tests__/sets.js b/src/utils/__tests__/sets.js new file mode 100644 index 00000000..6fa05463 --- /dev/null +++ b/src/utils/__tests__/sets.js @@ -0,0 +1,20 @@ +'use strict'; + +const { intersect } = require('../sets'); + +describe('intersect', () => { + test('should intersect two sets', () => { + expect(intersect(new Set([1, 2, 3]), new Set([2, 3, 4]))).toEqual(new Set([2, 3])); + expect(intersect(new Set([1, 2]), new Set([2, 3, 4]))).toEqual(new Set([2])); + expect(intersect(new Set([1, 2, 3]), new Set([2, 3]))).toEqual(new Set([2, 3])); + }); + + test('if one set is undefined, should return the other', () => { + expect(intersect(new Set([1, 2, 3]), undefined)).toEqual(new Set([1, 2, 3])); + expect(intersect(undefined, new Set([1, 2, 3]))).toEqual(new Set([1, 2, 3])); + }); + + test('if both sets are undefined, should return undefined', () => { + expect(intersect(undefined, undefined)).toBeUndefined(); + }); +}); diff --git a/src/utils/__tests__/strings.js b/src/utils/__tests__/strings.js new file mode 100644 index 00000000..7e67a164 --- /dev/null +++ b/src/utils/__tests__/strings.js @@ -0,0 +1,37 @@ +'use strict'; + +const { padNumber, padString, upperCaseFirstChar } = require('../strings'); + +describe('padNumber', () => { + test('should pad a number with leading zeros', () => { + expect(padNumber(1, 3)).toBe('001'); + expect(padNumber(10, 3)).toBe('010'); + expect(padNumber(100, 3)).toBe('100'); + }); + + test('should throw an error if the length is 0 or less', () => { + expect(() => padNumber(1, 0)).toThrow(); + expect(() => padNumber(1, -1)).toThrow(); + }); +}); + +describe('padString', () => { + test('should pad a string with spaces', () => { + expect(padString('foo', 3)).toBe('foo'); + expect(padString('foo', 5)).toBe('foo '); + }); + + test('should throw an error if the length is 0 or less', () => { + expect(() => padString('foo', 0)).toThrow(); + expect(() => padString('foo', -1)).toThrow(); + }); +}); + +describe('upperCaseFirstChar', () => { + test('should uppercase the first character of a string', () => { + expect(upperCaseFirstChar('foo')).toBe('Foo'); + expect(upperCaseFirstChar('Foo')).toBe('Foo'); + expect(upperCaseFirstChar('foo bar')).toBe('Foo bar'); + expect(upperCaseFirstChar('Foo Bar')).toBe('Foo Bar'); + }); +}); diff --git a/src/utils/__tests__/types.js b/src/utils/__tests__/types.js new file mode 100644 index 00000000..1a4b9565 --- /dev/null +++ b/src/utils/__tests__/types.js @@ -0,0 +1,23 @@ +'use strict'; + +const { InvalidOptionError } = require('../types'); + +describe('InvalidOptionError', () => { + test('should be an instance of Error', () => { + const error = new InvalidOptionError([{ text: 'foo' }]); + + expect(error).toBeInstanceOf(Error); + }); + + test('should have a message listing the invalid options', () => { + const error = new InvalidOptionError([{ text: 'foo' }, { text: 'bar' }]); + + expect(error.message).toBe('foo\nbar'); + }); + + test('should keep the reasons on the error', () => { + const error = new InvalidOptionError([{ text: 'foo' }, { text: 'bar' }]); + + expect(error.reasons).toEqual(['foo', 'bar']); + }); +}); diff --git a/src/utils/documents/__tests__/__snapshots__/create-text-edits.js.snap b/src/utils/documents/__tests__/__snapshots__/create-text-edits.js.snap new file mode 100644 index 00000000..bced1fcd --- /dev/null +++ b/src/utils/documents/__tests__/__snapshots__/create-text-edits.js.snap @@ -0,0 +1,160 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`createTextEdits should create text edits for deletions 1`] = ` +Array [ + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 4, + "line": 3, + }, + "start": Object { + "character": 4, + "line": 2, + }, + }, + }, +] +`; + +exports[`createTextEdits should create text edits for insertions 1`] = ` +Array [ + Object { + "newText": " font-size: 12px; + ", + "range": Object { + "end": Object { + "character": 3, + "line": 3, + }, + "start": Object { + "character": 3, + "line": 3, + }, + }, + }, +] +`; + +exports[`createTextEdits should create text edits for insertions and deletions 1`] = ` +Array [ + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 17, + "line": 2, + }, + "start": Object { + "character": 16, + "line": 2, + }, + }, + }, + Object { + "newText": "4", + "range": Object { + "end": Object { + "character": 17, + "line": 2, + }, + "start": Object { + "character": 17, + "line": 2, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 21, + "line": 3, + }, + "start": Object { + "character": 19, + "line": 2, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 20, + "line": 8, + }, + "start": Object { + "character": 17, + "line": 8, + }, + }, + }, + Object { + "newText": "e2e2e2", + "range": Object { + "end": Object { + "character": 20, + "line": 8, + }, + "start": Object { + "character": 20, + "line": 8, + }, + }, + }, + Object { + "newText": "'", + "range": Object { + "end": Object { + "character": 25, + "line": 8, + }, + "start": Object { + "character": 25, + "line": 8, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 29, + "line": 8, + }, + "start": Object { + "character": 26, + "line": 8, + }, + }, + }, + Object { + "newText": "bar", + "range": Object { + "end": Object { + "character": 29, + "line": 8, + }, + "start": Object { + "character": 29, + "line": 8, + }, + }, + }, + Object { + "newText": "'", + "range": Object { + "end": Object { + "character": 33, + "line": 8, + }, + "start": Object { + "character": 33, + "line": 8, + }, + }, + }, +] +`; diff --git a/src/utils/documents/__tests__/__snapshots__/get-fixes.js.snap b/src/utils/documents/__tests__/__snapshots__/get-fixes.js.snap new file mode 100644 index 00000000..00e1a894 --- /dev/null +++ b/src/utils/documents/__tests__/__snapshots__/get-fixes.js.snap @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getFixes should return edits if Stylelint made changes 1`] = ` +Array [ + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 4, + "line": 2, + }, + "start": Object { + "character": 3, + "line": 2, + }, + }, + }, + Object { + "newText": " ", + "range": Object { + "end": Object { + "character": 4, + "line": 2, + }, + "start": Object { + "character": 4, + "line": 2, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 3, + "line": 8, + }, + "start": Object { + "character": 3, + "line": 5, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 4, + "line": 9, + }, + "start": Object { + "character": 3, + "line": 9, + }, + }, + }, + Object { + "newText": " ", + "range": Object { + "end": Object { + "character": 4, + "line": 9, + }, + "start": Object { + "character": 4, + "line": 9, + }, + }, + }, + Object { + "newText": "", + "range": Object { + "end": Object { + "character": 4, + "line": 10, + }, + "start": Object { + "character": 3, + "line": 10, + }, + }, + }, + Object { + "newText": " ", + "range": Object { + "end": Object { + "character": 4, + "line": 10, + }, + "start": Object { + "character": 4, + "line": 10, + }, + }, + }, +] +`; diff --git a/src/utils/documents/__tests__/create-text-edits.js b/src/utils/documents/__tests__/create-text-edits.js new file mode 100644 index 00000000..e70e7666 --- /dev/null +++ b/src/utils/documents/__tests__/create-text-edits.js @@ -0,0 +1,101 @@ +'use strict'; + +const { TextDocument } = require('vscode-languageserver-textdocument'); + +const { createTextEdits } = require('../create-text-edits'); + +/** @param {string} text */ +const createTextDocument = (text) => { + return TextDocument.create('file:///test.css', 'css', 1, text); +}; + +describe('createTextEdits', () => { + test('should create text edits for insertions', () => { + const textDocument = createTextDocument(` + .foo { + color: red; + } + `); + const edits = createTextEdits( + textDocument, + ` + .foo { + color: red; + font-size: 12px; + } + `, + ); + + expect(edits).toMatchSnapshot(); + }); + + test('should create text edits for deletions', () => { + const textDocument = createTextDocument(` + table.foo { + width: 100%; + height: 100%; + } + `); + const edits = createTextEdits( + textDocument, + ` + table.foo { + height: 100%; + } + `, + ); + + expect(edits).toMatchSnapshot(); + }); + + test('should not create text edits without changes', () => { + const textDocument = createTextDocument(` + @media (min-width: 768px) { + .foo { + color: red; + } + } + `); + const edits = createTextEdits( + textDocument, + ` + @media (min-width: 768px) { + .foo { + color: red; + } + } + `, + ); + + expect(edits).toEqual([]); + }); + + test('should create text edits for insertions and deletions', () => { + const textDocument = createTextDocument(` + a { + font-size: 12px; + font-weight: bold; + } + + .foo { + overflow: hidden; + background: #fff url(/foo.png) no-repeat; + } + `); + const edits = createTextEdits( + textDocument, + ` + a { + font-size: 14px; + } + + .foo { + overflow: hidden; + background: #e2e2e2 url('/bar.png') no-repeat; + } + `, + ); + + expect(edits).toMatchSnapshot(); + }); +}); diff --git a/src/utils/documents/__tests__/get-disable-type.js b/src/utils/documents/__tests__/get-disable-type.js new file mode 100644 index 00000000..b1646c0b --- /dev/null +++ b/src/utils/documents/__tests__/get-disable-type.js @@ -0,0 +1,50 @@ +'use strict'; + +const { getDisableType } = require('../get-disable-type'); +const { TextDocument } = require('vscode-languageserver-textdocument'); +const { Position } = require('vscode-languageserver-types'); + +/** + * @param {string} code + * @returns {lsp.TextDocument} + */ +const createTextDocument = (code) => + TextDocument.create('file:///path/to/file.css', 'css', 1, code); + +describe('getDisableType', () => { + test("if the position is after a disable comment's type, should return its type", () => { + const code = '\n/* stylelint-disable indentation */\na {}'; + const position = Position.create(1, 21); + + const document = createTextDocument(code); + + expect(getDisableType(document, position)).toBe('stylelint-disable'); + }); + + test("if the position is before the end of a disable comment's type, should return undefined", () => { + const code = '\n/* stylelint-disable indentation */\na {}'; + const position = Position.create(1, 20); + + const document = createTextDocument(code); + + expect(getDisableType(document, position)).toBeUndefined(); + }); + + test('if the position is not inside a disable comment, should return undefined', () => { + const code = '\na {}'; + const position = Position.create(1, 1); + + const document = createTextDocument(code); + + expect(getDisableType(document, position)).toBeUndefined(); + }); + + test('if the position is inside a disable comment with a broken end, should return undefined', () => { + const code = '\n/* stylelint-disable indentation \na {}'; + const position = Position.create(1, 21); + + const document = createTextDocument(code); + + expect(getDisableType(document, position)).toBeUndefined(); + }); +}); diff --git a/src/utils/documents/__tests__/get-fixes.js b/src/utils/documents/__tests__/get-fixes.js new file mode 100644 index 00000000..0a701e74 --- /dev/null +++ b/src/utils/documents/__tests__/get-fixes.js @@ -0,0 +1,134 @@ +'use strict'; + +const { TextDocument } = require('vscode-languageserver-textdocument'); + +const { getFixes } = require('../get-fixes'); + +/** + * @param {string} [output] + * @returns {StylelintRunner} + */ +const createMockRunner = (output) => + /** @type {any} */ ({ + lintDocument: jest.fn(async () => ({ diagnostics: [], output })), + }); + +/** + * @param {string} code + * @returns {lsp.TextDocument} + */ +const createDocument = (code) => TextDocument.create('file:///path/test.css', 'css', 1, code); + +describe('getFixes', () => { + test('should call lintDocument with given options and fix set to true', async () => { + const document = createDocument('a { color: red; }'); + const runner = createMockRunner('a { color: red; }'); + /** @type {stylelint.LinterOptions} */ + const linterOptions = { + config: { + customSyntax: 'postcss-scss', + }, + fix: false, + reportNeedlessDisables: true, + reportInvalidScopeDisables: false, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + packageManager: 'pnpm', + validate: ['css', 'less', 'sass', 'scss'], + }; + + await getFixes(runner, document, linterOptions, extensionOptions); + + expect(runner.lintDocument).toHaveBeenCalledWith( + document, + expect.objectContaining({ + ...linterOptions, + fix: true, + }), + extensionOptions, + ); + }); + + test('should return no edits if Stylelint returned no output', async () => { + const document = createDocument(` + a { + color: red; + } + + div#foo { + } + + .foo { + overflow: hidden; + background: #ccc url(foo.png) no-repeat; + } + `); + const runner = createMockRunner(); + const fixes = await getFixes(runner, document); + + expect(fixes).toEqual([]); + }); + + test('should return no edits if Stylelint made no changes', async () => { + const document = createDocument(` + a { + color: red; + } + + div#foo { + } + + .foo { + overflow: hidden; + background: #ccc url(foo.png) no-repeat; + } + `); + const runner = createMockRunner(` + a { + color: red; + } + + div#foo { + } + + .foo { + overflow: hidden; + background: #ccc url(foo.png) no-repeat; + } + `); + const fixes = await getFixes(runner, document); + + expect(fixes).toEqual([]); + }); + + test('should return edits if Stylelint made changes', async () => { + const document = createDocument(` + a { + color: red; + } + + div#bar { + } + + .foo { + overflow: hidden; + background: #ccc url(foo.png) no-repeat; + } + `); + const runner = createMockRunner(` + a { + color: red; + } + + .foo { + overflow: hidden; + background: #ccc url(foo.png) no-repeat; + } + `); + const fixes = await getFixes(runner, document); + + expect(fixes).toMatchSnapshot(); + }); +}); diff --git a/src/utils/documents/__tests__/get-workspace-folder.js b/src/utils/documents/__tests__/get-workspace-folder.js new file mode 100644 index 00000000..90772a56 --- /dev/null +++ b/src/utils/documents/__tests__/get-workspace-folder.js @@ -0,0 +1,86 @@ +'use strict'; + +jest.mock('path'); + +const mockPath = /** @type {tests.mocks.PathModule} */ (require('path')); + +mockPath.__mockPlatform('posix'); + +jest.mock('vscode-uri', () => ({ + URI: { + parse: jest.fn((/** @type {string} */ str) => ({ + fsPath: str, + scheme: str.startsWith('untitled') ? 'untitled' : 'file', + })), + }, +})); + +const { getWorkspaceFolder } = require('../get-workspace-folder'); + +/** + * @param {string[] | null} [workspaceFolders] + * @returns {lsp.Connection} + */ +const createMockConnection = (workspaceFolders) => { + const folders = workspaceFolders && workspaceFolders.map((folder) => ({ uri: folder })); + + return /** @type {any} */ ({ + workspace: { + getWorkspaceFolders: async () => folders, + }, + }); +}; + +/** + * @param {string} uri + * @returns {lsp.TextDocument} + */ +const createMockTextDocument = (uri) => /** @type {any} */ ({ uri }); + +describe('getWorkspaceFolder', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test("when one is applicable, should return a document's workspace folder", async () => { + const connection = createMockConnection(['/home/user/directory', '/home/user/project']); + const document = createMockTextDocument('/home/user/project/file.js'); + + expect(await getWorkspaceFolder(connection, document)).toBe('/home/user/project'); + }); + + test('when no workspace folder is applicable, should return undefined', async () => { + const connection = createMockConnection(['/home/user/directory']); + const document = createMockTextDocument('/home/user/file.js'); + + expect(await getWorkspaceFolder(connection, document)).toBeUndefined(); + }); + + test('when no workspace folders are returned by the connection, should return undefined', async () => { + const connection = createMockConnection(); + const document = createMockTextDocument('/home/user/file.js'); + + expect(await getWorkspaceFolder(connection, document)).toBeUndefined(); + }); + + test('when the document has no FS path, should return undefined', async () => { + const connection = createMockConnection(['/home/user/project']); + const document = createMockTextDocument(''); + + expect(await getWorkspaceFolder(connection, document)).toBeUndefined(); + }); + + test('when given an untitled document and a workspace is open, should return the first workspace folder', async () => { + const connection = createMockConnection(['/home/user/directory', '/home/user/project']); + const document = createMockTextDocument('untitled:Untitled-1'); + + expect(await getWorkspaceFolder(connection, document)).toBe('/home/user/directory'); + }); + + test('when given an untitled document and no workspace is open, should return undefined', async () => { + const connection = createMockConnection(); + const document = createMockTextDocument('untitled:Untitled-1'); + + expect(await getWorkspaceFolder(connection, document)).toBeUndefined(); + }); +}); diff --git a/src/utils/documents/create-text-edits.js b/src/utils/documents/create-text-edits.js new file mode 100644 index 00000000..cd23f152 --- /dev/null +++ b/src/utils/documents/create-text-edits.js @@ -0,0 +1,43 @@ +'use strict'; + +const diff = require('fast-diff'); +const { Range, TextEdit } = require('vscode-languageserver-types'); + +/** + * Creates text edits for a document given updated contents. Allows for + * retaining the cursor position when the document is updated. + * @param {lsp.TextDocument} document The document to create text edits for. + * @param {string} newContents The new contents of the document. + * @returns {lsp.TextEdit[]} The text edits to apply to the document. + */ +function createTextEdits(document, newContents) { + const diffs = diff(document.getText(), newContents); + + const edits = []; + let offset = 0; + + for (const [op, text] of diffs) { + const start = offset; + + switch (op) { + case diff.EQUAL: + offset += text.length; + break; + case diff.DELETE: + offset += text.length; + edits.push( + TextEdit.del(Range.create(document.positionAt(start), document.positionAt(offset))), + ); + break; + case diff.INSERT: + edits.push(TextEdit.insert(document.positionAt(start), text)); + break; + } + } + + return edits; +} + +module.exports = { + createTextEdits, +}; diff --git a/src/utils/documents/get-disable-type.js b/src/utils/documents/get-disable-type.js new file mode 100644 index 00000000..2c559f8a --- /dev/null +++ b/src/utils/documents/get-disable-type.js @@ -0,0 +1,47 @@ +'use strict'; + +const { Position } = require('vscode-languageserver-types'); + +/** + * If the given position is inside a `stylelint-disable` after the comment' + * type, returns the disable comment's type. Otherwise, returns `undefined`. + * + * @example + * ```js + * const document = TextDocument.create( + * 'file:///path/to/file.css', + * 'css', + * 1, + * '/* stylelint-disable-line indentation *\/' + * // ^ Position is here + * ); + * const position = Position.create(0, 26); + * + * getDisableType(document, position); + * // => 'stylelint-disable-line' + * ``` + * + * @param {lsp.TextDocument} document + * @param {lsp.Position} position + * @returns {DisableType | undefined} + */ +function getDisableType(document, position) { + const lineStartOffset = document.offsetAt(Position.create(position.line, 0)); + const lineEndOffset = document.offsetAt(Position.create(position.line + 1, 0)); + const line = document.getText().slice(lineStartOffset, lineEndOffset); + + const before = line.slice(0, position.character); + const after = line.slice(position.character); + + const disableKind = before + .match(/\/\*\s*(stylelint-disable(?:(?:-next)?-line)?)\s[a-z\-/\s,]*$/i)?.[1] + ?.toLowerCase(); + + return disableKind && /^[a-z\-/\s,]*\*\//i.test(after) + ? /** @type {DisableType} */ (disableKind) + : undefined; +} + +module.exports = { + getDisableType, +}; diff --git a/src/utils/documents/get-fixes.js b/src/utils/documents/get-fixes.js new file mode 100644 index 00000000..b9c0e313 --- /dev/null +++ b/src/utils/documents/get-fixes.js @@ -0,0 +1,25 @@ +'use strict'; + +const { createTextEdits } = require('./create-text-edits'); + +/** + * Runs Stylelint and returns fix text edits for the given document. + * @param {StylelintRunner} runner The Stylelint runner. + * @param {lsp.TextDocument} document The document to get fixes for. + * @param {stylelint.LinterOptions} [linterOptions] Linter options to use. + * @param {ExtensionOptions} [extensionOptions] The extension options. + * @returns {Promise} + */ +async function getFixes(runner, document, linterOptions = {}, extensionOptions = {}) { + const result = await runner.lintDocument( + document, + { ...linterOptions, fix: true }, + extensionOptions, + ); + + return typeof result.output === 'string' ? createTextEdits(document, result.output) : []; +} + +module.exports = { + getFixes, +}; diff --git a/src/utils/documents/get-workspace-folder.js b/src/utils/documents/get-workspace-folder.js new file mode 100644 index 00000000..92a2e28f --- /dev/null +++ b/src/utils/documents/get-workspace-folder.js @@ -0,0 +1,42 @@ +'use strict'; + +const pathIsInside = require('path-is-inside'); +const { URI } = require('vscode-uri'); + +/** + * Gets the workspace folder for a given document. If the document is an + * untitled file, then the first open workspace folder is returned. + * @param {lsp.Connection} connection The language server connection to use to + * get available workspace folders. + * @param {lsp.TextDocument} document The document to get the workspace folder for. + * @returns {Promise} + */ +async function getWorkspaceFolder(connection, document) { + const { scheme, fsPath } = URI.parse(document.uri); + + if (scheme === 'untitled') { + const uri = (await connection.workspace.getWorkspaceFolders())?.[0]?.uri; + + return uri ? URI.parse(uri).fsPath : undefined; + } + + if (fsPath) { + const workspaceFolders = await connection.workspace.getWorkspaceFolders(); + + if (workspaceFolders) { + for (const { uri } of workspaceFolders) { + const workspacePath = URI.parse(uri).fsPath; + + if (pathIsInside(fsPath, workspacePath)) { + return workspacePath; + } + } + } + } + + return undefined; +} + +module.exports = { + getWorkspaceFolder, +}; diff --git a/src/utils/documents/index.js b/src/utils/documents/index.js new file mode 100644 index 00000000..dff876cd --- /dev/null +++ b/src/utils/documents/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + ...require('./create-text-edits'), + ...require('./get-disable-type'), + ...require('./get-fixes'), + ...require('./get-workspace-folder'), +}; diff --git a/src/utils/functions/__tests__/get-first-return-value.js b/src/utils/functions/__tests__/get-first-return-value.js new file mode 100644 index 00000000..40050397 --- /dev/null +++ b/src/utils/functions/__tests__/get-first-return-value.js @@ -0,0 +1,111 @@ +'use strict'; + +const { getFirstReturnValue, getFirstResolvedValue } = require('../get-first-return-value'); + +describe('getFirstReturnValue', () => { + test("should return the first return value that isn't undefined", () => { + expect( + getFirstReturnValue( + () => 1, + () => 2, + () => 3, + ), + ).toBe(1); + expect( + getFirstReturnValue( + () => 1, + () => undefined, + () => 3, + ), + ).toBe(1); + expect( + getFirstReturnValue( + () => undefined, + () => 2, + () => 3, + ), + ).toBe(2); + expect( + getFirstReturnValue( + () => undefined, + () => undefined, + () => 3, + ), + ).toBe(3); + expect( + getFirstReturnValue( + () => undefined, + () => undefined, + () => undefined, + ), + ).toBeUndefined(); + expect( + getFirstReturnValue( + () => undefined, + () => null, + () => undefined, + ), + ).toBeNull(); + }); + + test('should not call any subsequent functions after the first return value is found', () => { + const fn = jest.fn(() => 1); + + getFirstReturnValue(fn, fn, fn); + expect(fn).toHaveBeenCalledTimes(1); + }); +}); + +describe('getFirstResolvedValue', () => { + test("should resolve to the first resolved value that isn't undefined", async () => { + await expect( + getFirstResolvedValue( + async () => 1, + async () => 2, + async () => 3, + ), + ).resolves.toBe(1); + await expect( + getFirstResolvedValue( + async () => 1, + async () => undefined, + async () => 3, + ), + ).resolves.toBe(1); + await expect( + getFirstResolvedValue( + async () => undefined, + async () => 2, + async () => 3, + ), + ).resolves.toBe(2); + await expect( + getFirstResolvedValue( + async () => undefined, + async () => undefined, + async () => 3, + ), + ).resolves.toBe(3); + await expect( + getFirstResolvedValue( + async () => undefined, + async () => undefined, + async () => undefined, + ), + ).resolves.toBeUndefined(); + await expect( + getFirstResolvedValue( + async () => undefined, + async () => null, + async () => undefined, + ), + ).resolves.toBeNull(); + }); + + test('should not call any subsequent functions after the first resolved value is found', async () => { + const fn = jest.fn(async () => 1); + + await getFirstResolvedValue(fn, fn, fn); + expect(fn).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/utils/functions/__tests__/lazy-call.js b/src/utils/functions/__tests__/lazy-call.js new file mode 100644 index 00000000..605ad34c --- /dev/null +++ b/src/utils/functions/__tests__/lazy-call.js @@ -0,0 +1,67 @@ +'use strict'; + +const { lazyCall, lazyCallAsync } = require('../lazy-call'); + +describe('lazyCall', () => { + test('should return a function', () => { + expect(typeof lazyCall(() => undefined)).toBe('function'); + }); + + test('should return a function that calls the given function', () => { + const fn = jest.fn(); + const lazyFn = lazyCall(fn); + + lazyFn(); + + expect(fn).toHaveBeenCalled(); + }); + + test('should return a function that returns the result of the given function', () => { + const fn = jest.fn(() => 'foo'); + const lazyFn = lazyCall(fn); + + expect(lazyFn()).toBe('foo'); + }); + + test('should only call the given function once', () => { + const fn = jest.fn(() => 'foo'); + const lazyFn = lazyCall(fn); + + lazyFn(); + lazyFn(); + + expect(fn).toHaveBeenCalledTimes(1); + }); +}); + +describe('lazyCallAsync', () => { + test('should return a function', () => { + expect(typeof lazyCallAsync(async () => undefined)).toBe('function'); + }); + + test('should return a function that calls the given function', async () => { + const fn = jest.fn(); + const lazyFn = lazyCallAsync(fn); + + await lazyFn(); + + expect(fn).toHaveBeenCalled(); + }); + + test('should return a function that resolves to the result of the given function', async () => { + const fn = jest.fn(async () => 'foo'); + const lazyFn = lazyCallAsync(fn); + + expect(await lazyFn()).toBe('foo'); + }); + + test('should only call the given function once', async () => { + const fn = jest.fn(async () => 'foo'); + const lazyFn = lazyCallAsync(fn); + + await lazyFn(); + await lazyFn(); + + expect(fn).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/utils/functions/get-first-return-value.js b/src/utils/functions/get-first-return-value.js new file mode 100644 index 00000000..488f03ba --- /dev/null +++ b/src/utils/functions/get-first-return-value.js @@ -0,0 +1,45 @@ +'use strict'; + +/** + * Runs each function, passing the result of the first function return + * a value that is not `undefined`. Any subsequent functions are not run. + * @template {unknown | undefined} V + * @param {(() => V)[]} functions + * @returns {V | undefined} + */ +function getFirstReturnValue(...functions) { + for (const func of functions) { + const result = func(); + + if (result !== undefined) { + return result; + } + } + + return undefined; +} + +/** + * Runs each async function, passing the resolved value of the first function + * that resolves to a value that is not `undefined`. Any subsequent functions + * are not run. + * @template {unknown | undefined} V + * @param {(() => Promise)[]} functions + * @returns {Promise} + */ +async function getFirstResolvedValue(...functions) { + for (const func of functions) { + const result = await func(); + + if (result !== undefined) { + return result; + } + } + + return undefined; +} + +module.exports = { + getFirstReturnValue, + getFirstResolvedValue, +}; diff --git a/src/utils/functions/index.js b/src/utils/functions/index.js new file mode 100644 index 00000000..b6134ed6 --- /dev/null +++ b/src/utils/functions/index.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = { + ...require('./get-first-return-value'), + ...require('./lazy-call'), +}; diff --git a/src/utils/functions/lazy-call.js b/src/utils/functions/lazy-call.js new file mode 100644 index 00000000..2948dc52 --- /dev/null +++ b/src/utils/functions/lazy-call.js @@ -0,0 +1,54 @@ +'use strict'; + +/** + * Creates a lazy-call function. The inner function will be called only the + * first time the outer function is called. The inner function's return value + * will be cached for the lifetime of the outer function. + * @template {() => any} T + * @param {T} inner + * @returns {() => ReturnType} + */ +function lazyCall(inner) { + let cached = false; + + /** @type {ReturnType} */ + let cache; + + return () => { + if (!cached) { + cache = inner(); + cached = true; + } + + return cache; + }; +} + +/** + * Creates an async lazy-call function. The inner function will be called only + * the first time the outer function is called. The inner function's resolved + * value will be cached for the lifetime of the outer function. + * @template {() => Promise} T + * @param {T} inner + * @returns {() => Promise extends PromiseLike ? U : T>} + */ +function lazyCallAsync(inner) { + let cached = false; + + /** @type {ReturnType extends PromiseLike ? U : T} */ + let cache; + + return async () => { + if (!cached) { + cache = await inner(); + cached = true; + } + + return cache; + }; +} + +module.exports = { + lazyCall, + lazyCallAsync, +}; diff --git a/src/utils/logging/__tests__/get-log-function.js b/src/utils/logging/__tests__/get-log-function.js new file mode 100644 index 00000000..31398cd8 --- /dev/null +++ b/src/utils/logging/__tests__/get-log-function.js @@ -0,0 +1,23 @@ +'use strict'; + +const { getLogFunction } = require('../get-log-function'); + +/** @type {lsp.RemoteConsole} */ +const mockRemoteConsole = { + connection: /** @type {any} */ ({}), + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + log: jest.fn(), +}; + +describe('getLogFunction', () => { + it('should return a function when given a supported level', () => { + expect(getLogFunction(mockRemoteConsole, 'info')).toBe(mockRemoteConsole.info); + }); + + it("should return undefined if the level doesn't have a matching function", () => { + expect(getLogFunction(mockRemoteConsole, 'foo')).toBeUndefined(); + expect(getLogFunction(mockRemoteConsole, 'connection')).toBeUndefined(); + }); +}); diff --git a/src/utils/logging/__tests__/language-server-formatter.js b/src/utils/logging/__tests__/language-server-formatter.js new file mode 100644 index 00000000..573b7dab --- /dev/null +++ b/src/utils/logging/__tests__/language-server-formatter.js @@ -0,0 +1,146 @@ +'use strict'; + +const { LEVEL, MESSAGE } = require('triple-beam'); + +const { LanguageServerFormatter } = require('../language-server-formatter'); + +const mockConnection = /** @type {lsp.Connection} */ ( + /** @type {any} */ ({ + console: { + connection: /** @type {any} */ ({}), + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + log: jest.fn(), + }, + }) +); + +/** + * @param {string} message + * @param {string} level + * @param {{[key: string | symbol]: any}} [data] + * @returns {winston.Logform.TransformableInfo} + */ +const createMockInfo = (message, level, data = {}) => { + return /** @type {any} */ ({ + [MESSAGE]: message, + [LEVEL]: level, + message, + level, + ...data, + }); +}; + +describe('languageServerFormatter', () => { + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + test('should accept options', () => { + /** @type {LanguageServerFormatterOptions} */ + const options = { + connection: mockConnection, + preferredKeyOrder: ['uri', 'module'], + }; + + const format = new LanguageServerFormatter(options); + + expect(format.options?.connection).toBe(mockConnection); + expect(format.options?.preferredKeyOrder).toEqual(options.preferredKeyOrder); + }); + + test('should format a log message without data or a component tag', () => { + const info = createMockInfo('test message', 'info'); + const format = new LanguageServerFormatter({ + connection: mockConnection, + }); + + expect(format.transform(info)).toStrictEqual({ + [MESSAGE]: 'test message', + [LEVEL]: 'info', + message: 'test message', + level: 'info', + }); + }); + + test('should format a log message with data but no component tag', () => { + const info = createMockInfo('test message', 'warn', { + foo: 'bar', + }); + const format = new LanguageServerFormatter({ + connection: mockConnection, + }); + + expect(format.transform(info)).toStrictEqual({ + [MESSAGE]: 'test message | foo: "bar"', + [LEVEL]: 'warn', + message: 'test message | foo: "bar"', + level: 'warn', + }); + }); + + test('should format a log message with data and a component tag', () => { + const info = createMockInfo('test message', 'error', { + component: 'foo', + foo: 'bar', + }); + const format = new LanguageServerFormatter({ + connection: mockConnection, + }); + + expect(format.transform(info)).toStrictEqual({ + [MESSAGE]: '[foo] test message | foo: "bar"', + [LEVEL]: 'error', + message: '[foo] test message | foo: "bar"', + level: 'error', + }); + }); + + test('should order keys in given preferred order', () => { + const info = createMockInfo('test message', 'error', { + component: 'foo', + foo: 'bar', + module: 'baz', + }); + const format = new LanguageServerFormatter({ + connection: mockConnection, + preferredKeyOrder: ['module', 'foo', 'bar'], + }); + + expect(format.transform(info)).toStrictEqual({ + [MESSAGE]: '[foo] test message | module: "baz" foo: "bar"', + [LEVEL]: 'error', + message: '[foo] test message | module: "baz" foo: "bar"', + level: 'error', + }); + }); + + test('should prepend a timestamp and level if using a level not implemented by the remote console', () => { + const format = new LanguageServerFormatter({ + connection: mockConnection, + }); + + jest.setSystemTime(new Date(2021, 9, 16, 12, 15, 52)); + + expect(format.transform(createMockInfo('test message', 'debug'))).toStrictEqual({ + [MESSAGE]: '[Debug - 12:15:52 p.m.] test message', + [LEVEL]: 'debug', + message: '[Debug - 12:15:52 p.m.] test message', + level: 'debug', + }); + + jest.setSystemTime(new Date(2022, 4, 1, 9, 13, 12)); + + expect(format.transform(createMockInfo('test message', 'debug'))).toStrictEqual({ + [MESSAGE]: '[Debug - 9:13:12 a.m.] test message', + [LEVEL]: 'debug', + message: '[Debug - 9:13:12 a.m.] test message', + level: 'debug', + }); + }); +}); diff --git a/src/utils/logging/__tests__/language-server-transport.js b/src/utils/logging/__tests__/language-server-transport.js new file mode 100644 index 00000000..cf704e66 --- /dev/null +++ b/src/utils/logging/__tests__/language-server-transport.js @@ -0,0 +1,103 @@ +'use strict'; + +const { LEVEL, MESSAGE } = require('triple-beam'); + +const { LanguageServerTransport } = require('../language-server-transport'); + +// Test winston transport + +const mockConnection = /** @type {lsp.Connection} */ ( + /** @type {any} */ ({ + console: { + connection: /** @type {any} */ ({}), + error: jest.fn(), + warn: jest.fn(), + info: jest.fn(), + log: jest.fn(), + }, + }) +); + +/** + * @param {string} message + * @param {string} level + * @returns {winston.Logform.TransformableInfo} + */ +const createMockInfo = (message, level) => { + return /** @type {any} */ ({ + [MESSAGE]: message, + [LEVEL]: level, + }); +}; + +describe('LanguageServerTransport', () => { + /** @type {LanguageServerTransport} */ + let transport; + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(() => { + jest.clearAllMocks(); + transport = new LanguageServerTransport({ connection: mockConnection }); + }); + + test('should call the callback after logging', () => { + const info = createMockInfo('test', 'info'); + const callback = jest.fn(); + + transport.log(info, callback); + + expect(callback).toHaveBeenCalledTimes(1); + }); + + test('should emit a "logged" event after logging', () => { + const info = createMockInfo('test', 'info'); + const callback = jest.fn(); + + transport.on('logged', callback); + + transport.log(info, () => {}); + + jest.runAllTimers(); + + expect(callback).toHaveBeenCalledTimes(1); + }); + + test("should use the remote console's error method for error-level logs", () => { + const info = createMockInfo('test', 'error'); + + transport.log(info, () => undefined); + + expect(mockConnection.console.error).toHaveBeenCalledWith('test'); + }); + + test("should use the remote console's warn method for warn-level logs", () => { + const info = createMockInfo('test', 'warn'); + + transport.log(info, () => undefined); + + expect(mockConnection.console.warn).toHaveBeenCalledWith('test'); + }); + + test("should use the remote console's info method for info-level logs", () => { + const info = createMockInfo('test', 'info'); + + transport.log(info, () => undefined); + + expect(mockConnection.console.info).toHaveBeenCalledWith('test'); + }); + + test("should use the remote console's log method for logs with a level unimplemented by the console", () => { + const info = createMockInfo('test', 'debug'); + + transport.log(info, () => undefined); + + expect(mockConnection.console.log).toHaveBeenCalledWith('test'); + }); +}); diff --git a/src/utils/logging/get-log-function.js b/src/utils/logging/get-log-function.js new file mode 100644 index 00000000..c347e788 --- /dev/null +++ b/src/utils/logging/get-log-function.js @@ -0,0 +1,20 @@ +'use strict'; + +/** + * @param {lsp.RemoteConsole} remoteConsole + * @param {string} level + * @returns {lsp.RemoteConsole[ExtractKeysOfValueType] | undefined} + */ +const getLogFunction = (remoteConsole, level) => { + const logFunction = remoteConsole[/** @type {keyof lsp.RemoteConsole} */ (level)]; + + if (typeof logFunction === 'function') { + return logFunction; + } + + return undefined; +}; + +module.exports = { + getLogFunction, +}; diff --git a/src/utils/logging/index.js b/src/utils/logging/index.js new file mode 100644 index 00000000..528c6336 --- /dev/null +++ b/src/utils/logging/index.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = { + ...require('./get-log-function'), + ...require('./language-server-formatter'), + ...require('./language-server-transport'), +}; diff --git a/src/utils/logging/language-server-formatter.js b/src/utils/logging/language-server-formatter.js new file mode 100644 index 00000000..579c587a --- /dev/null +++ b/src/utils/logging/language-server-formatter.js @@ -0,0 +1,86 @@ +'use strict'; + +const { LEVEL, MESSAGE } = require('triple-beam'); + +const { getLogFunction } = require('./get-log-function'); +const { padString, padNumber, upperCaseFirstChar } = require('../strings'); + +/** + * Language server formatter for winston. + * @type {LanguageServerFormatterConstructor} + */ +class LanguageServerFormatter { + /** + * @param {LanguageServerFormatterOptions} options + */ + constructor(options) { + this.options = options; + } + + /** + * @param {winston.Logform.TransformableInfo & {[key: string | symbol]: any}} info + * @returns {winston.Logform.TransformableInfo} + */ + transform(info) { + const date = new Date(); + + // h:mm:ss a.m./p.m. + const timestamp = `${date.getHours() % 12 || 12}:${padNumber(date.getMinutes(), 2)}:${padNumber( + date.getSeconds(), + 2, + )} ${date.getHours() < 12 ? 'a.m.' : 'p.m.'}`; + + const messageParts = []; + + if (!getLogFunction(this.options.connection.console, info[LEVEL])) { + messageParts.push(`[${padString(upperCaseFirstChar(info[LEVEL]), 5)} - ${timestamp}]`); + } + + if (info.component) { + messageParts.push(`[${info.component}]`); + } + + messageParts.push(info.message); + + delete info.component; + delete info.timestamp; + + const keys = new Set(Object.keys({ ...info })); + const postMessageParts = []; + + if (this.options.preferredKeyOrder) { + for (const key of this.options.preferredKeyOrder) { + if (keys.has(key)) { + postMessageParts.push(`${key}: ${JSON.stringify(info[key])}`); + + keys.delete(key); + delete info[key]; + } + } + } + + for (const key of keys) { + if (key === 'level' || key === 'message') { + continue; + } + + postMessageParts.push(`${key}: ${JSON.stringify(info[key])}`); + + delete info[key]; + } + + const message = + postMessageParts.length > 0 + ? `${messageParts.join(' ')} | ${postMessageParts.join(' ')}` + : messageParts.join(' '); + + info[MESSAGE] = message; + info.message = message; + + return info; + } +} + +module.exports = { + LanguageServerFormatter, +}; diff --git a/src/utils/logging/language-server-transport.js b/src/utils/logging/language-server-transport.js new file mode 100644 index 00000000..e97418f7 --- /dev/null +++ b/src/utils/logging/language-server-transport.js @@ -0,0 +1,50 @@ +'use strict'; + +const TransportStream = require('winston-transport'); +const { LEVEL, MESSAGE } = require('triple-beam'); + +const { getLogFunction } = require('./get-log-function'); + +/** + * Winston transport for logging through the language server connection. + */ +class LanguageServerTransport extends TransportStream { + /** + * The language server remote console. + * @type {lsp.RemoteConsole} + */ + #console; + + /** + * @param {LanguageServerTransportOptions} options + */ + constructor(options) { + super(options); + + this.#console = options.connection.console; + } + + /** + * @param {winston.Logform.TransformableInfo & {[key: string | symbol]: any}} info + * @param {() => void} callback + */ + log(info, callback) { + setImmediate(() => { + this.emit('logged', info); + }); + + const logFunc = getLogFunction(this.#console, info[LEVEL]); + + if (typeof logFunc === 'function') { + logFunc.call(this.#console, String(info[MESSAGE])); + } else { + this.#console.log(String(info[MESSAGE])); + } + + callback(); + } +} + +module.exports = { + LanguageServerTransport, +}; diff --git a/src/utils/lsp/__tests__/__snapshots__/create-disable-completion-item.js.snap b/src/utils/lsp/__tests__/__snapshots__/create-disable-completion-item.js.snap new file mode 100644 index 00000000..5850167b --- /dev/null +++ b/src/utils/lsp/__tests__/__snapshots__/create-disable-completion-item.js.snap @@ -0,0 +1,101 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`createDisableCompletionItem should create a stylelint-disable completion item 1`] = ` +Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable rule */ +/* stylelint-enable rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:rule} */ +/* stylelint-enable \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", +} +`; + +exports[`createDisableCompletionItem should create a stylelint-disable completion item for a specific rule 1`] = ` +Object { + "detail": "Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable indentation */ +/* stylelint-enable indentation */ +\`\`\`", + }, + "insertText": "/* stylelint-disable \${0:indentation} */ +/* stylelint-enable \${0:indentation} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable", +} +`; + +exports[`createDisableCompletionItem should create a stylelint-disable-line completion item 1`] = ` +Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", +} +`; + +exports[`createDisableCompletionItem should create a stylelint-disable-line completion item for a specific rule 1`] = ` +Object { + "detail": "Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-line indentation */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-line \${0:indentation} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-line", +} +`; + +exports[`createDisableCompletionItem should create a stylelint-disable-next-line completion item 1`] = ` +Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line rule */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:rule} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", +} +`; + +exports[`createDisableCompletionItem should create a stylelint-disablenext--line completion item for a specific rule 1`] = ` +Object { + "detail": "Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)", + "documentation": Object { + "kind": "markdown", + "value": "\`\`\`css +/* stylelint-disable-next-line indentation */ +\`\`\`", + }, + "insertText": "/* stylelint-disable-next-line \${0:indentation} */", + "insertTextFormat": 2, + "kind": 15, + "label": "stylelint-disable-next-line", +} +`; diff --git a/src/utils/lsp/__tests__/create-disable-completion-item.js b/src/utils/lsp/__tests__/create-disable-completion-item.js new file mode 100644 index 00000000..74c76571 --- /dev/null +++ b/src/utils/lsp/__tests__/create-disable-completion-item.js @@ -0,0 +1,41 @@ +'use strict'; + +const { createDisableCompletionItem } = require('../create-disable-completion-item'); + +describe('createDisableCompletionItem', () => { + test('should create a stylelint-disable completion item', () => { + const result = createDisableCompletionItem('stylelint-disable'); + + expect(result).toMatchSnapshot(); + }); + + test('should create a stylelint-disable completion item for a specific rule', () => { + const result = createDisableCompletionItem('stylelint-disable', 'indentation'); + + expect(result).toMatchSnapshot(); + }); + + test('should create a stylelint-disable-line completion item', () => { + const result = createDisableCompletionItem('stylelint-disable-line'); + + expect(result).toMatchSnapshot(); + }); + + test('should create a stylelint-disable-line completion item for a specific rule', () => { + const result = createDisableCompletionItem('stylelint-disable-line', 'indentation'); + + expect(result).toMatchSnapshot(); + }); + + test('should create a stylelint-disable-next-line completion item', () => { + const result = createDisableCompletionItem('stylelint-disable-next-line'); + + expect(result).toMatchSnapshot(); + }); + + test('should create a stylelint-disablenext--line completion item for a specific rule', () => { + const result = createDisableCompletionItem('stylelint-disable-next-line', 'indentation'); + + expect(result).toMatchSnapshot(); + }); +}); diff --git a/src/utils/lsp/__tests__/display-error.js b/src/utils/lsp/__tests__/display-error.js new file mode 100644 index 00000000..0e3332aa --- /dev/null +++ b/src/utils/lsp/__tests__/display-error.js @@ -0,0 +1,70 @@ +'use strict'; + +const { InvalidOptionError } = require('../../types'); + +const { displayError } = require('../display-error'); + +const mockConnection = /** @type {lsp.Connection} */ ( + /** @type {any} */ ({ window: { showErrorMessage: jest.fn() } }) +); + +describe('displayError', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('for non-Error types, should display the value coalesced to a string', () => { + displayError(mockConnection, Symbol('foo')); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledWith('Symbol(foo)'); + }); + + test('for strings, should display the value with newlines replaced with spaces', () => { + displayError(mockConnection, 'test\nmessage'); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledWith('test message'); + }); + + test('for invalid option errors, should display an error message for each reason', () => { + displayError( + mockConnection, + new InvalidOptionError([{ text: 'reason 1' }, { text: 'reason 2' }]), + ); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(2); + expect(mockConnection.window.showErrorMessage).toHaveBeenNthCalledWith( + 1, + 'stylelint: reason 1', + ); + expect(mockConnection.window.showErrorMessage).toHaveBeenNthCalledWith( + 2, + 'stylelint: reason 2', + ); + }); + + test("for configuration errors, should display the error's message property", () => { + displayError(mockConnection, Object.assign(new Error('test message'), { code: 78 })); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledWith('stylelint: test message'); + }); + + test('for errors, should display the stack with newlines replaced with spaces', () => { + displayError( + mockConnection, + Object.assign(new Error('test message'), { stack: 'test\nstack' }), + ); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledWith('test stack'); + }); + + test('for errors without a stack, should display the message with newlines replaced with spaces', () => { + displayError(mockConnection, Object.assign(new Error('test\nmessage'), { stack: undefined })); + + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(mockConnection.window.showErrorMessage).toHaveBeenCalledWith('test message'); + }); +}); diff --git a/src/utils/lsp/create-disable-completion-item.js b/src/utils/lsp/create-disable-completion-item.js new file mode 100644 index 00000000..4be6a3d7 --- /dev/null +++ b/src/utils/lsp/create-disable-completion-item.js @@ -0,0 +1,52 @@ +'use strict'; + +const { + CompletionItem, + CompletionItemKind, + InsertTextFormat, + MarkupKind, +} = require('vscode-languageserver-types'); + +/** + * Creates a disable completion item for the given disable type. Uses the given rule if one is + * provided, otherwise uses a placeholder. + * @param {DisableType} disableType + * @param {string} [rule] + * @returns {CompletionItem} + */ +function createDisableCompletionItem(disableType, rule = '') { + const item = CompletionItem.create(disableType); + + item.kind = CompletionItemKind.Snippet; + item.insertTextFormat = InsertTextFormat.Snippet; + + if (disableType === 'stylelint-disable') { + item.insertText = `/* stylelint-disable \${0:${rule || 'rule'}} */\n/* stylelint-enable \${0:${ + rule || 'rule' + }} */`; + item.detail = + 'Turn off all Stylelint or individual rules, after which you do not need to re-enable stylelint. (stylelint)'; + item.documentation = { + kind: MarkupKind.Markdown, + value: `\`\`\`css\n/* stylelint-disable ${rule || 'rule'} */\n/* stylelint-enable ${ + rule || 'rule' + } */\n\`\`\``, + }; + } else { + item.insertText = `/* ${disableType} \${0:${rule || 'rule'}} */`; + item.detail = + disableType === 'stylelint-disable-line' + ? 'Turn off Stylelint rules for individual lines only, after which you do not need to explicitly re-enable them. (stylelint)' + : 'Turn off Stylelint rules for the next line only, after which you do not need to explicitly re-enable them. (stylelint)'; + item.documentation = { + kind: MarkupKind.Markdown, + value: `\`\`\`css\n/* ${disableType} ${rule || 'rule'} */\n\`\`\``, + }; + } + + return item; +} + +module.exports = { + createDisableCompletionItem, +}; diff --git a/src/utils/lsp/display-error.js b/src/utils/lsp/display-error.js new file mode 100644 index 00000000..c64dafb9 --- /dev/null +++ b/src/utils/lsp/display-error.js @@ -0,0 +1,36 @@ +'use strict'; + +/** + * Takes an error and displays it in the UI using the given connection. + * @param {lsp.Connection} connection The language server connection. + * @param {unknown} err + * @returns {void} + */ +function displayError(connection, err) { + if (!(err instanceof Error)) { + connection.window.showErrorMessage(String(err).replace(/\n/gu, ' ')); + + return; + } + + if (/** @type {InvalidOptionError} */ (err)?.reasons) { + for (const reason of /** @type {InvalidOptionError} */ (err)?.reasons) { + connection.window.showErrorMessage(`stylelint: ${reason}`); + } + + return; + } + + // https://github.com/stylelint/stylelint/blob/551dcb5/lib/utils/configurationError.js#L12 + if (/** @type {ConfigurationError} */ (err)?.code === 78) { + connection.window.showErrorMessage(`stylelint: ${err.message}`); + + return; + } + + connection.window.showErrorMessage((err.stack || err.message).replace(/\n/gu, ' ')); +} + +module.exports = { + displayError, +}; diff --git a/src/utils/lsp/index.js b/src/utils/lsp/index.js new file mode 100644 index 00000000..dd7b9a6a --- /dev/null +++ b/src/utils/lsp/index.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = { + ...require('./create-disable-completion-item'), + ...require('./display-error'), +}; diff --git a/src/utils/objects.js b/src/utils/objects.js new file mode 100644 index 00000000..868f40ab --- /dev/null +++ b/src/utils/objects.js @@ -0,0 +1,47 @@ +'use strict'; + +// ES 2020 syntax + +/** + * Copies all enumerable properties from one or two source objects to a target + * object, recursing for nested objects. + * @template T + * @template U + * @template V + * @param {T} target The target object to assign to. + * @param {U} source1 The first source object from which to copy properties. + * @param {V} [source2] The second source object from which to copy properties. + * @returns {T & U & V} + */ +function deepAssign(target, source1, source2) { + for (const object of [source1, source2]) { + if (!object) { + continue; + } + + for (const key of /** @type {(keyof typeof object)[]} */ (Object.keys(object))) { + const value = object[key]; + + if (typeof value === 'object' && value) { + if (!(/** @type {T & U & V} */ (target)[key])) { + /** @type {T & U & V} */ (target)[key] = /** @type {any} */ ( + Array.isArray(value) ? [] : {} + ); + } + + /** @type {T & U & V} */ (target)[key] = deepAssign( + /** @type {T & U & V} */ (target)[key], + value, + ); + } else { + /** @type {T & U & V} */ (target)[key] = /** @type {any} */ (value); + } + } + } + + return /** @type {T & U & V} */ (target); +} + +module.exports = { + deepAssign, +}; diff --git a/src/utils/packages/__mocks__/global-path-resolver.js b/src/utils/packages/__mocks__/global-path-resolver.js new file mode 100644 index 00000000..9894f12f --- /dev/null +++ b/src/utils/packages/__mocks__/global-path-resolver.js @@ -0,0 +1,31 @@ +'use strict'; + +const resolver = jest.createMockFromModule('../global-path-resolver'); + +/** @type {Partial<{[packageManager in PackageManager]: string | undefined}>} */ +let mockedPaths = {}; + +/** + * Mocks the global path for the given package manager. + * @param {PackageManager} packageManager + * @param {string} [globalPath] + */ +resolver.__mockPath = (packageManager, globalPath) => { + mockedPaths[packageManager] = globalPath; +}; + +/** + * Resets all mocked paths. + */ +resolver.__resetMockedResolutions = () => { + mockedPaths = {}; +}; + +resolver.getGlobalPathResolver = jest.fn(() => ({ + /** @param {PackageManager} packageManager */ + async resolve(packageManager) { + return mockedPaths[packageManager]; + }, +})); + +module.exports = resolver; diff --git a/src/utils/packages/__tests__/__snapshots__/stylelint-resolver.js.snap b/src/utils/packages/__tests__/__snapshots__/stylelint-resolver.js.snap new file mode 100644 index 00000000..6c42de33 --- /dev/null +++ b/src/utils/packages/__tests__/__snapshots__/stylelint-resolver.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`StylelintResolver should throw on invalid custom Stylelint paths 1`] = `"Cannot find module 'cwd/does-not-exist' from 'src/utils/packages/stylelint-resolver.js'"`; + +exports[`StylelintResolver should work without a connection 1`] = `"Cannot find module './does-not-exist' from 'src/utils/packages/stylelint-resolver.js'"`; diff --git a/src/utils/packages/__tests__/find-package-root.js b/src/utils/packages/__tests__/find-package-root.js index f38233bb..76a6a46b 100644 --- a/src/utils/packages/__tests__/find-package-root.js +++ b/src/utils/packages/__tests__/find-package-root.js @@ -3,19 +3,10 @@ jest.mock('fs/promises'); const { createError } = require('../../../../test/mockSystemErrors'); +const mockedFS = /** @type {tests.mocks.FSPromisesModule} */ (require('fs/promises')); +const findPackageRoot = require('../find-package-root').findPackageRoot; describe('findPackageRoot', () => { - /** @type {tests.mocks.FSPromisesModule} */ - let mockedFS; - - /** @type {typeof import('../find-package-root').findPackageRoot} */ - let findPackageRoot; - - beforeAll(() => { - mockedFS = /** @type {tests.mocks.FSPromisesModule} */ (require('fs/promises')); - findPackageRoot = require('../find-package-root').findPackageRoot; - }); - it('should resolve the package directory when package.json is present', async () => { mockedFS.__mockFileSystem({ foo: { diff --git a/src/utils/packages/__tests__/global-path-resolver.js b/src/utils/packages/__tests__/global-path-resolver.js index 031da60a..2b467bae 100644 --- a/src/utils/packages/__tests__/global-path-resolver.js +++ b/src/utils/packages/__tests__/global-path-resolver.js @@ -4,31 +4,24 @@ jest.mock('path'); jest.mock('os'); jest.mock('../../processes'); -/** @typedef {typeof import('../global-path-resolver').getGlobalPathResolver} getGlobalPathResolver */ +const mockedOS = /** @type {tests.mocks.OSModule} */ (require('os')); +const mockedPath = /** @type {tests.mocks.PathModule} */ (require('path')); +const mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); +const { getGlobalPathResolver } = require('../global-path-resolver'); /** * @param {'posix' | 'win32'} platform */ const mockPlatform = (platform) => { - const mockedOS = /** @type {tests.mocks.OSModule} */ (require('os')); - mockedOS.__mockPlatform(platform === 'win32' ? 'win32' : 'linux'); - - const mockedPath = /** @type {tests.mocks.PathModule} */ (require('path')); - mockedPath.__mockPlatform(platform); }; describe('Global Package Manager Path Resolver', () => { describe('Non-Windows', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - beforeAll(() => { mockPlatform('posix'); - const mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); mockedProcesses.__mockProcess( @@ -44,8 +37,6 @@ describe('Global Package Manager Path Resolver', () => { ); mockedProcesses.__mockProcess('pnpm', ['root', '-g'], ['/path/to/pnpm/global/dir']); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); it('should resolve the yarn global package directory', async () => { @@ -71,14 +62,9 @@ describe('Global Package Manager Path Resolver', () => { }); describe('Windows', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - beforeAll(() => { mockPlatform('win32'); - const mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); mockedProcesses.__mockProcess( @@ -94,8 +80,6 @@ describe('Global Package Manager Path Resolver', () => { ); mockedProcesses.__mockProcess('pnpm', ['root', '-g'], ['C:\\path\\to\\pnpm\\global\\dir']); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); it('should resolve the yarn global package directory', async () => { @@ -121,17 +105,9 @@ describe('Global Package Manager Path Resolver', () => { }); describe('Caching', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - - /** @type {tests.mocks.Processes} */ - let mockedProcesses; - beforeAll(() => { mockPlatform('posix'); - mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); mockedProcesses.__mockProcess( @@ -147,8 +123,6 @@ describe('Global Package Manager Path Resolver', () => { ); mockedProcesses.__mockProcess('pnpm', ['root', '-g'], ['/path/to/pnpm/global/dir']); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); beforeEach(() => { @@ -185,17 +159,10 @@ describe('Global Package Manager Path Resolver', () => { describe('Error handling', () => { describe('Missing commands', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - beforeAll(() => { mockPlatform('posix'); - const mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); it('should throw an error if yarn cannot be found', async () => { @@ -218,24 +185,14 @@ describe('Global Package Manager Path Resolver', () => { }); describe('Bad output', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - - /** @type {tests.mocks.Processes} */ - let mockedProcesses; - beforeAll(() => { mockPlatform('posix'); - mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); mockedProcesses.__mockProcess('npm', ['config', 'get', 'prefix'], ['']); mockedProcesses.__mockProcess('pnpm', ['root', '-g'], ['']); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); it('should resolve to undefined for yarn', async () => { @@ -271,20 +228,9 @@ describe('Global Package Manager Path Resolver', () => { }); describe('Non-zero exit codes', () => { - /** @type {getGlobalPathResolver} */ - let getGlobalPathResolver; - beforeAll(() => { - const mockedOS = /** @type {tests.mocks.OSModule} */ (require('os')); - mockedOS.__mockPlatform('linux'); - - const mockedPath = /** @type {tests.mocks.PathModule} */ (require('path')); - mockedPath.__mockPlatform('posix'); - - const mockedProcesses = /** @type {tests.mocks.Processes} */ (require('../../processes')); - mockedProcesses.__resetMockedProcesses(); mockedProcesses.__mockProcess( @@ -302,8 +248,6 @@ describe('Global Package Manager Path Resolver', () => { ); mockedProcesses.__mockProcess('pnpm', ['root', '-g'], ['/path/to/pnpm/global/dir'], 1); - - getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; }); it('should throw an error if yarn returns a non-zero exit code', async () => { @@ -327,8 +271,6 @@ describe('Global Package Manager Path Resolver', () => { describe('Unsupported package managers', () => { it('should resolve to undefined when passed an unsupported package manager name', async () => { - const getGlobalPathResolver = require('../global-path-resolver').getGlobalPathResolver; - const globalPath = await getGlobalPathResolver().resolve( /** @type {any} */ ('unsupported'), ); diff --git a/src/utils/packages/__tests__/stylelint-resolver.js b/src/utils/packages/__tests__/stylelint-resolver.js new file mode 100644 index 00000000..65ed80a2 --- /dev/null +++ b/src/utils/packages/__tests__/stylelint-resolver.js @@ -0,0 +1,304 @@ +'use strict'; + +jest.mock('vscode-languageserver/node'); +jest.mock('../global-path-resolver'); +jest.mock('path'); + +const path = /** @type {tests.mocks.PathModule} */ (require('path')); + +/** @type {string | undefined} */ +let mockCWD = path.join('/fake', 'cwd'); + +jest.mock('../../documents', () => ({ + getWorkspaceFolder: jest.fn(async () => mockCWD), +})); + +const { StylelintResolver } = require('../stylelint-resolver'); + +/** @returns {lsp.Connection} */ +const createMockConnection = () => + /** @type {any} */ ({ + console: { error: jest.fn() }, + window: { showErrorMessage: jest.fn() }, + tracer: { log: jest.fn() }, + }); + +/** @returns {winston.Logger} */ +const createMockLogger = () => + /** @type {any} */ ({ + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }); + +/** @returns {lsp.TextDocument} */ +const createMockTextDocument = (nonFileURI = false) => + /** @type {any} */ ({ + uri: nonFileURI ? 'scheme:///fake/cwd/document.css' : 'file:///fake/cwd/document.css', + }); + +const goodStylelintPath = path.join(__dirname, 'stylelint.js'); +const badStylelintPath = path.join(__dirname, 'bad-stylelint.js'); + +/** @type {{[packageManager in PackageManager]: string}} */ +const mockGlobalPaths = { + yarn: path.join('/fake', 'yarn'), + npm: path.join('/fake', 'npm'), + pnpm: path.join('/fake', 'pnpm'), +}; + +jest.mock( + require('path').join(__dirname, 'stylelint.js'), + () => ({ lint: jest.fn(() => 'good') }), + { virtual: true }, +); +jest.mock(require('path').join(__dirname, 'bad-stylelint.js'), () => ({}), { virtual: true }); + +const { Files: mockedFiles } = /** @type {tests.mocks.VSCodeLanguageServerModule.Node} */ ( + require('vscode-languageserver/node') +); + +/** + * @param {PackageManager} packageManager + * @param {string} stylelintPath + */ +const mockGlobalFileResolution = (packageManager, stylelintPath) => { + mockedFiles.__mockResolution('stylelint', (globalPath, cwd, trace) => { + trace && trace('Resolving globally'); + + return cwd === mockCWD && globalPath === mockGlobalPaths[packageManager] + ? stylelintPath + : undefined; + }); +}; + +/** + * @param {string} stylelintPath + */ +const mockLocalFileResolution = (stylelintPath) => { + mockedFiles.__mockResolution('stylelint', (_, cwd, trace) => { + trace && trace('Resolving locally'); + + return cwd === mockCWD ? stylelintPath : undefined; + }); +}; + +const mockedGlobalPathResolver = /** @type {tests.mocks.GlobalPathResolver} */ ( + require('../global-path-resolver') +); + +mockedGlobalPathResolver.__mockPath('yarn', mockGlobalPaths.yarn); +mockedGlobalPathResolver.__mockPath('npm', mockGlobalPaths.npm); +mockedGlobalPathResolver.__mockPath('pnpm', mockGlobalPaths.pnpm); + +describe('StylelintResolver', () => { + beforeEach(() => { + jest.clearAllMocks(); + path.__mockPlatform(); + mockCWD = path.join('/fake', 'cwd'); + }); + + test('should resolve valid custom Stylelint paths', async () => { + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { stylelintPath: goodStylelintPath }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should resolve valid relative custom Stylelint paths with a workspace', async () => { + mockCWD = __dirname; + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { stylelintPath: './stylelint.js' }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should resolve valid relative custom Stylelint paths without a workspace', async () => { + mockCWD = undefined; + path.isAbsolute.mockReturnValueOnce(false); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { stylelintPath: goodStylelintPath }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should resolve to undefined for custom Stylelint paths pointing to modules without a lint function', async () => { + const connection = createMockConnection(); + const logger = createMockLogger(); + const stylelintResolver = new StylelintResolver(connection, logger); + const result = await stylelintResolver.resolve( + { stylelintPath: badStylelintPath }, + createMockTextDocument(), + ); + + expect(result).toBeUndefined(); + expect(logger.warn).toHaveBeenCalledTimes(1); + expect(logger.error).toHaveBeenCalledTimes(1); + expect(connection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should throw on invalid custom Stylelint paths', async () => { + const connection = createMockConnection(); + const logger = createMockLogger(); + const stylelintResolver = new StylelintResolver(connection, logger); + + mockCWD = path.join('.', 'cwd'); + path.__mockPlatform('posix'); + + await expect( + stylelintResolver.resolve({ stylelintPath: './does-not-exist' }, createMockTextDocument()), + ).rejects.toThrowErrorMatchingSnapshot(); + expect(logger.error).toHaveBeenCalledTimes(1); + expect(connection.window.showErrorMessage).toHaveBeenCalledTimes(1); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should resolve workspace Stylelint modules', async () => { + mockLocalFileResolution(goodStylelintPath); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve({}, createMockTextDocument()); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).toHaveBeenCalledTimes(1); + }); + + test('should resolve workspace Stylelint modules for documents with non-file URIs', async () => { + mockLocalFileResolution(goodStylelintPath); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve({}, createMockTextDocument(true)); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).toHaveBeenCalledTimes(1); + }); + + test('should resolve global Stylelint modules using yarn', async () => { + mockGlobalFileResolution('yarn', goodStylelintPath); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { packageManager: 'yarn' }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).toHaveBeenCalledTimes(1); + }); + + test('should resolve global Stylelint modules using npm', async () => { + mockGlobalFileResolution('npm', goodStylelintPath); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { packageManager: 'npm' }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).toHaveBeenCalledTimes(1); + }); + + test('should resolve global Stylelint modules using pnpm', async () => { + mockGlobalFileResolution('pnpm', goodStylelintPath); + + const connection = createMockConnection(); + const stylelintResolver = new StylelintResolver(connection); + const result = await stylelintResolver.resolve( + { packageManager: 'pnpm' }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + expect(connection.console.error).not.toHaveBeenCalled(); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).toHaveBeenCalledTimes(1); + }); + + test('should return undefined when no Stylelint module is found globally or in the workspace', async () => { + mockedFiles.__resetMockedResolutions(); + + const connection = createMockConnection(); + const logger = createMockLogger(); + const stylelintResolver = new StylelintResolver(connection, logger); + const result = await stylelintResolver.resolve({}, createMockTextDocument()); + + expect(result).toBeUndefined(); + expect(logger.warn).toHaveBeenCalledTimes(1); + expect(connection.window.showErrorMessage).not.toHaveBeenCalled(); + expect(connection.tracer.log).not.toHaveBeenCalled(); + }); + + test('should work without a connection', async () => { + mockGlobalFileResolution('npm', goodStylelintPath); + + let result = await new StylelintResolver().resolve( + { packageManager: 'npm' }, + createMockTextDocument(), + ); + + expect(result?.resolvedPath).toBe(goodStylelintPath); + expect(result?.stylelint?.lint({})).toBe('good'); + + mockGlobalFileResolution('npm', badStylelintPath); + + result = await new StylelintResolver().resolve( + { packageManager: 'npm' }, + createMockTextDocument(), + ); + + expect(result).toBeUndefined(); + + await expect( + new StylelintResolver().resolve( + { stylelintPath: './does-not-exist' }, + createMockTextDocument(), + ), + ).rejects.toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/utils/packages/index.js b/src/utils/packages/index.js index e25b7d09..b9b1d24b 100644 --- a/src/utils/packages/index.js +++ b/src/utils/packages/index.js @@ -1,6 +1,7 @@ 'use strict'; module.exports = { - ...require('./global-path-resolver'), ...require('./find-package-root'), + ...require('./global-path-resolver'), + ...require('./stylelint-resolver'), }; diff --git a/src/utils/packages/stylelint-resolver.js b/src/utils/packages/stylelint-resolver.js new file mode 100644 index 00000000..b212f59f --- /dev/null +++ b/src/utils/packages/stylelint-resolver.js @@ -0,0 +1,214 @@ +'use strict'; + +const path = require('path'); +const { Files } = require('vscode-languageserver/node'); +const { URI } = require('vscode-uri'); +const { getWorkspaceFolder } = require('../documents'); +const { getGlobalPathResolver } = require('./global-path-resolver'); +const { getFirstResolvedValue, lazyCallAsync } = require('../../utils/functions'); + +/** + * Utility for resolving the path to the Stylelint package. Each instance caches + * resolved paths to global `node_modules` directories. + */ +class StylelintResolver { + /** + * The language server connection. + * @type {lsp.Connection | undefined} + */ + #connection; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * The global path resolver. + * @type {GlobalPathResolver} + */ + #globalPathResolver; + + /** + * @param {lsp.Connection} [connection] The language server connection. + * @param {winston.Logger} [logger] The logger to use. + */ + constructor(connection, logger) { + this.#connection = connection; + this.#logger = logger; + this.#globalPathResolver = getGlobalPathResolver(); + } + + /** + * Logs an error message through the connection if one is available. + * @param {string} message The message to log. + * @returns {void} + */ + #logError(message) { + if (!this.#connection) { + return; + } + + this.#connection.window.showErrorMessage(`stylelint: ${message}`); + this.#logger?.error(message); + } + + /** + * If the given path is absolute, returns it. Otherwise, if a connection is + * available, returns the path resolved to the document's workspace folder. + * If no connection is available, returns the path as-is. + * @param {string} stylelintPath + * @param {() => Promise} getWorkspaceFolderFn + */ + async #getRequirePath(stylelintPath, getWorkspaceFolderFn) { + if (!this.#connection || path.isAbsolute(stylelintPath)) { + return stylelintPath; + } + + const workspaceFolder = await getWorkspaceFolderFn(); + + return workspaceFolder ? path.join(workspaceFolder, stylelintPath) : stylelintPath; + } + + /** + * Attempts to resolve the stylelint package from a path. If an error + * occurs, it will be logged through the connection and thrown. If the + * resolved module does not have a lint function, an error will be logged + * and `undefined` will be returned. + * @param {string | undefined} stylelintPath + * @param {() => Promise} getWorkspaceFolderFn + * @returns {Promise} + */ + async #resolveFromPath(stylelintPath, getWorkspaceFolderFn) { + if (!stylelintPath) { + return undefined; + } + + const errorMessage = `Failed to load stylelint from "stylelintPath": ${stylelintPath}.`; + + try { + const requirePath = await this.#getRequirePath(stylelintPath, getWorkspaceFolderFn); + + const stylelint = require(requirePath); + + if (stylelint && typeof stylelint.lint === 'function') { + return { + stylelint, + resolvedPath: requirePath, + }; + } + } catch (err) { + this.#logError(errorMessage); + + throw err; + } + + this.#logError(errorMessage); + + return undefined; + } + + /** + * Attempts to resolve the stylelint package from the given document's + * workspace folder or the global `node_modules` directory for the given + * package manager. Resolution will be traced through the connection. + * + * If a path cannot be resolved, `undefined` will be returned. If the + * resolved module does not have a lint function, an error will be logged + * and `undefined` will be returned. + * @private + * @param {lsp.TextDocument} textDocument + * @param {() => Promise} getWorkspaceFolderFn + * @param {PackageManager} [packageManager] + * @returns {Promise} + */ + async #resolveFromModules(textDocument, getWorkspaceFolderFn, packageManager) { + const connection = this.#connection; + + /** @type {TracerFn} */ + const trace = connection + ? (message, verbose) => { + this.#logger?.debug(message, { verbose }); + connection.tracer.log(message, verbose); + } + : () => undefined; + + try { + /** @type {string | undefined} */ + const globalModulesPath = packageManager + ? await this.#globalPathResolver.resolve(packageManager, trace) + : undefined; + + const documentURI = URI.parse(textDocument.uri); + + const cwd = + documentURI.scheme === 'file' + ? path.dirname(documentURI.fsPath) + : await getWorkspaceFolderFn(); + + const stylelintPath = await Files.resolve('stylelint', globalModulesPath, cwd, trace); + + const stylelint = require(stylelintPath); + + if (stylelint && typeof stylelint.lint !== 'function') { + this.#logError('stylelint.lint is not a function.'); + + return undefined; + } + + return { + stylelint, + resolvedPath: stylelintPath, + }; + } catch { + // ignore + } + + return undefined; + } + + /** + * Attempts to resolve the `stylelint` package from the following lcoations, + * in order: + * + * 1. `options.stylelintPath`, if provided. + * 2. `node_modules` in the workspace folder of the given document. + * 3. The global `node_modules` directory for the given package manager. + * + * If `options.stylelintPath` is provided, but the path to which it points + * cannot be required, an error will be thrown. In all other cases of failed + * resolution, `undefined` will be returned. Resolution fails if either the + * path to the `stylelint` package cannot be resolved or if the resolved + * module does not have a `lint` function. + * + * If a connection is available, errors will be logged through it and module + * resolution through `node_modules` will be traced through it. + * @param {ResolverOptions} options + * @param {lsp.TextDocument} textDocument + * @returns {Promise} + */ + async resolve({ packageManager, stylelintPath }, textDocument) { + const getWorkspaceFolderFn = lazyCallAsync( + async () => this.#connection && (await getWorkspaceFolder(this.#connection, textDocument)), + ); + + const stylelint = await getFirstResolvedValue( + async () => this.#resolveFromPath(stylelintPath, getWorkspaceFolderFn), + async () => + await this.#resolveFromModules(textDocument, getWorkspaceFolderFn, packageManager), + ); + + if (!stylelint) { + this.#logger?.warn('Failed to load stylelint either globally or from the current workspace.'); + + return undefined; + } + + return stylelint; + } +} + +module.exports = { + StylelintResolver, +}; diff --git a/src/utils/sets.js b/src/utils/sets.js new file mode 100644 index 00000000..e0ccbf42 --- /dev/null +++ b/src/utils/sets.js @@ -0,0 +1,36 @@ +'use strict'; + +/** + * Returns the intersection of the given sets. If one of the sets is + * `undefined`, the other set is returned. If both sets are `undefined`, + * returns `undefined`. + * @template T + * @param {Set | undefined} set1 + * @param {Set | undefined} set2 + * @returns {Set | undefined} + */ +function intersect(set1, set2) { + if (!set1) { + return set2; + } + + if (!set2) { + return set1; + } + + const [smallerSet, largerSet] = set1.size < set2.size ? [set1, set2] : [set2, set1]; + + const result = new Set(); + + for (const item of smallerSet) { + if (largerSet.has(item)) { + result.add(item); + } + } + + return result; +} + +module.exports = { + intersect, +}; diff --git a/src/utils/strings.js b/src/utils/strings.js new file mode 100644 index 00000000..9c4a4fbb --- /dev/null +++ b/src/utils/strings.js @@ -0,0 +1,35 @@ +'use strict'; + +/** + * @param {string} str + * @returns {string} + */ +const upperCaseFirstChar = (str) => { + return str.charAt(0).toUpperCase() + str.slice(1); +}; + +/** + * @param {string} str + * @param {number} length + * @returns {string} + */ +const padString = (str, length) => { + return str + ' '.repeat(length - str.length); +}; + +/** + * @param {number} number + * @param {number} length + * @returns {string} + */ +const padNumber = (number, length) => { + let str = String(number); + + return '0'.repeat(length - str.length) + str; +}; + +module.exports = { + upperCaseFirstChar, + padString, + padNumber, +}; diff --git a/src/utils/stylelint/__tests__/__snapshots__/process-linter-result.js.snap b/src/utils/stylelint/__tests__/__snapshots__/process-linter-result.js.snap new file mode 100644 index 00000000..ab36c6c5 --- /dev/null +++ b/src/utils/stylelint/__tests__/__snapshots__/process-linter-result.js.snap @@ -0,0 +1,94 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`processLinterResult should return diagnostics for each warning 1`] = ` +Object { + "diagnostics": Array [ + Object { + "code": "unit-no-unknown", + "codeDescription": Object { + "href": "https://stylelint.io/user-guide/rules/unit-no-unknown", + }, + "message": "unit-no-unknown", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + Object { + "code": "at-rule-no-unknown", + "codeDescription": Object { + "href": "https://stylelint.io/user-guide/rules/at-rule-no-unknown", + }, + "message": "at-rule-no-unknown", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + Object { + "code": "alpha-value-notation", + "message": "alpha-value-notation", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + ], +} +`; + +exports[`processLinterResult should return output if given 1`] = ` +Object { + "diagnostics": Array [ + Object { + "code": "unit-no-unknown", + "codeDescription": Object { + "href": "https://stylelint.io/user-guide/rules/unit-no-unknown", + }, + "message": "unit-no-unknown", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + ], + "output": "Output", +} +`; + +exports[`processLinterResult should throw if invalid option results are given 1`] = ` +"Warning 1 +Warning 2" +`; diff --git a/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.js.snap b/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.js.snap new file mode 100644 index 00000000..87dc79ab --- /dev/null +++ b/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.js.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`StylelintRunner should call stylelint.lint with the document path and given options 1`] = ` +Object { + "code": "a {}", + "codeFilename": "/path/to/file.scss", + "config": Object { + "customSyntax": "postcss-scss", + }, + "configBasedir": undefined, + "configFile": undefined, + "customSyntax": undefined, + "fix": true, + "formatter": [Function], + "ignoreDisables": undefined, + "ignorePath": "/.stylelintignore", + "reportInvalidScopeDisables": undefined, + "reportNeedlessDisables": undefined, +} +`; + +exports[`StylelintRunner should return processed lint results from Stylelint with configured rules 1`] = ` +Object { + "diagnostics": Array [ + Object { + "code": "block-no-empty", + "codeDescription": Object { + "href": "https://stylelint.io/user-guide/rules/block-no-empty", + }, + "message": "Unexpected empty block (block-no-empty)", + "range": Object { + "end": Object { + "character": 2, + "line": 0, + }, + "start": Object { + "character": 2, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + ], +} +`; + +exports[`StylelintRunner should return processed lint results from Stylelint without configured rules 1`] = ` +Object { + "diagnostics": Array [ + Object { + "code": "CssSyntaxError", + "message": "Unclosed block (CssSyntaxError)", + "range": Object { + "end": Object { + "character": 0, + "line": 0, + }, + "start": Object { + "character": 0, + "line": 0, + }, + }, + "severity": 1, + "source": "stylelint", + }, + ], +} +`; + +exports[`StylelintRunner should throw errors thrown by Stylelint 1`] = `"You must pass stylelint a \`files\` glob or a \`code\` string, though not both"`; diff --git a/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.js.snap b/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.js.snap new file mode 100644 index 00000000..429b2de7 --- /dev/null +++ b/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.js.snap @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`warningToDiagnostic should add a rule documentation URL if a matching rule exists 1`] = ` +Object { + "code": "color-hex-case", + "codeDescription": Object { + "href": "https://stylelint.io/user-guide/rules/color-hex-case", + }, + "message": "Expected \\"#AAA\\" to be \\"#aaa\\" (color-hex-case)", + "range": Object { + "end": Object { + "character": 11, + "line": 1, + }, + "start": Object { + "character": 11, + "line": 1, + }, + }, + "severity": 1, + "source": "stylelint", +} +`; + +exports[`warningToDiagnostic should convert a Stylelint warning to an LSP diagnostic 1`] = ` +Object { + "code": "color-hex-case", + "message": "Expected \\"#AAA\\" to be \\"#aaa\\" (color-hex-case)", + "range": Object { + "end": Object { + "character": 11, + "line": 1, + }, + "start": Object { + "character": 11, + "line": 1, + }, + }, + "severity": 1, + "source": "stylelint", +} +`; + +exports[`warningToDiagnostic should convert a Stylelint warning to an LSP diagnostic 2`] = ` +Object { + "code": "color-hex-length", + "message": "Expected \\"#bbbbbb\\" to be \\"#bbb\\" (color-hex-length)", + "range": Object { + "end": Object { + "character": 18, + "line": 2, + }, + "start": Object { + "character": 18, + "line": 2, + }, + }, + "severity": 2, + "source": "stylelint", +} +`; diff --git a/src/utils/stylelint/__tests__/build-stylelint-options.js b/src/utils/stylelint/__tests__/build-stylelint-options.js new file mode 100644 index 00000000..957862ba --- /dev/null +++ b/src/utils/stylelint/__tests__/build-stylelint-options.js @@ -0,0 +1,302 @@ +'use strict'; + +jest.mock('path'); +jest.mock('vscode-uri', () => ({ + URI: { + parse: jest.fn((uri) => ({ fsPath: uri, root: '/' })), + }, +})); +jest.mock('../../packages'); + +const mockedPackages = /** @type {jest.Mocked} */ ( + require('../../packages') +); + +const mockedPath = /** @type {tests.mocks.PathModule} */ (require('path')); + +mockedPath.__mockPlatform('posix'); + +const { buildStylelintOptions } = require('../build-stylelint-options'); + +describe('buildStylelintOptions', () => { + beforeEach(() => { + mockedPackages.findPackageRoot.mockReset(); + }); + + test('with no options, should only set ignore path', async () => { + const result = await buildStylelintOptions('/path/to/file.css', '/path'); + + expect(result).toEqual({ ignorePath: '/path/.stylelintignore' }); + }); + + test('should only override ignore path if document is in workspace', async () => { + const result1 = await buildStylelintOptions('/path/to/file.css', '/path', { + ignorePath: './stylelintignore', + }); + + expect(result1).toEqual({ ignorePath: '/path/.stylelintignore' }); + + const result2 = await buildStylelintOptions('/path/to/file.css', '/workspace', { + ignorePath: './stylelintignore', + }); + + expect(result2).toEqual({ ignorePath: './stylelintignore' }); + }); + + test('with no ignore path or workspace folder, should set ignore path to package root', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/path'); + + const result = await buildStylelintOptions('/path/to/file.css'); + + expect(result).toEqual({ ignorePath: '/path/.stylelintignore' }); + }); + + test('with no ignore path, when document is not in workspace, should set ignore path to package root', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/path'); + + const result = await buildStylelintOptions('/path/to/file.css', '/workspace'); + + expect(result).toEqual({ ignorePath: '/path/.stylelintignore' }); + }); + + test('with no ignore path, package root, or workspace, should set ignore path to URI root', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce(undefined); + + const result = await buildStylelintOptions('/path/to/file.css'); + + expect(result).toEqual({ ignorePath: '/.stylelintignore' }); + }); + + test('with no options or document FS path, should not set any options', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/path'); + + const result = await buildStylelintOptions('', '/workspace'); + + expect(result).toEqual({}); + }); + + test('with only base options, should not override base options except ignore path', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/path'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: false, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions('/path/to/file.css', '/path', options); + + expect(result).toEqual({ ...options, ignorePath: '/path/.stylelintignore' }); + }); + + test('with extension options, should override base options', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/path'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: true, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + config: { rules: { 'block-no-empty': true } }, + configFile: '/workspace/stylelint.config.js', + configBasedir: '/workspace', + customSyntax: 'postcss-html', + ignoreDisables: false, + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions( + '/workspace/file.css', + '/path', + options, + extensionOptions, + ); + + expect(result).toEqual({ + ...options, + ...extensionOptions, + }); + }); + + test('with extension options and workspace, should override and replace ${workspaceFolder} in paths', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/workspace'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: true, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + config: { rules: { 'block-no-empty': true } }, + configFile: '${workspaceFolder}/stylelint.config.js', + configBasedir: '/workspace', + customSyntax: '${workspaceFolder}/postcss-html', + ignoreDisables: false, + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions( + '/workspace/file.css', + '/workspace', + options, + extensionOptions, + ); + + expect(result).toEqual({ + ...options, + ...extensionOptions, + configFile: '/workspace/stylelint.config.js', + configBasedir: '/workspace', + customSyntax: '/workspace/postcss-html', + ignorePath: '/workspace/.stylelintignore', + }); + }); + + test('with extension options and no workspace, should not replace ${workspaceFolder} in paths', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/workspace'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: true, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + config: { rules: { 'block-no-empty': true } }, + configFile: '${workspaceFolder}/stylelint.config.js', + configBasedir: '/workspace', + customSyntax: '${workspaceFolder}/postcss-html', + ignoreDisables: false, + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions( + '/workspace/file.css', + undefined, + options, + extensionOptions, + ); + + expect(result).toEqual({ + ...options, + ...extensionOptions, + configBasedir: '/workspace', + ignorePath: '/.stylelintignore', + }); + }); + + test('with extension options and workspace, should make configBasedir absolute if it is relative', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/workspace'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: true, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + config: { rules: { 'block-no-empty': true } }, + configFile: '/workspace/stylelint.config.js', + configBasedir: './base', + customSyntax: '/workspace/postcss-html', + ignoreDisables: false, + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions( + '/workspace/file.css', + '/workspace', + options, + extensionOptions, + ); + + expect(result).toEqual({ + ...options, + ...extensionOptions, + configBasedir: '/workspace/base', + ignorePath: '/workspace/.stylelintignore', + }); + }); + + test('with extension options and no workspace, should not make configBasedir absolute if it is relative', async () => { + mockedPackages.findPackageRoot.mockResolvedValueOnce('/workspace'); + + /** @type {imports.stylelint.LinterOptions} */ + const options = { + config: {}, + configFile: '/path/stylelint.config.js', + configBasedir: '/path', + customSyntax: 'postcss-scss', + ignoreDisables: true, + ignorePath: '/.stylelintignore', + reportNeedlessDisables: true, + reportInvalidScopeDisables: true, + }; + + /** @type {ExtensionOptions} */ + const extensionOptions = { + config: { rules: { 'block-no-empty': true } }, + configFile: '/workspace/stylelint.config.js', + configBasedir: './base', + customSyntax: '/workspace/postcss-html', + ignoreDisables: false, + reportNeedlessDisables: false, + reportInvalidScopeDisables: false, + }; + + const result = await buildStylelintOptions( + '/workspace/file.css', + undefined, + options, + extensionOptions, + ); + + expect(result).toEqual({ + ...options, + ...extensionOptions, + configBasedir: 'base', + ignorePath: '/.stylelintignore', + }); + }); +}); diff --git a/src/utils/stylelint/__tests__/disable-metadata-lookup-table.js b/src/utils/stylelint/__tests__/disable-metadata-lookup-table.js new file mode 100644 index 00000000..52fa4b38 --- /dev/null +++ b/src/utils/stylelint/__tests__/disable-metadata-lookup-table.js @@ -0,0 +1,350 @@ +'use strict'; + +const { Range } = require('vscode-languageserver-types'); + +const { DisableReportRuleNames } = require('../../types'); + +const { DisableMetadataLookupTable } = require('../disable-metadata-lookup-table'); + +/** + * @param {{disableType: DisableReportRuleNames, rule: string, range: lsp.Range}} options + * @returns {lsp.Diagnostic} + */ +const createDisableDiagnostic = ({ disableType, rule, range }) => { + let message = ''; + + switch (disableType) { + case DisableReportRuleNames.Needless: + message = `Needless disable for "${rule}"`; + break; + + case DisableReportRuleNames.InvalidScope: + message = `Rule "${rule}" isn't enabled`; + break; + + case DisableReportRuleNames.Descriptionless: + message = `Disable for "${rule}" is missing a description`; + break; + + case DisableReportRuleNames.Illegal: + message = `Rule "${rule}" may not be disabled`; + break; + } + + return { + message, + range, + code: disableType, + }; +}; + +describe('DisableMetadataLookupTable', () => { + test('should be constructable', () => { + expect(() => new DisableMetadataLookupTable([])).not.toThrow(); + }); + + test('should look up disable reports by type', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(4, 2, 7, 5), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(5, 2, 3, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(1, 3, 1, 2), + }), + ]); + + expect(table.find({ type: DisableReportRuleNames.Needless })).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(4, 2, 7, 5), + }), + ]), + ); + }); + + test('should look up disable reports by rule', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(4, 2, 7, 5), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(5, 2, 3, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(1, 3, 1, 2), + }), + ]); + + expect(table.find({ rule: 'bar' })).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(5, 2, 3, 3), + }), + ]), + ); + }); + + test('should look up disable reports by range', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(4, 2, 7, 5), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(5, 2, 3, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(1, 3, 1, 2), + }), + ]); + + expect(table.find({ range: Range.create(1, 3, 1, 2) })).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(1, 3, 1, 2), + }), + ]), + ); + }); + + test('should look up disable reports by type and rule', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'foo', + range: Range.create(3, 2, 4, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'bar', + range: Range.create(9, 7, 1, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(8, 1, 6, 8), + }), + ]); + + expect(table.find({ type: DisableReportRuleNames.Needless, rule: 'foo' })).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + ]), + ); + }); + + test('should look up disable reports by type and range', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Illegal, + rule: 'bar', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(9, 7, 1, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Illegal, + rule: 'qux', + range: Range.create(9, 7, 1, 2), + }), + ]); + + expect( + table.find({ type: DisableReportRuleNames.Descriptionless, range: Range.create(9, 7, 1, 2) }), + ).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(9, 7, 1, 2), + }), + ]), + ); + }); + + test('should look up disable reports by rule and range', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'foo', + range: Range.create(3, 2, 4, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'bar', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Illegal, + rule: 'bar', + range: Range.create(8, 1, 6, 8), + }), + ]); + + expect(table.find({ rule: 'foo', range: Range.create(6, 8, 5, 2) })).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + ]), + ); + }); + + test('should look up disable reports by type, rule and range', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'foo', + range: Range.create(3, 2, 4, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'bar', + range: Range.create(6, 8, 5, 2), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(3, 2, 4, 3), + }), + ]); + + expect( + table.find({ + type: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + ).toStrictEqual( + new Set([ + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(6, 8, 5, 2), + }), + ]), + ); + }); + + test('should return an empty set if given no parameters', () => { + const table = new DisableMetadataLookupTable([ + { + code: 'indentation', + message: 'Expected indentation of 4 spaces', + range: Range.create(7, 8, 7, 1), + }, + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Needless, + rule: 'foo', + range: Range.create(4, 2, 7, 5), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.InvalidScope, + rule: 'bar', + range: Range.create(5, 2, 3, 3), + }), + createDisableDiagnostic({ + disableType: DisableReportRuleNames.Descriptionless, + rule: 'baz', + range: Range.create(1, 3, 1, 2), + }), + ]); + + expect(table.find({})).toStrictEqual(new Set()); + }); +}); diff --git a/src/utils/stylelint/__tests__/formatting-options-to-rules.js b/src/utils/stylelint/__tests__/formatting-options-to-rules.js new file mode 100644 index 00000000..fb8f4e14 --- /dev/null +++ b/src/utils/stylelint/__tests__/formatting-options-to-rules.js @@ -0,0 +1,57 @@ +'use strict'; + +const { formattingOptionsToRules } = require('../formatting-options-to-rules'); + +describe('formattingOptionsToRules', () => { + test('should convert insertSpaces and tabSize to an indentation rule', () => { + expect(formattingOptionsToRules({ insertSpaces: true, tabSize: 2 })).toStrictEqual({ + indentation: [2], + }); + expect(formattingOptionsToRules({ insertSpaces: false, tabSize: 2 })).toStrictEqual({ + indentation: ['tab'], + }); + }); + + test('should convert insertFinalNewline to a no-missing-end-of-source-newline rule', () => { + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, insertFinalNewline: true }), + ).toStrictEqual({ + indentation: [2], + 'no-missing-end-of-source-newline': true, + }); + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, insertFinalNewline: false }), + ).toStrictEqual({ + indentation: [2], + 'no-missing-end-of-source-newline': false, + }); + }); + + test('should convert trimTrailingWhitespace to a no-eol-whitespace rule', () => { + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, trimTrailingWhitespace: true }), + ).toStrictEqual({ + indentation: [2], + 'no-eol-whitespace': true, + }); + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, trimTrailingWhitespace: false }), + ).toStrictEqual({ + indentation: [2], + 'no-eol-whitespace': false, + }); + }); + + test('should ignore trimFinalNewlines', () => { + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, trimFinalNewlines: false }), + ).toStrictEqual({ + indentation: [2], + }); + expect( + formattingOptionsToRules({ insertSpaces: true, tabSize: 2, trimFinalNewlines: true }), + ).toStrictEqual({ + indentation: [2], + }); + }); +}); diff --git a/src/utils/stylelint/__tests__/get-disable-diagnostic-rule.js b/src/utils/stylelint/__tests__/get-disable-diagnostic-rule.js new file mode 100644 index 00000000..f08f63b1 --- /dev/null +++ b/src/utils/stylelint/__tests__/get-disable-diagnostic-rule.js @@ -0,0 +1,59 @@ +'use strict'; + +const { Range } = require('vscode-languageserver-types'); +const { DisableReportRuleNames } = require('../../types'); +const { getDisableDiagnosticRule } = require('../get-disable-diagnostic-rule'); + +const range = Range.create(0, 1, 2, 3); + +describe('getDisableDiagnosticRule', () => { + test('should return rules for needless disable diagnostics', () => { + expect( + getDisableDiagnosticRule({ + message: 'Needless disable for "color-named"', + range, + code: DisableReportRuleNames.Needless, + }), + ).toBe('color-named'); + }); + + test('should return rules for invalid scope disable diagnostics', () => { + expect( + getDisableDiagnosticRule({ + message: 'Rule "block-no-empty" isn\'t enabled', + range, + code: DisableReportRuleNames.InvalidScope, + }), + ).toBe('block-no-empty'); + }); + + test('should return rules for descriptionless disable diagnostics', () => { + expect( + getDisableDiagnosticRule({ + message: 'Disable for "all" is missing a description', + range, + code: DisableReportRuleNames.Descriptionless, + }), + ).toBe('all'); + }); + + test('should return rules for illegal disable diagnostics', () => { + expect( + getDisableDiagnosticRule({ + message: 'Rule "block-no-empty" may not be disabled', + range, + code: DisableReportRuleNames.Illegal, + }), + ).toBe('block-no-empty'); + }); + + test('should return undefined for non-disable diagnostics', () => { + expect( + getDisableDiagnosticRule({ + message: 'Expected indentation of 4 spaces (indentation)', + range, + code: 'indentation', + }), + ).toBeUndefined(); + }); +}); diff --git a/src/utils/stylelint/__tests__/process-linter-result.js b/src/utils/stylelint/__tests__/process-linter-result.js new file mode 100644 index 00000000..f4ae5b4d --- /dev/null +++ b/src/utils/stylelint/__tests__/process-linter-result.js @@ -0,0 +1,109 @@ +'use strict'; + +const { processLinterResult } = require('../process-linter-result'); + +/** @type {stylelint.PublicApi} */ +const mockStylelint = /** @type {any} */ ({ + rules: { + 'unit-no-unknown': {}, + 'at-rule-no-unknown': {}, + }, +}); + +/** + * @param {Partial[]} mockResults + * @param {string} [output] + */ +const createMockResult = (mockResults, output) => { + const results = mockResults.map((result) => ({ + invalidOptionWarnings: result.invalidOptionWarnings ?? [], + warnings: result.warnings ?? [], + ignored: result.ignored ?? false, + })); + + return /** @type {stylelint.LinterResult} */ (output ? { results, output } : { results }); +}; + +/** + * @param {string} rule + * @param {string} [text] + * @param {stylelint.Severity} [severity] + * @param {number} [line] + * @param {number} [column] + * @returns {stylelint.Warning} + */ +const createMockWarning = (rule, text, severity, line, column) => ({ + rule, + text: text ?? rule, + severity: severity ?? 'error', + line: line ?? 1, + column: column ?? 1, +}); + +describe('processLinterResult', () => { + test('should return diagnostics for each warning', () => { + const result = processLinterResult( + mockStylelint, + createMockResult([ + { + warnings: [ + createMockWarning('unit-no-unknown'), + createMockWarning('at-rule-no-unknown'), + createMockWarning('alpha-value-notation'), + ], + }, + ]), + ); + + expect(result).toMatchSnapshot(); + }); + + test('should return output if given', () => { + const result = processLinterResult( + mockStylelint, + createMockResult( + [ + { + warnings: [createMockWarning('unit-no-unknown')], + }, + ], + 'Output', + ), + ); + + expect(result).toMatchSnapshot(); + }); + + test('should return no diagnostics if no results are given', () => { + const result = processLinterResult(mockStylelint, createMockResult([])); + + expect(result).toEqual({ diagnostics: [] }); + }); + + test('should return no diagnostics if results are ignored', () => { + const result = processLinterResult( + mockStylelint, + createMockResult([ + { + warnings: [createMockWarning('unit-no-unknown')], + ignored: true, + }, + ]), + ); + + expect(result).toEqual({ diagnostics: [] }); + }); + + test('should throw if invalid option results are given', () => { + expect(() => + processLinterResult( + mockStylelint, + createMockResult([ + { + invalidOptionWarnings: [{ text: 'Warning 1' }, { text: 'Warning 2' }], + }, + ]), + ), + ).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/src/utils/stylelint/__tests__/stylelint-runner.js b/src/utils/stylelint/__tests__/stylelint-runner.js new file mode 100644 index 00000000..dcfdf9c3 --- /dev/null +++ b/src/utils/stylelint/__tests__/stylelint-runner.js @@ -0,0 +1,294 @@ +'use strict'; + +jest.mock('os'); +jest.mock('path'); +jest.mock('vscode-uri', () => ({ + URI: { + parse: jest.fn((/** @type {string} */ str) => ({ fsPath: str })), + }, +})); +jest.mock('../../packages/stylelint-resolver'); +jest.mock('../../documents'); + +const stylelint = require('stylelint'); + +const mockedOS = /** @type {tests.mocks.OSModule} */ (require('os')); +const mockedPath = /** @type {tests.mocks.PathModule} */ (require('path')); +const resolver = /** @type {jest.Mocked} */ ( + require('../../packages/stylelint-resolver') +); + +const mockedDocuments = /** @type {jest.Mocked} */ ( + require('../../documents') +); + +const { StylelintRunner } = require('../stylelint-runner'); + +/** @typedef {(options: stylelint.LinterOptions) => Promise>} FakeLintFunction */ + +/** + * @param {FakeLintFunction} [lint] + * @param {(serverOptions: ResolverOptions, document: lsp.TextDocument) => Promise<{stylelint: {lint: FakeLintFunction}}>} [resolve] + * @returns {() => import('../../packages/stylelint-resolver').StylelintResolver} + */ +const createMockResolver = (lint, resolve) => + /** @type {any} */ ( + () => ({ + resolve: resolve ?? (async () => (lint ? { stylelint: { lint } } : undefined)), + }) + ); + +/** + * @param {string} code + * @param {string} [uri] + * @returns {lsp.TextDocument} + */ +const createMockDocument = (code, uri = '/path/to/file.css') => + /** @type {lsp.TextDocument} */ ({ + getText: () => code, + uri, + }); + +/** @type {lsp.Connection} */ +const mockConnection = /** @type {any} */ ({}); + +describe('StylelintRunner', () => { + beforeEach(() => { + mockedOS.__mockPlatform('linux'); + mockedPath.__mockPlatform('posix'); + }); + + test('should return no diagnostics if Stylelint cannot be resolved', async () => { + resolver.StylelintResolver.mockImplementation(createMockResolver()); + + const results = await new StylelintRunner(mockConnection).lintDocument(createMockDocument('')); + + expect(results).toEqual({ diagnostics: [] }); + }); + + // TODO: Remove once fixed upstream + test('should upper-case drive letters on Windows (Stylelint bug #5594)', async () => { + expect.assertions(2); + + mockedOS.__mockPlatform('win32'); + resolver.StylelintResolver.mockImplementation( + createMockResolver(async (options) => { + expect(options.codeFilename).toBe('C:\\path\\to\\file.css'); + + return { results: [] }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('', 'c:\\path\\to\\file.css'), + ); + + mockedOS.__mockPlatform('linux'); + resolver.StylelintResolver.mockImplementation( + createMockResolver(async (options) => { + expect(options.codeFilename).toBe('c:/path/to/file.css'); + + return { results: [] }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('', 'c:/path/to/file.css'), + ); + }); + + test('should call stylelint.lint with the document path and given options', async () => { + expect.assertions(2); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(async (options) => { + expect(options).toMatchSnapshot(); + + expect(/** @type {stylelint.Formatter} */ (options.formatter)?.([])).toBe(''); + + return { results: [] }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('a {}', '/path/to/file.scss'), + { + config: { + customSyntax: 'postcss-scss', + }, + fix: true, + }, + ); + }); + + test("should pass empty rules if the document's path cannot be determined and rules aren't set", async () => { + expect.assertions(1); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(async (options) => { + expect(options.config).toEqual({ + rules: {}, + }); + + return { results: [] }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument(createMockDocument('a {}', '')); + }); + + test("should not change set rules if the document's path cannot be determined", async () => { + expect.assertions(1); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(async (options) => { + expect(options.config).toEqual({ + rules: { 'no-empty-source': true }, + }); + + return { results: [] }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument(createMockDocument('a {}', ''), { + config: { rules: { 'no-empty-source': true } }, + }); + }); + + test('should call the resolver with the server options and the document', async () => { + expect.assertions(3); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async (serverOptions, document) => { + expect(serverOptions).toEqual({ + packageManager: 'pnpm', + }); + + expect(document).toEqual({ + getText: expect.any(Function), + uri: '/path/to/file.css', + }); + + expect(document.getText()).toBe('a {}'); + + return { + stylelint: { lint: async () => ({ results: [] }) }, + }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('a {}', '/path/to/file.css'), + undefined, + { packageManager: 'pnpm' }, + ); + }); + + test('with stylelintPath, should call the resolver with the path', async () => { + expect.assertions(1); + + mockedDocuments.getWorkspaceFolder.mockResolvedValueOnce('/workspace'); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async (serverOptions) => { + expect(serverOptions).toEqual({ + stylelintPath: '/path/to/stylelint', + }); + + return { + stylelint: { lint: async () => ({ results: [] }) }, + }; + }), + ); + + await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('a {}', '/path/to/file.css'), + undefined, + { stylelintPath: '/path/to/stylelint' }, + ); + }); + + test('should return processed lint results from Stylelint without configured rules', async () => { + expect.assertions(1); + + mockedPath.__mockPlatform(); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async () => ({ stylelint })), + ); + + const results = await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('table {', '/path/to/file.css'), + ); + + expect(results).toMatchSnapshot(); + }); + + test('should return processed lint results from Stylelint with configured rules', async () => { + expect.assertions(1); + + mockedPath.__mockPlatform(); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async () => ({ stylelint })), + ); + + const results = await new StylelintRunner(mockConnection).lintDocument( + createMockDocument('a {}', '/path/to/file.css'), + { config: { rules: { 'block-no-empty': true } } }, + ); + + expect(results).toMatchSnapshot(); + }); + + test('should throw errors thrown by Stylelint', async () => { + expect.assertions(1); + + mockedPath.__mockPlatform(); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async () => ({ stylelint })), + ); + + await expect( + new StylelintRunner(mockConnection).lintDocument( + createMockDocument('a {}', '/path/to/file.css'), + { + config: { rules: {} }, + files: ['/path/to/file.css'], + }, + ), + ).rejects.toThrowErrorMatchingSnapshot(); + }); + + test('should log if a logger is provided', async () => { + expect.assertions(2); + + const mockLogger = /** @type {winston.Logger} */ ( + /** @type {unknown} */ ({ + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + debug: jest.fn(), + isDebugEnabled: jest.fn(() => true), + }) + ); + + mockedPath.__mockPlatform(); + + resolver.StylelintResolver.mockImplementation( + createMockResolver(undefined, async () => ({ stylelint })), + ); + + await new StylelintRunner(mockConnection, mockLogger).lintDocument( + createMockDocument('a {}', '/path/to/file.css'), + { config: { rules: { 'block-no-empty': true } } }, + ); + + expect(mockLogger.debug).toHaveBeenCalledTimes(1); + expect(mockLogger.debug).toHaveBeenCalledWith( + expect.stringMatching(/^Running Stylelint/), + expect.any(Object), + ); + }); +}); diff --git a/src/utils/stylelint/__tests__/warning-to-diagnostic.js b/src/utils/stylelint/__tests__/warning-to-diagnostic.js new file mode 100644 index 00000000..35e16f90 --- /dev/null +++ b/src/utils/stylelint/__tests__/warning-to-diagnostic.js @@ -0,0 +1,49 @@ +'use strict'; + +const { lint } = require('stylelint'); + +const { warningToDiagnostic } = require('../warning-to-diagnostic'); + +describe('warningToDiagnostic', () => { + test('should convert a Stylelint warning to an LSP diagnostic', async () => { + expect.assertions(2); + const { + results: [{ warnings }], + } = await lint({ + code: `a { + color: #AAA; + border-color: #bbbbbb; + }`, + config: { + rules: { + 'color-hex-case': ['lower'], + 'color-hex-length': ['short', { severity: 'warning' }], + }, + }, + }); + + expect(warningToDiagnostic(warnings[0])).toMatchSnapshot(); + expect(warningToDiagnostic(warnings[1])).toMatchSnapshot(); + }); + + test('should add a rule documentation URL if a matching rule exists', async () => { + expect.assertions(1); + const { + results: [{ warnings }], + } = await lint({ + code: `a { + color: #AAA; + border-color: #bbbbbb; + }`, + config: { + rules: { + 'color-hex-case': ['lower'], + }, + }, + }); + + const rules = { 'color-hex-case': {} }; + + expect(warningToDiagnostic(warnings[0], /** @type {any} */ (rules))).toMatchSnapshot(); + }); +}); diff --git a/src/utils/stylelint/build-stylelint-options.js b/src/utils/stylelint/build-stylelint-options.js new file mode 100644 index 00000000..9d9bf2ed --- /dev/null +++ b/src/utils/stylelint/build-stylelint-options.js @@ -0,0 +1,82 @@ +'use strict'; + +const path = require('path'); +const pathIsInside = require('path-is-inside'); +const { URI } = require('vscode-uri'); +const { findPackageRoot } = require('../packages'); + +/** + * Given a document URI, base options, and extension options, builds a Stylelint + * options object. Extension options supercede base options. + * @param {string} uri + * @param {string} [workspaceFolder] + * @param {Partial} [baseOptions] + * @param {ExtensionOptions} [extensionOptions] + * @returns {Promise>} + */ +async function buildStylelintOptions( + uri, + workspaceFolder, + baseOptions = {}, + { + config, + configFile, + configBasedir, + customSyntax, + ignoreDisables, + reportNeedlessDisables, + reportInvalidScopeDisables, + } = {}, +) { + const options = { + ...baseOptions, + + config: config ?? baseOptions.config, + + configFile: configFile + ? workspaceFolder + ? configFile.replace(/\$\{workspaceFolder\}/gu, workspaceFolder) + : configFile + : baseOptions.configFile, + + configBasedir: configBasedir + ? path.isAbsolute(configBasedir) + ? configBasedir + : path.join(workspaceFolder ?? '', configBasedir) + : baseOptions.configBasedir, + + customSyntax: customSyntax + ? workspaceFolder + ? customSyntax.replace(/\$\{workspaceFolder\}/gu, workspaceFolder) + : customSyntax + : baseOptions.customSyntax, + + ignoreDisables: ignoreDisables ?? baseOptions.ignoreDisables, + + reportNeedlessDisables: reportNeedlessDisables ?? baseOptions.reportNeedlessDisables, + + reportInvalidScopeDisables: + reportInvalidScopeDisables ?? baseOptions.reportInvalidScopeDisables, + }; + + const documentPath = URI.parse(uri).fsPath; + + if (documentPath) { + if (workspaceFolder && pathIsInside(documentPath, workspaceFolder)) { + options.ignorePath = path.join(workspaceFolder, '.stylelintignore'); + } + + if (options.ignorePath === undefined) { + options.ignorePath = path.join( + (await findPackageRoot(documentPath)) || path.parse(documentPath).root, + '.stylelintignore', + ); + } + } + + return options; +} + +module.exports = { + buildStylelintOptions, +}; diff --git a/src/utils/stylelint/disable-metadata-lookup-table.js b/src/utils/stylelint/disable-metadata-lookup-table.js new file mode 100644 index 00000000..e857326a --- /dev/null +++ b/src/utils/stylelint/disable-metadata-lookup-table.js @@ -0,0 +1,100 @@ +'use strict'; + +const { intersect } = require('../sets'); +const { getDisableDiagnosticRule } = require('./get-disable-diagnostic-rule'); + +/** + * Helps lookup disable reports by type, rule, or range. + */ +class DisableMetadataLookupTable { + /** + * Reports by type. + * @type {Map>} + */ + #reportsByType = new Map(); + + /** + * Reports by type. + * @type {Map>} + */ + #reportsByRule = new Map(); + + /** + * Reports by type. + * @type {Map>} + */ + #reportsByRange = new Map(); + + /** + * @param {lsp.Diagnostic[]} diagnostics The diagnostics to build the lookup + * table from. + */ + constructor(diagnostics) { + for (const diagnostic of diagnostics) { + const rule = getDisableDiagnosticRule(diagnostic); + + if (!rule) { + continue; + } + + // If getDisableDiagnosticRule returns a rule, the diagnostic code + // must be a string. + const code = /** @type {string} */ (diagnostic.code); + + const existingByType = this.#reportsByType.get(code); + + if (existingByType) { + existingByType.add(diagnostic); + } else { + this.#reportsByType.set(code, new Set([diagnostic])); + } + + const existingByRule = this.#reportsByRule.get(rule); + + if (existingByRule) { + existingByRule.add(diagnostic); + } else { + this.#reportsByRule.set(rule, new Set([diagnostic])); + } + + const rangeKey = this.#getRangeKey(diagnostic.range); + + const existingByRange = this.#reportsByRange.get(rangeKey); + + if (existingByRange) { + existingByRange.add(diagnostic); + } else { + this.#reportsByRange.set(rangeKey, new Set([diagnostic])); + } + } + } + + /** + * @param {lsp.Range} range + * @returns {string} + */ + #getRangeKey({ start, end }) { + return `${start.line}:${start.character}:${end.line}:${end.character}`; + } + + /** + * Finds the reports that match the given type, rule, and range. + * @param {{ + * type?: import('../types').DisableReportRuleNames | string; + * rule?: string; + * range?: lsp.Range; + * }} options + * @returns {Set} + */ + find({ type, rule, range }) { + const reportsByType = type ? this.#reportsByType.get(type) : undefined; + const reportsByRule = rule ? this.#reportsByRule.get(rule) : undefined; + const reportsByRange = range ? this.#reportsByRange.get(this.#getRangeKey(range)) : undefined; + + return intersect(intersect(reportsByType, reportsByRule), reportsByRange) ?? new Set(); + } +} + +module.exports = { + DisableMetadataLookupTable, +}; diff --git a/src/utils/stylelint/formatting-options-to-rules.js b/src/utils/stylelint/formatting-options-to-rules.js new file mode 100644 index 00000000..d71620a7 --- /dev/null +++ b/src/utils/stylelint/formatting-options-to-rules.js @@ -0,0 +1,43 @@ +'use strict'; + +/** + * @typedef {{ + * indentation: [number | string], + * 'no-missing-end-of-source-newline'?: boolean, + * 'no-eol-whitespace'?: boolean, + * }} FormattingRules + */ + +/** + * Converts the given formatting options to rules. + * @param {lsp.FormattingOptions} options The formatting options. + * @returns {FormattingRules} The rules. + */ +function formattingOptionsToRules({ + insertSpaces, + tabSize, + insertFinalNewline, + trimTrailingWhitespace, +}) { + // NOTE: There is no equivalent rule for trimFinalNewlines, so it is not respected. + // TODO: Create respective rule upstream? + + /** @type {FormattingRules} */ + const rules = { + indentation: [insertSpaces ? tabSize : 'tab'], + }; + + if (insertFinalNewline !== undefined) { + rules['no-missing-end-of-source-newline'] = insertFinalNewline; + } + + if (trimTrailingWhitespace !== undefined) { + rules['no-eol-whitespace'] = trimTrailingWhitespace; + } + + return rules; +} + +module.exports = { + formattingOptionsToRules, +}; diff --git a/src/utils/stylelint/get-disable-diagnostic-rule.js b/src/utils/stylelint/get-disable-diagnostic-rule.js new file mode 100644 index 00000000..8e49f6ef --- /dev/null +++ b/src/utils/stylelint/get-disable-diagnostic-rule.js @@ -0,0 +1,33 @@ +'use strict'; + +const { DisableReportRuleNames } = require('../types'); + +/** + * Gets the rule name to which a disable diagnostic applies. Returns `undefined` + * if the diagnostic is not a disable diagnostic. + * @param {lsp.Diagnostic} diagnostic The diagnostic corresponding to the + * Stylelint warning. + * @returns {string | undefined} + */ +function getDisableDiagnosticRule(diagnostic) { + switch (diagnostic.code) { + case DisableReportRuleNames.Needless: + return diagnostic.message.match(/^Needless disable for "(.+)"$/)?.[1]; + + case DisableReportRuleNames.InvalidScope: + return diagnostic.message.match(/^Rule "(.+)" isn't enabled$/)?.[1]; + + case DisableReportRuleNames.Descriptionless: + return diagnostic.message.match(/^Disable for "(.+)" is missing a description$/)?.[1]; + + case DisableReportRuleNames.Illegal: + return diagnostic.message.match(/^Rule "(.+)" may not be disabled$/)?.[1]; + + default: + return undefined; + } +} + +module.exports = { + getDisableDiagnosticRule, +}; diff --git a/src/utils/stylelint/index.js b/src/utils/stylelint/index.js new file mode 100644 index 00000000..9afb4f58 --- /dev/null +++ b/src/utils/stylelint/index.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = { + ...require('./build-stylelint-options'), + ...require('./disable-metadata-lookup-table'), + ...require('./formatting-options-to-rules'), + ...require('./get-disable-diagnostic-rule'), + ...require('./process-linter-result'), + ...require('./stylelint-runner'), + ...require('./warning-to-diagnostic'), +}; diff --git a/src/utils/stylelint/process-linter-result.js b/src/utils/stylelint/process-linter-result.js new file mode 100644 index 00000000..4b19c6e3 --- /dev/null +++ b/src/utils/stylelint/process-linter-result.js @@ -0,0 +1,41 @@ +'use strict'; + +const { warningToDiagnostic } = require('./warning-to-diagnostic'); +const { InvalidOptionError } = require('../types'); + +/** + * Processes the results of a Stylelint lint run. + * + * If Stylelint reported any warnings, they are converted to Diagnostics and + * returned. If the lint results contain raw output in the `output` property, it + * is also returned. + * + * Throws an `InvalidOptionError` for any invalid option warnings reported by + * Stylelint. + * @param {stylelint.PublicApi} stylelint The Stylelint instance that was used. + * @param {stylelint.LinterResult} result The results returned by Stylelint. + * @returns {LintDiagnostics} + */ +function processLinterResult(stylelint, { results, output }) { + if (results.length === 0) { + return { diagnostics: [] }; + } + + const [{ invalidOptionWarnings, warnings, ignored }] = results; + + if (ignored) { + return { diagnostics: [] }; + } + + if (invalidOptionWarnings.length !== 0) { + throw new InvalidOptionError(invalidOptionWarnings); + } + + const diagnostics = warnings.map((warning) => warningToDiagnostic(warning, stylelint.rules)); + + return output ? { output, diagnostics } : { diagnostics }; +} + +module.exports = { + processLinterResult, +}; diff --git a/src/utils/stylelint/stylelint-runner.js b/src/utils/stylelint/stylelint-runner.js new file mode 100644 index 00000000..84703f35 --- /dev/null +++ b/src/utils/stylelint/stylelint-runner.js @@ -0,0 +1,123 @@ +'use strict'; + +const os = require('os'); +const { URI } = require('vscode-uri'); +const { StylelintResolver } = require('../packages'); +const { getWorkspaceFolder } = require('../documents'); +const { processLinterResult } = require('./process-linter-result'); +const { buildStylelintOptions } = require('./build-stylelint-options'); + +/** + * Runs Stylelint in VS Code. + */ +class StylelintRunner { + /** + * The language server connection. + * @type {lsp.Connection | undefined} + */ + #connection; + + /** + * The logger to use, if any. + * @type {winston.Logger | undefined} + */ + #logger; + + /** + * The Stylelint resolver. + * @type {StylelintResolver} + */ + #stylelintResolver; + + /** + * @param {lsp.Connection} [connection] + * @param {winston.Logger} [logger] + * @param {StylelintResolver} [resolver] + */ + constructor(connection, logger, resolver) { + this.#connection = connection; + this.#logger = logger; + this.#stylelintResolver = resolver ?? new StylelintResolver(connection, logger); + } + + /** + * Lints the given document using Stylelint. The linting result is then + * converted to LSP diagnostics and returned. + * @param {lsp.TextDocument} document + * @param {stylelint.LinterOptions} [linterOptions] + * @param {ExtensionOptions} [extensionOptions] + * @returns {Promise} + */ + async lintDocument(document, linterOptions = {}, extensionOptions = {}) { + const workspaceFolder = + this.#connection && (await getWorkspaceFolder(this.#connection, document)); + + const result = await this.#stylelintResolver.resolve(extensionOptions, document); + + if (!result) { + this.#logger?.info('No Stylelint found with which to lint document', { + uri: document.uri, + options: extensionOptions, + }); + + return { diagnostics: [] }; + } + + const { stylelint } = result; + + const { fsPath } = URI.parse(document.uri); + + // Workaround for Stylelint treating paths as case-sensitive on Windows + // If the drive letter is lowercase, we need to convert it to uppercase + // See https://github.com/stylelint/stylelint/issues/5594 + // TODO: Remove once fixed upstream + const codeFilename = + os.platform() === 'win32' + ? fsPath.replace(/^[a-z]:/, (match) => match.toUpperCase()) + : fsPath; + + /** @type {stylelint.LinterOptions} */ + const options = { + ...(await buildStylelintOptions( + document.uri, + workspaceFolder, + linterOptions, + extensionOptions, + )), + code: document.getText(), + formatter: () => '', + }; + + if (codeFilename) { + options.codeFilename = codeFilename; + } else if (!linterOptions?.config?.rules) { + options.config = { rules: {} }; + } + + if (this.#logger?.isDebugEnabled()) { + this.#logger?.debug('Running Stylelint', { options: { ...options, code: '...' } }); + } + + try { + return processLinterResult(stylelint, await stylelint.lint(options)); + } catch (err) { + if ( + err instanceof Error && + (err.message.startsWith('No configuration provided for') || + err.message.includes('No rules found within configuration')) + ) { + // Check only CSS syntax errors without applying any Stylelint rules + return processLinterResult( + stylelint, + await stylelint.lint({ ...options, config: { rules: {} } }), + ); + } + + throw err; + } + } +} + +module.exports = { + StylelintRunner, +}; diff --git a/src/utils/stylelint/warning-to-diagnostic.js b/src/utils/stylelint/warning-to-diagnostic.js new file mode 100644 index 00000000..ef98eddc --- /dev/null +++ b/src/utils/stylelint/warning-to-diagnostic.js @@ -0,0 +1,68 @@ +'use strict'; + +const { Diagnostic, DiagnosticSeverity, Position, Range } = require('vscode-languageserver-types'); + +/** + * Converts a Stylelint warning to an LSP Diagnostic. + * + * @example + * ```js + * const [result] = await stylelint.lint({ + * code: 'a { color: red; }', + * config: { rules: { 'color-named': 'never' } } + * }); + * + * const [warning] = result.warnings; + * // { + * // rule: 'color-named', + * // text: 'Unexpected named color "red" (color-named)', + * // severity: 'error', + * // line: 1, + * // column: 12 + * // } + * + * const diagnostic = warningToDiagnostic(warning); + * // { + * // message: 'Unexpected named color "red" (color-named)', + * // severity: 1, + * // source: 'stylelint', + * // range: { + * // start: { + * // line: 0, + * // character: 11 + * // }, + * // end: { + * // line: 0, + * // character: 11 + * // } + * // } + * // } + * ``` + * @param {stylelint.Warning} warning The warning to convert. + * @param {{[name: string]: stylelint.Rule}} [rules] Available Stylelint rules. + * @returns {Diagnostic} + */ +function warningToDiagnostic(warning, rules) { + const position = Position.create(warning.line - 1, warning.column - 1); + + const ruleDocUrl = + rules?.[warning.rule] && `https://stylelint.io/user-guide/rules/${warning.rule}`; + + const diagnostic = Diagnostic.create( + Range.create(position, position), + warning.text, + DiagnosticSeverity[warning.severity === 'warning' ? 'Warning' : 'Error'], + warning.rule, + 'stylelint', + ); + + if (ruleDocUrl) { + diagnostic.codeDescription = { href: ruleDocUrl }; + } + + return diagnostic; +} + +module.exports = { + warningToDiagnostic, +}; diff --git a/src/utils/types.js b/src/utils/types.js new file mode 100644 index 00000000..098d9250 --- /dev/null +++ b/src/utils/types.js @@ -0,0 +1,50 @@ +'use strict'; + +const { CodeActionKind: VSCodeActionKind } = require('vscode-languageserver-types'); + +/** + * Command IDs + * @enum {string} + */ +const CommandId = { + ApplyAutoFix: 'stylelint.applyAutoFix', +}; + +/** + * Code action kinds + * @enum {string} + */ +const CodeActionKind = { + StylelintSourceFixAll: `${VSCodeActionKind.SourceFixAll}.stylelint`, +}; + +/** + * Disable report rule names + * @enum {string} + */ +const DisableReportRuleNames = { + Needless: '--report-needless-disables', + InvalidScope: '--report-invalid-scope-disables', + Descriptionless: '--report-descriptionless-disables', + Illegal: 'reportDisables', +}; + +/** + * Error thrown when a rule's option is invalid. + */ +class InvalidOptionError extends Error { + /** @param {{text: string}[]} warnings */ + constructor(warnings) { + const reasons = warnings.map((warning) => warning.text); + + super(reasons.join('\n')); + this.reasons = reasons; + } +} + +module.exports = { + CommandId, + CodeActionKind, + DisableReportRuleNames, + InvalidOptionError, +}; diff --git a/src/warnings-to-diagnostics.js b/src/warnings-to-diagnostics.js deleted file mode 100644 index 24344423..00000000 --- a/src/warnings-to-diagnostics.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -const { Diagnostic, DiagnosticSeverity, Position, Range } = require('vscode-languageserver-types'); - -/** @type {RuleDocUrlProvider} */ -const NOOP_RULE_DOC_URL_PROVIDER = () => undefined; - -/** - * @param {stylelint.Warning} warning - * @param {RuleDocUrlProvider} [ruleDocUrlProvider] - * @returns {Diagnostic} - */ -module.exports = function stylelintWarningToVscodeDiagnostic( - warning, - ruleDocUrlProvider = NOOP_RULE_DOC_URL_PROVIDER, -) { - const position = Position.create(warning.line - 1, warning.column - 1); - - /** - * @type {lsp.URI | null | undefined} - */ - const ruleDocUrl = ruleDocUrlProvider(warning.rule); - - const diagnostic = Diagnostic.create( - Range.create(position, position), - warning.text, - DiagnosticSeverity[warning.severity === 'warning' ? 'Warning' : 'Error'], - warning.rule, - 'stylelint', - ); - - if (ruleDocUrl) { - diagnostic.codeDescription = { href: ruleDocUrl }; - } - - return diagnostic; -}; diff --git a/src/warnings-to-diagnostics.md b/src/warnings-to-diagnostics.md deleted file mode 100644 index ec0aaa73..00000000 --- a/src/warnings-to-diagnostics.md +++ /dev/null @@ -1,68 +0,0 @@ -# stylelint-warning-to-vscode-diagnostic - -> 🚧 Inlined dependency taken from [https://github.com/shinnn/stylelint-warning-to-vscode-diagnostic](https://github.com/shinnn/stylelint-warning-to-vscode-diagnostic). - ---- - -Convert a [stylelint](https://github.com/stylelint/stylelint) warning into a [Visual Studio Code diagnostic](https://code.visualstudio.com/Docs/extensionAPI/vscode-api#Diagnostic) - -```javascript -const { lint } = require("stylelint"); -const stylelintWarningToVscodeDiagnostic = require("stylelint-warning-to-vscode-diagnostic"); - -(async () => { - const [result] = await lint({ - code: "a { color: red; }", - config: { - rules: { - "color-named": "never" - } - } - }); - - const [warning] = result.warnings; - /* { - rule: 'color-named', - text: 'Unexpected named color "red" (color-named)', - severity: 'error', - line: 1, - column: 12 - } */ - - stylelintWarningToVscodeDiagnostic(warnings); - /* { - message: 'Unexpected named color "red" (color-named)', - severity: 1, - source: 'stylelint', - range: { - start: { - line: 0, - character: 11 - }, - end: { - line: 0, - character: 11 - } - } - } */ -})(); -``` - -## Installation - -[Use](https://docs.npmjs.com/cli/install) [npm](https://docs.npmjs.com/getting-started/what-is-npm). - -``` -npm install stylelint-warning-to-vscode-diagnostic -``` - -## API - -```javascript -const stylelintWarningToVscodeDiagnostic = require("stylelint-warning-to-vscode-diagnostic"); -``` - -### stylelintWarningToVscodeDiagnostic(_warning_) - -_warning_: `Object` (stylelint [warning](https://github.com/stylelint/stylelint/blob/9.1.1/lib/createStylelintResult.js#L127-L131)) -Return: `Object` (VS Code [diagnostic](https://github.com/Microsoft/vscode-languageserver-node/blob/release/3.5.0/types/src/main.ts#L165-L192)) diff --git a/test/workspace/basic/.stylelintignore b/test/e2e/basic/.stylelintignore similarity index 100% rename from test/workspace/basic/.stylelintignore rename to test/e2e/basic/.stylelintignore diff --git a/test/workspace/basic/index.js b/test/e2e/basic/index.js similarity index 100% rename from test/workspace/basic/index.js rename to test/e2e/basic/index.js diff --git a/test/workspace/config-basedir/.vscode/settings.json b/test/e2e/config-basedir/.vscode/settings.json similarity index 100% rename from test/workspace/config-basedir/.vscode/settings.json rename to test/e2e/config-basedir/.vscode/settings.json diff --git a/test/workspace/config-basedir/__snapshots__/index.js.snap b/test/e2e/config-basedir/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/config-basedir/__snapshots__/index.js.snap rename to test/e2e/config-basedir/__snapshots__/index.js.snap diff --git a/test/workspace/config-basedir/config-basedir/stylelint-config1.js b/test/e2e/config-basedir/config-basedir/stylelint-config1.js similarity index 100% rename from test/workspace/config-basedir/config-basedir/stylelint-config1.js rename to test/e2e/config-basedir/config-basedir/stylelint-config1.js diff --git a/test/workspace/config-basedir/config-basedir/stylelint-config2.js b/test/e2e/config-basedir/config-basedir/stylelint-config2.js similarity index 100% rename from test/workspace/config-basedir/config-basedir/stylelint-config2.js rename to test/e2e/config-basedir/config-basedir/stylelint-config2.js diff --git a/test/workspace/config-basedir/index.js b/test/e2e/config-basedir/index.js similarity index 100% rename from test/workspace/config-basedir/index.js rename to test/e2e/config-basedir/index.js diff --git a/test/workspace/config-basedir/stylelint.config.js b/test/e2e/config-basedir/stylelint.config.js similarity index 100% rename from test/workspace/config-basedir/stylelint.config.js rename to test/e2e/config-basedir/stylelint.config.js diff --git a/test/workspace/config-basedir/test.css b/test/e2e/config-basedir/test.css similarity index 100% rename from test/workspace/config-basedir/test.css rename to test/e2e/config-basedir/test.css diff --git a/test/workspace/config-file/.vscode/settings.json b/test/e2e/config-file/.vscode/settings.json similarity index 100% rename from test/workspace/config-file/.vscode/settings.json rename to test/e2e/config-file/.vscode/settings.json diff --git a/test/workspace/config-file/__snapshots__/index.js.snap b/test/e2e/config-file/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/config-file/__snapshots__/index.js.snap rename to test/e2e/config-file/__snapshots__/index.js.snap diff --git a/test/workspace/config-file/config-folder/stylelint.config.js b/test/e2e/config-file/config-folder/stylelint.config.js similarity index 100% rename from test/workspace/config-file/config-folder/stylelint.config.js rename to test/e2e/config-file/config-folder/stylelint.config.js diff --git a/test/workspace/config-file/index.js b/test/e2e/config-file/index.js similarity index 100% rename from test/workspace/config-file/index.js rename to test/e2e/config-file/index.js diff --git a/test/workspace/config-file/test.css b/test/e2e/config-file/test.css similarity index 100% rename from test/workspace/config-file/test.css rename to test/e2e/config-file/test.css diff --git a/test/workspace/custom-syntax/.vscode/settings.json b/test/e2e/custom-syntax/.vscode/settings.json similarity index 100% rename from test/workspace/custom-syntax/.vscode/settings.json rename to test/e2e/custom-syntax/.vscode/settings.json diff --git a/test/workspace/custom-syntax/__snapshots__/index.js.snap b/test/e2e/custom-syntax/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/custom-syntax/__snapshots__/index.js.snap rename to test/e2e/custom-syntax/__snapshots__/index.js.snap diff --git a/test/workspace/custom-syntax/custom-syntax.js b/test/e2e/custom-syntax/custom-syntax.js similarity index 100% rename from test/workspace/custom-syntax/custom-syntax.js rename to test/e2e/custom-syntax/custom-syntax.js diff --git a/test/workspace/custom-syntax/index.js b/test/e2e/custom-syntax/index.js similarity index 100% rename from test/workspace/custom-syntax/index.js rename to test/e2e/custom-syntax/index.js diff --git a/test/workspace/custom-syntax/stylelint.config.js b/test/e2e/custom-syntax/stylelint.config.js similarity index 100% rename from test/workspace/custom-syntax/stylelint.config.js rename to test/e2e/custom-syntax/stylelint.config.js diff --git a/test/workspace/custom-syntax/test.css b/test/e2e/custom-syntax/test.css similarity index 100% rename from test/workspace/custom-syntax/test.css rename to test/e2e/custom-syntax/test.css diff --git a/test/workspace/formatter/.vscode/settings.json b/test/e2e/formatter/.vscode/settings.json similarity index 100% rename from test/workspace/formatter/.vscode/settings.json rename to test/e2e/formatter/.vscode/settings.json diff --git a/test/workspace/formatter/__snapshots__/index.js.snap b/test/e2e/formatter/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/formatter/__snapshots__/index.js.snap rename to test/e2e/formatter/__snapshots__/index.js.snap diff --git a/test/workspace/formatter/index.js b/test/e2e/formatter/index.js similarity index 100% rename from test/workspace/formatter/index.js rename to test/e2e/formatter/index.js diff --git a/test/workspace/formatter/test.css b/test/e2e/formatter/test.css similarity index 100% rename from test/workspace/formatter/test.css rename to test/e2e/formatter/test.css diff --git a/test/workspace/ignore-disables/.vscode/settings.json b/test/e2e/ignore-disables/.vscode/settings.json similarity index 100% rename from test/workspace/ignore-disables/.vscode/settings.json rename to test/e2e/ignore-disables/.vscode/settings.json diff --git a/test/workspace/ignore-disables/__snapshots__/index.js.snap b/test/e2e/ignore-disables/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/ignore-disables/__snapshots__/index.js.snap rename to test/e2e/ignore-disables/__snapshots__/index.js.snap diff --git a/test/workspace/ignore-disables/index.js b/test/e2e/ignore-disables/index.js similarity index 100% rename from test/workspace/ignore-disables/index.js rename to test/e2e/ignore-disables/index.js diff --git a/test/workspace/ignore-disables/stylelint.config.js b/test/e2e/ignore-disables/stylelint.config.js similarity index 100% rename from test/workspace/ignore-disables/stylelint.config.js rename to test/e2e/ignore-disables/stylelint.config.js diff --git a/test/workspace/ignore-disables/test.css b/test/e2e/ignore-disables/test.css similarity index 100% rename from test/workspace/ignore-disables/test.css rename to test/e2e/ignore-disables/test.css diff --git a/test/workspace/jest.config.js b/test/e2e/jest.config.js similarity index 100% rename from test/workspace/jest.config.js rename to test/e2e/jest.config.js diff --git a/test/workspace/lint/.vscode/settings.json b/test/e2e/lint/.vscode/settings.json similarity index 100% rename from test/workspace/lint/.vscode/settings.json rename to test/e2e/lint/.vscode/settings.json diff --git a/test/workspace/lint/__snapshots__/index.js.snap b/test/e2e/lint/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/lint/__snapshots__/index.js.snap rename to test/e2e/lint/__snapshots__/index.js.snap diff --git a/test/workspace/lint/index.js b/test/e2e/lint/index.js similarity index 100% rename from test/workspace/lint/index.js rename to test/e2e/lint/index.js diff --git a/test/workspace/lint/stylelint.config.js b/test/e2e/lint/stylelint.config.js similarity index 100% rename from test/workspace/lint/stylelint.config.js rename to test/e2e/lint/stylelint.config.js diff --git a/test/workspace/lint/test.css b/test/e2e/lint/test.css similarity index 100% rename from test/workspace/lint/test.css rename to test/e2e/lint/test.css diff --git a/test/workspace/lint/test.md b/test/e2e/lint/test.md similarity index 100% rename from test/workspace/lint/test.md rename to test/e2e/lint/test.md diff --git a/test/workspace/lint/test.scss b/test/e2e/lint/test.scss similarity index 100% rename from test/workspace/lint/test.scss rename to test/e2e/lint/test.scss diff --git a/test/workspace/report-invalid-scope-disables/.vscode/settings.json b/test/e2e/report-invalid-scope-disables/.vscode/settings.json similarity index 100% rename from test/workspace/report-invalid-scope-disables/.vscode/settings.json rename to test/e2e/report-invalid-scope-disables/.vscode/settings.json diff --git a/test/workspace/report-invalid-scope-disables/__snapshots__/index.js.snap b/test/e2e/report-invalid-scope-disables/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/report-invalid-scope-disables/__snapshots__/index.js.snap rename to test/e2e/report-invalid-scope-disables/__snapshots__/index.js.snap diff --git a/test/workspace/report-invalid-scope-disables/index.js b/test/e2e/report-invalid-scope-disables/index.js similarity index 100% rename from test/workspace/report-invalid-scope-disables/index.js rename to test/e2e/report-invalid-scope-disables/index.js diff --git a/test/workspace/report-invalid-scope-disables/stylelint.config.js b/test/e2e/report-invalid-scope-disables/stylelint.config.js similarity index 100% rename from test/workspace/report-invalid-scope-disables/stylelint.config.js rename to test/e2e/report-invalid-scope-disables/stylelint.config.js diff --git a/test/workspace/report-invalid-scope-disables/test.css b/test/e2e/report-invalid-scope-disables/test.css similarity index 100% rename from test/workspace/report-invalid-scope-disables/test.css rename to test/e2e/report-invalid-scope-disables/test.css diff --git a/test/workspace/report-needless-disables/.vscode/settings.json b/test/e2e/report-needless-disables/.vscode/settings.json similarity index 100% rename from test/workspace/report-needless-disables/.vscode/settings.json rename to test/e2e/report-needless-disables/.vscode/settings.json diff --git a/test/workspace/report-needless-disables/__snapshots__/index.js.snap b/test/e2e/report-needless-disables/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/report-needless-disables/__snapshots__/index.js.snap rename to test/e2e/report-needless-disables/__snapshots__/index.js.snap diff --git a/test/workspace/report-needless-disables/index.js b/test/e2e/report-needless-disables/index.js similarity index 100% rename from test/workspace/report-needless-disables/index.js rename to test/e2e/report-needless-disables/index.js diff --git a/test/workspace/report-needless-disables/stylelint.config.js b/test/e2e/report-needless-disables/stylelint.config.js similarity index 100% rename from test/workspace/report-needless-disables/stylelint.config.js rename to test/e2e/report-needless-disables/stylelint.config.js diff --git a/test/workspace/report-needless-disables/test.css b/test/e2e/report-needless-disables/test.css similarity index 100% rename from test/workspace/report-needless-disables/test.css rename to test/e2e/report-needless-disables/test.css diff --git a/test/workspace/resolve-local/.gitignore b/test/e2e/resolve-local/.gitignore similarity index 100% rename from test/workspace/resolve-local/.gitignore rename to test/e2e/resolve-local/.gitignore diff --git a/test/workspace/resolve-local/__snapshots__/index.js.snap b/test/e2e/resolve-local/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/resolve-local/__snapshots__/index.js.snap rename to test/e2e/resolve-local/__snapshots__/index.js.snap diff --git a/test/workspace/resolve-local/index.js b/test/e2e/resolve-local/index.js similarity index 100% rename from test/workspace/resolve-local/index.js rename to test/e2e/resolve-local/index.js diff --git a/test/workspace/resolve-local/node_modules/stylelint/index.js b/test/e2e/resolve-local/node_modules/stylelint/index.js similarity index 100% rename from test/workspace/resolve-local/node_modules/stylelint/index.js rename to test/e2e/resolve-local/node_modules/stylelint/index.js diff --git a/test/workspace/resolve-local/node_modules/stylelint/package.json b/test/e2e/resolve-local/node_modules/stylelint/package.json similarity index 100% rename from test/workspace/resolve-local/node_modules/stylelint/package.json rename to test/e2e/resolve-local/node_modules/stylelint/package.json diff --git a/test/workspace/resolve-local/test.css b/test/e2e/resolve-local/test.css similarity index 100% rename from test/workspace/resolve-local/test.css rename to test/e2e/resolve-local/test.css diff --git a/test/workspace/rule-doc/__snapshots__/index.js.snap b/test/e2e/rule-doc/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/rule-doc/__snapshots__/index.js.snap rename to test/e2e/rule-doc/__snapshots__/index.js.snap diff --git a/test/workspace/rule-doc/index.js b/test/e2e/rule-doc/index.js similarity index 100% rename from test/workspace/rule-doc/index.js rename to test/e2e/rule-doc/index.js diff --git a/test/workspace/rule-doc/stylelint.config.js b/test/e2e/rule-doc/stylelint.config.js similarity index 100% rename from test/workspace/rule-doc/stylelint.config.js rename to test/e2e/rule-doc/stylelint.config.js diff --git a/test/workspace/rule-doc/test-plugin.js b/test/e2e/rule-doc/test-plugin.js similarity index 100% rename from test/workspace/rule-doc/test-plugin.js rename to test/e2e/rule-doc/test-plugin.js diff --git a/test/workspace/rule-doc/test.css b/test/e2e/rule-doc/test.css similarity index 100% rename from test/workspace/rule-doc/test.css rename to test/e2e/rule-doc/test.css diff --git a/test/workspace/setup.js b/test/e2e/setup.js similarity index 84% rename from test/workspace/setup.js rename to test/e2e/setup.js index 4ab99600..843b1186 100644 --- a/test/workspace/setup.js +++ b/test/e2e/setup.js @@ -8,7 +8,7 @@ global.beforeAll(async () => { const vscodeStylelint = extensions.getExtension('stylelint.vscode-stylelint'); if (!vscodeStylelint) { - throw new Error('Unable to find stylelint extension'); + throw new Error('Unable to find Stylelint extension'); } await pWaitFor(() => vscodeStylelint.isActive, { timeout: 2000 }); diff --git a/test/workspace/stylelint-path/.vscode/settings.json b/test/e2e/stylelint-path/.vscode/settings.json similarity index 100% rename from test/workspace/stylelint-path/.vscode/settings.json rename to test/e2e/stylelint-path/.vscode/settings.json diff --git a/test/workspace/stylelint-path/__snapshots__/index.js.snap b/test/e2e/stylelint-path/__snapshots__/index.js.snap similarity index 100% rename from test/workspace/stylelint-path/__snapshots__/index.js.snap rename to test/e2e/stylelint-path/__snapshots__/index.js.snap diff --git a/test/lib/stylelint-vscode/fake-stylelint.js b/test/e2e/stylelint-path/fake-stylelint.js similarity index 100% rename from test/lib/stylelint-vscode/fake-stylelint.js rename to test/e2e/stylelint-path/fake-stylelint.js diff --git a/test/workspace/stylelint-path/index.js b/test/e2e/stylelint-path/index.js similarity index 100% rename from test/workspace/stylelint-path/index.js rename to test/e2e/stylelint-path/index.js diff --git a/test/workspace/stylelint-path/stylelint.config.js b/test/e2e/stylelint-path/stylelint.config.js similarity index 100% rename from test/workspace/stylelint-path/stylelint.config.js rename to test/e2e/stylelint-path/stylelint.config.js diff --git a/test/workspace/stylelint-path/test.css b/test/e2e/stylelint-path/test.css similarity index 100% rename from test/workspace/stylelint-path/test.css rename to test/e2e/stylelint-path/test.css diff --git a/test/workspace/utils.js b/test/e2e/utils.js similarity index 100% rename from test/workspace/utils.js rename to test/e2e/utils.js diff --git a/test/workspace/validate/.vscode/settings.json b/test/e2e/validate/.vscode/settings.json similarity index 100% rename from test/workspace/validate/.vscode/settings.json rename to test/e2e/validate/.vscode/settings.json diff --git a/test/workspace/validate/__snapshots__/index.js.snap b/test/e2e/validate/__snapshots__/index.js.snap similarity index 60% rename from test/workspace/validate/__snapshots__/index.js.snap rename to test/e2e/validate/__snapshots__/index.js.snap index 45848465..7bffb2b8 100644 --- a/test/workspace/validate/__snapshots__/index.js.snap +++ b/test/e2e/validate/__snapshots__/index.js.snap @@ -1,25 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`vscode-stylelint with "stylelint.validate" should be ignored lint and autofix on css 1`] = ` -"/* prettier-ignore */ -a { - color: red; -} -" -`; - -exports[`vscode-stylelint with "stylelint.validate" should be ignored lint and autofix on markdown 1`] = ` -"# title - -\`\`\`css -a { - color: red; -} -\`\`\` -" -`; - -exports[`vscode-stylelint with "stylelint.validate" should be ignored lint and autofix on scss 1`] = ` +exports[`vscode-stylelint with "stylelint.validate" set to ["scss"] should lint and autofix scss 1`] = ` Array [ Object { "code": "indentation", @@ -43,10 +24,29 @@ Array [ ] `; -exports[`vscode-stylelint with "stylelint.validate" should be ignored lint and autofix on scss 2`] = ` +exports[`vscode-stylelint with "stylelint.validate" set to ["scss"] should lint and autofix scss 2`] = ` "/* prettier-ignore */ a { color: red; } " `; + +exports[`vscode-stylelint with "stylelint.validate" set to ["scss"] shouldn't lint or fix css 1`] = ` +"/* prettier-ignore */ +a { + color: red; +} +" +`; + +exports[`vscode-stylelint with "stylelint.validate" set to ["scss"] shouldn't lint or fix markdown 1`] = ` +"# title + +\`\`\`css +a { + color: red; +} +\`\`\` +" +`; diff --git a/test/workspace/validate/index.js b/test/e2e/validate/index.js similarity index 89% rename from test/workspace/validate/index.js rename to test/e2e/validate/index.js index f7e916f6..5a083c1f 100644 --- a/test/workspace/validate/index.js +++ b/test/e2e/validate/index.js @@ -7,7 +7,7 @@ const { workspace, window, commands } = require('vscode'); const { normalizeDiagnostic, getStylelintDiagnostics } = require('../utils'); -describe('vscode-stylelint with "stylelint.validate"', () => { +describe('vscode-stylelint with "stylelint.validate" set to ["scss"]', () => { beforeAll(async () => { await pWaitFor( async () => { @@ -21,7 +21,7 @@ describe('vscode-stylelint with "stylelint.validate"', () => { ); }); - it('should be ignored lint and autofix on css', async () => { + it("shouldn't lint or fix css", async () => { // Open the './test.css' file. const cssDocument = await workspace.openTextDocument(path.resolve(__dirname, 'test.css')); @@ -40,7 +40,7 @@ describe('vscode-stylelint with "stylelint.validate"', () => { expect(cssDocument.getText()).toMatchSnapshot(); }); - it('should be ignored lint and autofix on scss', async () => { + it('should lint and autofix scss', async () => { // Open the './test.scss' file. const scssDocument = await workspace.openTextDocument(path.resolve(__dirname, 'test.scss')); @@ -59,7 +59,7 @@ describe('vscode-stylelint with "stylelint.validate"', () => { expect(scssDocument.getText()).toMatchSnapshot(); }); - it('should be ignored lint and autofix on markdown', async () => { + it("shouldn't lint or fix markdown", async () => { // Open the './test.md' file. const mdDocument = await workspace.openTextDocument(path.resolve(__dirname, 'test.md')); diff --git a/test/workspace/validate/stylelint.config.js b/test/e2e/validate/stylelint.config.js similarity index 100% rename from test/workspace/validate/stylelint.config.js rename to test/e2e/validate/stylelint.config.js diff --git a/test/workspace/validate/test.css b/test/e2e/validate/test.css similarity index 100% rename from test/workspace/validate/test.css rename to test/e2e/validate/test.css diff --git a/test/workspace/validate/test.md b/test/e2e/validate/test.md similarity index 100% rename from test/workspace/validate/test.md rename to test/e2e/validate/test.md diff --git a/test/workspace/validate/test.scss b/test/e2e/validate/test.scss similarity index 100% rename from test/workspace/validate/test.scss rename to test/e2e/validate/test.scss diff --git a/test/lib/jest.config.js b/test/integration/jest.config.js similarity index 100% rename from test/lib/jest.config.js rename to test/integration/jest.config.js diff --git a/test/lib/stylelint-vscode/.stylelintignore b/test/integration/stylelint-vscode/.stylelintignore similarity index 100% rename from test/lib/stylelint-vscode/.stylelintignore rename to test/integration/stylelint-vscode/.stylelintignore diff --git a/test/lib/stylelint-vscode/__snapshots__/test.js.snap b/test/integration/stylelint-vscode/__snapshots__/test.js.snap similarity index 84% rename from test/lib/stylelint-vscode/__snapshots__/test.js.snap rename to test/integration/stylelint-vscode/__snapshots__/test.js.snap index 2a2cde19..072f2aed 100644 --- a/test/lib/stylelint-vscode/__snapshots__/test.js.snap +++ b/test/integration/stylelint-vscode/__snapshots__/test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`stylelintVSCode() should be resolved with diagnostics when it lints CSS successfully 1`] = ` +exports[`StylelintRunner should be resolved with diagnostics when it lints CSS successfully 1`] = ` Array [ Object { "code": "string-quotes", @@ -43,7 +43,7 @@ Array [ ] `; -exports[`stylelintVSCode() should be resolved with diagnostics when the rules include unknown rules 1`] = ` +exports[`StylelintRunner should be resolved with diagnostics when the rules include unknown rules 1`] = ` Array [ Object { "code": "this-rule-does-not-exist", @@ -80,7 +80,7 @@ Array [ ] `; -exports[`stylelintVSCode() should be resolved with one diagnostic when the CSS is broken 1`] = ` +exports[`StylelintRunner should be resolved with one diagnostic when the CSS is broken 1`] = ` Array [ Object { "code": "CssSyntaxError", @@ -101,7 +101,7 @@ Array [ ] `; -exports[`stylelintVSCode() should check CSS syntax even if no configuration is provided 1`] = ` +exports[`StylelintRunner should check CSS syntax even if no configuration is provided 1`] = ` Array [ Object { "code": "CssSyntaxError", @@ -122,7 +122,7 @@ Array [ ] `; -exports[`stylelintVSCode() should check CSS syntax even if no rule is provided 1`] = ` +exports[`StylelintRunner should check CSS syntax even if no rule is provided 1`] = ` Array [ Object { "code": "CssSyntaxError", @@ -143,12 +143,12 @@ Array [ ] `; -exports[`stylelintVSCode() should reject with a reason when it takes incorrect options 1`] = ` +exports[`StylelintRunner should reject with a reason when it takes incorrect options 1`] = ` "Invalid option name \\"bar\\" for rule \\"at-rule-empty-line-before\\" Invalid option value \\"foo\\" for rule \\"color-hex-case\\"" `; -exports[`stylelintVSCode() should support \`processors\` option 1`] = ` +exports[`StylelintRunner should support \`processors\` option 1`] = ` Array [ Object { "code": "CssSyntaxError", @@ -169,7 +169,7 @@ Array [ ] `; -exports[`stylelintVSCode() should support CSS-in-JS with customSyntax 1`] = ` +exports[`StylelintRunner should support CSS-in-JS with customSyntax 1`] = ` Array [ Object { "code": "font-weight-notation", @@ -212,7 +212,7 @@ Array [ ] `; -exports[`stylelintVSCode() with a configuration file should adhere to configuration file settings 1`] = ` +exports[`StylelintRunner with a configuration file should adhere to configuration file settings 1`] = ` Array [ Object { "code": "length-zero-no-unit", @@ -236,7 +236,7 @@ Array [ ] `; -exports[`stylelintVSCode() with autofix autofix should work if there are errors that cannot be autofixed 1`] = ` +exports[`StylelintRunner with autofix autofix should work if there are errors that cannot be autofixed 1`] = ` Object { "diagnostics": Array [ Object { @@ -268,7 +268,7 @@ unknown { } `; -exports[`stylelintVSCode() with autofix autofix should work if there is syntax errors in css 1`] = ` +exports[`StylelintRunner with autofix autofix should work if there is syntax errors in css 1`] = ` " .a { width: 100%; @@ -277,14 +277,14 @@ exports[`stylelintVSCode() with autofix autofix should work if there is syntax e " `; -exports[`stylelintVSCode() with autofix autofix should work properly if configs are defined 1`] = ` +exports[`StylelintRunner with autofix autofix should work properly if configs are defined 1`] = ` "a { color:red; }" `; -exports[`stylelintVSCode() with customSyntax autofix should work properly if customSyntax is defined 1`] = ` +exports[`StylelintRunner with customSyntax autofix should work properly if customSyntax is defined 1`] = ` Object { "diagnostics": Array [], "output": "a @@ -292,7 +292,7 @@ Object { } `; -exports[`stylelintVSCode() with customSyntax should work properly if customSyntax is defined 1`] = ` +exports[`StylelintRunner with customSyntax should work properly if customSyntax is defined 1`] = ` Object { "diagnostics": Array [ Object { @@ -318,7 +318,7 @@ Object { } `; -exports[`stylelintVSCode() with reportInvalidScopeDisables should work properly if reportInvalidScopeDisables is true 1`] = ` +exports[`StylelintRunner with reportInvalidScopeDisables should work properly if reportInvalidScopeDisables is true 1`] = ` Object { "diagnostics": Array [ Object { @@ -373,7 +373,7 @@ Object { } `; -exports[`stylelintVSCode() with reportNeedlessDisables should work properly if reportNeedlessDisables is true 1`] = ` +exports[`StylelintRunner with reportNeedlessDisables should work properly if reportNeedlessDisables is true 1`] = ` Object { "diagnostics": Array [ Object { @@ -463,7 +463,7 @@ Object { } `; -exports[`stylelintVSCode() with stylelintPath should work properly if custom path is defined in stylelintPath 1`] = ` +exports[`StylelintRunner with stylelintPath should work properly if custom path is defined in stylelintPath 1`] = ` Object { "diagnostics": Array [ Object { @@ -486,7 +486,7 @@ Object { } `; -exports[`stylelintVSCode() with stylelintPath should work properly if stylelintPath is defined 1`] = ` +exports[`StylelintRunner with stylelintPath should work properly if stylelintPath is defined 1`] = ` Object { "diagnostics": Array [ Object { diff --git a/test/workspace/stylelint-path/fake-stylelint.js b/test/integration/stylelint-vscode/fake-stylelint.js similarity index 100% rename from test/workspace/stylelint-path/fake-stylelint.js rename to test/integration/stylelint-vscode/fake-stylelint.js diff --git a/test/lib/stylelint-vscode/no-unknown.config.js b/test/integration/stylelint-vscode/no-unknown.config.js similarity index 100% rename from test/lib/stylelint-vscode/no-unknown.config.js rename to test/integration/stylelint-vscode/no-unknown.config.js diff --git a/test/lib/stylelint-vscode/stylelint.config.js b/test/integration/stylelint-vscode/stylelint.config.js similarity index 100% rename from test/lib/stylelint-vscode/stylelint.config.js rename to test/integration/stylelint-vscode/stylelint.config.js diff --git a/test/lib/stylelint-vscode/test.js b/test/integration/stylelint-vscode/test.js similarity index 72% rename from test/lib/stylelint-vscode/test.js rename to test/integration/stylelint-vscode/test.js index 70b52176..38718547 100644 --- a/test/lib/stylelint-vscode/test.js +++ b/test/integration/stylelint-vscode/test.js @@ -4,7 +4,7 @@ const { join, resolve } = require('path'); const { pathToFileURL } = require('url'); const createTextDocument = require('vscode-languageserver').TextDocument.create; -const stylelintVSCode = require('../../../src/stylelint-vscode'); +const { StylelintRunner } = require('../../../src/utils/stylelint'); /** * @param {string | null} uri @@ -19,10 +19,11 @@ const createDocument = (uri, languageId, contents) => contents, ); -describe('stylelintVSCode()', () => { +describe('StylelintRunner', () => { test('should be resolved with diagnostics when it lints CSS successfully', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument(null, 'css', ' a[id="id"]{}'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument(null, 'css', ' a[id="id"]{}'), { config: { rules: { 'string-quotes': ['single', { severity: 'warning' }], @@ -36,7 +37,8 @@ describe('stylelintVSCode()', () => { test('should be resolved with an empty array when no errors and warnings are reported', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument(null, 'scss', ''), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument(null, 'scss', ''), { config: { customSyntax: 'postcss-scss', rules: { indentation: [2] }, @@ -48,8 +50,9 @@ describe('stylelintVSCode()', () => { test('should be resolved with one diagnostic when the CSS is broken', async () => { expect.assertions(1); + const runner = new StylelintRunner(); // TODO: Restore once postcss-markdown is PostCSS 8 compatible - // const result = await stylelintVSCode( + // const result = await runner.lintDocument( // createDocument( // 'markdown.md', // 'markdown', @@ -71,25 +74,29 @@ describe('stylelintVSCode()', () => { // }, // }, // ); - const result = await stylelintVSCode(createDocument('scss.scss', 'scss', ' a{\n'), { - config: { - customSyntax: 'postcss-scss', - rules: { - indentation: ['tab'], + const result = await runner.lintDocument( + createDocument('scss.scss', 'scss', ' a{\n'), + { + config: { + customSyntax: 'postcss-scss', + rules: { + indentation: ['tab'], + }, }, }, - }); + ); expect(result.diagnostics).toMatchSnapshot(); }); test('should be resolved even if no configs are defined', async () => { expect.assertions(1); + const runner = new StylelintRunner(); // TODO: Restore once postcss-html is PostCSS 8 compatible - // const result = await stylelintVSCode(createDocument(null, 'plaintext', ''), { + // const result = await runner.lintDocument(createDocument(null, 'plaintext', ''), { // customSyntax: 'postcss-html', // }); - const result = await stylelintVSCode(createDocument(null, 'plaintext', 'a{}'), { + const result = await runner.lintDocument(createDocument(null, 'plaintext', 'a{}'), { customSyntax: 'postcss-scss', }); @@ -98,7 +105,8 @@ describe('stylelintVSCode()', () => { test('should support `.stylelintignore`.', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument('listed-in-stylelintignore.css', 'css', '}'), { ignorePath: require.resolve('./.stylelintignore'), @@ -110,7 +118,8 @@ describe('stylelintVSCode()', () => { test('should support CSS-in-JS with customSyntax', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( null, 'javascript', @@ -134,7 +143,8 @@ font: normal test('should set `codeFilename` option from a TextDocument', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'should-be-ignored.xml', 'xml', @@ -157,7 +167,8 @@ a { color: #000 } test('should support `processors` option', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument('processors.tsx', 'typescriptreact', 'styled.p`"`'), { config: { @@ -172,18 +183,22 @@ a { color: #000 } test('should check CSS syntax even if no configuration is provided', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('unclosed.css', 'css', 'a{color:rgba(}')); + const runner = new StylelintRunner(); + const result = await runner.lintDocument( + createDocument('unclosed.css', 'css', 'a{color:rgba(}'), + ); expect(result.diagnostics).toMatchSnapshot(); }); test('should check CSS syntax even if no rule is provided', async () => { expect.assertions(1); + const runner = new StylelintRunner(); // TODO: Restore once postcss-html is PostCSS 8 compatible - // const result = await stylelintVSCode(createDocument('at.xsl', 'xsl', ''), { + // const result = await runner.lintDocument(createDocument('at.xsl', 'xsl', ''), { // customSyntax: 'postcss-html', // }); - const result = await stylelintVSCode(createDocument('at.scss', 'scss', '@'), { + const result = await runner.lintDocument(createDocument('at.scss', 'scss', '@'), { customSyntax: 'postcss-scss', }); @@ -192,7 +207,8 @@ a { color: #000 } test('should be resolved even if no rules are defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('no-rules.css', 'css', 'a{}'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('no-rules.css', 'css', 'a{}'), { config: {}, }); @@ -201,7 +217,8 @@ a { color: #000 } test('should reject with a reason when it takes incorrect options', async () => { expect.assertions(1); - const promise = stylelintVSCode( + const runner = new StylelintRunner(); + const promise = runner.lintDocument( createDocument('invalid-options.css', 'css', ' a[id="id"]{}'), { config: { @@ -219,7 +236,8 @@ a { color: #000 } test('should be resolved with diagnostics when the rules include unknown rules', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('unknown-rule.css', 'css', 'b{}'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('unknown-rule.css', 'css', 'b{}'), { config: { rules: { 'this-rule-does-not-exist': 1, @@ -232,10 +250,11 @@ a { color: #000 } }); }); -describe('stylelintVSCode() with a configuration file', () => { +describe('StylelintRunner with a configuration file', () => { test('should adhere to configuration file settings', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( join(__dirname, 'has-config-file.tsx'), 'typescriptreact', @@ -254,10 +273,11 @@ const what: string = "is this"; }); }); -describe('stylelintVSCode() with autofix', () => { +describe('StylelintRunner with autofix', () => { test('autofix should work properly if configs are defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument(null, 'css', 'a\n{\ncolor:red;\n}'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument(null, 'css', 'a\n{\ncolor:red;\n}'), { config: { rules: { indentation: [2] } }, fix: true, }); @@ -267,7 +287,8 @@ describe('stylelintVSCode() with autofix', () => { test('autofix should only work properly for syntax errors if no rules are defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('no-rules.css', 'css', 'a {'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('no-rules.css', 'css', 'a {'), { config: {}, fix: true, }); @@ -277,7 +298,8 @@ describe('stylelintVSCode() with autofix', () => { test('JS file autofix should not change the content if no rules are defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('no-rules.js', 'javascript', '"a"'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('no-rules.js', 'javascript', '"a"'), { customSyntax: '@stylelint/postcss-css-in-js', config: {}, fix: true, @@ -288,7 +310,8 @@ describe('stylelintVSCode() with autofix', () => { test('autofix should ignore if the file matches the ignoreFiles', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument('should-be-ignored.js', 'javascript', '"a"'), { customSyntax: '@stylelint/postcss-css-in-js', @@ -305,7 +328,8 @@ describe('stylelintVSCode() with autofix', () => { test('autofix should work if there is syntax errors in css', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'test.css', 'css', @@ -327,7 +351,8 @@ describe('stylelintVSCode() with autofix', () => { test('autofix should ignore if there is syntax errors in scss', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'test.scss', 'scss', @@ -339,6 +364,7 @@ describe('stylelintVSCode() with autofix', () => { `, ), { + customSyntax: 'postcss-scss', config: { rules: {} }, fix: true, }, @@ -348,7 +374,8 @@ describe('stylelintVSCode() with autofix', () => { }); test('autofix should work if there are errors that cannot be autofixed', async () => { - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'test.css', 'css', @@ -374,10 +401,11 @@ unknown { }); }); -describe('stylelintVSCode() with customSyntax', () => { +describe('StylelintRunner with customSyntax', () => { test('should work properly if customSyntax is defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('test.css', 'css', 'a\n color:red'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('test.css', 'css', 'a\n color:red'), { config: { rules: { indentation: [2] } }, customSyntax: 'postcss-sass', }); @@ -387,7 +415,8 @@ describe('stylelintVSCode() with customSyntax', () => { test('autofix should work properly if customSyntax is defined', async () => { expect.assertions(1); - const result = await stylelintVSCode(createDocument('test.css', 'css', 'a\n color:red'), { + const runner = new StylelintRunner(); + const result = await runner.lintDocument(createDocument('test.css', 'css', 'a\n color:red'), { config: { rules: { indentation: [2] } }, customSyntax: 'postcss-sass', fix: true, @@ -397,10 +426,11 @@ describe('stylelintVSCode() with customSyntax', () => { }); }); -describe('stylelintVSCode() with reportNeedlessDisables', () => { +describe('StylelintRunner with reportNeedlessDisables', () => { test('should work properly if reportNeedlessDisables is true', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'test.css', 'css', @@ -436,10 +466,11 @@ describe('stylelintVSCode() with reportNeedlessDisables', () => { }); }); -describe('stylelintVSCode() with reportInvalidScopeDisables', () => { +describe('StylelintRunner with reportInvalidScopeDisables', () => { test('should work properly if reportInvalidScopeDisables is true', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument( 'test.css', 'css', @@ -469,10 +500,11 @@ describe('stylelintVSCode() with reportInvalidScopeDisables', () => { }); }); -describe('stylelintVSCode() with stylelintPath', () => { +describe('StylelintRunner with stylelintPath', () => { test('should work properly if stylelintPath is defined', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument('test.css', 'css', 'a{\n color:red}'), { config: { rules: { indentation: [2] } }, @@ -487,7 +519,8 @@ describe('stylelintVSCode() with stylelintPath', () => { test('should work properly if custom path is defined in stylelintPath', async () => { expect.assertions(1); - const result = await stylelintVSCode( + const runner = new StylelintRunner(); + const result = await runner.lintDocument( createDocument('test.css', 'css', 'a{\n color:red}'), { config: { rules: { indentation: [2] } }, diff --git a/test/lib/warnings-to-diagnostics/__snapshots__/test.js.snap b/test/lib/warnings-to-diagnostics/__snapshots__/test.js.snap deleted file mode 100644 index 056d7c42..00000000 --- a/test/lib/warnings-to-diagnostics/__snapshots__/test.js.snap +++ /dev/null @@ -1,39 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`stylelintWarningToVscodeDiagnostic() should convert a stylelint warning into a VS Code diagnostic and consider severity level 1`] = ` -Object { - "code": "color-hex-case", - "message": "Expected \\"#AAA\\" to be \\"#aaa\\" (color-hex-case)", - "range": Object { - "end": Object { - "character": 11, - "line": 1, - }, - "start": Object { - "character": 11, - "line": 1, - }, - }, - "severity": 1, - "source": "stylelint", -} -`; - -exports[`stylelintWarningToVscodeDiagnostic() should convert a stylelint warning into a VS Code diagnostic and consider severity level 2`] = ` -Object { - "code": "color-hex-length", - "message": "Expected \\"#bbbbbb\\" to be \\"#bbb\\" (color-hex-length)", - "range": Object { - "end": Object { - "character": 18, - "line": 2, - }, - "start": Object { - "character": 18, - "line": 2, - }, - }, - "severity": 2, - "source": "stylelint", -} -`; diff --git a/test/lib/warnings-to-diagnostics/test.js b/test/lib/warnings-to-diagnostics/test.js deleted file mode 100644 index f9f35f70..00000000 --- a/test/lib/warnings-to-diagnostics/test.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -const { lint } = require('stylelint'); - -const fn = require('../../../src/warnings-to-diagnostics'); - -describe('stylelintWarningToVscodeDiagnostic()', () => { - test('should convert a stylelint warning into a VS Code diagnostic and consider severity level', async () => { - expect.assertions(2); - const { - results: [{ warnings }], - } = await lint({ - code: `a { - color: #AAA; - border-color: #bbbbbb; - }`, - config: { - rules: { - 'color-hex-case': ['lower'], - 'color-hex-length': ['short', { severity: 'warning' }], - }, - }, - }); - - expect(fn(warnings[0])).toMatchSnapshot(); - expect(fn(warnings[1])).toMatchSnapshot(); - }); -}); diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000..6e2282b6 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "composite": true, + "target": "ES2020", + "module": "commonjs", + "lib": ["es2020"], + "allowJs": true, + "checkJs": true, + "noEmit": true, + "strict": true, + "noImplicitThis": true, + "noImplicitAny": true, + "alwaysStrict": true, + "esModuleInterop": true, + "resolveJsonModule": true + } +} diff --git a/tsconfig.json b/tsconfig.json index 670cc4bd..80eb93dd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,9 @@ { - "compilerOptions": { - "target": "ES2020", - "module": "commonjs", - "lib": ["es2020"], - "allowJs": true, - "checkJs": true, - "noEmit": true, - "strict": true, - "noImplicitThis": true, - "noImplicitAny": true, - "alwaysStrict": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "typeRoots": ["./types", "./node_modules/@types"] - }, - "include": ["src/**/*", "test/**/*", "__mocks__/**/*", "scripts/**/*", "types/*.d.ts"], - "exclude": ["**/coverage"] + "include": [], + "files": [], + "references": [ + { "path": "./tsconfig.src.json" }, + { "path": "./tsconfig.scripts.json" }, + { "path": "./tsconfig.test.json" } + ] } diff --git a/tsconfig.scripts.json b/tsconfig.scripts.json new file mode 100644 index 00000000..eee270a0 --- /dev/null +++ b/tsconfig.scripts.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "typeRoots": ["./types", "./node_modules/@types"], + "types": ["node", "babel__core"] + }, + "include": ["*.js", "package.json", "scripts/**/*"], + "exclude": ["**/coverage"] +} diff --git a/tsconfig.src.json b/tsconfig.src.json new file mode 100644 index 00000000..20908adb --- /dev/null +++ b/tsconfig.src.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "typeRoots": ["./types", "./node_modules/@types"], + "types": ["node", "semver", "vscode", "path-is-inside"] + }, + "include": ["src/**/*", "types/*.d.ts"], + "exclude": ["**/coverage", "**/__tests__", "**/__mocks__", "types/tests.d.ts"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000..35513cbc --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "typeRoots": ["./types", "./node_modules/@types"] + }, + "include": ["src/**/*", "test/**/*", "__mocks__/**/*", "types/*.d.ts"], + "exclude": ["**/coverage"] +} diff --git a/types/imports.d.ts b/types/imports.d.ts index 5d3ddb05..2346c8de 100644 --- a/types/imports.d.ts +++ b/types/imports.d.ts @@ -10,10 +10,19 @@ export import vscode = vscode; import * as vscodeLanguageServer from 'vscode-languageserver'; export import vscodeLanguageServer = vscodeLanguageServer; +import * as vscodeLanguageServerProtocol from 'vscode-languageserver-protocol'; +export import vscodeLanguageServerProtocol = vscodeLanguageServerProtocol; + import * as vscodeLanguageServerTextDocument from 'vscode-languageserver-textdocument'; export import vscodeLanguageServerTextDocument = vscodeLanguageServerTextDocument; import * as vscodeLanguageServerTypes from 'vscode-languageserver-types'; export import vscodeLanguageServerTypes = vscodeLanguageServerTypes; +import * as winston from 'winston'; +export import winston = winston; + +import * as winstonTransport from 'winston-transport'; +export import winstonTransport = winstonTransport; + export as namespace imports; diff --git a/types/index.d.ts b/types/index.d.ts index 2b89c103..43d4c638 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -3,96 +3,66 @@ import postcss = imports.postcss; import stylelint = imports.stylelint; import vscode = imports.vscode; import vscodeLanguageServer = imports.vscodeLanguageServer; +import vscodeLanguageServerProtocol = imports.vscodeLanguageServerProtocol; import vscodeLanguageServerTextDocument = imports.vscodeLanguageServerTextDocument; import vscodeLanguageServerTypes = imports.vscodeLanguageServerTypes; +import winston = imports.winston; +import winstonTransport = imports.winstonTransport; /** * Language Server Protocol and VS Code language server types. */ declare namespace lsp { - export import CodeDescription = vscodeLanguageServer.CodeDescription; - export import CompletionItem = vscodeLanguageServer.CompletionItem; + export import CodeDescription = vscodeLanguageServerTypes.CodeDescription; + export import CompletionItem = vscodeLanguageServerTypes.CompletionItem; export import CompletionParams = vscodeLanguageServer.CompletionParams; export import Connection = vscodeLanguageServer.Connection; - export import Diagnostic = vscodeLanguageServer.Diagnostic; - export import DiagnosticRelatedInformation = vscodeLanguageServer.DiagnosticRelatedInformation; - export import DiagnosticSeverity = vscodeLanguageServer.DiagnosticSeverity; + export import Diagnostic = vscodeLanguageServerTypes.Diagnostic; + export import DiagnosticRelatedInformation = vscodeLanguageServerTypes.DiagnosticRelatedInformation; + export import DiagnosticSeverity = vscodeLanguageServerTypes.DiagnosticSeverity; + export import DidChangeConfigurationNotification = vscodeLanguageServerProtocol.DidChangeConfigurationNotification; + export import DidChangeConfigurationParams = vscodeLanguageServerProtocol.DidChangeConfigurationParams; export import Disposable = vscodeLanguageServer.Disposable; - export import DocumentUri = vscodeLanguageServer.DocumentUri; - export import FormattingOptions = vscodeLanguageServer.FormattingOptions; + export import DocumentUri = vscodeLanguageServerTypes.DocumentUri; + export import FormattingOptions = vscodeLanguageServerTypes.FormattingOptions; + export import InitializeParams = vscodeLanguageServer.InitializeParams; + export import InitializeResult = vscodeLanguageServer.InitializeResult; + export import Position = vscodeLanguageServerTypes.Position; + export import Range = vscodeLanguageServerTypes.Range; + export import RemoteConsole = vscodeLanguageServer.RemoteConsole; export import TextDocument = vscodeLanguageServerTextDocument.TextDocument; + export import TextDocuments = vscodeLanguageServer.TextDocuments; + export import TextEdit = vscodeLanguageServerTypes.TextEdit; export import URI = vscodeLanguageServerTypes.URI; } +/** + * Makes all properties of type `T` optional except for those in `K`. + */ type OptionalExcept, K extends keyof T> = Pick & Partial>; /** - * Types used in tests. - */ -declare namespace tests { - type CodePart = { - code?: lsp.Diagnostic['code']; - codeDescription?: lsp.CodeDescription; - }; - type Position = OptionalExcept; - type Range = { start: Position; end?: Position }; - type DiagnosticRelatedInformation = { - location: { range: Range; uri: string }; - message: string; - }; - type Diagnostic = Omit & { - range: Range; - relatedInformation?: DiagnosticRelatedInformation[]; - }; - - namespace mocks { - type FileSystemTree = { [path: string]: FileSystemEntry }; - type FileSystemEntry = string | FileSystemTree | Error | undefined; - type FSPromisesModule = typeof import('fs/promises') & { - __mockFileSystem(tree: FileSystemTree): void; - }; - - interface ChildProcessWithoutNullStreams { - on(event: string, listener: (...args: any[]) => void): this; - on(event: 'exit', listener: (code: number, signal?: string) => void): this; - on(event: 'error', listener: (err: Error) => void): this; - removeAllListeners(event?: string): this; - kill(signal?: string): void; - stdout: NodeJS.ReadableStream; - stderr: NodeJS.ReadableStream; - } - - type ChildProcessModule = typeof import('child_process') & { - __setDelay(exitDelay?: number, stdoutDelay?: number, stderrDelay?: number): void; - __mockProcess( - command: string, - args: string[], - exitCode: number | NodeJS.Signals, - stdout?: string, - stderr?: string, - ): void; - __resetMockedProcesses(): void; - }; - - type OSModule = typeof import('os') & { - __mockPlatform(platform: NodeJS.Platform): void; - }; - - type PathModule = typeof import('path') & { - __mockPlatform(platform: 'posix' | 'win32'): void; - }; - - type Processes = typeof import('../src/utils/processes') & { - runProcessFindLine: jest.Mock; - __mockProcess(command: string, args: string[], lines: string[], exitCode?: number): void; - __resetMockedProcesses(): void; - }; - } -} + * Makes all properties of type `T` required except for those in `K`. + */ +type RequiredExcept, K extends keyof T> = Pick> & + Required>; + +/** + * Extracts keys from a type `T` the values of which are type `V`. + */ +type ExtractKeysOfValueType = { + [K in keyof T]-?: T[K] extends V ? K : never; +}[keyof T]; +/** + * Package manager identifiers. + */ type PackageManager = 'npm' | 'yarn' | 'pnpm'; +/** + * An invalid option error. + */ type InvalidOptionError = Error & { reasons: string[] }; // TODO: Create type upstream @@ -102,32 +72,323 @@ type InvalidOptionError = Error & { reasons: string[] }; */ type ConfigurationError = Error & { code: 78 }; -type RuleDocUrlProvider = (rule: string) => lsp.URI | null | undefined; - +/** + * A tracer function that can be used to log messages. + */ type TracerFn = (message: string, verbose?: string) => void; +/** + * Global `node_modules` path resolver. + */ type GlobalPathResolver = { + /** + * Resolves the global `node_modules` path for the given package manager. + * When a path cannot be resolved, returns `undefined`. Traces resolution + * using the given tracer if one is provided. + * + * Paths are cached in the resolver on the first successful resolution. + * + * @example + * ```js + * const pnpmGlobalPath = await resolver.resolve( + * 'pnpm', + * message => connection && connection.tracer.log(message) + * ); + * ``` + * @param {trace} + */ resolve: (packageManager: PackageManager, trace?: TracerFn) => Promise; }; +/** + * The global `node_modules` path resolver cache. + */ type GlobalPathResolverCache = { [packageManager: string]: string | undefined; }; -type DisableReport = { - diagnostic: lsp.Diagnostic; - range: stylelint.DisableReportRange; -}; +/** + * Sisable directive comment types. + */ +type DisableType = 'stylelint-disable' | 'stylelint-disable-line' | 'stylelint-disable-next-line'; -type StylelintVSCodeOptions = { - connection?: lsp.Connection; +/** + * Stylelint runner. + */ +type StylelintRunner = import('../src/utils/stylelint/stylelint-runner').StylelintRunner; + +/** + * The vscode-stylelint extension options. Overrides any options in the + * workspace Stylelint configuration. + */ +type ExtensionOptions = { + config?: stylelint.Config | null; + configBasedir?: string; + configFile?: string; + customSyntax?: string; + ignoreDisables?: boolean; packageManager?: PackageManager; + reportInvalidScopeDisables?: boolean; + reportNeedlessDisables?: boolean; + snippet?: string[]; stylelintPath?: string; + validate?: string[]; }; -type StylelintVSCodeResult = { +/** + * Options for resolving the Stylelint package. + */ +type ResolverOptions = Pick; + +/** + * Diagnostics for a lint run. + */ +type LintDiagnostics = { + /** + * The diagnostics, each corresponding to a warning or error emitted by + * Stylelint. + */ diagnostics: lsp.Diagnostic[]; + + /** + * Raw output from Stylelint, if any. + */ output?: string; - needlessDisables?: DisableReport[]; - invalidScopeDisables?: DisableReport[]; +}; + +/** + * Stylelint package resolution result. + */ +type StylelintResolutionResult = { + stylelint: stylelint.PublicApi; + resolvedPath: string; +}; + +/** + * Parameters for the {@link LanguageServerModule.onDidChangeValidateLanguages} + * event. + */ +interface DidChangeValidateLanguagesParams { + /** + * IDs for the languages that should be validated. + */ + languages: Set; + + /** + * IDs for the languages that should no longer be validated. + */ + removedLanguages: Set; +} + +/** + * Parameters for the {@link LanguageServerModule.onDidChangeConfiguration} + * event. + * + * Note: This is not the same as {@link lsp.DidChangeConfigurationParams}, which + * is used for the {@link lsp.DidChangeConfigurationNotification}. + */ +interface DidChangeConfigurationParams { + settings: LanguageServerOptions; +} + +/** + * A language server module. + */ +interface LanguageServerModule { + /** + * Handler called when the server is initializing. + */ + onInitialize?: (params: lsp.InitializeParams) => Partial | undefined | void; + + /** + * Handler called after the language server finishes registering handlers + * with the connection. + */ + onDidRegisterHandlers?: () => void; + + /** + * Handler called after the language server has finished receiving, parsing, + * and setting updated configuration. + */ + onDidChangeConfiguration?: (params: DidChangeConfigurationParams) => void; + + /** + * Handler called after the languages for which documents should be + * validated have changed. + */ + onDidChangeValidateLanguages?: (params: DidChangeValidateLanguagesParams) => void; + + [key: string | symbol]: any; +} + +/** + * A language server module class. + */ +interface LanguageServerModuleConstructor { + /** + * The module's ID, used to identify the module in the language server's + * internal state and when logging. Should be a unique, short, lowercase + * string. + */ + id: string; + new (params: LanguageServerModuleConstructorParameters): LanguageServerModule; +} + +/** + * Parameters for the {@link LanguageServerModuleConstructor} constructor. + */ +type LanguageServerModuleConstructorParameters = { + context: LanguageServerContext; + logger?: winston.Logger; +}; + +/** + * Language server event handler names. + */ +type LanguageServerHandlers = ExtractKeysOfValueType; + +/** + * Parameters for language server event handlers, keyed by the handler name. + */ +type LanguageServerHandlerParameters = { + [key in LanguageServerHandlers]: Parameters[key]>; +}; + +/** + * Return types for language server event handlers, keyed by the handler name. + */ +type LanguageServerHandlerReturnValues = { + [key in LanguageServerHandlers]: ReturnType[key]>; +}; + +/** + * Language server constructor parameters. + */ +type LanguageServerConstructorParameters = { + /** + * The language server connection. + */ + connection: lsp.Connection; + + /** + * The logger to use. + */ + logger?: winston.Logger; + + /** + * The modules to load. + */ + modules?: LanguageServerModuleConstructor[]; +}; + +/** + * Language server options. + */ +type LanguageServerOptions = RequiredExcept< + ExtensionOptions, + 'packageManager' | 'snippet' | 'validate' +>; + +/** + * Context shared between the language server and its modules. + */ +interface LanguageServerContext { + /** + * The language server connection. + */ + connection: lsp.Connection; + + /** + * The text document manager. + */ + documents: lsp.TextDocuments; + + /** + * The current language server options. + */ + options: LanguageServerOptions; + + /** + * The runner with which to run Stylelint. + */ + runner: StylelintRunner; + + /** + * Displays the given error in the client using the language server + * connection. + * @param error The error to display. + */ + displayError(error: unknown): void; + + /** + * Returns the module with the given ID if it exists. + * @param id The ID of the module to return. + */ + getModule(id: string): LanguageServerModule | undefined; + + /** + * Lints a document using Stylelint and returns fix text edits. + * @param document The document to get text edits for. + * @param linterOptions Options to pass to the linter. Overridden by the + * language server options. + */ + getFixes( + document: lsp.TextDocument, + linterOptions?: stylelint.LinterOptions, + ): Promise; + + /** + * Lints a document using Stylelint and returns diagnostics. + * @param document The document to lint. + * @param linterOptions Options to pass to the linter. Overridden by the + * language server options. + */ + lintDocument( + document: lsp.TextDocument, + linterOptions?: Partial, + ): Promise; + + /** + * Resolves the Stylelint package to be used for the given document. + * @param document The document to resolve the package for. + */ + resolveStylelint(document: lsp.TextDocument): Promise; +} + +/** + * Language server log transport options. + */ +type LanguageServerTransportOptions = winstonTransport.TransportStreamOptions & { + connection: lsp.Connection; +}; + +/** + * Language server log formatter constructor. + */ +type LanguageServerFormatterConstructor = { + new (options: LanguageServerFormatterOptions): LanguageServerFormatter; +}; + +/** + * Language server log formatter. + */ +type LanguageServerFormatter = winston.Logform.Format & { + /** + * Formats a log object. + * @param info The log object to format. + */ + transform(info: winston.Logform.TransformableInfo): winston.Logform.TransformableInfo; + + /** + * The options used to format the log object. + */ + options: LanguageServerFormatterOptions; +}; + +/** + * Language server log formatter options. + */ +type LanguageServerFormatterOptions = { + connection: lsp.Connection; + preferredKeyOrder?: string[]; }; diff --git a/types/tests.d.ts b/types/tests.d.ts new file mode 100644 index 00000000..3eff635f --- /dev/null +++ b/types/tests.d.ts @@ -0,0 +1,81 @@ +/** + * Types used in tests. + */ +declare namespace tests { + type CodePart = { + code?: lsp.Diagnostic['code']; + codeDescription?: lsp.CodeDescription; + }; + type Position = OptionalExcept; + type Range = { start: Position; end?: Position }; + type DiagnosticRelatedInformation = { + location: { range: Range; uri: string }; + message: string; + }; + type Diagnostic = Omit & { + range: Range; + relatedInformation?: DiagnosticRelatedInformation[]; + }; + + namespace mocks { + type FileSystemTree = { [path: string]: FileSystemEntry }; + type FileSystemEntry = string | FileSystemTree | Error | undefined; + type FSPromisesModule = jest.Mocked & { + __mockFileSystem(tree: FileSystemTree): void; + }; + + interface ChildProcessWithoutNullStreams { + on(event: string, listener: (...args: any[]) => void): this; + on(event: 'exit', listener: (code: number, signal?: string) => void): this; + on(event: 'error', listener: (err: Error) => void): this; + removeAllListeners(event?: string): this; + kill(signal?: string): void; + stdout: NodeJS.ReadableStream; + stderr: NodeJS.ReadableStream; + } + + type ChildProcessModule = jest.Mocked & { + __setDelay(exitDelay?: number, stdoutDelay?: number, stderrDelay?: number): void; + __mockProcess( + command: string, + args: string[], + exitCode: number | NodeJS.Signals, + stdout?: string, + stderr?: string, + ): void; + __resetMockedProcesses(): void; + }; + + type OSModule = jest.Mocked & { + __mockPlatform(platform: NodeJS.Platform): void; + }; + + type PathModule = jest.Mocked & { + __mockPlatform(platform?: 'posix' | 'win32'): void; + }; + + namespace VSCodeLanguageServerModule { + type Node = jest.Mocked & { + Files: { + __mockResolution: ( + packageName: string, + resolver: (globalModulesPath?: string, cwd?: string, trace?: TracerFn) => any, + ) => void; + __resetMockedResolutions: () => void; + }; + }; + } + + type GlobalPathResolver = jest.Mocked< + typeof import('../src/utils/packages/global-path-resolver') + > & { + __mockPath: (packageManager: PackageManager, path: string) => void; + __resetMockedPaths: () => void; + }; + + type Processes = jest.Mocked & { + __mockProcess(command: string, args: string[], lines: string[], exitCode?: number): void; + __resetMockedProcesses(): void; + }; + } +}