@@ -7,7 +7,10 @@ import { defineConfig, globalIgnores } from "eslint/config";
77import _import from "eslint-plugin-import" ;
88import json from "eslint-plugin-json" ;
99import prettier from "eslint-plugin-prettier" ;
10+ import reactPlugin from "eslint-plugin-react" ;
11+ import reactHooksPlugin from "eslint-plugin-react-hooks" ;
1012import unusedImports from "eslint-plugin-unused-imports" ;
13+ import globals from "globals" ;
1114
1215import { readFileSync } from "fs" ;
1316import { dirname } from "node:path" ;
@@ -29,169 +32,201 @@ const prettierConfig = readFileSync(resolve(__dirname, "./.prettierrc.json"), "u
2932const prettierOptions = JSON . parse ( prettierConfig ) ;
3033const isProduction = process . env . NODE_ENV === "production" ;
3134
32- export default defineConfig ( [
33- {
34- extends : fixupConfigRules (
35- compat . extends (
36- "airbnb" ,
37- "prettier" ,
38- "plugin:import/recommended" ,
39- "plugin:@typescript-eslint/eslint-recommended" ,
40- "plugin:@typescript-eslint/recommended" ,
41- "plugin:@typescript-eslint/recommended-type-checked" ,
42- "plugin:@typescript-eslint/strict" ,
43- "plugin:@typescript-eslint/strict-type-checked" ,
44- "plugin:@typescript-eslint/stylistic" ,
45- "plugin:@typescript-eslint/stylistic-type-checked" ,
46- "plugin:import/typescript" ,
47- ) ,
48- ) ,
49-
50- plugins : {
51- json,
52- prettier,
53- "unused-imports" : unusedImports ,
54- import : fixupPluginRules ( _import ) ,
55- "@typescript-eslint" : fixupPluginRules ( typescriptEslint ) ,
35+ // ── Shared plugins ────────────────────────────────────────────────────────────
36+
37+ const sharedPlugins = {
38+ json,
39+ prettier,
40+ "unused-imports" : unusedImports ,
41+ import : fixupPluginRules ( _import ) ,
42+ "@typescript-eslint" : fixupPluginRules ( typescriptEslint ) ,
43+ } ;
44+
45+ const sharedParserOptions = {
46+ typescript : true ,
47+ experimentalDecorators : true ,
48+ requireConfigFile : false ,
49+ ecmaFeatures : { classes : true , impliedStrict : true } ,
50+ warnOnUnsupportedTypeScriptVersion : true ,
51+ } ;
52+
53+ // ── Shared rules applied to both packages ────────────────────────────────────
54+
55+ const sharedRules = {
56+ "no-console" : "error" ,
57+ "unused-imports/no-unused-imports" : "error" ,
58+ "prettier/prettier" : [ "error" , prettierOptions ] ,
59+ "@typescript-eslint/no-non-null-assertion" : "off" ,
60+ "@typescript-eslint/prefer-nullish-coalescing" : "off" ,
61+ "@typescript-eslint/use-unknown-in-catch-callback-variable" : "off" ,
62+ "@typescript-eslint/no-explicit-any" : "error" ,
63+ "@typescript-eslint/consistent-type-imports" : [ "error" , { fixStyle : "inline-type-imports" } ] ,
64+ "@typescript-eslint/no-misused-promises" : [ "error" , { checksVoidReturn : false } ] ,
65+ "@typescript-eslint/restrict-template-expressions" : [ "error" , { allowNumber : true } ] ,
66+ "@typescript-eslint/no-shadow" : [
67+ "error" ,
68+ {
69+ builtinGlobals : true ,
70+ allow : [ "location" , "event" , "history" , "name" , "status" , "Option" , "test" , "expect" , "jest" ] ,
5671 } ,
57-
58- languageOptions : {
59- parser : tsParser ,
60- sourceType : "module" ,
61- ecmaVersion : 2022 ,
62- parserOptions : {
63- project : resolve ( __dirname , "./tsconfig.json" ) ,
64- typescript : true ,
65- experimentalDecorators : true ,
66- requireConfigFile : false ,
67- ecmaFeatures : {
68- classes : true ,
69- impliedStrict : true ,
70- } ,
71- warnOnUnsupportedTypeScriptVersion : true ,
72- } ,
72+ ] ,
73+ } ;
74+
75+ // ── gas-benchmarks: Node.js, full airbnb + typescript ruleset ────────────────
76+
77+ const gasExtends = fixupConfigRules (
78+ compat . extends (
79+ "airbnb" ,
80+ "prettier" ,
81+ "plugin:import/recommended" ,
82+ "plugin:@typescript-eslint/eslint-recommended" ,
83+ "plugin:@typescript-eslint/recommended" ,
84+ "plugin:@typescript-eslint/recommended-type-checked" ,
85+ "plugin:@typescript-eslint/strict" ,
86+ "plugin:@typescript-eslint/strict-type-checked" ,
87+ "plugin:@typescript-eslint/stylistic" ,
88+ "plugin:@typescript-eslint/stylistic-type-checked" ,
89+ "plugin:import/typescript" ,
90+ ) ,
91+ ) ;
92+
93+ const gasConfig = {
94+ files : [ "gas-benchmarks/src/**/*.ts" ] ,
95+ extends : gasExtends ,
96+ plugins : sharedPlugins ,
97+ languageOptions : {
98+ parser : tsParser ,
99+ sourceType : "module" ,
100+ ecmaVersion : 2022 ,
101+ globals : globals . node ,
102+ parserOptions : {
103+ ...sharedParserOptions ,
104+ project : resolve ( __dirname , "./gas-benchmarks/tsconfig.json" ) ,
73105 } ,
74-
75- settings : {
76- react : {
77- version : "999.999.999" ,
106+ } ,
107+ settings : {
108+ react : { version : "999.999.999" } ,
109+ "import/resolver" : {
110+ typescript : { project : resolve ( __dirname , "./gas-benchmarks/tsconfig.json" ) } ,
111+ node : { extensions : [ ".ts" , ".js" ] , moduleDirectory : [ "node_modules" , "ts" , "src" ] } ,
112+ } ,
113+ } ,
114+ linterOptions : { reportUnusedDisableDirectives : isProduction } ,
115+ rules : {
116+ ...sharedRules ,
117+ "import/no-cycle" : [ "error" ] ,
118+ "import/no-extraneous-dependencies" : [
119+ "error" ,
120+ {
121+ devDependencies : [
122+ "**/*.test.ts" ,
123+ "**/__benchmarks__/**" ,
124+ "**/tests/**" ,
125+ "**/__tests__/**" ,
126+ "**/vitest.config.ts" ,
127+ ] ,
78128 } ,
79-
80- "import/resolver" : {
81- typescript : {
82- project : resolve ( __dirname , "./tsconfig.json" ) ,
83- } ,
84-
85- node : {
86- extensions : [ ".ts" , ".js" ] ,
87- moduleDirectory : [ "node_modules" , "ts" , "src" ] ,
88- } ,
129+ ] ,
130+ "no-debugger" : isProduction ? "error" : "off" ,
131+ "no-underscore-dangle" : "error" ,
132+ "no-redeclare" : [ "error" , { builtinGlobals : true } ] ,
133+ "import/order" : [
134+ "error" ,
135+ {
136+ groups : [ "external" , "builtin" , "internal" , "type" , "parent" , "sibling" , "index" , "object" ] ,
137+ alphabetize : { order : "asc" , caseInsensitive : true } ,
138+ warnOnUnassignedImports : true ,
139+ "newlines-between" : "always" ,
89140 } ,
141+ ] ,
142+ "import/prefer-default-export" : "off" ,
143+ "import/extensions" : [ "error" , { json : "always" } ] ,
144+ "class-methods-use-this" : "off" ,
145+ "prefer-promise-reject-errors" : "off" ,
146+ "max-classes-per-file" : "off" ,
147+ "no-use-before-define" : [ "off" ] ,
148+ "no-shadow" : "off" ,
149+ curly : [ "error" , "all" ] ,
150+ "no-return-await" : "off" ,
151+ "@typescript-eslint/explicit-member-accessibility" : [ "error" , { accessibility : "no-public" } ] ,
152+ "@typescript-eslint/explicit-module-boundary-types" : "error" ,
153+ "@typescript-eslint/no-use-before-define" : [ "error" , { functions : false , classes : false } ] ,
154+ } ,
155+ } ;
156+
157+ // ── project-evaluations: React + Browser, leaner typescript + prettier ruleset ──
158+
159+ const evalExtends = fixupConfigRules (
160+ compat . extends (
161+ "prettier" ,
162+ "plugin:react/recommended" ,
163+ "plugin:react-hooks/recommended" ,
164+ "plugin:@typescript-eslint/eslint-recommended" ,
165+ "plugin:@typescript-eslint/recommended" ,
166+ "plugin:@typescript-eslint/recommended-type-checked" ,
167+ "plugin:@typescript-eslint/strict" ,
168+ "plugin:@typescript-eslint/strict-type-checked" ,
169+ "plugin:@typescript-eslint/stylistic" ,
170+ "plugin:@typescript-eslint/stylistic-type-checked" ,
171+ ) ,
172+ ) ;
173+
174+ const evalConfig = {
175+ files : [ "project-evaluations/src/**/*.ts" , "project-evaluations/src/**/*.tsx" ] ,
176+ extends : evalExtends ,
177+ plugins : {
178+ prettier,
179+ "unused-imports" : unusedImports ,
180+ "@typescript-eslint" : fixupPluginRules ( typescriptEslint ) ,
181+ react : fixupPluginRules ( reactPlugin ) ,
182+ "react-hooks" : fixupPluginRules ( reactHooksPlugin ) ,
183+ } ,
184+ languageOptions : {
185+ parser : tsParser ,
186+ sourceType : "module" ,
187+ ecmaVersion : 2022 ,
188+ globals : globals . browser ,
189+ parserOptions : {
190+ ...sharedParserOptions ,
191+ project : resolve ( __dirname , "./project-evaluations/tsconfig.json" ) ,
90192 } ,
193+ } ,
194+ settings : {
195+ react : { version : "detect" } ,
196+ } ,
197+ linterOptions : { reportUnusedDisableDirectives : isProduction } ,
198+ rules : {
199+ ...sharedRules ,
200+ // Not needed with the new JSX transform (react-jsx).
201+ "react/react-in-jsx-scope" : "off" ,
202+ // TypeScript enforces prop types; PropTypes are redundant.
203+ "react/prop-types" : "off" ,
204+ // PropertyDefinition clashes with the DOM global of the same name.
205+ "@typescript-eslint/no-shadow" : [
206+ "error" ,
207+ {
208+ builtinGlobals : true ,
209+ allow : [
210+ "location" ,
211+ "event" ,
212+ "history" ,
213+ "name" ,
214+ "status" ,
215+ "Option" ,
216+ "test" ,
217+ "expect" ,
218+ "jest" ,
219+ "PropertyDefinition" ,
220+ ] ,
221+ } ,
222+ ] ,
223+ } ,
224+ } ;
91225
92- linterOptions : {
93- reportUnusedDisableDirectives : isProduction ,
94- } ,
226+ // ── Export ────────────────────────────────────────────────────────────────────
95227
96- rules : {
97- "import/no-cycle" : [ "error" ] ,
98- "unused-imports/no-unused-imports" : "error" ,
99- "import/no-extraneous-dependencies" : [
100- "error" ,
101- {
102- devDependencies : [
103- "**/*.test.ts" ,
104- "**/__benchmarks__/**" ,
105- "**/tests/**" ,
106- "**/__tests__/**" ,
107- "**/vitest.config.ts" ,
108- ] ,
109- } ,
110- ] ,
111- "no-debugger" : isProduction ? "error" : "off" ,
112- "no-console" : "error" ,
113- "no-underscore-dangle" : "error" ,
114- "no-redeclare" : [
115- "error" ,
116- {
117- builtinGlobals : true ,
118- } ,
119- ] ,
120- "import/order" : [
121- "error" ,
122- {
123- groups : [ "external" , "builtin" , "internal" , "type" , "parent" , "sibling" , "index" , "object" ] ,
124-
125- alphabetize : {
126- order : "asc" ,
127- caseInsensitive : true ,
128- } ,
129-
130- warnOnUnassignedImports : true ,
131- "newlines-between" : "always" ,
132- } ,
133- ] ,
134- "prettier/prettier" : [ "error" , prettierOptions ] ,
135- "import/prefer-default-export" : "off" ,
136- "import/extensions" : [
137- "error" ,
138- {
139- json : "always" ,
140- } ,
141- ] ,
142- "class-methods-use-this" : "off" ,
143- "prefer-promise-reject-errors" : "off" ,
144- "max-classes-per-file" : "off" ,
145- "no-use-before-define" : [ "off" ] ,
146- "no-shadow" : "off" ,
147- curly : [ "error" , "all" ] ,
148- "no-return-await" : "off" ,
149- "@typescript-eslint/explicit-member-accessibility" : [
150- "error" ,
151- {
152- accessibility : "no-public" ,
153- } ,
154- ] ,
155- "@typescript-eslint/no-non-null-assertion" : "off" ,
156- "@typescript-eslint/prefer-nullish-coalescing" : "off" ,
157- "@typescript-eslint/no-floating-promises" : "off" ,
158- "@typescript-eslint/use-unknown-in-catch-callback-variable" : "off" ,
159- "@typescript-eslint/no-explicit-any" : "error" ,
160- "@typescript-eslint/explicit-module-boundary-types" : "error" ,
161- "@typescript-eslint/consistent-type-imports" : [
162- "error" ,
163- {
164- fixStyle : "inline-type-imports" ,
165- } ,
166- ] ,
167- "@typescript-eslint/no-use-before-define" : [
168- "error" ,
169- {
170- functions : false ,
171- classes : false ,
172- } ,
173- ] ,
174- "@typescript-eslint/no-misused-promises" : [
175- "error" ,
176- {
177- checksVoidReturn : false ,
178- } ,
179- ] ,
180- "@typescript-eslint/no-shadow" : [
181- "error" ,
182- {
183- builtinGlobals : true ,
184-
185- allow : [ "location" , "event" , "history" , "name" , "status" , "Option" , "test" , "expect" , "jest" ] ,
186- } ,
187- ] ,
188- "@typescript-eslint/restrict-template-expressions" : [
189- "error" ,
190- {
191- allowNumber : true ,
192- } ,
193- ] ,
194- } ,
195- } ,
228+ export default defineConfig ( [
229+ gasConfig ,
230+ evalConfig ,
196231 globalIgnores ( [ "**/node_modules" , "**/dist" , "**/coverage" , "**/build" , "eslint.config.js" ] ) ,
197232] ) ;
0 commit comments