diff --git a/.github/workflows/code-scanning.yml b/.github/workflows/code-scanning.yml index ff827220a1..3f811bc964 100644 --- a/.github/workflows/code-scanning.yml +++ b/.github/workflows/code-scanning.yml @@ -27,6 +27,7 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@v1 + # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java diff --git a/CHANGELOG.md b/CHANGELOG.md index f31248903d..6be16ab022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,52 @@ All notable changes to this project are documented in this file. ## Head +- Fixed: double-slash disable comments when followed by another comment ([#4913](https://github.com/stylelint/stylelint/pull/4913)). + +## 13.7.0 + +- Deprecated: `*-blacklist`, `*-requirelist` and `*-whitelist` rules in favour of the new `*-disallowed-list`, `*-required-list` and `*-allowed-list` ones ([#4845](https://github.com/stylelint/stylelint/pull/4845)): + - `at-rule-blacklist`. Use `at-rule-disallowed-list` instead. + - `at-rule-property-requirelist`. Use `at-rule-property-required-list` instead. + - `at-rule-whitelist`. Use `at-rule-allowed-list` instead. + - `comment-word-blacklist`. Use `comment-word-disallowed-list` instead. + - `declaration-property-unit-blacklist`. Use `declaration-property-unit-disallowed-list` instead. + - `declaration-property-unit-whitelist`. Use `declaration-property-unit-allowed-list` instead. + - `declaration-property-value-blacklist`. Use `declaration-property-value-disallowed-list` instead. + - `declaration-property-value-whitelist`. Use `declaration-property-value-allowed-list` instead. + - `function-blacklist`. Use `function-disallowed-list` instead. + - `function-url-scheme-blacklist`. Use `function-url-scheme-disallowed-list` instead. + - `function-url-scheme-whitelist`. Use `function-url-scheme-allowed-list` instead. + - `function-whitelist`. Use `function-allowed-list` instead. + - `media-feature-name-blacklist`. Use `media-feature-name-disallowed-list` instead. + - `media-feature-name-value-whitelist`. Use `media-feature-name-value-allowed-list` instead. + - `media-feature-name-whitelist`. Use `media-feature-name-allowed-list` instead. + - `property-blacklist`. Use `property-disallowed-list` instead. + - `property-whitelist`. Use `property-allowed-list` instead. + - `selector-attribute-operator-blacklist`. Use `selector-attribute-operator-disallowed-list` instead. + - `selector-attribute-operator-whitelist`. Use `selector-attribute-operator-allowed-list` instead. + - `selector-combinator-blacklist`. Use `selector-combinator-disallowed-list` instead. + - `selector-combinator-whitelist`. Use `selector-combinator-allowed-list` instead. + - `selector-pseudo-class-blacklist`. Use `selector-pseudo-class-disallowed-list` instead. + - `selector-pseudo-class-whitelist`. Use `selector-pseudo-class-allowed-list` instead. + - `selector-pseudo-element-blacklist`. Use `selector-pseudo-element-disallowed-list` instead. + - `selector-pseudo-element-whitelist`. Use `selector-pseudo-element-allowed-list` instead. + - `unit-blacklist`. Use `unit-disallowed-list` instead. + - `unit-whitelist`. Use `unit-allowed-list` instead. - Added: syntax object acceptance to `customSyntax` option ([#4839](https://github.com/stylelint/stylelint/pull/4839)). +- Added: support for `*.cjs` config files ([#4905](https://github.com/stylelint/stylelint/pull/4905)). - Added: support for descriptions in stylelint command comments ([#4848](https://github.com/stylelint/stylelint/pull/4848)). -- Added: `*-allowed-list`, `*-disallowed-list` and `*-required-list` new names for `*-whitelist`, `*-blacklist` and `*-requirelist` rules, respectively; the rules are aliased as their old names ([#4845](https://github.com/stylelint/stylelint/pull/4845)). -- Added: `ignoreContextFunctionalPseudoClasses` to `selector-max-id` ([#4835](https://github.com/stylelint/stylelint/pull/4835)). +- Added: `reportDescriptionlessDisables` flag ([#4907](https://github.com/stylelint/stylelint/pull/4907)). +- Added: `reportDisables` secondary option ([#4897](https://github.com/stylelint/stylelint/pull/4897)). +- Added: `*-no-vendor-prefix` autofix ([#4859](https://github.com/stylelint/stylelint/pull/4859)). - Added: `ignoreComments[]` to `comment-empty-line-before` ([#4841](https://github.com/stylelint/stylelint/pull/4841)). -- Fixed: false negatives for `where`, `is`, `nth-child` and `nth-last-child` in `selector-max-*` rules (except selector-max-type) ([#4842](https://github.com/stylelint/stylelint/pull/4842)). +- Added: `ignoreContextFunctionalPseudoClasses` to `selector-max-id` ([#4835](https://github.com/stylelint/stylelint/pull/4835)). +- Fixed: inconsistent trailing newlines in CLI error output ([#4876](https://github.com/stylelint/stylelint/pull/4876)). +- Fixed: support for multi-line disable descriptions ([#4895](https://github.com/stylelint/stylelint/pull/4895)). +- Fixed: support for paths with parentheses ([#4867](https://github.com/stylelint/stylelint/pull/4867)). +- Fixed: `selector-max-*` (except `selector-max-type`) false negatives for `where`, `is`, `nth-child` and `nth-last-child` ([#4842](https://github.com/stylelint/stylelint/pull/4842)). +- Fixed: `length-zero-no-unit` TypeError for custom properties fallback ([#4860](https://github.com/stylelint/stylelint/pull/4860)). +- Fixed: `selector-combinator-space-after` false positives for trailing combinator ([#4878](https://github.com/stylelint/stylelint/pull/4878)). ## 13.6.1 diff --git a/docs/developer-guide/formatters.md b/docs/developer-guide/formatters.md index b51e1055e0..ad1b2f280d 100644 --- a/docs/developer-guide/formatters.md +++ b/docs/developer-guide/formatters.md @@ -57,7 +57,7 @@ And the second argument (`returnValue`) is an object (type `StylelintStandaloneR "ranges": [ { "start": 10, - "unusedRule": "indentation" + "rule": "indentation" } ] } @@ -69,7 +69,7 @@ And the second argument (`returnValue`) is an object (type `StylelintStandaloneR "ranges": [ { "start": 1, - "unusedRule": "color-named" + "rule": "color-named" } ] } diff --git a/docs/user-guide/configure.md b/docs/user-guide/configure.md index 38afea37d6..4811b02908 100644 --- a/docs/user-guide/configure.md +++ b/docs/user-guide/configure.md @@ -135,6 +135,26 @@ For example: Reporters may use these severity levels to display violations or exit the process differently. +### `reportDisables` + +You can set the `reportDisables` secondary option to report any disable comments for this rule, effectively disallowing authors to opt out of it. + +For example: + +```json +{ + "rules": { + "indentation": [ + 2, + { + "except": ["value"], + "reportDisables": true + } + ] + } +} +``` + ## `defaultSeverity` You can set the default severity level for all rules that do not have a severity specified in their secondary options. For example, you can set the default severity to `"warning"`: diff --git a/docs/user-guide/integrations/editor.md b/docs/user-guide/integrations/editor.md index 10e3e85029..034470de2a 100644 --- a/docs/user-guide/integrations/editor.md +++ b/docs/user-guide/integrations/editor.md @@ -9,3 +9,4 @@ Editor integrations built and maintained by the community. - [SublimeLinter-contrib-stylelint_d](https://github.com/jo-sm/SublimeLinter-contrib-stylelint_d) - Sublime Text plugin for stylelint that run's on daemon. - [WebStorm](https://blog.jetbrains.com/webstorm/2016/09/webstorm-2016-3-eap-163-4830-stylelint-usages-for-default-exports-and-more/) - version 2016.3 onwards has built-in support for stylelint. - [vscode-stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) - VS Code extension for stylelint. +- [coc-stylelint](https://github.com/neoclide/coc-stylelint) - coc.nvim language server extension for neovim. diff --git a/docs/user-guide/rules/list.md b/docs/user-guide/rules/list.md index 2fb3483afa..9c4f023149 100644 --- a/docs/user-guide/rules/list.md +++ b/docs/user-guide/rules/list.md @@ -102,10 +102,14 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Function - [`function-allowed-list`](../../../lib/rules/function-allowed-list/README.md): Specify a list of allowed functions. +- [`function-blacklist`](../../../lib/rules/function-blacklist/README.md): Specify a list of disallowed functions. **(deprecated)** - [`function-disallowed-list`](../../../lib/rules/function-disallowed-list/README.md): Specify a list of disallowed functions. - [`function-url-no-scheme-relative`](../../../lib/rules/function-url-no-scheme-relative/README.md): Disallow scheme-relative urls. - [`function-url-scheme-allowed-list`](../../../lib/rules/function-url-scheme-allowed-list/README.md): Specify a list of allowed URL schemes. +- [`function-url-scheme-blacklist`](../../../lib/rules/function-url-scheme-blacklist/README.md): Specify a list of disallowed URL schemes. **(deprecated)** - [`function-url-scheme-disallowed-list`](../../../lib/rules/function-url-scheme-disallowed-list/README.md): Specify a list of disallowed URL schemes. +- [`function-url-scheme-whitelist`](../../../lib/rules/function-url-scheme-whitelist/README.md): Specify a list of allowed URL schemes. **(deprecated)** +- [`function-whitelist`](../../../lib/rules/function-whitelist/README.md): Specify a list of allowed functions. **(deprecated)** ### Keyframes @@ -122,7 +126,9 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Unit - [`unit-allowed-list`](../../../lib/rules/unit-allowed-list/README.md): Specify a list of allowed units. +- [`unit-blacklist`](../../../lib/rules/unit-blacklist/README.md): Specify a list of disallowed units. **(deprecated)** - [`unit-disallowed-list`](../../../lib/rules/unit-disallowed-list/README.md): Specify a list of disallowed units. +- [`unit-whitelist`](../../../lib/rules/unit-whitelist/README.md): Specify a list of allowed units. **(deprecated)** ### Shorthand property @@ -130,7 +136,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Value -- [`value-no-vendor-prefix`](../../../lib/rules/value-no-vendor-prefix/README.md): Disallow vendor prefixes for values. +- [`value-no-vendor-prefix`](../../../lib/rules/value-no-vendor-prefix/README.md): Disallow vendor prefixes for values (Autofixable). ### Custom property @@ -139,17 +145,23 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Property - [`property-allowed-list`](../../../lib/rules/property-allowed-list/README.md): Specify a list of allowed properties. +- [`property-blacklist`](../../../lib/rules/property-blacklist/README.md): Specify a list of disallowed properties. **(deprecated)** - [`property-disallowed-list`](../../../lib/rules/property-disallowed-list/README.md): Specify a list of disallowed properties. -- [`property-no-vendor-prefix`](../../../lib/rules/property-no-vendor-prefix/README.md): Disallow vendor prefixes for properties. +- [`property-no-vendor-prefix`](../../../lib/rules/property-no-vendor-prefix/README.md): Disallow vendor prefixes for properties (Autofixable). +- [`property-whitelist`](../../../lib/rules/property-whitelist/README.md): Specify a list of allowed properties. **(deprecated)** ### Declaration - [`declaration-block-no-redundant-longhand-properties`](../../../lib/rules/declaration-block-no-redundant-longhand-properties/README.md): Disallow longhand properties that can be combined into one shorthand property. - [`declaration-no-important`](../../../lib/rules/declaration-no-important/README.md): Disallow `!important` within declarations. - [`declaration-property-unit-allowed-list`](../../../lib/rules/declaration-property-unit-allowed-list/README.md): Specify a list of allowed property and unit pairs within declarations. +- [`declaration-property-unit-blacklist`](../../../lib/rules/declaration-property-unit-blacklist/README.md): Specify a list of disallowed property and unit pairs within declarations. **(deprecated)** - [`declaration-property-unit-disallowed-list`](../../../lib/rules/declaration-property-unit-disallowed-list/README.md): Specify a list of disallowed property and unit pairs within declarations. +- [`declaration-property-unit-whitelist`](../../../lib/rules/declaration-property-unit-whitelist/README.md): Specify a list of allowed property and unit pairs within declarations. **(deprecated)** - [`declaration-property-value-allowed-list`](../../../lib/rules/declaration-property-value-allowed-list/README.md): Specify a list of allowed property and value pairs within declarations. +- [`declaration-property-value-blacklist`](../../../lib/rules/declaration-property-value-blacklist/README.md): Specify a list of disallowed property and value pairs within declarations. **(deprecated)** - [`declaration-property-value-disallowed-list`](../../../lib/rules/declaration-property-value-disallowed-list/README.md): Specify a list of disallowed property and value pairs within declarations. +- [`declaration-property-value-whitelist`](../../../lib/rules/declaration-property-value-whitelist/README.md): Specify a list of allowed property and value pairs within declarations. **(deprecated)** ### Declaration block @@ -158,10 +170,14 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### Selector - [`selector-attribute-operator-allowed-list`](../../../lib/rules/selector-attribute-operator-allowed-list/README.md): Specify a list of allowed attribute operators. +- [`selector-attribute-operator-blacklist`](../../../lib/rules/selector-attribute-operator-blacklist/README.md): Specify a list of disallowed attribute operators. **(deprecated)** - [`selector-attribute-operator-disallowed-list`](../../../lib/rules/selector-attribute-operator-disallowed-list/README.md): Specify a list of disallowed attribute operators. +- [`selector-attribute-operator-whitelist`](../../../lib/rules/selector-attribute-operator-whitelist/README.md): Specify a list of allowed attribute operators. **(deprecated)** - [`selector-class-pattern`](../../../lib/rules/selector-class-pattern/README.md): Specify a pattern for class selectors. - [`selector-combinator-allowed-list`](../../../lib/rules/selector-combinator-allowed-list/README.md): Specify a list of allowed combinators. +- [`selector-combinator-blacklist`](../../../lib/rules/selector-combinator-blacklist/README.md): Specify a list of disallowed combinators. **(deprecated)** - [`selector-combinator-disallowed-list`](../../../lib/rules/selector-combinator-disallowed-list/README.md): Specify a list of disallowed combinators. +- [`selector-combinator-whitelist`](../../../lib/rules/selector-combinator-whitelist/README.md): Specify a list of allowed combinators. **(deprecated)** - [`selector-id-pattern`](../../../lib/rules/selector-id-pattern/README.md): Specify a pattern for ID selectors. - [`selector-max-attribute`](../../../lib/rules/selector-max-attribute/README.md): Limit the number of attribute selectors in a selector. - [`selector-max-class`](../../../lib/rules/selector-max-class/README.md): Limit the number of classes in a selector. @@ -175,19 +191,25 @@ Grouped first by the following categories and then by the [_thing_](http://apps. - [`selector-max-universal`](../../../lib/rules/selector-max-universal/README.md): Limit the number of universal selectors in a selector. - [`selector-nested-pattern`](../../../lib/rules/selector-nested-pattern/README.md): Specify a pattern for the selectors of rules nested within rules. - [`selector-no-qualifying-type`](../../../lib/rules/selector-no-qualifying-type/README.md): Disallow qualifying a selector by type. -- [`selector-no-vendor-prefix`](../../../lib/rules/selector-no-vendor-prefix/README.md): Disallow vendor prefixes for selectors. +- [`selector-no-vendor-prefix`](../../../lib/rules/selector-no-vendor-prefix/README.md): Disallow vendor prefixes for selectors (Autofixable). - [`selector-pseudo-class-allowed-list`](../../../lib/rules/selector-pseudo-class-allowed-list/README.md): Specify a list of allowed pseudo-class selectors. +- [`selector-pseudo-class-blacklist`](../../../lib/rules/selector-pseudo-class-blacklist/README.md): Specify a list of disallowed pseudo-class selectors. **(deprecated)** - [`selector-pseudo-class-disallowed-list`](../../../lib/rules/selector-pseudo-class-disallowed-list/README.md): Specify a list of disallowed pseudo-class selectors. +- [`selector-pseudo-class-whitelist`](../../../lib/rules/selector-pseudo-class-whitelist/README.md): Specify a list of allowed pseudo-class selectors. **(deprecated)** - [`selector-pseudo-element-allowed-list`](../../../lib/rules/selector-pseudo-element-allowed-list/README.md): Specify a list of allowed pseudo-element selectors. +- [`selector-pseudo-element-blacklist`](../../../lib/rules/selector-pseudo-element-blacklist/README.md): Specify a list of disallowed pseudo-element selectors. **(deprecated)** - [`selector-pseudo-element-colon-notation`](../../../lib/rules/selector-pseudo-element-colon-notation/README.md): Specify single or double colon notation for applicable pseudo-elements (Autofixable). - [`selector-pseudo-element-disallowed-list`](../../../lib/rules/selector-pseudo-element-disallowed-list/README.md): Specify a list of disallowed pseudo-element selectors. +- [`selector-pseudo-element-whitelist`](../../../lib/rules/selector-pseudo-element-whitelist/README.md): Specify a list of allowed pseudo-element selectors. **(deprecated)** ### Media feature - [`media-feature-name-allowed-list`](../../../lib/rules/media-feature-name-allowed-list/README.md): Specify a list of allowed media feature names. +- [`media-feature-name-blacklist`](../../../lib/rules/media-feature-name-blacklist/README.md): Specify a list of disallowed media feature names. **(deprecated)** - [`media-feature-name-disallowed-list`](../../../lib/rules/media-feature-name-disallowed-list/README.md): Specify a list of disallowed media feature names. -- [`media-feature-name-no-vendor-prefix`](../../../lib/rules/media-feature-name-no-vendor-prefix/README.md): Disallow vendor prefixes for media feature names. +- [`media-feature-name-no-vendor-prefix`](../../../lib/rules/media-feature-name-no-vendor-prefix/README.md): Disallow vendor prefixes for media feature names (Autofixable). - [`media-feature-name-value-allowed-list`](../../../lib/rules/media-feature-name-value-allowed-list/README.md): Specify a list of allowed media feature name and value pairs. +- [`media-feature-name-whitelist`](../../../lib/rules/media-feature-name-whitelist/README.md): Specify a list of allowed media feature names. **(deprecated)** ### Custom media @@ -196,12 +218,16 @@ Grouped first by the following categories and then by the [_thing_](http://apps. ### At-rule - [`at-rule-allowed-list`](../../../lib/rules/at-rule-allowed-list/README.md): Specify a list of allowed at-rules. +- [`at-rule-blacklist`](../../../lib/rules/at-rule-blacklist/README.md): Specify a list of disallowed at-rules. **(deprecated)** - [`at-rule-disallowed-list`](../../../lib/rules/at-rule-disallowed-list/README.md): Specify a list of disallowed at-rules. -- [`at-rule-no-vendor-prefix`](../../../lib/rules/at-rule-no-vendor-prefix/README.md): Disallow vendor prefixes for at-rules. +- [`at-rule-no-vendor-prefix`](../../../lib/rules/at-rule-no-vendor-prefix/README.md): Disallow vendor prefixes for at-rules (Autofixable). - [`at-rule-property-required-list`](../../../lib/rules/at-rule-property-required-list/README.md): Specify a list of required properties for an at-rule. +- [`at-rule-property-requirelist`](../../../lib/rules/at-rule-property-requirelist/README.md): Specify a list of required properties for an at-rule. **(deprecated)** +- [`at-rule-whitelist`](../../../lib/rules/at-rule-whitelist/README.md): Specify a list of allowed at-rules. **(deprecated)** ### Comment +- [`comment-word-blacklist`](../../../lib/rules/comment-word-blacklist/README.md): Specify a list of disallowed words within comments. **(deprecated)** - [`comment-word-disallowed-list`](../../../lib/rules/comment-word-disallowed-list/README.md): Specify a list of disallowed words within comments. ### General / Sheet diff --git a/lib/__tests__/__snapshots__/cli.test.js.snap b/lib/__tests__/__snapshots__/cli.test.js.snap index 8daa701743..2cda5d64de 100644 --- a/lib/__tests__/__snapshots__/cli.test.js.snap +++ b/lib/__tests__/__snapshots__/cli.test.js.snap @@ -122,6 +122,11 @@ exports[`CLI --help 1`] = ` Report stylelint-disable comments that used for rules that don't exist within the configuration object. The process will exit with code 2 if invalid scope disables are found. + --report-descriptionless-disables, --rdd + + Report stylelint-disable comments without a description. + The process will exit with code 2 if descriptionless disables are found. + --max-warnings, --mw Number of warnings above which the process will exit with code 2. diff --git a/lib/__tests__/aliasedRules.test.js b/lib/__tests__/aliasedRules.test.js deleted file mode 100644 index 50a2eecaa4..0000000000 --- a/lib/__tests__/aliasedRules.test.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const rules = require('../rules'); - -const whitelistAndBlacklistRulePrefixes = [ - 'at-rule', - 'declaration-property-unit', - 'declaration-property-value', - 'function', - 'function-url-scheme', - 'media-feature-name', - 'property', - 'selector-attribute-operator', - 'selector-combinator', - 'selector-pseudo-class', - 'selector-pseudo-element', - 'unit', -]; - -const whitelistRulePrefixes = whitelistAndBlacklistRulePrefixes.concat([ - 'media-feature-name-value', -]); - -whitelistRulePrefixes.forEach((prefix) => { - it(`aliases ${prefix}-whitelist to ${prefix}-allowed-list`, () => - expect(rules[`${prefix}-whitelist`].ruleName).toEqual(`${prefix}-allowed-list`)); -}); - -const blacklistRulePrefixes = whitelistAndBlacklistRulePrefixes.concat(['comment-word']); - -blacklistRulePrefixes.forEach((prefix) => { - it(`aliases ${prefix}-blacklist to ${prefix}-disallowed-list`, () => - expect(rules[`${prefix}-blacklist`].ruleName).toEqual(`${prefix}-disallowed-list`)); -}); - -const requirelistRulePrefixes = ['at-rule-property']; - -requirelistRulePrefixes.forEach((prefix) => { - it(`aliases ${prefix}-requirelist to ${prefix}-required-list`, () => - expect(rules[`${prefix}-requirelist`].ruleName).toEqual(`${prefix}-required-list`)); -}); diff --git a/lib/__tests__/cli.test.js b/lib/__tests__/cli.test.js index f41b88f9e2..9599f39d4e 100644 --- a/lib/__tests__/cli.test.js +++ b/lib/__tests__/cli.test.js @@ -26,6 +26,7 @@ describe('buildCLI', () => { ignoreDisables: false, printConfig: false, quiet: false, + reportDescriptionlessDisables: false, reportInvalidScopeDisables: false, reportNeedlessDisables: false, stdin: false, @@ -234,7 +235,7 @@ describe('CLI', () => { expect(process.stdout.write).toHaveBeenCalledTimes(2); expect(process.stdout.write).toHaveBeenNthCalledWith( 1, - expect.stringContaining('unused rule: color-named'), + expect.stringContaining('needless disable: color-named'), ); expect(process.stdout.write).toHaveBeenNthCalledWith( 2, @@ -242,6 +243,39 @@ describe('CLI', () => { ); }); + it('reports disallowed disables', async () => { + await cli([ + '--config', + replaceBackslashes(path.join(fixturesPath, 'config-block-no-empty-report-disables.json')), + replaceBackslashes(path.join(fixturesPath, 'empty-block-with-relevant-disable.css')), + ]); + + expect(process.exitCode).toBe(2); + + expect(process.stdout.write).toHaveBeenCalledTimes(1); + expect(process.stdout.write).toHaveBeenNthCalledWith( + 1, + expect.stringContaining('forbidden disable: block-no-empty'), + ); + }); + + it('reports descriptionless disables', async () => { + await cli([ + '--report-descriptionless-disables', + '--config', + replaceBackslashes(path.join(fixturesPath, 'config-block-no-empty.json')), + replaceBackslashes(path.join(fixturesPath, 'empty-block-with-relevant-disable.css')), + ]); + + expect(process.exitCode).toBe(2); + + expect(process.stdout.write).toHaveBeenCalledTimes(1); + expect(process.stdout.write).toHaveBeenNthCalledWith( + 1, + expect.stringContaining('descriptionless disable: block-no-empty'), + ); + }); + it('--stdin', async () => { await cli(['--stdin', '--config', `${fixturesPath}/config-no-empty-source.json`]); diff --git a/lib/__tests__/descriptionlessDisables.test.js b/lib/__tests__/descriptionlessDisables.test.js new file mode 100644 index 0000000000..d1983b83f3 --- /dev/null +++ b/lib/__tests__/descriptionlessDisables.test.js @@ -0,0 +1,62 @@ +'use strict'; + +const standalone = require('../standalone'); +const stripIndent = require('common-tags').stripIndent; + +it('descriptionlessDisables', () => { + const config = { + rules: { 'block-no-empty': true }, + }; + + const css = stripIndent` + /* stylelint-disable -- Description */ + a {} + /* stylelint-enable */ + a { + b {} /* stylelint-disable-line block-no-empty -- Description */ + } + /* stylelint-disable-next-line block-no-empty + * -- + * Description */ + a {} + + /* stylelint-disable */ + a {} + /* stylelint-enable */ + a { + b {} /* stylelint-disable-line block-no-empty */ + } + /* stylelint-disable-next-line block-no-empty */ + a {} + `; + + return standalone({ + config, + code: css, + reportDescriptionlessDisables: true, + }).then((linted) => { + const report = linted.descriptionlessDisables; + + expect(report).toHaveLength(1); + expect(report[0].ranges).toEqual([ + { + start: 12, + end: 14, + rule: 'all', + unusedRule: 'all', + }, + { + start: 16, + end: 16, + rule: 'block-no-empty', + unusedRule: 'block-no-empty', + }, + { + start: 19, + end: 19, + rule: 'block-no-empty', + unusedRule: 'block-no-empty', + }, + ]); + }); +}); diff --git a/lib/__tests__/disableRanges.test.js b/lib/__tests__/disableRanges.test.js index fc93c29ebb..cef906a581 100644 --- a/lib/__tests__/disableRanges.test.js +++ b/lib/__tests__/disableRanges.test.js @@ -653,6 +653,7 @@ it('disable (with description) without re-enabling', () => { { start: 1, strictStart: true, + description: 'Description', }, ], }); @@ -672,6 +673,7 @@ it('disable and re-enable (with descriptions)', () => { end: 4, strictStart: true, strictEnd: true, + description: 'Description', }, ], }); @@ -689,6 +691,7 @@ it('disable rule (with description) without re-enabling', () => { strictStart: true, end: undefined, strictEnd: undefined, + description: 'Description', }, ], }); @@ -706,18 +709,21 @@ it('disable rules (with description) with newline in rule list', () => { { start: 1, strictStart: true, + description: 'Description', }, ], 'hoo-hah': [ { start: 1, strictStart: true, + description: 'Description', }, ], slime: [ { start: 1, strictStart: true, + description: 'Description', }, ], }); @@ -741,6 +747,82 @@ it('SCSS // line-disabling comment (with description)', () => { end: 2, strictStart: true, strictEnd: true, + description: 'Description', + }, + ], + }); + }); +}); + +it('SCSS // disable next-line comment (with multi-line description)', () => { + const scssSource = `a { + // stylelint-disable-next-line declaration-no-important + // -- + // Long-winded description + color: pink !important; + }`; + + return postcss() + .use(assignDisabledRanges) + .process(scssSource, { syntax: scss, from: undefined }) + .then((result) => { + expect(result.stylelint.disabledRanges).toEqual({ + all: [], + 'declaration-no-important': [ + { + start: 5, + end: 5, + strictStart: true, + strictEnd: true, + description: 'Long-winded description', + }, + ], + }); + }); +}); + +it('SCSS // disable comment (with // comment after blank line)', () => { + const scssSource = `a { + // stylelint-disable declaration-no-important + + // Unrelated + color: pink !important; + }`; + + return postcss() + .use(assignDisabledRanges) + .process(scssSource, { syntax: scss, from: undefined }) + .then((result) => { + expect(result.stylelint.disabledRanges).toEqual({ + all: [], + 'declaration-no-important': [ + { + start: 2, + strictStart: true, + }, + ], + }); + }); +}); + +it('SCSS /* disable comment (with // comment after blank line)', () => { + const scssSource = `a { + /* stylelint-disable declaration-no-important */ + + // Unrelated + color: pink !important; + }`; + + return postcss() + .use(assignDisabledRanges) + .process(scssSource, { syntax: scss, from: undefined }) + .then((result) => { + expect(result.stylelint.disabledRanges).toEqual({ + all: [], + 'declaration-no-important': [ + { + start: 2, + strictStart: true, }, ], }); @@ -764,6 +846,34 @@ it('Less // line-disabling comment (with description)', () => { end: 2, strictStart: true, strictEnd: true, + description: 'Description', + }, + ], + }); + }); +}); + +it('Less // disable next-line comment (with multi-line description)', () => { + const lessSource = `a { + // stylelint-disable-next-line declaration-no-important + // -- + // Long-winded description + color: pink !important; + }`; + + return postcss() + .use(assignDisabledRanges) + .process(lessSource, { syntax: less, from: undefined }) + .then((result) => { + expect(result.stylelint.disabledRanges).toEqual({ + all: [], + 'declaration-no-important': [ + { + start: 5, + end: 5, + strictStart: true, + strictEnd: true, + description: 'Long-winded description', }, ], }); diff --git a/lib/__tests__/fixtures/config-block-no-empty-report-disables.json b/lib/__tests__/fixtures/config-block-no-empty-report-disables.json new file mode 100644 index 0000000000..609545d4e3 --- /dev/null +++ b/lib/__tests__/fixtures/config-block-no-empty-report-disables.json @@ -0,0 +1,5 @@ +{ + "rules": { + "block-no-empty": [true, { "reportDisables": true }] + } +} diff --git a/lib/__tests__/fixtures/empty-block-with-relevant-disable.css b/lib/__tests__/fixtures/empty-block-with-relevant-disable.css new file mode 100644 index 0000000000..b37a3088b4 --- /dev/null +++ b/lib/__tests__/fixtures/empty-block-with-relevant-disable.css @@ -0,0 +1,2 @@ +/* stylelint-disable block-no-empty */ +a {} diff --git a/lib/__tests__/fixtures/globs/[digit]/not-digits/styles.css b/lib/__tests__/fixtures/globs/[digit]/not-digits/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/[digit]/not-digits/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/extglob!(s)/styles.css b/lib/__tests__/fixtures/globs/extglob!(s)/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/extglob!(s)/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/glob+chars/glob-plus.css b/lib/__tests__/fixtures/globs/glob+chars/glob-plus.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/glob+chars/glob-plus.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/glob-contains-plus/styles.css b/lib/__tests__/fixtures/globs/glob-contains-plus/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/glob-contains-plus/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/got!negate/negate/styles.css b/lib/__tests__/fixtures/globs/got!negate/negate/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/got!negate/negate/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/got[braces] and (spaces)/styles.css b/lib/__tests__/fixtures/globs/got[braces] and (spaces)/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/got[braces] and (spaces)/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/negated-globs/ignore/ignore-this-file.css b/lib/__tests__/fixtures/globs/negated-globs/ignore/ignore-this-file.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/negated-globs/ignore/ignore-this-file.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/negated-globs/lint-this-file.css b/lib/__tests__/fixtures/globs/negated-globs/lint-this-file.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/negated-globs/lint-this-file.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/fixtures/globs/with spaces/styles.css b/lib/__tests__/fixtures/globs/with spaces/styles.css new file mode 100644 index 0000000000..077f6dd7c0 --- /dev/null +++ b/lib/__tests__/fixtures/globs/with spaces/styles.css @@ -0,0 +1 @@ +a {} diff --git a/lib/__tests__/integration.test.js b/lib/__tests__/integration.test.js index df73623bf7..feddcbf36a 100644 --- a/lib/__tests__/integration.test.js +++ b/lib/__tests__/integration.test.js @@ -143,19 +143,6 @@ it('Scss integration test', () => { }); }); -it('rule aliasing integration test', () => { - return postcss() - .use(stylelint({ rules: { 'unit-blacklist': ['px'] } })) - .process('a { top: 10px; }', { from: undefined }) - .then((result) => { - const error = result.messages[0]; - - expect(error).toBeTruthy(); - expect(error.rule).toBe('unit-disallowed-list'); - expect(error.text).toBe('Unexpected unit "px" (unit-disallowed-list)'); - }); -}); - describe('integration test null option', () => { let results; diff --git a/lib/__tests__/invalidScopeDisables.test.js b/lib/__tests__/invalidScopeDisables.test.js index ffb2b2688e..f3a06bc03a 100644 --- a/lib/__tests__/invalidScopeDisables.test.js +++ b/lib/__tests__/invalidScopeDisables.test.js @@ -40,8 +40,8 @@ it('invalidScopeDisables simple case', () => { expect(report).toHaveLength(1); expect(report[0].ranges).toHaveLength(2); expect(report[0].ranges).toEqual([ - { end: 3, start: 1, unusedRule: 'block-no-empty' }, - { end: 5, start: 5, unusedRule: 'block-no-empty' }, + { end: 3, start: 1, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { end: 5, start: 5, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, ]); }); }); @@ -65,11 +65,11 @@ it('invalidScopeDisables complex case', () => { expect(invalidScopeDisables(linted.results, config)).toEqual([ { source: source('disabled-ranges-1.css'), - ranges: [{ start: 1, end: 3, unusedRule: 'color-named' }], + ranges: [{ start: 1, end: 3, rule: 'color-named', unusedRule: 'color-named' }], }, { source: source('disabled-ranges-2.css'), - ranges: [{ start: 5, end: 5, unusedRule: 'color-named' }], + ranges: [{ start: 5, end: 5, rule: 'color-named', unusedRule: 'color-named' }], }, ]); }); @@ -91,7 +91,7 @@ it('invalidScopeDisables ignored case', () => { expect(invalidScopeDisables(linted.results, config)).toEqual([ { source: source('disabled-ranges-1.css'), - ranges: [{ start: 5, end: 7, unusedRule: 'block-no-empty' }], + ranges: [{ start: 5, end: 7, rule: 'block-no-empty', unusedRule: 'block-no-empty' }], }, ]); }); @@ -119,6 +119,7 @@ it('invalidScopeDisables for config file', () => { { end: undefined, start: 4, + rule: 'foo', unusedRule: 'foo', }, ]); diff --git a/lib/__tests__/needlessDisables.test.js b/lib/__tests__/needlessDisables.test.js index ecf2e3451b..2a0b7380e4 100644 --- a/lib/__tests__/needlessDisables.test.js +++ b/lib/__tests__/needlessDisables.test.js @@ -42,8 +42,8 @@ it('needlessDisables simple case', () => { expect(report).toHaveLength(1); expect(report[0].ranges).toEqual([ - { start: 7, end: 9, unusedRule: 'all' }, - { start: 11, end: 11, unusedRule: 'block-no-empty' }, + { start: 7, end: 9, rule: 'all', unusedRule: 'all' }, + { start: 11, end: 11, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, ]); }); }); @@ -70,17 +70,17 @@ it('needlessDisables complex case', () => { { source: source('disabled-ranges-1.css'), ranges: [ - { start: 1, end: 3, unusedRule: 'color-named' }, - { start: 5, end: 7, unusedRule: 'block-no-empty' }, - { start: 10, end: 10, unusedRule: 'block-no-empty' }, + { start: 1, end: 3, rule: 'color-named', unusedRule: 'color-named' }, + { start: 5, end: 7, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { start: 10, end: 10, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, ], }, { source: source('disabled-ranges-2.css'), ranges: [ - { start: 5, end: 5, unusedRule: 'color-named' }, - { start: 6, end: 6, unusedRule: 'block-no-empty' }, - { start: 8, end: 10, unusedRule: 'block-no-empty' }, + { start: 5, end: 5, rule: 'color-named', unusedRule: 'color-named' }, + { start: 6, end: 6, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { start: 8, end: 10, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, ], }, ]); @@ -104,9 +104,9 @@ it('needlessDisables ignored case', () => { { source: source('disabled-ranges-1.css'), ranges: [ - { start: 1, end: 3, unusedRule: 'color-named' }, - { start: 5, end: 7, unusedRule: 'block-no-empty' }, - { start: 10, end: 10, unusedRule: 'all' }, + { start: 1, end: 3, rule: 'color-named', unusedRule: 'color-named' }, + { start: 5, end: 7, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { start: 10, end: 10, rule: 'all', unusedRule: 'all' }, ], }, ]); diff --git a/lib/__tests__/reportDisables.test.js b/lib/__tests__/reportDisables.test.js new file mode 100644 index 0000000000..c04d529c19 --- /dev/null +++ b/lib/__tests__/reportDisables.test.js @@ -0,0 +1,105 @@ +'use strict'; + +const standalone = require('../standalone'); +const stripIndent = require('common-tags').stripIndent; + +describe('reportDisables', () => { + it('reports a disabled comment', () => { + const config = { + rules: { 'block-no-empty': [true, { reportDisables: true }] }, + }; + + const css = stripIndent` + /* stylelint-disable block-no-empty */ + a {} + /* stylelint-enable block-no-empty */ + a { + b {} /* stylelint-disable-line block-no-empty */ + } + `; + + return standalone({ config, code: css }).then((linted) => { + const report = linted.reportedDisables; + + expect(report).toHaveLength(1); + expect(report[0].ranges).toEqual([ + { start: 1, end: 3, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { start: 5, end: 5, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + ]); + + // Although these disables are reported as issues, they're still in effect + // so the underlying lint issues are not reported. + expect(linted.results[0].warnings).toHaveLength(0); + }); + }); + + it('reports an ignored disabled comment', () => { + const config = { + rules: { 'block-no-empty': [true, { reportDisables: true }] }, + }; + + const css = stripIndent` + /* stylelint-disable block-no-empty */ + a {} + /* stylelint-enable block-no-empty */ + a { + b {} /* stylelint-disable-line block-no-empty */ + } + `; + + return standalone({ + config, + code: css, + ignoreDisables: true, + }).then((linted) => { + const report = linted.reportedDisables; + + expect(report).toHaveLength(1); + expect(report[0].ranges).toEqual([ + { start: 1, end: 3, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + { start: 5, end: 5, rule: 'block-no-empty', unusedRule: 'block-no-empty' }, + ]); + + expect(linted.results[0].warnings).toHaveLength(2); + }); + }); + + it("doesn't report disables by default", () => { + const config = { + rules: { 'block-no-empty': [true] }, + }; + + const css = stripIndent` + /* stylelint-disable block-no-empty */ + a {} + /* stylelint-enable block-no-empty */ + a { + b {} /* stylelint-disable-line block-no-empty */ + } + `; + + return standalone({ config, code: css }).then((linted) => { + const report = linted.reportedDisables; + + expect(report).toHaveLength(0); + }); + }); + + // This should be handled by the global `reportUnscopedDisables` option (#2292). + it("doesn't report unscoped disables", () => { + const config = { + rules: { 'block-no-empty': [true, { reportDisables: true }] }, + }; + + const css = stripIndent` + a {} /* stylelint-disable-line */ + `; + + return standalone({ config, code: css }).then((linted) => { + const report = linted.reportedDisables; + + expect(report).toHaveLength(1); + expect(report[0].ranges).toHaveLength(0); + }); + }); +}); diff --git a/lib/__tests__/standalone-globs.test.js b/lib/__tests__/standalone-globs.test.js new file mode 100644 index 0000000000..2f3f486287 --- /dev/null +++ b/lib/__tests__/standalone-globs.test.js @@ -0,0 +1,193 @@ +'use strict'; + +/* eslint-disable node/no-extraneous-require */ + +const describe = require('@jest/globals').describe; +const expect = require('@jest/globals').expect; +const it = require('@jest/globals').it; + +/* eslint-enable */ + +const path = require('path'); +const replaceBackslashes = require('../testUtils/replaceBackslashes'); +const standalone = require('../standalone'); + +const fixturesPath = replaceBackslashes(path.join(__dirname, 'fixtures', 'globs')); + +// Tests for https://github.com/stylelint/stylelint/issues/4521 + +describe('standalone globbing', () => { + describe('paths with special characters', () => { + // ref https://github.com/micromatch/micromatch#matching-features + const fixtureDirs = [ + `[digit]/not-digits`, + `with spaces`, + `extglob!(s)`, + `got!negate/negate`, + // `extglob+(s)`, // Note: +'s cause errors. Ignoring until it becomes a problem + ]; + + // https://github.com/stylelint/stylelint/issues/4193 + it.each(fixtureDirs)(`static path contains "%s"`, async (fixtureDir) => { + const cssPath = `${fixturesPath}/${fixtureDir}/styles.css`; + + const { results } = await standalone({ + files: cssPath, + config: { rules: { 'block-no-empty': true } }, + }); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + }); + + // https://github.com/stylelint/stylelint/issues/4211 + it('glob has no + character, matched path does', async () => { + const files = `${fixturesPath}/**/glob-plus.css`; // file is in dir 'glob+chars' + + const { results } = await standalone({ + files, + config: { rules: { 'block-no-empty': true } }, + }); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + + // https://github.com/stylelint/stylelint/issues/4211 + it('glob contains + character, matched path does not', async () => { + const files = `${fixturesPath}/+(g)lob-contains-plus/*.css`; + + const { results } = await standalone({ + files, + config: { rules: { 'block-no-empty': true } }, + }); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + + // https://github.com/stylelint/stylelint/issues/3272 + // should ignore 'negated-globs/ignore/styles.css' + it('negated glob patterns', async () => { + const files = [ + `${fixturesPath}/negated-globs/**/*.css`, + `!${fixturesPath}/negated-globs/ignore/**/*.css`, + ]; + + const { results } = await standalone({ + files, + config: { rules: { 'block-no-empty': true } }, + }); + + // ensure that the only result is from the unignored file + expect(results[0].source).toEqual(expect.stringContaining('lint-this-file.css')); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + + describe('mixed globs and paths with special chars', () => { + it('manual escaping', async () => { + const cssGlob = `${fixturesPath}/got\\[braces\\] and \\(spaces\\)/*.+(s|c)ss`; + + const { results } = await standalone({ + files: cssGlob, + config: { + rules: { + 'block-no-empty': true, + }, + }, + }); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + + it('setting "cwd" in globbyOptions', async () => { + const cssGlob = `*.+(s|c)ss`; + + const { results } = await standalone({ + files: cssGlob, + config: { + rules: { + 'block-no-empty': true, + }, + }, + globbyOptions: { + cwd: `${fixturesPath}/got[braces] and (spaces)/`, + }, + }); + + expect(results).toHaveLength(1); + expect(results[0].errored).toEqual(true); + expect(results[0].warnings[0]).toEqual( + expect.objectContaining({ + rule: 'block-no-empty', + severity: 'error', + }), + ); + }); + + /* eslint-disable jest/no-commented-out-tests -- Failing case for reference. Documents behaviour that doesn't work. */ + + // Note: This fails because there's no way to tell which parts of the glob are literal characters, and which are special globbing characters. + // + // 'got[braces] and (spaces)' is a literal directory path. `*.+(s|c)ss` is a glob. + + // https://github.com/stylelint/stylelint/issues/4855 + // it('glob and matched path contain different special chars, complex example', async () => { + // const cssGlob = `${fixturesPath}/got[braces] and (spaces)/*.+(s|c)ss`; + + // const { results } = await standalone({ + // files: cssGlob, + // config: { + // rules: { + // 'block-no-empty': true, + // }, + // }, + // }); + + // expect(results).toHaveLength(1); + // expect(results[0].errored).toEqual(true); + // expect(results[0].warnings[0]).toEqual( + // expect.objectContaining({ + // rule: 'block-no-empty', + // severity: 'error', + // }), + // ); + // }); + + /* eslint-enable */ + }); +}); diff --git a/lib/__tests__/standalone-invalidScopeDisables.test.js b/lib/__tests__/standalone-invalidScopeDisables.test.js index c65cab3321..220baff965 100644 --- a/lib/__tests__/standalone-invalidScopeDisables.test.js +++ b/lib/__tests__/standalone-invalidScopeDisables.test.js @@ -25,6 +25,7 @@ it('standalone with input css and `reportInvalidScopeDisables`', () => { expect(invalidScopeDisables[0].ranges).toHaveLength(1); expect(invalidScopeDisables[0].ranges[0]).toEqual({ start: 1, + rule: 'color-named', unusedRule: 'color-named', }); }); @@ -45,6 +46,7 @@ it('standalone with input file(s) and `reportInvalidScopeDisables`', () => { ); expect(invalidScopeDisables[0].ranges[0]).toEqual({ start: 1, + rule: 'color-named', unusedRule: 'color-named', }); }); diff --git a/lib/__tests__/standalone-needlessDisables.test.js b/lib/__tests__/standalone-needlessDisables.test.js index 08fbebcdfb..b3559e463a 100644 --- a/lib/__tests__/standalone-needlessDisables.test.js +++ b/lib/__tests__/standalone-needlessDisables.test.js @@ -27,6 +27,7 @@ it('standalone with input css and `reportNeedlessDisables`', () => { expect(needlessDisables[0].ranges).toHaveLength(1); expect(needlessDisables[0].ranges[0]).toEqual({ start: 1, + rule: 'color-named', unusedRule: 'color-named', }); @@ -130,6 +131,7 @@ it('standalone with input file(s) and `reportNeedlessDisables`', () => { ); expect(needlessDisables[0].ranges[0]).toEqual({ start: 1, + rule: 'color-named', unusedRule: 'color-named', }); }); diff --git a/lib/__tests__/stylelintignore-test/stylelintignore.test.js b/lib/__tests__/stylelintignore-test/stylelintignore.test.js index a2783fa202..04919e5e47 100644 --- a/lib/__tests__/stylelintignore-test/stylelintignore.test.js +++ b/lib/__tests__/stylelintignore-test/stylelintignore.test.js @@ -64,6 +64,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ errored: false, output: '[]', + reportedDisables: [], results: [], }); }); @@ -98,6 +99,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ errored: false, output: '[]', + reportedDisables: [], results: [], }); }); @@ -112,6 +114,7 @@ describe('stylelintignore', () => { expect(data).toEqual({ errored: false, output: '[]', + reportedDisables: [], results: [], }); }); diff --git a/lib/assignDisabledRanges.js b/lib/assignDisabledRanges.js index 31406d74b4..d57043e059 100644 --- a/lib/assignDisabledRanges.js +++ b/lib/assignDisabledRanges.js @@ -9,7 +9,7 @@ const disableLineCommand = `${COMMAND_PREFIX}disable-line`; const disableNextLineCommand = `${COMMAND_PREFIX}disable-next-line`; const ALL_RULES = 'all'; -/** @typedef {import('postcss').Comment} PostcssComment */ +/** @typedef {import('postcss/lib/comment')} PostcssComment */ /** @typedef {import('postcss').Root} PostcssRoot */ /** @typedef {import('stylelint').PostcssResult} PostcssResult */ /** @typedef {import('stylelint').DisabledRangeObject} DisabledRangeObject */ @@ -18,16 +18,18 @@ const ALL_RULES = 'all'; /** * @param {number} start * @param {boolean} strictStart + * @param {string|undefined} description * @param {number} [end] * @param {boolean} [strictEnd] * @returns {DisabledRange} */ -function createDisableRange(start, strictStart, end, strictEnd) { +function createDisableRange(start, strictStart, description, end, strictEnd) { return { start, end: end || undefined, strictStart, strictEnd: typeof strictEnd === 'boolean' ? strictEnd : undefined, + description, }; } @@ -53,19 +55,69 @@ module.exports = function (root, result) { }; result.stylelint.disabledRanges = disabledRanges; - root.walkComments(checkComment); + + // Work around postcss/postcss-scss#109 by merging adjacent `//` comments + // into a single node before passing to `checkComment`. + + /** @type {PostcssComment?} */ + let inlineEnd; + + root.walkComments((/** @type {PostcssComment} */ comment) => { + if (inlineEnd) { + // Ignore comments already processed by grouping with a previous one. + if (inlineEnd === comment) inlineEnd = null; + } else if (isInlineComment(comment)) { + const fullComment = comment.clone(); + let next = comment.next(); + let lastLine = (comment.source && comment.source.end && comment.source.end.line) || 0; + + while (next && next.type === 'comment') { + /** @type {PostcssComment} */ + const current = next; + + if (!isInlineComment(current)) break; + + const currentLine = (current.source && current.source.end && current.source.end.line) || 0; + + if (lastLine + 1 !== currentLine) break; + + fullComment.text += `\n${current.text}`; + + if (fullComment.source && current.source) { + fullComment.source.end = current.source.end; + } + + inlineEnd = current; + next = current.next(); + lastLine = currentLine; + } + checkComment(fullComment); + } else { + checkComment(comment); + } + }); return result; + /** + * @param {PostcssComment} comment + */ + function isInlineComment(comment) { + // We check both here because the Sass parser uses `raws.inline` to indicate + // inline comments, while the Less parser uses `inline`. + return comment.inline || comment.raws.inline; + } + /** * @param {PostcssComment} comment */ function processDisableLineCommand(comment) { if (comment.source && comment.source.start) { const line = comment.source.start.line; + const description = getDescription(comment.text); getCommandRules(disableLineCommand, comment.text).forEach((ruleName) => { - disableLine(line, ruleName, comment); + disableLine(line, ruleName, comment, description); }); } } @@ -74,11 +126,12 @@ module.exports = function (root, result) { * @param {PostcssComment} comment */ function processDisableNextLineCommand(comment) { - if (comment.source && comment.source.start) { - const line = comment.source.start.line; + if (comment.source && comment.source.end) { + const line = comment.source.end.line; + const description = getDescription(comment.text); getCommandRules(disableNextLineCommand, comment.text).forEach((ruleName) => { - disableLine(line + 1, ruleName, comment); + disableLine(line + 1, ruleName, comment, description); }); } } @@ -87,8 +140,9 @@ module.exports = function (root, result) { * @param {number} line * @param {string} ruleName * @param {PostcssComment} comment + * @param {string|undefined} description */ - function disableLine(line, ruleName, comment) { + function disableLine(line, ruleName, comment, description) { if (ruleIsDisabled(ALL_RULES)) { throw comment.error('All rules have already been disabled', { plugin: 'stylelint', @@ -101,7 +155,7 @@ module.exports = function (root, result) { const strict = disabledRuleName === ALL_RULES; - startDisabledRange(line, disabledRuleName, strict); + startDisabledRange(line, disabledRuleName, strict, description); endDisabledRange(line, disabledRuleName, strict); }); } else { @@ -111,7 +165,7 @@ module.exports = function (root, result) { }); } - startDisabledRange(line, ruleName, true); + startDisabledRange(line, ruleName, true, description); endDisabledRange(line, ruleName, true); } } @@ -120,6 +174,8 @@ module.exports = function (root, result) { * @param {PostcssComment} comment */ function processDisableCommand(comment) { + const description = getDescription(comment.text); + getCommandRules(disableCommand, comment.text).forEach((ruleToDisable) => { const isAllRules = ruleToDisable === ALL_RULES; @@ -139,10 +195,10 @@ module.exports = function (root, result) { if (isAllRules) { Object.keys(disabledRanges).forEach((ruleName) => { - startDisabledRange(line, ruleName, ruleName === ALL_RULES); + startDisabledRange(line, ruleName, ruleName === ALL_RULES, description); }); } else { - startDisabledRange(line, ruleToDisable, true); + startDisabledRange(line, ruleToDisable, true, description); } } }); @@ -182,8 +238,8 @@ module.exports = function (root, result) { if (ruleIsDisabled(ALL_RULES) && disabledRanges[ruleToEnable] === undefined) { // Get a starting point from the where all rules were disabled if (!disabledRanges[ruleToEnable]) { - disabledRanges[ruleToEnable] = disabledRanges.all.map(({ start, end }) => - createDisableRange(start, false, end, false), + disabledRanges[ruleToEnable] = disabledRanges.all.map(({ start, end, description }) => + createDisableRange(start, false, description, end, false), ); } else { const range = _.last(disabledRanges[ALL_RULES]); @@ -254,13 +310,26 @@ module.exports = function (root, result) { return rules; } + /** + * @param {string} fullText + * @returns {string|undefined} + */ + function getDescription(fullText) { + const descriptionStart = fullText.indexOf('--'); + + if (descriptionStart === -1) return; + + return fullText.slice(descriptionStart + 2).trim(); + } + /** * @param {number} line * @param {string} ruleName * @param {boolean} strict + * @param {string|undefined} description */ - function startDisabledRange(line, ruleName, strict) { - const rangeObj = createDisableRange(line, strict); + function startDisabledRange(line, ruleName, strict, description) { + const rangeObj = createDisableRange(line, strict, description); ensureRuleRanges(ruleName); disabledRanges[ruleName].push(rangeObj); @@ -288,8 +357,8 @@ module.exports = function (root, result) { */ function ensureRuleRanges(ruleName) { if (!disabledRanges[ruleName]) { - disabledRanges[ruleName] = disabledRanges.all.map(({ start, end }) => - createDisableRange(start, false, end, false), + disabledRanges[ruleName] = disabledRanges.all.map(({ start, end, description }) => + createDisableRange(start, false, description, end, false), ); } } diff --git a/lib/cli.js b/lib/cli.js index cf8179e083..80189a7759 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -39,6 +39,7 @@ const EXIT_CODE_ERROR = 2; * @property {string} [stdinFilename] * @property {boolean} [reportNeedlessDisables] * @property {boolean} [reportInvalidScopeDisables] + * @property {boolean} [reportDescriptionlessDisables] * @property {number} [maxWarnings] * @property {string | boolean} quiet * @property {string} [syntax] @@ -73,6 +74,7 @@ const EXIT_CODE_ERROR = 2; * @property {string} [outputFile] * @property {boolean} [reportNeedlessDisables] * @property {boolean} [reportInvalidScopeDisables] + * @property {boolean} [reportDescriptionlessDisables] * @property {boolean} [disableDefaultIgnores] * @property {number} [maxWarnings] * @property {string} [syntax] @@ -204,6 +206,11 @@ const meowOptions = { Report stylelint-disable comments that used for rules that don't exist within the configuration object. The process will exit with code ${EXIT_CODE_ERROR} if invalid scope disables are found. + --report-descriptionless-disables, --rdd + + Report stylelint-disable comments without a description. + The process will exit with code ${EXIT_CODE_ERROR} if descriptionless disables are found. + --max-warnings, --mw Number of warnings above which the process will exit with code ${EXIT_CODE_ERROR}. @@ -292,6 +299,10 @@ const meowOptions = { alias: 'q', type: 'boolean', }, + reportDescriptionlessDisables: { + alias: 'rdd', + type: 'boolean', + }, reportInvalidScopeDisables: { alias: 'risd', type: 'boolean', @@ -417,6 +428,7 @@ module.exports = (argv) => { const reportNeedlessDisables = cli.flags.reportNeedlessDisables; const reportInvalidScopeDisables = cli.flags.reportInvalidScopeDisables; + const reportDescriptionlessDisables = cli.flags.reportDescriptionlessDisables; if (reportNeedlessDisables) { optionsBase.reportNeedlessDisables = reportNeedlessDisables; @@ -426,6 +438,10 @@ module.exports = (argv) => { optionsBase.reportInvalidScopeDisables = reportInvalidScopeDisables; } + if (reportDescriptionlessDisables) { + optionsBase.reportDescriptionlessDisables = reportDescriptionlessDisables; + } + const maxWarnings = cli.flags.maxWarnings; if (maxWarnings !== undefined) { @@ -481,8 +497,18 @@ module.exports = (argv) => { .then((linted) => { const reports = []; + const report = disableOptionsReportStringFormatter( + linted.reportedDisables || [], + 'forbidden disable', + ); + + if (report) reports.push(report); + if (reportNeedlessDisables) { - const report = disableOptionsReportStringFormatter(linted.needlessDisables || []); + const report = disableOptionsReportStringFormatter( + linted.needlessDisables || [], + 'needless disable', + ); if (report) { reports.push(report); @@ -490,7 +516,21 @@ module.exports = (argv) => { } if (reportInvalidScopeDisables) { - const report = disableOptionsReportStringFormatter(linted.invalidScopeDisables || []); + const report = disableOptionsReportStringFormatter( + linted.invalidScopeDisables || [], + 'disable with invalid scope', + ); + + if (report) { + reports.push(report); + } + } + + if (reportDescriptionlessDisables) { + const report = disableOptionsReportStringFormatter( + linted.descriptionlessDisables || [], + 'descriptionless disable', + ); if (report) { reports.push(report); @@ -534,7 +574,7 @@ module.exports = (argv) => { * @returns {void} */ function handleError(err) { - process.stderr.write(err.stack); + process.stderr.write(err.stack + EOL); const exitCode = typeof err.code === 'number' ? err.code : 1; process.exitCode = exitCode; diff --git a/lib/createPlugin.js b/lib/createPlugin.js index b1233ce6d7..5e9ff6b25f 100644 --- a/lib/createPlugin.js +++ b/lib/createPlugin.js @@ -1,9 +1,11 @@ 'use strict'; +/** @typedef {import('stylelint').StylelintRule} StylelintRule */ + /** * @param {string} ruleName - * @param {Function} rule - * @returns {{ruleName: string, rule: Function}} + * @param {StylelintRule} rule + * @returns {{ruleName: string, rule: StylelintRule}} */ module.exports = function (ruleName, rule) { return { diff --git a/lib/descriptionlessDisables.js b/lib/descriptionlessDisables.js new file mode 100644 index 0000000000..6bfb634cce --- /dev/null +++ b/lib/descriptionlessDisables.js @@ -0,0 +1,52 @@ +'use strict'; + +/** @typedef {import('stylelint').RangeType} RangeType */ +/** @typedef {import('stylelint').DisableReportRange} DisableReportRange */ +/** @typedef {import('stylelint').StylelintDisableOptionsReport} StylelintDisableOptionsReport */ + +/** + * @param {import('stylelint').StylelintResult[]} results + * @returns {StylelintDisableOptionsReport} + */ +module.exports = function (results) { + /** @type {StylelintDisableOptionsReport} */ + const report = []; + + results.forEach((result) => { + // File with `CssSyntaxError` have not `_postcssResult` + if (!result._postcssResult) { + return; + } + + const rangeData = result._postcssResult.stylelint.disabledRanges; + + /** @type {import('stylelint').StylelintDisableReportEntry} */ + const entry = { source: result.source, ranges: [] }; + + Object.keys(rangeData).forEach((rule) => { + rangeData[rule].forEach((range) => { + if (range.description) return; + + // Avoid duplicates from stylelint-disable comments with multiple rules. + const alreadyReported = entry.ranges.find((existing) => { + return existing.start === range.start && existing.end === range.end; + }); + + if (alreadyReported) return; + + entry.ranges.push({ + rule, + start: range.start, + end: range.end, + unusedRule: rule, + }); + }); + }); + + if (entry.ranges.length > 0) { + report.push(entry); + } + }); + + return report; +}; diff --git a/lib/formatters/__tests__/disableOptionsReportStringFormatter.test.js b/lib/formatters/__tests__/disableOptionsReportStringFormatter.test.js index b6d5cdc743..28f336e465 100644 --- a/lib/formatters/__tests__/disableOptionsReportStringFormatter.test.js +++ b/lib/formatters/__tests__/disableOptionsReportStringFormatter.test.js @@ -7,36 +7,39 @@ const stripIndent = require('common-tags').stripIndent; describe('disableOptionsReportStringFormatter', () => { it('formatter stringified', () => { const actual = stripAnsi( - disableOptionsReportStringFormatterTest([ - { - source: 'foo', - ranges: [ - { start: 1, end: 3, unusedRule: 'baz' }, - { start: 7, unusedRule: 'all' }, - ], - }, - { - source: 'bar', - ranges: [ - { start: 19, end: 33, unusedRule: 'all' }, - { start: 99, end: 102, unusedRule: 'baz' }, - ], - }, - { - sourc: 'baz', - ranges: [], - }, - ]), + disableOptionsReportStringFormatterTest( + [ + { + source: 'foo', + ranges: [ + { start: 1, end: 3, rule: 'baz' }, + { start: 7, rule: 'all' }, + ], + }, + { + source: 'bar', + ranges: [ + { start: 19, end: 33, rule: 'all' }, + { start: 99, end: 102, rule: 'baz' }, + ], + }, + { + sourc: 'baz', + ranges: [], + }, + ], + 'wrong disable', + ), ); let expected = stripIndent` foo - unused rule: baz, start line: 1, end line: 3 - unused rule: all, start line: 7 + wrong disable: baz, start line: 1, end line: 3 + wrong disable: all, start line: 7 bar - unused rule: all, start line: 19, end line: 33 - unused rule: baz, start line: 99, end line: 102`; + wrong disable: all, start line: 19, end line: 33 + wrong disable: baz, start line: 99, end line: 102`; expected = `\n${expected}\n`; diff --git a/lib/formatters/disableOptionsReportStringFormatter.js b/lib/formatters/disableOptionsReportStringFormatter.js index 341f45ba67..3c1fcebe6d 100644 --- a/lib/formatters/disableOptionsReportStringFormatter.js +++ b/lib/formatters/disableOptionsReportStringFormatter.js @@ -15,9 +15,10 @@ function logFrom(fromValue) { /** * @param {import('stylelint').StylelintDisableOptionsReport} report + * @param {string} message * @returns {string} */ -module.exports = function (report) { +module.exports = function (report, message) { if (!report) return ''; let output = ''; @@ -32,7 +33,7 @@ module.exports = function (report) { output += chalk.underline(logFrom(sourceReport.source || '')) + '\n'; sourceReport.ranges.forEach((range) => { - output += `unused rule: ${range.unusedRule}, start line: ${range.start}`; + output += `${message}: ${range.rule}, start line: ${range.start}`; if (range.end !== undefined) { output += `, end line: ${range.end}`; diff --git a/lib/invalidScopeDisables.js b/lib/invalidScopeDisables.js index 4c572d5d0c..1249284cb0 100644 --- a/lib/invalidScopeDisables.js +++ b/lib/invalidScopeDisables.js @@ -1,7 +1,6 @@ 'use strict'; /** @typedef {import('stylelint').RangeType} RangeType */ -/** @typedef {import('stylelint').UnusedRange} UnusedRange */ /** @typedef {import('stylelint').StylelintDisableOptionsReport} StylelintDisableOptionsReport */ /** @@ -45,9 +44,10 @@ module.exports = function (results) { } sourceReport.ranges.push({ - unusedRule: rule, + rule, start: range.start, end: range.end, + unusedRule: rule, }); }); }); diff --git a/lib/needlessDisables.js b/lib/needlessDisables.js index 70c2886d74..70eae0f92a 100644 --- a/lib/needlessDisables.js +++ b/lib/needlessDisables.js @@ -3,7 +3,7 @@ const _ = require('lodash'); /** @typedef {import('stylelint').RangeType} RangeType */ -/** @typedef {import('stylelint').UnusedRange} UnusedRange */ +/** @typedef {import('stylelint').DisableReportRange} DisableReportRange */ /** @typedef {import('stylelint').StylelintDisableOptionsReport} StylelintDisableOptionsReport */ /** @@ -20,7 +20,7 @@ module.exports = function (results) { return; } - /** @type {{ranges: UnusedRange[], source: string}} */ + /** @type {{ranges: DisableReportRange[], source: string}} */ const unused = { source: result.source || '', ranges: [] }; /** @type {{[ruleName: string]: Array}} */ @@ -68,6 +68,7 @@ module.exports = function (results) { // mark this range as unused if (!range.used && !alreadyMarkedUnused) { unused.ranges.push({ + rule, start: range.start, end: range.end, unusedRule: rule, diff --git a/lib/prepareReturnValue.js b/lib/prepareReturnValue.js index 90f887c018..9319433cb2 100644 --- a/lib/prepareReturnValue.js +++ b/lib/prepareReturnValue.js @@ -1,7 +1,9 @@ 'use strict'; +const descriptionlessDisables = require('./descriptionlessDisables'); const invalidScopeDisables = require('./invalidScopeDisables'); const needlessDisables = require('./needlessDisables'); +const reportDisables = require('./reportDisables'); /** @typedef {import('stylelint').Formatter} Formatter */ /** @typedef {import('stylelint').StylelintResult} StylelintResult */ @@ -16,7 +18,12 @@ const needlessDisables = require('./needlessDisables'); * @returns {StylelintStandaloneReturnValue} */ function prepareReturnValue(stylelintResults, options, formatter) { - const { reportNeedlessDisables, reportInvalidScopeDisables, maxWarnings } = options; + const { + reportNeedlessDisables, + reportInvalidScopeDisables, + reportDescriptionlessDisables, + maxWarnings, + } = options; const errored = stylelintResults.some( (result) => result.errored || result.parseErrors.length > 0, @@ -27,6 +34,7 @@ function prepareReturnValue(stylelintResults, options, formatter) { errored, results: [], output: '', + reportedDisables: reportDisables(stylelintResults), }; if (reportNeedlessDisables) { @@ -37,6 +45,10 @@ function prepareReturnValue(stylelintResults, options, formatter) { returnValue.invalidScopeDisables = invalidScopeDisables(stylelintResults); } + if (reportDescriptionlessDisables) { + returnValue.descriptionlessDisables = descriptionlessDisables(stylelintResults); + } + if (maxWarnings !== undefined) { const foundWarnings = stylelintResults.reduce((count, file) => { return count + file.warnings.length; diff --git a/lib/reportDisables.js b/lib/reportDisables.js new file mode 100644 index 0000000000..a528fe7640 --- /dev/null +++ b/lib/reportDisables.js @@ -0,0 +1,71 @@ +'use strict'; + +const _ = require('lodash'); + +/** @typedef {import('stylelint').RangeType} RangeType */ +/** @typedef {import('stylelint').DisableReportRange} DisabledRange */ +/** @typedef {import('stylelint').StylelintDisableOptionsReport} StylelintDisableOptionsReport */ + +/** + * Returns a report describing which `results` (if any) contain disabled ranges + * for rules that disallow disables via `reportDisables: true`. + * + * @param {import('stylelint').StylelintResult[]} results + * @returns {StylelintDisableOptionsReport} + */ +module.exports = function (results) { + /** @type {StylelintDisableOptionsReport} */ + const report = []; + + results.forEach((result) => { + // File with `CssSyntaxError` don't have `_postcssResult`s. + if (!result._postcssResult) { + return; + } + + /** @type {{ranges: DisabledRange[], source: string}} */ + const reported = { source: result.source || '', ranges: [] }; + + /** @type {{[ruleName: string]: Array}} */ + const rangeData = result._postcssResult.stylelint.disabledRanges; + + if (!rangeData) return; + + const config = result._postcssResult.stylelint.config; + + // If no rules actually disallow disables, don't bother looking for ranges + // that correspond to disabled rules. + if (!Object.values(_.get(config, 'rules', {})).some(reportDisablesForRule)) { + return []; + } + + Object.keys(rangeData).forEach((rule) => { + rangeData[rule].forEach((range) => { + if (!reportDisablesForRule(_.get(config, ['rules', rule], []))) return; + + reported.ranges.push({ + rule, + start: range.start, + end: range.end, + unusedRule: rule, + }); + }); + }); + + reported.ranges = _.sortBy(reported.ranges, ['start', 'end']); + + report.push(reported); + }); + + return report; +}; + +/** + * @param {[any, object]|null} options + * @return {boolean} + */ +function reportDisablesForRule(options) { + if (!options) return false; + + return _.get(options[1], 'reportDisables', false); +} diff --git a/lib/reportUnknownRuleNames.js b/lib/reportUnknownRuleNames.js index e06f0f6722..6656bf5092 100644 --- a/lib/reportUnknownRuleNames.js +++ b/lib/reportUnknownRuleNames.js @@ -1,6 +1,6 @@ 'use strict'; -const leven = require('leven'); +const levenshtein = require('fastest-levenshtein'); const rules = require('./rules'); const MAX_LEVENSHTEIN_DISTANCE = 6; @@ -18,7 +18,7 @@ function extractSuggestions(ruleName) { } Object.keys(rules).forEach((existRuleName) => { - const distance = leven(existRuleName, ruleName); + const distance = levenshtein.distance(existRuleName, ruleName); if (distance <= MAX_LEVENSHTEIN_DISTANCE) { suggestions[distance - 1].push(existRuleName); diff --git a/lib/rules/at-rule-allowed-list/README.md b/lib/rules/at-rule-allowed-list/README.md index 8755baf322..995c21d40e 100644 --- a/lib/rules/at-rule-allowed-list/README.md +++ b/lib/rules/at-rule-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed at-rules. * At-rules like this */ ``` -This rule was previously called, and is aliased as, `at-rule-whitelist`. - ## Options `array|string`: `["array", "of", "unprefixed", "at-rules"]|"at-rule"` diff --git a/lib/rules/at-rule-blacklist/README.md b/lib/rules/at-rule-blacklist/README.md new file mode 100644 index 0000000000..454160549b --- /dev/null +++ b/lib/rules/at-rule-blacklist/README.md @@ -0,0 +1,52 @@ +# at-rule-blacklist + +**_Deprecated: Instead use the [`at-rule-disallowed-list`](../at-rule-disallowed-list/README.md) rule._** + +Specify a list of disallowed at-rules. + + +```css + @keyframes name {} +/** ↑ + * At-rules like this */ +``` + +## Options + +`array|string`: `["array", "of", "unprefixed", "at-rules"]|"at-rule"` + +Given: + +``` +["extend", "keyframes"] +``` + +The following patterns are considered violations: + + +```css +a { @extend placeholder; } +``` + + +```css +@keyframes name { + from { top: 10px; } + to { top: 20px; } +} +``` + + +```css +@-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } +} +``` + +The following patterns are _not_ considered violations: + + +```css +@import "path/to/file.css"; +``` diff --git a/lib/rules/at-rule-blacklist/__tests__/index.js b/lib/rules/at-rule-blacklist/__tests__/index.js new file mode 100644 index 0000000000..b7a1af7846 --- /dev/null +++ b/lib/rules/at-rule-blacklist/__tests__/index.js @@ -0,0 +1,197 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['extend'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'at-rule-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['extend', 'supports', 'keyframes'], + + accept: [ + { + code: 'a { color: pink; }', + description: 'Some random code.', + }, + { + code: '@mixin name ($p) {}', + description: '@rule not from a disallowed list.', + }, + ], + + reject: [ + { + code: 'a { @extend %placeholder; }', + message: messages.rejected('extend'), + line: 1, + column: 5, + description: '@rule from a disallowed list, is a Sass directive.', + }, + { + code: ` + a { + @extend + %placeholder; + } + `, + message: messages.rejected('extend'), + line: 3, + column: 9, + description: '@rule from a disallowed list; newline after its name.', + }, + { + code: ` + @keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('keyframes'), + line: 2, + description: '@rule from a disallowed list; independent rule.', + }, + { + code: ` + @Keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('Keyframes'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; messed case.', + }, + { + code: ` + @-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('-moz-keyframes'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; has vendor prefix.', + }, + { + code: ` + @-WEBKET-KEYFRAMES name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('-WEBKET-KEYFRAMES'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; has vendor prefix.', + }, + ], +}); + +testRule({ + ruleName, + + config: ['keyframes'], + + accept: [ + { + code: 'a { color: pink; }', + description: 'Some random code.', + }, + { + code: '@mixin name ($p) {}', + description: '@rule not from a disallowed list.', + }, + ], + + reject: [ + { + code: ` + @keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('keyframes'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule.', + }, + { + code: ` + @Keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('Keyframes'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; messed case.', + }, + { + code: ` + @-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('-moz-keyframes'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; has vendor prefix.', + }, + { + code: ` + @-WEBKET-KEYFRAMES name { + from { top: 10px; } + to { top: 20px; } + } + `, + message: messages.rejected('-WEBKET-KEYFRAMES'), + line: 2, + column: 7, + description: '@rule from a disallowed list; independent rule; has vendor prefix.', + }, + ], +}); + +testRule({ + ruleName, + syntax: 'less', + config: ['keyframes'], + + accept: [ + { + code: ` + .keyframes() { margin: 0; } + + span { .keyframes(); } + `, + description: 'ignore Less mixin which are treated as at-rule', + }, + ], +}); diff --git a/lib/rules/at-rule-blacklist/index.js b/lib/rules/at-rule-blacklist/index.js new file mode 100644 index 0000000000..3e056130e4 --- /dev/null +++ b/lib/rules/at-rule-blacklist/index.js @@ -0,0 +1,62 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'at-rule-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected at-rule "${name}"`, +}); + +function rule(listInput) { + // To allow for just a string as a parameter (not only arrays of strings) + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'at-rule-disallowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkAtRules((atRule) => { + const name = atRule.name; + + if (!isStandardSyntaxAtRule(atRule)) { + return; + } + + if (!list.includes(postcss.vendor.unprefixed(name).toLowerCase())) { + return; + } + + report({ + message: messages.rejected(name), + node: atRule, + result, + ruleName, + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/at-rule-disallowed-list/README.md b/lib/rules/at-rule-disallowed-list/README.md index 0baefb6134..336dc9d1a5 100644 --- a/lib/rules/at-rule-disallowed-list/README.md +++ b/lib/rules/at-rule-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed at-rules. * At-rules like this */ ``` -This rule was previously called, and is aliased as, `at-rule-blacklist`. - ## Options `array|string`: `["array", "of", "unprefixed", "at-rules"]|"at-rule"` diff --git a/lib/rules/at-rule-no-vendor-prefix/README.md b/lib/rules/at-rule-no-vendor-prefix/README.md index a84d210638..b39d3de552 100644 --- a/lib/rules/at-rule-no-vendor-prefix/README.md +++ b/lib/rules/at-rule-no-vendor-prefix/README.md @@ -9,6 +9,8 @@ Disallow vendor prefixes for at-rules. * This prefix */ ``` +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js b/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js index 37622f06af..006f727fda 100644 --- a/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/at-rule-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -18,22 +19,27 @@ testRule({ reject: [ { code: '@-webkit-keyframes { 0% { top: 0; } }', + fixed: '@keyframes { 0% { top: 0; } }', message: messages.rejected('-webkit-keyframes'), }, { code: '@-wEbKiT-kEyFrAmEs { 0% { top: 0; } }', + fixed: '@kEyFrAmEs { 0% { top: 0; } }', message: messages.rejected('-wEbKiT-kEyFrAmEs'), }, { code: '@-WEBKIT-KEYFRAMES { 0% { top: 0; } }', + fixed: '@KEYFRAMES { 0% { top: 0; } }', message: messages.rejected('-WEBKIT-KEYFRAMES'), }, { code: '@-moz-keyframes { 0% { top: 0; } }', + fixed: '@keyframes { 0% { top: 0; } }', message: messages.rejected('-moz-keyframes'), }, { code: '@-ms-viewport { orientation: landscape; }', + fixed: '@viewport { orientation: landscape; }', message: messages.rejected('-ms-viewport'), }, ], diff --git a/lib/rules/at-rule-no-vendor-prefix/index.js b/lib/rules/at-rule-no-vendor-prefix/index.js index 810b94c356..c3036f1974 100644 --- a/lib/rules/at-rule-no-vendor-prefix/index.js +++ b/lib/rules/at-rule-no-vendor-prefix/index.js @@ -14,7 +14,7 @@ const messages = ruleMessages(ruleName, { rejected: (p) => `Unexpected vendor-prefixed at-rule "@${p}"`, }); -function rule(actual) { +function rule(actual, options, context) { return function (root, result) { const validOptions = validateOptions(result, ruleName, { actual }); @@ -37,6 +37,12 @@ function rule(actual) { return; } + if (context.fix) { + atRule.name = isAutoprefixable.unprefix(atRule.name); + + return; + } + report({ message: messages.rejected(name), node: atRule, diff --git a/lib/rules/at-rule-property-required-list/README.md b/lib/rules/at-rule-property-required-list/README.md index 002bf1b02c..eb4eb944c6 100644 --- a/lib/rules/at-rule-property-required-list/README.md +++ b/lib/rules/at-rule-property-required-list/README.md @@ -9,8 +9,6 @@ Specify a list of required properties for an at-rule. * At-rule and required property names */ ``` -This rule was previously called, and is aliased as, `at-rule-requirelist`. - ## Options `object`: `{ "at-rule-name": ["array", "of", "properties"] }` diff --git a/lib/rules/at-rule-property-requirelist/README.md b/lib/rules/at-rule-property-requirelist/README.md new file mode 100644 index 0000000000..6108023b72 --- /dev/null +++ b/lib/rules/at-rule-property-requirelist/README.md @@ -0,0 +1,55 @@ +# at-rule-property-requirelist + +**_Deprecated: Instead use the [`at-rule-property-required-list`](../at-rule-property-required-list/README.md) rule._** + +Specify a list of required properties for an at-rule. + + +```css + @font-face { font-display: swap; font-family: 'foo'; } +/** ↑ ↑ ↑ + * At-rule and required property names */ +``` + +## Options + +`object`: `{ "at-rule-name": ["array", "of", "properties"] }` + +Given: + +``` +{ + "font-face": ["font-display", "font-family", "font-style"] +} +``` + +The following patterns are considered violations: + + +```css +@font-face { + font-family: 'foo'; + src: url('./fonts/foo.woff2') format('woff2'); +} +``` + + +```css +@font-face { + font-family: 'foo'; + font-style: normal; + src: url('./fonts/foo.woff2') format('woff2'); +} +``` + +The following patterns are _not_ considered violations: + + +```css +@font-face { + font-display: swap; + font-family: 'foo'; + font-style: normal; + src: url('./fonts/foo.woff2') format('woff2'); +} +``` diff --git a/lib/rules/at-rule-property-requirelist/__tests__/index.js b/lib/rules/at-rule-property-requirelist/__tests__/index.js new file mode 100644 index 0000000000..183e7643b4 --- /dev/null +++ b/lib/rules/at-rule-property-requirelist/__tests__/index.js @@ -0,0 +1,84 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: { page: ['margin'] }, + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'at-rule-property-required-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: { + 'font-face': ['font-display', 'font-family'], + page: ['margin'], + }, + + accept: [ + { + code: "@font-face { font-display: auto; font-family: 'Arvo'; }", + description: '@font-face with both required properties', + }, + { + code: "@font-face { font-display: auto; font-family: 'Arvo'; src: url('abc'); /* IE9 */ }", + description: '@font-face with inner comment', + }, + { + code: "@FONT-FACE { FONT-DISPLAY: AUTO; FONT-FAMILY: 'ARVO'; }", + description: '@font-face with both required properties (case-sensitive)', + }, + { + code: '@page { padding: 0.5cm; margin: 1cm; }', + description: '@page with required property', + }, + { + code: '@counter-style counter { system: cyclic; }', + description: 'at-rule not specified in config', + }, + { + code: '@mixin invalid-at-rule { @content; }', + description: '@mixin with invalid at-rule', + }, + ], + + reject: [ + { + code: '@font-face { font-display: auto; }', + description: '@font-face with missing property', + message: messages.expected('font-family', 'font-face'), + }, + { + code: '@FONT-FACE { FONT-DISPLAY: AUTO; }', + description: '@font-face with missing property (case-sensitive)', + message: messages.expected('font-family', 'font-face'), + }, + { + code: "@font-face { font-family: 'Arvo'; font-weight: normal }", + description: '@font-face with missing property', + message: messages.expected('font-display', 'font-face'), + }, + { + code: '@page { padding: 0.5cm }', + description: '@page with missing property', + message: messages.expected('margin', 'page'), + }, + ], +}); diff --git a/lib/rules/at-rule-property-requirelist/index.js b/lib/rules/at-rule-property-requirelist/index.js new file mode 100644 index 0000000000..e979f78b41 --- /dev/null +++ b/lib/rules/at-rule-property-requirelist/index.js @@ -0,0 +1,73 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'at-rule-property-requirelist'; + +const messages = ruleMessages(ruleName, { + expected: (property, atRule) => `Expected property "${property}" for at-rule "${atRule}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'at-rule-property-required-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkAtRules((atRule) => { + if (!isStandardSyntaxAtRule(atRule)) { + return; + } + + const { name, nodes } = atRule; + const atRuleName = name.toLowerCase(); + + if (!list[atRuleName]) { + return; + } + + list[atRuleName].forEach((property) => { + const propertyName = property.toLowerCase(); + + const hasProperty = nodes.find( + ({ type, prop }) => type === 'decl' && prop.toLowerCase() === propertyName, + ); + + if (hasProperty) { + return; + } + + return report({ + message: messages.expected(propertyName, atRuleName), + node: atRule, + result, + ruleName, + }); + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; + +module.exports = rule; diff --git a/lib/rules/at-rule-whitelist/README.md b/lib/rules/at-rule-whitelist/README.md new file mode 100644 index 0000000000..f6e0a006a3 --- /dev/null +++ b/lib/rules/at-rule-whitelist/README.md @@ -0,0 +1,67 @@ +# at-rule-whitelist + +**_Deprecated: Instead use the [`at-rule-allowed-list`](../at-rule-allowed-list/README.md) rule._** + +Specify a list of allowed at-rules. + + +```css + @keyframes name {} +/** ↑ + * At-rules like this */ +``` + +## Options + +`array|string`: `["array", "of", "unprefixed", "at-rules"]|"at-rule"` + +Given: + +``` +["extend", "keyframes"] +``` + +The following patterns are considered violations: + + +```css +@import "path/to/file.css"; +``` + + +```css +@media screen and (max-width: 1024px) { + a { display: none; } +} +``` + +The following patterns are _not_ considered violations: + + +```css +a { @extend placeholder; } +``` + + +```css +@keyframes name { + from { top: 10px; } + to { top: 20px; } +} +``` + + +```css +@KEYFRAMES name { + from { top: 10px; } + to { top: 20px; } +} +``` + + +```css +@-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } +} +``` diff --git a/lib/rules/at-rule-whitelist/__tests__/index.js b/lib/rules/at-rule-whitelist/__tests__/index.js new file mode 100644 index 0000000000..74f79a3e8c --- /dev/null +++ b/lib/rules/at-rule-whitelist/__tests__/index.js @@ -0,0 +1,190 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['extend'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'at-rule-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['extend', 'import', 'keyframes'], + + accept: [ + { + code: 'a { color: pink; }', + description: 'Some random code.', + }, + { + code: 'a { @extend %placeholder; }', + description: '@rule from an allowed list, is a Sass directive.', + }, + { + code: ` + a { + @extend + %placeholder; + } + `, + description: '@rule from an allowed list; newline after its name.', + }, + { + code: ` + @keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule.', + }, + { + code: ` + @Keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; messed case.', + }, + { + code: ` + @-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; has vendor prefix.', + }, + { + code: ` + @-WEBKET-KEYFRAMES name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; has vendor prefix.', + }, + ], + + reject: [ + { + code: ` + @mixin name () {} + `, + line: 2, + columt: 7, + message: messages.rejected('mixin'), + description: '@rule not from an allowed list; independent rule.', + }, + ], +}); + +testRule({ + ruleName, + skipBasicChecks: true, + + config: ['keyframes'], + + accept: [ + { + code: ` + @keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule.', + }, + { + code: ` + @Keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; messed case.', + }, + { + code: ` + @-moz-keyframes name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; has vendor prefix.', + }, + { + code: ` + @-WEBKET-KEYFRAMES name { + from { top: 10px; } + to { top: 20px; } + } + `, + description: '@rule from an allowed list; independent rule; has vendor prefix.', + }, + ], + + reject: [ + { + code: ` + @mixin name ($p) {} + `, + message: messages.rejected('mixin'), + line: 2, + column: 7, + description: '@rule not from an allowed list.', + }, + { + code: "@import 'path/to/file.css';", + message: messages.rejected('import'), + line: 1, + column: 1, + description: '@rule not from an allowed list.', + }, + { + code: '@media screen and (max-witdh: 1000px) {}', + message: messages.rejected('media'), + line: 1, + column: 1, + description: '@rule not from an allowed list.', + }, + ], +}); + +testRule({ + ruleName, + syntax: 'less', + config: ['keyframes'], + skipBasicChecks: true, + + accept: [ + { + code: ` + .mixin() { margin: 0; } + + span { .mixin(); } + `, + description: 'ignore Less mixin which are treated as at-rule', + }, + ], +}); diff --git a/lib/rules/at-rule-whitelist/index.js b/lib/rules/at-rule-whitelist/index.js new file mode 100644 index 0000000000..716ee578b7 --- /dev/null +++ b/lib/rules/at-rule-whitelist/index.js @@ -0,0 +1,62 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'at-rule-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected at-rule "${name}"`, +}); + +function rule(listInput) { + // To allow for just a string as a parameter (not only arrays of strings) + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'at-rule-allowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkAtRules((atRule) => { + const name = atRule.name; + + if (!isStandardSyntaxAtRule(atRule)) { + return; + } + + if (list.includes(postcss.vendor.unprefixed(name).toLowerCase())) { + return; + } + + report({ + message: messages.rejected(name), + node: atRule, + result, + ruleName, + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/comment-word-blacklist/README.md b/lib/rules/comment-word-blacklist/README.md new file mode 100644 index 0000000000..bcac8e8b90 --- /dev/null +++ b/lib/rules/comment-word-blacklist/README.md @@ -0,0 +1,50 @@ +# comment-word-blacklist + +**_Deprecated: Instead use the [`comment-word-disallowed-list`](../comment-word-disallowed-list/README.md) rule._** + +Specify a list of disallowed words within comments. + + +```css + /* words within comments */ +/** ↑ ↑ ↑ + * These three words */ +``` + +**Caveat:** Comments within _selector and value lists_ are currently ignored. + +## Options + +`array|string|regexp`: `["array", "of", "words", /or/, "/regex/"]|"word"|"/regex/"` + +If a string is surrounded with `"/"` (e.g. `"/^TODO:/"`), it is interpreted as a regular expression. + +Given: + +``` +["/^TODO:/", "badword"] +``` + +The following patterns are considered violations: + + +```css +/* TODO: */ +``` + + +```css +/* TODO: add fallback */ +``` + + +```css +/* some badword */ +``` + +The following patterns are _not_ considered violations: + + +```css +/* comment */ +``` diff --git a/lib/rules/comment-word-blacklist/__tests__/index.js b/lib/rules/comment-word-blacklist/__tests__/index.js new file mode 100644 index 0000000000..70a331716c --- /dev/null +++ b/lib/rules/comment-word-blacklist/__tests__/index.js @@ -0,0 +1,347 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['bad-word'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'comment-word-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['bad-word'], + + accept: [ + { + code: '/* comment */', + }, + { + code: '/*# bad-word */', + }, + ], + + reject: [ + { + code: '/* Comment with bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/* bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/*** bad-word ***/', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/*! bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/** bad-word **/', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + ], +}); + +testRule({ + ruleName, + config: ['/^TODO:/', 'bad-word'], + + accept: [ + { + code: '/* comment */', + }, + { + code: '/* comment comment */', + }, + { + code: '/* comment\ncomment */', + }, + { + code: '/* comment\n\ncomment */', + }, + { + code: '/** comment */', + }, + { + code: '/**** comment ***/', + }, + { + code: '/*\ncomment\n*/', + }, + { + code: '/*\tcomment */', + }, + { + code: '/*! copyright */', + }, + { + code: '/*# sourcemap */', + }, + { + code: '/*# sourcemap bad-word */', + }, + { + code: 'a { color: pink; /* comment */\ntop: 0; }', + }, + { + code: 'a {} /* comment */', + }, + { + code: '/* todo */', + }, + { + code: '/* todo: */', + }, + { + code: '/* todo: comment */', + }, + { + code: '/* tOdO: comment */', + }, + { + code: '/* Todo: comment */', + }, + { + code: '/*! Todo: comment */', + }, + { + code: '/*# Todo: comment */', + }, + { + code: '/** TODO: comment **/', + }, + { + code: '/*** TODO: comment ***/', + }, + ], + + reject: [ + { + code: '/* TODO: */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* TODO: comment */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* TODO: comment\n next line */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* TODO: comment\n next line */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* TODO: comment\r\n next line */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* TODO: comment\n\n next line */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/*\n TODO: comment */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/*\r\n TODO: comment */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/*\n\n TODO: comment */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/*\r\n\r\n TODO: comment */', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '/* bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/* Comment with bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/*! copyright bad-word */', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/** bad-word **/', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + { + code: '/*** bad-word ***/', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + ], +}); + +testRule({ + ruleName, + syntax: 'scss', + config: [['/^TODO:/', 'bad-word']], + + accept: [ + { + code: '// comment', + }, + { + code: '// todo', + }, + { + code: '// todo:', + }, + { + code: '// Todo:', + }, + { + code: '// tOdO:', + }, + ], + + reject: [ + { + code: '// TODO:', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '// TODO: comment', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '// bad-word', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + ], +}); + +testRule({ + ruleName, + syntax: 'less', + config: ['/^TODO:/', 'bad-word'], + + accept: [ + { + code: '// comment', + }, + { + code: '// todo:', + }, + { + code: '// Todo:', + }, + { + code: '// tOdO:', + }, + ], + + reject: [ + { + code: '// TODO:', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '// TODO: comment', + message: messages.rejected('/^TODO:/'), + line: 1, + column: 1, + }, + { + code: '// bad-word', + message: messages.rejected('bad-word'), + line: 1, + column: 1, + }, + ], +}); + +testRule({ + ruleName, + config: [/^TODO:/, 'bad-word'], + + accept: [ + { + code: '/* comment */', + }, + ], + + reject: [ + { + code: '/* TODO: */', + message: messages.rejected(/^TODO:/), + line: 1, + column: 1, + }, + ], +}); diff --git a/lib/rules/comment-word-blacklist/index.js b/lib/rules/comment-word-blacklist/index.js new file mode 100644 index 0000000000..b58df52d93 --- /dev/null +++ b/lib/rules/comment-word-blacklist/index.js @@ -0,0 +1,64 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const containsString = require('../../utils/containsString'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'comment-word-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (pattern) => `Unexpected word matching pattern "${pattern}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'comment-word-disallowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkComments((comment) => { + const text = comment.text; + const rawComment = comment.toString(); + const firstFourChars = rawComment.substr(0, 4); + + // Return early if sourcemap + if (firstFourChars === '/*# ') { + return; + } + + const matchesWord = matchesStringOrRegExp(text, list) || containsString(text, list); + + if (!matchesWord) { + return; + } + + report({ + message: messages.rejected(matchesWord.pattern), + node: comment, + result, + ruleName, + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/comment-word-disallowed-list/README.md b/lib/rules/comment-word-disallowed-list/README.md index 5578dc894a..814667b43c 100644 --- a/lib/rules/comment-word-disallowed-list/README.md +++ b/lib/rules/comment-word-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed words within comments. * These three words */ ``` -This rule was previously called, and is aliased as, `comment-word-blacklist`. - **Caveat:** Comments within _selector and value lists_ are currently ignored. ## Options diff --git a/lib/rules/custom-media-pattern/README.md b/lib/rules/custom-media-pattern/README.md index d95abf8bbd..d9dc628f56 100644 --- a/lib/rules/custom-media-pattern/README.md +++ b/lib/rules/custom-media-pattern/README.md @@ -17,8 +17,8 @@ A string will be translated into a RegExp like so `new RegExp(yourString)` —  Given the string: -```js -"foo-.+"; +``` +"foo-.+" ``` The following patterns are considered violations: diff --git a/lib/rules/custom-property-pattern/README.md b/lib/rules/custom-property-pattern/README.md index 9b4eeabe17..1382b9fc0b 100644 --- a/lib/rules/custom-property-pattern/README.md +++ b/lib/rules/custom-property-pattern/README.md @@ -17,8 +17,8 @@ A string will be translated into a RegExp like so `new RegExp(yourString)` —  Given the string: -```js -"foo-.+"; +``` +"foo-.+" ``` The following patterns are considered violations: diff --git a/lib/rules/declaration-property-unit-allowed-list/README.md b/lib/rules/declaration-property-unit-allowed-list/README.md index 8ff7d6d235..48a95c973d 100644 --- a/lib/rules/declaration-property-unit-allowed-list/README.md +++ b/lib/rules/declaration-property-unit-allowed-list/README.md @@ -9,8 +9,6 @@ a { width: 100px; } * These properties and these units */ ``` -This rule was previously called, and is aliased as, `declaration-property-unit-whitelist`. - ## Options `object`: `{ "unprefixed-property-name": ["array", "of", "units"] }` diff --git a/lib/rules/declaration-property-unit-blacklist/README.md b/lib/rules/declaration-property-unit-blacklist/README.md new file mode 100644 index 0000000000..7537255e43 --- /dev/null +++ b/lib/rules/declaration-property-unit-blacklist/README.md @@ -0,0 +1,76 @@ +# declaration-property-unit-blacklist + +**_Deprecated: Instead use the [`declaration-property-unit-disallowed-list`](../declaration-property-unit-disallowed-list/README.md) rule._** + +Specify a list of disallowed property and unit pairs within declarations. + + +```css +a { width: 100px; } +/** ↑ ↑ + * These properties and these units */ +``` + +## Options + +`object`: `{ "unprefixed-property-name": ["array", "of", "units"] }` + +If a property name is surrounded with `"/"` (e.g. `"/^animation/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^animation/` will match `animation`, `animation-duration`, `animation-timing-function`, etc. + +Given: + +``` +{ + "font-size": ["em", "px"], + "/^animation/": ["s"] +} +``` + +The following patterns are considered violations: + + +```css +a { font-size: 1em; } +``` + + +```css +a { animation: animation-name 5s ease; } +``` + + +```css +a { -webkit-animation: animation-name 5s ease; } +``` + + +```css +a { animation-duration: 5s; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { font-size: 1.2rem; } +``` + + +```css +a { height: 100px; } +``` + + +```css +a { animation: animation-name 500ms ease; } +``` + + +```css +a { -webkit-animation: animation-name 500ms ease; } +``` + + +```css +a { animation-duration: 500ms; } +``` diff --git a/lib/rules/declaration-property-unit-blacklist/__tests__/index.js b/lib/rules/declaration-property-unit-blacklist/__tests__/index.js new file mode 100644 index 0000000000..bf4f9a2fff --- /dev/null +++ b/lib/rules/declaration-property-unit-blacklist/__tests__/index.js @@ -0,0 +1,195 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [{ margin: ['em'] }], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-unit-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [ + { + 'font-size': ['px', 'em'], + margin: ['em'], + 'background-position': ['%'], + animation: ['s'], + }, + ], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { top: 0; }', + }, + { + code: 'a { color: #000; }', + }, + { + code: 'a { margin: 0 0 0 0 }', + }, + { + code: 'a { margin: 0 10px 5rem 2in; }', + }, + { + code: 'a { margin: 0 10pX 5rem 2in; }', + }, + { + code: 'a { margin: 0 10PX 5rem 2in; }', + }, + { + code: 'a { background-position: top right, 1em 5vh; }', + }, + { + code: 'a { margin: calc(30vh - 10vh); }', + }, + { + code: 'a { animation: animation-name 300ms ease; }', + }, + { + code: 'a { -webkit-animation: animation-name 300ms ease; }', + }, + { + code: 'a { animation-duration: 3s; }', + }, + { + code: 'a { -webkit-animation-duration: 3s; }', + }, + { + code: 'a { font-size: /* 100px */ 1.2rem; }', + description: 'ignore unit within comments', + }, + { + code: 'a::before { font-size: "10px"}', + description: 'ignore unit within quotes', + }, + { + code: 'a { font-size: $fs10px; }', + description: 'ignore preprocessor variable includes unit', + }, + { + code: 'a { font-size: --some-fs-10px; }', + description: 'ignore css variable includes unit', + }, + ], + + reject: [ + { + code: 'a { font-size: 12px; }', + message: messages.rejected('font-size', 'px'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 12pX; }', + message: messages.rejected('font-size', 'pX'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 12PX; }', + message: messages.rejected('font-size', 'PX'), + line: 1, + column: 16, + }, + { + code: 'a { margin: 10px 0 5em; }', + message: messages.rejected('margin', 'em'), + line: 1, + column: 20, + }, + { + code: 'a { background-position: 0 10%; }', + message: messages.rejected('background-position', '%'), + line: 1, + column: 28, + }, + { + code: 'a { background-position: top right, 0 10%; }', + message: messages.rejected('background-position', '%'), + line: 1, + column: 39, + }, + { + code: 'a { margin: calc(10vh - 10em); }', + message: messages.rejected('margin', 'em'), + column: 25, + }, + { + code: 'a { animation: foo 3s; }', + message: messages.rejected('animation', 's'), + }, + { + code: 'a { -webkit-animation: foo 3s; }', + message: messages.rejected('-webkit-animation', 's'), + }, + ], +}); + +testRule({ + ruleName, + + config: [ + { + '/^animation/': ['s'], + }, + ], + + skipBasicChecks: true, + + accept: [ + { + code: 'a { animation: animation-name 300ms ease; }', + }, + { + code: 'a { -webkit-animation: animation-name 300ms ease; }', + }, + { + code: 'a { animation-duration: 300ms; }', + }, + { + code: 'a { -webkit-animation-duration: 300ms; }', + }, + ], + + reject: [ + { + code: 'a { animation: animation-name 3s ease; }', + message: messages.rejected('animation', 's'), + }, + { + code: 'a { -webkit-animation: animation-name 3s ease; }', + message: messages.rejected('-webkit-animation', 's'), + }, + { + code: 'a { animation-duration: 3s; }', + message: messages.rejected('animation-duration', 's'), + }, + { + code: 'a { -webkit-animation-duration: 3s; }', + message: messages.rejected('-webkit-animation-duration', 's'), + }, + ], +}); diff --git a/lib/rules/declaration-property-unit-blacklist/index.js b/lib/rules/declaration-property-unit-blacklist/index.js new file mode 100644 index 0000000000..db1d840dd2 --- /dev/null +++ b/lib/rules/declaration-property-unit-blacklist/index.js @@ -0,0 +1,84 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const getUnitFromValueNode = require('../../utils/getUnitFromValueNode'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'declaration-property-unit-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (property, unit) => `Unexpected unit "${unit}" for property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-unit-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + const prop = decl.prop; + const value = decl.value; + + const unprefixedProp = postcss.vendor.unprefixed(prop); + + const propList = _.find(list, (units, propIdentifier) => + matchesStringOrRegExp(unprefixedProp, propIdentifier), + ); + + if (!propList) { + return; + } + + valueParser(value).walk((node) => { + // Ignore wrong units within `url` function + if (node.type === 'function' && node.value.toLowerCase() === 'url') { + return false; + } + + if (node.type === 'string') { + return; + } + + const unit = getUnitFromValueNode(node); + + if (!unit || (unit && !propList.includes(unit.toLowerCase()))) { + return; + } + + report({ + message: messages.rejected(prop, unit), + node: decl, + index: declarationValueIndex(decl) + node.sourceIndex, + result, + ruleName, + }); + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/declaration-property-unit-disallowed-list/README.md b/lib/rules/declaration-property-unit-disallowed-list/README.md index 50d0cc81f0..088d42a3af 100644 --- a/lib/rules/declaration-property-unit-disallowed-list/README.md +++ b/lib/rules/declaration-property-unit-disallowed-list/README.md @@ -9,8 +9,6 @@ a { width: 100px; } * These properties and these units */ ``` -This rule was previously called, and is aliased as, `declaration-property-unit-blacklist`. - ## Options `object`: `{ "unprefixed-property-name": ["array", "of", "units"] }` diff --git a/lib/rules/declaration-property-unit-whitelist/README.md b/lib/rules/declaration-property-unit-whitelist/README.md new file mode 100644 index 0000000000..da73901d63 --- /dev/null +++ b/lib/rules/declaration-property-unit-whitelist/README.md @@ -0,0 +1,87 @@ +# declaration-property-unit-whitelist + +**_Deprecated: Instead use the [`declaration-property-unit-allowed-list`](../declaration-property-unit-allowed-list/README.md) rule._** + +Specify a list of allowed property and unit pairs within declarations. + + +```css +a { width: 100px; } +/** ↑ ↑ + * These properties and these units */ +``` + +## Options + +`object`: `{ "unprefixed-property-name": ["array", "of", "units"] }` + +If a property name is surrounded with `"/"` (e.g. `"/^animation/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^animation/` will match `animation`, `animation-duration`, `animation-timing-function`, etc. + +Given: + +``` +{ + "font-size": ["em", "px"], + "/^animation/": ["s"], + "line-height": [] +} +``` + +The following patterns are considered violations: + + +```css +a { font-size: 1.2rem; } +``` + + +```css +a { animation: animation-name 500ms ease; } +``` + + +```css +a { -webkit-animation: animation-name 500ms ease; } +``` + + +```css +a { animation-duration: 500ms; } +``` + + +```css +a { line-height: 13px; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { font-size: 1em; } +``` + + +```css +a { height: 100px; } +``` + + +```css +a { animation: animation-name 5s ease; } +``` + + +```css +a { -webkit-animation: animation-name 5s ease; } +``` + + +```css +a { animation-duration: 5s; } +``` + + +```css +a { line-height: 1; } +``` diff --git a/lib/rules/declaration-property-unit-whitelist/__tests__/index.js b/lib/rules/declaration-property-unit-whitelist/__tests__/index.js new file mode 100644 index 0000000000..9850fb4cfc --- /dev/null +++ b/lib/rules/declaration-property-unit-whitelist/__tests__/index.js @@ -0,0 +1,200 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [{ margin: ['em'] }], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-unit-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [ + { + 'font-size': ['px', 'em'], + margin: ['em'], + 'background-position': ['%'], + animation: ['s'], + 'line-height': [], + }, + ], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { top: 0; }', + }, + { + code: 'a { color: #000; }', + }, + { + code: 'a { margin: 0 0 0 0; }', + }, + { + code: 'a { margin: 0 10em; }', + }, + { + code: 'a { margin: 0 10eM; }', + }, + { + code: 'a { margin: 0 10EM; }', + }, + { + code: 'a { background-position: top right, 0 50%; }', + }, + { + code: 'a { margin: calc(30em - 10em); }', + }, + { + code: 'a { animation: animation-name 1s ease; }', + }, + { + code: 'a { -webkit-animation: animation-name 1s ease; }', + }, + { + code: 'a { line-height: 1; }', + }, + { + code: 'a { font-size: /* 1.2rem */ 12px; }', + description: 'ignore unit within comments', + }, + { + code: 'a::before { font-size: "1.2rem"}', + description: 'ignore unit within quotes', + }, + { + code: 'a { font-size: $fs1rem; }', + description: 'ignore preprocessor variable includes unit', + }, + { + code: 'a { font-size: --some-fs-1rem; }', + description: 'ignore css variable includes unit', + }, + ], + + reject: [ + { + code: 'a { font-size: 1.2rem; }', + message: messages.rejected('font-size', 'rem'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 1.2rEm; }', + message: messages.rejected('font-size', 'rEm'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 1.2REM; }', + message: messages.rejected('font-size', 'REM'), + line: 1, + column: 16, + }, + { + code: 'a { margin: 10em 0 1rem; }', + message: messages.rejected('margin', 'rem'), + line: 1, + column: 20, + }, + { + code: 'a { background-position: 0 10px; }', + message: messages.rejected('background-position', 'px'), + line: 1, + column: 28, + }, + { + code: 'a { background-position: top right, 0 10px; }', + message: messages.rejected('background-position', 'px'), + line: 1, + column: 39, + }, + { + code: 'a { margin: calc(10em - 10px); }', + message: messages.rejected('margin', 'px'), + column: 25, + }, + { + code: 'a { animation: animation-name 300ms ease; }', + message: messages.rejected('animation', 'ms'), + column: 31, + }, + { + code: 'a { -webkit-animation: animation-name 300ms ease; }', + message: messages.rejected('-webkit-animation', 'ms'), + column: 39, + }, + { + code: 'a { line-height: 1.2em; }', + message: messages.rejected('line-height', 'em'), + column: 18, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + { + '/^animation/': ['ms'], + }, + ], + + skipBasicChecks: true, + + accept: [ + { + code: 'a { animation: animation-name 300ms ease; }', + }, + { + code: 'a { -webkit-animation: animation-name 300ms ease; }', + }, + { + code: 'a { animation-duration: 300ms; }', + }, + { + code: 'a { -webkit-animation-duration: 300ms; }', + }, + ], + + reject: [ + { + code: 'a { animation: animation-name 3s ease; }', + message: messages.rejected('animation', 's'), + }, + { + code: 'a { -webkit-animation: animation-name 3s ease; }', + message: messages.rejected('-webkit-animation', 's'), + }, + { + code: 'a { animation-duration: 3s; }', + message: messages.rejected('animation-duration', 's'), + }, + { + code: 'a { -webkit-animation-duration: 3s; }', + message: messages.rejected('-webkit-animation-duration', 's'), + }, + ], +}); diff --git a/lib/rules/declaration-property-unit-whitelist/index.js b/lib/rules/declaration-property-unit-whitelist/index.js new file mode 100644 index 0000000000..cd2dc9eef0 --- /dev/null +++ b/lib/rules/declaration-property-unit-whitelist/index.js @@ -0,0 +1,84 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const getUnitFromValueNode = require('../../utils/getUnitFromValueNode'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'declaration-property-unit-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (property, unit) => `Unexpected unit "${unit}" for property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-unit-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + const prop = decl.prop; + const value = decl.value; + + const unprefixedProp = postcss.vendor.unprefixed(prop); + + const propList = _.find(list, (units, propIdentifier) => + matchesStringOrRegExp(unprefixedProp, propIdentifier), + ); + + if (!propList) { + return; + } + + valueParser(value).walk((node) => { + // Ignore wrong units within `url` function + if (node.type === 'function' && node.value.toLowerCase() === 'url') { + return false; + } + + if (node.type === 'string') { + return; + } + + const unit = getUnitFromValueNode(node); + + if (!unit || (unit && propList.indexOf(unit.toLowerCase())) !== -1) { + return; + } + + report({ + message: messages.rejected(prop, unit), + node: decl, + index: declarationValueIndex(decl) + node.sourceIndex, + result, + ruleName, + }); + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/declaration-property-value-allowed-list/README.md b/lib/rules/declaration-property-value-allowed-list/README.md index 32ff898097..41371ddd09 100644 --- a/lib/rules/declaration-property-value-allowed-list/README.md +++ b/lib/rules/declaration-property-value-allowed-list/README.md @@ -9,8 +9,6 @@ a { text-transform: uppercase; } * These properties and these values */ ``` -This rule was previously called, and is aliased as, `declaration-property-value-whitelist`. - ## Options `object`: `{ "unprefixed-property-name": ["array", "of", "values"], "unprefixed-property-name": ["/regex/", "non-regex"] }` diff --git a/lib/rules/declaration-property-value-blacklist/README.md b/lib/rules/declaration-property-value-blacklist/README.md new file mode 100644 index 0000000000..9edd6c9b1d --- /dev/null +++ b/lib/rules/declaration-property-value-blacklist/README.md @@ -0,0 +1,107 @@ +# declaration-property-value-blacklist + +**_Deprecated: Instead use the [`declaration-property-value-disallowed-list`](../declaration-property-value-disallowed-list/README.md) rule._** + +Specify a list of disallowed property and value pairs within declarations. + + +```css +a { text-transform: uppercase; } +/** ↑ ↑ + * These properties and these values */ +``` + +## Options + +`object`: `{ "unprefixed-property-name": ["array", "of", "values"], "unprefixed-property-name": ["/regex/", "non-regex", /regex/] }` + +If a property name is surrounded with `"/"` (e.g. `"/^animation/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^animation/` will match `animation`, `animation-duration`, `animation-timing-function`, etc. + +The same goes for values. Keep in mind that a regular expression value is matched against the entire value of the declaration, not specific parts of it. For example, a value like `"10px solid rgba( 255 , 0 , 0 , 0.5 )"` will _not_ match `"/^solid/"` (notice beginning of the line boundary) but _will_ match `"/\\s+solid\\s+/"` or `"/\\bsolid\\b/"`. + +Be careful with regex matching not to accidentally consider quoted string values and `url()` arguments. For example, `"/red/"` will match value such as `"1px dotted red"` as well as `"\"foo\""` and `"white url(/mysite.com/red.png)"`. + +Given: + +``` +{ + "transform": ["/scale3d/", "/rotate3d/", "/translate3d/"], + "position": ["fixed"], + "color": ["/^green/"], + "/^animation/": ["/ease/"] +} +``` + +The following patterns are considered violations: + + +```css +a { position: fixed; } +``` + + +```css +a { transform: scale3d(1, 2, 3); } +``` + + +```css +a { -webkit-transform: scale3d(1, 2, 3); } +``` + + +```css +a { color: green; } +``` + + +```css +a { animation: foo 2s ease-in-out; } +``` + + +```css +a { animation-timing-function: ease-in-out; } +``` + + +```css +a { -webkit-animation-timing-function: ease-in-out; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { position: relative; } +``` + + +```css +a { transform: scale(2); } +``` + + +```css +a { -webkit-transform: scale(2); } +``` + + +```css +a { color: lightgreen; } +``` + + +```css +a { animation: foo 2s linear; } +``` + + +```css +a { animation-timing-function: linear; } +``` + + +```css +a { -webkit-animation-timing-function: linear; } +``` diff --git a/lib/rules/declaration-property-value-blacklist/__tests__/index.js b/lib/rules/declaration-property-value-blacklist/__tests__/index.js new file mode 100644 index 0000000000..a1d3005a29 --- /dev/null +++ b/lib/rules/declaration-property-value-blacklist/__tests__/index.js @@ -0,0 +1,210 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [{ color: ['red'] }], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-value-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [ + { + // regular string + 'text-transform': ['uppercase'], + // regexes + transform: ['/scale3d/', '/rotate3d/', '/translate3d/'], + // mixed string and regex + color: ['red', 'green', 'blue', '/^sea/'], + }, + ], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { color: lightgreen; }', + }, + { + code: 'a { text-transform: lowercase; }', + }, + { + code: 'a { transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0) translate(12px, 50%); }', + }, + { + code: 'a { -webkit-transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0) translate(12px, 50%); }', + }, + { + code: 'a { color: /* red */ pink; }', + description: 'ignore value within comments', + }, + { + code: 'a::before { color: "red"}', + description: 'ignore value within quotes', + }, + { + code: 'a { color: $red; }', + description: 'ignore preprocessor variable includes value', + }, + { + code: 'a { color: --some-red; }', + description: 'ignore css variable includes value', + }, + { + code: 'a { color: darkseagreen }', + }, + ], + + reject: [ + { + code: 'a { color: red; }', + message: messages.rejected('color', 'red'), + line: 1, + column: 5, + }, + { + code: 'a { color: green }', + message: messages.rejected('color', 'green'), + line: 1, + column: 5, + }, + { + code: 'a { text-transform: uppercase; }', + message: messages.rejected('text-transform', 'uppercase'), + line: 1, + column: 5, + }, + { + code: 'a { transform: scale3d(1, 2, 3) }', + message: messages.rejected('transform', 'scale3d(1, 2, 3)'), + line: 1, + column: 5, + }, + { + code: 'a { -webkit-transform: scale3d(1, 2, 3) }', + message: messages.rejected('-webkit-transform', 'scale3d(1, 2, 3)'), + column: 5, + }, + { + code: 'a { color: seagreen }', + message: messages.rejected('color', 'seagreen'), + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + { + '/^animation/': ['/ease/'], + }, + ], + + skipBasicChecks: true, + + accept: [ + { + code: 'a { animation: foo 1s linear; }', + }, + { + code: 'a { -webkit-animation: foo 1s linear; }', + }, + { + code: 'a { animation-timing-function: linear; }', + }, + { + code: 'a { -webkit-animation-timing-function: linear; }', + }, + ], + + reject: [ + { + code: 'a { animation: foo 1s ease-in-out; }', + message: messages.rejected('animation', 'foo 1s ease-in-out'), + }, + { + code: 'a { -webkit-animation: foo 1s ease-in-out; }', + message: messages.rejected('-webkit-animation', 'foo 1s ease-in-out'), + }, + { + code: 'a { animation-timing-function: ease-in-out; }', + message: messages.rejected('animation-timing-function', 'ease-in-out'), + }, + { + code: 'a { -webkit-animation-timing-function: ease-in-out; }', + message: messages.rejected('-webkit-animation-timing-function', 'ease-in-out'), + }, + ], +}); + +testRule({ + ruleName, + + config: [ + { + '/^animation/': [/ease/], + }, + ], + + skipBasicChecks: true, + + accept: [ + { + code: 'a { animation: foo 1s linear; }', + }, + ], + + reject: [ + { + code: 'a { animation: foo 1s ease-in-out; }', + message: messages.rejected('animation', 'foo 1s ease-in-out'), + }, + { + code: 'a { -webkit-animation: foo 1s ease-in-out; }', + message: messages.rejected('-webkit-animation', 'foo 1s ease-in-out'), + }, + { + code: 'a { animation-timing-function: ease-in-out; }', + message: messages.rejected('animation-timing-function', 'ease-in-out'), + }, + { + code: 'a { -webkit-animation-timing-function: ease-in-out; }', + message: messages.rejected('-webkit-animation-timing-function', 'ease-in-out'), + }, + ], +}); + +testRule({ + ruleName, + config: { position: ['fixed'] }, + skipBasicChecks: true, + accept: [ + { + code: 'a { font-size: 1em; }', + description: 'irrelevant CSS', + }, + ], +}); diff --git a/lib/rules/declaration-property-value-blacklist/index.js b/lib/rules/declaration-property-value-blacklist/index.js new file mode 100644 index 0000000000..3550bf70e4 --- /dev/null +++ b/lib/rules/declaration-property-value-blacklist/index.js @@ -0,0 +1,66 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'declaration-property-value-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (property, value) => `Unexpected value "${value}" for property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-value-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + const prop = decl.prop; + const value = decl.value; + + const unprefixedProp = postcss.vendor.unprefixed(prop); + const propList = _.find(list, (values, propIdentifier) => + matchesStringOrRegExp(unprefixedProp, propIdentifier), + ); + + if (_.isEmpty(propList)) { + return; + } + + if (!matchesStringOrRegExp(value, propList)) { + return; + } + + report({ + message: messages.rejected(prop, value), + node: decl, + result, + ruleName, + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/declaration-property-value-disallowed-list/README.md b/lib/rules/declaration-property-value-disallowed-list/README.md index ea583a2f9f..982799a29d 100644 --- a/lib/rules/declaration-property-value-disallowed-list/README.md +++ b/lib/rules/declaration-property-value-disallowed-list/README.md @@ -9,8 +9,6 @@ a { text-transform: uppercase; } * These properties and these values */ ``` -This rule was previously called, and is aliased as, `declaration-property-value-blacklist`. - ## Options `object`: `{ "unprefixed-property-name": ["array", "of", "values"], "unprefixed-property-name": ["/regex/", "non-regex", /regex/] }` diff --git a/lib/rules/declaration-property-value-whitelist/README.md b/lib/rules/declaration-property-value-whitelist/README.md new file mode 100644 index 0000000000..2e7f2b9848 --- /dev/null +++ b/lib/rules/declaration-property-value-whitelist/README.md @@ -0,0 +1,98 @@ +# declaration-property-value-whitelist + +**_Deprecated: Instead use the [`declaration-property-value-allowed-list`](../declaration-property-value-allowed-list/README.md) rule._** + +Specify a list of allowed property and value pairs within declarations. + + +```css +a { text-transform: uppercase; } +/** ↑ ↑ + * These properties and these values */ +``` + +## Options + +`object`: `{ "unprefixed-property-name": ["array", "of", "values"], "unprefixed-property-name": ["/regex/", "non-regex"] }` + +If a property name is found in the object, only the listed property values are allowed. This rule complains about all non-matching values. (If the property name is not included in the object, anything goes.) + +If a property name is surrounded with `"/"` (e.g. `"/^animation/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^animation/` will match `animation`, `animation-duration`, `animation-timing-function`, etc. + +The same goes for values. Keep in mind that a regular expression value is matched against the entire value of the declaration, not specific parts of it. For example, a value like `"10px solid rgba( 255 , 0 , 0 , 0.5 )"` will _not_ match `"/^solid/"` (notice beginning of the line boundary) but _will_ match `"/\\s+solid\\s+/"` or `"/\\bsolid\\b/"`. + +Be careful with regex matching not to accidentally consider quoted string values and `url()` arguments. For example, `"/red/"` will match value such as `"1px dotted red"` as well as `"\"red\""` and `"white url(/mysite.com/red.png)"`. + +Given: + +``` +{ + "transform": ["/scale/"], + "whitespace": ["nowrap"], + "/color/": ["/^green/"] +} +``` + +The following patterns are considered violations: + + +```css +a { whitespace: pre; } +``` + + +```css +a { transform: translate(1, 1); } +``` + + +```css +a { -webkit-transform: translate(1, 1); } +``` + + +```css +a { color: pink; } +``` + + +```css +a { background-color: pink; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { color: pink; } +``` + + +```css +a { whitespace: nowrap; } +``` + + +```css +a { transform: scale(1, 1); } +``` + + +```css +a { -webkit-transform: scale(1, 1); } +``` + + +```css +a { color: green; } +``` + + +```css +a { background-color: green; } +``` + + +```css +a { background: pink; } +``` diff --git a/lib/rules/declaration-property-value-whitelist/__tests__/index.js b/lib/rules/declaration-property-value-whitelist/__tests__/index.js new file mode 100644 index 0000000000..7f674ab4b7 --- /dev/null +++ b/lib/rules/declaration-property-value-whitelist/__tests__/index.js @@ -0,0 +1,101 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [{ transform: ['/scale/'] }], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-value-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [ + { + transform: ['/scale/'], + whitespace: ['nowrap'], + '/color/': ['/^green/'], + }, + ], + + accept: [ + { + code: 'div { whitespace: nowrap; }', + }, + { + code: 'a { transform: scale(1, 1); }', + }, + { + code: 'a { -webkit-transform: scale(1, 1); }', + }, + { + code: 'a { color: green; }', + }, + { + code: 'a { background-color: green; }', + }, + ], + + reject: [ + { + code: 'div { whitespace: pre; }', + message: messages.rejected('whitespace', 'pre'), + line: 1, + column: 7, + }, + { + code: 'a { transform: translate(1, 1); }', + message: messages.rejected('transform', 'translate(1, 1)'), + line: 1, + column: 5, + }, + { + code: 'a { -webkit-transform: translate(1, 1); }', + message: messages.rejected('-webkit-transform', 'translate(1, 1)'), + line: 1, + column: 5, + }, + { + code: 'a { color: pink; }', + message: messages.rejected('color', 'pink'), + line: 1, + column: 5, + }, + { + code: 'a { background-color: pink; }', + message: messages.rejected('background-color', 'pink'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + config: { position: ['static'] }, + skipBasicChecks: true, + accept: [ + { + code: 'a { font-size: 1em; }', + description: 'irrelevant CSS', + }, + ], +}); diff --git a/lib/rules/declaration-property-value-whitelist/index.js b/lib/rules/declaration-property-value-whitelist/index.js new file mode 100644 index 0000000000..3a20e2b340 --- /dev/null +++ b/lib/rules/declaration-property-value-whitelist/index.js @@ -0,0 +1,66 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'declaration-property-value-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (property, value) => `Unexpected value "${value}" for property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'declaration-property-value-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + const prop = decl.prop; + const value = decl.value; + + const unprefixedProp = postcss.vendor.unprefixed(prop); + const propList = _.find(list, (values, propIdentifier) => + matchesStringOrRegExp(unprefixedProp, propIdentifier), + ); + + if (_.isEmpty(propList)) { + return; + } + + if (matchesStringOrRegExp(value, propList)) { + return; + } + + report({ + message: messages.rejected(prop, value), + node: decl, + result, + ruleName, + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/function-allowed-list/README.md b/lib/rules/function-allowed-list/README.md index e8229a835a..92b304d491 100644 --- a/lib/rules/function-allowed-list/README.md +++ b/lib/rules/function-allowed-list/README.md @@ -9,8 +9,6 @@ a { transform: scale(1); } * This function */ ``` -This rule was previously called, and is aliased as, `function-whitelist`. - ## Options `array|string`: `["array", "of", "unprefixed", /functions/ or "regex"]|"function"|"/regex/"` diff --git a/lib/rules/function-blacklist/README.md b/lib/rules/function-blacklist/README.md new file mode 100644 index 0000000000..9cb80e361c --- /dev/null +++ b/lib/rules/function-blacklist/README.md @@ -0,0 +1,54 @@ +# function-blacklist + +**_Deprecated: Instead use the [`function-disallowed-list`](../function-disallowed-list/README.md) rule._** + +Specify a list of disallowed functions. + + +```css +a { transform: scale(1); } +/** ↑ + * This function */ +``` + +## Options + +`array|string`: `["array", "of", "unprefixed", /functions/ or "regex"]|"function"|"/regex/"` + +If a string is surrounded with `"/"` (e.g. `"/^rgb/"`), it is interpreted as a regular expression. + +Given: + +``` +["scale", "rgba", "linear-gradient"] +``` + +The following patterns are considered violations: + + +```css +a { transform: scale(1); } +``` + + +```css +a { + color: rgba(0, 0, 0, 0.5); +} +``` + + +```css +a { + background: + red, + -moz-linear-gradient(45deg, blue, red); +} +``` + +The following patterns are _not_ considered violations: + + +```css +a { background: red; } +``` diff --git a/lib/rules/function-blacklist/__tests__/index.js b/lib/rules/function-blacklist/__tests__/index.js new file mode 100644 index 0000000000..7d7db8d4ff --- /dev/null +++ b/lib/rules/function-blacklist/__tests__/index.js @@ -0,0 +1,243 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['rgba'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'function-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['rgba', 'scale', 'linear-gradient'], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { transform: SCALE(1); }', + }, + { + code: 'a { transform: sCaLe(1); }', + }, + { + code: 'a { transform: rotate(7deg) }', + }, + { + code: 'a { transform: rOtAtE(7deg) }', + }, + { + code: 'a { transform: ROTATE(7deg) }', + }, + { + code: 'a { background: -webkit-radial-gradient(red, green, blue); }', + }, + { + code: 'a { color: color(rgb(0, 0, 0) lightness(50%)); }', + }, + { + code: '@media (max-width: 10px) { a { color: color(rgb(0, 0, 0) lightness(50%)); } }', + }, + { + code: '$scale: (value, value2)', + description: 'Sass list ignored', + }, + ], + + reject: [ + { + code: 'a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 16, + }, + { + code: 'a { transform : scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 17, + }, + { + code: 'a\n{ transform: scale(1); }', + message: messages.rejected('scale'), + line: 2, + column: 14, + }, + { + code: 'a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 19, + }, + { + code: ' a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 18, + }, + { + code: 'a { color: rgba(0, 0, 0, 0) }', + message: messages.rejected('rgba'), + line: 1, + column: 12, + }, + { + code: 'a { color: color(rgba(0, 0, 0, 0) lightness(50%)); }', + message: messages.rejected('rgba'), + line: 1, + column: 18, + }, + { + code: 'a { background: red, -moz-linear-gradient(45deg, blue, red); }', + message: messages.rejected('-moz-linear-gradient'), + line: 1, + column: 22, + }, + { + code: '@media (max-width: 10px) { a { color: color(rgba(0, 0, 0) lightness(50%)); } }', + message: messages.rejected('rgba'), + line: 1, + column: 45, + }, + ], +}); + +testRule({ + ruleName, + + config: ['/rgb/'], + + accept: [ + { + code: 'a { color: hsl(208, 100%, 97%); }', + }, + ], + + reject: [ + { + code: 'a { color: rgb(0, 0, 0); }', + message: messages.rejected('rgb'), + line: 1, + column: 12, + }, + { + code: 'a { color: rgba(0, 0, 0); }', + message: messages.rejected('rgba'), + line: 1, + column: 12, + }, + ], +}); + +testRule({ + ruleName, + + config: [/rgb/], + + accept: [ + { + code: 'a { color: hsl(208, 100%, 97%); }', + }, + ], + + reject: [ + { + code: 'a { color: rgb(0, 0, 0); }', + message: messages.rejected('rgb'), + line: 1, + column: 12, + }, + { + code: 'a { color: rgba(0, 0, 0); }', + message: messages.rejected('rgba'), + line: 1, + column: 12, + }, + ], +}); + +testRule({ + ruleName, + + config: ['skewx', 'translateX', 'SCALEX', '/rotate/i', '/MATRIX/'], + + accept: [ + { + code: 'a { transform: stewX(10deg); }', + }, + { + code: 'a { transform: translateY(5px); }', + }, + { + code: 'a { transform: scaleX(1); }', + }, + { + code: 'a { transform: matrix3d(a1); }', + }, + ], + + reject: [ + { + code: 'a { transform: skewx(10deg); }', + message: messages.rejected('skewx'), + line: 1, + column: 16, + }, + { + code: 'a { transform: translateX(5px); }', + message: messages.rejected('translateX'), + line: 1, + column: 16, + }, + { + code: 'a { transform: SCALEX(1); }', + message: messages.rejected('SCALEX'), + line: 1, + column: 16, + }, + { + code: 'a { transform: rotatex(60deg); }', + message: messages.rejected('rotatex'), + line: 1, + column: 16, + }, + { + code: 'a { transform: rotateX(60deg); }', + message: messages.rejected('rotateX'), + line: 1, + column: 16, + }, + { + code: 'a { transform: ROTATEX(60deg); }', + message: messages.rejected('ROTATEX'), + line: 1, + column: 16, + }, + { + code: 'a { transform: MATRIX3d(a1); }', + message: messages.rejected('MATRIX3d'), + line: 1, + column: 16, + }, + ], +}); diff --git a/lib/rules/function-blacklist/index.js b/lib/rules/function-blacklist/index.js new file mode 100644 index 0000000000..e26654a22d --- /dev/null +++ b/lib/rules/function-blacklist/index.js @@ -0,0 +1,69 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const isStandardSyntaxFunction = require('../../utils/isStandardSyntaxFunction'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'function-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected function "${name}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'function-disallowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkDecls((decl) => { + const value = decl.value; + + valueParser(value).walk((node) => { + if (node.type !== 'function') { + return; + } + + if (!isStandardSyntaxFunction(node)) { + return; + } + + if (!matchesStringOrRegExp(postcss.vendor.unprefixed(node.value), list)) { + return; + } + + report({ + message: messages.rejected(node.value), + node: decl, + index: declarationValueIndex(decl) + node.sourceIndex, + result, + ruleName, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/function-disallowed-list/README.md b/lib/rules/function-disallowed-list/README.md index 8f622db3ae..e6dad004a2 100644 --- a/lib/rules/function-disallowed-list/README.md +++ b/lib/rules/function-disallowed-list/README.md @@ -9,8 +9,6 @@ a { transform: scale(1); } * This function */ ``` -This rule was previously called, and is aliased as, `function-blacklist`. - ## Options `array|string`: `["array", "of", "unprefixed", /functions/ or "regex"]|"function"|"/regex/"` diff --git a/lib/rules/function-url-scheme-allowed-list/README.md b/lib/rules/function-url-scheme-allowed-list/README.md index 8a2d49154c..64cbbdcfd6 100644 --- a/lib/rules/function-url-scheme-allowed-list/README.md +++ b/lib/rules/function-url-scheme-allowed-list/README.md @@ -9,8 +9,6 @@ a { background-image: url('http://www.example.com/file.jpg'); } * This URL scheme */ ``` -This rule was previously called, and is aliased as, `function-url-scheme-whitelist`. - A [URL scheme](https://url.spec.whatwg.org/#syntax-url-scheme) consists of alphanumeric, `+`, `-`, and `.` characters. It can appear at the start of a URL and is followed by `:`. This rule ignores: diff --git a/lib/rules/function-url-scheme-blacklist/README.md b/lib/rules/function-url-scheme-blacklist/README.md new file mode 100644 index 0000000000..14fb678310 --- /dev/null +++ b/lib/rules/function-url-scheme-blacklist/README.md @@ -0,0 +1,73 @@ +# function-url-scheme-blacklist + +**_Deprecated: Instead use the [`function-url-scheme-disallowed-list`](../function-url-scheme-disallowed-list/README.md) rule._** + +Specify a list of disallowed URL schemes. + + +```css +a { background-image: url('http://www.example.com/file.jpg'); } +/** ↑ + * This URL scheme */ +``` + +A [URL scheme](https://url.spec.whatwg.org/#syntax-url-scheme) consists of alphanumeric, `+`, `-`, and `.` characters. It can appear at the start of a URL and is followed by `:`. + +This rule ignores: + +- URL arguments without an existing URL scheme +- URL arguments with variables or variable interpolation (`$sass`, `@less`, `--custom-property`, `#{$var}`, `@{var}`, `$(var)`) + +## Options + +`array|string|regex`: `["array", "of", /schemes/ or "/regex/"]|"scheme"|/regex/` + +Given: + +``` +["ftp", "/^http/"] +``` + +The following patterns are considered violations: + + +```css +a { background-image: url('ftp://www.example.com/file.jpg'); } +``` + + +```css +a { background-image: url('http://www.example.com/file.jpg'); } +``` + + +```css +a { background-image: url('https://www.example.com/file.jpg'); } +``` + +The following patterns are _not_ considered violations: + + +```css +a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } +``` + + +```css +a { background-image: url('example.com/file.jpg'); } +``` + + +```css +a { background-image: url('/example.com/file.jpg'); } +``` + + +```css +a { background-image: url('//example.com/file.jpg'); } +``` + + +```css +a { background-image: url('./path/to/file.jpg'); } +``` diff --git a/lib/rules/function-url-scheme-blacklist/__tests__/index.js b/lib/rules/function-url-scheme-blacklist/__tests__/index.js new file mode 100644 index 0000000000..d4ec6f2dbc --- /dev/null +++ b/lib/rules/function-url-scheme-blacklist/__tests__/index.js @@ -0,0 +1,280 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['https'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'function-url-scheme-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: [[]], + + accept: [ + { + code: "a { background: url('http://www.example.com/file.jpg'); }", + }, + ], +}); + +testRule({ + ruleName, + config: [''], + + accept: [ + { + code: "a { background: url('http://www.example.com/file.jpg'); }", + }, + ], +}); + +testRule({ + ruleName, + config: ['https', 'data'], + + accept: [ + { + code: 'a { background: url(); }', + }, + { + code: "a { background: url(''); }", + }, + { + code: 'a { background: url(""); }', + }, + { + code: 'a { background: url(:); }', + }, + { + code: 'a { background: url(://); }', + }, + { + code: 'a { background: url(//); }', + }, + { + code: 'a { background: url(/); }', + }, + { + code: 'a { background: url(./); }', + }, + { + code: 'a { background: url(./file.jpg); }', + }, + { + code: 'a { background: url(../file.jpg); }', + }, + { + code: 'a { background: URL(../file.jpg); }', + }, + { + code: "a { background: url('../file.jpg'); }", + }, + { + code: 'a { background: url("../file.jpg"); }', + }, + { + code: "a { background: url('/path/to/file.jpg'); }", + }, + { + code: 'a { background: url(//www.example.com/file.jpg); }', + }, + { + code: 'a { background: url("//www.example.com/file.jpg"); }', + }, + { + code: "a { background: url('http://www.example.com/file.jpg'); }", + }, + { + code: "a { background-image: url('http://example.com:3000'); }", + }, + { + code: "a { background-image: url('//example.com:3000'); }", + }, + { + code: "@font-face { font-family: 'foo'; src: url('/path/to/foo.ttf'); }", + }, + { + code: 'a { background: url(HTTP://example.com/file.jpg); }', + description: 'ignore case', + }, + { + code: 'a { background: some-url(); }', + description: 'ignore contain url function', + }, + { + code: 'a { background: url($image); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(@image); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(http://#{$host}/path); }', + description: 'ignore interpolation', + }, + { + code: "a { background: url('http://@{host}/path'); }", + description: 'ignore interpolation', + }, + { + code: 'a { background: url(http://$(host)/path); }', + description: 'ignore interpolation', + }, + { + code: 'a { background: url(var(--image)); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(example.com); }', + description: 'schemeless url', + }, + { + code: 'a { background: url(example.com:3000); }', + description: 'schemeless url and port', + }, + { + code: 'a { background: url(http://example.com:3000); }', + description: 'url with scheme and port', + }, + ], + + reject: [ + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, + }, + { + code: 'a { background: url(HTTPS://www.example.com/file.jpg); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: "a { background: url('https://www.example.com/file.jpg'); }", + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: 'a { background: url("https://www.example.com/file.jpg"); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: "a { background: url('https://example.com:3000'); }", + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: "@font-face { font-family: 'foo'; src: url('https://www.example.com/file.jpg'); }", + message: messages.rejected('https'), + line: 1, + column: 43, + }, + { + code: "a { background: no-repeat center/80% url('https://www.example.com/file.jpg'); }", + message: messages.rejected('https'), + line: 1, + column: 42, + }, + ], +}); + +testRule({ + ruleName, + + config: [['/^http/']], + + accept: [ + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + }, + { + code: 'a { background: url(./file.jpg); }', + }, + ], + + reject: [ + { + code: 'a { background: url(https://example.com/file.jpg); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: 'a { background: url(HTTPS://example.com/file.jpg); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: 'a { background: url(http://example.com/file.jpg); }', + message: messages.rejected('http'), + line: 1, + column: 21, + }, + ], +}); + +testRule({ + ruleName, + + config: [[/^http/]], + + accept: [ + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + }, + { + code: 'a { background: url(./file.jpg); }', + }, + ], + + reject: [ + { + code: 'a { background: url(https://example.com/file.jpg); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: 'a { background: url(HTTPS://example.com/file.jpg); }', + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: 'a { background: url(http://example.com/file.jpg); }', + message: messages.rejected('http'), + line: 1, + column: 21, + }, + ], +}); diff --git a/lib/rules/function-url-scheme-blacklist/index.js b/lib/rules/function-url-scheme-blacklist/index.js new file mode 100644 index 0000000000..c85bb0f68a --- /dev/null +++ b/lib/rules/function-url-scheme-blacklist/index.js @@ -0,0 +1,74 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const functionArgumentsSearch = require('../../utils/functionArgumentsSearch'); +const getSchemeFromUrl = require('../../utils/getSchemeFromUrl'); +const isStandardSyntaxUrl = require('../../utils/isStandardSyntaxUrl'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'function-url-scheme-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (scheme) => `Unexpected URL scheme "${scheme}:"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'function-url-scheme-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => { + const unspacedUrlString = _.trim(args, ' '); + + if (!isStandardSyntaxUrl(unspacedUrlString)) { + return; + } + + const urlString = _.trim(unspacedUrlString, '\'"'); + const scheme = getSchemeFromUrl(urlString); + + if (scheme === null) { + return; + } + + if (!matchesStringOrRegExp(scheme, list)) { + return; + } + + report({ + message: messages.rejected(scheme), + node: decl, + index, + result, + ruleName, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/function-url-scheme-disallowed-list/README.md b/lib/rules/function-url-scheme-disallowed-list/README.md index a6dadce430..11e4d73d7e 100644 --- a/lib/rules/function-url-scheme-disallowed-list/README.md +++ b/lib/rules/function-url-scheme-disallowed-list/README.md @@ -9,8 +9,6 @@ a { background-image: url('http://www.example.com/file.jpg'); } * This URL scheme */ ``` -This rule was previously called, and is aliased as, `function-url-scheme-blacklist`. - A [URL scheme](https://url.spec.whatwg.org/#syntax-url-scheme) consists of alphanumeric, `+`, `-`, and `.` characters. It can appear at the start of a URL and is followed by `:`. This rule ignores: diff --git a/lib/rules/function-url-scheme-whitelist/README.md b/lib/rules/function-url-scheme-whitelist/README.md new file mode 100644 index 0000000000..ece68797d7 --- /dev/null +++ b/lib/rules/function-url-scheme-whitelist/README.md @@ -0,0 +1,78 @@ +# function-url-scheme-whitelist + +**_Deprecated: Instead use the [`function-url-scheme-allowed-list`](../function-url-scheme-allowed-list/README.md) rule._** + +Specify a list of allowed URL schemes. + + +```css +a { background-image: url('http://www.example.com/file.jpg'); } +/** ↑ + * This URL scheme */ +``` + +A [URL scheme](https://url.spec.whatwg.org/#syntax-url-scheme) consists of alphanumeric, `+`, `-`, and `.` characters. It can appear at the start of a URL and is followed by `:`. + +This rule ignores: + +- URL arguments without an existing URL scheme +- URL arguments with variables or variable interpolation (`$sass`, `@less`, `--custom-property`, `#{$var}`, `@{var}`, `$(var)`) + +## Options + +`array|string|regex`: `["array", "of", /schemes/ or "/regex/"]|"scheme"|/regex/` + +Given: + +``` +["data", "/^http/"] +``` + +The following patterns are considered violations: + + +```css +a { background-image: url('file://file.jpg'); } +``` + +The following patterns are _not_ considered violations: + + +```css +a { background-image: url('example.com/file.jpg'); } +``` + + +```css +a { background-image: url('/example.com/file.jpg'); } +``` + + +```css +a { background-image: url('//example.com/file.jpg'); } +``` + + +```css +a { background-image: url('./path/to/file.jpg'); } +``` + + +```css +a { background-image: url('http://www.example.com/file.jpg'); } +``` + + +```css +a { background-image: url('https://www.example.com/file.jpg'); } +``` + + +```css +a { background-image: url('HTTPS://www.example.com/file.jpg'); } +``` + + +```css +a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } +``` diff --git a/lib/rules/function-url-scheme-whitelist/__tests__/index.js b/lib/rules/function-url-scheme-whitelist/__tests__/index.js new file mode 100644 index 0000000000..f6e3823f86 --- /dev/null +++ b/lib/rules/function-url-scheme-whitelist/__tests__/index.js @@ -0,0 +1,342 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['https'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'function-url-scheme-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['https', 'data'], + + accept: [ + { + code: 'a { background: url(); }', + }, + { + code: "a { background: url(''); }", + }, + { + code: 'a { background: url(""); }', + }, + { + code: 'a { background: url(:); }', + }, + { + code: 'a { background: url(://); }', + }, + { + code: 'a { background: url(//); }', + }, + { + code: 'a { background: url(/); }', + }, + { + code: 'a { background: url(./); }', + }, + { + code: 'a { background: url(./file.jpg); }', + }, + { + code: 'a { background: url(../file.jpg); }', + }, + { + code: 'a { background: URL(../file.jpg); }', + }, + { + code: "a { background: url('../file.jpg'); }", + }, + { + code: 'a { background: url("../file.jpg"); }', + }, + { + code: "a { background: url('/path/to/file.jpg'); }", + }, + { + code: 'a { background: url(//www.example.com/file.jpg); }', + }, + { + code: 'a { background: url("//www.example.com/file.jpg"); }', + }, + { + code: "a { background: url('https://www.example.com/file.jpg'); }", + }, + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + }, + { + code: "a { background-image: url('https://example.com:3000'); }", + }, + { + code: "a { background-image: url('//example.com:3000'); }", + }, + { + code: "@font-face { font-family: 'foo'; src: url('/path/to/foo.ttf'); }", + }, + { + code: 'a { background: url(HTTPS://example.com/file.jpg); }', + description: 'ignore case', + }, + { + code: 'a { background: some-url(); }', + description: 'ignore contain url function', + }, + { + code: 'a { background: url($image); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(@image); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(http://#{$host}/path); }', + description: 'ignore interpolation', + }, + { + code: "a { background: url('http://@{host}/path'); }", + description: 'ignore interpolation', + }, + { + code: 'a { background: url(http://$(host)/path); }', + description: 'ignore interpolation', + }, + { + code: 'a { background: url(var(--image)); }', + description: 'ignore variable', + }, + { + code: 'a { background: url(example.com); }', + description: 'schemeless url', + }, + { + code: 'a { background: url(example.com:3000); }', + description: 'schemeless url and port', + }, + { + code: 'a { background: url(https://example.com:3000); }', + description: 'url with scheme and port', + }, + ], + + reject: [ + { + code: 'a { background: url(http://www.example.com/file.jpg); }', + message: messages.rejected('http'), + line: 1, + column: 21, + }, + { + code: "a { background: url('http://www.example.com/file.jpg'); }", + message: messages.rejected('http'), + line: 1, + column: 21, + }, + { + code: 'a { background: url("http://www.example.com/file.jpg"); }', + message: messages.rejected('http'), + line: 1, + column: 21, + }, + { + code: "a { background: url('http://example.com:3000'); }", + message: messages.rejected('http'), + line: 1, + column: 21, + }, + { + code: "@font-face { font-family: 'foo'; src: url('http://www.example.com/file.jpg'); }", + message: messages.rejected('http'), + line: 1, + column: 43, + }, + { + code: "a { background: no-repeat center/80% url('http://www.example.com/file.jpg'); }", + message: messages.rejected('http'), + line: 1, + column: 42, + }, + ], +}); + +testRule({ + ruleName, + config: [[]], + + accept: [ + { + code: "a { background: url('/path/to/file.jpg'); }", + }, + { + code: 'a { background: url(//www.example.com/file.jpg); }', + }, + { + code: 'a { background: url("//www.example.com/file.jpg"); }', + }, + { + code: 'a { background: url(example.com:3000); }', + }, + ], + + reject: [ + { + code: "a { background: url('https://www.example.com/file.jpg'); }", + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, + }, + ], +}); + +testRule({ + ruleName, + config: [''], + + accept: [ + { + code: "a { background: url('/path/to/file.jpg'); }", + }, + { + code: 'a { background: url(//www.example.com/file.jpg); }', + }, + { + code: 'a { background: url("//www.example.com/file.jpg"); }', + }, + { + code: 'a { background: url(example.com:3000); }', + }, + ], + + reject: [ + { + code: "a { background: url('https://www.example.com/file.jpg'); }", + message: messages.rejected('https'), + line: 1, + column: 21, + }, + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, + }, + ], +}); + +testRule({ + ruleName, + // primaryOptionArray + config: ['uri', 'file', 'https'], + + accept: [ + { + code: 'a { background: url(https://example.com/file.jpg); }', + }, + ], + + reject: [ + { + code: 'a { background: url(http://example.com/file.jpg); }', + message: messages.rejected('http'), + line: 1, + column: 21, + }, + ], +}); + +testRule({ + ruleName, + + config: [['/^http/']], + + accept: [ + { + code: 'a { background: url(http://example.com/file.jpg); }', + }, + { + code: 'a { background: url(HTTP://example.com/file.jpg); }', + }, + { + code: 'a { background: url(https://example.com/file.jpg); }', + }, + ], + + reject: [ + { + code: 'a { background: url(ftp://example.com/file.jpg); }', + message: messages.rejected('ftp'), + line: 1, + column: 21, + }, + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, + }, + ], +}); + +testRule({ + ruleName, + + config: [[/^http/]], + + accept: [ + { + code: 'a { background: url(http://example.com/file.jpg); }', + }, + { + code: 'a { background: url(HTTP://example.com/file.jpg); }', + }, + { + code: 'a { background: url(https://example.com/file.jpg); }', + }, + ], + + reject: [ + { + code: 'a { background: url(ftp://example.com/file.jpg); }', + message: messages.rejected('ftp'), + line: 1, + column: 21, + }, + { + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, + }, + ], +}); diff --git a/lib/rules/function-url-scheme-whitelist/index.js b/lib/rules/function-url-scheme-whitelist/index.js new file mode 100644 index 0000000000..320453c993 --- /dev/null +++ b/lib/rules/function-url-scheme-whitelist/index.js @@ -0,0 +1,74 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const functionArgumentsSearch = require('../../utils/functionArgumentsSearch'); +const getSchemeFromUrl = require('../../utils/getSchemeFromUrl'); +const isStandardSyntaxUrl = require('../../utils/isStandardSyntaxUrl'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'function-url-scheme-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (scheme) => `Unexpected URL scheme "${scheme}:"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'function-url-scheme-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkDecls((decl) => { + functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => { + const unspacedUrlString = _.trim(args, ' '); + + if (!isStandardSyntaxUrl(unspacedUrlString)) { + return; + } + + const urlString = _.trim(unspacedUrlString, '\'"'); + const scheme = getSchemeFromUrl(urlString); + + if (scheme === null) { + return; + } + + if (matchesStringOrRegExp(scheme, list)) { + return; + } + + report({ + message: messages.rejected(scheme), + node: decl, + index, + result, + ruleName, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/function-whitelist/README.md b/lib/rules/function-whitelist/README.md new file mode 100644 index 0000000000..f3620b3b4b --- /dev/null +++ b/lib/rules/function-whitelist/README.md @@ -0,0 +1,75 @@ +# function-whitelist + +**_Deprecated: Instead use the [`function-allowed-list`](../function-allowed-list/README.md) rule._** + +Specify a list of allowed functions. + + +```css +a { transform: scale(1); } +/** ↑ + * This function */ +``` + +## Options + +`array|string`: `["array", "of", "unprefixed", /functions/ or "regex"]|"function"|"/regex/"` + +If a string is surrounded with `"/"` (e.g. `"/^rgb/"`), it is interpreted as a regular expression. + +Given: + +``` +["scale", "rgba", "linear-gradient"] +``` + +The following patterns are considered violations: + + +```css +a { transform: rotate(1); } +``` + + +```css +a { + color: hsla(170, 50%, 45%, 1) +} +``` + + +```css +a { + background: + red, + -webkit-radial-gradient(red, green, blue); +} +``` + +The following patterns are _not_ considered violations: + + +```css +a { background: red; } +``` + + +```css +a { transform: scale(1); } +``` + + +```css +a { + color: rgba(0, 0, 0, 0.5); +} +``` + + +```css +a { + background: + red, + -moz-linear-gradient(45deg, blue, red); +} +``` diff --git a/lib/rules/function-whitelist/__tests__/index.js b/lib/rules/function-whitelist/__tests__/index.js new file mode 100644 index 0000000000..e2843265d8 --- /dev/null +++ b/lib/rules/function-whitelist/__tests__/index.js @@ -0,0 +1,204 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['rgba'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'function-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['rotate', 'rgb', 'radial-gradient', 'lightness', 'color'], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { transform: rotate(7deg) }', + }, + { + code: 'a { background: -webkit-radial-gradient(red, green, blue); }', + }, + { + code: 'a { color: color(rgb(0, 0, 0) lightness(50%)); }', + }, + { + code: '@media (max-width: 10px) { a { color: color(rgb(0, 0, 0) lightness(50%)); } }', + }, + { + code: '$list: (value, value2)', + description: 'Sass list ignored', + }, + ], + + reject: [ + { + code: 'a { transform: rOtAtE(7deg) }', + message: messages.rejected('rOtAtE'), + line: 1, + column: 16, + }, + { + code: 'a { transform: ROTATE(7deg) }', + message: messages.rejected('ROTATE'), + line: 1, + column: 16, + }, + { + code: 'a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 16, + }, + { + code: 'a { transform: sCaLe(1); }', + message: messages.rejected('sCaLe'), + line: 1, + column: 16, + }, + { + code: 'a { transform: SCALE(1); }', + message: messages.rejected('SCALE'), + line: 1, + column: 16, + }, + { + code: 'a { transform : scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 17, + }, + { + code: 'a\n{ transform: scale(1); }', + message: messages.rejected('scale'), + line: 2, + column: 14, + }, + { + code: 'a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 19, + }, + { + code: ' a { transform: scale(1); }', + message: messages.rejected('scale'), + line: 1, + column: 18, + }, + { + code: 'a { color: rgba(0, 0, 0, 0) }', + message: messages.rejected('rgba'), + line: 1, + column: 12, + }, + { + code: 'a { color: color(rgba(0, 0, 0, 0) lightness(50%)); }', + message: messages.rejected('rgba'), + line: 1, + column: 18, + }, + { + code: 'a { background: red, -moz-linear-gradient(45deg, blue, red); }', + message: messages.rejected('-moz-linear-gradient'), + line: 1, + column: 22, + }, + { + code: '@media (max-width: 10px) { a { color: color(rgba(0, 0, 0) lightness(50%)); } }', + message: messages.rejected('rgba'), + line: 1, + column: 45, + }, + ], +}); + +testRule({ + ruleName, + config: ['translate'], + skipBasicChecks: true, + + accept: [ + { + code: 'a { transform: translate(1px); }', + }, + ], + + reject: [ + { + code: 'a { transform: scale(4); }', + message: messages.rejected('scale'), + line: 1, + column: 16, + }, + ], +}); + +testRule({ + ruleName, + + config: ['/rgb/'], + + accept: [ + { + code: 'a { color: rgb(0, 0, 0); }', + }, + { + code: 'a { color: rgba(0, 0, 0, 0); }', + }, + ], + + reject: [ + { + code: 'a { color: hsl(208, 100%, 97%); }', + message: messages.rejected('hsl'), + line: 1, + column: 12, + }, + ], +}); + +testRule({ + ruleName, + + config: [/rgb/], + + accept: [ + { + code: 'a { color: rgb(0, 0, 0); }', + }, + { + code: 'a { color: rgba(0, 0, 0, 0); }', + }, + ], + + reject: [ + { + code: 'a { color: hsl(208, 100%, 97%); }', + message: messages.rejected('hsl'), + line: 1, + column: 12, + }, + ], +}); diff --git a/lib/rules/function-whitelist/index.js b/lib/rules/function-whitelist/index.js new file mode 100644 index 0000000000..95627bb108 --- /dev/null +++ b/lib/rules/function-whitelist/index.js @@ -0,0 +1,71 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const isStandardSyntaxFunction = require('../../utils/isStandardSyntaxFunction'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'function-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected function "${name}"`, +}); + +function rule(listInput) { + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'function-allowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkDecls((decl) => { + const value = decl.value; + + valueParser(value).walk((node) => { + if (node.type !== 'function') { + return; + } + + if (!isStandardSyntaxFunction(node)) { + return; + } + + if (matchesStringOrRegExp(postcss.vendor.unprefixed(node.value), list)) { + return; + } + + report({ + message: messages.rejected(node.value), + node: decl, + index: declarationValueIndex(decl) + node.sourceIndex, + result, + ruleName, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/index.js b/lib/rules/index.js index 4846a04021..a2ee0d5260 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -4,12 +4,13 @@ const importLazy = require('import-lazy'); -/** @type {{[k: string]: Function}} */ +/** @typedef {import('stylelint').StylelintRule} StylelintRule */ + +/** @type {{[k: string]: StylelintRule}} */ const rules = { 'alpha-value-notation': importLazy(() => require('./alpha-value-notation'))(), 'at-rule-allowed-list': importLazy(() => require('./at-rule-allowed-list'))(), - // Renamed to at-rule-disallowed-list - 'at-rule-blacklist': importLazy(() => require('./at-rule-disallowed-list'))(), + 'at-rule-blacklist': importLazy(() => require('./at-rule-blacklist'))(), 'at-rule-disallowed-list': importLazy(() => require('./at-rule-disallowed-list'))(), 'at-rule-empty-line-before': importLazy(() => require('./at-rule-empty-line-before'))(), 'at-rule-name-case': importLazy(() => require('./at-rule-name-case'))(), @@ -19,13 +20,11 @@ const rules = { 'at-rule-no-unknown': importLazy(() => require('./at-rule-no-unknown'))(), 'at-rule-no-vendor-prefix': importLazy(() => require('./at-rule-no-vendor-prefix'))(), 'at-rule-property-required-list': importLazy(() => require('./at-rule-property-required-list'))(), - // Renamed to at-rule-required-list - 'at-rule-property-requirelist': importLazy(() => require('./at-rule-property-required-list'))(), + 'at-rule-property-requirelist': importLazy(() => require('./at-rule-property-requirelist'))(), 'at-rule-semicolon-newline-after': importLazy(() => require('./at-rule-semicolon-newline-after'), )(), - // Renamed to at-rule-allowed-list - 'at-rule-whitelist': importLazy(() => require('./at-rule-allowed-list'))(), + 'at-rule-whitelist': importLazy(() => require('./at-rule-whitelist'))(), 'block-closing-brace-empty-line-before': importLazy(() => require('./block-closing-brace-empty-line-before'), )(), @@ -63,8 +62,7 @@ const rules = { 'comment-empty-line-before': importLazy(() => require('./comment-empty-line-before'))(), 'comment-no-empty': importLazy(() => require('./comment-no-empty'))(), 'comment-whitespace-inside': importLazy(() => require('./comment-whitespace-inside'))(), - // Renamed to comment-word-disallowed-list - 'comment-word-blacklist': importLazy(() => require('./comment-word-disallowed-list'))(), + 'comment-word-blacklist': importLazy(() => require('./comment-word-blacklist'))(), 'comment-word-disallowed-list': importLazy(() => require('./comment-word-disallowed-list'))(), 'custom-media-pattern': importLazy(() => require('./custom-media-pattern'))(), 'custom-property-empty-line-before': importLazy(() => @@ -110,30 +108,26 @@ const rules = { 'declaration-property-unit-allowed-list': importLazy(() => require('./declaration-property-unit-allowed-list'), )(), - // Renamed to declaration-property-unit-disallowed-list 'declaration-property-unit-blacklist': importLazy(() => - require('./declaration-property-unit-disallowed-list'), + require('./declaration-property-unit-blacklist'), )(), 'declaration-property-unit-disallowed-list': importLazy(() => require('./declaration-property-unit-disallowed-list'), )(), - // Renamed to declaration-property-unit-allowed-list 'declaration-property-unit-whitelist': importLazy(() => - require('./declaration-property-unit-allowed-list'), + require('./declaration-property-unit-whitelist'), )(), 'declaration-property-value-allowed-list': importLazy(() => require('./declaration-property-value-allowed-list'), )(), - // Renamed to declaration-property-value-disallowed-list 'declaration-property-value-blacklist': importLazy(() => - require('./declaration-property-value-disallowed-list'), + require('./declaration-property-value-blacklist'), )(), 'declaration-property-value-disallowed-list': importLazy(() => require('./declaration-property-value-disallowed-list'), )(), - // Renamed to declaration-property-value-allowed-list 'declaration-property-value-whitelist': importLazy(() => - require('./declaration-property-value-allowed-list'), + require('./declaration-property-value-whitelist'), )(), 'font-family-no-missing-generic-family-keyword': importLazy(() => require('./font-family-no-missing-generic-family-keyword'), @@ -142,8 +136,7 @@ const rules = { 'font-family-no-duplicate-names': importLazy(() => require('./font-family-no-duplicate-names'))(), 'font-weight-notation': importLazy(() => require('./font-weight-notation'))(), 'function-allowed-list': importLazy(() => require('./function-allowed-list'))(), - // Renamed to function-disallowed-list - 'function-blacklist': importLazy(() => require('./function-disallowed-list'))(), + 'function-blacklist': importLazy(() => require('./function-blacklist'))(), 'function-calc-no-invalid': importLazy(() => require('./function-calc-no-invalid'))(), 'function-calc-no-unspaced-operator': importLazy(() => require('./function-calc-no-unspaced-operator'), @@ -171,20 +164,13 @@ const rules = { 'function-url-scheme-allowed-list': importLazy(() => require('./function-url-scheme-allowed-list'), )(), - // Renamed to function-url-scheme-disallowed-list - 'function-url-scheme-blacklist': importLazy(() => - require('./function-url-scheme-disallowed-list'), - )(), + 'function-url-scheme-blacklist': importLazy(() => require('./function-url-scheme-blacklist'))(), 'function-url-scheme-disallowed-list': importLazy(() => require('./function-url-scheme-disallowed-list'), )(), - // Renamed to function-url-scheme-allowed-list - 'function-url-scheme-whitelist': importLazy(() => - require('./function-url-scheme-allowed-list'), - )(), + 'function-url-scheme-whitelist': importLazy(() => require('./function-url-scheme-whitelist'))(), 'function-whitespace-after': importLazy(() => require('./function-whitespace-after'))(), - // Renamed to function-allowed-list - 'function-whitelist': importLazy(() => require('./function-allowed-list'))(), + 'function-whitelist': importLazy(() => require('./function-whitelist'))(), 'hue-degree-notation': importLazy(() => require('./hue-degree-notation'))(), 'keyframe-declaration-no-important': importLazy(() => require('./keyframe-declaration-no-important'), @@ -204,10 +190,7 @@ const rules = { 'media-feature-name-allowed-list': importLazy(() => require('./media-feature-name-allowed-list'), )(), - // Renamed to media-feature-name-disallowed-list - 'media-feature-name-blacklist': importLazy(() => - require('./media-feature-name-disallowed-list'), - )(), + 'media-feature-name-blacklist': importLazy(() => require('./media-feature-name-blacklist'))(), 'media-feature-name-case': importLazy(() => require('./media-feature-name-case'))(), 'media-feature-name-disallowed-list': importLazy(() => require('./media-feature-name-disallowed-list'), @@ -220,10 +203,9 @@ const rules = { require('./media-feature-name-value-allowed-list'), )(), 'media-feature-name-value-whitelist': importLazy(() => - require('./media-feature-name-value-allowed-list'), + require('./media-feature-name-value-whitelist'), )(), - // Renamed to media-feature-name-allowed-list - 'media-feature-name-whitelist': importLazy(() => require('./media-feature-name-allowed-list'))(), + 'media-feature-name-whitelist': importLazy(() => require('./media-feature-name-whitelist'))(), 'media-feature-parentheses-space-inside': importLazy(() => require('./media-feature-parentheses-space-inside'), )(), @@ -263,14 +245,12 @@ const rules = { 'number-max-precision': importLazy(() => require('./number-max-precision'))(), 'number-no-trailing-zeros': importLazy(() => require('./number-no-trailing-zeros'))(), 'property-allowed-list': importLazy(() => require('./property-allowed-list'))(), - // Renamed to property-disallowed-list - 'property-blacklist': importLazy(() => require('./property-disallowed-list'))(), + 'property-blacklist': importLazy(() => require('./property-blacklist'))(), 'property-case': importLazy(() => require('./property-case'))(), 'property-disallowed-list': importLazy(() => require('./property-disallowed-list'))(), 'property-no-unknown': importLazy(() => require('./property-no-unknown'))(), 'property-no-vendor-prefix': importLazy(() => require('./property-no-vendor-prefix'))(), - // Renamed to property-allowed-list - 'property-whitelist': importLazy(() => require('./property-allowed-list'))(), + 'property-whitelist': importLazy(() => require('./property-whitelist'))(), 'rule-empty-line-before': importLazy(() => require('./rule-empty-line-before'))(), 'selector-attribute-brackets-space-inside': importLazy(() => require('./selector-attribute-brackets-space-inside'), @@ -278,9 +258,8 @@ const rules = { 'selector-attribute-operator-allowed-list': importLazy(() => require('./selector-attribute-operator-allowed-list'), )(), - // Renamed to selector-attribute-operator-disallowed-list 'selector-attribute-operator-blacklist': importLazy(() => - require('./selector-attribute-operator-disallowed-list'), + require('./selector-attribute-operator-blacklist'), )(), 'selector-attribute-operator-disallowed-list': importLazy(() => require('./selector-attribute-operator-disallowed-list'), @@ -291,19 +270,15 @@ const rules = { 'selector-attribute-operator-space-before': importLazy(() => require('./selector-attribute-operator-space-before'), )(), - // Renamed to selector-attribute-operator-allowed-list 'selector-attribute-operator-whitelist': importLazy(() => - require('./selector-attribute-operator-allowed-list'), + require('./selector-attribute-operator-whitelist'), )(), 'selector-attribute-quotes': importLazy(() => require('./selector-attribute-quotes'))(), 'selector-class-pattern': importLazy(() => require('./selector-class-pattern'))(), 'selector-combinator-allowed-list': importLazy(() => require('./selector-combinator-allowed-list'), )(), - // Renamed to selector-combinator-disallowed-list - 'selector-combinator-blacklist': importLazy(() => - require('./selector-combinator-disallowed-list'), - )(), + 'selector-combinator-blacklist': importLazy(() => require('./selector-combinator-blacklist'))(), 'selector-combinator-disallowed-list': importLazy(() => require('./selector-combinator-disallowed-list'), )(), @@ -313,10 +288,7 @@ const rules = { 'selector-combinator-space-before': importLazy(() => require('./selector-combinator-space-before'), )(), - // Renamed to selector-combinator-allowed-list - 'selector-combinator-whitelist': importLazy(() => - require('./selector-combinator-allowed-list'), - )(), + 'selector-combinator-whitelist': importLazy(() => require('./selector-combinator-whitelist'))(), 'selector-descendant-combinator-no-non-space': importLazy(() => require('./selector-descendant-combinator-no-non-space'), )(), @@ -351,9 +323,8 @@ const rules = { 'selector-pseudo-class-allowed-list': importLazy(() => require('./selector-pseudo-class-allowed-list'), )(), - // Renamed to selector-pseudo-class-disallowed-list 'selector-pseudo-class-blacklist': importLazy(() => - require('./selector-pseudo-class-disallowed-list'), + require('./selector-pseudo-class-blacklist'), )(), 'selector-pseudo-class-case': importLazy(() => require('./selector-pseudo-class-case'))(), 'selector-pseudo-class-disallowed-list': importLazy(() => @@ -365,16 +336,14 @@ const rules = { 'selector-pseudo-class-parentheses-space-inside': importLazy(() => require('./selector-pseudo-class-parentheses-space-inside'), )(), - // Renamed to selector-pseudo-class-allowed-list 'selector-pseudo-class-whitelist': importLazy(() => - require('./selector-pseudo-class-allowed-list'), + require('./selector-pseudo-class-whitelist'), )(), 'selector-pseudo-element-allowed-list': importLazy(() => require('./selector-pseudo-element-allowed-list'), )(), - // Renamed to selector-pseudo-element-disallowed-list 'selector-pseudo-element-blacklist': importLazy(() => - require('./selector-pseudo-element-disallowed-list'), + require('./selector-pseudo-element-blacklist'), )(), 'selector-pseudo-element-case': importLazy(() => require('./selector-pseudo-element-case'))(), 'selector-pseudo-element-colon-notation': importLazy(() => @@ -386,9 +355,8 @@ const rules = { 'selector-pseudo-element-no-unknown': importLazy(() => require('./selector-pseudo-element-no-unknown'), )(), - // Renamed to selector-pseudo-element-allowed-list 'selector-pseudo-element-whitelist': importLazy(() => - require('./selector-pseudo-element-allowed-list'), + require('./selector-pseudo-element-whitelist'), )(), 'selector-type-case': importLazy(() => require('./selector-type-case'))(), 'selector-type-no-unknown': importLazy(() => require('./selector-type-no-unknown'))(), @@ -400,13 +368,11 @@ const rules = { 'time-min-milliseconds': importLazy(() => require('./time-min-milliseconds'))(), 'unicode-bom': importLazy(() => require('./unicode-bom'))(), 'unit-allowed-list': importLazy(() => require('./unit-allowed-list'))(), - // Renamed to unit-disallowed-list - 'unit-blacklist': importLazy(() => require('./unit-disallowed-list'))(), + 'unit-blacklist': importLazy(() => require('./unit-blacklist'))(), 'unit-case': importLazy(() => require('./unit-case'))(), 'unit-disallowed-list': importLazy(() => require('./unit-disallowed-list'))(), 'unit-no-unknown': importLazy(() => require('./unit-no-unknown'))(), - // Renamed to unit-allowed-list - 'unit-whitelist': importLazy(() => require('./unit-allowed-list'))(), + 'unit-whitelist': importLazy(() => require('./unit-whitelist'))(), 'value-keyword-case': importLazy(() => require('./value-keyword-case'))(), 'value-list-comma-newline-after': importLazy(() => require('./value-list-comma-newline-after'))(), 'value-list-comma-newline-before': importLazy(() => diff --git a/lib/rules/keyframes-name-pattern/README.md b/lib/rules/keyframes-name-pattern/README.md index 703fa684b3..cda65c13c1 100644 --- a/lib/rules/keyframes-name-pattern/README.md +++ b/lib/rules/keyframes-name-pattern/README.md @@ -17,8 +17,8 @@ A string will be translated into a RegExp like so `new RegExp(yourString)` —  Given the string: -```js -"foo-.+"; +``` +"foo-.+" ``` The following patterns are considered violations: diff --git a/lib/rules/length-zero-no-unit/__tests__/index.js b/lib/rules/length-zero-no-unit/__tests__/index.js index e0ffd733ad..6efb8e176e 100644 --- a/lib/rules/length-zero-no-unit/__tests__/index.js +++ b/lib/rules/length-zero-no-unit/__tests__/index.js @@ -237,6 +237,10 @@ testRule({ code: 'a { font: normal normal 400 16px /0px cursive; }', description: 'ignore line-height in font declaration', }, + { + code: 'a { font: var(--foo, normal normal 400 16px/0px cursive); }', + description: 'ignore line-height in font declaration within var function', + }, { code: 'a { font: normal normal 400 1.2em cursive; }', description: 'do not fail if no line-height in font declaration', @@ -530,6 +534,13 @@ testRule({ line: 1, column: 30, }, + { + code: 'a { margin: var(--foo, 0px); }', + fixed: 'a { margin: var(--foo, 0); }', + message: messages.rejected, + line: 1, + column: 25, + }, ], }); diff --git a/lib/rules/length-zero-no-unit/index.js b/lib/rules/length-zero-no-unit/index.js index 40acda60a3..6145771b27 100644 --- a/lib/rules/length-zero-no-unit/index.js +++ b/lib/rules/length-zero-no-unit/index.js @@ -40,9 +40,9 @@ function rule(actual, secondary, context) { const ignorableIndexes = new Array(stringValue.length).fill(false); const parsedValue = valueParser(stringValue); - parsedValue.walk((node, nodeIndex) => { + parsedValue.walk((node, nodeIndex, nodes) => { if (decl.prop.toLowerCase() === 'font' && node.type === 'div' && node.value === '/') { - const lineHeightNode = parsedValue.nodes[nodeIndex + 1]; + const lineHeightNode = nodes[nodeIndex + 1]; const lineHeightNodeValue = valueParser.stringify(lineHeightNode); for (let i = 0; i < lineHeightNodeValue.length; i++) { diff --git a/lib/rules/media-feature-name-allowed-list/README.md b/lib/rules/media-feature-name-allowed-list/README.md index 4c5c28abcf..255b865f1f 100644 --- a/lib/rules/media-feature-name-allowed-list/README.md +++ b/lib/rules/media-feature-name-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed media feature names. * This media feature name */ ``` -This rule was previously called, and is aliased as, `media-feature-name-whitelist`. - ## Options `array|string|regex`: `["array", "of", "unprefixed", /media-features/ or "regex"]|"media-feature"|/regex/` diff --git a/lib/rules/media-feature-name-blacklist/README.md b/lib/rules/media-feature-name-blacklist/README.md new file mode 100644 index 0000000000..e89f5753cf --- /dev/null +++ b/lib/rules/media-feature-name-blacklist/README.md @@ -0,0 +1,66 @@ +# media-feature-name-blacklist + +**_Deprecated: Instead use the [`media-feature-name-disallowed-list`](../media-feature-name-disallowed-list/README.md) rule._** + +Specify a list of disallowed media feature names. + + +```css +@media (min-width: 700px) {} +/** ↑ + * This media feature name */ +``` + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", /media-features/ or "regex"]|"media-feature"|/regex/` + +Given: + +``` +["max-width", "/^my-/"] +``` + +The following patterns are considered violations: + + +```css +@media (max-width: 50em) {} +``` + + +```css +@media (my-width: 50em) {} +``` + + +```css +@media (max-width < 50em) {} +``` + + +```css +@media (10em < my-height < 50em) {} +``` + +The following patterns are _not_ considered violations: + + +```css +@media (min-width: 50em) {} +``` + + +```css +@media print and (min-resolution: 300dpi) {} +``` + + +```css +@media (min-width >= 50em) {} +``` + + +```css +@media (10em < width < 50em) {} +``` diff --git a/lib/rules/media-feature-name-blacklist/__tests__/index.js b/lib/rules/media-feature-name-blacklist/__tests__/index.js new file mode 100644 index 0000000000..bd28913d70 --- /dev/null +++ b/lib/rules/media-feature-name-blacklist/__tests__/index.js @@ -0,0 +1,228 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['max-width'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['max-width', '--wide-viewport', 'width', '/^my-/', 'color'], + + accept: [ + { + code: '@media (min-width: 50em) { }', + }, + { + code: '@media (MaX-wIdTh: 50em) { }', + }, + { + code: '@media (MiN-wIdTh: 50em) { }', + }, + { + code: '@media (height <= 50em) { }', + }, + { + code: '@media (400px < height < 1000px) { }', + }, + { + code: '@media (--wide-viewport) { }', + description: 'ignore custom media query', + }, + { + code: '@media (/* max-width: 50em */ min-width: 50em) { }', + description: 'ignore comments', + }, + { + code: '@media (monochrome) { }', + description: 'boolean feature name', + }, + ], + + reject: [ + { + code: '@media (max-width: 50em) { }', + message: messages.rejected('max-width'), + line: 1, + column: 9, + }, + { + code: '@media print and (max-width: 50em) { }', + message: messages.rejected('max-width'), + line: 1, + column: 19, + }, + { + code: '@media handheld and (min-width: 20em), screen and (max-width: 20em) { }', + message: messages.rejected('max-width'), + line: 1, + column: 52, + }, + { + code: '@media (my-width: 50em) { }', + message: messages.rejected('my-width'), + line: 1, + column: 9, + }, + { + code: '@media (color) { }', + message: messages.rejected('color'), + line: 1, + column: 9, + }, + { + code: '@media (width: 50em) { }', + message: messages.rejected('width'), + line: 1, + column: 9, + }, + { + code: '@media (20em < width <= 50em) { }', + message: messages.rejected('width'), + line: 1, + column: 16, + }, + { + code: '@media (10em < max-width <= 50em) and (width > 50em) { }', + warnings: [ + { + message: messages.rejected('max-width'), + line: 1, + column: 16, + }, + { + message: messages.rejected('width'), + line: 1, + column: 40, + }, + ], + }, + ], +}); + +testRule({ + ruleName, + config: [/^my-/], + + accept: [ + { + code: '@media (min-width: 50em) { }', + }, + ], + + reject: [ + { + code: '@media (my-width: 50em) { }', + message: messages.rejected('my-width'), + line: 1, + column: 9, + }, + { + code: '@media (my-width >= 50em) { }', + message: messages.rejected('my-width'), + line: 1, + column: 9, + }, + { + code: '@media (10em < my-width <= 50em) { }', + message: messages.rejected('my-width'), + line: 1, + column: 16, + }, + { + code: '@media (50em < my-width) { }', + message: messages.rejected('my-width'), + line: 1, + column: 16, + }, + ], +}); + +testRule({ + ruleName, + config: ['feature-name'], + syntax: 'less', + + accept: [ + { + code: '@media @feature-name and (orientation: landscape) { }', + }, + { + code: '@media @feature-name { }', + }, + ], +}); + +testRule({ + ruleName, + config: ['feature-name', 'width'], + syntax: 'scss', + + accept: [ + { + code: '@media not all and ($feature-name) { }', + }, + { + code: '@media not all and ($FEATURE-NAME) { }', + }, + { + code: '@media not all and (#{feature-name}) { }', + }, + { + code: '@media not all and (#{FEATURE-NAME}) { }', + }, + { + code: '@media ($feature-name: $value) { }', + }, + { + code: '@media ($FEATURE-NAME: $value) { }', + }, + { + code: '@media (#{$feature-name}: $value) { }', + }, + { + code: '@media (#{$FEATURE-NAME}: $value) { }', + }, + { + code: "@media ('min-' + $width: $value) { }", + }, + { + code: "@media ('MIN-' + $WIDTH: $value) { }", + }, + { + code: "@media ($value + 'width': $value) { }", + }, + { + code: "@media ($VALUE + 'WIDTH': $value) { }", + }, + { + code: '@media (#{$width}: $value) { }', + }, + { + code: '@media (#{$WIDTH}: $value) { }', + }, + { + code: '@media #{$feature-name} { }', + }, + ], +}); diff --git a/lib/rules/media-feature-name-blacklist/index.js b/lib/rules/media-feature-name-blacklist/index.js new file mode 100644 index 0000000000..40f0a54db1 --- /dev/null +++ b/lib/rules/media-feature-name-blacklist/index.js @@ -0,0 +1,84 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const atRuleParamIndex = require('../../utils/atRuleParamIndex'); +const isCustomMediaQuery = require('../../utils/isCustomMediaQuery'); +const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeature'); +const isStandardSyntaxMediaFeatureName = require('../../utils/isStandardSyntaxMediaFeatureName'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const mediaParser = require('postcss-media-query-parser').default; +const rangeContextNodeParser = require('../rangeContextNodeParser'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'media-feature-name-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected media feature name "${name}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkAtRules(/^media$/i, (atRule) => { + mediaParser(atRule.params).walk(/^media-feature$/i, (mediaFeatureNode) => { + const parent = mediaFeatureNode.parent; + const mediaFeatureRangeContext = isRangeContextMediaFeature(parent.value); + + let value; + let sourceIndex; + + if (mediaFeatureRangeContext) { + const parsedRangeContext = rangeContextNodeParser(mediaFeatureNode); + + value = parsedRangeContext.name.value; + sourceIndex = parsedRangeContext.name.sourceIndex; + } else { + value = mediaFeatureNode.value; + sourceIndex = mediaFeatureNode.sourceIndex; + } + + if (!isStandardSyntaxMediaFeatureName(value) || isCustomMediaQuery(value)) { + return; + } + + if (!matchesStringOrRegExp(value, list)) { + return; + } + + report({ + index: atRuleParamIndex(atRule) + sourceIndex, + message: messages.rejected(value), + node: atRule, + ruleName, + result, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/media-feature-name-disallowed-list/README.md b/lib/rules/media-feature-name-disallowed-list/README.md index aa4b012208..cd232e1736 100644 --- a/lib/rules/media-feature-name-disallowed-list/README.md +++ b/lib/rules/media-feature-name-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed media feature names. * This media feature name */ ``` -This rule was previously called, and is aliased as, `media-feature-name-blacklist`. - ## Options `array|string|regex`: `["array", "of", "unprefixed", /media-features/ or "regex"]|"media-feature"|/regex/` diff --git a/lib/rules/media-feature-name-no-vendor-prefix/README.md b/lib/rules/media-feature-name-no-vendor-prefix/README.md index 53ec93df7b..91c113cf5f 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/README.md +++ b/lib/rules/media-feature-name-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ Disallow vendor prefixes for media feature names. Right now this rule simply checks for prefixed _resolutions_. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js b/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js index aaad9dff7f..89a70ff5c9 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/media-feature-name-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -13,47 +14,57 @@ testRule({ { code: '@media (device-pixel-ratio: 2) {}', }, + { + code: '@media (min-device-pixel-ratio: 2) {}', + }, ], reject: [ { code: '@media (-webkit-min-device-pixel-ratio: 1) {}', + fixed: '@media (min-device-pixel-ratio: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (-wEbKiT-mIn-DeViCe-PiXeL-rAtIo: 1) {}', + fixed: '@media (mIn-DeViCe-PiXeL-rAtIo: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (-WEBKIT-MIN-DEVICE-PIXEL-RATIO: 1) {}', + fixed: '@media (MIN-DEVICE-PIXEL-RATIO: 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media\n\t(min--moz-device-pixel-ratio: 1) {}', + fixed: '@media\n\t(min-device-pixel-ratio: 1) {}', message: messages.rejected, line: 2, - column: 3, + column: 6, }, { code: '@media (-o-max-device-pixel-ratio: 1/1) {}', + fixed: '@media (max-device-pixel-ratio: 1/1) {}', message: messages.rejected, line: 1, column: 11, }, { code: '@media (-o-max-device-pixel-ratio > 1) {}', + fixed: '@media (max-device-pixel-ratio > 1) {}', message: messages.rejected, line: 1, column: 9, }, { code: '@media (1 < -o-max-device-pixel-ratio < 2) {}', + fixed: '@media (1 < max-device-pixel-ratio < 2) {}', message: messages.rejected, line: 1, column: 13, diff --git a/lib/rules/media-feature-name-no-vendor-prefix/index.js b/lib/rules/media-feature-name-no-vendor-prefix/index.js index 5c777335d4..bfdbd2b6d4 100644 --- a/lib/rules/media-feature-name-no-vendor-prefix/index.js +++ b/lib/rules/media-feature-name-no-vendor-prefix/index.js @@ -13,7 +13,7 @@ const messages = ruleMessages(ruleName, { rejected: 'Unexpected vendor-prefix', }); -function rule(actual) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual }); @@ -28,12 +28,18 @@ function rule(actual) { return; } - const matches = atRule.toString().match(/[a-z-]+device-pixel-ratio/gi); + const matches = atRule.toString().match(/-[a-z-]+device-pixel-ratio/gi); if (!matches) { return; } + if (context.fix) { + atRule.params = isAutoprefixable.unprefix(atRule.params); + + return; + } + matches.forEach((match) => { report({ message: messages.rejected, diff --git a/lib/rules/media-feature-name-value-allowed-list/README.md b/lib/rules/media-feature-name-value-allowed-list/README.md index 0e45c430d8..e81fd3cf29 100644 --- a/lib/rules/media-feature-name-value-allowed-list/README.md +++ b/lib/rules/media-feature-name-value-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed media feature name and value pairs. * These features and values */ ``` -This rule was previously called, and is aliased as, `media-feature-name-value-whitelist`. - ## Options ```js diff --git a/lib/rules/media-feature-name-value-whitelist/README.md b/lib/rules/media-feature-name-value-whitelist/README.md new file mode 100644 index 0000000000..3a975e64d7 --- /dev/null +++ b/lib/rules/media-feature-name-value-whitelist/README.md @@ -0,0 +1,86 @@ +# media-feature-name-value-whitelist + +**_Deprecated: Instead use the [`media-feature-name-value-allowed-list`](../media-feature-name-value-allowed-list/README.md) rule._** + +Specify a list of allowed media feature name and value pairs. + + +```css +@media screen and (min-width: 768px) {} +/** ↑ ↑ + * These features and values */ +``` + +## Options + +```js +{ + "unprefixed-media-feature-name": ["array", "of", "values"], + "/unprefixed-media-feature-name/": ["/regex/", "non-regex", /real-regex/] +} +``` + +If a media feature name is found in the object, only its allowed-listed values are +allowed. If the media feature name is not included in the object, anything goes. + +If a name or value is surrounded with `/` (e.g. `"/width$/"`), it is interpreted +as a regular expression. For example, `/width$/` will match `max-width` and +`min-width`. + +Given: + +``` +{ + "min-width": ["768px", "1024px"], + "/resolution/": ["/dpcm$/"] +} +``` + +The following patterns are considered violations: + + +```css +@media screen and (min-width: 1000px) {} +``` + + +```css +@media screen and (min-resolution: 2dpi) {} +``` + + +```css +@media screen and (min-width > 1000px) {} +``` + +The following patterns are _not_ considered violations: + + +```css +@media screen and (min-width: 768px) {} +``` + + +```css +@media screen and (min-width: 1024px) {} +``` + + +```css +@media screen and (orientation: portrait) {} +``` + + +```css +@media screen and (min-resolution: 2dpcm) {} +``` + + +```css +@media screen and (resolution: 10dpcm) {} +``` + + +```css +@media screen and (768px < min-width) {} +``` diff --git a/lib/rules/media-feature-name-value-whitelist/__tests__/index.js b/lib/rules/media-feature-name-value-whitelist/__tests__/index.js new file mode 100644 index 0000000000..e7d1f0baf2 --- /dev/null +++ b/lib/rules/media-feature-name-value-whitelist/__tests__/index.js @@ -0,0 +1,195 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [{ color: [] }], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-value-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: [ + { + 'min-width': ['768px', '$sm'], + '/resolution/': ['/dpcm$/'], // Only dpcm unit + color: [], // Test boolean context + width: [], // Test range context + }, + ], + + accept: [ + { + code: '@media screen and (min-width: 768px) {}', + description: 'Specified media feature', + }, + { + code: '@media screen and ( min-width : 768px ) {}', + description: 'Whitespace', + }, + { + code: '@media screen and (max-width: 1000px) {}', + description: 'Unspecified media feature', + }, + { + code: '@media screen and ( min-resolution : 2dpcm ) {}', + description: 'Regex feature name and Regex value', + }, + { + code: '@media screen and (resolution: 10.1dpcm) {}', + description: 'Floating point value', + }, + { + code: '@media screen and (min-width: $sm) {}', + description: 'Non-standard syntax in allowed list', + }, + { + code: '@media (color) {}', + description: 'Boolean context, media feature in allowed list', + }, + { + code: '@media (update) {}', + description: 'Boolean context, media feature NOT in allowed list', + }, + { + code: '@media (update /* pw:ned */) {}', + description: 'Boolean context with colon in comments', + }, + { + code: '@media screen and (min-width <= 768px) {}', + description: 'Range context, media feature in allowed list', + }, + ], + + reject: [ + { + code: '@media screen and (min-width: 1000px) {}', + message: messages.rejected('min-width', '1000px'), + line: 1, + column: 31, + }, + { + code: '@media screen (min-width: 768px) and (min-width: 1000px) {}', + description: 'Media feature multiple', + message: messages.rejected('min-width', '1000px'), + line: 1, + column: 50, + }, + { + code: '@media screen (min-width: 768px)\nand (min-width: 1000px) {}', + description: 'Media feature multiline', + message: messages.rejected('min-width', '1000px'), + line: 2, + column: 17, + }, + { + code: '@media screen and (min-width: 768PX) {}', + description: 'Case sensitive', + message: messages.rejected('min-width', '768PX'), + line: 1, + column: 31, + }, + { + code: '@media screen and (min-width: $md) {}', + description: 'Non-standard syntax NOT in allowed list', + message: messages.rejected('min-width', '$md'), + line: 1, + column: 31, + }, + { + code: '@media screen and (min-resolution: 2dpi) {}', + message: messages.rejected('min-resolution', '2dpi'), + line: 1, + column: 37, + }, + { + code: '@media screen and (min-width > 500px) {}', + message: messages.rejected('min-width', '500px'), + line: 1, + column: 32, + }, + { + code: '@media screen and (400px < min-width) {}', + message: messages.rejected('min-width', '400px'), + line: 1, + column: 20, + }, + { + code: '@media (400px < min-width < 500px) and (min-width < 1200px)', + warnings: [ + { + message: messages.rejected('min-width', '400px'), + line: 1, + column: 9, + }, + { + message: messages.rejected('min-width', '500px'), + line: 1, + column: 29, + }, + { + message: messages.rejected('min-width', '1200px'), + line: 1, + column: 53, + }, + ], + }, + ], +}); + +testRule({ + ruleName, + config: [ + { + '/resolution/': [/dpcm$/], // Only dpcm unit + }, + ], + + accept: [ + { + code: '@media screen and (min-width: 768px) {}', + description: 'Specified media feature', + }, + { + code: '@media screen and ( min-resolution : 2dpcm ) {}', + description: 'Regex feature name and Regex value', + }, + { + code: '@media screen and (resolution: 10.1dpcm) {}', + description: 'Floating point value', + }, + ], + + reject: [ + { + code: '@media screen and (min-resolution: 2dpi) {}', + message: messages.rejected('min-resolution', '2dpi'), + line: 1, + column: 37, + }, + { + code: '@media screen and (min-resolution > 2dpi) {}', + message: messages.rejected('min-resolution', '2dpi'), + line: 1, + column: 38, + }, + ], +}); diff --git a/lib/rules/media-feature-name-value-whitelist/index.js b/lib/rules/media-feature-name-value-whitelist/index.js new file mode 100644 index 0000000000..3eb18856e5 --- /dev/null +++ b/lib/rules/media-feature-name-value-whitelist/index.js @@ -0,0 +1,97 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const atRuleParamIndex = require('../../utils/atRuleParamIndex'); +const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeature'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const mediaParser = require('postcss-media-query-parser').default; +const postcss = require('postcss'); +const rangeContextNodeParser = require('../rangeContextNodeParser'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'media-feature-name-value-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (name, value) => `Unexpected value "${value}" for name "${name}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isObject], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-value-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkAtRules(/^media$/i, (atRule) => { + mediaParser(atRule.params).walk(/^media-feature-expression$/i, (node) => { + const mediaFeatureRangeContext = isRangeContextMediaFeature(node.parent.value); + + // Ignore boolean + if (!node.value.includes(':') && !mediaFeatureRangeContext) { + return; + } + + const mediaFeatureNode = _.find(node.nodes, { type: 'media-feature' }); + + let mediaFeatureName; + let values = []; + + if (mediaFeatureRangeContext) { + const parsedRangeContext = rangeContextNodeParser(mediaFeatureNode); + + mediaFeatureName = parsedRangeContext.name.value; + values = parsedRangeContext.values; + } else { + mediaFeatureName = mediaFeatureNode.value; + values.push(_.find(node.nodes, { type: 'value' })); + } + + for (let i = 0; i < values.length; i++) { + const valueNode = values[i]; + const value = valueNode.value; + const unprefixedMediaFeatureName = postcss.vendor.unprefixed(mediaFeatureName); + + const allowedValues = _.find(list, (v, featureName) => + matchesStringOrRegExp(unprefixedMediaFeatureName, featureName), + ); + + if (allowedValues === undefined) { + return; + } + + if (matchesStringOrRegExp(value, allowedValues)) { + return; + } + + report({ + index: atRuleParamIndex(atRule) + valueNode.sourceIndex, + message: messages.rejected(mediaFeatureName, value), + node: atRule, + ruleName, + result, + }); + } + }); + }); + }; +} + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/media-feature-name-whitelist/README.md b/lib/rules/media-feature-name-whitelist/README.md new file mode 100644 index 0000000000..292ab9afe9 --- /dev/null +++ b/lib/rules/media-feature-name-whitelist/README.md @@ -0,0 +1,66 @@ +# media-feature-name-whitelist + +**_Deprecated: Instead use the [`media-feature-name-allowed-list`](../media-feature-name-allowed-list/README.md) rule._** + +Specify a list of allowed media feature names. + + +```css +@media (min-width: 700px) {} +/** ↑ + * This media feature name */ +``` + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", /media-features/ or "regex"]|"media-feature"|/regex/` + +Given: + +``` +["max-width", "/^my-/"] +``` + +The following patterns are considered violations: + + +```css +@media (min-width: 50em) {} +``` + + +```css +@media print and (min-resolution: 300dpi) {} +``` + + +```css +@media (min-width < 50em) {} +``` + + +```css +@media (10em < min-width < 50em) {} +``` + +The following patterns are _not_ considered violations: + + +```css +@media (max-width: 50em) {} +``` + + +```css +@media (my-width: 50em) {} +``` + + +```css +@media (max-width > 50em) {} +``` + + +```css +@media (10em < my-width < 50em) {} +``` diff --git a/lib/rules/media-feature-name-whitelist/__tests__/index.js b/lib/rules/media-feature-name-whitelist/__tests__/index.js new file mode 100644 index 0000000000..f0af8f625b --- /dev/null +++ b/lib/rules/media-feature-name-whitelist/__tests__/index.js @@ -0,0 +1,218 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['max-width'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['max-width', '/^my-/', 'color'], + + accept: [ + { + code: '@media (max-width: 50em) { }', + }, + { + code: '@media (--wide-viewport) { }', + description: 'ignore custom media query', + }, + { + code: '@media (/* min-width: 50em */ max-width: 50em) { }', + description: 'ignore comments', + }, + { + code: '@media (max-width <= 50em) { }', + }, + { + code: '@media (400px < my-width < 1000px) { }', + }, + { + code: '@media (my-width: 50em) { }', + }, + { + code: '@media (my-max-width: 50em) { }', + }, + { + code: '@media print and (max-width: 50em) { }', + }, + { + code: '@media (color) { }', + }, + ], + + reject: [ + { + code: '@media (MaX-wIdTh: 50em) { }', + message: messages.rejected('MaX-wIdTh'), + line: 1, + column: 9, + }, + { + code: '@media (min-width: 50em) { }', + message: messages.rejected('min-width'), + line: 1, + column: 9, + }, + { + code: '@media (-webkit-min-device-pixel-ratio: 2) { }', + message: messages.rejected('-webkit-min-device-pixel-ratio'), + line: 1, + column: 9, + }, + { + code: '@media handheld and (max-width: 20em), screen and (min-width: 20em) { }', + message: messages.rejected('min-width'), + line: 1, + column: 52, + }, + { + code: '@media (monochrome) { }', + message: messages.rejected('monochrome'), + line: 1, + column: 9, + }, + { + code: '@media (width: 50em) { }', + message: messages.rejected('width'), + line: 1, + column: 9, + }, + { + code: '@media (50em < width) { }', + message: messages.rejected('width'), + line: 1, + column: 16, + }, + { + code: '@media (10em < width <= 50em) { }', + message: messages.rejected('width'), + line: 1, + column: 16, + }, + { + code: '@media (max-width <= 50em) and (10em < min-width < 50em) { }', + message: messages.rejected('min-width'), + line: 1, + column: 40, + }, + ], +}); + +testRule({ + ruleName, + config: [/^my-/], + + accept: [ + { + code: '@media (my-width: 50em) { }', + }, + { + code: '@media (my-max-width: 50em) { }', + }, + { + code: '@media (my-width >= 50em) { }', + }, + { + code: '@media (10em < my-max-width <= 50em) { }', + }, + ], + + reject: [ + { + code: '@media (MaX-wIdTh: 50em) { }', + message: messages.rejected('MaX-wIdTh'), + line: 1, + column: 9, + }, + ], +}); + +testRule({ + ruleName, + config: ['max-width', 'orientation'], + syntax: 'less', + + accept: [ + { + code: '@media @feature-name and (orientation: landscape) { }', + }, + { + code: '@media @feature-name { }', + }, + ], +}); + +testRule({ + ruleName, + config: ['max-width'], + syntax: 'scss', + + accept: [ + { + code: '@media not all and ($feature-name) { }', + }, + { + code: '@media not all and ($FEATURE-NAME) { }', + }, + { + code: '@media not all and (#{feature-name}) { }', + }, + { + code: '@media not all and (#{FEATURE-NAME}) { }', + }, + { + code: '@media ($feature-name: $value) { }', + }, + { + code: '@media ($FEATURE-NAME: $value) { }', + }, + { + code: '@media (#{$feature-name}: $value) { }', + }, + { + code: '@media (#{$FEATURE-NAME}: $value) { }', + }, + { + code: "@media ('min-' + $width: $value) { }", + }, + { + code: "@media ('MIN-' + $WIDTH: $value) { }", + }, + { + code: "@media ($value + 'width': $value) { }", + }, + { + code: "@media ($VALUE + 'WIDTH': $value) { }", + }, + { + code: '@media (#{$width}: $value) { }', + }, + { + code: '@media (#{$WIDTH}: $value) { }', + }, + { + code: '@media #{$feature-name} { }', + }, + ], +}); diff --git a/lib/rules/media-feature-name-whitelist/index.js b/lib/rules/media-feature-name-whitelist/index.js new file mode 100644 index 0000000000..ebfdff9fb6 --- /dev/null +++ b/lib/rules/media-feature-name-whitelist/index.js @@ -0,0 +1,84 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const atRuleParamIndex = require('../../utils/atRuleParamIndex'); +const isCustomMediaQuery = require('../../utils/isCustomMediaQuery'); +const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeature'); +const isStandardSyntaxMediaFeatureName = require('../../utils/isStandardSyntaxMediaFeatureName'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const mediaParser = require('postcss-media-query-parser').default; +const rangeContextNodeParser = require('../rangeContextNodeParser'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'media-feature-name-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (name) => `Unexpected media feature name "${name}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'media-feature-name-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkAtRules(/^media$/i, (atRule) => { + mediaParser(atRule.params).walk(/^media-feature$/i, (mediaFeatureNode) => { + const parent = mediaFeatureNode.parent; + const mediaFeatureRangeContext = isRangeContextMediaFeature(parent.value); + + let value; + let sourceIndex; + + if (mediaFeatureRangeContext) { + const parsedRangeContext = rangeContextNodeParser(mediaFeatureNode); + + value = parsedRangeContext.name.value; + sourceIndex = parsedRangeContext.name.sourceIndex; + } else { + value = mediaFeatureNode.value; + sourceIndex = mediaFeatureNode.sourceIndex; + } + + if (!isStandardSyntaxMediaFeatureName(value) || isCustomMediaQuery(value)) { + return; + } + + if (matchesStringOrRegExp(value, list)) { + return; + } + + report({ + index: atRuleParamIndex(atRule) + sourceIndex, + message: messages.rejected(value), + node: atRule, + ruleName, + result, + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/property-allowed-list/README.md b/lib/rules/property-allowed-list/README.md index 4383c3164c..e2b2250e1a 100644 --- a/lib/rules/property-allowed-list/README.md +++ b/lib/rules/property-allowed-list/README.md @@ -9,8 +9,6 @@ a { display: block; } * This property */ ``` -This rule was previously called, and is aliased as, `property-whitelist`. - This rule ignores variables (`$sass`, `@less`, `--custom-property`). ## Options diff --git a/lib/rules/property-blacklist/README.md b/lib/rules/property-blacklist/README.md new file mode 100644 index 0000000000..b244fb8584 --- /dev/null +++ b/lib/rules/property-blacklist/README.md @@ -0,0 +1,66 @@ +# property-blacklist + +**_Deprecated: Instead use the [`property-disallowed-list`](../property-disallowed-list/README.md) rule._** + +Specify a list of disallowed properties. + + +```css +a { text-rendering: optimizeLegibility; } +/** ↑ + * This property */ +``` + +## Options + +`array|string`: `["array", "of", "unprefixed", /properties/ or "regex"]|"property"|"/regex/"`|/regex/ + +If a string is surrounded with `"/"` (e.g. `"/^background/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^background/` will match `background`, `background-size`, `background-color`, etc. + +Given: + +``` +["text-rendering", "animation", "/^background/"] +``` + +The following patterns are considered violations: + + +```css +a { text-rendering: optimizeLegibility; } +``` + + +```css +a { + animation: my-animation 2s; + color: pink; +} +``` + + +```css +a { -webkit-animation: my-animation 2s; } +``` + + +```css +a { background: pink; } +``` + + +```css +a { background-size: cover; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { color: pink; } +``` + + +```css +a { no-background: sure; } +``` diff --git a/lib/rules/property-blacklist/__tests__/index.js b/lib/rules/property-blacklist/__tests__/index.js new file mode 100644 index 0000000000..68a3c450aa --- /dev/null +++ b/lib/rules/property-blacklist/__tests__/index.js @@ -0,0 +1,182 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'property-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [''], + + accept: [ + { + code: 'a { color: pink; }', + }, + ], +}); + +testRule({ + ruleName, + + config: [[]], + + accept: [ + { + code: 'a { color: pink; }', + }, + ], +}); + +testRule({ + ruleName, + + config: ['transform', 'background-size'], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { background: red; }', + }, + { + code: 'a { top: 0; color: pink; }', + }, + { + code: 'a { $scss: 0; }', + }, + { + code: 'a { @less: 0; }', + }, + { + code: 'a { --custom-property: 0; }', + }, + ], + + reject: [ + { + code: 'a { transform: scale(1); }', + message: messages.rejected('transform'), + line: 1, + column: 5, + }, + { + code: 'a { color: pink; background-size: cover; }', + message: messages.rejected('background-size'), + line: 1, + column: 18, + }, + { + code: 'a { color: pink; -webkit-transform: scale(1); }', + message: messages.rejected('-webkit-transform'), + line: 1, + column: 18, + }, + ], +}); + +testRule({ + ruleName, + + config: [['/^background/']], + + accept: [ + { + code: 'a { color: pink; }', + }, + { + code: 'a { no-background: sure; }', + }, + { + code: 'a { $scss: 0; }', + }, + { + code: 'a { @less: 0; }', + }, + { + code: 'a { --custom-property: 0; }', + }, + ], + + reject: [ + { + code: 'a { background: pink; }', + message: messages.rejected('background'), + line: 1, + column: 5, + }, + { + code: 'a { background-size: cover; }', + message: messages.rejected('background-size'), + line: 1, + column: 5, + }, + { + code: 'a { background-image: none; }', + message: messages.rejected('background-image'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: [[/^background/]], + + accept: [ + { + code: 'a { color: pink; }', + }, + ], + + reject: [ + { + code: 'a { background-size: cover; }', + message: messages.rejected('background-size'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: ['/margin/'], + + accept: [ + { + code: 'a { $margin: 0; }', + }, + { + code: 'a { @margin: 0; }', + }, + { + code: 'a { --margin: 0; }', + }, + ], +}); diff --git a/lib/rules/property-blacklist/index.js b/lib/rules/property-blacklist/index.js new file mode 100644 index 0000000000..6744c9dc16 --- /dev/null +++ b/lib/rules/property-blacklist/index.js @@ -0,0 +1,65 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isCustomProperty = require('../../utils/isCustomProperty'); +const isStandardSyntaxProperty = require('../../utils/isStandardSyntaxProperty'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'property-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (property) => `Unexpected property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'property-disallowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkDecls((decl) => { + const prop = decl.prop; + + if (!isStandardSyntaxProperty(prop)) { + return; + } + + if (isCustomProperty(prop)) { + return; + } + + if (!matchesStringOrRegExp(postcss.vendor.unprefixed(prop), list)) { + return; + } + + report({ + message: messages.rejected(prop), + node: decl, + result, + ruleName, + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/property-disallowed-list/README.md b/lib/rules/property-disallowed-list/README.md index 012981f710..81edc3444f 100644 --- a/lib/rules/property-disallowed-list/README.md +++ b/lib/rules/property-disallowed-list/README.md @@ -9,8 +9,6 @@ a { text-rendering: optimizeLegibility; } * This property */ ``` -This rule was previously called, and is aliased as, `property-blacklist`. - ## Options `array|string`: `["array", "of", "unprefixed", /properties/ or "regex"]|"property"|"/regex/"`|/regex/ diff --git a/lib/rules/property-no-vendor-prefix/README.md b/lib/rules/property-no-vendor-prefix/README.md index 89f237302b..7833e0f16f 100644 --- a/lib/rules/property-no-vendor-prefix/README.md +++ b/lib/rules/property-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ a { -webkit-transform: scale(1); } This rule does not blanketly condemn vendor prefixes. Instead, it uses [Autoprefixer's](https://github.com/postcss/autoprefixer) up-to-date data (from [caniuse.com](http://caniuse.com/)) to know whether a vendor prefix should cause a violation or not. _If you've included a vendor prefixed property that has a standard alternative, one that Autoprefixer could take care of for you, this rule will complain about it_. If, however, you use a non-standard vendor-prefixed property, one that Autoprefixer would ignore and could not provide (such as `-webkit-touch-callout`), this rule will ignore it. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/property-no-vendor-prefix/__tests__/index.js b/lib/rules/property-no-vendor-prefix/__tests__/index.js index d81b624e8a..424c03e553 100644 --- a/lib/rules/property-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/property-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -40,48 +41,56 @@ testRule({ reject: [ { code: 'a { -webkit-transform: scale(1); }', + fixed: 'a { transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 5, }, { code: 'a { -wEbKiT-tRaNsFoRm: scale(1); }', + fixed: 'a { tRaNsFoRm: scale(1); }', message: messages.rejected('-wEbKiT-tRaNsFoRm'), line: 1, column: 5, }, { code: 'a { -WEBKIT-TRANSFORM: scale(1); }', + fixed: 'a { TRANSFORM: scale(1); }', message: messages.rejected('-WEBKIT-TRANSFORM'), line: 1, column: 5, }, { code: 'a { -webkit-transform: scale(1); transform: scale(1); }', + fixed: 'a { transform: scale(1); transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 5, }, { code: 'a { transform: scale(1); -webkit-transform: scale(1); }', + fixed: 'a { transform: scale(1); transform: scale(1); }', message: messages.rejected('-webkit-transform'), line: 1, column: 26, }, { code: 'a { -moz-transition: all 3s; }', + fixed: 'a { transition: all 3s; }', message: messages.rejected('-moz-transition'), line: 1, column: 5, }, { code: 'a { -moz-columns: 2; }', + fixed: 'a { columns: 2; }', message: messages.rejected('-moz-columns'), line: 1, column: 5, }, { code: 'a { -o-columns: 2; }', + fixed: 'a { columns: 2; }', description: 'mistaken prefix', message: messages.rejected('-o-columns'), line: 1, @@ -89,6 +98,7 @@ testRule({ }, { code: 'a { -ms-interpolation-mode: nearest-neighbor; }', + fixed: 'a { interpolation-mode: nearest-neighbor; }', description: '"hack" prefix', message: messages.rejected('-ms-interpolation-mode'), line: 1, @@ -100,6 +110,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreProperties: ['transform', 'columns', '/^animation-/i'] }], + fix: true, accept: [ { @@ -121,18 +132,21 @@ testRule({ reject: [ { code: 'a { -webkit-border-radius: 10px; }', + fixed: 'a { border-radius: 10px; }', message: messages.rejected('-webkit-border-radius'), line: 1, column: 5, }, { code: 'a { -moz-background-size: cover; }', + fixed: 'a { background-size: cover; }', message: messages.rejected('-moz-background-size'), line: 1, column: 5, }, { code: 'a { -WEBKIT-tranSFoRM: translateY(-50%); }', + fixed: 'a { tranSFoRM: translateY(-50%); }', message: messages.rejected('-WEBKIT-tranSFoRM'), line: 1, column: 5, @@ -143,6 +157,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreProperties: [/^animation-/i] }], + fix: true, accept: [ { @@ -152,6 +167,7 @@ testRule({ reject: [ { code: 'a { -webkit-border-radius: 10px; }', + fixed: 'a { border-radius: 10px; }', message: messages.rejected('-webkit-border-radius'), line: 1, column: 5, diff --git a/lib/rules/property-no-vendor-prefix/index.js b/lib/rules/property-no-vendor-prefix/index.js index 0771731993..d5fbcc0969 100644 --- a/lib/rules/property-no-vendor-prefix/index.js +++ b/lib/rules/property-no-vendor-prefix/index.js @@ -16,7 +16,7 @@ const messages = ruleMessages(ruleName, { rejected: (property) => `Unexpected vendor-prefix "${property}"`, }); -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -55,6 +55,12 @@ function rule(actual, options) { return; } + if (context.fix) { + decl.prop = isAutoprefixable.unprefix(decl.prop); + + return; + } + report({ message: messages.rejected(prop), node: decl, diff --git a/lib/rules/property-whitelist/README.md b/lib/rules/property-whitelist/README.md new file mode 100644 index 0000000000..1500c0ca19 --- /dev/null +++ b/lib/rules/property-whitelist/README.md @@ -0,0 +1,77 @@ +# property-whitelist + +**_Deprecated: Instead use the [`property-allowed-list`](../property-allowed-list/README.md) rule._** + +Specify a list of allowed properties. + + +```css +a { display: block; } +/** ↑ + * This property */ +``` + +This rule ignores variables (`$sass`, `@less`, `--custom-property`). + +## Options + +`array|string`: `["array", "of", "unprefixed", /properties/ or "regex"]|"property"|"/regex/"`|/regex/ + +If a string is surrounded with `"/"` (e.g. `"/^background/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^background/` will match `background`, `background-size`, `background-color`, etc. + +Given: + +``` +["display", "animation", "/^background/"] +``` + +The following patterns are considered violations: + + +```css +a { color: pink; } +``` + + +```css +a { + animation: my-animation 2s; + color: pink; +} +``` + + +```css +a { borkgrund: orange; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { display: block; } +``` + + +```css +a { -webkit-animation: my-animation 2s; } +``` + + +```css +a { + animation: my-animation 2s; + -webkit-animation: my-animation 2s; + display: block; +} +``` + + +```css +a { background: pink; } +``` + + +```css +a { background-color: pink; } +``` diff --git a/lib/rules/property-whitelist/__tests__/index.js b/lib/rules/property-whitelist/__tests__/index.js new file mode 100644 index 0000000000..65efbc1efb --- /dev/null +++ b/lib/rules/property-whitelist/__tests__/index.js @@ -0,0 +1,191 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: [], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'property-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: [''], + + reject: [ + { + code: 'a { color: pink; }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: [[]], + + reject: [ + { + code: 'a { color: pink; }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: ['transform', 'background-size'], + + accept: [ + { + code: 'a { background-size: cover; }', + }, + { + code: 'a { transform: scale(1); }', + }, + { + code: 'a { -webkit-transform: scale(1); }', + }, + { + code: 'a { transform: scale(1); background-size: cover; }', + }, + { + code: 'a { transform: scale(1); -webkit-transform: scale(1); background-size: cover; }', + }, + { + code: 'a { $scss: 0; }', + }, + { + code: 'a { @less: 0; }', + }, + { + code: 'a { --custom-property: 0; }', + }, + ], + + reject: [ + { + code: 'a { background: pink; }', + message: messages.rejected('background'), + line: 1, + column: 5, + }, + { + code: 'a { color: pink; }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + { + code: 'a { overflow: hidden; background-size: cover; }', + message: messages.rejected('overflow'), + line: 1, + column: 5, + }, + { + code: 'a { color: orange; -webkit-transform: scale(1); }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: [['/^background/']], + + accept: [ + { + code: 'a { background: pink; }', + }, + { + code: 'a { background-color: pink; }', + }, + { + code: 'a { background-image: none; }', + }, + { + code: 'a { $scss: 0; }', + }, + { + code: 'a { @less: 0; }', + }, + { + code: 'a { --custom-property: 0; }', + }, + ], + + reject: [ + { + code: 'a { color: pink; }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: [[/^background/]], + + accept: [ + { + code: 'a { background-image: none; }', + }, + ], + + reject: [ + { + code: 'a { color: pink; }', + message: messages.rejected('color'), + line: 1, + column: 5, + }, + ], +}); + +testRule({ + ruleName, + + config: ['/margin/'], + + accept: [ + { + code: 'a { $padding: 0; }', + }, + { + code: 'a { @padding: 0; }', + }, + { + code: 'a { --padding: 0; }', + }, + ], +}); diff --git a/lib/rules/property-whitelist/index.js b/lib/rules/property-whitelist/index.js new file mode 100644 index 0000000000..81f4fb0f8a --- /dev/null +++ b/lib/rules/property-whitelist/index.js @@ -0,0 +1,65 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isCustomProperty = require('../../utils/isCustomProperty'); +const isStandardSyntaxProperty = require('../../utils/isStandardSyntaxProperty'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'property-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (property) => `Unexpected property "${property}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'property-allowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + root.walkDecls((decl) => { + const prop = decl.prop; + + if (!isStandardSyntaxProperty(prop)) { + return; + } + + if (isCustomProperty(prop)) { + return; + } + + if (matchesStringOrRegExp(postcss.vendor.unprefixed(prop), list)) { + return; + } + + report({ + message: messages.rejected(prop), + node: decl, + result, + ruleName, + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-attribute-operator-allowed-list/README.md b/lib/rules/selector-attribute-operator-allowed-list/README.md index 6cdbae223b..557d9ec0a8 100644 --- a/lib/rules/selector-attribute-operator-allowed-list/README.md +++ b/lib/rules/selector-attribute-operator-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed attribute operators. * This operator */ ``` -This rule was previously called, and is aliased as, `selector-attribute-operator-whitelist`. - ## Options `array|string`: `["array", "of", "operators"]|"operator"` diff --git a/lib/rules/selector-attribute-operator-blacklist/README.md b/lib/rules/selector-attribute-operator-blacklist/README.md new file mode 100644 index 0000000000..f3e54f4629 --- /dev/null +++ b/lib/rules/selector-attribute-operator-blacklist/README.md @@ -0,0 +1,46 @@ +# selector-attribute-operator-blacklist + +**_Deprecated: Instead use the [`selector-attribute-operator-disallowed-list`](../selector-attribute-operator-disallowed-list/README.md) rule._** + +Specify a list of disallowed attribute operators. + + +```css +[target="_blank"] {} +/** ↑ + * This operator */ +``` + +## Options + +`array|string`: `["array", "of", "operators"]|"operator"` + +Given: + +``` +["*="] +``` + +The following patterns are considered violations: + + +```css +[class*="test"] {} +``` + +The following patterns are _not_ considered violations: + + +```css +[target] {} +``` + + +```css +[target="_blank"] {} +``` + + +```css +[class|="top"] {} +``` diff --git a/lib/rules/selector-attribute-operator-blacklist/__tests__/index.js b/lib/rules/selector-attribute-operator-blacklist/__tests__/index.js new file mode 100644 index 0000000000..e6d9f654d3 --- /dev/null +++ b/lib/rules/selector-attribute-operator-blacklist/__tests__/index.js @@ -0,0 +1,114 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['~='], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-attribute-operator-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['*=', '~='], + + accept: [ + { + code: 'a[target] { }', + }, + { + code: 'a[target="_blank"] { }', + }, + { + code: '[class|="top"] { }', + }, + { + code: '[class^=top] { }', + }, + { + code: '[class$="test"] { }', + }, + { + code: ':root { --foo: 1px; }', + description: 'custom property in root', + }, + { + code: 'html { --foo: 1px; }', + description: 'custom property in selector', + }, + { + code: ':root { --custom-property-set: {} }', + description: 'custom property set in root', + }, + { + code: 'html { --custom-property-set: {} }', + description: 'custom property set in selector', + }, + ], + + reject: [ + { + code: '[title~="flower"] { }', + message: messages.rejected('~='), + line: 1, + column: 7, + }, + { + code: '[ title~="flower" ] { }', + message: messages.rejected('~='), + line: 1, + column: 8, + }, + { + code: '[title ~= "flower"] { }', + message: messages.rejected('~='), + line: 1, + column: 8, + }, + { + code: '[class*=te] { }', + message: messages.rejected('*='), + line: 1, + column: 7, + }, + ], +}); + +testRule({ + ruleName, + + config: ['*='], + + accept: [ + { + code: 'a[target="_blank"] { }', + }, + ], + + reject: [ + { + code: '[title*="foo"] { }', + message: messages.rejected('*='), + line: 1, + column: 7, + }, + ], +}); diff --git a/lib/rules/selector-attribute-operator-blacklist/index.js b/lib/rules/selector-attribute-operator-blacklist/index.js new file mode 100644 index 0000000000..d28b3d09ea --- /dev/null +++ b/lib/rules/selector-attribute-operator-blacklist/index.js @@ -0,0 +1,73 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const parseSelector = require('../../utils/parseSelector'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-attribute-operator-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (operator) => `Unexpected operator "${operator}"`, +}); + +function rule(listInput) { + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-attribute-operator-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + if (!rule.selector.includes('[') || !rule.selector.includes('=')) { + return; + } + + parseSelector(rule.selector, result, rule, (selectorTree) => { + selectorTree.walkAttributes((attributeNode) => { + const operator = attributeNode.operator; + + if (!operator || (operator && !list.includes(operator))) { + return; + } + + report({ + message: messages.rejected(operator), + node: rule, + index: attributeNode.sourceIndex + attributeNode.offsetOf('operator'), + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-attribute-operator-disallowed-list/README.md b/lib/rules/selector-attribute-operator-disallowed-list/README.md index 97b51a25d3..62cbb512bc 100644 --- a/lib/rules/selector-attribute-operator-disallowed-list/README.md +++ b/lib/rules/selector-attribute-operator-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed attribute operators. * This operator */ ``` -This rule was previously called, and is aliased as, `selector-attribute-operator-blacklist`. - ## Options `array|string`: `["array", "of", "operators"]|"operator"` diff --git a/lib/rules/selector-attribute-operator-whitelist/README.md b/lib/rules/selector-attribute-operator-whitelist/README.md new file mode 100644 index 0000000000..364d8266e6 --- /dev/null +++ b/lib/rules/selector-attribute-operator-whitelist/README.md @@ -0,0 +1,56 @@ +# selector-attribute-operator-whitelist + +**_Deprecated: Instead use the [`selector-attribute-operator-allowed-list`](../selector-attribute-operator-allowed-list/README.md) rule._** + +Specify a list of allowed attribute operators. + + +```css +[target="_blank"] {} +/** ↑ + * This operator */ +``` + +## Options + +`array|string`: `["array", "of", "operators"]|"operator"` + +Given: + +``` +["=", "|="] +``` + +The following patterns are considered violations: + + +```css +[class*="test"] {} +``` + + +```css +[title~="flower"] {} +``` + + +```css +[class^="top"] {} +``` + +The following patterns are _not_ considered violations: + + +```css +[target] {} +``` + + +```css +[target="_blank"] {} +``` + + +```css +[class|="top"] {} +``` diff --git a/lib/rules/selector-attribute-operator-whitelist/__tests__/index.js b/lib/rules/selector-attribute-operator-whitelist/__tests__/index.js new file mode 100644 index 0000000000..e43b0c1683 --- /dev/null +++ b/lib/rules/selector-attribute-operator-whitelist/__tests__/index.js @@ -0,0 +1,120 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['='], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-attribute-operator-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['=', '|='], + + accept: [ + { + code: 'a[target] { }', + }, + { + code: 'a[target="_blank"] { }', + }, + { + code: '[class|="top"] { }', + }, + { + code: ':root { --foo: 1px; }', + description: 'custom property in root', + }, + { + code: 'html { --foo: 1px; }', + description: 'custom property in selector', + }, + { + code: ':root { --custom-property-set: {} }', + description: 'custom property set in root', + }, + { + code: 'html { --custom-property-set: {} }', + description: 'custom property set in selector', + }, + ], + + reject: [ + { + code: '[title~="flower"] { }', + message: messages.rejected('~='), + line: 1, + column: 7, + }, + { + code: '[ title~="flower" ] { }', + message: messages.rejected('~='), + line: 1, + column: 8, + }, + { + code: '[title ~= "flower"] { }', + message: messages.rejected('~='), + line: 1, + column: 8, + }, + { + code: '[class^=top] { }', + message: messages.rejected('^='), + line: 1, + column: 7, + }, + { + code: '[class$="test"] { }', + message: messages.rejected('$='), + line: 1, + column: 7, + }, + { + code: '[class*=te] { }', + message: messages.rejected('*='), + line: 1, + column: 7, + }, + ], +}); + +testRule({ + ruleName, + + config: ['='], + + accept: [ + { + code: 'a[target="_blank"] { }', + }, + ], + + reject: [ + { + code: '[title~="flower"] { }', + message: messages.rejected('~='), + line: 1, + column: 7, + }, + ], +}); diff --git a/lib/rules/selector-attribute-operator-whitelist/index.js b/lib/rules/selector-attribute-operator-whitelist/index.js new file mode 100644 index 0000000000..34a39dfcc9 --- /dev/null +++ b/lib/rules/selector-attribute-operator-whitelist/index.js @@ -0,0 +1,73 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const parseSelector = require('../../utils/parseSelector'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-attribute-operator-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (operator) => `Unexpected operator "${operator}"`, +}); + +function rule(listInput) { + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-attribute-operator-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + if (!rule.selector.includes('[') || !rule.selector.includes('=')) { + return; + } + + parseSelector(rule.selector, result, rule, (selectorTree) => { + selectorTree.walkAttributes((attributeNode) => { + const operator = attributeNode.operator; + + if (!operator || (operator && list.includes(operator))) { + return; + } + + report({ + message: messages.rejected(operator), + node: rule, + index: attributeNode.sourceIndex + attributeNode.offsetOf('operator'), + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-class-pattern/README.md b/lib/rules/selector-class-pattern/README.md index b6961ad1e6..e7da1ed34e 100644 --- a/lib/rules/selector-class-pattern/README.md +++ b/lib/rules/selector-class-pattern/README.md @@ -25,6 +25,7 @@ Given the string: ```js "foo-[a-z]+"; + ``` The following patterns are considered violations: @@ -76,8 +77,8 @@ For example, with `true`. Given the string: -```js -"^[A-Z]+$"; +``` +"^[A-Z]+$" ``` The following patterns are considered violations: diff --git a/lib/rules/selector-combinator-allowed-list/README.md b/lib/rules/selector-combinator-allowed-list/README.md index 9181f40b93..5fdce86ffa 100644 --- a/lib/rules/selector-combinator-allowed-list/README.md +++ b/lib/rules/selector-combinator-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed combinators. * This combinator */ ``` -This rule was previously called, and is aliased as, `selector-combinator-whitelist`. - This rule normalizes the whitespace descendant combinator to be a single space. This rule ignores [reference combinators](https://www.w3.org/TR/selectors4/#idref-combinators) e.g. `/for/`. diff --git a/lib/rules/selector-combinator-blacklist/README.md b/lib/rules/selector-combinator-blacklist/README.md new file mode 100644 index 0000000000..cb64dfe82b --- /dev/null +++ b/lib/rules/selector-combinator-blacklist/README.md @@ -0,0 +1,56 @@ +# selector-combinator-blacklist + +**_Deprecated: Instead use the [`selector-combinator-disallowed-list`](../selector-combinator-disallowed-list/README.md) rule._** + +Specify a list of disallowed combinators. + + +```css + a + b {} +/** ↑ + * This combinator */ +``` + +This rule normalizes the whitespace descendant combinator to be a single space. + +This rule ignores [reference combinators](https://www.w3.org/TR/selectors4/#idref-combinators) e.g. `/for/`. + +## Options + +`array|string`: `["array", "of", "combinators"]|"combinator"` + +Given: + +``` +[">", " "] +``` + +The following patterns are considered violations: + + +```css +a > b {} +``` + + +```css +a b {} +``` + + +```css +a +b {} +``` + +The following patterns are _not_ considered violations: + + +```css +a + b {} +``` + + +```css +a ~ b {} +``` diff --git a/lib/rules/selector-combinator-blacklist/__tests__/index.js b/lib/rules/selector-combinator-blacklist/__tests__/index.js new file mode 100644 index 0000000000..e3ff4b7c43 --- /dev/null +++ b/lib/rules/selector-combinator-blacklist/__tests__/index.js @@ -0,0 +1,88 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['>'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-combinator-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); +testRule({ + ruleName, + config: ['>', ' '], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a, b {}', + }, + { + code: 'a /for/ b {}', + }, + { + code: 'a + b {}', + }, + { + code: 'a:not(b ~ c) {}', + }, + ], + + reject: [ + { + code: 'a b {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + { + code: 'a\tb {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + { + code: 'a\n\tb {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + { + code: 'a,\nb c {}', + message: messages.rejected(' '), + line: 2, + column: 2, + }, + { + code: 'a:not(b > c) {}', + message: messages.rejected('>'), + line: 1, + column: 9, + }, + { + code: 'a > b {}', + message: messages.rejected('>'), + line: 1, + column: 3, + }, + ], +}); diff --git a/lib/rules/selector-combinator-blacklist/index.js b/lib/rules/selector-combinator-blacklist/index.js new file mode 100644 index 0000000000..698dc7df4c --- /dev/null +++ b/lib/rules/selector-combinator-blacklist/index.js @@ -0,0 +1,78 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxCombinator = require('../../utils/isStandardSyntaxCombinator'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const parseSelector = require('../../utils/parseSelector'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-combinator-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (combinator) => `Unexpected combinator "${combinator}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-combinator-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + parseSelector(selector, result, rule, (fullSelector) => { + fullSelector.walkCombinators((combinatorNode) => { + if (!isStandardSyntaxCombinator(combinatorNode)) { + return; + } + + const value = normalizeCombinator(combinatorNode.value); + + if (!list.includes(value)) { + return; + } + + report({ + result, + ruleName, + message: messages.rejected(value), + node: rule, + index: combinatorNode.sourceIndex, + }); + }); + }); + }); + }; +} + +function normalizeCombinator(value) { + return value.replace(/\s+/g, ' '); +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-combinator-disallowed-list/README.md b/lib/rules/selector-combinator-disallowed-list/README.md index 98685b9867..ae4fe2a419 100644 --- a/lib/rules/selector-combinator-disallowed-list/README.md +++ b/lib/rules/selector-combinator-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed combinators. * This combinator */ ``` -This rule was previously called, and is aliased as, `selector-combinator-blacklist`. - This rule normalizes the whitespace descendant combinator to be a single space. This rule ignores [reference combinators](https://www.w3.org/TR/selectors4/#idref-combinators) e.g. `/for/`. diff --git a/lib/rules/selector-combinator-space-after/__tests__/index.js b/lib/rules/selector-combinator-space-after/__tests__/index.js index eb05188292..a153b793a4 100644 --- a/lib/rules/selector-combinator-space-after/__tests__/index.js +++ b/lib/rules/selector-combinator-space-after/__tests__/index.js @@ -554,33 +554,9 @@ testRule({ code: 'a { > /*comment*/a, > /*comment*/.b{} }', description: 'scss nesting and comment', }, - ], - - reject: [ { - code: 'a { >/*comment*/a {} }', - fixed: 'a { > /*comment*/a {} }', - description: 'scss nesting and comment', - message: messages.expectedAfter('>'), - line: 1, - column: 5, - }, - { - code: 'a { >/*comment*/a, >/*comment*/.b{} }', - fixed: 'a { > /*comment*/a, > /*comment*/.b{} }', - description: 'scss nesting, comment and comma', - warnings: [ - { - message: messages.expectedAfter('>'), - line: 1, - column: 5, - }, - { - message: messages.expectedAfter('>'), - line: 1, - column: 20, - }, - ], + code: 'a ~, b {}', + description: 'scss trailing combinator', }, ], }); @@ -596,33 +572,9 @@ testRule({ code: 'a { >/*comment*/a, >/*comment*/.b {} }', description: 'scss nesting and comment', }, - ], - - reject: [ { - code: 'a { > /*comment*/a {} }', - fixed: 'a { >/*comment*/a {} }', - description: 'scss nesting and comment', - message: messages.rejectedAfter('>'), - line: 1, - column: 5, - }, - { - code: 'a { > /*comment*/a, > /*comment*/.b {} }', - fixed: 'a { >/*comment*/a, >/*comment*/.b {} }', - description: 'scss nesting, comment and comma', - warnings: [ - { - message: messages.rejectedAfter('>'), - line: 1, - column: 5, - }, - { - message: messages.rejectedAfter('>'), - line: 1, - column: 21, - }, - ], + code: 'a ~, b {}', + description: 'scss trailing combinator', }, ], }); diff --git a/lib/rules/selector-combinator-whitelist/README.md b/lib/rules/selector-combinator-whitelist/README.md new file mode 100644 index 0000000000..49454ca37a --- /dev/null +++ b/lib/rules/selector-combinator-whitelist/README.md @@ -0,0 +1,56 @@ +# selector-combinator-whitelist + +**_Deprecated: Instead use the [`selector-combinator-allowed-list`](../selector-combinator-allowed-list/README.md) rule._** + +Specify a list of allowed combinators. + + +```css + a + b {} +/** ↑ + * This combinator */ +``` + +This rule normalizes the whitespace descendant combinator to be a single space. + +This rule ignores [reference combinators](https://www.w3.org/TR/selectors4/#idref-combinators) e.g. `/for/`. + +## Options + +`array|string`: `["array", "of", "combinators"]|"combinator"` + +Given: + +``` +[">", " "] +``` + +The following patterns are considered violations: + + +```css +a + b {} +``` + + +```css +a ~ b {} +``` + +The following patterns are _not_ considered violations: + + +```css +a > b {} +``` + + +```css +a b {} +``` + + +```css +a +b {} +``` diff --git a/lib/rules/selector-combinator-whitelist/__tests__/index.js b/lib/rules/selector-combinator-whitelist/__tests__/index.js new file mode 100644 index 0000000000..e08d23c145 --- /dev/null +++ b/lib/rules/selector-combinator-whitelist/__tests__/index.js @@ -0,0 +1,113 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['>'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-combinator-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['>', ' '], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a, b {}', + }, + { + code: 'a /for/ b {}', + }, + { + code: 'a > b {}', + }, + { + code: 'a:not(b > c) {}', + }, + { + code: 'a b {}', + }, + { + code: 'a\tb {}', + }, + { + code: 'a\nb {}', + }, + ], + + reject: [ + { + code: 'a ~ b {}', + message: messages.rejected('~'), + line: 1, + column: 3, + }, + { + code: 'a:not(b ~ c) {}', + message: messages.rejected('~'), + line: 1, + column: 9, + }, + { + code: 'a,\nb + c {}', + message: messages.rejected('+'), + line: 2, + column: 3, + }, + ], +}); + +testRule({ + ruleName, + config: ['~'], + skipBasicChecks: true, + + accept: [ + { + code: 'a ~ b {}', + }, + ], + + reject: [ + { + code: 'a b {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + { + code: 'a\tb {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + { + code: 'a\n\tb {}', + message: messages.rejected(' '), + line: 1, + column: 2, + }, + ], +}); diff --git a/lib/rules/selector-combinator-whitelist/index.js b/lib/rules/selector-combinator-whitelist/index.js new file mode 100644 index 0000000000..a2d28034c4 --- /dev/null +++ b/lib/rules/selector-combinator-whitelist/index.js @@ -0,0 +1,78 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxCombinator = require('../../utils/isStandardSyntaxCombinator'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const parseSelector = require('../../utils/parseSelector'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-combinator-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (combinator) => `Unexpected combinator "${combinator}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-combinator-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + parseSelector(selector, result, rule, (fullSelector) => { + fullSelector.walkCombinators((combinatorNode) => { + if (!isStandardSyntaxCombinator(combinatorNode)) { + return; + } + + const value = normalizeCombinator(combinatorNode.value); + + if (list.includes(value)) { + return; + } + + report({ + result, + ruleName, + message: messages.rejected(value), + node: rule, + index: combinatorNode.sourceIndex, + }); + }); + }); + }); + }; +} + +function normalizeCombinator(value) { + return value.replace(/\s+/g, ' '); +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-id-pattern/README.md b/lib/rules/selector-id-pattern/README.md index 489b89ae2d..cab22b7d18 100644 --- a/lib/rules/selector-id-pattern/README.md +++ b/lib/rules/selector-id-pattern/README.md @@ -19,8 +19,8 @@ The selector value _after `#`_ will be checked. No need to include `#` in your p Given the string: -```js -"foo-[a-z]+"; +``` +"foo-[a-z]+" ``` The following patterns are considered violations: diff --git a/lib/rules/selector-nested-pattern/README.md b/lib/rules/selector-nested-pattern/README.md index 49415d8c7b..fc223497cd 100644 --- a/lib/rules/selector-nested-pattern/README.md +++ b/lib/rules/selector-nested-pattern/README.md @@ -24,8 +24,8 @@ The selector value will be checked in its entirety. If you'd like to allow for c Given the string: -```js -"^&:(?:hover|focus)$"; +``` +"^&:(?:hover|focus)$" ``` The following patterns are considered violations: diff --git a/lib/rules/selector-no-vendor-prefix/README.md b/lib/rules/selector-no-vendor-prefix/README.md index adf3b0b6ce..8555ec6d10 100644 --- a/lib/rules/selector-no-vendor-prefix/README.md +++ b/lib/rules/selector-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ input::-moz-placeholder {} This rule does not blanketly condemn vendor prefixes. Instead, it uses [Autoprefixer's](https://github.com/postcss/autoprefixer) up-to-date data (from [caniuse.com](http://caniuse.com/)) to know whether a vendor prefix should cause a violation or not. _If you've included a vendor prefixed selector that has a standard alternative, one that Autoprefixer could take care of for you, this rule will complain about it_. If, however, you use a non-standard vendor-prefixed selector, one that Autoprefixer would ignore and could not provide, this rule will ignore it. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/selector-no-vendor-prefix/__tests__/index.js b/lib/rules/selector-no-vendor-prefix/__tests__/index.js index 3fa68a4d2b..f22ea1897c 100644 --- a/lib/rules/selector-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/selector-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -46,42 +47,49 @@ testRule({ reject: [ { code: ':-webkit-full-screen a {}', + fixed: ':full-screen a {}', message: messages.rejected(':-webkit-full-screen'), line: 1, column: 1, }, { code: ':-wEbKiT-fUlL-sCrEeN a {}', + fixed: ':fUlL-sCrEeN a {}', message: messages.rejected(':-wEbKiT-fUlL-sCrEeN'), line: 1, column: 1, }, { code: ':-WEBKIT-FULL-SCREEN a {}', + fixed: ':FULL-SCREEN a {}', message: messages.rejected(':-WEBKIT-FULL-SCREEN'), line: 1, column: 1, }, { code: 'body, :-ms-fullscreen a {}', + fixed: 'body, :fullscreen a {}', message: messages.rejected(':-ms-fullscreen'), line: 1, column: 7, }, { code: 'input::-moz-placeholder, input::placeholder { color: pink; }', + fixed: 'input::placeholder, input::placeholder { color: pink; }', message: messages.rejected('::-moz-placeholder'), line: 1, column: 6, }, { code: 'input::-moz-placeholder { color: pink; }', + fixed: 'input::placeholder { color: pink; }', message: messages.rejected('::-moz-placeholder'), line: 1, column: 6, }, { code: 'input::-webkit-input-placeholder { color: pink; }', + fixed: 'input::input-placeholder { color: pink; }', message: messages.rejected('::-webkit-input-placeholder'), }, ], @@ -90,6 +98,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreSelectors: ['::-webkit-input-placeholder', '/-moz-.*/'] }], + fix: true, accept: [ { @@ -103,6 +112,7 @@ testRule({ reject: [ { code: 'input::-ms-input-placeholder { color: pink; }', + fixed: 'input::input-placeholder { color: pink; }', message: messages.rejected('::-ms-input-placeholder'), }, ], diff --git a/lib/rules/selector-no-vendor-prefix/index.js b/lib/rules/selector-no-vendor-prefix/index.js index 4e37e01865..9f768f586e 100644 --- a/lib/rules/selector-no-vendor-prefix/index.js +++ b/lib/rules/selector-no-vendor-prefix/index.js @@ -17,7 +17,7 @@ const messages = ruleMessages(ruleName, { rejected: (selector) => `Unexpected vendor-prefix "${selector}"`, }); -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -50,6 +50,12 @@ function rule(actual, options) { return; } + if (context.fix) { + rule.selector = isAutoprefixable.unprefix(rule.selector); + + return; + } + report({ result, ruleName, diff --git a/lib/rules/selector-pseudo-class-allowed-list/README.md b/lib/rules/selector-pseudo-class-allowed-list/README.md index b22b2711fa..5932b92623 100644 --- a/lib/rules/selector-pseudo-class-allowed-list/README.md +++ b/lib/rules/selector-pseudo-class-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed pseudo-class selectors. * This pseudo-class selector */ ``` -This rule was previously called, and is aliased as, `selector-pseudo-class-whitelist`. - This rule ignores selectors that use variable interpolation e.g. `:#{$variable} {}`. ## Options diff --git a/lib/rules/selector-pseudo-class-blacklist/README.md b/lib/rules/selector-pseudo-class-blacklist/README.md new file mode 100644 index 0000000000..be91d9a071 --- /dev/null +++ b/lib/rules/selector-pseudo-class-blacklist/README.md @@ -0,0 +1,55 @@ +# selector-pseudo-class-blacklist + +**_Deprecated: Instead use the [`selector-pseudo-class-disallowed-list`](../selector-pseudo-class-disallowed-list/README.md) rule._** + +Specify a list of disallowed pseudo-class selectors. + + +```css + a:hover {} +/** ↑ + * This pseudo-class selector */ +``` + +This rule ignores selectors that use variable interpolation e.g. `:#{$variable} {}`. + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", /pseudo-classes/ or "/regex/"]|"pseudo-class"|/regex/` + +If a string is surrounded with `"/"` (e.g. `"/^nth-/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^nth-/` will match `nth-child`, `nth-last-child`, `nth-of-type`, etc. + +Given: + +``` +["hover", "/^nth-/"] +``` + +The following patterns are considered violations: + + +```css +a:hover {} +``` + + +```css +a:nth-of-type(5) {} +``` + + +```css +a:nth-child(2) {} +``` + +The following patterns are _not_ considered violations: + + +```css +a:focus {} +``` + + +```css +a:first-of-type {} +``` diff --git a/lib/rules/selector-pseudo-class-blacklist/__tests__/index.js b/lib/rules/selector-pseudo-class-blacklist/__tests__/index.js new file mode 100644 index 0000000000..9ee952df21 --- /dev/null +++ b/lib/rules/selector-pseudo-class-blacklist/__tests__/index.js @@ -0,0 +1,247 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['focus'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-class-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['focus', 'global', 'input-placeholder', 'not', 'nth-last-child', 'has'], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:hover {}', + }, + { + code: 'a:nth-child(5) {}', + }, + { + code: 'div:nth-LAST-child {}', + }, + { + code: 'input:-Ms-INPUT-placeholder {}', + }, + { + code: ':root {}', + }, + { + code: 'a:HOVER {}', + }, + { + code: 'a:hover, a:nth-child(5) {}', + }, + { + code: 'a::before {}', + }, + { + code: 'a:nth-child(5)::before {}', + }, + { + code: 'a:-moz-placeholder {}', + }, + { + code: 'a:-MOZ-PLACEholder {}', + }, + { + code: ':root { --foo: 1px; }', + description: 'custom property in root', + }, + { + code: 'html { --foo: 1px; }', + description: 'custom property in selector', + }, + { + code: ':root { --custom-property-set: {} }', + description: 'custom property set in root', + }, + { + code: 'html { --custom-property-set: {} }', + description: 'custom property set in selector', + }, + ], + + reject: [ + { + code: 'a:focus {}', + message: messages.rejected('focus'), + line: 1, + column: 2, + }, + { + code: 'a,\n:global {}', + message: messages.rejected('global'), + line: 2, + column: 1, + }, + { + code: 'input:-ms-input-placeholder {}', + message: messages.rejected('-ms-input-placeholder'), + line: 1, + column: 6, + }, + { + code: 'a:not(::selection) {}', + message: messages.rejected('not'), + line: 1, + column: 2, + }, + { + code: 'a:has(> img) {}', + message: messages.rejected('has'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: [['/^last/']], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:first-child() {}', + }, + { + code: 'a:nth-LAST-child(5) {}', + }, + ], + + reject: [ + { + code: 'a:last-child {}', + message: messages.rejected('last-child'), + line: 1, + column: 2, + }, + { + code: 'a:last-of-child {}', + message: messages.rejected('last-of-child'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: [[/^last/]], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + ], + + reject: [ + { + code: 'a:last-child {}', + message: messages.rejected('last-child'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: [[/(not|matches|has)/]], + skipBasicChecks: true, + + accept: [ + { + code: 'a:focus {}', + }, + ], + + reject: [ + { + code: 'a:not() {}', + message: messages.rejected('not'), + line: 1, + column: 2, + }, + { + code: 'body:not(div):has(span) {}', + warnings: [ + { + message: messages.rejected('not'), + line: 1, + column: 5, + }, + { + message: messages.rejected('has'), + line: 1, + column: 14, + }, + ], + }, + { + code: 'body:nt(div):not(span) {}', + message: messages.rejected('not'), + line: 1, + column: 13, + }, + { + code: 'a:has() {}', + message: messages.rejected('has'), + line: 1, + column: 2, + }, + { + code: 'a:matches() {}', + message: messages.rejected('matches'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: ['variable'], + skipBasicChecks: true, + syntax: 'scss', + + accept: [ + { + code: ':#{$variable} {}', + }, + { + code: ':#{$VARIABLE} {}', + }, + { + code: 'a:#{$variable} {}', + }, + ], +}); diff --git a/lib/rules/selector-pseudo-class-blacklist/index.js b/lib/rules/selector-pseudo-class-blacklist/index.js new file mode 100644 index 0000000000..73040ba475 --- /dev/null +++ b/lib/rules/selector-pseudo-class-blacklist/index.js @@ -0,0 +1,83 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const parseSelector = require('../../utils/parseSelector'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-pseudo-class-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (selector) => `Unexpected pseudo-class "${selector}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-class-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + if (!selector.includes(':')) { + return; + } + + parseSelector(selector, result, rule, (selectorTree) => { + selectorTree.walkPseudos((pseudoNode) => { + const value = pseudoNode.value; + + // Ignore pseudo-elements + + if (value.slice(0, 2) === '::') { + return; + } + + const name = value.slice(1); + + if (!matchesStringOrRegExp(postcss.vendor.unprefixed(name), list)) { + return; + } + + report({ + index: pseudoNode.sourceIndex, + message: messages.rejected(name), + node: rule, + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-pseudo-class-disallowed-list/README.md b/lib/rules/selector-pseudo-class-disallowed-list/README.md index bb21ebf65a..dbd5a98d31 100644 --- a/lib/rules/selector-pseudo-class-disallowed-list/README.md +++ b/lib/rules/selector-pseudo-class-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed pseudo-class selectors. * This pseudo-class selector */ ``` -This rule was previously called, and is aliased as, `selector-pseudo-class-blacklist`. - This rule ignores selectors that use variable interpolation e.g. `:#{$variable} {}`. ## Options diff --git a/lib/rules/selector-pseudo-class-whitelist/README.md b/lib/rules/selector-pseudo-class-whitelist/README.md new file mode 100644 index 0000000000..294f80300a --- /dev/null +++ b/lib/rules/selector-pseudo-class-whitelist/README.md @@ -0,0 +1,55 @@ +# selector-pseudo-class-whitelist + +**_Deprecated: Instead use the [`selector-pseudo-class-allowed-list`](../selector-pseudo-class-allowed-list/README.md) rule._** + +Specify a list of allowed pseudo-class selectors. + + +```css + a:hover {} +/** ↑ + * This pseudo-class selector */ +``` + +This rule ignores selectors that use variable interpolation e.g. `:#{$variable} {}`. + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", /pseudo-classes/ or "/regex/"]|"pseudo-class"|/regex/` + +If a string is surrounded with `"/"` (e.g. `"/^nth-/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^nth-/` will match `nth-child`, `nth-last-child`, `nth-of-type`, etc. + +Given: + +``` +["hover", "/^nth-/"] +``` + +The following patterns are considered violations: + + +```css +a:focus {} +``` + + +```css +a:first-of-type {} +``` + +The following patterns are _not_ considered violations: + + +```css +a:hover {} +``` + + +```css +a:nth-of-type(5) {} +``` + + +```css +a:nth-child(2) {} +``` diff --git a/lib/rules/selector-pseudo-class-whitelist/__tests__/index.js b/lib/rules/selector-pseudo-class-whitelist/__tests__/index.js new file mode 100644 index 0000000000..136f7392a1 --- /dev/null +++ b/lib/rules/selector-pseudo-class-whitelist/__tests__/index.js @@ -0,0 +1,196 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['hover'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-class-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['hover', 'nth-child', 'root', 'placeholder', 'has'], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:hover {}', + }, + { + code: 'a:nth-child(5) {}', + }, + { + code: ':root {}', + }, + { + code: 'a:has(#id) {}', + }, + { + code: 'a:hover, a:nth-child(5) {}', + }, + { + code: 'a::before {}', + }, + { + code: 'a:nth-child(5)::before {}', + }, + { + code: 'a:-moz-placeholder {}', + }, + { + code: ':root { --foo: 1px; }', + description: 'custom property in root', + }, + { + code: 'html { --foo: 1px; }', + description: 'custom property in selector', + }, + { + code: ':root { --custom-property-set: {} }', + description: 'custom property set in root', + }, + { + code: 'html { --custom-property-set: {} }', + description: 'custom property set in selector', + }, + ], + + reject: [ + { + code: 'a:HOVER {}', + message: messages.rejected('HOVER'), + line: 1, + column: 2, + }, + { + code: 'a:-MOZ-PLACEholder {}', + message: messages.rejected('-MOZ-PLACEholder'), + line: 1, + column: 2, + }, + { + code: 'a:focus {}', + message: messages.rejected('focus'), + line: 1, + column: 2, + }, + { + code: 'div:nth-LAST-child {}', + message: messages.rejected('nth-LAST-child'), + line: 1, + column: 4, + }, + { + code: 'a,\n:global {}', + message: messages.rejected('global'), + line: 2, + column: 1, + }, + { + code: 'input:-ms-input-placeholder {}', + message: messages.rejected('-ms-input-placeholder'), + line: 1, + column: 6, + }, + { + code: 'input:-Ms-INPUT-placeholder {}', + message: messages.rejected('-Ms-INPUT-placeholder'), + line: 1, + column: 6, + }, + { + code: 'a:not(::selection) {}', + message: messages.rejected('not'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: [['/^nth/']], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:nth-child(5) {}', + }, + { + code: 'a:nth-LAST-child {}', + }, + ], + + reject: [ + { + code: 'a:hover {}', + message: messages.rejected('hover'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: [[/^nth/]], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + ], + + reject: [ + { + code: 'a:hover {}', + message: messages.rejected('hover'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: ['hover'], + skipBasicChecks: true, + syntax: 'scss', + + accept: [ + { + code: ':#{$variable} {}', + }, + { + code: ':#{$VARIABLE} {}', + }, + { + code: 'a:#{$variable} {}', + }, + ], +}); diff --git a/lib/rules/selector-pseudo-class-whitelist/index.js b/lib/rules/selector-pseudo-class-whitelist/index.js new file mode 100644 index 0000000000..8f9d8d8773 --- /dev/null +++ b/lib/rules/selector-pseudo-class-whitelist/index.js @@ -0,0 +1,82 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const parseSelector = require('../../utils/parseSelector'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-pseudo-class-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (selector) => `Unexpected pseudo-class "${selector}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-class-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + if (!selector.includes(':')) { + return; + } + + parseSelector(selector, result, rule, (selectorTree) => { + selectorTree.walkPseudos((pseudoNode) => { + const value = pseudoNode.value; + + // Ignore pseudo-elements + if (value.slice(0, 2) === '::') { + return; + } + + const name = value.slice(1); + + if (matchesStringOrRegExp(postcss.vendor.unprefixed(name), list)) { + return; + } + + report({ + index: pseudoNode.sourceIndex, + message: messages.rejected(name), + node: rule, + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-pseudo-element-allowed-list/README.md b/lib/rules/selector-pseudo-element-allowed-list/README.md index 2ed1068195..c920727f8a 100644 --- a/lib/rules/selector-pseudo-element-allowed-list/README.md +++ b/lib/rules/selector-pseudo-element-allowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of allowed pseudo-element selectors. * This pseudo-element selector */ ``` -This rule was previously called, and is aliased as, `selector-pseudo-element-whitelist`. - This rule ignores: - CSS2 pseudo-elements i.e. those prefixed with a single colon diff --git a/lib/rules/selector-pseudo-element-blacklist/README.md b/lib/rules/selector-pseudo-element-blacklist/README.md new file mode 100644 index 0000000000..bcb9cf2908 --- /dev/null +++ b/lib/rules/selector-pseudo-element-blacklist/README.md @@ -0,0 +1,56 @@ +# selector-pseudo-element-blacklist + +**_Deprecated: Instead use the [`selector-pseudo-element-disallowed-list`](../selector-pseudo-element-disallowed-list/README.md) rule._** + +Specify a list of disallowed pseudo-element selectors. + + +```css + a::before {} +/** ↑ + * This pseudo-element selector */ +``` + +This rule ignores: + +- CSS2 pseudo-elements i.e. those prefixed with a single colon +- selectors that use variable interpolation e.g. `::#{$variable} {}` + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", "pseudo-elements" or "regex"]|"pseudo-element"|/regex/` + +Given: + +``` +["before", "/^my-/i"] +``` + +The following patterns are considered violations: + + +```css +a::before {} +``` + + +```css +a::my-pseudo-element {} +``` + + +```css +a::MY-OTHER-pseudo-element {} +``` + +The following patterns are _not_ considered violations: + + +```css +a::after {} +``` + + +```css +a::not-my-pseudo-element {} +``` diff --git a/lib/rules/selector-pseudo-element-blacklist/__tests__/index.js b/lib/rules/selector-pseudo-element-blacklist/__tests__/index.js new file mode 100644 index 0000000000..77cf01b66b --- /dev/null +++ b/lib/rules/selector-pseudo-element-blacklist/__tests__/index.js @@ -0,0 +1,126 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['before'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-element-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['before', 'selection', /^my/i], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:hover {}', + }, + { + code: 'a::BEFORE {}', + }, + { + code: 'a::after {}', + }, + { + code: '::first-line {}', + }, + { + code: '::-webkit-first-line {}', + }, + { + code: 'a:not(::first-line) {}', + }, + { + code: 'a::their-pseudo-element {}', + }, + { + code: 'a::THEIR-other-pseudo-element {}', + }, + ], + + reject: [ + { + code: 'a::before {}', + message: messages.rejected('before'), + line: 1, + column: 2, + }, + { + code: 'a,\nb::before {}', + message: messages.rejected('before'), + line: 2, + column: 2, + }, + { + code: '::selection {}', + message: messages.rejected('selection'), + line: 1, + column: 1, + }, + { + code: '::-webkit-selection {}', + message: messages.rejected('-webkit-selection'), + line: 1, + column: 1, + }, + { + code: 'a:not(::selection) {}', + message: messages.rejected('selection'), + line: 1, + column: 7, + }, + { + code: 'a::my-pseudo-element {}', + message: messages.rejected('my-pseudo-element'), + line: 1, + column: 2, + }, + { + code: 'a::MY-OTHER-pseudo-element {}', + message: messages.rejected('MY-OTHER-pseudo-element'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: ['before'], + skipBasicChecks: true, + syntax: 'scss', + + accept: [ + { + code: '::#{$variable} {}', + }, + { + code: '::#{$VARIABLE} {}', + }, + { + code: 'a::#{$variable} {}', + }, + ], +}); diff --git a/lib/rules/selector-pseudo-element-blacklist/index.js b/lib/rules/selector-pseudo-element-blacklist/index.js new file mode 100644 index 0000000000..8333f37bbb --- /dev/null +++ b/lib/rules/selector-pseudo-element-blacklist/index.js @@ -0,0 +1,82 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const parseSelector = require('../../utils/parseSelector'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-pseudo-element-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (selector) => `Unexpected pseudo-element "${selector}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-element-disallowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + if (!selector.includes('::')) { + return; + } + + parseSelector(selector, result, rule, (selectorTree) => { + selectorTree.walkPseudos((pseudoNode) => { + const value = pseudoNode.value; + + // Ignore pseudo-classes + if (value[1] !== ':') { + return; + } + + const name = value.slice(2); + + if (!matchesStringOrRegExp(postcss.vendor.unprefixed(name), list)) { + return; + } + + report({ + index: pseudoNode.sourceIndex, + message: messages.rejected(name), + node: rule, + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selector-pseudo-element-disallowed-list/README.md b/lib/rules/selector-pseudo-element-disallowed-list/README.md index 0db5b8df2c..36516836e7 100644 --- a/lib/rules/selector-pseudo-element-disallowed-list/README.md +++ b/lib/rules/selector-pseudo-element-disallowed-list/README.md @@ -9,8 +9,6 @@ Specify a list of disallowed pseudo-element selectors. * This pseudo-element selector */ ``` -This rule was previously called, and is aliased as, `selector-pseudo-element-blacklist`. - This rule ignores: - CSS2 pseudo-elements i.e. those prefixed with a single colon diff --git a/lib/rules/selector-pseudo-element-whitelist/README.md b/lib/rules/selector-pseudo-element-whitelist/README.md new file mode 100644 index 0000000000..2a24022cb0 --- /dev/null +++ b/lib/rules/selector-pseudo-element-whitelist/README.md @@ -0,0 +1,56 @@ +# selector-pseudo-element-whitelist + +**_Deprecated: Instead use the [`selector-pseudo-element-allowed-list`](../selector-pseudo-element-allowed-list/README.md) rule._** + +Specify a list of allowed pseudo-element selectors. + + +```css + a::before {} +/** ↑ + * This pseudo-element selector */ +``` + +This rule ignores: + +- CSS2 pseudo-elements i.e. those prefixed with a single colon +- selectors that use variable interpolation e.g. `::#{$variable} {}` + +## Options + +`array|string|regex`: `["array", "of", "unprefixed", "pseudo-elements" or "regex"]|"pseudo-element"|/regex/` + +Given: + +``` +["before", "/^my-/i"] +``` + +The following patterns are considered violations: + + +```css +a::after {} +``` + + +```css +a::not-my-pseudo-element {} +``` + +The following patterns are _not_ considered violations: + + +```css +a::before {} +``` + + +```css +a::my-pseudo-element {} +``` + + +```css +a::MY-OTHER-pseudo-element {} +``` diff --git a/lib/rules/selector-pseudo-element-whitelist/__tests__/index.js b/lib/rules/selector-pseudo-element-whitelist/__tests__/index.js new file mode 100644 index 0000000000..20823c8a20 --- /dev/null +++ b/lib/rules/selector-pseudo-element-whitelist/__tests__/index.js @@ -0,0 +1,148 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['before'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-element-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + config: ['before', 'selection', /^my/i], + skipBasicChecks: true, + + accept: [ + { + code: 'a {}', + }, + { + code: 'a:hover {}', + }, + { + code: 'a::before {}', + }, + { + code: '::selection {}', + }, + { + code: '::-webkit-selection {}', + }, + { + code: 'a:not(::selection) {}', + }, + { + code: 'a::my-pseudo-element {}', + }, + { + code: 'a::MY-other-pseudo-element {}', + }, + ], + + reject: [ + { + code: 'a::BEFORE {}', + message: messages.rejected('BEFORE'), + line: 1, + column: 2, + }, + { + code: 'a::after {}', + message: messages.rejected('after'), + line: 1, + column: 2, + }, + { + code: 'a::AFTER {}', + message: messages.rejected('AFTER'), + line: 1, + column: 2, + }, + { + code: 'a,\nb::after {}', + message: messages.rejected('after'), + line: 2, + column: 2, + }, + { + code: 'a::not-my-pseudo-element {}', + message: messages.rejected('not-my-pseudo-element'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: /^before/, + skipBasicChecks: true, + + accept: [ + { + code: '::before {}', + }, + { + code: '::before-custom {}', + }, + ], + reject: [ + { + code: 'a::after {}', + message: messages.rejected('after'), + line: 1, + column: 2, + }, + { + code: 'a::not-before {}', + message: messages.rejected('not-before'), + line: 1, + column: 2, + }, + ], +}); + +testRule({ + ruleName, + config: ['before'], + skipBasicChecks: true, + syntax: 'scss', + + accept: [ + { + code: '::#{$variable} {}', + }, + { + code: '::#{$VARIABLE} {}', + }, + { + code: 'a::#{$variable} {}', + }, + ], + reject: [ + { + code: 'a::after {}', + message: messages.rejected('after'), + line: 1, + column: 2, + }, + ], +}); diff --git a/lib/rules/selector-pseudo-element-whitelist/index.js b/lib/rules/selector-pseudo-element-whitelist/index.js new file mode 100644 index 0000000000..949785a55b --- /dev/null +++ b/lib/rules/selector-pseudo-element-whitelist/index.js @@ -0,0 +1,82 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); +const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const parseSelector = require('../../utils/parseSelector'); +const postcss = require('postcss'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateOptions = require('../../utils/validateOptions'); + +const ruleName = 'selector-pseudo-element-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (selector) => `Unexpected pseudo-element "${selector}"`, +}); + +function rule(list) { + return (root, result) => { + const validOptions = validateOptions(result, ruleName, { + actual: list, + possible: [_.isString, _.isRegExp], + }); + + if (!validOptions) { + return; + } + + result.warn( + `'${ruleName}' has been deprecated. Instead use 'selector-pseudo-element-allowed-list'.`, + { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }, + ); + + root.walkRules((rule) => { + if (!isStandardSyntaxRule(rule)) { + return; + } + + const selector = rule.selector; + + if (!selector.includes('::')) { + return; + } + + parseSelector(selector, result, rule, (selectorTree) => { + selectorTree.walkPseudos((pseudoNode) => { + const value = pseudoNode.value; + + // Ignore pseudo-classes + if (value[1] !== ':') { + return; + } + + const name = value.slice(2); + + if (matchesStringOrRegExp(postcss.vendor.unprefixed(name), list)) { + return; + } + + report({ + index: pseudoNode.sourceIndex, + message: messages.rejected(name), + node: rule, + result, + ruleName, + }); + }); + }); + }); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/selectorCombinatorSpaceChecker.js b/lib/rules/selectorCombinatorSpaceChecker.js index c6731dc1bc..d8c73a846a 100644 --- a/lib/rules/selectorCombinatorSpaceChecker.js +++ b/lib/rules/selectorCombinatorSpaceChecker.js @@ -2,6 +2,7 @@ 'use strict'; +const isStandardSyntaxCombinator = require('../utils/isStandardSyntaxCombinator'); const isStandardSyntaxRule = require('../utils/isStandardSyntaxRule'); const parseSelector = require('../utils/parseSelector'); const report = require('../utils/report'); @@ -19,6 +20,11 @@ module.exports = function (opts) { const fixedSelector = parseSelector(selector, opts.result, rule, (selectorTree) => { selectorTree.walkCombinators((node) => { + // Ignore non-standard combinators + if (!isStandardSyntaxCombinator(node)) { + return; + } + // Ignore spaced descendant combinator if (/\s/.test(node.value)) { return; diff --git a/lib/rules/unit-allowed-list/README.md b/lib/rules/unit-allowed-list/README.md index 2c34eda820..3f5e2de93c 100644 --- a/lib/rules/unit-allowed-list/README.md +++ b/lib/rules/unit-allowed-list/README.md @@ -9,8 +9,6 @@ a { width: 100px; } * These units */ ``` -This rule was previously called, and is aliased as, `unit-whitelist`. - ## Options `array|string`: `["array", "of", "units"]|"unit"` diff --git a/lib/rules/unit-blacklist/README.md b/lib/rules/unit-blacklist/README.md new file mode 100644 index 0000000000..bcfa8710b3 --- /dev/null +++ b/lib/rules/unit-blacklist/README.md @@ -0,0 +1,161 @@ +# unit-blacklist + +**_Deprecated: Instead use the [`unit-disallowed-list`](../unit-disallowed-list/README.md) rule._** + +Specify a list of disallowed units. + + +```css +a { width: 100px; } +/** ↑ + * These units */ +``` + +## Options + +`array|string`: `["array", "of", "units"]|"unit"` + +Given: + +``` +["px", "em", "deg"] +``` + +The following patterns are considered violations: + + +```css +a { width: 100px; } +``` + + +```css +a { font-size: 10em; } +``` + + +```css +a { transform: rotate(30deg); } +``` + +The following patterns are _not_ considered violations: + + +```css +a { font-size: 1.2rem; } +``` + + +```css +a { line-height: 1.2; } +``` + + +```css +a { height: 100vmin; } +``` + + +```css +a { animation: animation-name 5s ease; } +``` + +## Optional secondary options + +### `ignoreProperties: { unit: ["property", "/regex/", /regex/] }` + +Ignore units in the values of declarations with the specified properties. + +For example, with `["px", "vmin"]`. + +Given: + +``` +{ + "px": [ "font-size", "/^border/" ], + "vmin": [ "width" ] +} +``` + +The following patterns are _not_ considered violations: + + +```css +a { font-size: 13px; } +``` + + +```css +a { border-bottom-width: 6px; } +``` + + +```css +a { width: 100vmin; } +``` + +The following patterns are considered violations: + + +```css +a { line-height: 12px; } +``` + + +```css +a { -moz-border-radius-topright: 40px; } +``` + + +```css +a { height: 100vmin; } +``` + +### `ignoreMediaFeatureNames: { unit: ["property", "/regex/", /regex/] }` + +Ignore units for specific feature names. + +For example, with `["px", "dpi"]`. + +Given: + +``` +{ + "px": [ "min-width", "/height$/" ], + "dpi": [ "resolution" ] +} +``` + +The following patterns are _not_ considered violations: + + +```css +@media (min-width: 960px) {} +``` + + +```css +@media (max-height: 280px) {} +``` + + +```css +@media not (resolution: 300dpi) {} +``` + +The following patterns are considered violations: + + +```css +@media screen and (max-device-width: 500px) {} +``` + + +```css +@media all and (min-width: 500px) and (max-width: 200px) {} +``` + + +```css +@media print and (max-resolution: 100dpi) {} +``` diff --git a/lib/rules/unit-blacklist/__tests__/index.js b/lib/rules/unit-blacklist/__tests__/index.js new file mode 100644 index 0000000000..728701be94 --- /dev/null +++ b/lib/rules/unit-blacklist/__tests__/index.js @@ -0,0 +1,563 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['px'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'unit-disallowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['px', 'vmin'], + + accept: [ + { + code: 'a { line-height: 1; }', + }, + { + code: 'a { color: #000; }', + }, + { + code: 'a { top: 0; left: 0; }', + }, + { + code: 'a { font-size: 100%; }', + }, + { + code: 'a { line-height: 1.2rem; }', + }, + { + code: 'a { line-height: 1.2rEm; }', + }, + { + code: 'a { line-height: 1.2REM; }', + }, + { + code: 'a { font-size: .5rem; }', + }, + { + code: 'a { font-size: 0.5rem; }', + }, + { + code: 'a { margin: 0 10em 5rem 2in; }', + }, + { + code: 'a { background-position: top right, 1em 5vh; }', + }, + { + code: 'a { top: calc(10em - 3em); }', + }, + { + code: 'a { top: calc(10em*2rem); }', + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100% - 50em), silver); }', + }, + { + code: 'a { width: /* 100px */ 1em; }', + description: 'ignore unit within comments', + }, + { + code: 'a::before { content: "10px"}', + description: 'ignore unit within quotes', + }, + { + code: 'a { font-size: $fs10px; }', + description: 'ignore preprocessor variable includes unit', + }, + { + code: 'a { font-size: --some-fs-10px; }', + description: 'ignore css variable includes unit', + }, + { + code: 'a { background-url: url(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { background-url: uRl(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { background-url: URL(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { margin10px: 10em; }', + description: 'ignore property include wrong unit', + }, + { + code: 'a10px { margin: 10em; }', + description: 'ignore type selector include wrong unit', + }, + { + code: '#a10px { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: '.a10px { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: 'input[type=10px] { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: 'a:hover10px { margin: 10em; }', + description: 'ignore pseudo-class include wrong unit', + }, + { + code: 'a::before10px { margin: 10em; }', + description: 'ignore pseudo-class include wrong unit', + }, + { + code: 'a { margin: calc(100% - #{margin * 2}); }', + description: 'work with interpolation', + }, + { + code: '@media (min-width: 10em) {}', + description: '@media', + }, + { + code: '@media (min-width: 10em)\n and (max-width: 20em) {}', + description: 'complex @media', + }, + ], + + reject: [ + { + code: 'a { font-size: 13px; }', + message: messages.rejected('px'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 13pX; }', + message: messages.rejected('pX'), + line: 1, + column: 16, + }, + { + code: 'a { font-size: 13PX; }', + message: messages.rejected('PX'), + line: 1, + column: 16, + }, + { + code: 'a { width: 100vmin; }', + message: messages.rejected('vmin'), + line: 1, + column: 12, + }, + { + code: 'a { line-height: .1px; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + { + code: 'a { line-height: 0.1px; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + { + code: 'a { border-left: 1px solid #ccc; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + { + code: 'a { margin: 0 20px; }', + message: messages.rejected('px'), + line: 1, + column: 15, + }, + { + code: 'a { margin: 0 0 0 20px; }', + message: messages.rejected('px'), + line: 1, + column: 19, + }, + { + code: 'a { background-position: top right, 1em 5px; }', + message: messages.rejected('px'), + line: 1, + column: 41, + }, + { + code: 'a { top: calc(100px - 30vh); }', + message: messages.rejected('px'), + line: 1, + column: 15, + }, + { + code: 'a { top: calc(100px*2); }', + message: messages.rejected('px'), + line: 1, + column: 15, + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100vh - 5vmin), silver); }', + message: messages.rejected('vmin'), + line: 1, + column: 68, + }, + { + code: 'a { margin: calc(100% - #{$margin * 2px}); }', + message: messages.rejected('px'), + line: 1, + column: 37, + }, + { + code: '@media (min-width: 13px) {}', + message: messages.rejected('px'), + description: '@media', + line: 1, + column: 20, + }, + { + code: '@media (min-width: 10em)\n and (max-width: 20px) {}', + message: messages.rejected('px'), + description: 'complex @media', + line: 2, + column: 19, + }, + { + code: '@media (width < 10.01px) {}', + message: messages.rejected('px'), + description: 'media feature range', + line: 1, + column: 17, + }, + ], +}); + +testRule({ + ruleName, + + config: ['px'], + + accept: [ + { + code: 'a { line-height: 1em; }', + }, + ], + + reject: [ + { + code: 'a { line-height: 1px; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'vmin'], + { + ignoreProperties: { + px: ['font-size', 'margin', '/^border/'], + vmin: ['width', 'height'], + }, + }, + ], + + accept: [ + { + code: 'a { font-size: 13px; }', + }, + { + code: 'a { font-size: 13pX; }', + }, + { + code: 'a { margin: 0 20px; }', + }, + { + code: 'a { margin: 0 0 0 20Px; }', + }, + { + code: 'a { width: 100vmin; }', + }, + { + code: 'a { height: 99vmIn; }', + }, + { + code: 'a { border: 1px solid purple; }', + }, + { + code: 'a { border-bottom-width: 6px; }', + }, + ], + + reject: [ + { + code: 'a { line-height: .1px; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100vh - 5vmin), silver); }', + message: messages.rejected('vmin'), + line: 1, + column: 68, + }, + { + code: 'a { -moz-border-radius-topright: 40px; }', + message: messages.rejected('px'), + line: 1, + column: 34, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'vmin'], + { + ignoreProperties: { + px: ['font-size', 'margin', /^border/], + vmin: ['width', 'height'], + }, + }, + ], + + accept: [ + { + code: 'a { border: 1px solid purple; }', + }, + { + code: 'a { border-bottom-width: 6px; }', + }, + ], + + reject: [ + { + code: 'a { line-height: .1px; }', + message: messages.rejected('px'), + line: 1, + column: 18, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'dpi', '%'], + { + ignoreMediaFeatureNames: { + px: ['min-width', 'height'], + dpi: ['min-resolution', 'resolution'], + '%': ['width', '/^min/'], + }, + }, + ], + + accept: [ + { + code: '@media (min-width: 960px) { body { font-size: 13em } }', + }, + { + code: '@media (width: 960%) { /* body { font-size: 13em } */ }', + }, + { + code: '@media (min-width: 960%) { /* body { font-size: 13em } */ }', + }, + { + code: 'a { @media (min-width: 960px) { body { font-size: 13em } } }', + }, + { + code: '@media print and (min-resolution: 300dpi) { body { font-size: 13em } }', + }, + { + code: '@media print { body { font-size: 40pt } }', + }, + { + code: '@media screen, print { body { line-height: 1.2 } }', + }, + { + code: '@MEDIA (min-width: 960px) { body { font-size: 13em } }', + }, + { + code: '@media (MIN-WIDTH: 960px) { body { font-size: 13em } }', + }, + { + code: '@media (height > -100px) { body { background: green; } }', + }, + { + code: '@media not (resolution: -300dpi) { body { background: green; } }', + }, + { + code: '@media only screen and (min-width: 500px) { }', + }, + { + code: '@media only speech and (width > 20%) { }', + }, + { + code: '@media speech and (device-aspect-ratio: 16/9) { }', + }, + { + code: + '@media only screen and (min-width: 320px) and (height: 480px) and (-webkit-min-device-pixel-ratio: 2) { body { line-height: 1.4 } }', + }, + { + code: '@media screen, print { }', + }, + { + code: '@media speech and (aspect-ratio: 11/5) { }', + }, + { + code: '@media (min-width: 700px), handheld and (orientation: landscape) { }', + }, + ], + + reject: [ + { + code: '@media screen and (max-width: 500px) { }', + message: messages.rejected('px'), + line: 1, + column: 31, + }, + { + code: '@media (width: 960px) { /* body { font-size: 13em } */ }', + message: messages.rejected('px'), + line: 1, + column: 16, + }, + { + code: '@media (min-height: 960px) { /* body { font-size: 13em } */ }', + message: messages.rejected('px'), + line: 1, + column: 21, + }, + { + code: 'a { @media screen and (max-width: 500px) { } }', + message: messages.rejected('px'), + line: 1, + column: 35, + }, + { + code: '@media all and (min-width: 500px) and (max-width: 200px) { }', + message: messages.rejected('px'), + line: 1, + column: 51, + }, + { + code: '@MEDIA print { body { font-size: 60dpi } }', + message: messages.rejected('dpi'), + line: 1, + column: 34, + }, + { + code: '@media (MAX-WIDTH: 10px) { }', + message: messages.rejected('px'), + line: 1, + column: 20, + }, + { + code: '@media (min-width: 10em)\n and (max-width: 20px) { }', + message: messages.rejected('px'), + line: 2, + column: 19, + }, + { + code: '@media (width < 10.01px) {}', + message: messages.rejected('px'), + line: 1, + column: 17, + }, + { + code: '@media only speech and (max-device-width > 20%) { }', + message: messages.rejected('%'), + line: 1, + column: 44, + }, + { + code: '@media not (max-resolution: -300dpi) { body { background: green; } }', + message: messages.rejected('dpi'), + line: 1, + column: 29, + }, + { + code: + '@media only screen and (min-width: 320px) and (height: 480px) and (-webkit-min-device-pixel-ratio: 2) { body { line-height: 1.4px } }', + message: messages.rejected('px'), + line: 1, + column: 125, + }, + { + code: + '@media only screen and (min-width: 320px) and (height: 480px) and (-webkit-min-device-pixel-ratio: 2px) { body { line-height: 1.4 } }', + message: messages.rejected('px'), + line: 1, + column: 100, + }, + { + code: '@media screen and (min-width: 699px) and (min-width: 520px), (max-width: 1151px)', + message: messages.rejected('px'), + line: 1, + column: 74, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'dpi', '%'], + { + ignoreMediaFeatureNames: { + px: ['min-width', 'height'], + dpi: ['min-resolution', 'resolution'], + '%': ['width', /^min/], + }, + }, + ], + + accept: [ + { + code: '@media (width: 960%) { /* body { font-size: 13em } */ }', + }, + { + code: '@media (min-width: 960%) { /* body { font-size: 13em } */ }', + }, + ], + + reject: [ + { + code: '@media screen and (max-width: 500px) { }', + message: messages.rejected('px'), + line: 1, + column: 31, + }, + ], +}); diff --git a/lib/rules/unit-blacklist/index.js b/lib/rules/unit-blacklist/index.js new file mode 100644 index 0000000000..b27a5ae3e7 --- /dev/null +++ b/lib/rules/unit-blacklist/index.js @@ -0,0 +1,130 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const atRuleParamIndex = require('../../utils/atRuleParamIndex'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const getUnitFromValueNode = require('../../utils/getUnitFromValueNode'); +const mediaParser = require('postcss-media-query-parser').default; +const optionsMatches = require('../../utils/optionsMatches'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateObjectWithArrayProps = require('../../utils/validateObjectWithArrayProps'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'unit-blacklist'; + +const messages = ruleMessages(ruleName, { + rejected: (unit) => `Unexpected unit "${unit}"`, +}); + +// a function to retrieve only the media feature name +// could be externalized in an utils function if needed in other code +const getMediaFeatureName = (mediaFeatureNode) => { + const value = mediaFeatureNode.value.toLowerCase(); + + return /((-?\w*)*)/i.exec(value)[1]; +}; + +function rule(listInput, options) { + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions( + result, + ruleName, + { + actual: list, + possible: [_.isString], + }, + { + optional: true, + actual: options, + possible: { + ignoreProperties: validateObjectWithArrayProps([_.isString, _.isRegExp]), + ignoreMediaFeatureNames: validateObjectWithArrayProps([_.isString, _.isRegExp]), + }, + }, + ); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'unit-disallowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + function check(node, nodeIndex, valueNode, input, option) { + const unit = getUnitFromValueNode(valueNode); + + // There is not unit or it is not configured as a violation + if (!unit || (unit && !list.includes(unit.toLowerCase()))) { + return; + } + + // The unit has an ignore option for the specific input + if (optionsMatches(option, unit.toLowerCase(), input)) { + return; + } + + report({ + index: nodeIndex + valueNode.sourceIndex, + message: messages.rejected(unit), + node, + result, + ruleName, + }); + } + + function checkMedia(node, value, getIndex) { + mediaParser(node.params).walk(/^media-feature$/i, (mediaFeatureNode) => { + const mediaName = getMediaFeatureName(mediaFeatureNode); + const parentValue = mediaFeatureNode.parent.value; + + valueParser(value).walk((valueNode) => { + // Ignore all non-word valueNode and + // the values not included in the parentValue string + if (valueNode.type !== 'word' || !parentValue.includes(valueNode.value)) { + return; + } + + check( + node, + getIndex(node), + valueNode, + mediaName, + options ? options.ignoreMediaFeatureNames : {}, + ); + }); + }); + } + + function checkDecl(node, value, getIndex) { + // make sure multiplication operations (*) are divided - not handled + // by postcss-value-parser + value = value.replace(/\*/g, ','); + + valueParser(value).walk((valueNode) => { + // Ignore wrong units within `url` function + if (valueNode.type === 'function' && valueNode.value.toLowerCase() === 'url') { + return false; + } + + check(node, getIndex(node), valueNode, node.prop, options ? options.ignoreProperties : {}); + }); + } + + root.walkAtRules(/^media$/i, (atRule) => checkMedia(atRule, atRule.params, atRuleParamIndex)); + root.walkDecls((decl) => checkDecl(decl, decl.value, declarationValueIndex)); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/unit-disallowed-list/README.md b/lib/rules/unit-disallowed-list/README.md index 2f20017030..e38d426968 100644 --- a/lib/rules/unit-disallowed-list/README.md +++ b/lib/rules/unit-disallowed-list/README.md @@ -9,8 +9,6 @@ a { width: 100px; } * These units */ ``` -This rule was previously called, and is aliased as, `unit-blacklist`. - ## Options `array|string`: `["array", "of", "units"]|"unit"` diff --git a/lib/rules/unit-whitelist/README.md b/lib/rules/unit-whitelist/README.md new file mode 100644 index 0000000000..c32c1333d7 --- /dev/null +++ b/lib/rules/unit-whitelist/README.md @@ -0,0 +1,117 @@ +# unit-whitelist + +**_Deprecated: Instead use the [`unit-allowed-list`](../unit-allowed-list/README.md) rule._** + +Specify a list of allowed units. + + +```css +a { width: 100px; } +/** ↑ + * These units */ +``` + +## Options + +`array|string`: `["array", "of", "units"]|"unit"` + +Given: + +``` +["px", "em", "deg"] +``` + +The following patterns are considered violations: + + +```css +a { width: 100%; } +``` + + +```css +a { font-size: 10rem; } +``` + + +```css +a { animation: animation-name 5s ease; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { font-size: 1.2em; } +``` + + +```css +a { line-height: 1.2; } +``` + + +```css +a { height: 100px; } +``` + + +```css +a { height: 100PX; } +``` + + +```css +a { transform: rotate(30deg); } +``` + +## Optional secondary options + +### `ignoreProperties: { unit: ["property", "/regex/", /regex/] }` + +Ignore units in the values of declarations with the specified properties. + +For example, with `["px", "em"]`. + +Given: + +``` +{ + "rem": [ "line-height", "/^border/" ], + "%": [ "width" ] +} +``` + +The following patterns are _not_ considered violations: + + +```css +a { line-height: 0.1rem; } +``` + + +```css +a { border-bottom-width: 6rem; } +``` + + +```css +a { width: 100%; } +``` + +The following patterns are considered violations: + + +```css +a { margin: 0 20rem; } +``` + + +```css +a { -moz-border-radius-topright: 20rem; } +``` + + +```css +a { height: 100%; } +``` diff --git a/lib/rules/unit-whitelist/__tests__/index.js b/lib/rules/unit-whitelist/__tests__/index.js new file mode 100644 index 0000000000..07ef614ca0 --- /dev/null +++ b/lib/rules/unit-whitelist/__tests__/index.js @@ -0,0 +1,365 @@ +'use strict'; + +const standalone = require('../../../standalone'); +const { messages, ruleName } = require('..'); + +it('warns that the rule is deprecated', () => { + const config = { + rules: { + [ruleName]: ['px'], + }, + }; + + const code = ''; + + return standalone({ code, config }).then((output) => { + const result = output.results[0]; + + expect(result.deprecations).toHaveLength(1); + expect(result.deprecations[0].text).toEqual( + `'${ruleName}' has been deprecated. Instead use 'unit-allowed-list'.`, + ); + expect(result.deprecations[0].reference).toEqual( + `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + ); + }); +}); + +testRule({ + ruleName, + + config: ['px', 'em'], + + accept: [ + { + code: 'a { line-height: 1; }', + }, + { + code: 'a { color: #000; }', + }, + { + code: 'a { font-size: 14px; }', + }, + { + code: 'a { font-size: 14pX; }', + }, + { + code: 'a { font-size: 14PX; }', + }, + { + code: 'a { font-size: 1.2em; }', + }, + { + code: 'a { font-size: .5em; }', + }, + { + code: 'a { font-size: 0.5em; }', + }, + { + code: 'a { margin: 0 10em 5em 2px; }', + }, + { + code: 'a { background-position: top right, 10px 20px; }', + }, + { + code: 'a { top: calc(10em - 3em); }', + }, + { + code: 'a { top: calc(10em*3); }', + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100px - 50em), silver); }', + }, + { + code: 'a { width: /* 100pc */ 1em; }', + description: 'ignore unit within comments', + }, + { + code: 'a::before { content: "10%"}', + description: 'ignore unit within quotes', + }, + { + code: 'a { font-size: $fs10%; }', + description: 'ignore preprocessor variable includes unit', + }, + { + code: 'a { font-size: --some-fs-10rem; }', + description: 'ignore css variable includes unit', + }, + { + code: 'a { background-url: url(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { background-url: uRl(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { background-url: URL(10vmin); }', + description: 'ignore url function', + }, + { + code: 'a { margin10rem: 10em; }', + description: 'ignore property include wrong unit', + }, + { + code: 'a10rem { margin: 10em; }', + description: 'ignore type selector include wrong unit', + }, + { + code: '#a10rem { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: '.a10rem { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: 'input[type=10rem] { margin: 10em; }', + description: 'ignore class selector include wrong unit', + }, + { + code: 'a:hover10rem { margin: 10em; }', + description: 'ignore pseudo-class include wrong unit', + }, + { + code: 'a::before10rem { margin: 10em; }', + description: 'ignore pseudo-class include wrong unit', + }, + { + code: 'a { margin: calc(100px - #{margin * 2}); }', + description: 'work with interpolation', + }, + { + code: '@media (min-width: 10em) {}', + description: '@media', + }, + { + code: '@media (min-width: 10px)\n and (max-width: 20em) {}', + description: 'complex @media', + }, + ], + + reject: [ + { + code: 'a { font-size: 80%; }', + message: messages.rejected('%'), + line: 1, + column: 16, + }, + { + code: 'a { width: 100vmin; }', + message: messages.rejected('vmin'), + line: 1, + column: 12, + }, + { + code: 'a { width: 100vMiN; }', + message: messages.rejected('vMiN'), + line: 1, + column: 12, + }, + { + code: 'a { width: 100VMIN; }', + message: messages.rejected('VMIN'), + line: 1, + column: 12, + }, + { + code: 'a { line-height: .1rem; }', + message: messages.rejected('rem'), + line: 1, + column: 18, + }, + { + code: 'a { line-height: 0.1rem; }', + message: messages.rejected('rem'), + line: 1, + column: 18, + }, + { + code: 'a { border-left: 1rem solid #ccc; }', + message: messages.rejected('rem'), + line: 1, + column: 18, + }, + { + code: 'a { margin: 0 20%; }', + message: messages.rejected('%'), + line: 1, + column: 15, + }, + { + code: 'a { margin: 0 0 0 20rem; }', + message: messages.rejected('rem'), + line: 1, + column: 19, + }, + { + code: 'a { background-position: top right, 1em 5rem; }', + message: messages.rejected('rem'), + line: 1, + column: 41, + }, + { + code: 'a { top: calc(2vh*3); }', + message: messages.rejected('vh'), + line: 1, + column: 15, + }, + { + code: 'a { top: calc(100px - 30vh); }', + message: messages.rejected('vh'), + line: 1, + column: 23, + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100px - 5vmin), silver); }', + message: messages.rejected('vmin'), + line: 1, + column: 68, + }, + { + code: 'a { margin: calc(100px - #{$margin * 2rem}); }', + message: messages.rejected('rem'), + line: 1, + column: 38, + }, + { + code: '@media (min-width: 13rem) {}', + message: messages.rejected('rem'), + description: '@media', + line: 1, + column: 20, + }, + { + code: '@media (min-width: 10em)\n and (max-width: 20rem) {}', + message: messages.rejected('rem'), + description: 'complex @media', + line: 2, + column: 19, + }, + { + code: '@media (width < 10.01REM) {}', + message: messages.rejected('REM'), + description: 'media feature range', + line: 1, + column: 17, + }, + ], +}); + +testRule({ + ruleName, + + config: ['px'], + + accept: [ + { + code: 'a { line-height: 1px; }', + }, + ], + + reject: [ + { + code: 'a { line-height: 1em; }', + message: messages.rejected('em'), + line: 1, + column: 18, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'em'], + { + ignoreProperties: { + rem: ['line-height', 'margin', '/^border/'], + '%': ['width', 'height'], + }, + }, + ], + + accept: [ + { + code: 'a { line-height: 0.1rem; }', + }, + { + code: 'a { line-height: 0.1rEm; }', + }, + { + code: 'a { margin: 0 20rem; }', + }, + { + code: 'a { margin: 0 0 0 20reM; }', + }, + { + code: 'a { width: 100%; }', + }, + { + code: 'a { height: 50%; }', + }, + { + code: 'a { border: 1rem solid purple; }', + }, + { + code: 'a { border-bottom-width: 6rem; }', + }, + ], + + reject: [ + { + code: 'a { font-size: 80%; }', + message: messages.rejected('%'), + line: 1, + column: 16, + }, + { + code: 'a { background-image: linear-gradient(to right, white calc(100px - 5rem), silver); }', + message: messages.rejected('rem'), + line: 1, + column: 68, + }, + { + code: 'a { -moz-border-radius-topright: 40rem; }', + message: messages.rejected('rem'), + line: 1, + column: 34, + }, + ], +}); + +testRule({ + ruleName, + + config: [ + ['px', 'em'], + { + ignoreProperties: { + rem: ['line-height', 'margin', /^border/], + '%': ['width', 'height'], + }, + }, + ], + + accept: [ + { + code: 'a { border: 1rem solid purple; }', + }, + { + code: 'a { border-bottom-width: 6rem; }', + }, + ], + + reject: [ + { + code: 'a { font-size: 80%; }', + message: messages.rejected('%'), + line: 1, + column: 16, + }, + ], +}); diff --git a/lib/rules/unit-whitelist/index.js b/lib/rules/unit-whitelist/index.js new file mode 100644 index 0000000000..b9f6b18b9f --- /dev/null +++ b/lib/rules/unit-whitelist/index.js @@ -0,0 +1,90 @@ +// @ts-nocheck + +'use strict'; + +const _ = require('lodash'); +const atRuleParamIndex = require('../../utils/atRuleParamIndex'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const getUnitFromValueNode = require('../../utils/getUnitFromValueNode'); +const optionsMatches = require('../../utils/optionsMatches'); +const report = require('../../utils/report'); +const ruleMessages = require('../../utils/ruleMessages'); +const validateObjectWithArrayProps = require('../../utils/validateObjectWithArrayProps'); +const validateOptions = require('../../utils/validateOptions'); +const valueParser = require('postcss-value-parser'); + +const ruleName = 'unit-whitelist'; + +const messages = ruleMessages(ruleName, { + rejected: (unit) => `Unexpected unit "${unit}"`, +}); + +function rule(listInput, options) { + const list = [].concat(listInput); + + return (root, result) => { + const validOptions = validateOptions( + result, + ruleName, + { + actual: list, + possible: [_.isString], + }, + { + optional: true, + actual: options, + possible: { + ignoreProperties: validateObjectWithArrayProps([_.isString, _.isRegExp]), + }, + }, + ); + + if (!validOptions) { + return; + } + + result.warn(`'${ruleName}' has been deprecated. Instead use 'unit-allowed-list'.`, { + stylelintType: 'deprecation', + stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`, + }); + + function check(node, value, getIndex) { + // make sure multiplication operations (*) are divided - not handled + // by postcss-value-parser + value = value.replace(/\*/g, ','); + valueParser(value).walk((valueNode) => { + // Ignore wrong units within `url` function + if (valueNode.type === 'function' && valueNode.value.toLowerCase() === 'url') { + return false; + } + + const unit = getUnitFromValueNode(valueNode); + + if (!unit || (unit && list.includes(unit.toLowerCase()))) { + return; + } + + if (options && optionsMatches(options.ignoreProperties, unit.toLowerCase(), node.prop)) { + return; + } + + report({ + index: getIndex(node) + valueNode.sourceIndex, + message: messages.rejected(unit), + node, + result, + ruleName, + }); + }); + } + + root.walkAtRules(/^media$/i, (atRule) => check(atRule, atRule.params, atRuleParamIndex)); + root.walkDecls((decl) => check(decl, decl.value, declarationValueIndex)); + }; +} + +rule.primaryOptionArray = true; + +rule.ruleName = ruleName; +rule.messages = messages; +module.exports = rule; diff --git a/lib/rules/value-no-vendor-prefix/README.md b/lib/rules/value-no-vendor-prefix/README.md index 08a8c10f1e..9a08e40582 100644 --- a/lib/rules/value-no-vendor-prefix/README.md +++ b/lib/rules/value-no-vendor-prefix/README.md @@ -11,6 +11,8 @@ a { display: -webkit-flex; } This rule will only complain for prefixed _standard_ values, and not for prefixed _proprietary_ or _unknown_ ones. +The [`fix` option](../../../docs/user-guide/usage/options.md#fix) can automatically fix all of the problems reported by this rule. + ## Options ### `true` diff --git a/lib/rules/value-no-vendor-prefix/__tests__/index.js b/lib/rules/value-no-vendor-prefix/__tests__/index.js index 8c9ef0e663..39934295e1 100644 --- a/lib/rules/value-no-vendor-prefix/__tests__/index.js +++ b/lib/rules/value-no-vendor-prefix/__tests__/index.js @@ -5,6 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, config: [true], + fix: true, accept: [ { @@ -33,54 +34,63 @@ testRule({ reject: [ { code: '.foo { display: -webkit-flex; }', + fixed: '.foo { display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { display: -wEbKiT-fLeX; }', + fixed: '.foo { display: fLeX; }', message: messages.rejected('-wEbKiT-fLeX'), line: 1, column: 17, }, { code: '.foo { display: -WEBKIT-FLEX; }', + fixed: '.foo { display: FLEX; }', message: messages.rejected('-WEBKIT-FLEX'), line: 1, column: 17, }, { code: '.foo { dIsPlAy: -webkit-flex; }', + fixed: '.foo { dIsPlAy: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { DISPLAY: -webkit-flex; }', + fixed: '.foo { DISPLAY: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { color: pink; display: -webkit-flex; }', + fixed: '.foo { color: pink; display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 30, }, { code: '.foo { display: -webkit-box; }', + fixed: '.foo { display: box; }', message: messages.rejected('-webkit-box'), line: 1, column: 17, }, { code: '.foo { background: -webkit-linear-gradient(bottom, #000, #fff); }', + fixed: '.foo { background: linear-gradient(bottom, #000, #fff); }', message: messages.rejected('-webkit-linear-gradient'), line: 1, column: 20, }, { code: '.foo { max-width: -moz-max-content; }', + fixed: '.foo { max-width: max-content; }', message: messages.rejected('-moz-max-content'), line: 1, column: 19, @@ -92,6 +102,7 @@ testRule({ ruleName, config: [true], syntax: 'scss', + fix: true, accept: [ { @@ -113,6 +124,7 @@ testRule({ ruleName, config: [true], syntax: 'less', + fix: true, accept: [ { @@ -127,6 +139,7 @@ testRule({ testRule({ ruleName, config: [true, { ignoreValues: ['grab', 'max-content', '/^linear-/'] }], + fix: true, accept: [ { @@ -142,18 +155,21 @@ testRule({ reject: [ { code: '.foo { display: -webkit-flex; }', + fixed: '.foo { display: flex; }', message: messages.rejected('-webkit-flex'), line: 1, column: 17, }, { code: '.foo { display: -wEbKiT-fLeX; }', + fixed: '.foo { display: fLeX; }', message: messages.rejected('-wEbKiT-fLeX'), line: 1, column: 17, }, { code: '.foo { display: -WEBKIT-FLEX; }', + fixed: '.foo { display: FLEX; }', message: messages.rejected('-WEBKIT-FLEX'), line: 1, column: 17, diff --git a/lib/rules/value-no-vendor-prefix/index.js b/lib/rules/value-no-vendor-prefix/index.js index f82718d921..ba4b3609c3 100644 --- a/lib/rules/value-no-vendor-prefix/index.js +++ b/lib/rules/value-no-vendor-prefix/index.js @@ -21,7 +21,7 @@ const messages = ruleMessages(ruleName, { const valuePrefixes = ['-webkit-', '-moz-', '-ms-', '-o-']; -function rule(actual, options) { +function rule(actual, options, context) { return (root, result) => { const validOptions = validateOptions( result, @@ -67,6 +67,12 @@ function rule(actual, options) { return; } + if (context.fix) { + decl.value = isAutoprefixable.unprefix(decl.value); + + return; + } + report({ message: messages.rejected(fullIdentifier), node: decl, diff --git a/lib/standalone.js b/lib/standalone.js index 6ecc3fd3f7..9674e2ff34 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const createStylelint = require('./createStylelint'); const createStylelintResult = require('./createStylelintResult'); const debug = require('debug')('stylelint:standalone'); +const fastGlob = require('fast-glob'); const FileCache = require('./utils/FileCache'); const filterFilePaths = require('./utils/filterFilePaths'); const formatters = require('./formatters'); @@ -47,6 +48,7 @@ module.exports = function (options) { const ignoreDisables = options.ignoreDisables; const reportNeedlessDisables = options.reportNeedlessDisables; const reportInvalidScopeDisables = options.reportInvalidScopeDisables; + const reportDescriptionlessDisables = options.reportDescriptionlessDisables; const syntax = options.syntax; const allowEmptyInput = options.allowEmptyInput || false; const useCache = options.cache || false; @@ -98,6 +100,7 @@ module.exports = function (options) { ignorePath: ignoreFilePath, reportNeedlessDisables, reportInvalidScopeDisables, + reportDescriptionlessDisables, syntax, customSyntax, fix, @@ -175,6 +178,20 @@ module.exports = function (options) { fileList = [fileList]; } + fileList = fileList.map((entry) => { + if (globby.hasMagic(entry)) { + const cwd = _.get(globbyOptions, 'cwd', process.cwd()); + const absolutePath = !path.isAbsolute(entry) ? path.join(cwd, entry) : path.normalize(entry); + + if (fs.existsSync(absolutePath)) { + // This glob-like path points to a file. Return an escaped path to avoid globbing + return fastGlob.escapePath(entry); + } + } + + return entry; + }); + if (!options.disableDefaultIgnores) { fileList = fileList.concat(ALWAYS_IGNORED_GLOBS.map((glob) => `!${glob}`)); } diff --git a/lib/utils/__tests__/atRuleParamIndex.test.js b/lib/utils/__tests__/atRuleParamIndex.test.js index fe4daf0989..ab20fead7d 100644 --- a/lib/utils/__tests__/atRuleParamIndex.test.js +++ b/lib/utils/__tests__/atRuleParamIndex.test.js @@ -5,30 +5,26 @@ const postcss = require('postcss'); describe('atRuleParamIndex', () => { it('has a single space before the param', () => { - atRules('@media (color) {}', (atRule) => { - expect(atRuleParamIndex(atRule)).toBe(7); - }); + expect(atRuleParamIndex(atRule('@media (color) {}'))).toBe(7); }); it('has multiple spaces before the param', () => { - atRules('@media (color) {}', (atRule) => { - expect(atRuleParamIndex(atRule)).toBe(8); - }); + expect(atRuleParamIndex(atRule('@media (color) {}'))).toBe(8); }); it('has a newline before the param', () => { - atRules("@import\n'x.css');", (atRule) => { - expect(atRuleParamIndex(atRule)).toBe(8); - }); + expect(atRuleParamIndex(atRule("@import\n'x.css');"))).toBe(8); }); it('has a function param', () => { - atRules('@document url-prefix(http://www.w3.org/Style/)', (atRule) => { - expect(atRuleParamIndex(atRule)).toBe(10); - }); + expect(atRuleParamIndex(atRule('@document url-prefix(http://www.w3.org/Style/)'))).toBe(10); }); }); -function atRules(css, cb) { - postcss.parse(css).walkAtRules(cb); +function atRule(css) { + const list = []; + + postcss.parse(css).walkAtRules((rule) => list.push(rule)); + + return list[0]; } diff --git a/lib/utils/__tests__/checkAgainstRule.test.js b/lib/utils/__tests__/checkAgainstRule.test.js index df353eb45f..13a2ee22a6 100644 --- a/lib/utils/__tests__/checkAgainstRule.test.js +++ b/lib/utils/__tests__/checkAgainstRule.test.js @@ -60,24 +60,4 @@ describe('checkAgainstRule', () => { expect(warnings[0].line).toBe(3); expect(warnings[0].column).toBe(1); }); - - it('warns against a renamed rule when an aliased rule is used', () => { - const root = postcss.parse('a { top: 10px; }'); - - const warnings = []; - - checkAgainstRule( - { - ruleName: 'unit-whitelist', - ruleSettings: ['em'], - root, - }, - (warning) => warnings.push(warning), - ); - - expect(warnings).toHaveLength(1); - expect(warnings[0].rule).toBe('unit-allowed-list'); - expect(warnings[0].line).toBe(1); - expect(warnings[0].column).toBe(10); - }); }); diff --git a/lib/utils/__tests__/declarationValueIndex.test.js b/lib/utils/__tests__/declarationValueIndex.test.js index d5b98ec46a..b6b0ed4dd8 100644 --- a/lib/utils/__tests__/declarationValueIndex.test.js +++ b/lib/utils/__tests__/declarationValueIndex.test.js @@ -5,36 +5,30 @@ const postcss = require('postcss'); describe('declarationValueIndex', () => { it('has a space before the value', () => { - rules('a { a: b}', (decl) => { - expect(declarationValueIndex(decl)).toBe(3); - }); + expect(declarationValueIndex(decl('a { a: b}'))).toBe(3); }); it('has a colon before the value', () => { - rules('a { a :b }', (decl) => { - expect(declarationValueIndex(decl)).toBe(3); - }); + expect(declarationValueIndex(decl('a { a :b }'))).toBe(3); }); it('has no spaces before the value', () => { - rules('a { a:b }', (decl) => { - expect(declarationValueIndex(decl)).toBe(2); - }); + expect(declarationValueIndex(decl('a { a:b }'))).toBe(2); }); it('has multiple characters before the value', () => { - rules('a { a : b }', (decl) => { - expect(declarationValueIndex(decl)).toBe(5); - }); + expect(declarationValueIndex(decl('a { a : b }'))).toBe(5); }); it('has a newline before the value', () => { - rules('a { a:\nb }', (decl) => { - expect(declarationValueIndex(decl)).toBe(3); - }); + expect(declarationValueIndex(decl('a { a:\nb }'))).toBe(3); }); }); -function rules(css, cb) { - postcss.parse(css).walkDecls(cb); +function decl(css) { + const list = []; + + postcss.parse(css).walkDecls((decl) => list.push(decl)); + + return list[0]; } diff --git a/lib/utils/__tests__/isCustomPropertySet.test.js b/lib/utils/__tests__/isCustomPropertySet.test.js index 0dee043e9d..0a3de8fc11 100644 --- a/lib/utils/__tests__/isCustomPropertySet.test.js +++ b/lib/utils/__tests__/isCustomPropertySet.test.js @@ -5,18 +5,14 @@ const postcss = require('postcss'); describe('isCustomPropertySet', () => { it('accepts custom property set', () => { - customPropertySet('--foo: {};', (customPropertySet) => { - expect(isCustomPropertySet(customPropertySet)).toBeTruthy(); - }); + expect(isCustomPropertySet(node('--foo: {};'))).toBeTruthy(); }); it('rejects custom property', () => { - customPropertySet('--foo: red;', (customPropertySet) => { - expect(isCustomPropertySet(customPropertySet)).toBeFalsy(); - }); + expect(isCustomPropertySet(node('--foo: red;'))).toBeFalsy(); }); }); -function customPropertySet(css, cb) { - postcss.parse(css).walk(cb); +function node(css) { + return postcss.parse(css).first; } diff --git a/lib/utils/__tests__/isFirstNested.test.js b/lib/utils/__tests__/isFirstNested.test.js index c3ced6594e..6e699bc0a4 100644 --- a/lib/utils/__tests__/isFirstNested.test.js +++ b/lib/utils/__tests__/isFirstNested.test.js @@ -22,9 +22,13 @@ describe('isFirstNested', () => { } `); - root.walkRules((rule) => { - expect(isFirstNested(rule)).toBe(true); - }); + const rules = []; + + root.walkRules((rule) => rules.push(rule)); + + expect(rules).toHaveLength(2); + expect(isFirstNested(rules[0])).toBe(true); + expect(isFirstNested(rules[1])).toBe(true); }); it('returns true with the first-nested at-rule', () => { @@ -37,9 +41,13 @@ describe('isFirstNested', () => { } `); - root.walkAtRules((atRule) => { - expect(isFirstNested(atRule)).toBe(true); - }); + const atRules = []; + + root.walkAtRules((rule) => atRules.push(rule)); + + expect(atRules).toHaveLength(2); + expect(isFirstNested(atRules[0])).toBe(true); + expect(isFirstNested(atRules[1])).toBe(true); }); it('returns true with the first-nested declaration', () => { @@ -52,9 +60,13 @@ describe('isFirstNested', () => { } `); - root.walkDecls((atRule) => { - expect(isFirstNested(atRule)).toBe(true); - }); + const decls = []; + + root.walkDecls((decl) => decls.push(decl)); + + expect(decls).toHaveLength(2); + expect(isFirstNested(decls[0])).toBe(true); + expect(isFirstNested(decls[1])).toBe(true); }); it('returns true with first-nested non-statement', () => { @@ -67,9 +79,14 @@ describe('isFirstNested', () => { } `); - root.walkComments((comment) => { - expect(isFirstNested(comment)).toBe(true); - }); + const comments = []; + + root.walkComments((comment) => comments.push(comment)); + + expect(comments).toHaveLength(3); + expect(isFirstNested(comments[0])).toBe(true); + expect(isFirstNested(comments[1])).toBe(true); + expect(isFirstNested(comments[2])).toBe(true); }); it('returns false with not-first-nested rule', () => { @@ -84,9 +101,13 @@ describe('isFirstNested', () => { } `); - root.walkRules('b', (rule) => { - expect(isFirstNested(rule)).toBe(false); - }); + const rules = []; + + root.walkRules('b', (rule) => rules.push(rule)); + + expect(rules).toHaveLength(2); + expect(isFirstNested(rules[0])).toBe(false); + expect(isFirstNested(rules[1])).toBe(false); }); it('returns false with not-first-nested at-rule', () => { @@ -101,9 +122,13 @@ describe('isFirstNested', () => { } `); - root.walkAtRules('expect', (atRule) => { - expect(isFirstNested(atRule)).toBe(false); - }); + const atRules = []; + + root.walkAtRules('expect', (atRule) => atRules.push(atRule)); + + expect(atRules).toHaveLength(2); + expect(isFirstNested(atRules[0])).toBe(false); + expect(isFirstNested(atRules[1])).toBe(false); }); it('returns false with not-first-nested declaration', () => { @@ -126,8 +151,14 @@ describe('isFirstNested', () => { } `); - root.walkDecls('color', (atRule) => { - expect(isFirstNested(atRule)).toBe(false); - }); + const decls = []; + + root.walkDecls('color', (decl) => decls.push(decl)); + + expect(decls).toHaveLength(4); + expect(isFirstNested(decls[0])).toBe(false); + expect(isFirstNested(decls[1])).toBe(false); + expect(isFirstNested(decls[2])).toBe(false); + expect(isFirstNested(decls[3])).toBe(false); }); }); diff --git a/lib/utils/__tests__/isStandardSyntaxCombinator.test.js b/lib/utils/__tests__/isStandardSyntaxCombinator.test.js index ed73f96d59..65b71d3454 100644 --- a/lib/utils/__tests__/isStandardSyntaxCombinator.test.js +++ b/lib/utils/__tests__/isStandardSyntaxCombinator.test.js @@ -60,6 +60,26 @@ describe('isStandardSyntaxCombinator', () => { expect(isStandardSyntaxCombinator(func)).toBeFalsy(); }); }); + it('last node is combinator', () => { + rules('a ~, {}', (func) => { + expect(isStandardSyntaxCombinator(func)).toBeFalsy(); + }); + }); + it('first node is combinator', () => { + rules('~ b {}', (func) => { + expect(isStandardSyntaxCombinator(func)).toBeFalsy(); + }); + }); + it('last node (in first container) is combinator', () => { + rules('a ~, b {}', (func) => { + expect(isStandardSyntaxCombinator(func)).toBeFalsy(); + }); + }); + it('first node (in second container) is combinator', () => { + rules('a, ~ b {}', (func) => { + expect(isStandardSyntaxCombinator(func)).toBeFalsy(); + }); + }); }); function rules(css, cb) { diff --git a/lib/utils/checkAgainstRule.js b/lib/utils/checkAgainstRule.js index 57775063c1..88a24d3c4a 100644 --- a/lib/utils/checkAgainstRule.js +++ b/lib/utils/checkAgainstRule.js @@ -10,7 +10,7 @@ const rules = require('../rules'); * @param {{ ruleName: string, ruleSettings: import('stylelint').StylelintConfigRuleSettings, - root: Object, + root: import('postcss').Root, }} options * @param {Function} callback * @returns {void} diff --git a/lib/utils/checkInvalidCLIOptions.js b/lib/utils/checkInvalidCLIOptions.js index 9334ecb9e5..9bb937669b 100644 --- a/lib/utils/checkInvalidCLIOptions.js +++ b/lib/utils/checkInvalidCLIOptions.js @@ -3,7 +3,7 @@ const _ = require('lodash'); const chalk = require('chalk'); const EOL = require('os').EOL; -const leven = require('leven'); +const levenshtein = require('fastest-levenshtein'); /** * @param {{ [key: string]: { alias?: string } }} allowedOptions @@ -35,7 +35,7 @@ const suggest = (all, invalid) => { const maxThreshold = 10; for (let threshold = 1; threshold <= maxThreshold; threshold++) { - const suggestion = all.find((option) => leven(option, invalid) <= threshold); + const suggestion = all.find((option) => levenshtein.distance(option, invalid) <= threshold); if (suggestion) { return suggestion; diff --git a/lib/utils/isAutoprefixable.js b/lib/utils/isAutoprefixable.js index 521aee12bb..051e23ea32 100644 --- a/lib/utils/isAutoprefixable.js +++ b/lib/utils/isAutoprefixable.js @@ -74,4 +74,13 @@ module.exports = { }) ); }, + + /** + * + * @param {string} value + * @returns {string} + */ + unprefix(value) { + return value.replace(/-\w+-/, ''); + }, }; diff --git a/lib/utils/isStandardSyntaxCombinator.js b/lib/utils/isStandardSyntaxCombinator.js index 2a929510ca..2eba3d9677 100644 --- a/lib/utils/isStandardSyntaxCombinator.js +++ b/lib/utils/isStandardSyntaxCombinator.js @@ -7,6 +7,28 @@ * @return {boolean} If `true`, the combinator is standard */ module.exports = function (node) { + // if it's not a combinator, then it's not a standard combinator + if (node.type !== 'combinator') { + return false; + } + // Ignore reference combinators like `/deep/` - return node.type === 'combinator' && !node.value.startsWith('/') && !node.value.endsWith('/'); + if (node.value.startsWith('/') || node.value.endsWith('/')) { + return false; + } + + // ignore the combinators that are the first or last node in their container + if (node.parent !== undefined && node.parent !== null) { + let parent = node.parent; + + if (node === parent.first) { + return false; + } + + if (node === parent.last) { + return false; + } + } + + return true; }; diff --git a/lib/utils/validateOptions.js b/lib/utils/validateOptions.js index a315839309..be701baaea 100644 --- a/lib/utils/validateOptions.js +++ b/lib/utils/validateOptions.js @@ -2,7 +2,7 @@ const _ = require('lodash'); -const ignoredOptions = ['severity', 'message']; +const ignoredOptions = ['severity', 'message', 'reportDisables']; /** @typedef {{possible: any, actual: any, optional: boolean}} Options */ diff --git a/package-lock.json b/package-lock.json index 5a4a2b3961..38a3e30479 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ { "name": "stylelint", - "version": "13.6.1", + "version": "13.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.10.4" } }, "@babel/compat-data": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.4.tgz", - "integrity": "sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", + "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", "dev": true, "requires": { "browserslist": "^4.12.0", @@ -24,37 +24,126 @@ } }, "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.0", - "@babel/parser": "^7.9.0", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz", + "integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.4", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/generator": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz", + "integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==", + "requires": { + "@babel/types": "^7.11.5", + "jsesc": "^2.5.1", + "source-map": "^0.6.1" + } + }, + "@babel/parser": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/generator": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", - "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", + "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", "requires": { - "@babel/types": "^7.9.5", + "@babel/types": "^7.11.0", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-annotate-as-pure": { @@ -73,13 +162,13 @@ "dev": true }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } @@ -102,13 +191,13 @@ "dev": true }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } @@ -131,27 +220,27 @@ "dev": true }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } } }, "@babel/helper-builder-react-jsx-experimental": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.4.tgz", - "integrity": "sha512-LyacH/kgQPgLAuaWrvvq1+E7f5bLyT8jXCh7nM67sRsy2cpIGfgWJ+FCnAKQXfY+F0tXUaN6FqLkp4JiCzdK8Q==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.11.5.tgz", + "integrity": "sha512-Vc4aPJnRZKWfzeCBsqTBnzulVNjABVdahSPhtdMD3Vs80ykx4a87jTHtF/VR+alSrDmNvat7l13yrRHauGcHVw==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-module-imports": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.11.5" }, "dependencies": { "@babel/helper-module-imports": { @@ -170,13 +259,13 @@ "dev": true }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } @@ -196,69 +285,19 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz", - "integrity": "sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", + "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.10.5", "@babel/helper-optimise-call-expression": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", "@babel/helper-replace-supers": "^7.10.4", "@babel/helper-split-export-declaration": "^7.10.4" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, "@babel/helper-optimise-call-expression": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", @@ -274,25 +313,13 @@ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.11.0" } }, "@babel/helper-validator-identifier": { @@ -301,72 +328,16 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.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" - } } } }, @@ -382,159 +353,77 @@ } }, "@babel/helper-define-map": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz", - "integrity": "sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", + "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" } - }, - "@babel/parser": { + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", + "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.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" - } } } }, - "@babel/helper-explode-assignable-expression": { + "@babel/helper-function-name": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", - "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "requires": { - "@babel/traverse": "^7.10.4", + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", "@babel/types": "^7.10.4" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, "@babel/helper-get-function-arity": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, "requires": { "@babel/types": "^7.10.4" } @@ -542,96 +431,30 @@ "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, "@babel/template": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.10.4", "@babel/types": "^7.10.4" } }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.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" - } } } }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, "@babel/helper-hoist-variables": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", @@ -648,54 +471,98 @@ "dev": true }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } } }, "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.11.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", "requires": { - "@babel/types": "^7.8.3" + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-plugin-utils": { @@ -852,55 +719,258 @@ } }, "@babel/helper-replace-supers": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", - "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", - "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==" - }, - "@babel/helper-wrap-function": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", - "dev": true, + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/generator": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz", + "integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==", + "requires": { + "@babel/types": "^7.11.5", + "jsesc": "^2.5.1", + "source-map": "^0.6.1" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/parser": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==" + }, + "@babel/traverse": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", + "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "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, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", "requires": { - "@babel/helper-function-name": "^7.10.4", "@babel/template": "^7.10.4", "@babel/traverse": "^7.10.4", "@babel/types": "^7.10.4" }, + "dependencies": { + "@babel/generator": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz", + "integrity": "sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==", + "requires": { + "@babel/types": "^7.11.5", + "jsesc": "^2.5.1", + "source-map": "^0.6.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", + "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.5", + "@babel/types": "^7.11.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@babel/parser": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", + "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==" + } + } + }, + "@babel/types": { + "version": "7.11.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", + "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -909,7 +979,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, "requires": { "@babel/types": "^7.10.4", "jsesc": "^2.5.1", @@ -921,7 +990,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.10.4", "@babel/template": "^7.10.4", @@ -932,7 +1000,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, "requires": { "@babel/types": "^7.10.4" } @@ -941,7 +1008,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, "requires": { "@babel/types": "^7.10.4" } @@ -949,14 +1015,12 @@ "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -966,14 +1030,12 @@ "@babel/parser": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==" }, "@babel/template": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.10.4", @@ -984,7 +1046,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.10.4", @@ -1001,46 +1062,12 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.13", "to-fast-properties": "^2.0.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" - } - } - } - }, - "@babel/helpers": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", - "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", - "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0" - } - }, - "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1054,14 +1081,14 @@ } }, "@babel/parser": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", - "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==" + "version": "7.11.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", + "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz", - "integrity": "sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", + "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1164,22 +1191,13 @@ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true - }, - "@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, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } } } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz", - "integrity": "sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", + "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1286,12 +1304,20 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", - "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } } }, "@babel/plugin-syntax-dynamic-import": { @@ -1320,6 +1346,23 @@ } } }, + "@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, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@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", @@ -1347,14 +1390,22 @@ } }, "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", - "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "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, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "@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", @@ -1980,823 +2031,65 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz", "integrity": "sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA==", "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "dev": true, "requires": { "@babel/helper-module-transforms": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", - "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, "@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.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" - } } } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", + "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.5", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", - "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.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" - } - } - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz", - "integrity": "sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", - "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.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" - } - } - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", - "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-plugin-utils": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", + "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.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" - } } } }, @@ -3133,9 +2426,9 @@ } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.4.tgz", - "integrity": "sha512-FTK3eQFrPv2aveerUSazFmGygqIdTtvskG50SnGnbEUnRPcGx2ylBhdFIzoVS1ty44hEgcPoCAyw5r3VDEq+Ug==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz", + "integrity": "sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -3460,9 +2753,9 @@ } }, "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "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.0.0", @@ -3499,6 +2792,7 @@ "version": "7.9.2", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", + "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } @@ -3507,6 +2801,7 @@ "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", @@ -3517,6 +2812,7 @@ "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.5", @@ -3533,6 +2829,7 @@ "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", @@ -3555,6 +2852,53 @@ "minimist": "^1.2.0" } }, + "@eslint/eslintrc": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", + "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "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 + } + } + }, "@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", @@ -3562,13 +2906,14 @@ "dev": true }, "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "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, "requires": { "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" }, @@ -3582,45 +2927,6 @@ "locate-path": "^5.0.0", "path-exists": "^4.0.0" } - }, - "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, - "requires": { - "p-locate": "^4.1.0" - } - }, - "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, - "requires": { - "p-try": "^2.0.0" - } - }, - "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, - "requires": { - "p-limit": "^2.2.0" - } - }, - "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 - }, - "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 } } }, @@ -3631,46 +2937,72 @@ "dev": true }, "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz", + "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.3.0", + "jest-util": "^26.3.0", "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + } } }, "@jest/core": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", - "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.2.tgz", + "integrity": "sha512-sDva7YkeNprxJfepOctzS8cAk9TOekldh+5FhVuXS40+94SHbiicRO1VV2tSoRtgIo+POs/Cdyf8p76vPTd6dg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/reporters": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/reporters": "^26.4.1", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.0.1", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-changed-files": "^26.3.0", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-resolve-dependencies": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "jest-watcher": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-resolve-dependencies": "^26.4.2", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", + "jest-watcher": "^26.3.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", @@ -3678,286 +3010,132 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "@jest/reporters": { + "version": "26.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.1.tgz", + "integrity": "sha512-aROTkCLU8++yiRGVxLsuDmZsQEKO6LprlrxtAuzvtpbIFl3eIjgIf3EUxDKgomkS25R9ZzwGEdB5weCcBZlrpQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.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": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^5.0.1" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.0.1", - "string-length": "^4.0.1" + "@types/istanbul-lib-report": "*" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "glob": "^7.1.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - } - } - }, - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - } - } - }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "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, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "color-name": "~1.1.4" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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 }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - } - } - }, - "@jest/globals": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", - "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", - "dev": true, - "requires": { - "@jest/environment": "^26.0.1", - "@jest/types": "^26.0.1", - "expect": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - } - } - }, - "@jest/reporters": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", - "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "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.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" - }, - "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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 }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "glob": "^7.1.3" } }, "source-map": { @@ -3965,118 +3143,49 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } } } }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", - "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "@jest/source-map": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz", + "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", + "callsites": "^3.0.0", "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1" + "source-map": "^0.6.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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 - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } } } }, "@jest/transform": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", - "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz", + "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "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": "^26.0.1", + "jest-haste-map": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-util": "^26.0.1", + "jest-util": "^26.3.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "slash": "^3.0.0", @@ -4084,41 +3193,31 @@ "write-file-atomic": "^3.0.0" }, "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@types/istanbul-lib-report": "*" } }, "source-map": { @@ -4129,18 +3228,6 @@ } } }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -5422,14 +4509,19 @@ } }, "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", + "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", "dev": true, "requires": { "any-observable": "^0.3.0" }, "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, "any-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", @@ -5439,9 +4531,9 @@ } }, "@sindresorhus/is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz", + "integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==", "dev": true }, "@sinonjs/commons": { @@ -5450,7 +4542,31 @@ "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", "dev": true, "requires": { - "type-detect": "4.0.8" + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^6.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + } } }, "@sinonjs/fake-timers": { @@ -5463,9 +4579,9 @@ } }, "@stylelint/postcss-css-in-js": { - "version": "0.37.1", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.1.tgz", - "integrity": "sha512-UMf2Rni3JGKi3ZwYRGMYJ5ipOA5ENJSKMtYA/pE1ZLURwdh7B5+z2r73RmWvub+N0UuH1Lo+TGfCgYwPvqpXNw==", + "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==", "requires": { "@babel/core": ">=7.9.0" } @@ -5591,12 +4707,6 @@ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -5612,9 +4722,154 @@ "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", "dev": true, "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" + "chalk": "^2.4.1", + "inquirer": "^6.2.1", + "rxjs": "^6.3.3" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + } } }, "@types/global-modules": { @@ -5666,12 +4921,11 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, @@ -5691,9 +4945,9 @@ } }, "@types/lodash": { - "version": "4.14.158", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.158.tgz", - "integrity": "sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w==", + "version": "4.14.161", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.161.tgz", + "integrity": "sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==", "dev": true }, "@types/micromatch": { @@ -5705,12 +4959,6 @@ "@types/braces": "*" } }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, "@types/minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", @@ -5780,6 +5028,12 @@ "integrity": "sha512-PlLI3u2hocS4nbzd9WUzQn/EyFl+NifbssU9QV40XzWOpwf5R7cDod2dmTUKYN7awE9jMrhy9FCO904ZYwaBDw==", "dev": true }, + "@types/table": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/table/-/table-5.0.0.tgz", + "integrity": "sha512-fQLtGLZXor264zUPWI95WNDsZ3QV43/c0lJpR/h1hhLJumXRmHNsrvBfEzW2YMhb0EWCsn4U6h82IgwsajAuTA==", + "dev": true + }, "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", @@ -5904,9 +5158,9 @@ "dev": true }, "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { "clean-stack": "^2.0.0", @@ -5917,6 +5171,7 @@ "version": "6.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5980,9 +5235,9 @@ } }, "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "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 }, "ansi-escapes": { @@ -5994,6 +5249,11 @@ "type-fest": "^0.11.0" }, "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", @@ -6093,11 +5353,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -6153,7 +5408,8 @@ "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true }, "async-exit-hook": { "version": "2.0.1", @@ -6180,17 +5436,24 @@ "dev": true }, "autoprefixer": { - "version": "9.8.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.4.tgz", - "integrity": "sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A==", + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", "requires": { "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001087", - "colorette": "^1.2.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", "postcss": "^7.0.32", "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "caniuse-lite": { + "version": "1.0.30001123", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001123.tgz", + "integrity": "sha512-03dJDoa4YC4332jq0rqwiM+Hw6tA5RJtrnZKvOQy7ASoIUv8CinkcmGhYpCvCjedvkBQrrKnkcELxrUSW/XwNQ==" + } } }, "available-typed-arrays": { @@ -6214,42 +5477,6 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, - "babel-jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", - "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", - "dev": true, - "requires": { - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } - } - }, "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", @@ -6272,45 +5499,6 @@ "test-exclude": "^6.0.0" } }, - "babel-plugin-jest-hoist": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", - "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", - "dev": true, - "requires": { - "@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-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-preset-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", - "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^26.0.0", - "babel-preset-current-node-syntax": "^0.1.2" - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -7053,7 +6241,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" }, @@ -7061,8 +6248,7 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" } } }, @@ -7182,12 +6368,6 @@ "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", "dev": true }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true - }, "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", @@ -7329,15 +6509,22 @@ "dev": true }, "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "requires": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", + "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.7.2" + "yaml": "^1.10.0" + }, + "dependencies": { + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + } } }, "create-ecdh": { @@ -7856,14 +7043,6 @@ "dev": true, "requires": { "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - } } }, "dedent": { @@ -8034,12 +7213,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -8233,6 +7406,12 @@ } } }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -8272,18 +7451,17 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } }, "enquirer": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz", - "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { - "ansi-colors": "^3.2.1" + "ansi-colors": "^4.1.1" } }, "entities": { @@ -8380,12 +7558,13 @@ } }, "eslint": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.3.0.tgz", - "integrity": "sha512-dJMVXwfU5PT1cj2Nv2VPPrKahKTGdX+5Dh0Q3YuKt+Y2UhdL2YbzsVaBMyG9HC0tBismlv/r1+eZqs6SMIV38Q==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.8.1.tgz", + "integrity": "sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.1.3", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -8393,9 +7572,9 @@ "doctrine": "^3.0.0", "enquirer": "^2.3.5", "eslint-scope": "^5.1.0", - "eslint-utils": "^2.0.0", - "eslint-visitor-keys": "^1.2.0", - "espree": "^7.1.0", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^1.3.0", + "espree": "^7.3.0", "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -8409,7 +7588,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.14", + "lodash": "^4.17.19", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -8423,6 +7602,12 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -8434,6 +7619,12 @@ "which": "^2.0.1" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -8455,6 +7646,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8512,6 +7709,51 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8671,20 +7913,20 @@ "dev": true }, "espree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", - "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, "requires": { - "acorn": "^7.2.0", + "acorn": "^7.4.0", "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.2.0" + "eslint-visitor-keys": "^1.3.0" }, "dependencies": { "acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", + "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", "dev": true }, "eslint-visitor-keys": { @@ -8711,9 +7953,9 @@ }, "dependencies": { "estraverse": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", - "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } @@ -8857,65 +8099,6 @@ } } }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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 - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - } - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9030,9 +8213,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", - "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -9070,6 +8253,11 @@ } } }, + "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==" + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -9189,6 +8377,21 @@ "p-locate": "^3.0.0", "path-exists": "^3.0.0" } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true } } }, @@ -9307,6 +8510,12 @@ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "dev": true }, + "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 + }, "get-port": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", @@ -9451,20 +8660,19 @@ } }, "got": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/got/-/got-11.3.0.tgz", - "integrity": "sha512-yi/kiZY2tNMtt5IfbfX8UL3hAZWb2gZruxYZ72AY28pU5p0TZjZdl0uRsuaFbnC0JopdUi3I+Mh1F3dPQ9Dh0Q==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-11.6.0.tgz", + "integrity": "sha512-ErhWb4IUjQzJ3vGs3+RR12NWlBDDkRciFpAkQ1LPUxi6OnwhGj07gQxjPsyIk69s7qMihwKrKquV6VQq7JNYLA==", "dev": true, "requires": { - "@sindresorhus/is": "^2.1.1", + "@sindresorhus/is": "^3.1.1", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.1", "decompress-response": "^6.0.0", - "get-stream": "^5.1.0", - "http2-wrapper": "^1.0.0-beta.4.5", + "http2-wrapper": "^1.0.0-beta.5.2", "lowercase-keys": "^2.0.0", "p-cancelable": "^2.0.0", "responselike": "^2.0.0" @@ -9473,7 +8681,8 @@ "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, "growly": { "version": "1.3.0", @@ -9766,8 +8975,7 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-proxy": { "version": "1.18.1", @@ -9915,19 +9123,19 @@ } }, "http2-wrapper": { - "version": "1.0.0-beta.4.6", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.4.6.tgz", - "integrity": "sha512-9oB4BiGDTI1FmIBlOF9OJ5hwJvcBEmPCqk/hy314Uhy2uq5TjekUZM8w8SPLLlUEM+mxNhXdPAXfrJN2Zbb/GQ==", + "version": "1.0.0-beta.5.2", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", + "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", "dev": true, "requires": { - "quick-lru": "^5.0.0", + "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" }, "dependencies": { "quick-lru": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.0.tgz", - "integrity": "sha512-WjAKQ9ORzvqjLijJXiXWqc3Gcs1ivoxCj6KJmEjoWBE6OtHwuaDLSAUqGHALUiid7A1KqGqsSHZs8prxF5xxAQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true } } @@ -9960,6 +9168,21 @@ "please-upgrade-node": "^3.2.0", "slash": "^3.0.0", "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + } } }, "iconv-lite": { @@ -10732,15 +9955,6 @@ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "dev": true }, - "is-url-superb": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-3.0.0.tgz", - "integrity": "sha512-3faQP+wHCGDQT1qReM5zCPx2mxoal6DzbzquFlCYJLWyy4WPTved33ea2xFbX37z4NoriEwZGIYhFtx8RUB5wQ==", - "dev": true, - "requires": { - "url-regex": "^5.0.0" - } - }, "is-whitespace-character": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", @@ -10893,122 +10107,109 @@ } }, "jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", - "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.2.tgz", + "integrity": "sha512-LLCjPrUh98Ik8CzW8LLVnSCfLaiY+wbK53U7VxnFSX7Q+kWC4noVeDvGWIFw0Amfq1lq2VfGm7YHWSLBV62MJw==", "dev": true, "requires": { - "@jest/core": "^26.0.1", + "@jest/core": "^26.4.2", "import-local": "^3.0.2", - "jest-cli": "^26.0.1" + "jest-cli": "^26.4.2" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-cli": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", - "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.2.tgz", + "integrity": "sha512-zb+lGd/SfrPvoRSC/0LWdaWCnscXc1mGYW//NP4/tmBvRPT3VntZ2jtKUONsRi59zc5JqmsSajA9ewJKFYp8Cw==", "dev": true, "requires": { - "@jest/core": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/core": "^26.4.2", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-config": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "prompts": "^2.0.1", "yargs": "^15.3.1" } - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } } } }, "jest-changed-files": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", - "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz", + "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cross-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", - "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -11017,20 +10218,45 @@ } }, "execa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.1.tgz", - "integrity": "sha512-SCjM/zlBdOK8Q5TIjOn6iEHZaPHFsMoTxXQ2nvUvtPnuohz3H2dIozSg+etNR98dGoYUp2ENSKLL/XaMmbxVgw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "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 + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + } + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" } }, "is-stream": { @@ -11039,6 +10265,11 @@ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -11048,12 +10279,29 @@ "path-key": "^3.0.0" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, "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 }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -11081,170 +10329,281 @@ } }, "jest-circus": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.0.1.tgz", - "integrity": "sha512-dp20V0Pi1N92Y7+ULPa3tNR9KCG0Sy19NiopyPmo5rNoQ4OGWmuzp1P0q1je2HV3fRD0BYE7wqh8aReGGENfUA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.4.2.tgz", + "integrity": "sha512-gzxoteivskdUTNxT7Jx6hrANsEm+x1wh8jaXmQCtzC7zoNWirk9chYdSosHFC4tJlfDZa0EsPreVAxLicLsV0w==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/environment": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^26.0.1", + "expect": "^26.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", + "jest-each": "^26.4.2", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2", "stack-utils": "^2.0.2", "throat": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" + } + }, + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "expect": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@jest/types": "^26.3.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-regex-util": "^26.0.0" } } } }, "jest-config": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", - "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.2.tgz", + "integrity": "sha512-QBf7YGLuToiM8PmTnJEdRxyYy3mHWLh24LJZKVdXZ2PNdizSe1B/E8bVm+HYcjbEzGuVXDv/di+EzdO/6Gq80A==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.0.1", - "@jest/types": "^26.0.1", - "babel-jest": "^26.0.1", + "@jest/test-sequencer": "^26.4.2", + "@jest/types": "^26.3.0", + "babel-jest": "^26.3.0", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.0.1", - "jest-environment-node": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.0.1", + "jest-environment-jsdom": "^26.3.0", + "jest-environment-node": "^26.3.0", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.4.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "micromatch": "^4.0.2", - "pretty-format": "^26.0.1" + "pretty-format": "^26.4.2" }, "dependencies": { + "@jest/test-result": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.2.tgz", + "integrity": "sha512-83DRD8N3M0tOhz9h0bn6Kl6dSp+US6DazuVF8J9m21WAp5x7CqSMaNycMP0aemC/SH/pDQQddbsfHRTBXVUgog==", + "dev": true, + "requires": { + "@jest/test-result": "^26.3.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.3.0", + "jest-runner": "^26.4.2", + "jest-runtime": "^26.4.2" + } + }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "babel-jest": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", + "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "dev": true, + "requires": { + "@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-preset-jest": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz", + "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.3" } } } }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz", + "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.3.0", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" + }, + "dependencies": { + "diff-sequences": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", + "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", + "dev": true + } } }, "jest-docblock": { @@ -11257,349 +10616,432 @@ } }, "jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.2.tgz", + "integrity": "sha512-p15rt8r8cUcRY0Mvo1fpkOGYm7iI8S6ySxgIdfh3oOIv+gHwrHTy5VWCGOecWUhDsit4Nz8avJWdT07WLpbwDA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } } } }, "jest-environment-jsdom": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", - "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz", + "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0", "jsdom": "^16.2.2" }, "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" + } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } } } }, "jest-environment-node": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", - "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz", + "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" }, "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" + } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } } } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz", + "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.3.0", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "isexe": "^2.0.0" + "@types/istanbul-lib-report": "*" } } } }, "jest-jasmine2": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", - "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.2.tgz", + "integrity": "sha512-z7H4EpCldHN1J8fNgsja58QftxBSL+JcwZmaXIvV9WKIM+x49F4GLHu/+BQh2kzRKHAgaN/E82od+8rTOBPyPA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/environment": "^26.3.0", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.0.1", + "expect": "^26.4.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", + "jest-each": "^26.4.2", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-runtime": "^26.4.2", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "pretty-format": "^26.4.2", "throat": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, - "@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", "dev": true, "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, + "expect": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-regex-util": "^26.0.0" + } + }, + "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==", + "requires": { + "path-key": "^3.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==" + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "isexe": "^2.0.0" } }, - "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 + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, "jest-leak-detector": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", - "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.2.tgz", + "integrity": "sha512-akzGcxwxtE+9ZJZRW+M2o+nTNnmQZxrHJxX/HjgDaU5+PLmY1qnQPnMjgADPGCRPhB+Yawe1iij0REe+k/aHoA==", "dev": true, "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" } }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz", + "integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.4.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz", + "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/stack-utils": "^1.0.1", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -11609,52 +11051,67 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } } } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz", + "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.3.0", + "@types/node": "*" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } } } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "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 }, "jest-preset-stylelint": { @@ -11670,50 +11127,41 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz", + "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.3.0", "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@types/istanbul-lib-report": "*" } }, "resolve": { @@ -11728,294 +11176,343 @@ } }, "jest-resolve-dependencies": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", - "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.2.tgz", + "integrity": "sha512-ADHaOwqEcVc71uTfySzSowA/RdxUpCxhxa2FNLiin9vWLB1uLPad3we+JSSROq5+SrL9iYPdZZF8bdKM7XABTQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.0.1" + "jest-snapshot": "^26.4.2" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true } } }, "jest-runner": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", - "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.2.tgz", + "integrity": "sha512-FgjDHeVknDjw1gRAYaoUoShe1K3XUuFMkIaXbdhEys+1O4bEJS8Avmn4lBwoMfL8O5oFTdWYKcf3tEJyyYyk8g==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", + "jest-config": "^26.4.2", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.0.1", - "jest-jasmine2": "^26.0.1", - "jest-leak-detector": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-haste-map": "^26.3.0", + "jest-leak-detector": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", + "jest-runtime": "^26.4.2", + "jest-util": "^26.3.0", + "jest-worker": "^26.3.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" + } + }, + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@types/istanbul-lib-report": "*" } } } }, "jest-runtime": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", - "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/globals": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.2.tgz", + "integrity": "sha512-4Pe7Uk5a80FnbHwSOk7ojNCJvz3Ks2CNQWT5Z7MJo4tX0jb3V/LThKvD9tKPNVNyeMH98J/nzGlcwc00R2dSHQ==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/environment": "^26.3.0", + "@jest/fake-timers": "^26.3.0", + "@jest/globals": "^26.4.2", + "@jest/source-map": "^26.3.0", + "@jest/test-result": "^26.3.0", + "@jest/transform": "^26.3.0", + "@jest/types": "^26.3.0", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", + "jest-config": "^26.4.2", + "jest-haste-map": "^26.3.0", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.4.0", + "jest-snapshot": "^26.4.2", + "jest-util": "^26.3.0", + "jest-validate": "^26.4.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", "yargs": "^15.3.1" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "@jest/environment": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", + "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "@jest/fake-timers": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", + "jest-mock": "^26.3.0" } }, - "@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "@jest/fake-timers": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", + "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", "dev": true, "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@jest/types": "^26.3.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.3.0", + "jest-mock": "^26.3.0", + "jest-util": "^26.3.0" + } + }, + "@jest/globals": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.2.tgz", + "integrity": "sha512-Ot5ouAlehhHLRhc+sDz2/9bmNv9p5ZWZ9LE1pXGGTCXBasmi5jnYjlgYcYt03FBwLmZXCZ7GrL29c33/XRQiow==", + "dev": true, + "requires": { + "@jest/environment": "^26.3.0", + "@jest/types": "^26.3.0", + "expect": "^26.4.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "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, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "color-name": "~1.1.4" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "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 + }, + "expect": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-regex-util": "^26.0.0" + } } } }, "jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz", + "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.2.tgz", + "integrity": "sha512-N6Uub8FccKlf5SBFnL2Ri/xofbaA68Cc3MGjP/NuwgnsvWh+9hLIR/DhrxbSiKXMY9vUW5dI6EW1eHaDHqe9sg==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.4.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.4.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-resolve": "^26.4.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.4.2", "semver": "^7.3.2" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 }, + "expect": { + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", + "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.4.2", + "jest-message-util": "^26.3.0", + "jest-regex-util": "^26.0.0" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -12025,48 +11522,66 @@ } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } } } }, "jest-validate": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", - "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.2.tgz", + "integrity": "sha512-blft+xDX7XXghfhY0mrsBCYhX365n8K5wNDC4XAcNKqqjEzsRUSXP44m6PL0QJEW2crxQFLLztVnJ4j7oPlQrQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "camelcase": "^6.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.0.1" + "pretty-format": "^26.4.2" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } @@ -12095,29 +11610,63 @@ } }, "jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz", + "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/test-result": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.0.1", + "jest-util": "^26.3.0", "string-length": "^4.0.1" + }, + "dependencies": { + "@jest/test-result": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", + "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", + "dev": true, + "requires": { + "@jest/console": "^26.3.0", + "@jest/types": "^26.3.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + } } }, "jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", + "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -12125,9 +11674,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -12163,9 +11712,9 @@ "dev": true }, "jsdom": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", - "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", "dev": true, "requires": { "abab": "^2.0.3", @@ -12188,7 +11737,7 @@ "tough-cookie": "^3.0.1", "w3c-hr-time": "^1.0.2", "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.0.0", + "webidl-conversions": "^6.1.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.0.0", @@ -12207,9 +11756,9 @@ } }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "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 }, "data-urls": { @@ -12248,12 +11797,6 @@ "requires": { "whatwg-encoding": "^1.0.5" } - }, - "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true } } }, @@ -12273,6 +11816,11 @@ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, + "json-parse-even-better-errors": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz", + "integrity": "sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q==" + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -12359,7 +11907,8 @@ "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==" + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true }, "levenary": { "version": "1.1.1", @@ -12439,6 +11988,12 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true } } }, @@ -12448,20 +12003,20 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, "lint-staged": { - "version": "10.2.11", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.11.tgz", - "integrity": "sha512-LRRrSogzbixYaZItE2APaS4l2eJMjjf5MbclRZpLJtcQJShcvUzKXsNeZgsLIZ0H0+fg2tL4B59fU9wHIHtFIA==", + "version": "10.2.13", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.2.13.tgz", + "integrity": "sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA==", "dev": true, "requires": { - "chalk": "^4.0.0", - "cli-truncate": "2.1.0", - "commander": "^5.1.0", - "cosmiconfig": "^6.0.0", + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.0.0", + "cosmiconfig": "^7.0.0", "debug": "^4.1.1", "dedent": "^0.7.0", - "enquirer": "^2.3.5", - "execa": "^4.0.1", - "listr2": "^2.1.0", + "enquirer": "^2.3.6", + "execa": "^4.0.3", + "listr2": "^2.6.0", "log-symbols": "^4.0.0", "micromatch": "^4.0.2", "normalize-path": "^3.0.0", @@ -12470,6 +12025,12 @@ "stringify-object": "^3.3.0" }, "dependencies": { + "commander": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz", + "integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -12482,9 +12043,9 @@ } }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -12870,18 +12431,18 @@ } }, "listr2": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.1.8.tgz", - "integrity": "sha512-Op+hheiChfAphkJ5qUxZtHgyjlX9iNnAeFS/S134xw7mVSg0YVrQo1IY4/K+ElY6XgOPg2Ij4z07urUXR+YEew==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-2.6.2.tgz", + "integrity": "sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA==", "dev": true, "requires": { - "chalk": "^4.0.0", + "chalk": "^4.1.0", "cli-truncate": "^2.1.0", "figures": "^3.2.0", "indent-string": "^4.0.0", "log-update": "^4.0.0", "p-map": "^4.0.0", - "rxjs": "^6.5.5", + "rxjs": "^6.6.2", "through": "^2.3.8" }, "dependencies": { @@ -12900,6 +12461,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -12907,87 +12469,63 @@ "strip-bom": "^3.0.0" }, "dependencies": { - "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==", - "requires": { - "path-key": "^3.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "pify": { + "json-buffer": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, - "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==", + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "requires": { - "shebang-regex": "^3.0.0" + "json-buffer": "3.0.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==" + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "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, "requires": { - "isexe": "^2.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "lowercase-keys": "^1.0.0" } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, @@ -13001,10 +12539,18 @@ "resolve-from": "^5.0.0" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.clone": { "version": "4.5.0", @@ -13054,85 +12600,6 @@ "cli-cursor": "^3.1.0", "slice-ansi": "^4.0.0", "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "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 - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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, - "requires": { - "color-name": "~1.1.4" - } - }, - "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 - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "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, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - } - } - } } }, "longest-streak": { @@ -13166,18 +12633,18 @@ } }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" } }, "make-dir": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", - "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "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, "requires": { "semver": "^6.0.0" @@ -13314,17 +12781,15 @@ "dev": true }, "meow": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", "requires": { "@types/minimist": "^1.2.0", - "arrify": "^2.0.1", - "camelcase": "^6.0.0", "camelcase-keys": "^6.2.2", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", + "minimist-options": "4.1.0", "normalize-package-data": "^2.5.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", @@ -13333,11 +12798,6 @@ "yargs-parser": "^18.1.3" }, "dependencies": { - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==" - }, "type-fest": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", @@ -13350,13 +12810,6 @@ "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } } } } @@ -13368,9 +12821,9 @@ "dev": true }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { "version": "4.0.2", @@ -13405,19 +12858,21 @@ "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", - "dev": true - }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + } } }, "mimic-fn": { @@ -13426,10 +12881,16 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + }, "min-indent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", - "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, "minimalistic-assert": { "version": "1.0.1", @@ -13585,9 +13046,9 @@ "dev": true }, "node-gyp-build": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.2.tgz", - "integrity": "sha512-Lqh7mrByWCM8Cf9UPqpeoVBBo5Ugx+RKu885GAzmLBVYjeywScxHXPGLa4JfYNZmcNGwzR0Glu5/9GaQZMFqyA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "dev": true }, "node-int64": { @@ -13603,20 +13064,30 @@ "dev": true }, "node-notifier": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.0.tgz", - "integrity": "sha512-y8ThJESxsHcak81PGpzWwQKxzk+5YtP3IxR8AYdpXQ1IB6FmcVzFdZXrkPin49F/DKUCfeeiziB8ptY9npzGuA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", "dev": true, "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^7.2.1", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "uuid": "^7.0.3", + "uuid": "^8.3.0", "which": "^2.0.2" }, "dependencies": { + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -13637,9 +13108,9 @@ } }, "node-releases": { - "version": "1.1.59", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.59.tgz", - "integrity": "sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw==" + "version": "1.1.60", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", + "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==" }, "normalize-html-whitespace": { "version": "1.0.0", @@ -13677,13 +13148,12 @@ "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, "np": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/np/-/np-6.2.4.tgz", - "integrity": "sha512-3ChpSEnrQQGSH5kU8qei/vfmQRI8mggPjDvrIvGUBkAjCO0u3b3xTuraefJADZps0dGsblzcSXc5ZrAWcQAbaQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/np/-/np-6.5.0.tgz", + "integrity": "sha512-Xm1kUUlEqOZsu0qBA3A9wB44EBDRXubrLvfdCodG1TOllW0aymVI0qeFWKGN+kH74/XjO1B5how07fm3g+c72w==", "dev": true, "requires": { "@samverschueren/stream-to-observable": "^0.3.0", @@ -13707,7 +13177,7 @@ "log-symbols": "^3.0.0", "meow": "^6.0.0", "new-github-release-url": "^1.0.0", - "npm-name": "^5.4.0", + "npm-name": "^6.0.0", "onetime": "^5.1.0", "open": "^7.0.0", "ow": "^0.15.0", @@ -13767,6 +13237,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -13800,9 +13283,9 @@ "dev": true }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -13844,12 +13327,12 @@ "dev": true }, "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz", + "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==", "dev": true, "requires": { - "lru-cache": "^5.1.1" + "lru-cache": "^6.0.0" } }, "is-stream": { @@ -13987,9 +13470,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -14023,151 +13506,87 @@ } }, "npm-name": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/npm-name/-/npm-name-5.5.0.tgz", - "integrity": "sha512-l7/uyVfEi2e3ho+ovaJZC0xlbwzXNUz3RxkxpfcnLuoGKAuYoo9YoJ/uy18PsTD8IziugGHks4t/mGmBJEZ4Qg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/npm-name/-/npm-name-6.0.1.tgz", + "integrity": "sha512-fhKRvUAxaYzMEUZim4mXWyfFbVS+M1CbrCLdAo3txWzrctxKka/h+KaBW0O9Cz5uOM00Nldn2JLWhuwnyW3SUw==", "dev": true, "requires": { - "got": "^9.6.0", + "got": "^10.6.0", "is-scoped": "^2.1.0", - "is-url-superb": "^3.0.0", + "is-url-superb": "^4.0.0", "lodash.zip": "^4.2.0", + "org-regex": "^1.0.0", + "p-map": "^3.0.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.1.0", "validate-npm-package-name": "^3.0.0" }, "dependencies": { "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", "dev": true, "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" } }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dev": true, + "requires": { + "mimic-response": "^2.0.0" + } }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", "dev": true, "requires": { - "json-buffer": "3.0.0" + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" } }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", "dev": true }, "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", "dev": true }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } } } }, @@ -14199,6 +13618,38 @@ "supports-color": "^5.3.0" } }, + "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, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -14224,6 +13675,16 @@ "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -14318,9 +13779,9 @@ } }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-is": { @@ -14341,23 +13802,36 @@ }, "object-visit": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { - "isobject": "^3.0.0" + "callsites": "^3.0.0" } }, "object.assign": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "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 + } } }, "object.getownpropertydescriptors": { @@ -14409,18 +13883,18 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "open": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/open/-/open-7.0.3.tgz", - "integrity": "sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/open/-/open-7.2.1.tgz", + "integrity": "sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==", "dev": true, "requires": { "is-docker": "^2.0.0", @@ -14448,9 +13922,9 @@ } }, "ora": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", - "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", + "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", "dev": true, "requires": { "chalk": "^3.0.0", @@ -14566,9 +14040,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -14576,6 +14050,12 @@ } } }, + "org-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/org-regex/-/org-regex-1.0.0.tgz", + "integrity": "sha512-7bqkxkEJwzJQUAlyYniqEZ3Ilzjh0yoa62c7gL6Ijxj5bEpPL+8IE1Z0PFj0ywjjXQcdrwR51g9MIcLezR0hKQ==", + "dev": true + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -14615,6 +14095,15 @@ "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", "dev": true }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -14631,18 +14120,16 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-map": { @@ -14676,8 +14163,7 @@ "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 + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "6.5.0", @@ -14722,9 +14208,9 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -14753,6 +14239,15 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -14784,23 +14279,49 @@ "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, "requires": { "json-buffer": "3.0.0" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, "mimic-response": { "version": "1.0.1", @@ -14814,11 +14335,36 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "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==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "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==" + }, + "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==" + }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, "requires": { "lowercase-keys": "^1.0.0" } @@ -14828,6 +14374,12 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true } } }, @@ -14912,20 +14464,20 @@ } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "requires": { "@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" } }, "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "dev": true }, "parseurl": { @@ -14947,10 +14499,9 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -15063,52 +14614,13 @@ "locate-path": "^5.0.0", "path-exists": "^4.0.0" } - }, - "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, - "requires": { - "p-locate": "^4.1.0" - } - }, - "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, - "requires": { - "p-try": "^2.0.0" - } - }, - "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, - "requires": { - "p-limit": "^2.2.0" - } - }, - "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 - }, - "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 } } }, "platform": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", - "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", "dev": true }, "please-upgrade-node": { @@ -15178,6 +14690,11 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15190,6 +14707,11 @@ "requires": { "has-flag": "^3.0.0" } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" } } }, @@ -15537,37 +15059,18 @@ "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", "dev": true, "requires": { - "css-selector-tokenizer": "^0.7.0", - "postcss": "^6.0.1" + "find-up": "^4.0.0" }, "dependencies": { - "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" - } - }, - "postcss": { - "version": "6.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "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, "requires": { - "chalk": "^2.4.1", - "source-map": "^0.6.1", - "supports-color": "^5.4.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } - }, - "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 } } }, @@ -15950,9 +15453,9 @@ "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz", + "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==", "dev": true }, "prettier-plugin-packagejson": { @@ -15965,27 +15468,39 @@ } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", + "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.3.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" + }, + "dependencies": { + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + } } }, "ansi-styles": { @@ -16095,7 +15610,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -16377,39 +15891,10 @@ "path-exists": "^4.0.0" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "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==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "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==" - }, - "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==" + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, @@ -16459,7 +15944,8 @@ "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true }, "regenerator-transform": { "version": "0.14.5", @@ -16501,9 +15987,9 @@ } }, "registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", "dev": true, "requires": { "rc": "^1.2.8" @@ -16542,9 +16028,9 @@ } }, "remark": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.0.tgz", - "integrity": "sha512-oX4lMIS0csgk8AEbzY0h2jdR0ngiCHOpwwpxjmRa5TqAkeknY+tkhjRJGZqnCmvyuWh55/0SW5WY3R3nn3PH9A==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.1.tgz", + "integrity": "sha512-gS7HDonkdIaHmmP/+shCPejCEEW+liMp/t/QwmF0Xt47Rpuhl32lLtDV1uKWvGoq+kxr5jSgg5oAIpGuyULjUw==", "requires": { "remark-parse": "^8.0.0", "remark-stringify": "^8.0.0", @@ -16552,9 +16038,9 @@ } }, "remark-cli": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-8.0.0.tgz", - "integrity": "sha512-5iRrk8ad+dU4espDl60H7ANhXqoaEXYsIyL8Mau0lDN6pP7QMAZsZTCX2XdoCfKfKEpiOggA7CHv43HkyVEppA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-8.0.1.tgz", + "integrity": "sha512-UaYeFI5qUAzkthUd8/MLBQD5OKM6jLN8GRvF6v+KF7xO/i1jQ+X2VqUSQAxWFYxZ8R25gM56GVjeoKOZ0EIr8A==", "dev": true, "requires": { "markdown-extensions": "^1.1.0", @@ -16573,27 +16059,27 @@ } }, "remark-lint": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.0.tgz", - "integrity": "sha512-OLrWPYy0MUcGLa/2rjuy1kQILTRRK+JiRtyUzqe4XRoHboGuvFDcy/W2e7sq5hu/0xmD+Eh7cEa1Coiqp7LeaA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.1.tgz", + "integrity": "sha512-caZXo3qhuBxzvq9JSJFVQ/ERDq/6TJVgWn0KDwKOIJCGOuLXfQhby5XttUq+Rn7kLbNMtvwfWHJlte14LpaeXQ==", "dev": true, "requires": { "remark-message-control": "^6.0.0" } }, "remark-lint-final-newline": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.4.tgz", - "integrity": "sha512-pUwqX8TVTTfqX5arMnu9Dr2ufg6wZ6Pk1VeqlnWfK92PBXLG8Zc3yrLpYXOJy1fHdWpqUECRRowG0H/OkZIEbw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.5.tgz", + "integrity": "sha512-rfLlW8+Fz2dqnaEgU4JwLA55CQF1T4mfSs/GwkkeUCGPenvEYwSkCN2KO2Gr1dy8qPoOdTFE1rSufLjmeTW5HA==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-hard-break-spaces": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.0.tgz", - "integrity": "sha512-dmB8GucOSDtEctwa+Y8JlSAWF4q8HcquvLr+OpFOSE1QCrpFoZdb2mcSY+rZuTtfeg4S60orhhzArd2aiHvUPQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.1.tgz", + "integrity": "sha512-Qfn/BMQFamHhtbfLrL8Co/dbYJFLRL4PGVXZ5wumkUO5f9FkZC2RsV+MD9lisvGTkJK0ZEJrVVeaPbUIFM0OAw==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16603,9 +16089,9 @@ } }, "remark-lint-list-item-bullet-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-2.0.0.tgz", - "integrity": "sha512-8iK+ht771UBf/Iuj4YBgdLnFFOyEgfXY62jBoywtMuiOLVWXDfPe+jUY7pCrnFjsnxXGEnMaxHJqENgrHd0J/w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-2.0.1.tgz", + "integrity": "sha512-tozDt9LChG1CvYJnBQH/oh45vNcHYBvg79ogvV0f8MtE/K0CXsM8EpfQ6pImFUdHpBV1op6aF6zPMrB0AkRhcQ==", "dev": true, "requires": { "pluralize": "^8.0.0", @@ -16616,9 +16102,9 @@ } }, "remark-lint-list-item-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.0.tgz", - "integrity": "sha512-qnKsq2UQpCC8gnI1O23dgoKsd+5RAJrAJuvHXrlkRgzsab7BOMluptxRlyLVXn0P71l4Wo/bfo84Ual7qpOyWw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.1.tgz", + "integrity": "sha512-4IKbA9GA14Q9PzKSQI6KEHU/UGO36CSQEjaDIhmb9UOhyhuzz4vWhnSIsxyI73n9nl9GGRAMNUSGzr4pQUFwTA==", "dev": true, "requires": { "pluralize": "^8.0.0", @@ -16629,9 +16115,9 @@ } }, "remark-lint-no-auto-link-without-protocol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.0.tgz", - "integrity": "sha512-pIntUa+zNiyRxIt2Wvp1soktDbVnk1SEiJXsjcLYYn9GapgXqOQG5ZfFwR6zxTkGV5mZKo9927EvHQkvIV6cLQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.1.tgz", + "integrity": "sha512-TFcXxzucsfBb/5uMqGF1rQA+WJJqm1ZlYQXyvJEXigEZ8EAxsxZGPb/gOQARHl/y0vymAuYxMTaChavPKaBqpQ==", "dev": true, "requires": { "mdast-util-to-string": "^1.0.2", @@ -16642,9 +16128,9 @@ } }, "remark-lint-no-blockquote-without-marker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-3.0.0.tgz", - "integrity": "sha512-auyAxMVDuhvGw29VilqUfUIUnBT7qmByG/kBPqV/GwM1a5rn4fIUJ7p9Je9BlWMRCBMTNQUMsm3ce0dawouVew==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-3.0.1.tgz", + "integrity": "sha512-sM953+u0zN90SGd2V5hWcFbacbpaROUslS5Q5F7/aa66/2rAwh6zVnrXc4pf7fFOpj7I9Xa8Aw+uB+3RJWwdrQ==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16655,9 +16141,9 @@ } }, "remark-lint-no-duplicate-definitions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.0.tgz", - "integrity": "sha512-Z5DkYKbmS+r4D0ZhaXgK6L72EWzhiklpXNF/TS+KCsffAFgfy5aJfSA3A8GpVNj1wYMP35STXBGBCLW5TckvGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.1.tgz", + "integrity": "sha512-XL22benJZB01m+aOse91nsu1IMFqeWJWme9QvoJuxIcBROO1BG1VoqLOkwNcawE/M/0CkvTo5rfx0eMlcnXOIw==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16668,9 +16154,9 @@ } }, "remark-lint-no-heading-content-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-2.0.0.tgz", - "integrity": "sha512-Zqg0WXG60Nan8j7HZtnBXidMxXhlhc7Q5JrB54I3n7H3vSPCyaqhZJ2/obYVLalEVGND8NOJGvfA1rtchaZyYg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-2.0.1.tgz", + "integrity": "sha512-Jp0zCykGwg13z7XU4VuoFK7DN8bVZ1u3Oqu3hqECsH6LMASb0tW4zcTIc985kcVo3OQTRyb6KLQXL2ltOvppKA==", "dev": true, "requires": { "mdast-util-heading-style": "^1.0.2", @@ -16682,9 +16168,9 @@ } }, "remark-lint-no-inline-padding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-2.0.0.tgz", - "integrity": "sha512-0YueQ3SBA8zFQYCN0/afRc6ZuSbM4Azx4sPVeVpAfMT0MrYgmi6msswyhUDXaeN2RwVO6bx/ZW6di8dVqRr7UA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-2.0.1.tgz", + "integrity": "sha512-a36UlPvRrLCgxjjG3YZA9VCDvLBcoBtGNyM04VeCPz+d9hHe+5Fs1C/jL+DRLCH7nff90jJ5C/9b8/LTwhjaWA==", "dev": true, "requires": { "mdast-util-to-string": "^1.0.2", @@ -16694,9 +16180,9 @@ } }, "remark-lint-no-literal-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.0.tgz", - "integrity": "sha512-bZAxr65ftz9joszDkSs2LBeJB2cRE8GydUtxYdA1WRHYmVW1AfM5ilcqLnWhiOmu+XMPH7J0eRvUzbtvu+xerw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.1.tgz", + "integrity": "sha512-IDdKtWOMuKVQIlb1CnsgBoyoTcXU3LppelDFAIZePbRPySVHklTtuK57kacgU5grc7gPM04bZV96eliGrRU7Iw==", "dev": true, "requires": { "mdast-util-to-string": "^1.0.2", @@ -16707,9 +16193,9 @@ } }, "remark-lint-no-shortcut-reference-image": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.0.tgz", - "integrity": "sha512-kgGCQBHibJ0IFVhWjnfjbqkKC0VeL5+cvyjjwfMJlgZrHEXNOYb2FJE2nvF/l6PSXQ17goRZpznTBfP4mQieUA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.1.tgz", + "integrity": "sha512-2jcZBdnN6ecP7u87gkOVFrvICLXIU5OsdWbo160FvS/2v3qqqwF2e/n/e7D9Jd+KTq1mR1gEVVuTqkWWuh3cig==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16718,9 +16204,9 @@ } }, "remark-lint-no-shortcut-reference-link": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.0.tgz", - "integrity": "sha512-rSdGLWpEsHa4b2doUch+B7QtUHH9XuC8Hndb4rAYf8U0d48KfGAIoiicxUho8qZJ4VA3RIaDo4kA/iQ15Al+Vg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.1.tgz", + "integrity": "sha512-pTZbslG412rrwwGQkIboA8wpBvcjmGFmvugIA+UQR+GfFysKtJ5OZMPGJ98/9CYWjw9Z5m0/EktplZ5TjFjqwA==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16729,9 +16215,9 @@ } }, "remark-lint-no-undefined-references": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-2.0.0.tgz", - "integrity": "sha512-K4k05pmlMRqEMUDYewitRUx8zM+ntJWbG61dILmL7to7uy0JoSbzuDtz1cxC+kKBKzkulPnyE3WOgRZG8RX2Jg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-2.0.1.tgz", + "integrity": "sha512-tXM2ctFnduC3QcskrIePUajcjtNtBmo2dvlj4aoQJtQy09Soav/rYngb8u/SgERc6Irdmm5s55UAwR9CcSrzVg==", "dev": true, "requires": { "collapse-white-space": "^1.0.4", @@ -16741,9 +16227,9 @@ } }, "remark-lint-no-unused-definitions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.0.tgz", - "integrity": "sha512-Y8zrulwaf7z6WR1ICfEGjW92iq2SPEN7Zhrs0nloNITHOg22tIPf28TurUz9HSQ3sEd52d9bZCfW9RkdfMq1xw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.1.tgz", + "integrity": "sha512-+BMc0BOjc364SvKYLkspmxDch8OaKPbnUGgQBvK0Bmlwy42baR4C9zhwAWBxm0SBy5Z4AyM4G4jKpLXPH40Oxg==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16752,9 +16238,9 @@ } }, "remark-lint-ordered-list-marker-style": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.0.tgz", - "integrity": "sha512-zYMZA8tQD/slJYKqsstZv0/Q34Hkdlf4DjC8SOr92PSA60R/xr7JdVd/AHHisbMsFvdnHZrxaB8oIOtbAUJCSw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.1.tgz", + "integrity": "sha512-Cnpw1Dn9CHn+wBjlyf4qhPciiJroFOEGmyfX008sQ8uGoPZsoBVIJx76usnHklojSONbpjEDcJCjnOvfAcWW1A==", "dev": true, "requires": { "unified-lint-rule": "^1.0.0", @@ -16774,9 +16260,9 @@ } }, "remark-parse": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.0.tgz", - "integrity": "sha512-Ck14G1Ns/GEPXhSw6m1Uv28kMtVk63e59NyL+QlhBBwBdIUXROM6MPfBehPhW6TW2d73batMdZsKwuxl5i3tEA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", + "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", "requires": { "ccount": "^1.0.0", "collapse-white-space": "^1.0.2", @@ -16797,9 +16283,9 @@ } }, "remark-preset-lint-recommended": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-4.0.0.tgz", - "integrity": "sha512-Nroe+4Itvk+AHxkMCMu6iRUptE/5pXWgLoEOGdVO/2JIiMk/+15HEogMZ05vMhPct9+Wp4uVt2zqfuvzNzdcww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-4.0.1.tgz", + "integrity": "sha512-zn+ImQbOVcAQVWLL0R0rFQ2Wy8JyWnuU3mJ8Zh0EVOckglcxByssvTbKqPih3Lh8ogpE38EfnC3a/vshj4Jx6A==", "dev": true, "requires": { "remark-lint": "^7.0.0", @@ -16827,9 +16313,9 @@ "dev": true }, "remark-stringify": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.0.0.tgz", - "integrity": "sha512-cABVYVloFH+2ZI5bdqzoOmemcz/ZuhQSH6W6ZNYnLojAUUn3xtX7u+6BpnYp35qHoGr2NFBsERV14t4vCIeW8w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.1.1.tgz", + "integrity": "sha512-q4EyPZT3PcA3Eq7vPpT6bIdokXzFGp9i85igjmhRyXWmPs0Y6/d2FYwUNotKAWyLch7g0ASZJn/KHHcHZQ163A==", "requires": { "ccount": "^1.0.0", "is-alphanumeric": "^1.0.0", @@ -16864,12 +16350,12 @@ }, "dependencies": { "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz", + "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==", "dev": true, "requires": { - "lru-cache": "^5.1.1" + "lru-cache": "^6.0.0" } } } @@ -16943,21 +16429,21 @@ } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" }, @@ -17104,9 +16590,9 @@ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" }, "rxjs": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", - "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -17480,19 +16966,41 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "is-fullwidth-code-point": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" } } }, @@ -18023,9 +17531,9 @@ } }, "strip-json-comments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", - "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "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 }, "style-search": { @@ -18090,9 +17598,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -18152,47 +17660,25 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.1.tgz", + "integrity": "sha512-fmr6168splcy/3XIvhSm5w6hYYOqyr3plAsd7OqoerzyoMnIpoxYuwrpdO2Cm22dh6KCnvirvigPrFZp+tdWFA==", "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^6.12.4", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "ajv": { + "version": "6.12.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", + "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", "requires": { - "ansi-regex": "^4.1.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } } } @@ -18282,12 +17768,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "tlds": { - "version": "1.207.0", - "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.207.0.tgz", - "integrity": "sha512-k7d7Q1LqjtAvhtEOs3yN14EabsNO8ZCoY6RESSJDB9lst3bTx3as/m1UuAeCKzYxiyhR1qq72ZPhpSf+qlqiwg==", - "dev": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -18335,9 +17815,9 @@ } }, "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", "dev": true }, "to-regex": { @@ -18455,16 +17935,11 @@ "prelude-ls": "~1.1.2" } }, - "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 - }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true }, "typedarray": { "version": "0.0.6", @@ -18481,9 +17956,9 @@ } }, "typescript": { - "version": "3.9.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz", - "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "dev": true }, "uncss": { @@ -18570,6 +18045,12 @@ "xml-name-validator": "^3.0.0" } }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, "saxes": { "version": "3.1.11", "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", @@ -18675,9 +18156,9 @@ "dev": true }, "unified": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.0.0.tgz", - "integrity": "sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", "requires": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -18745,9 +18226,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -18781,9 +18262,9 @@ } }, "unified-lint-rule": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.5.tgz", - "integrity": "sha512-jOPr/fx8lTzqszEfh46p99jUMqgPlIZ8rNKllEepumISvgfj9lUq1c7BSpVihr0L1df3lkjVHAThRPS7dIyjYg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.6.tgz", + "integrity": "sha512-YPK15YBFwnsVorDFG/u0cVVQN5G2a3V8zv5/N6KN3TCG+ajKtaALcy7u14DCSrJI+gZeyYquFL9cioJXOGXSvg==", "dev": true, "requires": { "wrapped": "^1.0.1" @@ -18882,9 +18363,9 @@ } }, "unist-util-visit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", - "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", @@ -18892,9 +18373,9 @@ } }, "unist-util-visit-parents": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", - "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", + "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" @@ -18953,9 +18434,9 @@ } }, "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz", + "integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -19021,9 +18502,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "requires": { "has-flag": "^4.0.0" @@ -19032,9 +18513,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -19072,24 +18553,6 @@ "prepend-http": "^2.0.0" } }, - "url-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-5.0.0.tgz", - "integrity": "sha512-O08GjTiAFNsSlrUWfqF1jH0H1W3m35ZyadHrGv5krdnmPPoxP27oDTqux/579PtaroiSGm5yma6KT1mHFH6Y/g==", - "dev": true, - "requires": { - "ip-regex": "^4.1.0", - "tlds": "^1.203.0" - }, - "dependencies": { - "ip-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", - "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==", - "dev": true - } - } - }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -19134,9 +18597,9 @@ "dev": true }, "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", "dev": true, "optional": true }, @@ -19146,9 +18609,9 @@ "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz", + "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -19200,9 +18663,9 @@ } }, "vfile": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.0.tgz", - "integrity": "sha512-BaTPalregj++64xbGK6uIlsurN3BCRNM/P2Pg8HezlGzKd1O9PrwIac6bd9Pdx2uTb0QHoioZ+rXKolbVXEgJg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.0.tgz", + "integrity": "sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw==", "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -19212,9 +18675,9 @@ } }, "vfile-location": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", - "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.1.0.tgz", + "integrity": "sha512-FCZ4AN9xMcjFIG1oGmZKo61PjwJHRVA+0/tPUP2ul4uIwjGGndIxavEMRpWn5p4xwm/ZsdXp9YNygf1ZyE4x8g==" }, "vfile-message": { "version": "2.0.4", @@ -19326,22 +18789,14 @@ "dev": true }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-ZmVCr6nfBeaMxEHALLEGy0LszYjpJqf6PVNQUQ1qd9Et+q7Jpygd4rGGDXgHjD8e99yLFseD69msHDM4YwPZ4A==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "webidl-conversions": "^6.1.0" } }, "which": { @@ -19466,9 +18921,9 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", "dev": true }, "xdg-basedir": { @@ -19501,23 +18956,24 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.3.tgz", "integrity": "sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==", + "dev": true, "requires": { "@babel/runtime": "^7.8.7" } }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -19530,7 +18986,7 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" }, "dependencies": { "find-up": { @@ -19542,45 +18998,6 @@ "locate-path": "^5.0.0", "path-exists": "^4.0.0" } - }, - "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, - "requires": { - "p-locate": "^4.1.0" - } - }, - "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, - "requires": { - "p-try": "^2.0.0" - } - }, - "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, - "requires": { - "p-limit": "^2.2.0" - } - }, - "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 - }, - "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 } } }, diff --git a/package.json b/package.json index 25ce9d021b..971f430fc5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stylelint", - "version": "13.6.1", + "version": "13.7.0", "description": "A mighty, modern CSS linter.", "keywords": [ "css-in-js", @@ -111,14 +111,16 @@ ] }, "dependencies": { - "@stylelint/postcss-css-in-js": "^0.37.1", + "@stylelint/postcss-css-in-js": "^0.37.2", "@stylelint/postcss-markdown": "^0.36.1", - "autoprefixer": "^9.8.2", + "autoprefixer": "^9.8.6", "balanced-match": "^1.0.0", "chalk": "^4.1.0", - "cosmiconfig": "^6.0.0", + "cosmiconfig": "^7.0.0", "debug": "^4.1.1", "execall": "^2.0.0", + "fast-glob": "^3.2.4", + "fastest-levenshtein": "^1.0.12", "file-entry-cache": "^5.0.1", "get-stdin": "^8.0.0", "global-modules": "^2.0.0", @@ -129,11 +131,10 @@ "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "known-css-properties": "^0.19.0", - "leven": "^3.1.0", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^7.0.1", + "meow": "^7.1.1", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", "postcss": "^7.0.32", @@ -155,7 +156,7 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^5.4.6", + "table": "^6.0.1", "v8-compile-cache": "^2.1.1", "write-file-atomic": "^3.0.3" }, @@ -169,30 +170,31 @@ "@types/global-modules": "^2.0.0", "@types/globjoin": "^0.1.0", "@types/imurmurhash": "^0.1.1", - "@types/lodash": "^4.14.157", + "@types/lodash": "^4.14.161", "@types/micromatch": "^4.0.1", "@types/postcss-safe-parser": "^4.0.0", "@types/style-search": "^0.1.1", "@types/svg-tags": "^1.0.0", + "@types/table": "^5.0.0", "@types/write-file-atomic": "^3.0.1", "benchmark": "^2.1.4", "common-tags": "^1.8.0", "del": "^5.1.0", - "eslint": "^7.2.0", + "eslint": "^7.7.0", "eslint-config-stylelint": "^12.0.0", - "got": "^11.3.0", + "got": "^11.5.2", "husky": "^4.2.5", - "jest": "^26.0.1", - "jest-circus": "^26.0.1", + "jest": "^26.4.2", + "jest-circus": "^26.4.2", "jest-preset-stylelint": "^3.0.0", "jest-watch-typeahead": "^0.6.0", - "lint-staged": "^10.2.11", - "np": "^6.2.4", + "lint-staged": "^10.2.13", + "np": "^6.5.0", "npm-run-all": "^4.1.5", "parcel": "^2.0.0-nightly.318", "postcss-import": "^12.0.1", - "prettier": "^2.0.5", - "remark-cli": "^8.0.0", + "prettier": "^2.1.1", + "remark-cli": "^8.0.1", "typescript": "^3.9.6" }, "engines": { diff --git a/system-tests/001/__snapshots__/fs.test.js.snap b/system-tests/001/__snapshots__/fs.test.js.snap index 1838ea5b96..dc44057660 100644 --- a/system-tests/001/__snapshots__/fs.test.js.snap +++ b/system-tests/001/__snapshots__/fs.test.js.snap @@ -12,6 +12,7 @@ Object { "warnings": Array [], }, ], + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/system-tests/001/__snapshots__/no-fs.test.js.snap b/system-tests/001/__snapshots__/no-fs.test.js.snap index a646cc6cbe..d9b364db78 100644 --- a/system-tests/001/__snapshots__/no-fs.test.js.snap +++ b/system-tests/001/__snapshots__/no-fs.test.js.snap @@ -12,6 +12,7 @@ Object { "warnings": Array [], }, ], + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/system-tests/002/__snapshots__/fs.test.js.snap b/system-tests/002/__snapshots__/fs.test.js.snap index a3477dd5e0..f7b6f0e9e7 100644 --- a/system-tests/002/__snapshots__/fs.test.js.snap +++ b/system-tests/002/__snapshots__/fs.test.js.snap @@ -34,6 +34,7 @@ Object { ], }, ], + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/system-tests/002/__snapshots__/no-fs.test.js.snap b/system-tests/002/__snapshots__/no-fs.test.js.snap index 506d78742a..ec12680bcf 100644 --- a/system-tests/002/__snapshots__/no-fs.test.js.snap +++ b/system-tests/002/__snapshots__/no-fs.test.js.snap @@ -34,6 +34,7 @@ Object { ], }, ], + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/system-tests/003/__snapshots__/fs.test.js.snap b/system-tests/003/__snapshots__/fs.test.js.snap index 7557ca761c..6e827c1243 100644 --- a/system-tests/003/__snapshots__/fs.test.js.snap +++ b/system-tests/003/__snapshots__/fs.test.js.snap @@ -20,6 +20,7 @@ Object { ], }, ], + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/system-tests/003/__snapshots__/no-fs.test.js.snap b/system-tests/003/__snapshots__/no-fs.test.js.snap index 56d3b040f8..db2e6e6b69 100644 --- a/system-tests/003/__snapshots__/no-fs.test.js.snap +++ b/system-tests/003/__snapshots__/no-fs.test.js.snap @@ -216,6 +216,7 @@ footer a:visited { height: 110px; } ", + "reportedDisables": Array [], "results": Array [ Object { "deprecations": Array [], diff --git a/types/global.d.ts b/types/global.d.ts index b32f120a83..57e1654f4c 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -4,6 +4,4 @@ declare module 'import-lazy'; declare module 'postcss-html'; declare module 'postcss-less'; declare module 'postcss-sass'; -declare module 'postcss-scss'; declare module 'sugarss'; -declare module 'table'; diff --git a/types/postcss-syntax/index.d.ts b/types/postcss-syntax/index.d.ts new file mode 100644 index 0000000000..75a6c32315 --- /dev/null +++ b/types/postcss-syntax/index.d.ts @@ -0,0 +1,7 @@ +declare module 'postcss-syntax' { + import { Syntax } from 'postcss'; + + function syntax(config: { [k: string]: Syntax }): Syntax; + + export = syntax; +} diff --git a/types/postcss/index.d.ts b/types/postcss/index.d.ts index 5173bd4af7..93e6a97875 100644 --- a/types/postcss/index.d.ts +++ b/types/postcss/index.d.ts @@ -1,3 +1,20 @@ +declare module 'postcss/lib/comment' { + import { Comment, NodeRaws } from 'postcss'; + + interface NodeRawsExt extends NodeRaws { + // Used by the SCSS parser to indicate `//` comments. + inline?: boolean; + } + + interface CommentExt extends Comment { + // Used by the Less parser to indicate `//` comments. + inline?: boolean; + raws: NodeRawsExt; + } + + export = CommentExt; +} + declare module 'postcss/lib/lazy-result' { import { LazyResult, @@ -27,12 +44,6 @@ declare module 'postcss/lib/lazy-result' { export = LazyResultImpl; } -declare module 'postcss-syntax' { - var result: any; // TODO TYPES - - export = result; -} - declare module 'postcss/lib/result' { import { Result } from 'postcss'; diff --git a/types/stylelint/index.d.ts b/types/stylelint/index.d.ts index f3f8aecfa0..800abaa67e 100644 --- a/types/stylelint/index.d.ts +++ b/types/stylelint/index.d.ts @@ -1,5 +1,5 @@ declare module 'stylelint' { - import { Result, ResultMessage, Syntax, WarningOptions, Warning } from 'postcss'; + import { Result, ResultMessage, Root, Syntax, WarningOptions, Warning } from 'postcss'; export type StylelintConfigExtends = string | Array; export type StylelintConfigPlugins = string | Array; @@ -36,6 +36,7 @@ declare module 'stylelint' { end?: number; strictEnd?: boolean; rules?: string[]; + description?: string; }; export type DisabledRangeObject = { @@ -53,6 +54,7 @@ declare module 'stylelint' { ignored?: boolean; ignoreDisables?: boolean; reportNeedlessDisables?: boolean; + reportDescriptionlessDisables?: boolean; stylelintError?: boolean; disableWritingFix?: boolean; config?: StylelintConfig; @@ -101,11 +103,20 @@ declare module 'stylelint' { ignorePath?: string; reportInvalidScopeDisables?: boolean; reportNeedlessDisables?: boolean; + reportDescriptionlessDisables?: boolean; syntax?: string; customSyntax?: CustomSyntax; fix?: boolean; }; + export type StylelintPluginContext = { fix?: boolean; newline?: string }; + + export type StylelintRule = ( + primaryOption: any, + secondaryOptions: object, + context: StylelintPluginContext, + ) => (root: Root, result: PostcssResult) => Promise | void; + export type GetPostcssOptions = { code?: string; codeFilename?: string; @@ -156,6 +167,7 @@ declare module 'stylelint' { ignoreDisables?: boolean; ignorePath?: string; ignorePattern?: string[]; + reportDescriptionlessDisables?: boolean; reportNeedlessDisables?: boolean; reportInvalidScopeDisables?: boolean; maxWarnings?: number; @@ -208,21 +220,22 @@ declare module 'stylelint' { _postcssResult?: PostcssResult; }; - export type UnusedRange = { - unusedRule: string; + export type DisableReportRange = { + rule: string; start: number; end?: number; + + // This is for backwards-compatibility with formatters that were written + // when this name was used instead of `rule`. It should be avoided for new + // formatters. + unusedRule: string; }; export type RangeType = DisabledRange & { used?: boolean }; export type StylelintDisableReportEntry = { source?: string; - ranges: Array<{ - unusedRule: string; - start: number; - end?: number; - }>; + ranges: Array; }; export type StylelintStandaloneReturnValue = { @@ -233,15 +246,20 @@ declare module 'stylelint' { maxWarnings: number; foundWarnings: number; }; + reportedDisables: StylelintDisableOptionsReport; + descriptionlessDisables?: StylelintDisableOptionsReport; needlessDisables?: StylelintDisableOptionsReport; invalidScopeDisables?: StylelintDisableOptionsReport; }; export type StylelintPublicAPI = { lint: Function; - rules: { [k: string]: any }; + rules: { [k: string]: StylelintRule }; formatters: { [k: string]: Formatter }; - createPlugin: Function; + createPlugin: ( + ruleName: string, + rule: StylelintRule, + ) => { ruleName: string; rule: StylelintRule }; createLinter: Function; utils: { report: Function;