| // NOTICE: This file is generated by Rollup. To modify it, |
| // please instead edit the ESM counterpart and rebuild with Rollup (npm run build). |
| 'use strict'; |
| |
| const node_os = require('node:os'); |
| const constants = require('./constants.cjs'); |
| const configurationComment = require('./utils/configurationComment.cjs'); |
| const assignDisabledRanges = require('./assignDisabledRanges.cjs'); |
| const emitWarning = require('./utils/emitWarning.cjs'); |
| const cssTree = require('css-tree'); |
| const getStylelintRule = require('./utils/getStylelintRule.cjs'); |
| const reportUnknownRuleNames = require('./reportUnknownRuleNames.cjs'); |
| const index = require('./rules/index.cjs'); |
| const timing = require('./timing.cjs'); |
| |
| /** @import {Config, LinterOptions, PostcssResult} from 'stylelint' */ |
| |
| /** |
| * @param {LinterOptions} stylelintOptions |
| * @param {PostcssResult} postcssResult |
| * @param {Config} config |
| * @returns {Promise<any>} |
| */ |
| async function lintPostcssResult(stylelintOptions, postcssResult, config) { |
| postcssResult.stylelint.stylelintError = false; |
| postcssResult.stylelint.stylelintWarning = false; |
| postcssResult.stylelint.quiet = config.quiet; |
| postcssResult.stylelint.quietDeprecationWarnings = stylelintOptions.quietDeprecationWarnings; |
| postcssResult.stylelint.config = config; |
| |
| const postcssDoc = postcssResult.root; |
| |
| if (!('type' in postcssDoc)) { |
| throw new Error('Unexpected Postcss root object!'); |
| } |
| |
| const newlineMatch = postcssDoc.source?.input.css.match(/\r?\n/); |
| const newline = newlineMatch ? newlineMatch[0] : node_os.EOL; |
| const configurationComment$1 = config.configurationComment || configurationComment.DEFAULT_CONFIGURATION_COMMENT; |
| const ctx = { configurationComment: configurationComment$1, newline }; |
| |
| assignDisabledRanges(postcssDoc, postcssResult); |
| |
| const postcssRoots = /** @type {import('postcss').Root[]} */ ( |
| postcssDoc && postcssDoc.constructor.name === 'Document' ? postcssDoc.nodes : [postcssDoc] |
| ); |
| |
| // Promises for the rules. Although the rule code runs synchronously now, |
| // the use of Promises makes it compatible with the possibility of async |
| // rules down the line. |
| /** @type {Array<Promise<any>>} */ |
| const performRules = []; |
| |
| const rulesOrder = Object.keys(index); |
| const ruleNames = config.rules |
| ? Object.keys(config.rules).sort((a, b) => rulesOrder.indexOf(a) - rulesOrder.indexOf(b)) |
| : []; |
| |
| for (const ruleName of ruleNames) { |
| const ruleFunction = await getStylelintRule(ruleName, config); |
| |
| if (ruleFunction === undefined) { |
| performRules.push( |
| Promise.all( |
| postcssRoots.map((postcssRoot) => |
| reportUnknownRuleNames(ruleName, postcssRoot, postcssResult), |
| ), |
| ), |
| ); |
| |
| continue; |
| } |
| |
| const ruleSettings = config.rules?.[ruleName]; |
| |
| if (ruleSettings === null || ruleSettings[0] === null) continue; |
| |
| if (ruleFunction.meta?.deprecated && !stylelintOptions.quietDeprecationWarnings) { |
| warnDeprecatedRule(postcssResult, ruleName); |
| } |
| |
| const primaryOption = ruleSettings[0]; |
| const secondaryOptions = ruleSettings[1]; |
| |
| // Log the rule's severity in the PostCSS result |
| const defaultSeverity = config.defaultSeverity || constants.DEFAULT_SEVERITY; |
| |
| postcssResult.stylelint.ruleSeverities[ruleName] = |
| (secondaryOptions && secondaryOptions.severity) || defaultSeverity; |
| postcssResult.stylelint.customMessages[ruleName] = secondaryOptions && secondaryOptions.message; |
| postcssResult.stylelint.customUrls[ruleName] = secondaryOptions && secondaryOptions.url; |
| postcssResult.stylelint.ruleMetadata[ruleName] = ruleFunction.meta || {}; |
| |
| const shouldWarn = ruleFunction.meta?.fixable && !stylelintOptions.quietDeprecationWarnings; |
| const disableFix = secondaryOptions?.disableFix === true; |
| const fix = !disableFix && config.fix && isFixCompatible(postcssResult, ruleName); |
| const lexer = getCachedLexer(config); |
| const context = { |
| ...ctx, |
| lexer, |
| // context.fix is unlikely to be removed in the foreseeable future |
| // due to the sheer number of rules in the wild that rely on it |
| get fix() { |
| if (shouldWarn) { |
| emitWarning.emitDeprecationWarning( |
| '`context.fix` is being deprecated.', |
| 'CONTEXT_FIX', |
| `Please pass a \`fix\` callback to the \`report\` utility of "${ruleName}" instead.`, |
| ); |
| } |
| |
| return fix; |
| }, |
| }; |
| |
| const ruleFn = ruleFunction(primaryOption, secondaryOptions, context); |
| |
| /** |
| * @param {import('postcss').Root} postcssRoot |
| */ |
| async function runRule(postcssRoot) { |
| if (timing.enabled) { |
| return timing.time(ruleName, () => ruleFn(postcssRoot, postcssResult))(); |
| } |
| |
| return ruleFn(postcssRoot, postcssResult); |
| } |
| |
| performRules.push(Promise.all(postcssRoots.map(runRule))); |
| } |
| |
| return Promise.all(performRules); |
| } |
| |
| /** |
| * using context.fix instead of the fix callback has the drawback |
| * of not honouring the configuration comments in subtle ways |
| * @see file://./../docs/user-guide/options.md#fix for details |
| * @param {PostcssResult} postcssResult |
| * @param {string} name |
| * @returns {boolean} |
| */ |
| function isFixCompatible({ stylelint: { disabledRanges } }, name) { |
| return !disabledRanges[constants.RULE_NAME_ALL]?.length && !disabledRanges[name]; |
| } |
| |
| /** |
| * @param {PostcssResult} result |
| * @param {string} ruleName |
| * @returns {void} |
| */ |
| function warnDeprecatedRule(result, ruleName) { |
| const message = `The "${ruleName}" rule is deprecated.`; |
| |
| emitWarning.emitDeprecationWarning( |
| message, |
| 'RULE', |
| `Please be aware that the "${ruleName}" rule will soon be either removed or renamed.`, |
| ); |
| |
| result.warn(message, { stylelintType: 'deprecation' }); |
| } |
| |
| const lexerCache = new Map(); |
| |
| /** |
| * @param {Config} config |
| * @returns {import('css-tree').Lexer} |
| * */ |
| function getCachedLexer(config) { |
| const cacheKey = JSON.stringify(config.languageOptions?.syntax || {}); |
| |
| if (lexerCache.has(cacheKey)) { |
| return lexerCache.get(cacheKey); |
| } |
| |
| const newLexer = cssTree.fork({ |
| atrules: config.languageOptions?.syntax?.atRules || {}, |
| properties: config.languageOptions?.syntax?.properties || {}, |
| types: config.languageOptions?.syntax?.types || {}, |
| cssWideKeywords: config.languageOptions?.syntax?.cssWideKeywords || [], |
| }).lexer; |
| |
| lexerCache.set(cacheKey, newLexer); |
| |
| return newLexer; |
| } |
| |
| module.exports = lintPostcssResult; |