diff --git a/CHANGELOG.md b/CHANGELOG.md index 6494cb85b8..f31248903d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project are documented in this file. - 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: `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)). ## 13.6.1 diff --git a/lib/formatters/__tests__/verboseFormatter.test.js b/lib/formatters/__tests__/verboseFormatter.test.js index af58772952..6a98b8c4b8 100644 --- a/lib/formatters/__tests__/verboseFormatter.test.js +++ b/lib/formatters/__tests__/verboseFormatter.test.js @@ -4,7 +4,7 @@ const prepareFormatterOutput = require('./prepareFormatterOutput'); const stripIndent = require('common-tags').stripIndent; const verboseFormatter = require('../verboseFormatter'); -describe('stringFormatter', () => { +describe('verboseFormatter', () => { it('outputs no warnings', () => { const results = [ { diff --git a/lib/formatters/stringFormatter.js b/lib/formatters/stringFormatter.js index 7047f2b595..5896827be8 100644 --- a/lib/formatters/stringFormatter.js +++ b/lib/formatters/stringFormatter.js @@ -6,7 +6,6 @@ const path = require('path'); const stringWidth = require('string-width'); const symbols = require('log-symbols'); const table = require('table'); -const utils = require('postcss-reporter/lib/util'); const MARGIN_WIDTHS = 9; @@ -134,14 +133,14 @@ function formatter(messages, source) { } const cleanedMessages = orderedMessages.map((message) => { - const location = utils.getLocation(message); + const { line, column } = message; const severity = /** @type {keyof import('log-symbols')} */ (message.severity); /** * @type {[string, string, string, string, string]} */ const row = [ - location.line ? location.line.toString() : '', - location.column ? location.column.toString() : '', + line ? line.toString() : '', + column ? column.toString() : '', symbols[severity] ? chalk[/** @type {'blue' | 'red' | 'yellow'} */ (levelColors[severity])](symbols[severity]) : severity, diff --git a/lib/reference/keywordSets.js b/lib/reference/keywordSets.js index 0fdf90ffc2..52f4a718d5 100644 --- a/lib/reference/keywordSets.js +++ b/lib/reference/keywordSets.js @@ -208,9 +208,7 @@ keywordSets.pseudoElements = uniteSets( ); keywordSets.aNPlusBNotationPseudoClasses = new Set([ - 'nth-child', 'nth-column', - 'nth-last-child', 'nth-last-column', 'nth-last-of-type', 'nth-of-type', @@ -220,6 +218,10 @@ keywordSets.linguisticPseudoClasses = new Set(['dir', 'lang']); keywordSets.atRulePagePseudoClasses = new Set(['first', 'right', 'left', 'blank']); +keywordSets.logicalCombinationsPseudoClasses = new Set(['has', 'is', 'matches', 'not', 'where']); + +keywordSets.aNPlusBOfSNotationPseudoClasses = new Set(['nth-child', 'nth-last-child']); + keywordSets.otherPseudoClasses = new Set([ 'active', 'any-link', @@ -241,19 +243,15 @@ keywordSets.otherPseudoClasses = new Set([ 'focus-visible', 'fullscreen', 'future', - 'has', 'host', 'host-context', 'hover', 'indeterminate', 'in-range', 'invalid', - 'is', 'last-child', 'last-of-type', 'link', - 'matches', - 'not', 'only-child', 'only-of-type', 'optional', @@ -302,6 +300,8 @@ keywordSets.webkitProprietaryPseudoClasses = new Set([ keywordSets.pseudoClasses = uniteSets( keywordSets.aNPlusBNotationPseudoClasses, keywordSets.linguisticPseudoClasses, + keywordSets.logicalCombinationsPseudoClasses, + keywordSets.aNPlusBOfSNotationPseudoClasses, keywordSets.otherPseudoClasses, ); diff --git a/lib/rules/function-calc-no-unspaced-operator/index.js b/lib/rules/function-calc-no-unspaced-operator/index.js index 27a4368ffd..abcc9e8f70 100644 --- a/lib/rules/function-calc-no-unspaced-operator/index.js +++ b/lib/rules/function-calc-no-unspaced-operator/index.js @@ -36,7 +36,13 @@ function rule(actual) { return; } - const parensMatch = balancedMatch('(', ')', valueParser.stringify(node)); + const nodeText = valueParser.stringify(node); + const parensMatch = balancedMatch('(', ')', nodeText); + + if (!parensMatch) { + throw new Error(`No parens match: "${nodeText}"`); + } + const rawExpression = parensMatch.body; const expressionIndex = decl.source.start.column + diff --git a/lib/rules/selector-max-attribute/index.js b/lib/rules/selector-max-attribute/index.js index c344139628..f0a4f9c3c6 100644 --- a/lib/rules/selector-max-attribute/index.js +++ b/lib/rules/selector-max-attribute/index.js @@ -3,7 +3,7 @@ 'use strict'; const _ = require('lodash'); -const isLogicalCombination = require('../../utils/isLogicalCombination'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const optionsMatches = require('../../utils/optionsMatches'); const parseSelector = require('../../utils/parseSelector'); @@ -49,8 +49,8 @@ function rule(max, options) { function checkSelector(selectorNode, ruleNode) { const count = selectorNode.reduce((total, childNode) => { - // Only traverse inside actual selectors and logical combinations - if (childNode.type === 'selector' || isLogicalCombination(childNode)) { + // Only traverse inside actual selectors and context functional pseudo-classes + if (childNode.type === 'selector' || isContextFunctionalPseudoClass(childNode)) { checkSelector(childNode, ruleNode); } diff --git a/lib/rules/selector-max-class/index.js b/lib/rules/selector-max-class/index.js index b48a9a5b8a..8e08e1a4ed 100644 --- a/lib/rules/selector-max-class/index.js +++ b/lib/rules/selector-max-class/index.js @@ -2,7 +2,7 @@ 'use strict'; -const isLogicalCombination = require('../../utils/isLogicalCombination'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const parseSelector = require('../../utils/parseSelector'); const report = require('../../utils/report'); @@ -34,8 +34,8 @@ function rule(max) { function checkSelector(selectorNode, ruleNode) { const count = selectorNode.reduce((total, childNode) => { - // Only traverse inside actual selectors and logical combinations - if (childNode.type === 'selector' || isLogicalCombination(childNode)) { + // Only traverse inside actual selectors and context functional pseudo-classes + if (childNode.type === 'selector' || isContextFunctionalPseudoClass(childNode)) { checkSelector(childNode, ruleNode); } diff --git a/lib/rules/selector-max-compound-selectors/index.js b/lib/rules/selector-max-compound-selectors/index.js index febfddf17a..92ed6145ec 100644 --- a/lib/rules/selector-max-compound-selectors/index.js +++ b/lib/rules/selector-max-compound-selectors/index.js @@ -2,7 +2,7 @@ 'use strict'; -const isLogicalCombination = require('../../utils/isLogicalCombination'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const parseSelector = require('../../utils/parseSelector'); const report = require('../../utils/report'); @@ -39,8 +39,8 @@ function rule(max) { let compoundCount = 1; selectorNode.each((childNode) => { - // Only traverse inside actual selectors and logical combinations - if (childNode.type === 'selector' || isLogicalCombination(childNode)) { + // Only traverse inside actual selectors and context functional pseudo-classes + if (childNode.type === 'selector' || isContextFunctionalPseudoClass(childNode)) { checkSelector(childNode, rule); } diff --git a/lib/rules/selector-max-id/index.js b/lib/rules/selector-max-id/index.js index bf608bb3dc..91555fe03d 100644 --- a/lib/rules/selector-max-id/index.js +++ b/lib/rules/selector-max-id/index.js @@ -3,7 +3,7 @@ 'use strict'; const _ = require('lodash'); -const isLogicalCombination = require('../../utils/isLogicalCombination'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const optionsMatches = require('../../utils/optionsMatches'); const parseSelector = require('../../utils/parseSelector'); @@ -47,10 +47,10 @@ function rule(max, options) { function checkSelector(selectorNode, ruleNode) { const count = selectorNode.reduce((total, childNode) => { - // Only traverse inside actual selectors and logical combinations that are not part of ignored functional pseudo-classes + // Only traverse inside actual selectors and context functional pseudo-classes that are not part of ignored functional pseudo-classes if ( childNode.type === 'selector' || - (isLogicalCombination(childNode) && + (isContextFunctionalPseudoClass(childNode) && !isIgnoredContextFunctionalPseudoClass(childNode, options)) ) { checkSelector(childNode, ruleNode); diff --git a/lib/rules/selector-max-pseudo-class/index.js b/lib/rules/selector-max-pseudo-class/index.js index 0d73785815..fc8d581a98 100644 --- a/lib/rules/selector-max-pseudo-class/index.js +++ b/lib/rules/selector-max-pseudo-class/index.js @@ -2,7 +2,7 @@ 'use strict'; -const isLogicalCombination = require('../../utils/isLogicalCombination'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const keywordSets = require('../../reference/keywordSets'); const parseSelector = require('../../utils/parseSelector'); @@ -35,8 +35,8 @@ function rule(max) { function checkSelector(selectorNode, ruleNode) { const count = selectorNode.reduce((total, childNode) => { - // Only traverse inside actual selectors and logical combinations - if (childNode.type === 'selector' || isLogicalCombination(childNode)) { + // Only traverse inside actual selectors and context functional pseudo-classes + if (childNode.type === 'selector' || isContextFunctionalPseudoClass(childNode)) { checkSelector(childNode, ruleNode); } diff --git a/lib/rules/selector-max-type/index.js b/lib/rules/selector-max-type/index.js index 05bc10ab5a..0b4502c660 100644 --- a/lib/rules/selector-max-type/index.js +++ b/lib/rules/selector-max-type/index.js @@ -3,11 +3,12 @@ 'use strict'; const _ = require('lodash'); +const isContextFunctionalPseudoClass = require('../../utils/isContextFunctionalPseudoClass'); const isKeyframeSelector = require('../../utils/isKeyframeSelector'); -const isLogicalCombination = require('../../utils/isLogicalCombination'); const isOnlyWhitespace = require('../../utils/isOnlyWhitespace'); const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector'); +const isStandardSyntaxTypeSelector = require('../../utils/isStandardSyntaxTypeSelector'); const optionsMatches = require('../../utils/optionsMatches'); const parseSelector = require('../../utils/parseSelector'); const report = require('../../utils/report'); @@ -56,8 +57,8 @@ function rule(max, options) { function checkSelector(selectorNode, ruleNode) { const count = selectorNode.reduce((total, childNode) => { - // Only traverse inside actual selectors and logical combinations - if (childNode.type === 'selector' || isLogicalCombination(childNode)) { + // Only traverse inside actual selectors and context functional pseudo-classes + if (childNode.type === 'selector' || isContextFunctionalPseudoClass(childNode)) { checkSelector(childNode, ruleNode); } @@ -81,6 +82,10 @@ function rule(max, options) { return total; } + if (childNode.type === 'tag' && !isStandardSyntaxTypeSelector(childNode)) { + return total; + } + return total + (childNode.type === 'tag'); }, 0); diff --git a/lib/utils/FileCache.js b/lib/utils/FileCache.js index d16060bb90..0474a6ce81 100644 --- a/lib/utils/FileCache.js +++ b/lib/utils/FileCache.js @@ -8,6 +8,8 @@ const path = require('path'); const DEFAULT_CACHE_LOCATION = './.stylelintcache'; const DEFAULT_HASH = ''; +/** @typedef {import('file-entry-cache').FileDescriptor["meta"] & { hashOfConfig?: string }} CacheMetadata */ + /** * @param {string} [cacheLocation] * @param {string} [hashOfConfig] @@ -30,6 +32,7 @@ class FileCache { // Get file descriptor compares current metadata against cached // one and stores the result to "changed" prop.w const descriptor = this._fileCache.getFileDescriptor(absoluteFilepath); + /** @type {CacheMetadata} */ const meta = descriptor.meta || {}; const changed = descriptor.changed || meta.hashOfConfig !== this._hashOfConfig; diff --git a/lib/utils/__tests__/isContextFunctionalPseudoClass.test.js b/lib/utils/__tests__/isContextFunctionalPseudoClass.test.js new file mode 100644 index 0000000000..f3f506128b --- /dev/null +++ b/lib/utils/__tests__/isContextFunctionalPseudoClass.test.js @@ -0,0 +1,48 @@ +'use strict'; + +const isContextFunctionalPseudoClass = require('../isContextFunctionalPseudoClass'); +const parseSelector = require('postcss-selector-parser'); +const postcss = require('postcss'); + +function selector(css, cb) { + postcss.parse(css).walkRules((rule) => { + parseSelector((selectorAST) => { + selectorAST.walkPseudos(cb); + }).processSync(rule.selector); + }); +} + +describe('isContextFunctionalPseudoClass', () => { + it('handles non-context-functional pseudo-classes, like hover', () => { + selector('a:hover {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(false); + }); + }); + + it('handles logical combinations, ', () => { + selector('a:has(.foo) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + selector('a:is(.foo) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + selector('a:matches(.foo) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + selector('a:not(.foo) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + selector('a:where(.foo) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + }); + + it('handles tree structural/NPlusBOfSNotationPseudoClasses classes', () => { + selector('a:nth-child(n+7) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + selector('a:nth-last-child(n+7) {}', (selector) => { + expect(isContextFunctionalPseudoClass(selector)).toBe(true); + }); + }); +}); diff --git a/lib/utils/__tests__/isLogicalCombination.test.js b/lib/utils/__tests__/isLogicalCombination.test.js deleted file mode 100644 index 33e64ef749..0000000000 --- a/lib/utils/__tests__/isLogicalCombination.test.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const isLogicalCombination = require('../isLogicalCombination'); -const parseSelector = require('postcss-selector-parser'); -const postcss = require('postcss'); - -function selector(css, cb) { - postcss.parse(css).walkRules((rule) => { - parseSelector((selectorAST) => { - selectorAST.walkPseudos(cb); - }).processSync(rule.selector); - }); -} - -describe('isLogicalCombination', () => { - it('hover pseudo class is NOT logical combination', () => { - selector('a:hover {}', (selector) => { - expect(isLogicalCombination(selector)).toBe(false); - }); - }); - - it('not pseudo class is logical combination', () => { - selector('a:not(.foo) {}', (selector) => { - expect(isLogicalCombination(selector)).toBe(true); - }); - }); - - it('has pseudo class is logical combination', () => { - selector('a:has(.foo) {}', (selector) => { - expect(isLogicalCombination(selector)).toBe(true); - }); - }); - - it('matches pseudo class is logical combination', () => { - selector('a:matches(.foo) {}', (selector) => { - expect(isLogicalCombination(selector)).toBe(true); - }); - }); -}); diff --git a/lib/utils/blurFunctionArguments.js b/lib/utils/blurFunctionArguments.js index f4d9f72497..0f64378e0b 100644 --- a/lib/utils/blurFunctionArguments.js +++ b/lib/utils/blurFunctionArguments.js @@ -33,8 +33,13 @@ module.exports = function (source, functionName, blurChar = '`') { while (lowerCaseSource.includes(nameWithParen, searchStartIndex)) { const openingParenIndex = lowerCaseSource.indexOf(nameWithParen, searchStartIndex) + functionNameLength; - const closingParenIndex = - balancedMatch('(', ')', lowerCaseSource.slice(openingParenIndex)).end + openingParenIndex; + const parensMatch = balancedMatch('(', ')', lowerCaseSource.slice(openingParenIndex)); + + if (!parensMatch) { + throw new Error(`No parens match: "${source}"`); + } + + const closingParenIndex = parensMatch.end + openingParenIndex; const argumentsLength = closingParenIndex - openingParenIndex - 1; result = diff --git a/lib/utils/functionArgumentsSearch.js b/lib/utils/functionArgumentsSearch.js index 88088b126f..fac9aa647a 100644 --- a/lib/utils/functionArgumentsSearch.js +++ b/lib/utils/functionArgumentsSearch.js @@ -31,6 +31,10 @@ module.exports = function (source, functionName, callback) { const parensMatch = balancedMatch('(', ')', source.substr(match.startIndex)); + if (!parensMatch) { + throw new Error(`No parens match: "${source}"`); + } + callback(parensMatch.body, match.endIndex + 1); }, ); diff --git a/lib/utils/isContextFunctionalPseudoClass.js b/lib/utils/isContextFunctionalPseudoClass.js new file mode 100644 index 0000000000..4fcca055bb --- /dev/null +++ b/lib/utils/isContextFunctionalPseudoClass.js @@ -0,0 +1,23 @@ +'use strict'; + +const keywordSets = require('../reference/keywordSets'); + +/** + * Check whether a node is a context-functional pseudo-class (i.e. either a logical combination + * or a 'aNPlusBOfSNotationPseudoClasses' / tree-structural pseudo-class) + * + * @param {import('postcss-selector-parser').Pseudo} node postcss-selector-parser node (of type pseudo) + * @return {boolean} If `true`, the node is a context-functional pseudo-class + */ +module.exports = function isContextFunctionalPseudoClass(node) { + if (node.type === 'pseudo') { + const normalisedParentName = node.value.toLowerCase().replace(/:+/, ''); + + return ( + keywordSets.logicalCombinationsPseudoClasses.has(normalisedParentName) || + keywordSets.aNPlusBOfSNotationPseudoClasses.has(normalisedParentName) + ); + } + + return false; +}; diff --git a/lib/utils/isLogicalCombination.js b/lib/utils/isLogicalCombination.js deleted file mode 100644 index cd92885eec..0000000000 --- a/lib/utils/isLogicalCombination.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -/** - * Check whether a node is logical combination (`:not`, `:has`, `:matches`) - * - * @param {import('postcss-selector-parser').Pseudo} node postcss-selector-parser node (of type pseudo) - * @return {boolean} If `true`, the combination is logical - */ -module.exports = function isLogicalCombination(node) { - if (node.type === 'pseudo') { - switch (node.value) { - case ':not': - case ':has': - case ':matches': - return true; - default: - return false; - } - } - - return false; -}; diff --git a/lib/utils/isStandardSyntaxTypeSelector.js b/lib/utils/isStandardSyntaxTypeSelector.js index 1275676272..3bf35e4bf5 100644 --- a/lib/utils/isStandardSyntaxTypeSelector.js +++ b/lib/utils/isStandardSyntaxTypeSelector.js @@ -27,6 +27,7 @@ module.exports = function (node) { if ( parentType === 'pseudo' && (keywordSets.aNPlusBNotationPseudoClasses.has(normalisedParentName) || + keywordSets.aNPlusBOfSNotationPseudoClasses.has(normalisedParentName) || keywordSets.linguisticPseudoClasses.has(normalisedParentName) || keywordSets.shadowTreePseudoElements.has(normalisedParentName)) ) { diff --git a/lib/writeOutputFile.js b/lib/writeOutputFile.js index 3ab4a4342e..a495f45a1e 100644 --- a/lib/writeOutputFile.js +++ b/lib/writeOutputFile.js @@ -7,7 +7,7 @@ const writeFileAtomic = require('write-file-atomic'); /** * @param {string} content * @param {string} filePath - * @returns {Promise} + * @returns {Promise} */ module.exports = (content, filePath) => writeFileAtomic(path.normalize(filePath), stripAnsi(content)); diff --git a/package-lock.json b/package-lock.json index 16cc1a7d37..5a4a2b3961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1365,12 +1365,20 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "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.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-object-rest-spread": { @@ -1484,13 +1492,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.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } } @@ -5542,6 +5550,12 @@ "@babel/types": "^7.3.0" } }, + "@types/balanced-match": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/balanced-match/-/balanced-match-1.0.1.tgz", + "integrity": "sha512-flYjxKu45rRRd//gE2Y3zfVb1rCa4aNHW8fZ68c4Yt++iCBjij7YmraB9DGjsue1RC5pj4+yU50sI5cADCKZRA==", + "dev": true + }, "@types/braces": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.0.tgz", @@ -5583,6 +5597,15 @@ "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", + "integrity": "sha512-WeUjhy7AbHrD8GlhFSMDXlJkZ0aKrwdDg4cEsFDaFeSphMvsCU3eM9LH6pfCRAz1ZPa64WOYLN0Bv8gNBKRB6A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -5621,6 +5644,12 @@ "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", "dev": true }, + "@types/imurmurhash": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@types/imurmurhash/-/imurmurhash-0.1.1.tgz", + "integrity": "sha512-ThbETc7uxx6rIpNP0fE3bqrSSIeBWPrFY4TzY4WFsvdQYWinub+PLZV/9nT3zicRJJPWbmHqJIsHZHeh5Ad+Ug==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", @@ -5662,9 +5691,9 @@ } }, "@types/lodash": { - "version": "4.14.155", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.155.tgz", - "integrity": "sha512-vEcX7S7aPhsBCivxMwAANQburHBtfN9RdyXFk84IJmu2Z4Hkg1tOFgaslRiEqqvoLtbCBi6ika1EMspE+NZ9Lg==", + "version": "4.14.158", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.158.tgz", + "integrity": "sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w==", "dev": true }, "@types/micromatch": { @@ -5703,6 +5732,15 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "@types/postcss-safe-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/postcss-safe-parser/-/postcss-safe-parser-4.0.0.tgz", + "integrity": "sha512-ugodq0ycpehQTRKoVybk7dmaoLDwK5M7nzTdCqlKErfEWIrp0R0UHRL4YEwS/4FIP1lM0rJ68ZCRAQpRc13vWA==", + "dev": true, + "requires": { + "postcss": "^7.0.30" + } + }, "@types/prettier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.0.tgz", @@ -5730,11 +5768,32 @@ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, + "@types/style-search": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@types/style-search/-/style-search-0.1.1.tgz", + "integrity": "sha512-pJOod5SN0d6rTl9d9YMqiFqLY1tMlqaQtpB/2E/SceXCf+Lwn0VVkthe7Ts4Ln3m0USPoY1lqXoyF5c7N2redg==", + "dev": true + }, + "@types/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-PlLI3u2hocS4nbzd9WUzQn/EyFl+NifbssU9QV40XzWOpwf5R7cDod2dmTUKYN7awE9jMrhy9FCO904ZYwaBDw==", + "dev": true + }, "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" }, + "@types/write-file-atomic": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-3.0.1.tgz", + "integrity": "sha512-o5Pl/qux8JEuFpof5fUg/Fl6R3N26ExJlsmWpB67ayrEJDMIxWdM9NDJacisXeNB7YW+vij8onctH8Pr1Zhi5g==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "15.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", @@ -9119,6 +9178,18 @@ "dev": true, "requires": { "locate-path": "^3.0.0" + }, + "dependencies": { + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + } } }, "find-versions": { @@ -9402,8 +9473,7 @@ "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 + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "growly": { "version": "1.3.0", @@ -12830,7 +12900,6 @@ "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", @@ -12855,7 +12924,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -12869,8 +12937,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "semver": { "version": "7.3.2", @@ -12893,8 +12960,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "supports-color": { "version": "7.1.0", @@ -12935,20 +13001,10 @@ "resolve-from": "^5.0.0" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.clone": { "version": "4.5.0", @@ -13000,22 +13056,22 @@ "wrap-ansi": "^6.2.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" - } - }, "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", @@ -13031,6 +13087,29 @@ "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", @@ -13040,6 +13119,18 @@ "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" + } + } } } } @@ -15740,37 +15831,6 @@ } } }, - "postcss-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", - "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", - "requires": { - "chalk": "^2.4.1", - "lodash": "^4.17.11", - "log-symbols": "^2.2.0", - "postcss": "^7.0.7" - }, - "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==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "requires": { - "chalk": "^2.0.1" - } - } - } - }, "postcss-resolve-nested-selector": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", diff --git a/package.json b/package.json index 2fb065b7d5..25ce9d021b 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "imurmurhash": "^0.1.4", "known-css-properties": "^0.19.0", "leven": "^3.1.0", - "lodash": "^4.17.15", + "lodash": "^4.17.19", "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", "meow": "^7.0.1", @@ -140,7 +140,6 @@ "postcss-html": "^0.36.0", "postcss-less": "^3.1.4", "postcss-media-query-parser": "^0.2.3", - "postcss-reporter": "^6.0.1", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^4.0.2", "postcss-sass": "^0.4.4", @@ -163,12 +162,19 @@ "devDependencies": { "@stylelint/prettier-config": "^2.0.0", "@stylelint/remark-preset": "^1.0.0", + "@types/balanced-match": "^1.0.1", "@types/browserslist": "^4.8.0", "@types/debug": "^4.1.5", + "@types/file-entry-cache": "^5.0.1", "@types/global-modules": "^2.0.0", "@types/globjoin": "^0.1.0", - "@types/lodash": "^4.14.155", + "@types/imurmurhash": "^0.1.1", + "@types/lodash": "^4.14.157", "@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/write-file-atomic": "^3.0.1", "benchmark": "^2.1.4", "common-tags": "^1.8.0", "del": "^5.1.0", diff --git a/types/balanced-match/index.d.ts b/types/balanced-match/index.d.ts deleted file mode 100644 index daf5e78b31..0000000000 --- a/types/balanced-match/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'balanced-match' { - var def: any; // TODO TYPES - - export = def; -} diff --git a/types/file-entry-cache/index.d.ts b/types/file-entry-cache/index.d.ts deleted file mode 100644 index 99d37a6b15..0000000000 --- a/types/file-entry-cache/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'file-entry-cache' { - type CacheEntry = any; // TODO TYPES - - export function create(file: string): CacheEntry; -} diff --git a/types/imurmurhash/index.d.ts b/types/imurmurhash/index.d.ts deleted file mode 100644 index 3277fc8589..0000000000 --- a/types/imurmurhash/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'imurmurhash' { - var result: any; // TODO TYPES - - export = result; -} diff --git a/types/postcss/extensions.d.ts b/types/postcss/extensions.d.ts deleted file mode 100644 index 3e612db517..0000000000 --- a/types/postcss/extensions.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as postcss from 'postcss'; -declare module 'postcss' { - interface NodeSource { - lang?: string; - } - - interface Input { - css?: string; - } -} diff --git a/types/postcss/index.d.ts b/types/postcss/index.d.ts index a8084ba565..5173bd4af7 100644 --- a/types/postcss/index.d.ts +++ b/types/postcss/index.d.ts @@ -33,10 +33,6 @@ declare module 'postcss-syntax' { export = result; } -declare module 'postcss-reporter/lib/util' { - export function getLocation(message: Object): { line: number; column: number; file?: string }; -} - declare module 'postcss/lib/result' { import { Result } from 'postcss'; diff --git a/types/style-search/index.d.ts b/types/style-search/index.d.ts deleted file mode 100644 index 77ba994646..0000000000 --- a/types/style-search/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -declare function searchFn( - param: { - source: string; - target: string | string[]; - once?: boolean; - comments?: 'skip' | 'check' | 'only'; - strings?: 'skip' | 'check' | 'only'; - functionNames?: 'skip' | 'check' | 'only'; - functionArguments?: 'skip' | 'check' | 'only'; - parentheticals?: 'skip' | 'check' | 'only'; - }, - callback: (param: { startIndex: number; endIndex: number }) => void, -): void; - -declare module 'style-search' { - export = searchFn; -} diff --git a/types/svg-tags/index.d.ts b/types/svg-tags/index.d.ts deleted file mode 100644 index 165bca0cef..0000000000 --- a/types/svg-tags/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module 'svg-tags' { - var def: any; // TODO TYPES - // Export is string[] - - export = def; -} diff --git a/types/svg-tags/postcss-safe-parser.ts b/types/svg-tags/postcss-safe-parser.ts deleted file mode 100644 index 0037a904e1..0000000000 --- a/types/svg-tags/postcss-safe-parser.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'postcss-safe-parser'; diff --git a/types/write-file-atomic/index.d.ts b/types/write-file-atomic/index.d.ts deleted file mode 100644 index 90c55572c5..0000000000 --- a/types/write-file-atomic/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -declare namespace writeFile { - interface Options { - chown?: { - uid: number; - gid: number; - }; - encoding?: string; - fsync?: boolean; - mode?: number; - } -} - -declare function writeFileAsync( - filename: string, - data: string | Buffer, - options?: writeFile.Options, -): Promise; - -declare module 'write-file-atomic' { - export = writeFileAsync; -}