1- import { FlatCompat } from '@eslint/eslintrc' ;
21import js from '@eslint/js' ;
3- import tsEslintPlugin from '@typescript-eslint/eslint-plugin' ;
4- import { createRequire } from 'node:module' ;
5- import path from 'node:path' ;
6- import { fileURLToPath } from 'node:url' ;
2+ import { defineConfig } from 'eslint/config' ;
3+ import prettier from 'eslint-config-prettier' ;
4+ import jest from 'eslint-plugin-jest' ;
5+ import react from 'eslint-plugin-react' ;
6+ import reactHooks from 'eslint-plugin-react-hooks' ;
7+ import globals from 'globals' ;
8+ import tseslint from 'typescript-eslint' ;
79
8- const __filename = fileURLToPath ( import . meta. url ) ;
9- const __dirname = path . dirname ( __filename ) ;
10- const require = createRequire ( import . meta. url ) ;
11-
12- const compat = new FlatCompat ( {
13- baseDirectory : __dirname ,
14- recommendedConfig : js . configs . recommended ,
15- allConfig : js . configs . all ,
16- } ) ;
17-
18- const legacyConfig = require ( './.eslintrc.js' ) ;
19- const recommendedTsRulesConfig = tsEslintPlugin . configs . recommended ;
20- const recommendedTsRulesObject = Array . isArray ( recommendedTsRulesConfig )
21- ? recommendedTsRulesConfig . reduce ( ( rules , config ) => ( { ...rules , ...( config . rules || { } ) } ) , { } )
22- : recommendedTsRulesConfig ?. rules || { } ;
23- const recommendedTsRules = new Set ( Object . keys ( recommendedTsRulesObject ) ) ;
24-
25- function hasCurrentTsRule ( ruleName ) {
26- const tsRuleName = ruleName . replace ( '@typescript-eslint/' , '' ) ;
27- return Boolean ( tsEslintPlugin . rules [ tsRuleName ] ) ;
28- }
29- const localTsRules = new Set (
30- Object . keys ( legacyConfig . rules || { } ) . filter (
31- ( ruleName ) => ruleName . startsWith ( '@typescript-eslint/' ) && hasCurrentTsRule ( ruleName ) ,
32- ) ,
33- ) ;
34-
35- const noopRule = {
36- meta : { type : 'problem' , docs : { } , schema : [ ] } ,
37- create : ( ) => ( { } ) ,
38- } ;
39-
40- function normalizeConfig ( config ) {
41- const next = { ...config } ;
42-
43- if ( next . plugins ?. [ '@typescript-eslint' ] ) {
44- next . plugins = { ...next . plugins } ;
45- delete next . plugins [ '@typescript-eslint' ] ;
46- }
47-
48- if ( next . rules ) {
49- next . rules = Object . fromEntries (
50- Object . entries ( next . rules ) . filter ( ( [ ruleName ] ) => {
51- if ( ruleName . startsWith ( '@babel/' ) ) {
52- return false ;
53- }
54- if ( ! ruleName . startsWith ( '@typescript-eslint/' ) ) {
55- return true ;
56- }
57- return recommendedTsRules . has ( ruleName ) || localTsRules . has ( ruleName ) ;
58- } ) ,
59- ) ;
60- }
61-
62- return next ;
63- }
64-
65- export default [
10+ export default defineConfig ( [
11+ {
12+ plugins : {
13+ '@typescript-eslint' : tseslint . plugin ,
14+ } ,
15+ } ,
16+ {
17+ linterOptions : {
18+ reportUnusedDisableDirectives : 'off' ,
19+ } ,
20+ } ,
6621 {
6722 ignores : [
6823 'node_modules/' ,
@@ -74,27 +29,83 @@ export default [
7429 '.dumi/' ,
7530 '.doc/' ,
7631 '.vercel/' ,
77- '.eslintrc.js' ,
7832 'src/index.d.ts' ,
7933 ] ,
8034 } ,
8135 {
36+ files : [ '**/*.{js,jsx,ts,tsx}' ] ,
37+ extends : [
38+ js . configs . recommended ,
39+ react . configs . flat . recommended ,
40+ react . configs . flat [ 'jsx-runtime' ] ,
41+ prettier ,
42+ ] ,
8243 plugins : {
83- '@typescript-eslint' : {
84- ...tsEslintPlugin ,
85- rules : {
86- ...tsEslintPlugin . rules ,
87- 'consistent-type-exports' : noopRule ,
88- } ,
44+ 'react-hooks' : reactHooks ,
45+ } ,
46+ languageOptions : {
47+ globals : {
48+ ...globals . browser ,
49+ ...globals . node ,
50+ } ,
51+ } ,
52+ settings : {
53+ react : {
54+ version : 'detect' ,
8955 } ,
9056 } ,
57+ rules : {
58+ 'no-async-promise-executor' : 'off' ,
59+ 'no-empty-pattern' : 'off' ,
60+ 'no-irregular-whitespace' : 'off' ,
61+ 'no-prototype-builtins' : 'off' ,
62+ 'no-useless-escape' : 'off' ,
63+ 'no-extra-boolean-cast' : 'off' ,
64+ 'no-undef' : 'off' ,
65+ 'no-unused-vars' : 'off' ,
66+ 'react/no-find-dom-node' : 'off' ,
67+ 'react/display-name' : 'off' ,
68+ 'react/no-unknown-property' : 'off' ,
69+ 'react/prop-types' : 'off' ,
70+ 'react-hooks/exhaustive-deps' : 'warn' ,
71+ 'react-hooks/rules-of-hooks' : 'error' ,
72+ } ,
9173 } ,
92- ...compat . config ( legacyConfig ) . map ( normalizeConfig ) ,
9374 {
75+ files : [ '**/*.{ts,tsx}' ] ,
76+ extends : [ ...tseslint . configs . recommended ] ,
9477 rules : {
78+ '@typescript-eslint/ban-ts-comment' : 'off' ,
9579 '@typescript-eslint/no-empty-object-type' : 'off' ,
80+ '@typescript-eslint/no-explicit-any' : 'off' ,
9681 '@typescript-eslint/no-unsafe-function-type' : 'off' ,
82+ '@typescript-eslint/no-unnecessary-type-constraint' : 'off' ,
9783 '@typescript-eslint/no-unused-vars' : 'off' ,
9884 } ,
9985 } ,
100- ] ;
86+ {
87+ files : [ 'src/**/*.{ts,tsx}' ] ,
88+ languageOptions : {
89+ parserOptions : {
90+ projectService : true ,
91+ tsconfigRootDir : import . meta. dirname ,
92+ } ,
93+ } ,
94+ } ,
95+ {
96+ files : [ 'tests/**/*.{js,jsx,ts,tsx}' , '**/*.{test,spec}.{js,jsx,ts,tsx}' ] ,
97+ extends : [ jest . configs [ 'flat/recommended' ] ] ,
98+ rules : {
99+ 'jest/no-disabled-tests' : 'off' ,
100+ 'jest/no-done-callback' : 'off' ,
101+ 'jest/no-identical-title' : 'off' ,
102+ 'jest/expect-expect' : 'off' ,
103+ 'jest/no-alias-methods' : 'off' ,
104+ 'jest/no-conditional-expect' : 'off' ,
105+ 'jest/no-export' : 'off' ,
106+ 'jest/no-standalone-expect' : 'off' ,
107+ 'jest/valid-expect' : 'off' ,
108+ 'jest/valid-title' : 'off' ,
109+ } ,
110+ } ,
111+ ] ) ;
0 commit comments