@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 +175 -56
- package/configs/base.js +148 -0
- package/configs/local.js +16 -0
- package/configs/naming-convention.js +68 -0
- package/configs/nextjs.js +46 -0
- package/configs/playwright.js +13 -0
- package/configs/prettier-disable.js +10 -0
- package/configs/react.js +108 -0
- package/{base → configs}/strict.js +5 -11
- package/index.js +24 -0
- package/package.json +19 -21
- package/base/index.js +0 -156
- package/base/local.js +0 -20
- package/playwright/index.js +0 -16
- package/prettier-disable/index.js +0 -13
- package/react/index.js +0 -96
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
|
|
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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
65
|
+
Opinionated Options that differ from the standard/recommended ESLint configurations.
|
|
57
66
|
|
|
58
|
-
###
|
|
67
|
+
### Base
|
|
59
68
|
|
|
60
69
|
```js
|
|
61
|
-
|
|
62
|
-
|
|
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/
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
###
|
|
103
|
+
### Local
|
|
88
104
|
|
|
89
105
|
```js
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
###
|
|
116
|
+
### Strict
|
|
98
117
|
|
|
99
118
|
```js
|
|
100
|
-
|
|
101
|
-
|
|
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
|
|
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
|
-
###
|
|
128
|
+
### React
|
|
108
129
|
|
|
109
130
|
```js
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
- [
|
|
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)
|
|
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
|
package/configs/base.js
ADDED
|
@@ -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
|
+
);
|
package/configs/local.js
ADDED
|
@@ -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
|
+
});
|
package/configs/react.js
ADDED
|
@@ -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
|
|
3
|
+
const base = require('./base.js');
|
|
8
4
|
|
|
9
|
-
|
|
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
|
-
...
|
|
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": "
|
|
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
|
-
"
|
|
18
|
-
"lib"
|
|
19
|
-
"react",
|
|
20
|
-
"playwright",
|
|
21
|
-
"prettier-disable"
|
|
17
|
+
"configs",
|
|
18
|
+
"lib"
|
|
22
19
|
],
|
|
23
|
-
"main": "
|
|
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": "
|
|
29
|
+
"eslint": ">= 8"
|
|
32
30
|
},
|
|
33
31
|
"dependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"
|
|
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.
|
|
38
|
+
"eslint-plugin-perfectionist": "^4.6.0",
|
|
42
39
|
"eslint-plugin-playwright": "^2.1.0",
|
|
43
|
-
"eslint-plugin-react": "^7.37.
|
|
40
|
+
"eslint-plugin-react": "^7.37.4",
|
|
44
41
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
45
|
-
"eslint-plugin-react-refresh": "^0.4.
|
|
42
|
+
"eslint-plugin-react-refresh": "^0.4.18",
|
|
46
43
|
"eslint-plugin-sonarjs": "^1.0.4",
|
|
47
|
-
"
|
|
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.
|
|
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": "
|
|
55
|
+
"dotenv-cli": "8.0.0",
|
|
58
56
|
"husky": "9.1.7",
|
|
59
57
|
"prettier": "3.4.2",
|
|
60
|
-
"semantic-release": "24.2.
|
|
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
|
-
};
|
package/playwright/index.js
DELETED
|
@@ -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
|
-
};
|