stylelint
Version:
A mighty CSS linter that helps you avoid errors and enforce conventions.
111 lines (89 loc) • 3.25 kB
JavaScript
import { join } from 'node:path';
import { ConfigurationError } from './utils/errors.mjs';
import { augmentConfigFull } from './augmentConfig.mjs';
import normalizeFilePath from './utils/normalizeFilePath.mjs';
/** @import {CosmiconfigResult, InternalApi} from 'stylelint' */
/**
* Creates a cache key for the augmented config cache.
*
* @param {string} configPath Path to the config file
* @param {string} filePath Path to the target file
* @returns {string}
*/
function getAugmentedConfigCacheKey(configPath, filePath) {
return `${configPath || 'no-config'}::${filePath || 'no-file'}`;
}
/**
* Get a configuration by the following way:
*
* 1. If the `config` option is given, it's returned.
* 2. If the `configFile` option is given, the file's config is returned.
* 3. If the options above are not given, a config found in `searchPath` is returned.
*
* @param {Object} options
* @param {InternalApi} options.stylelint
* @param {string} [options.searchPath] - Defaults to `cwd`.
* @param {string} [options.filePath] - For applying overrides.
* @param {boolean} [options.failIfNoConfig=true] - Throws an error if a config is not found.
* @returns {Promise<CosmiconfigResult>}
*/
export default async function getConfigForFile({
stylelint,
searchPath = stylelint._options.cwd,
filePath,
failIfNoConfig = true,
}) {
const optionsConfig = stylelint._options.config;
const cwd = stylelint._options.cwd;
if (optionsConfig) {
const filePathAsCacheKey = normalizeFilePath(filePath ?? '');
/** @type {Map<string, CosmiconfigResult>} */
const cachedForFiles = stylelint._specifiedConfigCache.get(optionsConfig) ?? new Map();
const cached = cachedForFiles.get(filePathAsCacheKey);
if (cached) {
return cached;
}
const augmentedResult = await augmentConfigFull(stylelint, filePath, {
config: optionsConfig,
// Add the extra path part so that we can get the directory without being
// confused
filepath: join(cwd, 'argument-config'),
});
cachedForFiles.set(filePathAsCacheKey, augmentedResult);
stylelint._specifiedConfigCache.set(optionsConfig, cachedForFiles);
return augmentedResult;
}
const configExplorer = stylelint._configExplorer;
const configFile = stylelint._options.configFile;
// First, discover the raw config, cached by cosmiconfig.
let rawConfig = configFile
? await configExplorer.load(configFile)
: await configExplorer.search(searchPath);
if (!rawConfig) {
rawConfig = await configExplorer.search(cwd);
}
if (!rawConfig && failIfNoConfig) {
throw new ConfigurationError(
`No configuration provided${searchPath ? ` for ${searchPath}` : ''}`,
);
}
if (!rawConfig) {
return rawConfig;
}
// Check the augmented config cache.
const cacheKey = getAugmentedConfigCacheKey(
rawConfig.filepath,
filePath ? normalizeFilePath(filePath) : '',
);
const cachedAugmented = stylelint._augmentedConfigCache.get(cacheKey);
if (cachedAugmented) {
return cachedAugmented;
}
// Perform full augmentation.
const augmentedResult = await augmentConfigFull(stylelint, filePath, rawConfig);
// Cache the augmented result.
if (augmentedResult) {
stylelint._augmentedConfigCache.set(cacheKey, augmentedResult);
}
return augmentedResult;
}