Files
OliveTin/frontend/node_modules/stylelint/lib/lintPostcssResult.cjs

190 lines
6.1 KiB
JavaScript

// 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;