| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- // 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 path = require('node:path');
- const globjoin = require('globjoin');
- const micromatch = require('micromatch');
- const normalizePath = require('normalize-path');
- const validateTypes = require('./utils/validateTypes.cjs');
- const errors = require('./utils/errors.cjs');
- const dynamicImport = require('./utils/dynamicImport.cjs');
- const emitWarning = require('./utils/emitWarning.cjs');
- const getModulePath = require('./utils/getModulePath.cjs');
- const normalizeAllRuleSettings = require('./normalizeAllRuleSettings.cjs');
- /** @import {Config as StylelintConfig, CosmiconfigResult as StylelintCosmiconfigResult, InternalApi as StylelintInternalApi} from 'stylelint' */
- /**
- * @param {string} glob
- * @param {string} basedir
- * @returns {string}
- */
- function absolutizeGlob(glob, basedir) {
- const result = path.isAbsolute(glob.replace(/^!/, '')) ? glob : globjoin(basedir, glob);
- // Glob patterns for micromatch should be in POSIX-style
- return normalizePath(result);
- }
- /**
- * - Merges config and stylelint options
- * - Makes all paths absolute
- * - Merges extends
- * @param {StylelintInternalApi} stylelint
- * @param {StylelintConfig} config
- * @param {string} configDir
- * @param {boolean} allowOverrides
- * @param {string} rootConfigDir
- * @param {string} [filePath]
- * @returns {Promise<StylelintConfig>}
- */
- async function augmentConfigBasic(
- stylelint,
- config,
- configDir,
- allowOverrides,
- rootConfigDir,
- filePath,
- ) {
- let augmentedConfig = config;
- if (allowOverrides) {
- augmentedConfig = addOptions(stylelint, augmentedConfig);
- }
- if (filePath) {
- augmentedConfig = applyOverrides(augmentedConfig, rootConfigDir, filePath);
- }
- augmentedConfig = await extendConfig(
- stylelint,
- augmentedConfig,
- configDir,
- rootConfigDir,
- filePath,
- );
- const cwd = stylelint._options.cwd;
- return absolutizePaths(augmentedConfig, configDir, cwd);
- }
- /**
- * Extended configs need to be run through augmentConfigBasic
- * but do not need the full treatment. Things like pluginFunctions
- * will be resolved and added by the parent config.
- * @param {string} cwd
- * @returns {(cosmiconfigResult?: StylelintCosmiconfigResult) => Promise<StylelintCosmiconfigResult>}
- */
- function augmentConfigExtended(cwd) {
- return async (cosmiconfigResult) => {
- if (!cosmiconfigResult) {
- return null;
- }
- const configDir = path.dirname(cosmiconfigResult.filepath || '');
- const { config } = cosmiconfigResult;
- const augmentedConfig = absolutizePaths(config, configDir, cwd);
- return {
- config: augmentedConfig,
- filepath: cosmiconfigResult.filepath,
- };
- };
- }
- /**
- * @param {StylelintInternalApi} stylelint
- * @param {string} [filePath]
- * @param {StylelintCosmiconfigResult} [cosmiconfigResult]
- * @returns {Promise<StylelintCosmiconfigResult>}
- */
- async function augmentConfigFull(stylelint, filePath, cosmiconfigResult) {
- if (!cosmiconfigResult) {
- return null;
- }
- const config = cosmiconfigResult.config;
- const filepath = cosmiconfigResult.filepath;
- const configDir = stylelint._options.configBasedir || path.dirname(filepath || '');
- let augmentedConfig = await augmentConfigBasic(
- stylelint,
- config,
- configDir,
- true,
- configDir,
- filePath,
- );
- augmentedConfig = await addPluginFunctions(augmentedConfig, stylelint._options);
- augmentedConfig = await addProcessorFunctions(augmentedConfig);
- if (!augmentedConfig.rules) {
- throw new errors.ConfigurationError(
- 'No rules found within configuration. Have you provided a "rules" property?',
- );
- }
- augmentedConfig = await normalizeAllRuleSettings(augmentedConfig);
- return {
- config: augmentedConfig,
- filepath: cosmiconfigResult.filepath,
- };
- }
- /**
- * Make all paths in the config absolute.
- *
- * @param {StylelintConfig} config
- * @param {string} configDir
- * @param {string} cwd
- * @returns {StylelintConfig}
- */
- function absolutizePaths(config, configDir, cwd) {
- if (config.ignoreFiles) {
- config.ignoreFiles = [config.ignoreFiles].flat().map((glob) => absolutizeGlob(glob, configDir));
- }
- /** @type {<T>(lookup: T) => (string | T)} */
- const toAbsolutePath = (lookup) => {
- if (typeof lookup === 'string') {
- return getModulePath(configDir, lookup, cwd);
- }
- return lookup;
- };
- if (config.plugins) {
- config.plugins = [config.plugins].flat().map(toAbsolutePath);
- }
- if (config.processors) {
- config.processors = config.processors.map(toAbsolutePath);
- }
- return config;
- }
- /**
- * @param {StylelintInternalApi} stylelint
- * @param {StylelintConfig} config
- * @param {string} configDir
- * @param {string} rootConfigDir
- * @param {string} [filePath]
- * @returns {Promise<StylelintConfig>}
- */
- async function extendConfig(stylelint, config, configDir, rootConfigDir, filePath) {
- if (config.extends === undefined) {
- return config;
- }
- const { extends: configExtends, ...originalWithoutExtends } = config;
- const normalizedExtends = [configExtends].flat();
- let resultConfig = originalWithoutExtends;
- for (const extendLookup of normalizedExtends) {
- let extendResult;
- if (typeof extendLookup === 'string') {
- extendResult = await loadExtendedConfig(stylelint, configDir, extendLookup);
- } else if (typeof extendLookup === 'object' && extendLookup !== null) {
- extendResult = { config: extendLookup };
- }
- if (extendResult) {
- let extendResultConfig = extendResult.config;
- const extendConfigDir = path.dirname(extendResult.filepath || '');
- extendResultConfig = await augmentConfigBasic(
- stylelint,
- extendResultConfig,
- extendConfigDir,
- false,
- rootConfigDir,
- filePath,
- );
- resultConfig = mergeConfigs(resultConfig, extendResultConfig);
- }
- }
- return mergeConfigs(resultConfig, originalWithoutExtends);
- }
- /**
- * @param {StylelintInternalApi} stylelint
- * @param {string} configDir
- * @param {string} extendLookup
- * @returns {Promise<StylelintCosmiconfigResult>}
- */
- function loadExtendedConfig(stylelint, configDir, extendLookup) {
- const extendPath = getModulePath(configDir, extendLookup, stylelint._options.cwd);
- return stylelint._extendExplorer.load(extendPath);
- }
- /**
- * When merging configs (via extends)
- * - plugin, extends, overrides arrays are joined
- * - rules are merged via Object.assign, so there is no attempt made to
- * merge any given rule's settings. If b contains the same rule as a,
- * b's rule settings will override a's rule settings entirely.
- * - Everything else is merged via Object.assign
- * @param {StylelintConfig} a
- * @param {StylelintConfig} b
- * @returns {StylelintConfig}
- */
- function mergeConfigs(a, b) {
- /** @type {Pick<StylelintConfig, 'plugins'>} */
- const pluginMerger = {};
- if (a.plugins || b.plugins) {
- pluginMerger.plugins = [];
- if (a.plugins) {
- pluginMerger.plugins = pluginMerger.plugins.concat(a.plugins);
- }
- if (b.plugins) {
- pluginMerger.plugins = [...new Set(pluginMerger.plugins.concat(b.plugins))];
- }
- }
- /** @type {Pick<StylelintConfig, 'processors'>} */
- const processorMerger = {};
- if (a.processors || b.processors) {
- processorMerger.processors = [];
- if (a.processors) {
- processorMerger.processors = processorMerger.processors.concat(a.processors);
- }
- if (b.processors) {
- processorMerger.processors = [...new Set(processorMerger.processors.concat(b.processors))];
- }
- }
- /** @type {Pick<StylelintConfig, 'overrides'>} */
- const overridesMerger = {};
- if (a.overrides || b.overrides) {
- overridesMerger.overrides = [];
- if (a.overrides) {
- overridesMerger.overrides = overridesMerger.overrides.concat(a.overrides);
- }
- if (b.overrides) {
- overridesMerger.overrides = [...new Set(overridesMerger.overrides.concat(b.overrides))];
- }
- }
- /** @type {Pick<StylelintConfig, 'extends'>} */
- const extendsMerger = {};
- if (a.extends || b.extends) {
- extendsMerger.extends = [];
- if (a.extends) {
- extendsMerger.extends = extendsMerger.extends.concat(a.extends);
- }
- if (b.extends) {
- extendsMerger.extends = extendsMerger.extends.concat(b.extends);
- }
- // Remove duplicates from the array, the last item takes precedence
- extendsMerger.extends = extendsMerger.extends.filter(
- (item, index, arr) => arr.lastIndexOf(item) === index,
- );
- }
- const rulesMerger = {};
- if (a.rules || b.rules) {
- rulesMerger.rules = { ...a.rules, ...b.rules };
- }
- const result = {
- ...a,
- ...b,
- ...extendsMerger,
- ...pluginMerger,
- ...processorMerger,
- ...overridesMerger,
- ...rulesMerger,
- };
- return result;
- }
- /**
- * @param {StylelintConfig} config
- * @param {import('stylelint').LinterOptions} options
- * @returns {Promise<StylelintConfig>}
- */
- async function addPluginFunctions(config, { quietDeprecationWarnings }) {
- if (!config.plugins) {
- return config;
- }
- const normalizedPlugins = [config.plugins].flat();
- /** @type {StylelintConfig['pluginFunctions']} */
- const pluginFunctions = {};
- for (const pluginLookup of normalizedPlugins) {
- let pluginImport;
- if (typeof pluginLookup === 'string') {
- pluginImport = await dynamicImport(pluginLookup);
- // NOTE: This '.cjs' check is limited. Some CommonJS plugins may have the '.js' extension.
- if (!quietDeprecationWarnings && pluginLookup.endsWith('.cjs')) {
- emitWarning.emitDeprecationWarning(
- `CommonJS plugins are deprecated ("${pluginLookup}").`,
- 'COMMONJS_PLUGINS',
- 'See https://stylelint.io/migration-guide/to-16',
- );
- }
- } else {
- pluginImport = pluginLookup;
- }
- // Handle either ES6 or CommonJS modules
- pluginImport = pluginImport.default || pluginImport;
- // A plugin can export either a single rule definition
- // or an array of them
- const normalizedPluginImport = [pluginImport].flat();
- for (const pluginRuleDefinition of normalizedPluginImport) {
- if (!pluginRuleDefinition.ruleName) {
- throw new errors.ConfigurationError(
- `stylelint requires plugins to expose a ruleName. The plugin "${pluginLookup}" is not doing this, so will not work with stylelint. Please file an issue with the plugin.`,
- );
- }
- if (!pluginRuleDefinition.ruleName.includes('/')) {
- throw new errors.ConfigurationError(
- `stylelint requires plugin rules to be namespaced, i.e. only \`plugin-namespace/plugin-rule-name\` plugin rule names are supported. The plugin rule "${pluginRuleDefinition.ruleName}" does not do this, so will not work. Please file an issue with the plugin.`,
- );
- }
- pluginFunctions[pluginRuleDefinition.ruleName] = pluginRuleDefinition.rule;
- }
- }
- config.pluginFunctions = pluginFunctions;
- return config;
- }
- /**
- * @param {StylelintConfig} config
- * @returns {Promise<StylelintConfig>}
- */
- async function addProcessorFunctions(config) {
- if (!config.processors) {
- return config;
- }
- const processorPromises = config.processors.map(async (processorLookup) => {
- let processor = await dynamicImport(processorLookup);
- processor = processor.default ?? processor;
- if (!validateTypes.isFunction(processor)) {
- throw new errors.ConfigurationError(`The processor "${processorLookup}" must be a function`);
- }
- const { name, postprocess } = processor();
- if (!validateTypes.isString(name) || !name) {
- throw new errors.ConfigurationError(
- `The processor "${processorLookup}" must return an object with the "name" property`,
- );
- }
- if (!validateTypes.isFunction(postprocess)) {
- throw new errors.ConfigurationError(
- `The processor "${processorLookup}" must return an object with the "postprocess" property`,
- );
- }
- return { name, postprocess };
- });
- /** @type {StylelintConfig['_processorFunctions']} */
- const processorFunctions = new Map();
- (await Promise.all(processorPromises)).forEach(({ name, postprocess }) => {
- if (name) {
- processorFunctions.set(name, postprocess);
- }
- });
- config._processorFunctions = processorFunctions;
- return config;
- }
- /**
- * @param {StylelintConfig} fullConfig
- * @param {string} rootConfigDir
- * @param {string} filePath
- * @returns {StylelintConfig}
- */
- function applyOverrides(fullConfig, rootConfigDir, filePath) {
- let { overrides, ...config } = fullConfig;
- if (!overrides) {
- return config;
- }
- if (!Array.isArray(overrides)) {
- throw new TypeError(
- 'The `overrides` configuration property should be an array, e.g. { "overrides": [{ "files": "*.css", "rules": {} }] }.',
- );
- }
- /** @type {(glob: string) => boolean} */
- const nonegateGlob = (glob) => !glob.startsWith('!');
- for (const override of overrides) {
- const { files, ...configOverrides } = override;
- if (!files) {
- throw new Error(
- 'Every object in the `overrides` configuration property should have a `files` property with globs, e.g. { "overrides": [{ "files": "*.css", "rules": {} }] }.',
- );
- }
- const fileList = [files].flat();
- const absoluteGlobs = fileList.map((glob) => absolutizeGlob(glob, rootConfigDir));
- if (
- micromatch.isMatch(filePath, absoluteGlobs, { dot: true }) ||
- // E.g. `*.css` matches any CSS files in any directories.
- micromatch.isMatch(filePath, fileList.filter(nonegateGlob), { dot: true, basename: true })
- ) {
- config = mergeConfigs(config, configOverrides);
- }
- }
- return config;
- }
- /**
- * Add options to the config
- *
- * @param {StylelintInternalApi} stylelint
- * @param {StylelintConfig} config
- *
- * @returns {StylelintConfig}
- */
- function addOptions(stylelint, config) {
- const augmentedConfig = {
- ...config,
- };
- const subset = /** @type {const} */ ([
- 'customSyntax',
- 'fix',
- 'computeEditInfo',
- 'ignoreDisables',
- 'quiet',
- 'reportDescriptionlessDisables',
- 'reportInvalidScopeDisables',
- 'reportNeedlessDisables',
- 'reportUnscopedDisables',
- 'validate',
- ]);
- /** @type {Partial<StylelintConfig>} */
- const options = {
- ...stylelint._options,
- // Override fix to match Config type.
- fix: stylelint._options.fix ? Boolean(stylelint._options.fix) : undefined,
- };
- /**
- * @template T
- * @param {T extends typeof subset[number] ? T : never} key
- */
- const addOption = (key) => {
- const value = options[key];
- if (value) {
- augmentedConfig[key] = value;
- }
- };
- subset.forEach((key) => addOption(key));
- return augmentedConfig;
- }
- exports.applyOverrides = applyOverrides;
- exports.augmentConfigExtended = augmentConfigExtended;
- exports.augmentConfigFull = augmentConfigFull;
|