UNPKG

@code-pushup/eslint-plugin

Version:

Code PushUp plugin for detecting problems in source code using ESLint.📋

81 lines • 3.06 kB
import { builtinRules } from 'eslint/use-at-your-own-risk'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; import { exists, findNearestFile, toArray, ui } from '@code-pushup/utils'; import { jsonHash } from '../hash.js'; import { isRuleOff, optionsFromRuleEntry, parseRuleId, } from '../parse.js'; export async function loadRulesForFlatConfig({ eslintrc, }) { const config = eslintrc ? await loadConfigByPath(eslintrc) : await loadConfigByDefaultLocation(); const configs = toArray(config); const rules = findEnabledRulesWithOptions(configs); return rules .map(rule => { const meta = findRuleMeta(rule.id, configs); if (!meta) { ui().logger.warning(`Cannot find metadata for rule ${rule.id}`); return null; } return { ...rule, meta }; }) .filter(exists); } async function loadConfigByDefaultLocation() { const flatConfigFileNames = [ 'eslint.config.js', 'eslint.config.mjs', 'eslint.config.cjs', ]; const configPath = await findNearestFile(flatConfigFileNames); if (configPath) { return loadConfigByPath(configPath); } throw new Error([ `ESLint config file not found - expected ${flatConfigFileNames.join('/')} in ${process.cwd()} or some parent directory`, 'If your ESLint config is in a non-standard location, use the `eslintrc` parameter to specify the path.', ].join('\n')); } async function loadConfigByPath(configPath) { const absolutePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath); const url = pathToFileURL(absolutePath).toString(); const mod = (await import(url)); return 'default' in mod ? mod.default : mod; } function findEnabledRulesWithOptions(configs) { const enabledRules = configs .flatMap(({ rules }) => Object.entries(rules ?? {})) .filter(([, entry]) => entry != null && !isRuleOff(entry)) .map(([id, entry]) => ({ id, options: entry ? optionsFromRuleEntry(entry) : [], })); const uniqueRulesMap = new Map(enabledRules.map(({ id, options }) => [ `${id}::${jsonHash(options)}`, { id, options }, ])); return [...uniqueRulesMap.values()]; } function findRuleMeta(ruleId, configs) { const { plugin, name } = parseRuleId(ruleId); if (!plugin) { return findBuiltinRuleMeta(name); } return findPluginRuleMeta(plugin, name, configs); } function findBuiltinRuleMeta(name) { const rule = builtinRules.get(name); return rule?.meta; } function findPluginRuleMeta(plugin, name, configs) { const config = configs.find(({ plugins = {} }) => plugin in plugins); const rule = config?.plugins?.[plugin]?.rules?.[name]; if (typeof rule === 'function') { ui().logger.warning(`Cannot parse metadata for rule ${plugin}/${name}, plugin registers it as a function`); return undefined; } return rule?.meta; } //# sourceMappingURL=flat.js.map