stylelint
Advanced tools
Comparing version 15.3.0 to 15.4.0
@@ -47,2 +47,3 @@ 'use strict'; | ||
* @property {boolean} quiet | ||
* @property {boolean} quietDeprecationWarnings | ||
* @property {string} [version] | ||
@@ -74,2 +75,3 @@ * @property {boolean} [allowEmptyInput] | ||
* @property {boolean} [quiet] | ||
* @property {boolean} [quietDeprecationWarnings] | ||
* @property {any} [printConfig] | ||
@@ -106,3 +108,3 @@ * @property {boolean} [fix] | ||
--config | ||
--config, -c | ||
@@ -205,2 +207,6 @@ Path to a specific configuration file (JSON, YAML, or CommonJS), or the | ||
--quiet-deprecation-warnings | ||
Ignore deprecations warnings. | ||
--color | ||
@@ -266,2 +272,3 @@ --no-color | ||
config: { | ||
alias: 'c', | ||
type: 'string', | ||
@@ -323,2 +330,5 @@ }, | ||
}, | ||
quietDeprecationWarnings: { | ||
type: 'boolean', | ||
}, | ||
reportDescriptionlessDisables: { | ||
@@ -384,2 +394,6 @@ alias: 'rdd', | ||
if (cli.flags.quietDeprecationWarnings) { | ||
optionsBase.quietDeprecationWarnings = cli.flags.quietDeprecationWarnings; | ||
} | ||
if (cli.flags.customSyntax) { | ||
@@ -386,0 +400,0 @@ optionsBase.customSyntax = cli.flags.customSyntax; |
@@ -24,4 +24,2 @@ 'use strict'; | ||
const cwd = stylelint._options.cwd; | ||
const ignorer = getFileIgnorer(stylelint._options); | ||
const result = await getConfigForFile(stylelint, filePath, filePath); | ||
@@ -40,3 +38,4 @@ | ||
// Check filePath with .stylelintignore file | ||
const ignorer = getFileIgnorer(stylelint._options); | ||
if (filterFilePaths(ignorer, [path.relative(cwd, absoluteFilePath)]).length === 0) { | ||
@@ -43,0 +42,0 @@ return true; |
@@ -81,6 +81,2 @@ 'use strict'; | ||
if (ruleFunction.meta && ruleFunction.meta.deprecated) { | ||
warnDeprecatedRule(postcssResult, ruleName); | ||
} | ||
const ruleSettings = config.rules && config.rules[ruleName]; | ||
@@ -92,2 +88,10 @@ | ||
if ( | ||
ruleFunction.meta && | ||
ruleFunction.meta.deprecated && | ||
!stylelintOptions.quietDeprecationWarnings | ||
) { | ||
warnDeprecatedRule(postcssResult, ruleName); | ||
} | ||
const primaryOption = ruleSettings[0]; | ||
@@ -94,0 +98,0 @@ const secondaryOptions = ruleSettings[1]; |
'use strict'; | ||
const arrayEqual = require('../../utils/arrayEqual'); | ||
const { basicKeywords } = require('../../reference/keywords'); | ||
const eachDeclarationBlock = require('../../utils/eachDeclarationBlock'); | ||
@@ -24,4 +25,2 @@ const optionsMatches = require('../../utils/optionsMatches'); | ||
const IGNORED_VALUES = new Set(['inherit']); | ||
/** @typedef {import('postcss').Declaration} Declaration */ | ||
@@ -72,3 +71,4 @@ | ||
eachDecl((decl) => { | ||
if (IGNORED_VALUES.has(decl.value)) { | ||
// basic keywords are not allowed in shorthand properties | ||
if (basicKeywords.has(decl.value)) { | ||
return; | ||
@@ -75,0 +75,0 @@ } |
@@ -9,2 +9,3 @@ 'use strict'; | ||
const isStandardSyntaxUrl = require('../../utils/isStandardSyntaxUrl'); | ||
const isStandardSyntaxDeclaration = require('../../utils/isStandardSyntaxDeclaration'); | ||
const optionsMatches = require('../../utils/optionsMatches'); | ||
@@ -60,2 +61,4 @@ const report = require('../../utils/report'); | ||
function checkDeclParams(decl) { | ||
if (!isStandardSyntaxDeclaration(decl)) return; | ||
const value = getDeclarationValue(decl); | ||
@@ -62,0 +65,0 @@ const startIndex = declarationValueIndex(decl); |
@@ -244,2 +244,3 @@ 'use strict'; | ||
'no-unknown-animations': importLazy(() => require('./no-unknown-animations'))(), | ||
'no-unknown-custom-properties': importLazy(() => require('./no-unknown-custom-properties'))(), | ||
'number-leading-zero': importLazy(() => require('./number-leading-zero'))(), | ||
@@ -246,0 +247,0 @@ 'number-max-precision': importLazy(() => require('./number-max-precision'))(), |
'use strict'; | ||
const mediaParser = require('postcss-media-query-parser').default; | ||
const { | ||
MediaFeatureName, | ||
MediaFeatureRangeNameValue, | ||
isMediaFeature, | ||
isMediaFeaturePlain, | ||
isMediaFeatureRange, | ||
} = require('@csstools/media-query-list-parser'); | ||
const { TokenNode } = require('@csstools/css-parser-algorithms'); | ||
const { TokenType } = require('@csstools/css-tokenizer'); | ||
const { rangeTypeMediaFeatureNames } = require('../../reference/mediaFeatures.js'); | ||
const atRuleParamIndex = require('../../utils/atRuleParamIndex'); | ||
const isRangeContextMediaFeature = require('../../utils/isRangeContextMediaFeature'); | ||
const isStandardSyntaxMediaFeatureName = require('../../utils/isStandardSyntaxMediaFeatureName'); | ||
const parseMediaQuery = require('../../utils/parseMediaQuery'); | ||
const report = require('../../utils/report'); | ||
const ruleMessages = require('../../utils/ruleMessages'); | ||
const validateOptions = require('../../utils/validateOptions'); | ||
const { rangeTypeMediaFeatureNames } = require('../../reference/mediaFeatures'); | ||
@@ -21,6 +28,7 @@ const ruleName = 'media-feature-range-notation'; | ||
url: 'https://stylelint.io/user-guide/rules/media-feature-range-notation', | ||
fixable: true, | ||
}; | ||
/** @type {import('stylelint').Rule} */ | ||
const rule = (primary) => { | ||
const rule = (primary, _secondaryOptions, context) => { | ||
return (root, result) => { | ||
@@ -37,26 +45,91 @@ const validOptions = validateOptions(result, ruleName, { | ||
root.walkAtRules(/^media$/i, (atRule) => { | ||
mediaParser(atRule.params).walk(/^media-feature$/i, ({ parent, value }) => { | ||
if (!isStandardSyntaxMediaFeatureName(value)) return; | ||
const mediaQueryList = parseMediaQuery(atRule, result); | ||
let hasFixes = false; | ||
if (!isRangeContextMediaFeature(value) && isInBooleanContext(parent)) return; | ||
mediaQueryList.forEach((mediaQuery) => { | ||
mediaQuery.walk((entry) => { | ||
const node = entry.node; | ||
if (!isRangeContextMediaFeature(value) && !isRangeTypeMediaFeature(value)) return; | ||
// Only look at plain and range notation media features | ||
if (!isMediaFeatureRange(node) && !isMediaFeaturePlain(node)) return; | ||
if (primary === 'prefix' && isPrefixedRangeMediaFeature(value)) return; | ||
// Expected plain notation and received plain notation | ||
if (primary === 'prefix' && isMediaFeaturePlain(node)) return; | ||
if (primary === 'context' && isRangeContextMediaFeature(value)) return; | ||
// Expected range notation and received range notation | ||
if (primary === 'context' && isMediaFeatureRange(node)) return; | ||
const index = atRuleParamIndex(atRule) + parent.sourceIndex; | ||
const endIndex = index + parent.value.length; | ||
const featureName = node.getName(); | ||
const unprefixedMediaFeature = featureName.replace(/^(?:min|max)-/i, ''); | ||
report({ | ||
message: messages.expected, | ||
messageArgs: [primary], | ||
node: atRule, | ||
index, | ||
endIndex, | ||
result, | ||
ruleName, | ||
if (!rangeTypeMediaFeatureNames.has(unprefixedMediaFeature)) return; | ||
if (context.fix && primary === 'context' && isMediaFeaturePlain(node)) { | ||
const parent = entry.parent; | ||
if (!isMediaFeature(parent)) return; | ||
hasFixes = true; | ||
/** @type {import('@csstools/css-tokenizer').TokenDelim} */ | ||
const operator = /^min-/i.test(featureName) | ||
? [TokenType.Delim, '>', -1, -1, { value: '>' }] | ||
: [TokenType.Delim, '<', -1, -1, { value: '<' }]; | ||
parent.feature = new MediaFeatureRangeNameValue( | ||
new MediaFeatureName( | ||
new TokenNode([ | ||
TokenType.Ident, | ||
unprefixedMediaFeature, | ||
-1, | ||
-1, | ||
{ value: unprefixedMediaFeature }, | ||
]), | ||
node.name.before, | ||
node.name.after.length > 0 | ||
? node.name.after | ||
: [[TokenType.Whitespace, ' ', -1, -1, undefined]], | ||
), | ||
[operator, [TokenType.Delim, '=', -1, -1, { value: '=' }]], | ||
node.value, | ||
); | ||
return; | ||
} | ||
const tokens = node.tokens(); | ||
const firstToken = tokens[0]; | ||
const lastToken = tokens[tokens.length - 1]; | ||
let startIndex = 0; | ||
let endIndex = atRule.params.length; | ||
if (firstToken && lastToken) { | ||
startIndex = firstToken[2]; | ||
endIndex = lastToken[3]; | ||
} | ||
const atRuleIndex = atRuleParamIndex(atRule); | ||
report({ | ||
message: messages.expected, | ||
messageArgs: [primary], | ||
node: atRule, | ||
index: atRuleIndex + startIndex - 1, | ||
endIndex: atRuleIndex + endIndex + 1 + 1, | ||
result, | ||
ruleName, | ||
}); | ||
}); | ||
}); | ||
if (hasFixes) { | ||
const expectedMediaQueryList = mediaQueryList | ||
.map((mediaQuery) => mediaQuery.toString()) | ||
.join(','); | ||
if (expectedMediaQueryList === atRule.params) return; | ||
atRule.params = expectedMediaQueryList; | ||
} | ||
}); | ||
@@ -66,25 +139,2 @@ }; | ||
/** | ||
* @param {string} mediaFeature | ||
*/ | ||
function isPrefixedRangeMediaFeature(mediaFeature) { | ||
return mediaFeature.startsWith('min-') || mediaFeature.startsWith('max-'); | ||
} | ||
/** | ||
* @param {string} mediaFeature | ||
*/ | ||
function isRangeTypeMediaFeature(mediaFeature) { | ||
const unprefixedMediaFeature = mediaFeature.replace(/^(?:min|max)-/, ''); | ||
return rangeTypeMediaFeatureNames.has(unprefixedMediaFeature); | ||
} | ||
/** | ||
* @param {import('postcss-media-query-parser').Node} mediaFeatureExpressionNode | ||
*/ | ||
function isInBooleanContext({ nodes }) { | ||
return nodes && nodes.length === 1; | ||
} | ||
rule.ruleName = ruleName; | ||
@@ -91,0 +141,0 @@ rule.messages = messages; |
@@ -72,4 +72,2 @@ 'use strict'; | ||
rule.primaryOptionArray = true; | ||
rule.ruleName = ruleName; | ||
@@ -76,0 +74,0 @@ rule.messages = messages; |
@@ -51,3 +51,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -54,0 +54,0 @@ */ |
@@ -36,3 +36,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -39,0 +39,0 @@ */ |
@@ -37,3 +37,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -40,0 +40,0 @@ */ |
@@ -40,3 +40,3 @@ 'use strict'; | ||
* | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -43,0 +43,0 @@ */ |
@@ -49,3 +49,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -52,0 +52,0 @@ */ |
@@ -37,3 +37,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -40,0 +40,0 @@ */ |
@@ -100,3 +100,3 @@ 'use strict'; | ||
* | ||
* @param {import('postcss-selector-parser').Container<unknown>} node | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} node | ||
* @returns {Specificity} | ||
@@ -103,0 +103,0 @@ */ |
@@ -63,3 +63,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -66,0 +66,0 @@ */ |
@@ -51,3 +51,3 @@ 'use strict'; | ||
/** | ||
* @param {import('postcss-selector-parser').Container<unknown>} selectorNode | ||
* @param {import('postcss-selector-parser').Container<string | undefined>} selectorNode | ||
* @param {import('postcss').Rule} ruleNode | ||
@@ -54,0 +54,0 @@ */ |
@@ -53,2 +53,3 @@ 'use strict'; | ||
quiet, | ||
quietDeprecationWarnings = false, | ||
reportDescriptionlessDisables, | ||
@@ -104,2 +105,3 @@ reportInvalidScopeDisables, | ||
quiet, | ||
quietDeprecationWarnings, | ||
}); | ||
@@ -106,0 +108,0 @@ |
@@ -13,8 +13,10 @@ 'use strict'; | ||
/** | ||
* @param {{ cwd: string, ignorePath?: string | string[], ignorePattern?: string[] }} options | ||
* @typedef {import('stylelint').LinterOptions} LinterOptions | ||
* | ||
* @param {Pick<LinterOptions, 'ignorePath' | 'ignorePattern'> & { cwd: string }} options | ||
* @return {import('ignore').Ignore} | ||
*/ | ||
module.exports = function getFileIgnorer(options) { | ||
module.exports = function getFileIgnorer({ ignorePath, ignorePattern, cwd }) { | ||
const ignorer = ignore(); | ||
const ignorePaths = [options.ignorePath || []].flat(); | ||
const ignorePaths = [ignorePath || []].flat(); | ||
@@ -28,3 +30,3 @@ if (ignorePaths.length === 0) { | ||
? ignoreFilePath | ||
: path.resolve(options.cwd, ignoreFilePath); | ||
: path.resolve(cwd, ignoreFilePath); | ||
@@ -42,5 +44,5 @@ try { | ||
ignorer.add(options.ignorePattern || []); | ||
if (ignorePattern) ignorer.add(ignorePattern); | ||
return ignorer; | ||
}; |
{ | ||
"name": "stylelint", | ||
"version": "15.3.0", | ||
"version": "15.4.0", | ||
"description": "A mighty CSS linter that helps you avoid errors and enforce conventions.", | ||
@@ -115,9 +115,9 @@ "keywords": [ | ||
"dependencies": { | ||
"@csstools/css-parser-algorithms": "^2.0.1", | ||
"@csstools/css-parser-algorithms": "^2.1.0", | ||
"@csstools/css-tokenizer": "^2.1.0", | ||
"@csstools/media-query-list-parser": "^2.0.1", | ||
"@csstools/selector-specificity": "^2.1.1", | ||
"@csstools/selector-specificity": "^2.2.0", | ||
"balanced-match": "^2.0.0", | ||
"colord": "^2.9.3", | ||
"cosmiconfig": "^8.1.0", | ||
"cosmiconfig": "^8.1.3", | ||
"css-functions-list": "^3.1.0", | ||
@@ -160,3 +160,3 @@ "css-tree": "^2.3.1", | ||
"devDependencies": { | ||
"@changesets/cli": "^2.26.0", | ||
"@changesets/cli": "^2.26.1", | ||
"@changesets/get-github-info": "^0.5.2", | ||
@@ -183,3 +183,3 @@ "@stylelint/prettier-config": "^2.0.0", | ||
"common-tags": "^1.8.2", | ||
"deepmerge": "^4.3.0", | ||
"deepmerge": "^4.3.1", | ||
"eslint": "^8.36.0", | ||
@@ -194,3 +194,3 @@ "eslint-config-stylelint": "^18.0.0", | ||
"node-fetch": "^3.3.1", | ||
"np": "^7.6.3", | ||
"np": "^7.6.4", | ||
"npm-run-all": "^4.1.5", | ||
@@ -205,3 +205,3 @@ "patch-package": "^6.5.1", | ||
"sugarss": "^4.0.1", | ||
"typescript": "^4.9.5" | ||
"typescript": "^5.0.2" | ||
}, | ||
@@ -208,0 +208,0 @@ "engines": { |
@@ -271,2 +271,3 @@ import type * as PostCSS from 'postcss'; | ||
quiet?: boolean; | ||
quietDeprecationWarnings?: boolean; | ||
}; | ||
@@ -273,0 +274,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28880
913219
389
1
+ Addedcss-functions-list@3.2.2(transitive)
- Removedcss-functions-list@3.2.3(transitive)
Updatedcosmiconfig@^8.1.3