@timobechtel/style 1.14.0 → 2.0.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 +55 -42
- package/eslint/core.js +86 -0
- package/eslint/react.js +32 -0
- package/eslint/rules/base.js +52 -0
- package/eslint/rules/{css-in-js.cjs → css-in-js.js} +2 -4
- package/eslint/rules/import.js +28 -0
- package/eslint/rules/react.js +40 -0
- package/eslint/rules/typescript.js +63 -0
- package/eslint/rules/unicorn.js +71 -0
- package/package.json +23 -19
- package/eslint/core.cjs +0 -63
- package/eslint/react.cjs +0 -21
- package/eslint/rules/base.cjs +0 -84
- package/eslint/rules/import.cjs +0 -39
- package/eslint/rules/react.cjs +0 -90
- package/eslint/rules/typescript.cjs +0 -108
- package/eslint/rules/unicorn.cjs +0 -129
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Highly opinionated configuration files for typescript projects. Inspired by [@ve
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm i -D @timobechtel/style prettier "eslint@^
|
|
13
|
+
npm i -D @timobechtel/style prettier "eslint@^9" typescript
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
### Prettier
|
|
@@ -94,7 +94,6 @@ With expo make sure to add `"moduleResolution": "bundler"` to the `compilerOptio
|
|
|
94
94
|
|
|
95
95
|
</details>
|
|
96
96
|
|
|
97
|
-
|
|
98
97
|
#### Or with React
|
|
99
98
|
|
|
100
99
|
```bash
|
|
@@ -117,51 +116,44 @@ curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/temp
|
|
|
117
116
|
### Eslint
|
|
118
117
|
|
|
119
118
|
```bash
|
|
120
|
-
curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/core
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
#### Fix Parsing errors for config files
|
|
124
|
-
|
|
125
|
-
You may get a `Parsing error: <FILE> was not found by the project service.` for config files like .eslintrc.cjs when not included in the tsconfig.
|
|
126
|
-
|
|
127
|
-
To fix, either add to tsconfig or add them to the eslint config:
|
|
128
|
-
|
|
129
|
-
```diff
|
|
130
|
-
//...
|
|
131
|
-
parserOptions: {
|
|
132
|
-
+ projectService: {
|
|
133
|
-
+ allowDefaultProject: ['.eslintrc.cjs'],
|
|
134
|
-
+ },
|
|
135
|
-
//...
|
|
136
|
-
},
|
|
137
|
-
//...
|
|
119
|
+
curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/core/eslint.config.js
|
|
138
120
|
```
|
|
139
121
|
|
|
122
|
+
Note: If your project is not ESM (no `"type": "module"` in `package.json`), rename the file to `eslint.config.mjs`.
|
|
140
123
|
|
|
141
124
|
<details>
|
|
142
125
|
<summary>Or manually</summary>
|
|
143
126
|
|
|
144
|
-
Copy the following to
|
|
127
|
+
Copy the following to an `eslint.config.js`:
|
|
145
128
|
|
|
146
129
|
```js
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
130
|
+
import path from 'node:path';
|
|
131
|
+
import { fileURLToPath } from 'node:url';
|
|
132
|
+
import { defineConfig } from 'eslint/config';
|
|
133
|
+
import styleCore from '@timobechtel/style/eslint/core.js';
|
|
134
|
+
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
|
|
135
|
+
import { createNodeResolver } from 'eslint-plugin-import-x';
|
|
136
|
+
|
|
137
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
138
|
+
|
|
139
|
+
export default defineConfig([
|
|
140
|
+
...styleCore,
|
|
141
|
+
{
|
|
142
|
+
languageOptions: {
|
|
143
|
+
parserOptions: {
|
|
144
|
+
tsconfigRootDir: __dirname,
|
|
161
145
|
},
|
|
162
146
|
},
|
|
147
|
+
settings: {
|
|
148
|
+
'import-x/resolver-next': [
|
|
149
|
+
createTypeScriptImportResolver({
|
|
150
|
+
project: path.resolve(__dirname, 'tsconfig.json'),
|
|
151
|
+
}),
|
|
152
|
+
createNodeResolver(),
|
|
153
|
+
],
|
|
154
|
+
},
|
|
163
155
|
},
|
|
164
|
-
|
|
156
|
+
]);
|
|
165
157
|
```
|
|
166
158
|
|
|
167
159
|
</details>
|
|
@@ -169,28 +161,49 @@ To fix, either add to tsconfig or add them to the eslint config:
|
|
|
169
161
|
#### React
|
|
170
162
|
|
|
171
163
|
```bash
|
|
172
|
-
curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react
|
|
164
|
+
curl -O https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react/eslint.config.js
|
|
173
165
|
```
|
|
174
166
|
|
|
175
167
|
<details>
|
|
176
168
|
<summary>Or manually</summary>
|
|
177
169
|
|
|
178
|
-
Also
|
|
170
|
+
Also spread `styleReact` from `@timobechtel/style/eslint/react.js`:
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
import styleCore from '@timobechtel/style/eslint/core.js';
|
|
174
|
+
import styleReact from '@timobechtel/style/eslint/react.js';
|
|
175
|
+
import { defineConfig } from 'eslint/config';
|
|
176
|
+
|
|
177
|
+
export default defineConfig([
|
|
178
|
+
...styleCore,
|
|
179
|
+
...styleReact,
|
|
180
|
+
// ... your config
|
|
181
|
+
]);
|
|
182
|
+
```
|
|
179
183
|
|
|
180
184
|
Example config:
|
|
181
|
-
<https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react
|
|
185
|
+
<https://raw.githubusercontent.com/TimoBechtel/style/refs/heads/main/templates/eslint/react/eslint.config.js>
|
|
182
186
|
</details>
|
|
183
187
|
|
|
188
|
+
#### Migration from v1.x
|
|
189
|
+
|
|
190
|
+
If you're upgrading from v1.x, you'll need to:
|
|
191
|
+
|
|
192
|
+
1. Upgrade to ESLint v9+
|
|
193
|
+
2. Replace `.eslintrc.cjs` with `eslint.config.js`
|
|
194
|
+
3. Update imports to use `.js` extension (e.g., `@timobechtel/style/eslint/core.js`)
|
|
195
|
+
4. Note: Import plugin rules now use `import-x/` prefix instead of `import/`
|
|
196
|
+
|
|
184
197
|
#### VSCode
|
|
185
198
|
|
|
186
|
-
Note: You should disable `source.organizeImports` in your VSCode config, as this collides with the `import/order` rule.
|
|
199
|
+
Note: You should disable `source.organizeImports` in your VSCode config, as this collides with the `import-x/order` rule.
|
|
187
200
|
|
|
188
201
|
Add the following to your VSCode config, e.g. `.vscode/settings.json`
|
|
189
202
|
|
|
190
203
|
```json
|
|
191
204
|
{
|
|
192
205
|
"editor.codeActionsOnSave": {
|
|
193
|
-
// use eslint import/order instead
|
|
206
|
+
// use eslint import-x/order instead
|
|
194
207
|
"source.sortImports": "never"
|
|
195
208
|
}
|
|
196
209
|
}
|
|
@@ -201,7 +214,7 @@ Add the following to your VSCode config, e.g. `.vscode/settings.json`
|
|
|
201
214
|
This repo also contains a [semantic-release](https://github.com/semantic-release/semantic-release) configuration.
|
|
202
215
|
|
|
203
216
|
```bash
|
|
204
|
-
npm i -D semantic-release
|
|
217
|
+
npm i -D semantic-release @semantic-release/changelog @semantic-release/git
|
|
205
218
|
```
|
|
206
219
|
|
|
207
220
|
```bash
|
package/eslint/core.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import timobechtelRulesPlugin from '@timobechtel/eslint-plugin-rules';
|
|
3
|
+
import prettierConfig from 'eslint-config-prettier/flat';
|
|
4
|
+
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
|
|
5
|
+
import { createNodeResolver, importX } from 'eslint-plugin-import-x';
|
|
6
|
+
import unicornPlugin from 'eslint-plugin-unicorn';
|
|
7
|
+
import { defineConfig } from 'eslint/config';
|
|
8
|
+
import globals from 'globals';
|
|
9
|
+
import tseslint from 'typescript-eslint';
|
|
10
|
+
|
|
11
|
+
import baseRules from './rules/base.js';
|
|
12
|
+
import importRules from './rules/import.js';
|
|
13
|
+
import typescriptRules from './rules/typescript.js';
|
|
14
|
+
import unicornRules from './rules/unicorn.js';
|
|
15
|
+
|
|
16
|
+
const mergeRules = (configs) =>
|
|
17
|
+
Object.assign({}, ...configs.map((config) => config?.rules ?? {}));
|
|
18
|
+
|
|
19
|
+
export default defineConfig([
|
|
20
|
+
js.configs.recommended,
|
|
21
|
+
importX.flatConfigs.recommended,
|
|
22
|
+
importX.flatConfigs.typescript,
|
|
23
|
+
timobechtelRulesPlugin.configs['flat/all'],
|
|
24
|
+
|
|
25
|
+
{
|
|
26
|
+
languageOptions: {
|
|
27
|
+
globals: {
|
|
28
|
+
...globals.browser,
|
|
29
|
+
...globals.node,
|
|
30
|
+
...globals.es2021,
|
|
31
|
+
},
|
|
32
|
+
ecmaVersion: 2021,
|
|
33
|
+
sourceType: 'module',
|
|
34
|
+
},
|
|
35
|
+
plugins: {
|
|
36
|
+
unicorn: unicornPlugin,
|
|
37
|
+
},
|
|
38
|
+
rules: {
|
|
39
|
+
...mergeRules(baseRules),
|
|
40
|
+
...mergeRules(importRules),
|
|
41
|
+
...mergeRules(unicornRules),
|
|
42
|
+
},
|
|
43
|
+
linterOptions: {
|
|
44
|
+
reportUnusedDisableDirectives: true,
|
|
45
|
+
},
|
|
46
|
+
settings: {
|
|
47
|
+
'import-x/resolver-next': [
|
|
48
|
+
createTypeScriptImportResolver(),
|
|
49
|
+
createNodeResolver(),
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
...tseslint.configs.recommended,
|
|
55
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
56
|
+
...tseslint.configs.strict,
|
|
57
|
+
...tseslint.configs.strictTypeChecked,
|
|
58
|
+
...tseslint.configs.stylistic,
|
|
59
|
+
...tseslint.configs.stylisticTypeChecked,
|
|
60
|
+
{
|
|
61
|
+
languageOptions: {
|
|
62
|
+
parserOptions: {
|
|
63
|
+
projectService: true,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
files: ['**/*.js'],
|
|
69
|
+
extends: [tseslint.configs.disableTypeChecked],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
73
|
+
rules: {
|
|
74
|
+
...mergeRules(typescriptRules),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
{
|
|
79
|
+
files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx'],
|
|
80
|
+
rules: {
|
|
81
|
+
'@typescript-eslint/ban-ts-comment': 'off',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
prettierConfig,
|
|
86
|
+
]);
|
package/eslint/react.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import prettierConfig from 'eslint-config-prettier/flat';
|
|
2
|
+
import reactPlugin from 'eslint-plugin-react';
|
|
3
|
+
import reactHooksPlugin from 'eslint-plugin-react-hooks';
|
|
4
|
+
import { defineConfig } from 'eslint/config';
|
|
5
|
+
import reactRules from './rules/react.js';
|
|
6
|
+
|
|
7
|
+
const mergeRules = (configs) =>
|
|
8
|
+
Object.assign({}, ...configs.map((config) => config?.rules ?? {}));
|
|
9
|
+
|
|
10
|
+
export default defineConfig([
|
|
11
|
+
reactPlugin.configs.flat.recommended,
|
|
12
|
+
reactPlugin.configs.flat['jsx-runtime'],
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
plugins: {
|
|
16
|
+
react: reactPlugin,
|
|
17
|
+
'react-hooks': reactHooksPlugin,
|
|
18
|
+
},
|
|
19
|
+
settings: {
|
|
20
|
+
react: {
|
|
21
|
+
version: 'detect',
|
|
22
|
+
},
|
|
23
|
+
linkComponents: ['Link'],
|
|
24
|
+
},
|
|
25
|
+
rules: {
|
|
26
|
+
...reactHooksPlugin.configs.flat.recommended.rules,
|
|
27
|
+
...mergeRules(reactRules),
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
prettierConfig,
|
|
32
|
+
]);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
rules: {
|
|
5
|
+
'prefer-arrow-callback': [
|
|
6
|
+
'warn',
|
|
7
|
+
{
|
|
8
|
+
allowNamedFunctions: true,
|
|
9
|
+
allowUnboundThis: true,
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
'no-console': [
|
|
13
|
+
'error',
|
|
14
|
+
{
|
|
15
|
+
allow: ['warn', 'error', 'clear', 'info'],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
'max-depth': ['warn', 4],
|
|
19
|
+
'no-restricted-globals': ['error', 'event', 'name'],
|
|
20
|
+
curly: ['warn', 'multi-line'],
|
|
21
|
+
'default-case-last': 'error',
|
|
22
|
+
eqeqeq: 'error',
|
|
23
|
+
'no-alert': 'error',
|
|
24
|
+
'no-useless-rename': 'warn',
|
|
25
|
+
'no-var': 'error',
|
|
26
|
+
'object-shorthand': 'warn',
|
|
27
|
+
'prefer-const': 'warn',
|
|
28
|
+
'prefer-rest-params': 'error',
|
|
29
|
+
'prefer-spread': 'error',
|
|
30
|
+
'prefer-template': 'warn',
|
|
31
|
+
'no-promise-executor-return': 'error',
|
|
32
|
+
'no-unreachable-loop': 'error',
|
|
33
|
+
'new-cap': ['error', { capIsNew: false }],
|
|
34
|
+
'new-parens': 'warn',
|
|
35
|
+
'no-lonely-if': 'warn',
|
|
36
|
+
'no-unneeded-ternary': 'error',
|
|
37
|
+
'prefer-object-spread': 'warn',
|
|
38
|
+
'no-label-var': 'error',
|
|
39
|
+
'no-undef-init': 'warn',
|
|
40
|
+
'no-unused-vars': [
|
|
41
|
+
'error',
|
|
42
|
+
{
|
|
43
|
+
args: 'after-used',
|
|
44
|
+
argsIgnorePattern: '^_',
|
|
45
|
+
ignoreRestSiblings: false,
|
|
46
|
+
vars: 'all',
|
|
47
|
+
varsIgnorePattern: '^_',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
'no-constant-binary-expression': 'error',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
export default defineConfig({
|
|
5
4
|
rules: {
|
|
6
5
|
'no-restricted-syntax': [
|
|
7
6
|
'error',
|
|
8
7
|
{
|
|
9
|
-
// catches common mistakes when writing comments in CSS
|
|
10
8
|
selector:
|
|
11
9
|
'TemplateElement[value.cooked=/\\s+\\u002F\\u002F\\s*/], Literal[value=/\\s+\\u002F\\u002F\\s*/]',
|
|
12
10
|
message: 'Invalid comment syntax. Use `/* */` instead of `//`.',
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
rules: {
|
|
5
|
+
'import-x/first': 'error',
|
|
6
|
+
'import-x/newline-after-import': 'warn',
|
|
7
|
+
'import-x/no-self-import': 'error',
|
|
8
|
+
'import-x/no-useless-path-segments': ['error'],
|
|
9
|
+
'import-x/order': [
|
|
10
|
+
'warn',
|
|
11
|
+
{
|
|
12
|
+
groups: [
|
|
13
|
+
'builtin',
|
|
14
|
+
'external',
|
|
15
|
+
'internal',
|
|
16
|
+
'parent',
|
|
17
|
+
'sibling',
|
|
18
|
+
'index',
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
'import-x/no-default-export': 'off',
|
|
23
|
+
'import-x/default': 'off',
|
|
24
|
+
'import-x/export': 'off',
|
|
25
|
+
'import-x/namespace': 'off',
|
|
26
|
+
'import-x/no-unresolved': 'off',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
rules: {
|
|
5
|
+
'react/prop-types': 'off',
|
|
6
|
+
'react/react-in-jsx-scope': 'off',
|
|
7
|
+
'react/button-has-type': 'error',
|
|
8
|
+
'react/function-component-definition': 'warn',
|
|
9
|
+
'react/hook-use-state': 'warn',
|
|
10
|
+
'react/jsx-boolean-value': 'warn',
|
|
11
|
+
'react/jsx-curly-brace-presence': [
|
|
12
|
+
'warn',
|
|
13
|
+
{
|
|
14
|
+
props: 'never',
|
|
15
|
+
children: 'ignore',
|
|
16
|
+
propElementValues: 'always',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
'react/jsx-fragments': 'warn',
|
|
20
|
+
'react/jsx-no-leaked-render': 'error',
|
|
21
|
+
'react/jsx-no-target-blank': [
|
|
22
|
+
'error',
|
|
23
|
+
{
|
|
24
|
+
allowReferrer: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
|
|
28
|
+
'react/jsx-pascal-case': 'warn',
|
|
29
|
+
'react/jsx-sort-props': [
|
|
30
|
+
'warn',
|
|
31
|
+
{
|
|
32
|
+
callbacksLast: true,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
'react/no-unstable-nested-components': 'error',
|
|
36
|
+
'react/self-closing-comp': 'warn',
|
|
37
|
+
'react-hooks/exhaustive-deps': 'error',
|
|
38
|
+
'react/destructuring-assignment': ['warn', 'always'],
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import baseRules from './base.js';
|
|
3
|
+
|
|
4
|
+
const noUnusedVarsConfig = baseRules[0]?.rules?.['no-unused-vars'];
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
rules: {
|
|
8
|
+
'@typescript-eslint/consistent-type-exports': [
|
|
9
|
+
'error',
|
|
10
|
+
{ fixMixedExportsWithInlineTypeSpecifier: true },
|
|
11
|
+
],
|
|
12
|
+
'@typescript-eslint/consistent-type-imports': [
|
|
13
|
+
'error',
|
|
14
|
+
{
|
|
15
|
+
prefer: 'type-imports',
|
|
16
|
+
fixStyle: 'inline-type-imports',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
'@typescript-eslint/naming-convention': [
|
|
20
|
+
'error',
|
|
21
|
+
{
|
|
22
|
+
format: ['PascalCase'],
|
|
23
|
+
selector: ['typeLike', 'enumMember'],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
custom: {
|
|
27
|
+
match: false,
|
|
28
|
+
regex: '^I[A-Z]|^(Interface|Props|State)$',
|
|
29
|
+
},
|
|
30
|
+
format: ['PascalCase'],
|
|
31
|
+
selector: 'interface',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
'@typescript-eslint/no-redundant-type-constituents': 'error',
|
|
35
|
+
'@typescript-eslint/prefer-regexp-exec': 'warn',
|
|
36
|
+
'@typescript-eslint/require-array-sort-compare': [
|
|
37
|
+
'error',
|
|
38
|
+
{ ignoreStringArrays: true },
|
|
39
|
+
],
|
|
40
|
+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
41
|
+
'default-param-last': 'off',
|
|
42
|
+
'@typescript-eslint/default-param-last': 'error',
|
|
43
|
+
'no-loop-func': 'off',
|
|
44
|
+
'@typescript-eslint/no-loop-func': 'error',
|
|
45
|
+
'no-unused-vars': 'off',
|
|
46
|
+
'@typescript-eslint/no-unused-vars': noUnusedVarsConfig,
|
|
47
|
+
'import-x/default': 'off',
|
|
48
|
+
'import-x/export': 'off',
|
|
49
|
+
'import-x/namespace': 'off',
|
|
50
|
+
'import-x/no-unresolved': 'off',
|
|
51
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
52
|
+
'@typescript-eslint/no-misused-promises': [
|
|
53
|
+
'error',
|
|
54
|
+
{
|
|
55
|
+
checksVoidReturn: false,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
59
|
+
'@typescript-eslint/method-signature-style': 'off',
|
|
60
|
+
'@typescript-eslint/consistent-indexed-object-style': 'off',
|
|
61
|
+
'@typescript-eslint/no-import-type-side-effects': 'error',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
rules: {
|
|
5
|
+
'unicorn/consistent-destructuring': 'warn',
|
|
6
|
+
'unicorn/consistent-function-scoping': [
|
|
7
|
+
'warn',
|
|
8
|
+
{
|
|
9
|
+
checkArrowFunctions: false,
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
'unicorn/error-message': 'error',
|
|
13
|
+
'unicorn/escape-case': 'warn',
|
|
14
|
+
'unicorn/no-empty-file': 'error',
|
|
15
|
+
'unicorn/no-for-loop': 'warn',
|
|
16
|
+
'unicorn/no-instanceof-array': 'error',
|
|
17
|
+
'unicorn/no-invalid-remove-event-listener': 'error',
|
|
18
|
+
'unicorn/no-object-as-default-parameter': 'error',
|
|
19
|
+
'unicorn/no-thenable': 'error',
|
|
20
|
+
'unicorn/no-unnecessary-await': 'error',
|
|
21
|
+
'unicorn/no-unreadable-iife': 'warn',
|
|
22
|
+
'unicorn/no-useless-fallback-in-spread': 'warn',
|
|
23
|
+
'unicorn/no-useless-length-check': 'warn',
|
|
24
|
+
'unicorn/no-useless-promise-resolve-reject': 'error',
|
|
25
|
+
'unicorn/no-useless-spread': 'error',
|
|
26
|
+
'unicorn/no-zero-fractions': 'warn',
|
|
27
|
+
'unicorn/numeric-separators-style': 'error',
|
|
28
|
+
'unicorn/prefer-add-event-listener': 'error',
|
|
29
|
+
'unicorn/prefer-array-find': 'error',
|
|
30
|
+
'unicorn/prefer-array-flat': 'error',
|
|
31
|
+
'unicorn/prefer-array-flat-map': 'error',
|
|
32
|
+
'unicorn/prefer-array-index-of': 'error',
|
|
33
|
+
'unicorn/prefer-array-some': 'error',
|
|
34
|
+
'unicorn/prefer-at': 'error',
|
|
35
|
+
'unicorn/prefer-blob-reading-methods': 'error',
|
|
36
|
+
'unicorn/prefer-date-now': 'error',
|
|
37
|
+
'unicorn/prefer-default-parameters': 'warn',
|
|
38
|
+
'unicorn/prefer-dom-node-append': 'error',
|
|
39
|
+
'unicorn/prefer-dom-node-dataset': 'error',
|
|
40
|
+
'unicorn/prefer-dom-node-remove': 'error',
|
|
41
|
+
'unicorn/prefer-event-target': 'warn',
|
|
42
|
+
'unicorn/prefer-export-from': [
|
|
43
|
+
'warn',
|
|
44
|
+
{
|
|
45
|
+
ignoreUsedVariables: true,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
'unicorn/prefer-includes': 'error',
|
|
49
|
+
'unicorn/prefer-keyboard-event-key': 'error',
|
|
50
|
+
'unicorn/prefer-logical-operator-over-ternary': 'error',
|
|
51
|
+
'unicorn/prefer-math-trunc': 'error',
|
|
52
|
+
'unicorn/prefer-modern-dom-apis': 'error',
|
|
53
|
+
'unicorn/prefer-modern-math-apis': 'error',
|
|
54
|
+
'unicorn/prefer-negative-index': 'error',
|
|
55
|
+
'unicorn/prefer-node-protocol': 'error',
|
|
56
|
+
'unicorn/prefer-number-properties': ['error', { checkInfinity: false }],
|
|
57
|
+
'unicorn/prefer-object-from-entries': 'error',
|
|
58
|
+
'unicorn/prefer-reflect-apply': 'error',
|
|
59
|
+
'unicorn/prefer-regexp-test': 'error',
|
|
60
|
+
'unicorn/prefer-set-has': 'error',
|
|
61
|
+
'unicorn/prefer-set-size': 'error',
|
|
62
|
+
'unicorn/prefer-spread': 'error',
|
|
63
|
+
'unicorn/prefer-string-replace-all': 'error',
|
|
64
|
+
'unicorn/prefer-string-slice': 'error',
|
|
65
|
+
'unicorn/prefer-string-starts-ends-with': 'error',
|
|
66
|
+
'unicorn/prefer-ternary': ['warn', 'only-single-line'],
|
|
67
|
+
'unicorn/prefer-top-level-await': 'error',
|
|
68
|
+
'unicorn/require-array-join-separator': 'error',
|
|
69
|
+
'unicorn/switch-case-braces': 'error',
|
|
70
|
+
},
|
|
71
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timobechtel/style",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/TimoBechtel/style"
|
|
8
|
+
},
|
|
5
9
|
"files": [
|
|
6
10
|
"bin",
|
|
7
11
|
"eslint",
|
|
@@ -10,30 +14,30 @@
|
|
|
10
14
|
"tsconfig"
|
|
11
15
|
],
|
|
12
16
|
"devDependencies": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
+
"@semantic-release/npm": "^13.1.4",
|
|
18
|
+
"eslint": "^9.39.3",
|
|
19
|
+
"prettier": "^3.8.1",
|
|
20
|
+
"semantic-release": "^25.0.3",
|
|
21
|
+
"typescript": "^5.9.3"
|
|
17
22
|
},
|
|
18
23
|
"peerDependencies": {
|
|
19
|
-
"eslint": "^
|
|
20
|
-
"prettier": "^3.
|
|
21
|
-
"semantic-release": "^
|
|
22
|
-
"typescript": "^5.
|
|
24
|
+
"eslint": "^9.39.3",
|
|
25
|
+
"prettier": "^3.8.1",
|
|
26
|
+
"semantic-release": "^25.0.3",
|
|
27
|
+
"typescript": "^5.9.3"
|
|
23
28
|
},
|
|
24
29
|
"dependencies": {
|
|
30
|
+
"@eslint/js": "^9.39.3",
|
|
25
31
|
"@semantic-release/changelog": "^6.0.3",
|
|
26
32
|
"@semantic-release/git": "^10.0.1",
|
|
27
33
|
"@timobechtel/eslint-plugin-rules": "^1.0.0",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"eslint-
|
|
31
|
-
"eslint-
|
|
32
|
-
"eslint-
|
|
33
|
-
"eslint-plugin-
|
|
34
|
-
"
|
|
35
|
-
"eslint
|
|
36
|
-
"eslint-plugin-react-hooks": "^5.1.0",
|
|
37
|
-
"eslint-plugin-unicorn": "^56.0.1"
|
|
34
|
+
"eslint-config-prettier": "^10.1.8",
|
|
35
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
36
|
+
"eslint-plugin-import-x": "^4.16.1",
|
|
37
|
+
"eslint-plugin-react": "^7.37.5",
|
|
38
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
39
|
+
"eslint-plugin-unicorn": "^63.0.0",
|
|
40
|
+
"globals": "^17.3.0",
|
|
41
|
+
"typescript-eslint": "^8.56.0"
|
|
38
42
|
}
|
|
39
43
|
}
|
package/eslint/core.cjs
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
extends: [
|
|
6
|
-
'eslint:recommended',
|
|
7
|
-
'plugin:import/recommended',
|
|
8
|
-
'prettier',
|
|
9
|
-
'plugin:no-template-curly-in-string-fix/recommended',
|
|
10
|
-
'plugin:@timobechtel/rules/all',
|
|
11
|
-
require.resolve('./rules/base.cjs'),
|
|
12
|
-
require.resolve('./rules/import.cjs'),
|
|
13
|
-
require.resolve('./rules/unicorn.cjs'),
|
|
14
|
-
],
|
|
15
|
-
parser: '@typescript-eslint/parser',
|
|
16
|
-
plugins: [],
|
|
17
|
-
env: {
|
|
18
|
-
es2021: true,
|
|
19
|
-
node: true,
|
|
20
|
-
browser: true,
|
|
21
|
-
},
|
|
22
|
-
// Report unused `eslint-disable` comments.
|
|
23
|
-
reportUnusedDisableDirectives: true,
|
|
24
|
-
// Tell ESLint not to ignore dot-files, which are ignored by default.
|
|
25
|
-
ignorePatterns: ['!.*.js'],
|
|
26
|
-
// Global settings used by all overrides.
|
|
27
|
-
settings: {
|
|
28
|
-
// Use the Node resolver by default.
|
|
29
|
-
'import/resolver': { node: {} },
|
|
30
|
-
},
|
|
31
|
-
// Global parser options.
|
|
32
|
-
parserOptions: {
|
|
33
|
-
ecmaVersion: 2021,
|
|
34
|
-
sourceType: 'module',
|
|
35
|
-
projectService: true,
|
|
36
|
-
},
|
|
37
|
-
overrides: [
|
|
38
|
-
{
|
|
39
|
-
files: ['*.ts?(x)'],
|
|
40
|
-
extends: [
|
|
41
|
-
'plugin:@typescript-eslint/recommended',
|
|
42
|
-
'plugin:@typescript-eslint/recommended-type-checked',
|
|
43
|
-
'plugin:@typescript-eslint/strict',
|
|
44
|
-
'plugin:@typescript-eslint/strict-type-checked',
|
|
45
|
-
'plugin:@typescript-eslint/stylistic',
|
|
46
|
-
'plugin:@typescript-eslint/stylistic-type-checked',
|
|
47
|
-
'plugin:import/typescript',
|
|
48
|
-
'prettier',
|
|
49
|
-
require.resolve('./rules/typescript.cjs'),
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
files: ['*.test.ts?(x)', '*.spec.ts?(x)'],
|
|
54
|
-
rules: {
|
|
55
|
-
// ts-expect-error makes sense for tests
|
|
56
|
-
'@typescript-eslint/ban-ts-comment': [
|
|
57
|
-
'off',
|
|
58
|
-
{ 'ts-expect-error': 'off' },
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
});
|
package/eslint/react.cjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
extends: [
|
|
6
|
-
'plugin:react/recommended',
|
|
7
|
-
'plugin:react-hooks/recommended',
|
|
8
|
-
'plugin:import/react',
|
|
9
|
-
'prettier',
|
|
10
|
-
require.resolve('./rules/react.cjs'),
|
|
11
|
-
],
|
|
12
|
-
settings: {
|
|
13
|
-
react: {
|
|
14
|
-
version: 'detect',
|
|
15
|
-
},
|
|
16
|
-
linkComponents: [
|
|
17
|
-
// Components used as alternatives to <a> for linking, eg. <Link to={ url } />
|
|
18
|
-
'Link',
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
});
|
package/eslint/rules/base.cjs
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
rules: {
|
|
6
|
-
// prefer arrow functions for callbacks
|
|
7
|
-
'prefer-arrow-callback': [
|
|
8
|
-
'warn',
|
|
9
|
-
{
|
|
10
|
-
allowNamedFunctions: true,
|
|
11
|
-
allowUnboundThis: true,
|
|
12
|
-
},
|
|
13
|
-
],
|
|
14
|
-
// console logs other than error and warn are only needed for debugging, so they should be removed before merging
|
|
15
|
-
'no-console': [
|
|
16
|
-
'error',
|
|
17
|
-
{
|
|
18
|
-
allow: [
|
|
19
|
-
'warn',
|
|
20
|
-
'error',
|
|
21
|
-
'clear',
|
|
22
|
-
// sometimes we really need to log something, even in production, so info is allowed in edge cases
|
|
23
|
-
'info',
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
'max-depth': ['warn', 4],
|
|
28
|
-
// some globals, like "name" might be similar to the name of a variable, so we prevent them from being used
|
|
29
|
-
'no-restricted-globals': ['error', 'event', 'name'],
|
|
30
|
-
// Require curly braces for multiline blocks.
|
|
31
|
-
curly: ['warn', 'multi-line'],
|
|
32
|
-
// Require default clauses in switch statements to be last (if used).
|
|
33
|
-
'default-case-last': 'error',
|
|
34
|
-
// Require triple equals (`===` and `!==`).
|
|
35
|
-
eqeqeq: 'error',
|
|
36
|
-
// disallow the use of `alert()`
|
|
37
|
-
'no-alert': 'error',
|
|
38
|
-
// Disallow renaming import, export, and destructured assignments to the same name.
|
|
39
|
-
'no-useless-rename': 'warn',
|
|
40
|
-
// Require `let` or `const` instead of `var`.
|
|
41
|
-
'no-var': 'error',
|
|
42
|
-
// Require object literal shorthand syntax.
|
|
43
|
-
'object-shorthand': 'warn',
|
|
44
|
-
// Require default to `const` instead of `let`.
|
|
45
|
-
'prefer-const': 'warn',
|
|
46
|
-
// Require rest parameters instead of `arguments`.
|
|
47
|
-
'prefer-rest-params': 'error',
|
|
48
|
-
// Require spread syntax instead of `.apply()`.
|
|
49
|
-
'prefer-spread': 'error',
|
|
50
|
-
// Require template literals instead of string concatenation.
|
|
51
|
-
'prefer-template': 'warn',
|
|
52
|
-
// Disallow returning values from Promise executor functions.
|
|
53
|
-
'no-promise-executor-return': 'error',
|
|
54
|
-
// Disallow loops with a body that allows only one iteration.
|
|
55
|
-
'no-unreachable-loop': 'error',
|
|
56
|
-
// Require a capital letter for constructors.
|
|
57
|
-
'new-cap': ['error', { capIsNew: false }],
|
|
58
|
-
// Disallow the omission of parentheses when invoking a constructor with no arguments.
|
|
59
|
-
'new-parens': 'warn',
|
|
60
|
-
// Disallow if as the only statement in an else block.
|
|
61
|
-
'no-lonely-if': 'warn',
|
|
62
|
-
// Disallow ternary operators when simpler alternatives exist.
|
|
63
|
-
'no-unneeded-ternary': 'error',
|
|
64
|
-
// Require use of an object spread over Object.assign.
|
|
65
|
-
'prefer-object-spread': 'warn',
|
|
66
|
-
// Disallow labels that share a name with a variable.
|
|
67
|
-
'no-label-var': 'error',
|
|
68
|
-
// Disallow initializing variables to `undefined`.
|
|
69
|
-
'no-undef-init': 'warn',
|
|
70
|
-
// Disallow unused variables.
|
|
71
|
-
'no-unused-vars': [
|
|
72
|
-
'error',
|
|
73
|
-
{
|
|
74
|
-
args: 'after-used',
|
|
75
|
-
argsIgnorePattern: '^_',
|
|
76
|
-
ignoreRestSiblings: false,
|
|
77
|
-
vars: 'all',
|
|
78
|
-
varsIgnorePattern: '^_',
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
// Disallow expressions where the operation doesn't affect the value
|
|
82
|
-
'no-constant-binary-expression': 'error',
|
|
83
|
-
},
|
|
84
|
-
});
|
package/eslint/rules/import.cjs
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
rules: {
|
|
6
|
-
// Disallow non-import statements appearing before import statements.
|
|
7
|
-
'import/first': 'error',
|
|
8
|
-
// Require a newline after the last import/require.
|
|
9
|
-
'import/newline-after-import': 'warn',
|
|
10
|
-
// Disallow a module from importing itself.
|
|
11
|
-
'import/no-self-import': 'error',
|
|
12
|
-
// Ensures that there are no useless path segments.
|
|
13
|
-
'import/no-useless-path-segments': ['error'],
|
|
14
|
-
// Enforce a module import order convention.
|
|
15
|
-
'import/order': [
|
|
16
|
-
'warn',
|
|
17
|
-
{
|
|
18
|
-
groups: [
|
|
19
|
-
'builtin', // Node.js built-in modules
|
|
20
|
-
'external', // Packages
|
|
21
|
-
'internal', // Aliased modules
|
|
22
|
-
'parent', // Relative parent
|
|
23
|
-
'sibling', // Relative sibling
|
|
24
|
-
'index', // Relative index
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
// allow default exports
|
|
29
|
-
'import/no-default-export': 'off',
|
|
30
|
-
/**
|
|
31
|
-
* These are enabled by `import/recommended`, but are better handled by
|
|
32
|
-
* TypeScript and @typescript-eslint.
|
|
33
|
-
*/
|
|
34
|
-
'import/default': 'off',
|
|
35
|
-
'import/export': 'off',
|
|
36
|
-
'import/namespace': 'off',
|
|
37
|
-
'import/no-unresolved': 'off',
|
|
38
|
-
},
|
|
39
|
-
});
|
package/eslint/rules/react.cjs
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
rules: {
|
|
6
|
-
// We should prefer TypeScript over prop-types.
|
|
7
|
-
'react/prop-types': 'off',
|
|
8
|
-
// Disable requiring React to be imported, as this is no longer required.
|
|
9
|
-
'react/react-in-jsx-scope': 'off',
|
|
10
|
-
/**
|
|
11
|
-
* Require an explicit type when using button elements. Prevents common mistakes where `type="button"` is omitted on `<button>` elements.
|
|
12
|
-
*/
|
|
13
|
-
'react/button-has-type': 'error',
|
|
14
|
-
/**
|
|
15
|
-
* Require consistent function type for function components.
|
|
16
|
-
*/
|
|
17
|
-
'react/function-component-definition': 'warn',
|
|
18
|
-
/**
|
|
19
|
-
* Require destructuring and symmetric naming of `useState` hook value and setter variables.
|
|
20
|
-
*/
|
|
21
|
-
'react/hook-use-state': 'warn',
|
|
22
|
-
/**
|
|
23
|
-
* Require consistent boolean attributes notation in JSX.
|
|
24
|
-
*/
|
|
25
|
-
'react/jsx-boolean-value': 'warn',
|
|
26
|
-
/**
|
|
27
|
-
* Disallow unnecessary curly braces in JSX props and children.
|
|
28
|
-
*/
|
|
29
|
-
'react/jsx-curly-brace-presence': [
|
|
30
|
-
'warn',
|
|
31
|
-
{
|
|
32
|
-
props: 'never',
|
|
33
|
-
children: 'ignore',
|
|
34
|
-
propElementValues: 'always',
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
/**
|
|
38
|
-
* Require using shorthand form for React fragments, unless required.
|
|
39
|
-
*/
|
|
40
|
-
'react/jsx-fragments': 'warn',
|
|
41
|
-
/**
|
|
42
|
-
* Prevent problematic leaked values from being rendered.
|
|
43
|
-
*/
|
|
44
|
-
'react/jsx-no-leaked-render': 'error',
|
|
45
|
-
/**
|
|
46
|
-
* Prevents usage of unsafe `target='_blank'`.
|
|
47
|
-
*
|
|
48
|
-
* This rule is a part of `react/recommended`, but modified to
|
|
49
|
-
* enable allowReferrer.
|
|
50
|
-
*/
|
|
51
|
-
'react/jsx-no-target-blank': [
|
|
52
|
-
'error',
|
|
53
|
-
{
|
|
54
|
-
allowReferrer: true,
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
/**
|
|
58
|
-
* Disallow empty React fragments.
|
|
59
|
-
*/
|
|
60
|
-
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
|
|
61
|
-
/**
|
|
62
|
-
* Require the use of PascalCase for user-defined JSX components.
|
|
63
|
-
*/
|
|
64
|
-
'react/jsx-pascal-case': 'warn',
|
|
65
|
-
/**
|
|
66
|
-
* Require props to be sorted alphabetically.
|
|
67
|
-
*/
|
|
68
|
-
'react/jsx-sort-props': [
|
|
69
|
-
'warn',
|
|
70
|
-
{
|
|
71
|
-
// list callbacks after all other props
|
|
72
|
-
callbacksLast: true,
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
/**
|
|
76
|
-
* Disallow creating unstable components inside components.
|
|
77
|
-
*/
|
|
78
|
-
'react/no-unstable-nested-components': 'error',
|
|
79
|
-
/**
|
|
80
|
-
* Disallow closing tags for components without children.
|
|
81
|
-
*/
|
|
82
|
-
'react/self-closing-comp': 'warn',
|
|
83
|
-
/**
|
|
84
|
-
* Enforce exhaustive dependencies in `useEffect` and `useCallback` hooks.
|
|
85
|
-
*/
|
|
86
|
-
'react-hooks/exhaustive-deps': 'error',
|
|
87
|
-
// prefer destructuring props
|
|
88
|
-
'react/destructuring-assignment': ['warn', 'always'],
|
|
89
|
-
},
|
|
90
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const { defineConfig } = require('eslint-define-config');
|
|
2
|
-
const noUnusedVarsConfig = require('./base.cjs').rules['no-unused-vars'];
|
|
3
|
-
|
|
4
|
-
// @ts-check
|
|
5
|
-
module.exports = defineConfig({
|
|
6
|
-
rules: {
|
|
7
|
-
// Require consistent usage of type exports.
|
|
8
|
-
'@typescript-eslint/consistent-type-exports': [
|
|
9
|
-
'error',
|
|
10
|
-
{ fixMixedExportsWithInlineTypeSpecifier: true },
|
|
11
|
-
],
|
|
12
|
-
// Require consistent usage of type imports.
|
|
13
|
-
'@typescript-eslint/consistent-type-imports': [
|
|
14
|
-
'error',
|
|
15
|
-
{
|
|
16
|
-
prefer: 'type-imports',
|
|
17
|
-
fixStyle: 'inline-type-imports',
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
/**
|
|
21
|
-
* Require using function property types in method signatures.
|
|
22
|
-
* These have enhanced typechecking, whereas method signatures do not.
|
|
23
|
-
*/
|
|
24
|
-
'@typescript-eslint/method-signature-style': 'error',
|
|
25
|
-
/**
|
|
26
|
-
* Require consistent naming conventions.
|
|
27
|
-
* Improves IntelliSense suggestions and avoids name collisions.
|
|
28
|
-
*/
|
|
29
|
-
'@typescript-eslint/naming-convention': [
|
|
30
|
-
'error',
|
|
31
|
-
// Anything type-like should be written in PascalCase.
|
|
32
|
-
{
|
|
33
|
-
format: ['PascalCase'],
|
|
34
|
-
selector: ['typeLike', 'enumMember'],
|
|
35
|
-
},
|
|
36
|
-
// Interfaces cannot be prefixed with `I`, or have restricted names.
|
|
37
|
-
{
|
|
38
|
-
custom: {
|
|
39
|
-
match: false,
|
|
40
|
-
regex: '^I[A-Z]|^(Interface|Props|State)$',
|
|
41
|
-
},
|
|
42
|
-
format: ['PascalCase'],
|
|
43
|
-
selector: 'interface',
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
// Disallow members of unions and intersections that do nothing or override type information.
|
|
47
|
-
'@typescript-eslint/no-redundant-type-constituents': 'error',
|
|
48
|
-
// Require using `RegExp.exec()` over `String.match()` for consistency.
|
|
49
|
-
'@typescript-eslint/prefer-regexp-exec': 'warn',
|
|
50
|
-
//
|
|
51
|
-
'@typescript-eslint/require-array-sort-compare': [
|
|
52
|
-
'error',
|
|
53
|
-
{ ignoreStringArrays: true },
|
|
54
|
-
],
|
|
55
|
-
/**
|
|
56
|
-
* Require exhaustive checks when using union types in switch statements.
|
|
57
|
-
* This ensures cases are considered when items are later added to a union.
|
|
58
|
-
*/
|
|
59
|
-
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
60
|
-
// Require default parameters to be last.
|
|
61
|
-
'default-param-last': 'off',
|
|
62
|
-
'@typescript-eslint/default-param-last': 'error',
|
|
63
|
-
// Disallow creation of functions within loops.
|
|
64
|
-
'no-loop-func': 'off',
|
|
65
|
-
'@typescript-eslint/no-loop-func': 'error',
|
|
66
|
-
// Disallow unused variables.
|
|
67
|
-
'no-unused-vars': 'off',
|
|
68
|
-
'@typescript-eslint/no-unused-vars': noUnusedVarsConfig,
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* These are enabled by `import/recommended`, but are better handled by
|
|
72
|
-
* TypeScript and @typescript-eslint.
|
|
73
|
-
*/
|
|
74
|
-
'import/default': 'off',
|
|
75
|
-
'import/export': 'off',
|
|
76
|
-
'import/namespace': 'off',
|
|
77
|
-
'import/no-unresolved': 'off',
|
|
78
|
-
|
|
79
|
-
// This is disabled as I feel that checking empty strings is a valid use
|
|
80
|
-
// of `||` over `??`.
|
|
81
|
-
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
82
|
-
|
|
83
|
-
// Disallow Promises in places not designed to handle them.
|
|
84
|
-
'@typescript-eslint/no-misused-promises': [
|
|
85
|
-
'error',
|
|
86
|
-
{
|
|
87
|
-
// Disabled as I feel that passing a async callback to a function expecting
|
|
88
|
-
// a void callback is a valid use case.
|
|
89
|
-
// e.g. fn.on('event', async () => {})
|
|
90
|
-
// Strictly requiring to return 'undefined' does not have a functional benefit,
|
|
91
|
-
// but makes the code more verbose.
|
|
92
|
-
checksVoidReturn: false,
|
|
93
|
-
},
|
|
94
|
-
],
|
|
95
|
-
// While I'd prefer using types over interfaces, there are a lot of cases
|
|
96
|
-
// where interfaces are needed, e.g. merging declarations and this rule is too strict.
|
|
97
|
-
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
98
|
-
// while using property signatures provides better typechecking,
|
|
99
|
-
// method signatures provide better hinting in the editor.
|
|
100
|
-
// (different color for methods vs properties)
|
|
101
|
-
'@typescript-eslint/method-signature-style': 'off',
|
|
102
|
-
// There are cases where using the index signature is more descriptive
|
|
103
|
-
// as the index can be named
|
|
104
|
-
'@typescript-eslint/consistent-indexed-object-style': 'off',
|
|
105
|
-
// Enforce using a top-level type qualifier for imports when only types are imported using the inline type qualifier
|
|
106
|
-
'@typescript-eslint/no-import-type-side-effects': 'error',
|
|
107
|
-
},
|
|
108
|
-
});
|
package/eslint/rules/unicorn.cjs
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('eslint-define-config');
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
plugins: ['unicorn'],
|
|
6
|
-
rules: {
|
|
7
|
-
// Use destructured variables over properties.
|
|
8
|
-
'unicorn/consistent-destructuring': 'warn',
|
|
9
|
-
// Move function definitions to the highest possible scope.
|
|
10
|
-
'unicorn/consistent-function-scoping': [
|
|
11
|
-
'warn',
|
|
12
|
-
{
|
|
13
|
-
checkArrowFunctions: false,
|
|
14
|
-
},
|
|
15
|
-
],
|
|
16
|
-
// Enforce passing a message value when creating a built-in error.
|
|
17
|
-
'unicorn/error-message': 'error',
|
|
18
|
-
// Require escape sequences to use uppercase values.
|
|
19
|
-
'unicorn/escape-case': 'warn',
|
|
20
|
-
// Disallow empty files.
|
|
21
|
-
'unicorn/no-empty-file': 'error',
|
|
22
|
-
// Do not use a for loop that can be replaced with a for-of loop.
|
|
23
|
-
'unicorn/no-for-loop': 'warn',
|
|
24
|
-
// Require Array.isArray() instead of instanceof Array.
|
|
25
|
-
'unicorn/no-instanceof-array': 'error',
|
|
26
|
-
// Prevent calling EventTarget#removeEventListener() with the result of an expression.
|
|
27
|
-
'unicorn/no-invalid-remove-event-listener': 'error',
|
|
28
|
-
// Disallow the use of objects as default parameters.
|
|
29
|
-
'unicorn/no-object-as-default-parameter': 'error',
|
|
30
|
-
// Disallow then property.
|
|
31
|
-
'unicorn/no-thenable': 'error',
|
|
32
|
-
// Disallow awaiting non-promise values.
|
|
33
|
-
'unicorn/no-unnecessary-await': 'error',
|
|
34
|
-
// Disallow unreadable IIFEs.
|
|
35
|
-
'unicorn/no-unreadable-iife': 'warn',
|
|
36
|
-
// Disallow useless fallback when spreading in object literals.
|
|
37
|
-
'unicorn/no-useless-fallback-in-spread': 'warn',
|
|
38
|
-
// Disallow useless array length check.
|
|
39
|
-
'unicorn/no-useless-length-check': 'warn',
|
|
40
|
-
// Disallow returning/yielding Promise.resolve/reject() in async functions or promise callbacks
|
|
41
|
-
'unicorn/no-useless-promise-resolve-reject': 'error',
|
|
42
|
-
// Disallow unnecessary spread.
|
|
43
|
-
'unicorn/no-useless-spread': 'error',
|
|
44
|
-
// Disallow number literals with zero fractions or dangling dots.
|
|
45
|
-
'unicorn/no-zero-fractions': 'warn',
|
|
46
|
-
// Enforce the style of numeric separators by correctly grouping digits.
|
|
47
|
-
'unicorn/numeric-separators-style': 'error',
|
|
48
|
-
// Prefer .addEventListener() and .removeEventListener() over on-functions.
|
|
49
|
-
'unicorn/prefer-add-event-listener': 'error',
|
|
50
|
-
// Prefer .find(…) and .findLast(…) over the first or last element from .filter(…).
|
|
51
|
-
'unicorn/prefer-array-find': 'error',
|
|
52
|
-
// Prefer Array#flat() over legacy techniques to flatten arrays.
|
|
53
|
-
'unicorn/prefer-array-flat': 'error',
|
|
54
|
-
// Prefer .flatMap(…) over .map(…).flat().
|
|
55
|
-
'unicorn/prefer-array-flat-map': 'error',
|
|
56
|
-
// Prefer Array#{indexOf,lastIndexOf}() over Array#{findIndex,findLastIndex}() when looking for the index of an item.
|
|
57
|
-
'unicorn/prefer-array-index-of': 'error',
|
|
58
|
-
// Prefer .some(…) over .filter(…).length check and .{find,findLast}(…).
|
|
59
|
-
'unicorn/prefer-array-some': 'error',
|
|
60
|
-
// Prefer .at() method for index access and String#charAt().
|
|
61
|
-
'unicorn/prefer-at': 'error',
|
|
62
|
-
// Prefer Blob#arrayBuffer() over FileReader#readAsArrayBuffer(…) and Blob#text() over FileReader#readAsText(…).
|
|
63
|
-
'unicorn/prefer-blob-reading-methods': 'error',
|
|
64
|
-
// Prefer Date.now() to get the number of milliseconds since the Unix Epoch.
|
|
65
|
-
'unicorn/prefer-date-now': 'error',
|
|
66
|
-
// Prefer default parameters over reassignment.
|
|
67
|
-
'unicorn/prefer-default-parameters': 'warn',
|
|
68
|
-
// Prefer Node#append() over Node#appendChild().
|
|
69
|
-
'unicorn/prefer-dom-node-append': 'error',
|
|
70
|
-
// Prefer using .dataset on DOM elements over calling attribute methods.
|
|
71
|
-
'unicorn/prefer-dom-node-dataset': 'error',
|
|
72
|
-
// Prefer childNode.remove() over parentNode.removeChild(childNode).
|
|
73
|
-
'unicorn/prefer-dom-node-remove': 'error',
|
|
74
|
-
// Prefer EventTarget over EventEmitter.
|
|
75
|
-
'unicorn/prefer-event-target': 'warn',
|
|
76
|
-
// Prefer export…from when re-exporting.
|
|
77
|
-
'unicorn/prefer-export-from': [
|
|
78
|
-
'warn',
|
|
79
|
-
{
|
|
80
|
-
ignoreUsedVariables: true,
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
// Prefer .includes() over .indexOf() and Array#some() when checking for existence or non-existence.
|
|
84
|
-
'unicorn/prefer-includes': 'error',
|
|
85
|
-
// Prefer KeyboardEvent#key over KeyboardEvent#keyCode.
|
|
86
|
-
'unicorn/prefer-keyboard-event-key': 'error',
|
|
87
|
-
// Prefer using a logical operator over a ternary.
|
|
88
|
-
'unicorn/prefer-logical-operator-over-ternary': 'error',
|
|
89
|
-
// Enforce the use of Math.trunc instead of bitwise operators.
|
|
90
|
-
'unicorn/prefer-math-trunc': 'error',
|
|
91
|
-
// Prefer .before() over .insertBefore(), .replaceWith() over .replaceChild(), prefer one of .before(), .after(), .append() or .prepend() over insertAdjacentText() and insertAdjacentElement().
|
|
92
|
-
'unicorn/prefer-modern-dom-apis': 'error',
|
|
93
|
-
// Prefer modern Math APIs over legacy patterns.
|
|
94
|
-
'unicorn/prefer-modern-math-apis': 'error',
|
|
95
|
-
// Prefer negative index over .length - index when possible.
|
|
96
|
-
'unicorn/prefer-negative-index': 'error',
|
|
97
|
-
// Require using the `node:` protocol when importing Node.js built-in modules.
|
|
98
|
-
'unicorn/prefer-node-protocol': 'error',
|
|
99
|
-
// Prefer Number static properties over global ones.
|
|
100
|
-
'unicorn/prefer-number-properties': ['error', { checkInfinity: false }],
|
|
101
|
-
// Prefer using Object.fromEntries(…) to transform a list of key-value pairs into an object.
|
|
102
|
-
'unicorn/prefer-object-from-entries': 'error',
|
|
103
|
-
// Prefer Reflect.apply() over Function#apply().
|
|
104
|
-
'unicorn/prefer-reflect-apply': 'error',
|
|
105
|
-
// using RegExp.test() is faster than string.match()
|
|
106
|
-
// note: you should not use the global flag /g with RegExp.test() though!
|
|
107
|
-
'unicorn/prefer-regexp-test': 'error',
|
|
108
|
-
// Prefer Set#has() over Array#includes() when checking for existence or non-existence.
|
|
109
|
-
'unicorn/prefer-set-has': 'error',
|
|
110
|
-
// Prefer using Set#size instead of Array#length.
|
|
111
|
-
'unicorn/prefer-set-size': 'error',
|
|
112
|
-
// Prefer the spread operator over Array.from().
|
|
113
|
-
'unicorn/prefer-spread': 'error',
|
|
114
|
-
// Prefer String#replaceAll() over regex searches with the global flag.
|
|
115
|
-
'unicorn/prefer-string-replace-all': 'error',
|
|
116
|
-
// Prefer String#slice() over String#substr() and String#substring().
|
|
117
|
-
'unicorn/prefer-string-slice': 'error',
|
|
118
|
-
// Prefer String#startsWith() & String#endsWith() over RegExp#test().
|
|
119
|
-
'unicorn/prefer-string-starts-ends-with': 'error',
|
|
120
|
-
// Prefer ternary expressions over simple if-else statements.
|
|
121
|
-
'unicorn/prefer-ternary': ['warn', 'only-single-line'],
|
|
122
|
-
// Prefer top-level await over top-level promises and async function calls.
|
|
123
|
-
'unicorn/prefer-top-level-await': 'error',
|
|
124
|
-
// Enforce using the separator argument with Array#join().
|
|
125
|
-
'unicorn/require-array-join-separator': 'error',
|
|
126
|
-
// Enforce consistent brace style for case clauses.
|
|
127
|
-
'unicorn/switch-case-braces': 'error',
|
|
128
|
-
},
|
|
129
|
-
});
|