Skip to content

Commit

Permalink
feat: support rules override, close #255
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 26, 2023
1 parent 05073cd commit 3935399
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 23 deletions.
7 changes: 5 additions & 2 deletions src/configs/markdown.ts
Expand Up @@ -2,11 +2,12 @@ import type { FlatESLintConfigItem } from 'eslint-define-config'
import { GLOB_MARKDOWN, GLOB_MARKDOWN_CODE } from '../globs'
import { pluginMarkdown } from '../plugins'
import { OFF } from '../flags'
import type { OptionsComponentExts } from '../types'
import type { OptionsComponentExts, OptionsOverrides } from '../types'

export function markdown(options: OptionsComponentExts = {}): FlatESLintConfigItem[] {
export function markdown(options: OptionsComponentExts & OptionsOverrides = {}): FlatESLintConfigItem[] {
const {
componentExts = [],
overrides = {},
} = options

return [
Expand Down Expand Up @@ -57,6 +58,8 @@ export function markdown(options: OptionsComponentExts = {}): FlatESLintConfigIt
'unicode-bom': 'off',
'unused-imports/no-unused-imports': OFF,
'unused-imports/no-unused-vars': OFF,

...overrides,
},
},
]
Expand Down
12 changes: 9 additions & 3 deletions src/configs/test.ts
Expand Up @@ -2,9 +2,14 @@ import type { FlatESLintConfigItem } from 'eslint-define-config'
import { pluginNoOnlyTests } from '../plugins'
import { GLOB_TESTS } from '../globs'
import { OFF } from '../flags'
import type { OptionsIsInEditor } from '../types'
import type { OptionsIsInEditor, OptionsOverrides } from '../types'

export function test(options: OptionsIsInEditor & OptionsOverrides = {}): FlatESLintConfigItem[] {
const {
isInEditor = false,
overrides = {},
} = options

export function test(options: OptionsIsInEditor = {}): FlatESLintConfigItem[] {
return [
{
plugins: {
Expand All @@ -14,7 +19,8 @@ export function test(options: OptionsIsInEditor = {}): FlatESLintConfigItem[] {
{
files: GLOB_TESTS,
rules: {
'no-only-tests/no-only-tests': options.isInEditor ? OFF : 'error',
'no-only-tests/no-only-tests': isInEditor ? OFF : 'error',
...overrides,
},
},
]
Expand Down
15 changes: 11 additions & 4 deletions src/configs/typescript.ts
Expand Up @@ -3,12 +3,13 @@ import type { FlatESLintConfigItem } from 'eslint-define-config'
import { GLOB_TS, GLOB_TSX } from '../globs'
import { parserTs, pluginAntfu, pluginImport, pluginTs } from '../plugins'
import { OFF } from '../flags'
import type { OptionsComponentExts, OptionsTypeScriptWithLanguageServer } from '../types'
import type { OptionsComponentExts, OptionsOverrides, OptionsTypeScriptWithLanguageServer } from '../types'
import { renameRules } from '../utils'

export function typescript(options?: OptionsComponentExts): FlatESLintConfigItem[] {
export function typescript(options?: OptionsComponentExts & OptionsOverrides): FlatESLintConfigItem[] {
const {
componentExts = [],
overrides = {},
} = options ?? {}

return [
Expand Down Expand Up @@ -74,6 +75,8 @@ export function typescript(options?: OptionsComponentExts): FlatESLintConfigItem
'ts/no-use-before-define': ['error', { classes: false, functions: false, variables: true }],
'ts/prefer-ts-expect-error': 'error',
'ts/triple-slash-reference': OFF,

...overrides,
},
},
{
Expand All @@ -100,11 +103,14 @@ export function typescript(options?: OptionsComponentExts): FlatESLintConfigItem
]
}

export function typescriptWithLanguageServer(options: OptionsTypeScriptWithLanguageServer & OptionsComponentExts): FlatESLintConfigItem[] {
export function typescriptWithLanguageServer(
options: OptionsTypeScriptWithLanguageServer & OptionsComponentExts & OptionsOverrides,
): FlatESLintConfigItem[] {
const {
componentExts = [],
tsconfigPath,
tsconfigRootDir = process.cwd(),
overrides = {},
} = options

return [
Expand All @@ -113,8 +119,8 @@ export function typescriptWithLanguageServer(options: OptionsTypeScriptWithLangu
GLOB_TS,
GLOB_TSX,
...componentExts.map(ext => `**/*.${ext}`),
'!**/*.md/*.*',
],
ignores: ['**/*.md/*.*'],
languageOptions: {
parser: parserTs,
parserOptions: {
Expand Down Expand Up @@ -142,6 +148,7 @@ export function typescriptWithLanguageServer(options: OptionsTypeScriptWithLangu
'ts/restrict-plus-operands': 'error',
'ts/restrict-template-expressions': 'error',
'ts/unbound-method': 'error',
...overrides,
},
},
]
Expand Down
11 changes: 9 additions & 2 deletions src/configs/vue.ts
Expand Up @@ -2,9 +2,14 @@ import type { FlatESLintConfigItem } from 'eslint-define-config'
import { GLOB_VUE } from '../globs'
import { parserTs, parserVue, pluginVue } from '../plugins'
import { OFF } from '../flags'
import type { OptionsHasTypeScript } from '../types'
import type { OptionsHasTypeScript, OptionsOverrides } from '../types'

export function vue(options: OptionsHasTypeScript = {}): FlatESLintConfigItem[] {
export function vue(
options: OptionsHasTypeScript & OptionsOverrides = {},
): FlatESLintConfigItem[] {
const {
overrides = {},
} = options
return [
{
plugins: {
Expand Down Expand Up @@ -103,6 +108,8 @@ export function vue(options: OptionsHasTypeScript = {}): FlatESLintConfigItem[]
'vue/space-infix-ops': 'error',
'vue/space-unary-ops': ['error', { nonwords: false, words: true }],
'vue/template-curly-spacing': 'error',

...overrides,
},
},
]
Expand Down
50 changes: 38 additions & 12 deletions src/factory.ts
Expand Up @@ -36,15 +36,25 @@ const flatConfigProps: (keyof FlatESLintConfigItem)[] = [
'settings',
]

const VuePackages = [
'vue',
'nuxt',
'vitepress',
'@slidev/cli',
]

/**
* Construct an array of ESLint flat config items.
*/
export function antfu(options: OptionsConfig & FlatESLintConfigItem = {}, ...userConfigs: (FlatESLintConfigItem | FlatESLintConfigItem[])[]) {
const isInEditor = options.isInEditor ?? !!((process.env.VSCODE_PID || process.env.JETBRAINS_IDE) && !process.env.CI)
const enableVue = options.vue ?? (isPackageExists('vue') || isPackageExists('nuxt') || isPackageExists('vitepress') || isPackageExists('@slidev/cli'))
const enableTypeScript = options.typescript ?? (isPackageExists('typescript'))
const enableStylistic = options.stylistic ?? true
const enableGitignore = options.gitignore ?? true
const {
isInEditor = !!((process.env.VSCODE_PID || process.env.JETBRAINS_IDE) && !process.env.CI),
vue: enableVue = VuePackages.some(i => isPackageExists(i)),
typescript: enableTypeScript = isPackageExists('typescript'),
stylistic: enableStylistic = true,
gitignore: enableGitignore = true,
overrides = {},
} = options

const configs: FlatESLintConfigItem[][] = []

Expand Down Expand Up @@ -76,24 +86,36 @@ export function antfu(options: OptionsConfig & FlatESLintConfigItem = {}, ...use
componentExts.push('vue')

if (enableTypeScript) {
configs.push(typescript({ componentExts }))
configs.push(typescript({
componentExts,
overrides: overrides.typescript,
}))

if (typeof enableTypeScript !== 'boolean') {
configs.push(typescriptWithLanguageServer({
...enableTypeScript,
componentExts,
overrides: overrides.typescriptWithTypes,
}))
}
}

if (enableStylistic)
configs.push(stylistic)

if (options.test ?? true)
configs.push(test({ isInEditor }))
if (options.test ?? true) {
configs.push(test({
isInEditor,
overrides: overrides.test,
}))
}

if (enableVue)
configs.push(vue({ typescript: !!enableTypeScript }))
if (enableVue) {
configs.push(vue({
overrides: overrides.vue,
typescript: !!enableTypeScript,
}))
}

if (options.jsonc ?? true) {
configs.push(
Expand All @@ -106,8 +128,12 @@ export function antfu(options: OptionsConfig & FlatESLintConfigItem = {}, ...use
if (options.yaml ?? true)
configs.push(yml)

if (options.markdown ?? true)
configs.push(markdown({ componentExts }))
if (options.markdown ?? true) {
configs.push(markdown({
componentExts,
overrides: overrides.markdown,
}))
}

// User can optionally pass a flat config item to the first argument
// We pick the known keys as ESLint would do schema validation
Expand Down
18 changes: 18 additions & 0 deletions src/types.ts
@@ -1,4 +1,5 @@
import type { FlatGitignoreOptions } from 'eslint-config-flat-gitignore'
import type { FlatESLintConfigItem } from 'eslint-define-config'

export interface OptionsComponentExts {
/**
Expand All @@ -19,6 +20,10 @@ export interface OptionsHasTypeScript {
typescript?: boolean
}

export interface OptionsOverrides {
overrides?: FlatESLintConfigItem['rules']
}

export interface OptionsIsInEditor {
isInEditor?: boolean
}
Expand Down Expand Up @@ -90,4 +95,17 @@ export interface OptionsConfig {
* @default auto-detect based on the process.env
*/
isInEditor?: boolean

/**
* Provide overrides for rules for each integration.
*/
overrides?: {
typescript?: FlatESLintConfigItem['rules']
typescriptWithTypes?: FlatESLintConfigItem['rules']

test?: FlatESLintConfigItem['rules']
vue?: FlatESLintConfigItem['rules']
jsonc?: FlatESLintConfigItem['rules']
markdown?: FlatESLintConfigItem['rules']
}
}

0 comments on commit 3935399

Please sign in to comment.