@boehringer-ingelheim/eslint-config 6.0.2 → 7.0.0-naming-convetion-configuration.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,29 +21,38 @@ npm install --save-dev @boehringer-ingelheim/eslint-config
21
21
 
22
22
  ### Add the configuration
23
23
 
24
- Create or update the `.eslintrc.js` file in your projects root directory accordingly.
24
+ Create or update the `eslint.config.mjs` (`eslint.config.cjs` is also possible if commonjs is preferred) file in your projects root directory accordingly.
25
25
 
26
26
  ```js
27
- module.exports = {
28
- extends: ['@boehringer-ingelheim/eslint-config/base/strict'],
29
- };
27
+ import boehringer from '@boehringer-ingelheim/eslint-config';
28
+
29
+ export default boehringer.config(
30
+ boehringer.configs.strict
31
+ )
30
32
  ```
31
33
 
34
+ #### `boehringer.config(...)`
35
+
36
+ This function is a re-export for the config-helper of typescript eslint (See [docs](https://github.com/typescript-eslint/typescript-eslint/blob/a383d5022b81eaf65ce7b0946491444c6eaa28e3/docs/packages/TypeScript_ESLint.mdx#config)).
37
+
32
38
  #### Extend or Override configuration
33
39
 
34
40
  This is not recommended as the goal is to have similar code stylings in all projects, but if for some reason you need to add or change the configuration, it is possible in the following way:
35
41
 
36
42
  ```js
37
- module.exports = {
38
- extends: ['@boehringer-ingelheim/eslint-config/base/strict'],
39
- rules: {
40
- 'no-empty-function': 'off',
41
- },
42
- };
43
+ import boehringer from '@boehringer-ingelheim/eslint-config';
44
+
45
+ export default boehringer.config(
46
+ boehringer.configs.strict,
47
+ {
48
+ rules: {
49
+ 'no-empty-function': 'off',
50
+ },
51
+ }
52
+ );
43
53
  ```
44
54
 
45
- More Information: [ESLint - Configuration Files
46
- ](https://eslint.org/docs/latest/use/configure/configuration-files#extending-configuration-files)
55
+ More Information: [ESLint - Configuration Files](https://eslint.org/docs/latest/use/configure/configuration-files#extending-configuration-files)
47
56
 
48
57
  ### Run
49
58
 
@@ -53,14 +62,16 @@ npx eslint .
53
62
 
54
63
  ## Shared Configurations
55
64
 
56
- Opinionated Options that differ from the standard/recommended eslint configurations.
65
+ Opinionated Options that differ from the standard/recommended ESLint configurations.
57
66
 
58
- ### `@boehringer-ingelheim/eslint-config/base`
67
+ ### Base
59
68
 
60
69
  ```js
61
- module.exports = {
62
- extends: ['@boehringer-ingelheim/eslint-config/base'],
63
- };
70
+ import boehringer from '@boehringer-ingelheim/eslint-config';
71
+
72
+ export default boehringer.config(
73
+ boehringer.configs.base
74
+ )
64
75
  ```
65
76
 
66
77
  This shared ESLint configuration is set up for TypeScript projects that adhere to modern JavaScript standards. It uses the latest version of TypeScript (ES2022) and extends several plugins and recommended rules to enforce best practices and catch potential errors.
@@ -73,60 +84,90 @@ The following plugins are used in this configuration:
73
84
 
74
85
  Additionally, the [`eslint-plugin-perfectionist`](https://github.com/azat-io/eslint-plugin-perfectionist) is used to automatically fix sorting issues.
75
86
 
76
- This configuration also sets up the TypeScript parser [`@typescript-eslint/parser`](https://typescript-eslint.io/architecture/parser) and [`eslint-import-resolver-typescript`](https://github.com/import-js/eslint-import-resolver-typescript). The TypeScript project file `./tsconfig.json` is set as default value for the project option in the parser configuration. If this is not the case, this must be changed accordingly:
87
+ This configuration also sets up the TypeScript parser [`@typescript-eslint/parser`](https://typescript-eslint.io/packages/parser/) and [`eslint-import-resolver-typescript`](https://github.com/import-js/eslint-import-resolver-typescript). The TypeScript project configuration file `./tsconfig.json` is set as default value in the parser configuration. If this is not the case, this must be changed accordingly:
77
88
 
78
89
  ```js
79
- module.exports = {
80
- parserOptions: {
81
- // Use `tsconfing.dev.json` as typescript project configuration, see: https://typescript-eslint.io/architecture/parser/#project
82
- project: './tsconfig.dev.json',
90
+ import boehringer from '@boehringer-ingelheim/eslint-config';
91
+
92
+ export default boehringer.config(boehringer.configs.base, {
93
+ languageOptions: {
94
+ parserOptions: {
95
+ projectService: {
96
+ defaultProject: ['./tsconfig.dev.json'],
97
+ },
98
+ },
83
99
  },
84
- };
100
+ });
85
101
  ```
86
102
 
87
- ### `@boehringer-ingelheim/eslint-config/base/local`
103
+ ### Local
88
104
 
89
105
  ```js
90
- module.exports = {
91
- extends: ['@boehringer-ingelheim/eslint-config/base/strict', '@boehringer-ingelheim/eslint-config/base/local'],
92
- };
106
+ import boehringer from '@boehringer-ingelheim/eslint-config';
107
+
108
+ export default boehringer.config(
109
+ boehringer.configs.base,
110
+ boehringer.configs.local
111
+ );
93
112
  ```
94
113
 
95
114
  This shared ESLint configuration configures or disables some rules for a better performance locally. With the help of [`is-ci`](https://www.npmjs.com/package/is-ci) those configs only apply to environments outside the CI pipelines.
96
115
 
97
- ### `@boehringer-ingelheim/eslint-config/base/strict`
116
+ ### Strict
98
117
 
99
118
  ```js
100
- module.exports = {
101
- extends: ['@boehringer-ingelheim/eslint-config/base/strict'],
102
- };
119
+ import boehringer from '@boehringer-ingelheim/eslint-config';
120
+
121
+ export default boehringer.config(
122
+ boehringer.configs.strict
123
+ );
103
124
  ```
104
125
 
105
- This shared ESLint configuration extends the `@boehringer-ingelheim/eslint-config/base` configuration and adds additional strict linting rules from the `@typescript-eslint/eslint-plugin` plugin. These strict rules aim to enforce a high standard of code quality and improve code maintainability.
126
+ This shared ESLint configuration extends the [base configuration](#base) and adds additional strict linting rules from the typescript-eslint plugin. These strict rules aim to enforce a high standard of code quality and improve code maintainability.
106
127
 
107
- ### `@boehringer-ingelheim/eslint-config/react`
128
+ ### React
108
129
 
109
130
  ```js
110
- module.exports = {
111
- extends: ['@boehringer-ingelheim/eslint-config/base/strict', '@boehringer-ingelheim/eslint-config/react'],
112
- };
131
+ import boehringer from '@boehringer-ingelheim/eslint-config';
132
+
133
+ export default boehringer.config(
134
+ boehringer.configs.strict,
135
+ boehringer.configs.react
136
+ );
113
137
  ```
114
138
 
115
- This shared ESLint configuration is specifically tailored for [React](https://reactjs.org/) projects, and extends `@boehringer-ingelheim/eslint-config/base`. It uses the browser environment, and includes recommended configurations for the following plugins:
139
+ This shared ESLint configuration is specifically tailored for [React](https://reactjs.org/) projects, and extends the [base configuration](#base). It uses the browser environment, and includes recommended configurations for the following plugins:
116
140
 
117
141
  - [`eslint-plugin-jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
118
142
  - [`eslint-plugin-react`](https://github.com/jsx-eslint/eslint-plugin-react)
119
143
  - [`eslint-plugin-react-hooks`](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks)
120
- - [`eslint-plugin-typescript-enum`](https://github.com/shian15810/eslint-plugin-typescript-enum)
144
+ - [`eslint-plugin-react-refresh`](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) (with rule severity `warn`)
145
+
146
+ The configuration sets several custom rules, including [`@typescript-eslint/no-restricted-types`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-restricted-types.mdx) and [`@typescript-eslint/consistent-type-definitions`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/consistent-type-definitions.mdx), as well as rules for organizing and formatting import statements.
147
+ Additionally in restricts the usage of enums using [`no-restricted-syntax`](https://github.com/eslint/eslint/blob/main/docs/src/rules/no-restricted-syntax.md).
148
+
149
+ ### Next.js
121
150
 
122
- The configuration sets several custom rules, including `@typescript-eslint/ban-types` and `@typescript-eslint/consistent-type-definitions`, as well as rules for organizing and formatting import statements.
151
+ ```js
152
+ import boehringer from '@boehringer-ingelheim/eslint-config';
153
+
154
+ export default boehringer.config(
155
+ boehringer.configs.strict,
156
+ boehringer.configs.nextjs
157
+ );
158
+ ```
123
159
 
124
- ### `@boehringer-ingelheim/eslint-config/playwright`
160
+ This shared ESLint configuration is specifically tailored for [Next.js](https://nextjs.org/) projects. It extends the [react configuration](#react) and includes the [`@next/eslint-plugin-next`](https://nextjs.org/docs/app/api-reference/config/eslint) plugin with the recommended and [`core-web-vital`](https://nextjs.org/docs/app/api-reference/config/eslint#with-core-web-vitals) rule set. The configuration also adapts the rule `react-refresh/only-export-components` to be compatible with Next.js.
161
+
162
+ ### Playwright
125
163
 
126
164
  ```js
127
- module.exports = {
128
- extends: ['@boehringer-ingelheim/eslint-config/base/strict', '@boehringer-ingelheim/eslint-config/playwright'],
129
- };
165
+ import boehringer from '@boehringer-ingelheim/eslint-config';
166
+
167
+ export default boehringer.config(
168
+ boehringer.configs.strict,
169
+ boehringer.configs.playwright
170
+ );
130
171
  ```
131
172
 
132
173
  This shared ESLint configuration is designed to enforce best practices and recommendations when writing tests with Playwright. It extends the [`eslint-plugin-playwright`](https://github.com/playwright-community/eslint-plugin-playwright) configuration and adds the following rules:
@@ -135,19 +176,34 @@ This shared ESLint configuration is designed to enforce best practices and recom
135
176
  - [`playwright/prefer-to-have-length`](https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/prefer-to-have-length.md): enforces the use of `.toHaveLength()` instead of `.toEqual(n)` when testing the length of an object.
136
177
  - [`playwright/require-top-level-describe`](https://github.com/playwright-community/eslint-plugin-playwright/blob/main/docs/rules/require-top-level-describe.md): requires tests to be organized into top-level `describe()` blocks.
137
178
 
138
- ### `@boehringer-ingelheim/eslint-config/prettier-disable`
179
+ ### Naming Convention
180
+
181
+ ```js
182
+ import boehringer from '@boehringer-ingelheim/eslint-config';
183
+
184
+ export default boehringer.config(
185
+ boehringer.configs.strict,
186
+ // possibly other configs,
187
+ boehringer.configs.namingConvention
188
+ );
189
+ ```
190
+
191
+ This shared ESLint configuration is designed to enforce some naming conventions. It uses the [`@typescript-eslint/naming-convention`](https://typescript-eslint.io/rules/naming-convention/) rule for enforcing the naming conventions. The enforced conventions can be found in [configs/naming-convention.js](./configs/naming-convention.js#L7-L65)
192
+
193
+ ### Prettier-disable
139
194
 
140
195
  ```js
141
- module.exports = {
142
- extends: [
143
- '@boehringer-ingelheim/eslint-config/base/strict',
144
- // Following needs eslint-plugin-prettier to be installed as described by https://github.com/prettier/eslint-plugin-prettier
145
- // Should be second to last
146
- 'plugin:prettier/recommended',
147
- // Should be last
148
- '@boehringer-ingelheim/eslint-config/prettier-disable'
149
- ],
150
- };
196
+ import boehringer from '@boehringer-ingelheim/eslint-config';
197
+ import prettier from 'eslint-plugin-prettier/recommended';
198
+
199
+ export default boehringer.config(
200
+ boehringer.configs.strict,
201
+ // Following needs eslint-plugin-prettier to be installed as described by https://github.com/prettier/eslint-plugin-prettier
202
+ // Should be second to last
203
+ prettier,
204
+ // Should be last
205
+ boehringer.configs.prettierDisable,
206
+ );
151
207
  ```
152
208
 
153
209
  This shared ESLint configuration is wrapper around [`eslint-config-disable`](https://github.com/prettier/eslint-config-prettier), which is used to turn off all rules that are unnecessary or might conflict with Prettier. This wrapper reenables a few rules that can be used with our shared configurations as we are using specific options of those rules which are compatible with Prettier (see [Special Rules](https://github.com/prettier/eslint-config-prettier#special-rules)). Following rules are reenabled:
@@ -155,6 +211,69 @@ This shared ESLint configuration is wrapper around [`eslint-config-disable`](htt
155
211
  - [`curly`](https://github.com/eslint/eslint/blob/main/docs/src/rules/curly.md) with the (default) option "all": Enforce consistent brace style for all control statements
156
212
  - [`no-confusing-arrow`](https://github.com/eslint/eslint/blob/main/docs/src/rules/no-confusing-arrow.md) with allowParens `false` and onlyOneSimpleParam `true`: Disallow arrow functions where they could be confused with comparisons.
157
213
 
214
+ ## Known issues
215
+
216
+ ### Parsing error
217
+
218
+ ESLint may throw the following error for some files (even for its own eslint.config.js): `ESLint was configured to run ... However, that TSConfig does not / none of those TSConfigs include this file`.
219
+
220
+ This error is caused by including the respective file in the scope of ESLint but not in the scope of TypeScript. For more information about this error and more suggestions how to solve it you can check the [FAQ of typescript-eslint](https://typescript-eslint.io/troubleshooting/typed-linting/#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file).
221
+
222
+ Our recommendation is to keep type-aware linting of those files.
223
+
224
+ #### Solution 1
225
+
226
+ Include the .(c|m)?js files in your main tsconfig.json:
227
+
228
+ ```json
229
+ {
230
+ "include": [
231
+ // your existing includes
232
+ "*.*js", // this will include all .js, .cjs, .mjs files and similar in your project root
233
+ "*.ts", // this will include all .ts files and similar in your project root
234
+ // Add all other files/folders in which this error occurs
235
+ ]
236
+ }
237
+ ```
238
+
239
+ #### Solution 2
240
+
241
+ Extend your main tsconfig.json in a tsconfig.eslint.json (or similar) which includes those files and ensures allowJs is set to true, which is used in a similar way by typescript-eslint in [their own repo](https://github.com/typescript-eslint/typescript-eslint/tree/v8.20.0):
242
+
243
+ ```json
244
+ {
245
+ "compilerOptions": {
246
+ "noEmit": true,
247
+ "allowJs": true
248
+ },
249
+ "extends": "./tsconfig.json",
250
+ "include": [
251
+ // you have to add here all the items from your original tsconfig.json as it overwrites the whole array
252
+ "*.*js", // this will include all .js, .cjs, .mjs files and similar in your project root
253
+ "*.ts", // this will include all .ts files and similar in your project root
254
+ // Add all other files/folders in which this error occurs
255
+ ]
256
+ }
257
+ ```
258
+
259
+ In this case you have to overwrite the configured tsconfig file:
260
+
261
+ ```js
262
+ import boehringer from '@boehringer-ingelheim/eslint-config';
263
+
264
+ export default boehringer.config(
265
+ // other configs,
266
+ {
267
+ languageOptions: {
268
+ parserOptions: {
269
+ project: './tsconfig.eslint.json',
270
+ tsconfigRootDir: __dirname,
271
+ },
272
+ },
273
+ },
274
+ )
275
+ ```
276
+
158
277
  ## Local Development
159
278
 
160
279
  ### Install Dependencies
@@ -202,7 +321,7 @@ npm run release
202
321
  - [ ] Shared configuration: Angular
203
322
  - [ ] Shared configuration: Node.js
204
323
  - [ ] Test Cases
205
- - [ ] "[Flat](https://eslint.org/docs/latest/use/configure/configuration-files-new)" Config
324
+ - [x] "[Flat](https://eslint.org/docs/latest/use/configure/configuration-files-new)" Config
206
325
 
207
326
  ## Show your support
208
327
 
@@ -210,7 +329,7 @@ Give a ⭐️ if this project helped you!
210
329
 
211
330
  ## License
212
331
 
213
- Copyright © 2023 [Boehringer Ingelheim](https://github.com/boehringer-ingelheim).<br />
332
+ Copyright © 2023 [Boehringer Ingelheim](https://github.com/boehringer-ingelheim).
214
333
  This project is [MIT](https://github.com/boehringer-ingelheim/eslint-config/blob/master/LICENSE) licensed.
215
334
 
216
335
  ## Resources
@@ -0,0 +1,148 @@
1
+ const eslint = require('@eslint/js');
2
+ const importPlugin = require('eslint-plugin-import');
3
+ const perfectionist = require('eslint-plugin-perfectionist');
4
+ const sonarjs = require('eslint-plugin-sonarjs');
5
+ const tseslint = require('typescript-eslint');
6
+
7
+ const {
8
+ SORT_CLASSES_GROUPS,
9
+ SORT_IMPORTS_GROUPS,
10
+ SORT_INTERSECTION_TYPES_GROUPS,
11
+ } = require('../lib/eslint-plugin-perfectionist.js');
12
+
13
+ module.exports = tseslint.config(
14
+ eslint.configs.recommended,
15
+ tseslint.configs.recommendedTypeChecked,
16
+ tseslint.configs.stylisticTypeChecked,
17
+ importPlugin.flatConfigs.recommended,
18
+ importPlugin.flatConfigs.typescript,
19
+ perfectionist.configs['recommended-natural'],
20
+ sonarjs.configs.recommended,
21
+ {
22
+ languageOptions: {
23
+ parserOptions: {
24
+ // find the tsconfig.json nearest each source file
25
+ projectService: true,
26
+ },
27
+ },
28
+ linterOptions: {
29
+ reportUnusedDisableDirectives: 'error',
30
+ },
31
+ rules: {
32
+ // @typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules
33
+ '@typescript-eslint/adjacent-overload-signatures': 'off', // disabled due to conflict with eslint-plugin-perfectionist
34
+ '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
35
+ '@typescript-eslint/no-misused-promises': [
36
+ 'error',
37
+ {
38
+ checksVoidReturn: false,
39
+ },
40
+ ],
41
+ '@typescript-eslint/no-unused-vars': [
42
+ 'error',
43
+ {
44
+ argsIgnorePattern: '^_',
45
+ caughtErrorsIgnorePattern: '^_',
46
+ varsIgnorePattern: '^_',
47
+ },
48
+ ],
49
+ '@typescript-eslint/sort-type-constituents': 'off', // disabled due to conflict with eslint-plugin-perfectionist
50
+
51
+ // eslint: https://github.com/eslint/eslint/tree/main/lib/rules
52
+ '@typescript-eslint/dot-notation': ['error', { allowPattern: '^[a-z]+(_[a-z]+)+$' }],
53
+ 'arrow-body-style': ['error', 'as-needed'],
54
+ camelcase: 'warn',
55
+ curly: 'error',
56
+ 'default-case': 'error',
57
+ eqeqeq: 'error',
58
+ 'logical-assignment-operators': ['error', 'never'],
59
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
60
+ 'no-else-return': ['error', { allowElseIf: false }],
61
+ 'no-empty-function': 'error',
62
+ 'no-lonely-if': 'error',
63
+ 'no-negated-condition': 'error',
64
+ 'no-nested-ternary': 'error',
65
+ 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
66
+ 'no-unneeded-ternary': 'error',
67
+ 'no-useless-concat': 'error',
68
+ 'operator-assignment': ['error', 'never'],
69
+ 'prefer-const': 'error',
70
+ 'prefer-rest-params': 'error',
71
+ 'prefer-template': 'error',
72
+ 'sort-imports': 'off', // disabled due to conflict with eslint-plugin-perfectionist
73
+ 'sort-keys': 'off', // disabled due to conflict with eslint-plugin-perfectionist
74
+
75
+ // eslint-plugin-import: https://github.com/import-js/eslint-plugin-import/tree/main/docs/rules
76
+ 'import/no-cycle': 'error',
77
+ 'import/no-unused-modules': [
78
+ 'error',
79
+ {
80
+ missingExports: true,
81
+ src: ['.'],
82
+ unusedExports: true,
83
+ },
84
+ ],
85
+ 'import/order': 'off', // disabled due to conflict with eslint-plugin-perfectionist
86
+ 'import/prefer-default-export': 'off',
87
+
88
+ // Deactivated as TypeScript provides the same checks as part of standard type checking: https://typescript-eslint.io/linting/troubleshooting/performance-troubleshooting
89
+ 'import/default': 'off',
90
+ 'import/named': 'off',
91
+ 'import/namespace': 'off',
92
+ 'import/no-named-as-default-member': 'off',
93
+
94
+ // eslint-plugin-perfectionist: https://github.com/azat-io/eslint-plugin-perfectionist
95
+ 'perfectionist/sort-classes': [
96
+ 'error',
97
+ {
98
+ ...perfectionist.configs['recommended-natural'].rules['perfectionist/sort-classes'][1],
99
+ groups: SORT_CLASSES_GROUPS,
100
+ },
101
+ ],
102
+ 'perfectionist/sort-imports': [
103
+ 'error',
104
+ {
105
+ ...perfectionist.configs['recommended-natural'].rules['perfectionist/sort-imports'][1],
106
+ groups: SORT_IMPORTS_GROUPS,
107
+ newlinesBetween: 'ignore',
108
+ },
109
+ ],
110
+ 'perfectionist/sort-intersection-types': [
111
+ 'error',
112
+ {
113
+ ...perfectionist.configs['recommended-natural'].rules['perfectionist/sort-intersection-types'][1],
114
+ groups: SORT_INTERSECTION_TYPES_GROUPS,
115
+ },
116
+ ],
117
+ 'perfectionist/sort-named-imports': [
118
+ 'error',
119
+ {
120
+ ...perfectionist.configs['recommended-natural'].rules['perfectionist/sort-named-imports'][1],
121
+ ignoreAlias: true,
122
+ },
123
+ ],
124
+ 'perfectionist/sort-objects': [
125
+ 'error',
126
+ {
127
+ ...perfectionist.configs['recommended-natural'].rules['perfectionist/sort-objects'][1],
128
+ partitionByComment: true,
129
+ },
130
+ ],
131
+ },
132
+ settings: {
133
+ 'import/resolver': {
134
+ typescript: true,
135
+ },
136
+ },
137
+ },
138
+ {
139
+ files: [
140
+ '**/*.d.ts', // TypeScript declaration files
141
+ '**/*.{spec,test}.*', // Usually test files
142
+ './*.{js,cjs,mjs,ts,cts,mts}', // Mostly configuration files on root level
143
+ ],
144
+ rules: {
145
+ 'import/no-unused-modules': 'off',
146
+ },
147
+ },
148
+ );
@@ -0,0 +1,16 @@
1
+ const isCI = require('is-ci');
2
+ const tseslint = require('typescript-eslint');
3
+
4
+ module.exports = tseslint.config(
5
+ isCI
6
+ ? {}
7
+ : {
8
+ rules: {
9
+ // Only activate in CI, as suggested here: https://typescript-eslint.io/linting/troubleshooting/performance-troubleshooting#eslint-plugin-import
10
+ 'import/no-cycle': 'off',
11
+ 'import/no-deprecated': 'off',
12
+ 'import/no-named-as-default': 'off',
13
+ 'import/no-unused-modules': 'off',
14
+ },
15
+ },
16
+ );
@@ -0,0 +1,68 @@
1
+ const tseslint = require('typescript-eslint');
2
+
3
+ module.exports = tseslint.config({
4
+ rules: {
5
+ '@typescript-eslint/naming-convention': [
6
+ 'error',
7
+ {
8
+ // Enforce that interface names do not start with an 'I'
9
+ custom: {
10
+ match: false,
11
+ regex: '^I[A-Z]',
12
+ },
13
+ format: ['StrictPascalCase'],
14
+ leadingUnderscore: 'forbid',
15
+ selector: 'interface',
16
+ trailingUnderscore: 'forbid',
17
+ },
18
+ {
19
+ // Enforce that type alias names do not start with an 'T'
20
+ custom: {
21
+ match: false,
22
+ regex: '^T[A-Z]',
23
+ },
24
+ format: ['StrictPascalCase'],
25
+ leadingUnderscore: 'forbid',
26
+ selector: 'typeAlias',
27
+ trailingUnderscore: 'forbid',
28
+ },
29
+ {
30
+ // Enforce that all top-level variables are in UPPER_CASE
31
+ format: ['UPPER_CASE'],
32
+ leadingUnderscore: 'forbid',
33
+ modifiers: ['global'],
34
+ selector: 'variable',
35
+ trailingUnderscore: 'forbid',
36
+ types: ['boolean', 'number', 'string'],
37
+ },
38
+ {
39
+ // Enforce that all top-level array variables are in UPPER_CASE and are suffixed with a 'S' to indicate plural form
40
+ format: ['UPPER_CASE'],
41
+ leadingUnderscore: 'forbid',
42
+ modifiers: ['global'],
43
+ selector: 'variable',
44
+ suffix: ['S'],
45
+ trailingUnderscore: 'forbid',
46
+ types: ['array'],
47
+ },
48
+ {
49
+ // Enforce that array variables are suffixed with a 's' to indicate plural form
50
+ format: ['strictCamelCase'],
51
+ leadingUnderscore: 'forbid',
52
+ selector: 'variable',
53
+ suffix: ['s'],
54
+ trailingUnderscore: 'forbid',
55
+ types: ['array'],
56
+ },
57
+ {
58
+ // Enforce that boolean variables are prefixed with an allowed verb
59
+ format: ['StrictPascalCase'],
60
+ leadingUnderscore: 'forbid',
61
+ prefix: ['is', 'has', 'should', 'can'],
62
+ selector: 'variable',
63
+ trailingUnderscore: 'forbid',
64
+ types: ['boolean'],
65
+ },
66
+ ],
67
+ },
68
+ });
@@ -0,0 +1,46 @@
1
+ const nextPlugin = require('@next/eslint-plugin-next');
2
+ const tseslint = require('typescript-eslint');
3
+
4
+ const react = require('./react.js');
5
+
6
+ module.exports = tseslint.config(
7
+ ...react,
8
+ {
9
+ plugins: {
10
+ '@next/next': nextPlugin,
11
+ },
12
+ rules: {
13
+ // eslint-plugin-react-refresh: https://github.com/ArnaudBarre/eslint-plugin-react-refresh
14
+ 'react-refresh/only-export-components': [
15
+ 'warn',
16
+ {
17
+ /**
18
+ * Next.js allows exporting the following options in pages, layouts and route handlers
19
+ *
20
+ * @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
21
+ */
22
+ allowExportNames: [
23
+ 'config',
24
+ 'dynamic',
25
+ 'dynamicParams',
26
+ 'fetchCache',
27
+ 'generateMetadata',
28
+ 'generateStaticParams',
29
+ 'generateViewport',
30
+ 'maxDuration',
31
+ 'metadata',
32
+ 'preferredRegion',
33
+ 'revalidate',
34
+ 'runtime',
35
+ 'viewport',
36
+ ],
37
+ },
38
+ ],
39
+ ...nextPlugin.configs.recommended.rules,
40
+ ...nextPlugin.configs['core-web-vitals'].rules,
41
+ },
42
+ },
43
+ {
44
+ ignores: ['.next/*'],
45
+ },
46
+ );
@@ -0,0 +1,13 @@
1
+ const playwright = require('eslint-plugin-playwright');
2
+ const tseslint = require('typescript-eslint');
3
+
4
+ module.exports = tseslint.config({
5
+ ...playwright.configs['flat/recommended'],
6
+ rules: {
7
+ ...playwright.configs['flat/recommended'].rules,
8
+ // eslint-plugin-playwright: https://github.com/playwright-community/eslint-plugin-playwright
9
+ 'playwright/prefer-to-be': 'error',
10
+ 'playwright/prefer-to-have-length': 'error',
11
+ 'playwright/require-top-level-describe': 'error',
12
+ },
13
+ });
@@ -0,0 +1,10 @@
1
+ const prettier = require('eslint-config-prettier');
2
+ const tseslint = require('typescript-eslint');
3
+
4
+ module.exports = tseslint.config({
5
+ ...prettier,
6
+ rules: {
7
+ ...prettier.rules,
8
+ curly: 'error',
9
+ },
10
+ });
@@ -0,0 +1,108 @@
1
+ const jsxA11y = require('eslint-plugin-jsx-a11y');
2
+ const react = require('eslint-plugin-react');
3
+ const reactHooks = require('eslint-plugin-react-hooks');
4
+ const reactRefresh = require('eslint-plugin-react-refresh');
5
+ const globals = require('globals');
6
+ const tseslint = require('typescript-eslint');
7
+
8
+ const { SORT_IMPORTS_GROUPS } = require('../lib/eslint-plugin-perfectionist.js');
9
+ const base = require('./base.js');
10
+
11
+ module.exports = tseslint.config(
12
+ ...base,
13
+ jsxA11y.flatConfigs.recommended,
14
+ react.configs.flat.recommended,
15
+ react.configs.flat['jsx-runtime'],
16
+ reactRefresh.configs.recommended,
17
+ {
18
+ languageOptions: {
19
+ globals: {
20
+ ...globals.browser,
21
+ },
22
+ parserOptions: {
23
+ ecmaFeatures: {
24
+ jsx: true,
25
+ },
26
+ },
27
+ },
28
+ plugins: {
29
+ 'react-hooks': reactHooks,
30
+ },
31
+ rules: {
32
+ // @typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules
33
+ '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
34
+ '@typescript-eslint/no-restricted-types': [
35
+ 'error',
36
+ {
37
+ types: {
38
+ 'React.FC': {
39
+ message:
40
+ 'Please use object type destructure declaration, see: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components',
41
+ },
42
+ 'React.FunctionalComponent': {
43
+ message:
44
+ 'Please use object type destructure declaration, see: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components',
45
+ },
46
+ },
47
+ },
48
+ ],
49
+
50
+ // eslint-plugin-react: https://github.com/jsx-eslint/eslint-plugin-react/tree/master/lib/rules
51
+ 'react/jsx-pascal-case': 'error',
52
+ 'react/jsx-sort-props': 'off', // disabled due to conflict with eslint-plugin-perfectionist
53
+ 'react/sort-default-props': 'error',
54
+
55
+ // eslint-plugin-react-hooks: https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md
56
+ 'react-hooks/exhaustive-deps': 'error',
57
+ 'react-hooks/rules-of-hooks': 'error',
58
+
59
+ // eslint-plugin-perfectionist: https://github.com/azat-io/eslint-plugin-perfectionist
60
+ 'perfectionist/sort-imports': [
61
+ 'error',
62
+ {
63
+ customGroups: {
64
+ type: {
65
+ react: ['react'],
66
+ },
67
+ value: {
68
+ react: ['react'],
69
+ },
70
+ },
71
+ groups: ['react', ...SORT_IMPORTS_GROUPS],
72
+ ignoreCase: true,
73
+ newlinesBetween: 'ignore',
74
+ type: 'natural',
75
+ },
76
+ ],
77
+ 'perfectionist/sort-jsx-props': [
78
+ 'error',
79
+ {
80
+ customGroups: {
81
+ callback: '^on.+',
82
+ reservedProps: ['children', 'dangerouslySetInnerHTML', 'key', 'ref'], // Reserved props from: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/lib/rules/jsx-sort-props.js#L41-L46
83
+ },
84
+ groups: ['reservedProps', 'unknown', 'callback'],
85
+ ignoreCase: true,
86
+ type: 'natural',
87
+ },
88
+ ],
89
+
90
+ // eslint-plugin-react-refresh: https://github.com/ArnaudBarre/eslint-plugin-react-refresh
91
+ 'react-refresh/only-export-components': 'warn',
92
+
93
+ // Forbid enum declaration
94
+ 'no-restricted-syntax': [
95
+ 'error',
96
+ {
97
+ message: "Don't declare enums",
98
+ selector: 'TSEnumDeclaration',
99
+ },
100
+ ],
101
+ },
102
+ settings: {
103
+ react: {
104
+ version: 'detect',
105
+ },
106
+ },
107
+ },
108
+ );
@@ -1,14 +1,8 @@
1
- /**
2
- * Workaround to allow ESLint to resolve plugins that were installed
3
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
4
- */
5
- require('@rushstack/eslint-patch/modern-module-resolution');
1
+ const tseslint = require('typescript-eslint');
6
2
 
7
- const typescriptEslintPlugin = require('@typescript-eslint/eslint-plugin');
3
+ const base = require('./base.js');
8
4
 
9
- /** @type {import('eslint').ESLint.ConfigData} */
10
- module.exports = {
11
- extends: ['./index.js', 'plugin:@typescript-eslint/strict-type-checked'],
5
+ module.exports = tseslint.config(...base, tseslint.configs.strictTypeChecked, {
12
6
  rules: {
13
7
  // @typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules
14
8
  '@typescript-eslint/consistent-type-imports': 'error',
@@ -16,7 +10,7 @@ module.exports = {
16
10
  '@typescript-eslint/restrict-template-expressions': [
17
11
  'error',
18
12
  {
19
- ...typescriptEslintPlugin.rules['restrict-template-expressions'].meta.docs.recommended.strict[0],
13
+ ...tseslint.plugin.rules['restrict-template-expressions'].meta.docs.recommended.strict[0],
20
14
  allowNumber: true,
21
15
  },
22
16
  ],
@@ -24,4 +18,4 @@ module.exports = {
24
18
  // eslint-plugin-import: https://github.com/import-js/eslint-plugin-import/tree/main/docs/rules
25
19
  'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
26
20
  },
27
- };
21
+ });
package/index.js ADDED
@@ -0,0 +1,24 @@
1
+ const tseslint = require('typescript-eslint');
2
+
3
+ const base = require('./configs/base.js');
4
+ const local = require('./configs/local.js');
5
+ const namingConvention = require('./configs/naming-convention.js');
6
+ const nextjs = require('./configs/nextjs.js');
7
+ const playwright = require('./configs/playwright.js');
8
+ const prettierDisable = require('./configs/prettier-disable.js');
9
+ const react = require('./configs/react.js');
10
+ const strict = require('./configs/strict.js');
11
+
12
+ module.exports = {
13
+ config: tseslint.config,
14
+ configs: {
15
+ base,
16
+ local,
17
+ namingConvention,
18
+ nextjs,
19
+ playwright,
20
+ prettierDisable,
21
+ react,
22
+ strict,
23
+ },
24
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boehringer-ingelheim/eslint-config",
3
- "version": "6.0.2",
3
+ "version": "7.0.0-naming-convetion-configuration.1",
4
4
  "description": "Shared eslint configuration used at Boehringer Ingelheim for code styling",
5
5
  "keywords": [
6
6
  "boehringer",
@@ -14,49 +14,47 @@
14
14
  ],
15
15
  "license": "MIT",
16
16
  "files": [
17
- "base",
18
- "lib",
19
- "react",
20
- "playwright",
21
- "prettier-disable"
17
+ "configs",
18
+ "lib"
22
19
  ],
23
- "main": "base/index.js",
20
+ "main": "index.js",
24
21
  "scripts": {
25
22
  "prepare": "husky",
26
23
  "release": "dotenv -- semantic-release --no-ci",
27
24
  "release:ci": "semantic-release",
28
- "repair": "npx --no rimraf .git/hooks node_modules package-lock.json && npm install"
25
+ "repair": "npx --no rimraf@6 .git/hooks node_modules package-lock.json && npm install",
26
+ "lint": "eslint ."
29
27
  },
30
28
  "peerDependencies": {
31
- "eslint": "^8.57.1"
29
+ "eslint": ">= 8"
32
30
  },
33
31
  "dependencies": {
34
- "@rushstack/eslint-patch": "^1.10.4",
35
- "@typescript-eslint/eslint-plugin": "^8.18.0",
36
- "@typescript-eslint/parser": "^8.18.0",
37
- "eslint-config-prettier": "^9.1.0",
32
+ "@eslint/js": "^9.18.0",
33
+ "@next/eslint-plugin-next": "^15.1.4",
34
+ "eslint-config-prettier": "^10.0.1",
38
35
  "eslint-import-resolver-typescript": "^3.7.0",
39
36
  "eslint-plugin-import": "^2.31.0",
40
37
  "eslint-plugin-jsx-a11y": "^6.10.2",
41
- "eslint-plugin-perfectionist": "^4.3.0",
38
+ "eslint-plugin-perfectionist": "^4.6.0",
42
39
  "eslint-plugin-playwright": "^2.1.0",
43
- "eslint-plugin-react": "^7.37.2",
40
+ "eslint-plugin-react": "^7.37.4",
44
41
  "eslint-plugin-react-hooks": "^5.1.0",
45
- "eslint-plugin-react-refresh": "^0.4.16",
42
+ "eslint-plugin-react-refresh": "^0.4.18",
46
43
  "eslint-plugin-sonarjs": "^1.0.4",
47
- "eslint-plugin-typescript-enum": "^2.1.0",
48
- "is-ci": "^4.1.0"
44
+ "globals": "^15.14.0",
45
+ "is-ci": "^4.1.0",
46
+ "typescript-eslint": "^8.20.0"
49
47
  },
50
48
  "devDependencies": {
51
49
  "@boehringer-ingelheim/prettier-config": "2.0.0",
52
- "@commitlint/cli": "19.6.0",
50
+ "@commitlint/cli": "19.6.1",
53
51
  "@commitlint/config-conventional": "19.6.0",
54
52
  "@commitlint/types": "19.5.0",
55
53
  "@semantic-release/changelog": "6.0.3",
56
54
  "@semantic-release/git": "10.0.1",
57
- "dotenv-cli": "7.4.4",
55
+ "dotenv-cli": "8.0.0",
58
56
  "husky": "9.1.7",
59
57
  "prettier": "3.4.2",
60
- "semantic-release": "24.2.0"
58
+ "semantic-release": "24.2.1"
61
59
  }
62
60
  }
package/base/index.js DELETED
@@ -1,156 +0,0 @@
1
- const {
2
- SORT_CLASSES_GROUPS,
3
- SORT_IMPORTS_GROUPS,
4
- SORT_INTERSECTION_TYPES_GROUPS,
5
- } = require('../lib/eslint-plugin-perfectionist');
6
-
7
- /**
8
- * Workaround to allow ESLint to resolve plugins that were installed
9
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
10
- */
11
- require('@rushstack/eslint-patch/modern-module-resolution');
12
- const eslintPluginPerfectionist = require('eslint-plugin-perfectionist');
13
-
14
- /** @type {import('eslint').ESLint.ConfigData & { parserOptions: import('eslint').ESLint.ConfigData['parserOptions'] & import('@typescript-eslint/parser').ParserOptions } } */
15
- module.exports = {
16
- env: {
17
- es2022: true,
18
- },
19
- extends: [
20
- 'eslint:recommended',
21
- 'plugin:@typescript-eslint/recommended-type-checked',
22
- 'plugin:@typescript-eslint/stylistic-type-checked',
23
- 'plugin:import/recommended',
24
- 'plugin:import/typescript',
25
- 'plugin:perfectionist/recommended-natural-legacy',
26
- 'plugin:sonarjs/recommended-legacy',
27
- ],
28
- overrides: [
29
- {
30
- files: [
31
- '**/*.d.ts', // TypeScript declaration files
32
- '**/*.{spec,test}.*', // Usually test files
33
- './*.{js,cjs,mjs,ts,cts,mts}', // Mostly configuration files on root level
34
- ],
35
- rules: {
36
- 'import/no-unused-modules': 'off',
37
- },
38
- },
39
- ],
40
- parser: '@typescript-eslint/parser',
41
- parserOptions: {
42
- // find the tsconfig.json nearest each source file
43
- project: true,
44
- },
45
- plugins: ['@typescript-eslint', 'sonarjs'],
46
- // Warn about unused eslint-disable directives
47
- reportUnusedDisableDirectives: true,
48
- rules: {
49
- // @typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules
50
- '@typescript-eslint/adjacent-overload-signatures': 'off', // disabled due to conflict with eslint-plugin-perfectionist
51
- '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
52
- '@typescript-eslint/no-misused-promises': [
53
- 'error',
54
- {
55
- checksVoidReturn: false,
56
- },
57
- ],
58
- '@typescript-eslint/no-unused-vars': [
59
- 'error',
60
- {
61
- argsIgnorePattern: '^_',
62
- caughtErrorsIgnorePattern: '^_',
63
- varsIgnorePattern: '^_',
64
- },
65
- ],
66
- '@typescript-eslint/sort-type-constituents': 'off', // disabled due to conflict with eslint-plugin-perfectionist
67
-
68
- // eslint: https://github.com/eslint/eslint/tree/main/lib/rules
69
- '@typescript-eslint/dot-notation': ['error', { allowPattern: '^[a-z]+(_[a-z]+)+$' }],
70
- 'arrow-body-style': ['error', 'as-needed'],
71
- camelcase: 'warn',
72
- curly: 'error',
73
- 'default-case': 'error',
74
- eqeqeq: 'error',
75
- 'logical-assignment-operators': ['error', 'never'],
76
- 'no-console': ['warn', { allow: ['warn', 'error'] }],
77
- 'no-else-return': ['error', { allowElseIf: false }],
78
- 'no-empty-function': 'error',
79
- 'no-lonely-if': 'error',
80
- 'no-negated-condition': 'error',
81
- 'no-nested-ternary': 'error',
82
- 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
83
- 'no-unneeded-ternary': 'error',
84
- 'no-useless-concat': 'error',
85
- 'operator-assignment': ['error', 'never'],
86
- 'prefer-const': 'error',
87
- 'prefer-rest-params': 'error',
88
- 'prefer-template': 'error',
89
- 'sort-imports': 'off', // disabled due to conflict with eslint-plugin-perfectionist
90
- 'sort-keys': 'off', // disabled due to conflict with eslint-plugin-perfectionist
91
-
92
- // eslint-plugin-import: https://github.com/import-js/eslint-plugin-import/tree/main/docs/rules
93
- 'import/no-cycle': 'error',
94
- 'import/no-unused-modules': [
95
- 'error',
96
- {
97
- missingExports: true,
98
- src: ['.'],
99
- unusedExports: true,
100
- },
101
- ],
102
- 'import/order': 'off', // disabled due to conflict with eslint-plugin-perfectionist
103
- 'import/prefer-default-export': 'off',
104
-
105
- // Deactivated as TypeScript provides the same checks as part of standard type checking: https://typescript-eslint.io/linting/troubleshooting/performance-troubleshooting
106
- 'import/default': 'off',
107
- 'import/named': 'off',
108
- 'import/namespace': 'off',
109
- 'import/no-named-as-default-member': 'off',
110
-
111
- // eslint-plugin-perfectionist: https://github.com/azat-io/eslint-plugin-perfectionist
112
- 'perfectionist/sort-classes': [
113
- 'error',
114
- {
115
- ...eslintPluginPerfectionist.configs['recommended-natural-legacy'].rules['perfectionist/sort-classes'][1],
116
- groups: SORT_CLASSES_GROUPS,
117
- },
118
- ],
119
- 'perfectionist/sort-imports': [
120
- 'error',
121
- {
122
- ...eslintPluginPerfectionist.configs['recommended-natural-legacy'].rules['perfectionist/sort-imports'][1],
123
- groups: SORT_IMPORTS_GROUPS,
124
- newlinesBetween: 'ignore',
125
- },
126
- ],
127
- 'perfectionist/sort-intersection-types': [
128
- 'error',
129
- {
130
- ...eslintPluginPerfectionist.configs['recommended-natural-legacy'].rules[
131
- 'perfectionist/sort-intersection-types'
132
- ][1],
133
- groups: SORT_INTERSECTION_TYPES_GROUPS,
134
- },
135
- ],
136
- 'perfectionist/sort-named-imports': [
137
- 'error',
138
- {
139
- ...eslintPluginPerfectionist.configs['recommended-natural-legacy'].rules['perfectionist/sort-named-imports'][1],
140
- ignoreAlias: true,
141
- },
142
- ],
143
- 'perfectionist/sort-objects': [
144
- 'error',
145
- {
146
- ...eslintPluginPerfectionist.configs['recommended-natural-legacy'].rules['perfectionist/sort-objects'][1],
147
- partitionByComment: true,
148
- },
149
- ],
150
- },
151
- settings: {
152
- 'import/resolver': {
153
- typescript: true,
154
- },
155
- },
156
- };
package/base/local.js DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * Workaround to allow ESLint to resolve plugins that were installed
3
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
4
- */
5
- require('@rushstack/eslint-patch/modern-module-resolution');
6
-
7
- const isCI = require('is-ci');
8
-
9
- /** @type {import('eslint').ESLint.ConfigData} */
10
- module.exports = {
11
- rules: isCI
12
- ? {}
13
- : {
14
- // Only activate in CI, as suggested here: https://typescript-eslint.io/linting/troubleshooting/performance-troubleshooting#eslint-plugin-import
15
- 'import/no-cycle': 'off',
16
- 'import/no-deprecated': 'off',
17
- 'import/no-named-as-default': 'off',
18
- 'import/no-unused-modules': 'off',
19
- },
20
- };
@@ -1,16 +0,0 @@
1
- /**
2
- * Workaround to allow ESLint to resolve plugins that were installed
3
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
4
- */
5
- require('@rushstack/eslint-patch/modern-module-resolution');
6
-
7
- /** @type {import('eslint').ESLint.ConfigData} */
8
- module.exports = {
9
- extends: ['plugin:playwright/playwright-test'],
10
- rules: {
11
- // eslint-plugin-playwright: https://github.com/playwright-community/eslint-plugin-playwright
12
- 'playwright/prefer-to-be': 'error',
13
- 'playwright/prefer-to-have-length': 'error',
14
- 'playwright/require-top-level-describe': 'error',
15
- },
16
- };
@@ -1,13 +0,0 @@
1
- /**
2
- * Workaround to allow ESLint to resolve plugins that were installed
3
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
4
- */
5
- require('@rushstack/eslint-patch/modern-module-resolution');
6
-
7
- /** @type {import('eslint').ESLint.ConfigData & { parserOptions: import('eslint').ESLint.ConfigData['parserOptions'] & import('@typescript-eslint/parser').ParserOptions } } */
8
- module.exports = {
9
- extends: ['prettier'],
10
- rules: {
11
- curly: 'error',
12
- },
13
- };
package/react/index.js DELETED
@@ -1,96 +0,0 @@
1
- const { SORT_IMPORTS_GROUPS } = require('../lib/eslint-plugin-perfectionist');
2
-
3
- /**
4
- * Workaround to allow ESLint to resolve plugins that were installed
5
- * by an external config, see https://github.com/eslint/eslint/issues/3458.
6
- */
7
- require('@rushstack/eslint-patch/modern-module-resolution');
8
-
9
- /** @type {import('eslint').ESLint.ConfigData & { parserOptions: import('eslint').ESLint.ConfigData['parserOptions'] & import('@typescript-eslint/parser').ParserOptions } } */
10
- module.exports = {
11
- env: {
12
- browser: true,
13
- },
14
- extends: [
15
- '../base/index.js',
16
- 'plugin:jsx-a11y/recommended',
17
- 'plugin:react/recommended',
18
- 'plugin:react/jsx-runtime',
19
- 'plugin:typescript-enum/recommended',
20
- ],
21
- parserOptions: {
22
- ecmaFeatures: {
23
- jsx: true,
24
- },
25
- ecmaVersion: 'latest',
26
- sourceType: 'module',
27
- },
28
- plugins: ['jsx-a11y', 'react', 'react-hooks', 'react-refresh', 'typescript-enum'],
29
- rules: {
30
- // @typescript-eslint: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules
31
- '@typescript-eslint/no-restricted-types': [
32
- 'error',
33
- {
34
- types: {
35
- 'React.FC': {
36
- message:
37
- 'Please use object type destructure declaration, see: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components',
38
- },
39
- 'React.FunctionalComponent': {
40
- message:
41
- 'Please use object type destructure declaration, see: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components',
42
- },
43
- },
44
- },
45
- ],
46
- '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
47
-
48
- // eslint-plugin-react: https://github.com/jsx-eslint/eslint-plugin-react/tree/master/lib/rules
49
- 'react/jsx-pascal-case': 'error',
50
- 'react/jsx-sort-props': 'off', // disabled due to conflict with eslint-plugin-perfectionist
51
- 'react/sort-default-props': 'error',
52
-
53
- // eslint-plugin-react-hooks: https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md
54
- 'react-hooks/exhaustive-deps': 'error',
55
- 'react-hooks/rules-of-hooks': 'error',
56
-
57
- // eslint-plugin-perfectionist: https://github.com/azat-io/eslint-plugin-perfectionist
58
- 'perfectionist/sort-imports': [
59
- 'error',
60
- {
61
- customGroups: {
62
- type: {
63
- react: ['react'],
64
- },
65
- value: {
66
- react: ['react'],
67
- },
68
- },
69
- groups: ['react', ...SORT_IMPORTS_GROUPS],
70
- ignoreCase: true,
71
- newlinesBetween: 'ignore',
72
- type: 'natural',
73
- },
74
- ],
75
- 'perfectionist/sort-jsx-props': [
76
- 'error',
77
- {
78
- customGroups: {
79
- callback: '^on.+',
80
- reservedProps: ['children', 'dangerouslySetInnerHTML', 'key', 'ref'], // Reserved props from: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/lib/rules/jsx-sort-props.js#L41-L46
81
- },
82
- groups: ['reservedProps', 'unknown', 'callback'],
83
- ignoreCase: true,
84
- type: 'natural',
85
- },
86
- ],
87
-
88
- // eslint-plugin-react-refresh: https://github.com/ArnaudBarre/eslint-plugin-react-refresh
89
- 'react-refresh/only-export-components': 'warn',
90
- },
91
- settings: {
92
- react: {
93
- version: 'detect',
94
- },
95
- },
96
- };