Skip to content

Commit

Permalink
feat: automatically rename plugins in factory
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Mar 21, 2024
1 parent e0b58ea commit 77df2f5
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 10 deletions.
6 changes: 2 additions & 4 deletions src/configs/typescript.ts
Expand Up @@ -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',
Expand Down
17 changes: 15 additions & 2 deletions src/factory.ts
Expand Up @@ -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)[] = [
Expand All @@ -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.
*
Expand All @@ -64,6 +73,7 @@ export async function antfu(
): Promise<UserConfigItem[]> {
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),
Expand Down Expand Up @@ -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
}

Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Expand Up @@ -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.
*
Expand Down
61 changes: 57 additions & 4 deletions 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'

Check failure on line 3 in src/utils.ts

View workflow job for this annotation

GitHub Actions / lint

'FlatConfigItem' is defined but never used

export const parserPlain = {
meta: {
Expand Down Expand Up @@ -31,17 +31,70 @@ export async function combine(...configs: Awaitable<UserConfigItem | UserConfigI
return resolved.flat()
}

export function renameRules(rules: Record<string, any>, 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<string, any>, map: Record<string, string>) {
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<string, string>): 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<T>(value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
Expand Down

0 comments on commit 77df2f5

Please sign in to comment.