eslint-plugin-oxlint
Version:
Turn off all rules already supported by oxlint
91 lines (80 loc) • 3.23 kB
text/typescript
import path from 'node:path';
import {
oxlintConfigMeta,
type OxlintConfig,
type OxlintConfigOverride,
type OxlintConfigPlugins,
type OxlintConfigRules,
type OxlintConfigExtends,
} from './types.js';
import { getConfigContent } from './utilities.js';
import { defaultPlugins, readPluginsFromConfig } from './plugins.js';
import { readRulesFromConfig } from './rules.js';
import { readOverridesFromConfig } from './overrides.js';
/**
* tries to return the "extends" section from the config.
* it returns `undefined` when not found or invalid.
*/
const readExtendsFromConfig = (config: OxlintConfig): OxlintConfigExtends | undefined => {
return 'extends' in config && Array.isArray(config.extends) ? config.extends : undefined;
};
/**
* Resolves the paths of the "extends" section relative to the given config file.
*/
export const resolveRelativeExtendsPaths = (config: OxlintConfig) => {
if (!config[oxlintConfigMeta]?.filePath) {
return;
}
const extendsFiles = readExtendsFromConfig(config);
if (!extendsFiles?.length) return;
const configFileDirectory = path.dirname(config[oxlintConfigMeta].filePath);
config.extends = extendsFiles.map((extendFile) => {
if (typeof extendFile === 'string') {
return path.resolve(configFileDirectory, extendFile);
}
return extendFile;
});
};
/**
* Appends plugins, rules and overrides from the extends configs files to the given config.
*/
export const handleExtendsScope = (extendsConfigs: OxlintConfig[], config: OxlintConfig) => {
let rules: OxlintConfigRules = readRulesFromConfig(config) ?? {};
const plugins: OxlintConfigPlugins = readPluginsFromConfig(config) ?? [];
const overrides: OxlintConfigOverride[] = readOverridesFromConfig(config) ?? [];
for (const extendConfig of extendsConfigs) {
plugins.unshift(...(readPluginsFromConfig(extendConfig) ?? defaultPlugins));
rules = { ...readRulesFromConfig(extendConfig), ...rules };
overrides.unshift(...(readOverridesFromConfig(extendConfig) ?? []));
}
if (plugins.length > 0) config.plugins = [...new Set(plugins)];
if (Object.keys(rules).length > 0) config.rules = rules;
if (overrides.length > 0) config.overrides = overrides;
};
/**
* tries to return the content of the chain "extends" section from the config.
*/
export const readExtendsConfigsFromConfig = (config: OxlintConfig): OxlintConfig[] => {
const extendsFiles = readExtendsFromConfig(config);
if (!extendsFiles?.length) return [];
const extendsConfigs: OxlintConfig[] = [];
for (const file of extendsFiles) {
// resolved extends from js config, we can directly use it without reading the file content
if (typeof file !== 'string') {
const extended = readExtendsConfigsFromConfig(file);
delete file.extends;
extendsConfigs.push(file, ...extended);
continue;
}
const extendConfig = getConfigContent(file);
if (!extendConfig) continue;
extendConfig[oxlintConfigMeta] = {
filePath: file,
};
resolveRelativeExtendsPaths(extendConfig);
const extended = readExtendsConfigsFromConfig(extendConfig);
delete extendConfig.extends;
extendsConfigs.push(extendConfig, ...extended);
}
return extendsConfigs;
};