Skip to content

Commit 4ff2080

Browse files
committedMar 27, 2024·
feat: improve types for rules
1 parent 698abe1 commit 4ff2080

File tree

9 files changed

+306
-99
lines changed

9 files changed

+306
-99
lines changed
 

Diff for: ‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,5 @@ _fixtures
8282

8383
.temp
8484
.history
85+
86+
src/typegen.d.ts

Diff for: ‎package.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
"dist"
2626
],
2727
"scripts": {
28-
"build": "tsup --format esm,cjs --clean --dts",
28+
"build": "nr typegen && tsup --format esm,cjs --clean --dts",
2929
"stub": "tsup --format esm",
3030
"dev": "tsup --format esm,cjs --watch & eslint-flat-config-viewer",
3131
"watch": "tsup --format esm,cjs --watch",
3232
"lint": "eslint .",
33+
"typegen": "esno scripts/typegen.ts",
3334
"prepack": "nr build",
3435
"release": "bumpp && pnpm publish",
3536
"test": "vitest",
@@ -86,12 +87,8 @@
8687
}
8788
},
8889
"dependencies": {
89-
"@antfu/eslint-define-config": "^1.23.0-2",
9090
"@antfu/install-pkg": "^0.3.1",
9191
"@clack/prompts": "^0.7.0",
92-
"@eslint-types/jsdoc": "48.2.1",
93-
"@eslint-types/typescript-eslint": "^7.2.0",
94-
"@eslint-types/unicorn": "^51.0.1",
9592
"@stylistic/eslint-plugin": "^1.7.0",
9693
"@typescript-eslint/eslint-plugin": "^7.4.0",
9794
"@typescript-eslint/parser": "^7.4.0",
@@ -145,6 +142,7 @@
145142
"eslint-plugin-react-hooks": "^4.6.0",
146143
"eslint-plugin-react-refresh": "^0.4.6",
147144
"eslint-plugin-svelte": "2.36.0-next.13",
145+
"eslint-typegen": "^0.0.2",
148146
"esno": "^4.7.0",
149147
"execa": "^8.0.1",
150148
"fast-glob": "^3.3.2",

Diff for: ‎pnpm-lock.yaml

+210-30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: ‎scripts/typegen.ts

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import fs from 'node:fs/promises'
2+
import { pluginsToRulesOptions } from 'eslint-typegen'
3+
import type { ESLint } from 'eslint'
4+
import {
5+
astro,
6+
combine,
7+
comments,
8+
formatters,
9+
imports,
10+
javascript,
11+
jsdoc,
12+
jsonc,
13+
markdown,
14+
node,
15+
perfectionist,
16+
react,
17+
sortPackageJson,
18+
stylistic,
19+
svelte,
20+
test,
21+
toml,
22+
typescript,
23+
unicorn,
24+
unocss,
25+
vue,
26+
yaml,
27+
} from '../src'
28+
29+
const plugins: Record<string, ESLint.Plugin> = {}
30+
31+
const configs = await combine(
32+
astro(),
33+
comments(),
34+
formatters(),
35+
imports(),
36+
javascript(),
37+
jsdoc(),
38+
jsonc(),
39+
markdown(),
40+
node(),
41+
perfectionist(),
42+
react(),
43+
sortPackageJson(),
44+
stylistic(),
45+
svelte(),
46+
test(),
47+
toml(),
48+
typescript(),
49+
unicorn(),
50+
unocss(),
51+
vue(),
52+
yaml(),
53+
)
54+
55+
for (const config of configs)
56+
Object.assign(plugins, config.plugins)
57+
58+
console.log(Object.keys(plugins))
59+
60+
const dts = await pluginsToRulesOptions(plugins)
61+
62+
await fs.writeFile('src/typegen.d.ts', dts)

Diff for: ‎src/factory.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import process from 'node:process'
22
import fs from 'node:fs'
33
import { isPackageExists } from 'local-pkg'
44
import { FlatConfigPipeline } from 'eslint-flat-config-utils'
5-
import type { Awaitable, FlatConfigItem, OptionsConfig, UserConfigItem } from './types'
5+
import type { Awaitable, FlatConfigItem, OptionsConfig } from './types'
66
import {
77
astro,
88
comments,
@@ -63,15 +63,15 @@ export const defaultPluginRenaming = {
6363
*
6464
* @param {OptionsConfig & FlatConfigItem} options
6565
* The options for generating the ESLint configurations.
66-
* @param {Awaitable<UserConfigItem | UserConfigItem[]>[]} userConfigs
66+
* @param {Awaitable<FlatConfigItem | FlatConfigItem[]>[]} userConfigs
6767
* The user configurations to be merged with the generated configurations.
68-
* @returns {Promise<UserConfigItem[]>}
68+
* @returns {Promise<FlatConfigItem[]>}
6969
* The merged ESLint configurations.
7070
*/
7171
export function antfu(
7272
options: OptionsConfig & FlatConfigItem = {},
73-
...userConfigs: Awaitable<UserConfigItem | UserConfigItem[]>[]
74-
): FlatConfigPipeline<UserConfigItem> {
73+
...userConfigs: Awaitable<FlatConfigItem | FlatConfigItem[]>[]
74+
): FlatConfigPipeline<FlatConfigItem> {
7575
const {
7676
astro: enableAstro = false,
7777
autoRenamePlugins = true,
@@ -243,7 +243,7 @@ export function antfu(
243243
if (Object.keys(fusedConfig).length)
244244
configs.push([fusedConfig])
245245

246-
let pipeline = new FlatConfigPipeline<UserConfigItem>()
246+
let pipeline = new FlatConfigPipeline<FlatConfigItem>()
247247

248248
pipeline = pipeline
249249
.append(

Diff for: ‎src/types.ts

+12-53
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,15 @@
22
import type { ParserOptions } from '@typescript-eslint/parser'
33
import type { Options as VueBlocksOptions } from 'eslint-processor-vue-blocks'
44
import type { Linter } from 'eslint'
5-
import type {
6-
EslintCommentsRules,
7-
EslintRules,
8-
FlatESLintConfigItem,
9-
ImportRules,
10-
JsoncRules,
11-
MergeIntersection,
12-
NRules,
13-
Prefix,
14-
ReactHooksRules,
15-
ReactRules,
16-
RenamePrefix,
17-
RuleConfig,
18-
VitestRules,
19-
VueRules,
20-
YmlRules,
21-
} from '@antfu/eslint-define-config'
22-
import type { RuleOptions as JSDocRules } from '@eslint-types/jsdoc/types'
23-
import type { RuleOptions as TypeScriptRules } from '@eslint-types/typescript-eslint/types'
24-
import type { RuleOptions as UnicornRules } from '@eslint-types/unicorn/types'
25-
import type { Rules as AntfuRules } from 'eslint-plugin-antfu'
26-
import type { StylisticCustomizeOptions, UnprefixedRuleOptions as StylisticRules } from '@stylistic/eslint-plugin'
5+
import type { StylisticCustomizeOptions } from '@stylistic/eslint-plugin'
276
import type { VendoredPrettierOptions } from './vender/prettier-types'
28-
29-
export type WrapRuleConfig<T extends { [key: string]: any }> = {
30-
[K in keyof T]: T[K] extends RuleConfig ? T[K] : RuleConfig<T[K]>
31-
}
7+
import type { RulesOptions } from './typegen'
328

339
export type Awaitable<T> = T | Promise<T>
3410

35-
export type Rules = WrapRuleConfig<
36-
MergeIntersection<
37-
RenamePrefix<TypeScriptRules, '@typescript-eslint/', 'ts/'> &
38-
RenamePrefix<VitestRules, 'vitest/', 'test/'> &
39-
RenamePrefix<YmlRules, 'yml/', 'yaml/'> &
40-
RenamePrefix<NRules, 'n/', 'node/'> &
41-
Prefix<StylisticRules, 'style/'> &
42-
Prefix<AntfuRules, 'antfu/'> &
43-
ReactHooksRules &
44-
ReactRules &
45-
JSDocRules &
46-
ImportRules &
47-
EslintRules &
48-
JsoncRules &
49-
VueRules &
50-
UnicornRules &
51-
EslintCommentsRules &
52-
// TODO: TOML rules
53-
{
54-
'test/no-only-tests': RuleConfig<[]>
55-
}
56-
>
57-
>
58-
59-
export type FlatConfigItem = Omit<FlatESLintConfigItem<Rules, false>, 'plugins'> & {
11+
export type Rules = RulesOptions
12+
13+
export type FlatConfigItem = Omit<Linter.FlatConfig, 'plugins' | 'rules'> & {
6014
/**
6115
* Custom name of each config item
6216
*/
@@ -69,9 +23,14 @@
6923
* @see [Using plugins in your configuration](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#using-plugins-in-your-configuration)
7024
*/
7125
plugins?: Record<string, any>
72-
}
7326

74-
export type UserConfigItem = FlatConfigItem | Linter.FlatConfig
27+
/**
28+
* An object containing a name-value mapping of rules to use.
29+
*/
30+
rules?: {
31+
[key: string]: Linter.RuleEntry
32+
} & RulesOptions
33+
}
7534

7635
export interface OptionsFiles {
7736
/**

Diff for: ‎src/utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import process from 'node:process'
22
import { isPackageExists } from 'local-pkg'
3-
import type { Awaitable, UserConfigItem } from './types'
3+
import type { Awaitable, FlatConfigItem } from './types'
44

55
export const parserPlain = {
66
meta: {
@@ -26,7 +26,7 @@ export const parserPlain = {
2626
/**
2727
* Combine array and non-array configs into a single array.
2828
*/
29-
export async function combine(...configs: Awaitable<UserConfigItem | UserConfigItem[]>[]): Promise<UserConfigItem[]> {
29+
export async function combine(...configs: Awaitable<FlatConfigItem | FlatConfigItem[]>[]): Promise<FlatConfigItem[]> {
3030
const resolved = await Promise.all(configs)
3131
return resolved.flat()
3232
}
@@ -76,7 +76,7 @@ export function renameRules(rules: Record<string, any>, map: Record<string, stri
7676
* })
7777
* ```
7878
*/
79-
export function renamePluginInConfigs(configs: UserConfigItem[], map: Record<string, string>): UserConfigItem[] {
79+
export function renamePluginInConfigs(configs: FlatConfigItem[], map: Record<string, string>): FlatConfigItem[] {
8080
return configs.map((i) => {
8181
const clone = { ...i }
8282
if (clone.rules)

Diff for: ‎test/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { Linter } from 'eslint'
2+
import type { FlatConfigItem } from '../src';
3+
4+
// Make sure they are compatible
5+
((): Linter.FlatConfig => ({} as FlatConfigItem))();
6+
((): FlatConfigItem => ({} as Linter.FlatConfig))()

Diff for: ‎tsconfig.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"compilerOptions": {
3-
"target": "es2020",
3+
"target": "ESNext",
44
"baseUrl": ".",
5-
"module": "es2020",
5+
"module": "ESNext",
66
"moduleResolution": "Bundler",
77
"strict": true,
88
"esModuleInterop": true,

0 commit comments

Comments
 (0)
Please sign in to comment.