4
0

getConfigForFile.mjs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { join } from 'node:path';
  2. import process from 'node:process';
  3. import { cosmiconfig } from 'cosmiconfig';
  4. import { ConfigurationError } from './utils/errors.mjs';
  5. import { augmentConfigFull } from './augmentConfig.mjs';
  6. const IS_TEST = process.env.NODE_ENV === 'test';
  7. const STOP_DIR = IS_TEST ? process.cwd() : undefined;
  8. /** @import {CosmiconfigResult, InternalApi} from 'stylelint' */
  9. /**
  10. * Get a configuration by the following way:
  11. *
  12. * 1. If the `config` option is given, it's returned.
  13. * 2. If the `configFile` option is given, the file's config is returned.
  14. * 3. If the options above are not given, a config found in `searchPath` is returned.
  15. *
  16. * @param {Object} options
  17. * @param {InternalApi} options.stylelint
  18. * @param {string} [options.searchPath] - Defaults to `cwd`.
  19. * @param {string} [options.filePath] - For applying overrides.
  20. * @param {boolean} [options.failIfNoConfig=true] - Throws an error if a config is not found.
  21. * @returns {Promise<CosmiconfigResult>}
  22. */
  23. export default async function getConfigForFile({
  24. stylelint,
  25. searchPath = stylelint._options.cwd,
  26. filePath,
  27. failIfNoConfig = true,
  28. }) {
  29. const optionsConfig = stylelint._options.config;
  30. const cwd = stylelint._options.cwd;
  31. if (optionsConfig) {
  32. const filePathAsCacheKey = filePath ?? '';
  33. /** @type {Map<string, CosmiconfigResult>} */
  34. const cachedForFiles = stylelint._specifiedConfigCache.get(optionsConfig) ?? new Map();
  35. const cached = cachedForFiles.get(filePathAsCacheKey);
  36. if (cached) {
  37. return cached;
  38. }
  39. const augmentedResult = await augmentConfigFull(stylelint, filePath, {
  40. config: optionsConfig,
  41. // Add the extra path part so that we can get the directory without being
  42. // confused
  43. filepath: join(cwd, 'argument-config'),
  44. });
  45. cachedForFiles.set(filePathAsCacheKey, augmentedResult);
  46. stylelint._specifiedConfigCache.set(optionsConfig, cachedForFiles);
  47. return augmentedResult;
  48. }
  49. const configExplorer = cosmiconfig('stylelint', {
  50. transform: (cosmiconfigResult) => augmentConfigFull(stylelint, filePath, cosmiconfigResult),
  51. stopDir: STOP_DIR,
  52. searchStrategy: 'global', // for backward compatibility
  53. });
  54. const configFile = stylelint._options.configFile;
  55. let config = configFile
  56. ? await configExplorer.load(configFile)
  57. : await configExplorer.search(searchPath);
  58. if (!config) {
  59. config = await configExplorer.search(cwd);
  60. }
  61. if (!config && failIfNoConfig) {
  62. throw new ConfigurationError(
  63. `No configuration provided${searchPath ? ` for ${searchPath}` : ''}`,
  64. );
  65. }
  66. return config;
  67. }