From 77df2f57e52f0b6618edcade02282086ee58e6c5 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Thu, 21 Mar 2024 13:11:05 +0100 Subject: [PATCH] feat: automatically rename plugins in factory --- src/configs/typescript.ts | 6 ++-- src/factory.ts | 17 +++++++++-- src/types.ts | 7 +++++ src/utils.ts | 61 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/configs/typescript.ts b/src/configs/typescript.ts index c4ebce61e2..448eefca7c 100644 --- a/src/configs/typescript.ts +++ b/src/configs/typescript.ts @@ -98,13 +98,11 @@ export async function typescript( rules: { ...renameRules( pluginTs.configs['eslint-recommended'].overrides![0].rules!, - '@typescript-eslint/', - 'ts/', + { '@typescript-eslint': 'ts' }, ), ...renameRules( pluginTs.configs.strict.rules!, - '@typescript-eslint/', - 'ts/', + { '@typescript-eslint': 'ts' }, ), 'no-dupe-class-members': 'off', 'no-loss-of-precision': 'off', diff --git a/src/factory.ts b/src/factory.ts index 379a98e0c3..a2acfe0682 100644 --- a/src/factory.ts +++ b/src/factory.ts @@ -26,7 +26,7 @@ import { vue, yaml, } from './configs' -import { combine, interopDefault } from './utils' +import { combine, interopDefault, renamePluginInConfigs } from './utils' import { formatters } from './configs/formatters' const flatConfigProps: (keyof FlatConfigItem)[] = [ @@ -48,6 +48,15 @@ const VuePackages = [ '@slidev/cli', ] +export const defaultPluginRenaming = { + '@stylistic': 'style', + '@typescript-eslint': 'ts', + 'import-x': 'import', + 'n': 'node', + 'vitest': 'test', + 'yml': 'yaml', +} + /** * Construct an array of ESLint flat config items. * @@ -64,6 +73,7 @@ export async function antfu( ): Promise { const { astro: enableAstro = false, + autoRenamePlugins = true, componentExts = [], gitignore: enableGitignore = true, isInEditor = !!((process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM) && !process.env.CI), @@ -232,11 +242,14 @@ export async function antfu( if (Object.keys(fusedConfig).length) configs.push([fusedConfig]) - const merged = combine( + const merged = await combine( ...configs, ...userConfigs, ) + if (autoRenamePlugins) + return renamePluginInConfigs(merged, defaultPluginRenaming) + return merged } diff --git a/src/types.ts b/src/types.ts index 462b0b5b30..9c5179de55 100644 --- a/src/types.ts +++ b/src/types.ts @@ -372,6 +372,13 @@ export interface OptionsConfig extends OptionsComponentExts { */ isInEditor?: boolean + /** + * Automatically rename plugins in the config. + * + * @default true + */ + autoRenamePlugins?: boolean + /** * Provide overrides for rules for each integration. * diff --git a/src/utils.ts b/src/utils.ts index ffc9ca8bd4..f007c32a8d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import process from 'node:process' import { isPackageExists } from 'local-pkg' -import type { Awaitable, UserConfigItem } from './types' +import type { Awaitable, FlatConfigItem, UserConfigItem } from './types' export const parserPlain = { meta: { @@ -31,17 +31,70 @@ export async function combine(...configs: Awaitable, from: string, to: string) { +/** + * Rename plugin prefixes in a rule object. + * Accepts a map of prefixes to rename. + * + * @example + * ```ts + * import { renameRules } from '@antfu/eslint-config' + * + * export default [{ + * rules: renameRules( + * { + * '@typescript-eslint/indent': 'error' + * }, + * { '@typescript-eslint': 'ts' } + * ) + * }] + * ``` + */ +export function renameRules(rules: Record, map: Record) { return Object.fromEntries( Object.entries(rules) .map(([key, value]) => { - if (key.startsWith(from)) - return [to + key.slice(from.length), value] + for (const [from, to] of Object.entries(map)) { + if (key.startsWith(`${from}/`)) + return [to + key.slice(from.length), value] + } return [key, value] }), ) } +/** + * Rename plugin names a flat configs array + * + * @example + * ```ts + * import { renamePluginInConfigs } from '@antfu/eslint-config' + * import someConfigs from './some-configs' + * + * export default renamePluginInConfigs(someConfigs, { + * '@typescript-eslint': 'ts', + * 'import-x': 'import', + * }) + * ``` + */ +export function renamePluginInConfigs(configs: UserConfigItem[], map: Record): UserConfigItem[] { + return configs.map((i) => { + const clone = { ...i } + if (clone.rules) + clone.rules = renameRules(clone.rules, map) + if (clone.plugins) { + clone.plugins = Object.fromEntries( + Object.entries(clone.plugins) + .map(([key, value]) => { + if (key in map) + return [map[key], value] + return [key, value] + }), + ) + } + return clone + }) +} + export function toArray(value: T | T[]): T[] { return Array.isArray(value) ? value : [value] }