@fullstacksjs/eslint-config 11.1.10 → 11.1.11
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 +68 -116
- package/package.json +37 -38
- package/src/{init.d.ts → index.d.ts} +4 -4
- package/src/index.js +39 -45
- package/src/modules/base.js +9 -8
- package/src/modules/cypress.js +5 -4
- package/src/modules/esm.js +1 -1
- package/src/modules/{fp.js → functional.js} +6 -3
- package/src/modules/graphql.js +8 -7
- package/src/modules/imports.js +24 -23
- package/src/modules/jest.js +6 -5
- package/src/modules/next.js +24 -23
- package/src/modules/node.js +36 -12
- package/src/modules/perfectionist.js +34 -0
- package/src/modules/playwright.js +5 -4
- package/src/modules/prettier.js +3 -3
- package/src/modules/promise.js +3 -3
- package/src/modules/react.js +5 -6
- package/src/modules/storybook.js +5 -4
- package/src/modules/tailwind.js +4 -5
- package/src/modules/tests.js +8 -7
- package/src/modules/typescript.js +8 -31
- package/src/modules/vitest.js +5 -4
- package/src/utils/compose.js +5 -7
- package/src/utils/conditions.js +2 -5
- package/src/utils/globs.js +3 -7
- package/src/utils/naming-convention.js +1 -1
- package/src/modules/strict.js +0 -13
package/README.md
CHANGED
|
@@ -18,56 +18,40 @@ $ npm install --save-dev @fullstacksjs/eslint-config eslint prettier
|
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Create `.eslintrc.js` file and init the configuration.
|
|
21
|
+
To use the configuration all you need is exporting generated config by `init` function. The configuration reads the metadata from your root `package.json` file and automatically adds the rules and plugins that are needed.
|
|
24
22
|
|
|
25
23
|
```js
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
module.exports = init({
|
|
29
|
-
modules: {
|
|
30
|
-
auto: true, // If you need auto module detection (refer to Auto Module Detection).
|
|
31
|
-
// Modules configuration check (optional). (refer to Module API)
|
|
32
|
-
},
|
|
33
|
-
// Other ESLint configurations
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
```
|
|
24
|
+
import { init } from '@fullstacksjs/eslint-config';
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
You can also use the configuration within a `json` or `yaml` files by extending from `@fullstacksjs`, the Auto Module Detection is enabled on this method
|
|
41
|
-
|
|
42
|
-
```json
|
|
43
|
-
{
|
|
44
|
-
"extends": ["@fullstacksjs"]
|
|
45
|
-
}
|
|
26
|
+
export default init();
|
|
46
27
|
```
|
|
47
28
|
|
|
48
|
-
## Auto Module Detection
|
|
49
|
-
|
|
50
|
-
When auto module detection is turned on, the configuration reads the metadata from your root "package.json" file and automatically adds the rules and plugins that are needed. It's enabled for the `extends` API, and you should set `modules.auto` to `true` when you use the `init` API.
|
|
51
|
-
|
|
52
29
|
## Modules API
|
|
53
30
|
|
|
31
|
+
You can fine tune module detection by overriding it, `init` function accepts options as its first argument to control enabled modules.
|
|
32
|
+
|
|
54
33
|
```typescript
|
|
55
|
-
interface
|
|
34
|
+
interface Options {
|
|
56
35
|
react?: boolean; // controls react, react-hooks, jsx/a11y plugins
|
|
57
36
|
typescript?: { // controls typescript plugin
|
|
58
|
-
|
|
37
|
+
project?: boolean | string[] | string; // https://typescript-eslint.io/packages/parser/#project
|
|
38
|
+
tsconfigRootDir?: string // https://typescript-eslint.io/packages/parser/#tsconfigrootdir
|
|
59
39
|
};
|
|
60
40
|
node?: boolean; // controls node plugin
|
|
61
|
-
|
|
41
|
+
fp?: boolean; // controls functional plugin
|
|
42
|
+
sort?: boolean; // controls perfectionist plugin
|
|
43
|
+
strict?: boolean; // controls strict rules
|
|
62
44
|
import?: {
|
|
63
45
|
projects?: string[] | string // controls settings['import/resolver'].typescript.project
|
|
64
46
|
internalRegExp?: string;
|
|
65
47
|
lifetime?: number;
|
|
66
48
|
}; // controls import plugin
|
|
67
49
|
esm?: boolean; // controls esm plugin
|
|
68
|
-
|
|
69
|
-
|
|
50
|
+
test?: boolean; // controls test formatting plugin
|
|
51
|
+
jest?: boolean; // controls jest plugin
|
|
52
|
+
vitest?: boolean; // controls vitest plugin
|
|
70
53
|
cypress?: boolean; // controls cypress plugin
|
|
54
|
+
playwright?: boolean // controls playwright plugin
|
|
71
55
|
storybook?: boolean; // controls storybook plugin
|
|
72
56
|
tailwind?: boolean; // controls tailwindcss plugin
|
|
73
57
|
next?: boolean; // controls next plugin
|
|
@@ -76,19 +60,22 @@ interface Modules {
|
|
|
76
60
|
}
|
|
77
61
|
```
|
|
78
62
|
|
|
79
|
-
##
|
|
63
|
+
## Extra configuration
|
|
80
64
|
|
|
81
|
-
|
|
65
|
+
You can pass any number of arbitrary custom config overrides to `init` function:
|
|
82
66
|
|
|
83
67
|
```js
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
68
|
+
import { init } from '@fullstacksjs/eslint-config';
|
|
69
|
+
|
|
70
|
+
export default init(
|
|
71
|
+
{
|
|
72
|
+
typescript: true,
|
|
73
|
+
}, {
|
|
74
|
+
files: ['**/*.ts'],
|
|
75
|
+
rules: {},
|
|
76
|
+
}, {
|
|
77
|
+
rules: {},
|
|
78
|
+
})
|
|
92
79
|
```
|
|
93
80
|
|
|
94
81
|
## Speed Optimization!
|
|
@@ -109,113 +96,78 @@ To conditionally disable expensive linting rules, you can modify your configurat
|
|
|
109
96
|
list of expensiveRules to be effected:
|
|
110
97
|
|
|
111
98
|
```
|
|
99
|
+
@typescript-eslint/no-floating-promises
|
|
112
100
|
@typescript-eslint/no-misused-promises
|
|
101
|
+
import/default
|
|
102
|
+
import/export
|
|
103
|
+
import/named
|
|
104
|
+
import/namespace
|
|
113
105
|
import/no-cycle
|
|
114
|
-
import/
|
|
115
|
-
import/
|
|
116
|
-
import/default *
|
|
117
|
-
import/no-named-as-default-member *
|
|
106
|
+
import/no-deprecated
|
|
107
|
+
import/no-named-as-default-member
|
|
118
108
|
```
|
|
119
109
|
|
|
120
|
-
> *: If you are using Typescript these rules are not needed and disabled by default.
|
|
121
|
-
|
|
122
110
|
```js
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
prettier: false // So you should run the formatter explicitly.
|
|
127
|
-
},
|
|
111
|
+
export default init({
|
|
112
|
+
disableExpensiveRules: !process.env.CI || !process.env.HUSKY // Or anywhere you want
|
|
113
|
+
prettier: false // So you should run the formatter explicitly.
|
|
128
114
|
});
|
|
129
115
|
```
|
|
130
116
|
|
|
131
117
|
This approach ensures a smoother development experience while still enforcing rigorous code quality checks in environments where performance is less of a concern.
|
|
132
118
|
|
|
133
|
-
## React/NextJS configuration
|
|
134
|
-
|
|
135
|
-
React/NextJS configuration should automatically work with Auto Module Detection, but if you need to have more control over the rules you can configure it through `modules.react`.
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
module.exports = init({
|
|
139
|
-
modules: {
|
|
140
|
-
react: true // for React/CRA/Vite
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
and
|
|
146
|
-
|
|
147
|
-
```js
|
|
148
|
-
module.exports = init({
|
|
149
|
-
modules: {
|
|
150
|
-
react: true,
|
|
151
|
-
next: true // for NextJS
|
|
152
|
-
},
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
119
|
## Migration Guid
|
|
157
120
|
|
|
158
|
-
### to
|
|
121
|
+
### to v10
|
|
159
122
|
|
|
160
|
-
|
|
123
|
+
v10 drops support for ESLint v8 configuration and only ESLint v9 is supported, which means you should migrate to [ESlint Flat Config](https://eslint.org/docs/latest/extend/plugin-migration-flat-config):
|
|
161
124
|
|
|
162
|
-
1. Move your configs to
|
|
125
|
+
1. Move your configs to `eslint.config.js` file.
|
|
163
126
|
2. Use init API.
|
|
164
127
|
```diff
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
- "settings": {
|
|
176
|
-
- "import/resolver": {
|
|
177
|
-
- "typescript": {
|
|
178
|
-
- "project": ["./tsconfig.json"]
|
|
179
|
-
- },
|
|
128
|
+
-const { init } = require('@fullstacksjs/eslint-config/init');
|
|
129
|
+
+import { init } from '@fullstacksjs/eslint-config/init'
|
|
130
|
+
|
|
131
|
+
-module.exports = init({
|
|
132
|
+
- modules: {
|
|
133
|
+
- auto: true,
|
|
134
|
+
- esm: true,
|
|
135
|
+
- typescript: {
|
|
136
|
+
- parserProject: ['./tsconfig.eslint.json'],
|
|
137
|
+
- resolverProject: ['./tsconfig.json'],
|
|
180
138
|
- },
|
|
181
139
|
- },
|
|
182
140
|
- // your configuration
|
|
183
|
-
-};
|
|
184
|
-
+
|
|
185
|
-
+
|
|
186
|
-
+
|
|
187
|
-
+ modules: {
|
|
188
|
-
+ auto: true,
|
|
189
|
-
+ esm: true,
|
|
190
|
-
+ graphql: true,
|
|
191
|
-
+ typescript: {
|
|
192
|
-
+ parserProject: ['./tsconfig.eslint.json'],
|
|
193
|
-
+ resolverProject: ['./tsconfig.json'],
|
|
194
|
-
+ },
|
|
141
|
+
-});
|
|
142
|
+
+export default init({
|
|
143
|
+
+ esm: true,
|
|
144
|
+
+ typescript true,
|
|
195
145
|
+ },
|
|
196
146
|
+ // your configuration
|
|
197
|
-
+
|
|
147
|
+
+);
|
|
198
148
|
```
|
|
199
149
|
|
|
200
150
|
## What's included?
|
|
201
151
|
|
|
202
|
-
* [@
|
|
203
|
-
* [eslint-
|
|
152
|
+
* [@eslint-react/eslint-plugin](https://eslint-react.xyz/)
|
|
153
|
+
* [@next/eslint-config-next](https://nextjs.org/docs/basic-features/eslint#eslint-plugin)
|
|
154
|
+
* [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress)
|
|
155
|
+
* [eslint-plugin-functional](https://github.com/eslint-functional/eslint-plugin-functional)
|
|
156
|
+
* [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x)
|
|
204
157
|
* [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)
|
|
205
158
|
* [eslint-plugin-jest-formatting](https://github.com/dangreenisrael/eslint-plugin-jest-formatting)
|
|
206
|
-
* [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress)
|
|
207
159
|
* [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
|
|
160
|
+
* [eslint-plugin-perfectionist](https://perfectionist.dev/)
|
|
161
|
+
* [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)
|
|
162
|
+
* [eslint-plugin-playwright](https://github.com/playwright-community/eslint-plugin-playwright)
|
|
208
163
|
* [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)
|
|
209
|
-
* [eslint-plugin-
|
|
210
|
-
* [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
|
|
211
|
-
* [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort)
|
|
212
|
-
* [eslint-plugin-fp](https://github.com/jfmengels/eslint-plugin-fp)
|
|
213
|
-
* [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node)
|
|
164
|
+
* [eslint-plugin-perfectionist](https://perfectionist.dev/)
|
|
214
165
|
* [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise)
|
|
166
|
+
* [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
|
|
215
167
|
* [eslint-plugin-storybook](https://github.com/storybookjs/eslint-plugin-storybook#readme)
|
|
216
|
-
* [eslint-plugin-graphql](https://github.com/apollographql/eslint-plugin-graphql)
|
|
217
|
-
* [eslint-config-next](https://github.com/vercel/next.js/tree/canary/packages/eslint-config-next)
|
|
218
168
|
* [eslint-plugin-tailwindcss](https://github.com/francoismassart/eslint-plugin-tailwindcss)
|
|
169
|
+
* [eslint-plugin-vitest](https://www.npmjs.com/package/eslint-plugin-vitest)
|
|
170
|
+
* [typescript-eslint](https://typescript-eslint.io/)
|
|
219
171
|
|
|
220
172
|
That's all. Feel free to use 💛
|
|
221
173
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fullstacksjs/eslint-config",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "fullstacks <fullstacksjs@gmail.com>",
|
|
6
6
|
"description": "fullstacks eslint config",
|
|
@@ -23,56 +23,58 @@
|
|
|
23
23
|
"pre-commit": "npm run test && lint-staged"
|
|
24
24
|
},
|
|
25
25
|
"main": "src/index.js",
|
|
26
|
+
"module": "src/index.js",
|
|
27
|
+
"type": "module",
|
|
26
28
|
"dependencies": {
|
|
27
|
-
"@eslint-react/eslint-plugin": "1.
|
|
28
|
-
"@
|
|
29
|
+
"@eslint-react/eslint-plugin": "1.15.0",
|
|
30
|
+
"@next/eslint-plugin-next": "14.2.15",
|
|
29
31
|
"deepmerge": "4.3.1",
|
|
30
|
-
"eslint-import-resolver-typescript": "3.6.
|
|
31
|
-
"eslint-plugin-cypress": "
|
|
32
|
-
"eslint-plugin-functional": "
|
|
33
|
-
"eslint-plugin-import-x": "
|
|
34
|
-
"eslint-plugin-jest": "28.
|
|
32
|
+
"eslint-import-resolver-typescript": "3.6.3",
|
|
33
|
+
"eslint-plugin-cypress": "4.0.0",
|
|
34
|
+
"eslint-plugin-functional": "7.0.2",
|
|
35
|
+
"eslint-plugin-import-x": "4.3.1",
|
|
36
|
+
"eslint-plugin-jest": "28.8.3",
|
|
35
37
|
"eslint-plugin-jest-formatting": "3.1.0",
|
|
36
|
-
"eslint-plugin-jsx-a11y": "6.
|
|
37
|
-
"eslint-plugin-n": "17.
|
|
38
|
-
"eslint-plugin-
|
|
39
|
-
"eslint-plugin-
|
|
40
|
-
"eslint-plugin-
|
|
41
|
-
"eslint-plugin-
|
|
42
|
-
"eslint-plugin-
|
|
43
|
-
"eslint-plugin-
|
|
38
|
+
"eslint-plugin-jsx-a11y": "6.10.0",
|
|
39
|
+
"eslint-plugin-n": "17.11.1",
|
|
40
|
+
"eslint-plugin-perfectionist": "3.9.1",
|
|
41
|
+
"eslint-plugin-playwright": "1.7.0",
|
|
42
|
+
"eslint-plugin-prettier": "5.2.1",
|
|
43
|
+
"eslint-plugin-promise": "7.1.0",
|
|
44
|
+
"eslint-plugin-react-hooks": "5.0.0",
|
|
45
|
+
"eslint-plugin-storybook": "0.9.0",
|
|
46
|
+
"eslint-plugin-tailwindcss": "3.17.5",
|
|
44
47
|
"eslint-plugin-vitest": "0.5.4",
|
|
45
|
-
"globals": "15.
|
|
48
|
+
"globals": "15.11.0",
|
|
46
49
|
"local-pkg": "0.5.0",
|
|
47
|
-
"typescript-eslint": "
|
|
50
|
+
"typescript-eslint": "8.10.0"
|
|
48
51
|
},
|
|
49
52
|
"devDependencies": {
|
|
50
53
|
"@eslint/eslintrc": "3.1.0",
|
|
51
|
-
"@eslint/js": "9.
|
|
52
|
-
"@semantic-release/github": "
|
|
53
|
-
"@semantic-release/npm": "
|
|
54
|
-
"@semantic-release/release-notes-generator": "
|
|
55
|
-
"@types/eslint": "
|
|
56
|
-
"cspell": "8.
|
|
57
|
-
"eslint": "9.
|
|
58
|
-
"eslint-find-rules": "4.
|
|
59
|
-
"husky": "9.
|
|
54
|
+
"@eslint/js": "9.12.0",
|
|
55
|
+
"@semantic-release/github": "11.0.0",
|
|
56
|
+
"@semantic-release/npm": "12.0.1",
|
|
57
|
+
"@semantic-release/release-notes-generator": "14.0.1",
|
|
58
|
+
"@types/eslint": "9.6.1",
|
|
59
|
+
"cspell": "8.15.3",
|
|
60
|
+
"eslint": "9.12.0",
|
|
61
|
+
"eslint-find-rules": "4.2.0",
|
|
62
|
+
"husky": "9.1.6",
|
|
60
63
|
"jest": "29.7.0",
|
|
61
|
-
"lint-staged": "15.2.
|
|
62
|
-
"np": "10.0.
|
|
64
|
+
"lint-staged": "15.2.10",
|
|
65
|
+
"np": "10.0.7",
|
|
63
66
|
"npm-run-all": "4.1.5",
|
|
64
67
|
"pinst": "3.0.0",
|
|
65
|
-
"prettier": "3.3.
|
|
66
|
-
"semantic-release": "
|
|
67
|
-
"typescript": "5.4
|
|
68
|
+
"prettier": "3.3.3",
|
|
69
|
+
"semantic-release": "24.1.2",
|
|
70
|
+
"typescript": "^5.4"
|
|
68
71
|
},
|
|
69
72
|
"peerDependencies": {
|
|
70
73
|
"cypress": ">=8",
|
|
71
|
-
"eslint": "9",
|
|
72
|
-
"graphql": ">=15",
|
|
74
|
+
"eslint": "^9",
|
|
73
75
|
"prettier": "3",
|
|
74
76
|
"react": ">=16",
|
|
75
|
-
"typescript": ">=4"
|
|
77
|
+
"typescript": ">=4.7"
|
|
76
78
|
},
|
|
77
79
|
"peerDependenciesMeta": {
|
|
78
80
|
"typescript": {
|
|
@@ -86,9 +88,6 @@
|
|
|
86
88
|
},
|
|
87
89
|
"jest": {
|
|
88
90
|
"optional": true
|
|
89
|
-
},
|
|
90
|
-
"graphql": {
|
|
91
|
-
"optional": true
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export interface Options {
|
|
2
2
|
react?: boolean;
|
|
3
|
+
sort?: boolean;
|
|
3
4
|
next?: boolean;
|
|
4
5
|
tailwind?: boolean;
|
|
5
6
|
node?: boolean;
|
|
6
7
|
strict?: boolean;
|
|
7
|
-
import?:
|
|
8
|
+
import?: { internalRegExp?: string; lifetime?: number; projects?: string | string[] } | boolean;
|
|
8
9
|
esm?: boolean;
|
|
9
10
|
fp?: boolean;
|
|
10
|
-
graphql?: boolean;
|
|
11
11
|
test?: boolean;
|
|
12
12
|
jest?: boolean;
|
|
13
13
|
vitest?: boolean;
|
|
@@ -15,9 +15,9 @@ export interface Options {
|
|
|
15
15
|
storybook?: boolean;
|
|
16
16
|
prettier?: boolean;
|
|
17
17
|
playwright?: boolean;
|
|
18
|
-
typescript?: { projects:
|
|
18
|
+
typescript?: { projects: boolean | string | string[]; tsconfigRootDir?: string };
|
|
19
19
|
disableExpensiveRules?: boolean;
|
|
20
20
|
ignores?: string[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export declare const init: (opts: Options) => import('eslint').Linter.
|
|
23
|
+
export declare const init: (opts: Options) => import('eslint').Linter.Config[];
|
package/src/index.js
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import merge from 'deepmerge';
|
|
2
|
+
import { isPackageExists } from 'local-pkg';
|
|
3
|
+
|
|
4
|
+
import base from './modules/base.js';
|
|
5
|
+
import cypress from './modules/cypress.js';
|
|
6
|
+
import fp from './modules/functional.js';
|
|
7
|
+
import imports from './modules/imports.js';
|
|
8
|
+
import jest from './modules/jest.js';
|
|
9
|
+
import next from './modules/next.js';
|
|
10
|
+
import node from './modules/node.js';
|
|
11
|
+
import perfectionist from './modules/perfectionist.js';
|
|
12
|
+
import playwright from './modules/playwright.js';
|
|
13
|
+
import prettier from './modules/prettier.js';
|
|
14
|
+
import react from './modules/react.js';
|
|
15
|
+
import storybook from './modules/storybook.js';
|
|
16
|
+
import tailwind from './modules/tailwind.js';
|
|
17
|
+
import tests from './modules/tests.js';
|
|
18
|
+
import typescript from './modules/typescript.js';
|
|
19
|
+
import vitest from './modules/vitest.js';
|
|
20
|
+
import { compose } from './utils/compose.js';
|
|
21
21
|
|
|
22
22
|
const testPackages = ['jest', 'vitest', 'cypress', 'playwright'];
|
|
23
23
|
|
|
24
|
-
/** @type {import('./
|
|
24
|
+
/** @type {import('./index.js').Options} */
|
|
25
25
|
const defaultOptions = {
|
|
26
|
+
cypress: isPackageExists('cypress'),
|
|
26
27
|
disableExpensiveRules: false,
|
|
27
|
-
fp: true,
|
|
28
28
|
esm: false,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
fp: true,
|
|
30
|
+
ignores: [],
|
|
31
31
|
import: {},
|
|
32
|
-
test: testPackages.some(p => isPackageExists(p)),
|
|
33
|
-
react: isPackageExists('react'),
|
|
34
32
|
jest: isPackageExists('jest'),
|
|
35
|
-
vitest: isPackageExists('vitest'),
|
|
36
33
|
next: isPackageExists('next'),
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
storybook: isPackageExists('storybook'),
|
|
34
|
+
node: false,
|
|
35
|
+
sort: true,
|
|
36
|
+
playwright: isPackageExists('playwright'),
|
|
41
37
|
prettier: isPackageExists('prettier'),
|
|
38
|
+
react: isPackageExists('react'),
|
|
39
|
+
storybook: isPackageExists('storybook'),
|
|
40
|
+
strict: false,
|
|
41
|
+
tailwind: isPackageExists('tailwindcss'),
|
|
42
|
+
test: testPackages.some(p => isPackageExists(p)),
|
|
42
43
|
typescript: isPackageExists('typescript') ? { projects: true } : false,
|
|
43
44
|
unocss: isPackageExists('unocss'),
|
|
44
|
-
|
|
45
|
-
ignores: [],
|
|
45
|
+
vitest: isPackageExists('vitest'),
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Initialize eslint config
|
|
50
50
|
*
|
|
51
|
-
* @param {import('./
|
|
52
|
-
* @param {...(import('eslint').Linter.
|
|
53
|
-
* @returns {import('eslint').Linter.
|
|
51
|
+
* @param {import('./index.js').Options} initOptions
|
|
52
|
+
* @param {...(import('eslint').Linter.Config)} extend
|
|
53
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
54
54
|
*/
|
|
55
|
-
function init(initOptions, ...extend) {
|
|
55
|
+
export function init(initOptions, ...extend) {
|
|
56
56
|
const options = merge(defaultOptions, initOptions);
|
|
57
57
|
if (options.typescript === true) {
|
|
58
58
|
options.typescript = {};
|
|
@@ -64,6 +64,7 @@ function init(initOptions, ...extend) {
|
|
|
64
64
|
const rules = [compose(base, options)];
|
|
65
65
|
|
|
66
66
|
if (options.fp) rules.push(compose(fp, options));
|
|
67
|
+
if (options.sort) rules.push(compose(perfectionist, options));
|
|
67
68
|
if (options.import) rules.push(compose(imports, options));
|
|
68
69
|
if (options.tailwind) rules.push(compose(tailwind, options));
|
|
69
70
|
if (options.test) rules.push(compose(tests, options));
|
|
@@ -75,16 +76,9 @@ function init(initOptions, ...extend) {
|
|
|
75
76
|
if (options.storybook) rules.push(compose(storybook, options));
|
|
76
77
|
if (options.typescript) rules.push(compose(typescript, options));
|
|
77
78
|
if (options.playwright) rules.push(compose(playwright, options));
|
|
79
|
+
if (options.next && options.next) rules.push(compose(next, options));
|
|
78
80
|
|
|
79
|
-
// ISSUE: Waiting for FlatConfig support https://github.com/dimaMachina/graphql-eslint/issues/2178
|
|
80
|
-
// if (false && options.graphql) rules.push(compose(graphql,options));
|
|
81
|
-
// ISSUE: Waiting for FlatConfig support https://github.com/vercel/next/issues/64409#issuecomment-2057325722
|
|
82
|
-
// if (false && options.next) rules.push(compose(next,options));
|
|
83
|
-
|
|
84
|
-
if (options.strict) rules.push(compose(strict, options));
|
|
85
81
|
if (options.prettier) rules.push(compose(prettier, options));
|
|
86
82
|
|
|
87
83
|
return rules.concat(extend);
|
|
88
84
|
}
|
|
89
|
-
|
|
90
|
-
module.exports.init = init;
|
package/src/modules/base.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
|
|
3
|
+
import { strict } from '../utils/conditions.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @param {{strict?: boolean}} options
|
|
6
|
-
* @return { import('eslint').Linter.
|
|
7
|
+
* @return { import('eslint').Linter.Config }
|
|
7
8
|
*/
|
|
8
9
|
function base(options = {}) {
|
|
9
10
|
return {
|
|
@@ -16,6 +17,7 @@ function base(options = {}) {
|
|
|
16
17
|
...globals.es2024,
|
|
17
18
|
},
|
|
18
19
|
parserOptions: {
|
|
20
|
+
ecmaVersion: 'latest',
|
|
19
21
|
ecmaFeatures: {
|
|
20
22
|
jsx: true,
|
|
21
23
|
},
|
|
@@ -68,6 +70,7 @@ function base(options = {}) {
|
|
|
68
70
|
'no-dupe-keys': 'error',
|
|
69
71
|
'no-duplicate-case': 'error',
|
|
70
72
|
'no-empty-character-class': 'error',
|
|
73
|
+
'no-empty-function': 'warn',
|
|
71
74
|
'no-empty-pattern': 'error',
|
|
72
75
|
'no-empty-static-block': 'warn',
|
|
73
76
|
'no-empty': 'error',
|
|
@@ -77,7 +80,6 @@ function base(options = {}) {
|
|
|
77
80
|
'no-extra-bind': 'error',
|
|
78
81
|
'no-extra-label': 'error',
|
|
79
82
|
'no-fallthrough': 'error',
|
|
80
|
-
'no-floating-decimal': 'error',
|
|
81
83
|
'no-func-assign': 'error',
|
|
82
84
|
'no-global-assign': 'error',
|
|
83
85
|
'no-implicit-globals': 'error',
|
|
@@ -112,7 +114,7 @@ function base(options = {}) {
|
|
|
112
114
|
'no-restricted-globals': ['error', { name: 'event', message: 'Use local parameter instead.' }],
|
|
113
115
|
'no-restricted-syntax': ['error', 'WithStatement'],
|
|
114
116
|
'no-return-assign': 'error',
|
|
115
|
-
'no-return-await': '
|
|
117
|
+
'no-return-await': 'warn',
|
|
116
118
|
'no-script-url': 'error',
|
|
117
119
|
'no-self-assign': 'error',
|
|
118
120
|
'no-self-compare': 'error',
|
|
@@ -178,10 +180,9 @@ function base(options = {}) {
|
|
|
178
180
|
'no-param-reassign': 'warn',
|
|
179
181
|
'prefer-regex-literals': ['warn', { disallowRedundantWrapping: true }],
|
|
180
182
|
|
|
181
|
-
'no-console': strict(options, '
|
|
182
|
-
'no-empty-function': strict(options, 'off'),
|
|
183
|
+
'no-console': strict(options, 'warn'),
|
|
183
184
|
},
|
|
184
185
|
};
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
export default base;
|
package/src/modules/cypress.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
const { globs } = require('../utils/globs');
|
|
1
|
+
import plugin from 'eslint-plugin-cypress/flat';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
4
|
+
|
|
5
|
+
/** @return { import('eslint').Linter.Config } */
|
|
5
6
|
function cypress() {
|
|
6
7
|
return {
|
|
7
8
|
files: globs.e2e,
|
|
@@ -20,4 +21,4 @@ function cypress() {
|
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
export default cypress;
|
package/src/modules/esm.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-functional';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* @param { import('..').Options } options
|
|
5
|
+
* @return { import('eslint').Linter.Config }
|
|
6
|
+
*/
|
|
4
7
|
function fp() {
|
|
5
8
|
return {
|
|
6
9
|
plugins: { functional: plugin },
|
|
@@ -12,4 +15,4 @@ function fp() {
|
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
export default fp;
|
package/src/modules/graphql.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
const globs = require('../utils/globs');
|
|
1
|
+
import plugin, { configs } from '@graphql-eslint/eslint-plugin';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
configs['schema-recommended'].parser;
|
|
6
|
+
|
|
7
|
+
/** @return { import('eslint').Linter.Config } */
|
|
7
8
|
function graphql() {
|
|
8
9
|
return {
|
|
9
|
-
files: globs.
|
|
10
|
+
files: globs.graphql,
|
|
10
11
|
plugins: { graphql: plugin },
|
|
11
12
|
languageOptions: {
|
|
12
|
-
parser:
|
|
13
|
+
parser: configs['schema-recommended'].parser,
|
|
13
14
|
},
|
|
14
15
|
rules: {
|
|
15
16
|
'@graphql-eslint/alphabetize': ['warn', { fields: ['ObjectTypeDefinition'] }],
|
|
@@ -81,4 +82,4 @@ function graphql() {
|
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
export default graphql;
|
package/src/modules/imports.js
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-import-x';
|
|
2
|
+
|
|
3
|
+
import { predicate } from '../utils/conditions.js';
|
|
3
4
|
|
|
4
5
|
const tsExtensions = ['.ts', '.tsx', '.cts', '.mts', '.ctsx', '.mtsx'];
|
|
5
6
|
const jsExtensions = ['.mjs', '.js', '.jsx', '.cjs'];
|
|
6
7
|
const allExtensions = [...jsExtensions, ...tsExtensions];
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
* @param { import('../
|
|
10
|
-
* @return { import('eslint').Linter.
|
|
10
|
+
* @param { import('../index.js').Options } options
|
|
11
|
+
* @return { import('eslint').Linter.Config }
|
|
11
12
|
*/
|
|
12
13
|
function imports(options = {}) {
|
|
13
14
|
const isObject = typeof options.import === 'object';
|
|
15
|
+
const ignoreExtensions = {};
|
|
16
|
+
if (!options.esm) {
|
|
17
|
+
ignoreExtensions.js = 'never';
|
|
18
|
+
ignoreExtensions.jsx = 'never';
|
|
19
|
+
|
|
20
|
+
if (options.typescript) {
|
|
21
|
+
ignoreExtensions.ts = 'never';
|
|
22
|
+
ignoreExtensions.tsx = 'never';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
14
25
|
|
|
15
26
|
const config = {
|
|
16
27
|
plugins: { import: plugin },
|
|
17
28
|
|
|
18
29
|
settings: {
|
|
19
|
-
'import-x/extensions':
|
|
20
|
-
'import-x/resolver': {
|
|
21
|
-
node: { extensions: allExtensions },
|
|
22
|
-
...predicate(isObject && 'projects' in options.import, {
|
|
23
|
-
typescript: { project: options.import.projects },
|
|
24
|
-
}),
|
|
25
|
-
},
|
|
26
|
-
'import-x/parsers': { '@typescript-eslint/parser': tsExtensions },
|
|
30
|
+
'import-x/extensions': jsExtensions,
|
|
27
31
|
'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],
|
|
28
32
|
'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json)$'],
|
|
33
|
+
...predicate(options.typescript, {
|
|
34
|
+
'import-x/resolver': { typescript: true },
|
|
35
|
+
'import-x/parsers': { '@typescript-eslint/parser': tsExtensions },
|
|
36
|
+
'import-x/extensions': allExtensions,
|
|
37
|
+
}),
|
|
29
38
|
...predicate(isObject && 'internalRegExp' in options.import, {
|
|
30
39
|
'import-x/internal-regex': options.import.internalRegExp,
|
|
31
40
|
}),
|
|
@@ -33,18 +42,10 @@ function imports(options = {}) {
|
|
|
33
42
|
'import-x/cache': { lifetime: options.import.lifetime },
|
|
34
43
|
}),
|
|
35
44
|
},
|
|
45
|
+
|
|
36
46
|
rules: {
|
|
37
47
|
'import/consistent-type-specifier-style': ['warn', 'prefer-top-level'],
|
|
38
|
-
'import/extensions': [
|
|
39
|
-
'error',
|
|
40
|
-
'always',
|
|
41
|
-
{
|
|
42
|
-
js: 'never',
|
|
43
|
-
jsx: 'never',
|
|
44
|
-
ts: 'never',
|
|
45
|
-
tsx: 'never',
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
+
'import/extensions': ['error', 'ignorePackages', ignoreExtensions],
|
|
48
49
|
'import/first': 'error',
|
|
49
50
|
'import/newline-after-import': 'warn',
|
|
50
51
|
'import/no-absolute-path': 'error',
|
|
@@ -97,4 +98,4 @@ function imports(options = {}) {
|
|
|
97
98
|
return config;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
export default imports;
|
package/src/modules/jest.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-jest';
|
|
2
|
+
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* @param { import('
|
|
6
|
-
* @return { import('eslint').Linter.
|
|
6
|
+
* @param { import('../index.d.ts').Options } options
|
|
7
|
+
* @return { import('eslint').Linter.Config } */
|
|
7
8
|
function jest() {
|
|
8
9
|
return {
|
|
9
10
|
files: globs.test,
|
|
@@ -68,4 +69,4 @@ function jest() {
|
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
export default jest;
|
package/src/modules/next.js
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
import plugin from '@next/eslint-plugin-next';
|
|
2
2
|
|
|
3
|
-
/** @type { import('eslint').Linter.
|
|
3
|
+
/** @type { import('eslint').Linter.Config } */
|
|
4
4
|
function next() {
|
|
5
5
|
return {
|
|
6
6
|
plugins: { next: plugin },
|
|
7
7
|
rules: {
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
8
|
+
'next/google-font-display': 'warn',
|
|
9
|
+
'next/google-font-preconnect': 'warn',
|
|
10
|
+
'next/inline-script-id': 'warn',
|
|
11
|
+
'next/next-script-for-ga': 'warn',
|
|
12
|
+
'next/no-assign-module-variable': 'warn',
|
|
13
|
+
'next/no-async-client-component': 'warn',
|
|
14
|
+
'next/no-before-interactive-script-outside-document': 'warn',
|
|
15
|
+
'next/no-css-tags': 'warn',
|
|
16
|
+
'next/no-document-import-in-page': 'warn',
|
|
17
|
+
// 'next/no-duplicate-head': 'warn',
|
|
18
|
+
'next/no-head-element': 'warn',
|
|
19
|
+
'next/no-head-import-in-document': 'warn',
|
|
20
|
+
'next/no-html-link-for-pages': 'warn',
|
|
21
|
+
'next/no-img-element': 'warn',
|
|
22
|
+
'next/no-page-custom-font': 'warn',
|
|
23
|
+
'next/no-script-component-in-head': 'warn',
|
|
24
|
+
'next/no-styled-jsx-in-document': 'warn',
|
|
25
|
+
'next/no-sync-scripts': 'warn',
|
|
26
|
+
'next/no-title-in-document-head': 'warn',
|
|
27
|
+
'next/no-typos': 'warn',
|
|
28
|
+
'next/no-unwanted-polyfillio': 'warn',
|
|
28
29
|
},
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
export default next;
|
package/src/modules/node.js
CHANGED
|
@@ -1,10 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-n';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { strict } from '../utils/conditions.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param { import('../index').Options } options
|
|
7
|
+
* @return { import('eslint').Linter.Config }
|
|
8
|
+
*/
|
|
9
|
+
function node(options = {}) {
|
|
5
10
|
return {
|
|
6
11
|
plugins: { n: plugin },
|
|
7
12
|
rules: {
|
|
13
|
+
'n/callback-return': 'off',
|
|
14
|
+
'n/exports-style': ['error', 'module.exports', { allowBatchAssign: false }],
|
|
15
|
+
'n/global-require': 'warn',
|
|
16
|
+
'n/handle-callback-err': 'warn',
|
|
17
|
+
'n/hashbang': 'off', // Cannot ignore other files
|
|
18
|
+
'n/no-callback-literal': 'off',
|
|
19
|
+
'n/no-deprecated-api': 'error',
|
|
20
|
+
'n/no-exports-assign': 'error',
|
|
21
|
+
'n/no-mixed-requires': 'warn',
|
|
22
|
+
'n/no-new-require': 'error',
|
|
23
|
+
'n/no-path-concat': 'error',
|
|
24
|
+
'n/no-process-env': 'error',
|
|
25
|
+
'n/no-process-exit': 'off',
|
|
26
|
+
'n/no-restricted-import': 'off',
|
|
27
|
+
'n/no-restricted-require': 'off',
|
|
28
|
+
'n/no-sync': strict(options, 'warn'),
|
|
29
|
+
'n/no-unpublished-bin': 'warn',
|
|
30
|
+
'n/no-unpublished-import': 'warn',
|
|
31
|
+
'n/no-unpublished-require': 'warn',
|
|
8
32
|
'n/no-unsupported-features/es-builtins': 'off', // Nice but not a general rule
|
|
9
33
|
'n/no-unsupported-features/es-syntax': 'off', // Nice but not a general rule
|
|
10
34
|
'n/no-unsupported-features/node-builtins': 'off', // Nice but not a general rule
|
|
@@ -15,19 +39,19 @@ function node() {
|
|
|
15
39
|
'n/prefer-global/text-encoder': 'warn',
|
|
16
40
|
'n/prefer-global/url-search-params': 'warn',
|
|
17
41
|
'n/prefer-global/url': 'warn',
|
|
42
|
+
'n/prefer-node-protocol': 'warn',
|
|
18
43
|
'n/prefer-promises/dns': 'warn',
|
|
19
44
|
'n/prefer-promises/fs': 'warn',
|
|
20
|
-
'n/exports-style': ['error', 'module.exports', { allowBatchAssign: false }],
|
|
21
|
-
'n/global-require': 'warn',
|
|
22
|
-
'n/handle-callback-err': 'warn',
|
|
23
|
-
'n/no-deprecated-api': 'error',
|
|
24
|
-
'n/no-exports-assign': 'error',
|
|
25
|
-
'n/no-mixed-requires': 'warn',
|
|
26
|
-
'n/no-new-require': 'error',
|
|
27
|
-
'n/no-path-concat': 'error',
|
|
28
45
|
'n/process-exit-as-throw': 'error',
|
|
46
|
+
|
|
47
|
+
// Disabled
|
|
48
|
+
'n/file-extension-in-import': 'off',
|
|
49
|
+
'n/no-extraneous-import': 'off',
|
|
50
|
+
'n/no-extraneous-require': 'off',
|
|
51
|
+
'n/no-missing-import': 'off',
|
|
52
|
+
'n/no-missing-require': 'off',
|
|
29
53
|
},
|
|
30
54
|
};
|
|
31
55
|
}
|
|
32
56
|
|
|
33
|
-
|
|
57
|
+
export default node;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import plugin from 'eslint-plugin-perfectionist';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @return { import('eslint').Linter.Config }
|
|
5
|
+
*/
|
|
6
|
+
function perfectionist() {
|
|
7
|
+
return {
|
|
8
|
+
plugins: { perfectionist: plugin },
|
|
9
|
+
rules: {
|
|
10
|
+
'perfectionist/sort-array-includes': 'warn',
|
|
11
|
+
'perfectionist/sort-astro-attributes': 'warn',
|
|
12
|
+
'perfectionist/sort-classes': 'warn',
|
|
13
|
+
'perfectionist/sort-enums': 'warn',
|
|
14
|
+
'perfectionist/sort-exports': 'warn',
|
|
15
|
+
'perfectionist/sort-imports': ['warn', {}],
|
|
16
|
+
'perfectionist/sort-interfaces': 'off',
|
|
17
|
+
'perfectionist/sort-intersection-types': 'warn',
|
|
18
|
+
'perfectionist/sort-jsx-props': 'warn',
|
|
19
|
+
'perfectionist/sort-maps': 'warn',
|
|
20
|
+
'perfectionist/sort-named-exports': 'warn',
|
|
21
|
+
'perfectionist/sort-named-imports': 'warn',
|
|
22
|
+
'perfectionist/sort-object-types': 'off',
|
|
23
|
+
'perfectionist/sort-objects': 'off',
|
|
24
|
+
'perfectionist/sort-sets': 'warn',
|
|
25
|
+
'perfectionist/sort-svelte-attributes': 'warn',
|
|
26
|
+
'perfectionist/sort-switch-case': 'warn',
|
|
27
|
+
'perfectionist/sort-union-types': 'warn',
|
|
28
|
+
'perfectionist/sort-variable-declarations': 'warn',
|
|
29
|
+
'perfectionist/sort-vue-attributes': 'warn',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default perfectionist;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
const { globs } = require('../utils/globs');
|
|
1
|
+
import plugin from 'eslint-plugin-playwright';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
4
|
+
|
|
5
|
+
/** @return { import('eslint').Linter.Config } */
|
|
5
6
|
function playwright() {
|
|
6
7
|
return {
|
|
7
8
|
plugins: { playwright: plugin },
|
|
@@ -26,4 +27,4 @@ function playwright() {
|
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
export default playwright;
|
package/src/modules/prettier.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-prettier';
|
|
2
2
|
|
|
3
|
-
/** @return { Promise<import('eslint').Linter.
|
|
3
|
+
/** @return { Promise<import('eslint').Linter.Config> } */
|
|
4
4
|
function prettier() {
|
|
5
5
|
return {
|
|
6
6
|
plugins: { prettier: plugin },
|
|
@@ -90,4 +90,4 @@ function prettier() {
|
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
export default prettier;
|
package/src/modules/promise.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-promise';
|
|
2
2
|
|
|
3
|
-
/** @return { import('eslint').Linter.
|
|
3
|
+
/** @return { import('eslint').Linter.Config } */
|
|
4
4
|
function promise() {
|
|
5
5
|
return {
|
|
6
6
|
plugins: { promise: plugin },
|
|
@@ -24,4 +24,4 @@ function promise() {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
export default promise;
|
package/src/modules/react.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import reactPlugin from '@eslint-react/eslint-plugin';
|
|
2
|
+
import a11yPlugin from 'eslint-plugin-jsx-a11y';
|
|
3
|
+
import hooksPlugin from 'eslint-plugin-react-hooks';
|
|
4
4
|
|
|
5
|
-
/** @return { import('eslint').Linter.
|
|
5
|
+
/** @return { import('eslint').Linter.Config } */
|
|
6
6
|
function react() {
|
|
7
7
|
return {
|
|
8
8
|
plugins: {
|
|
@@ -67,7 +67,6 @@ function react() {
|
|
|
67
67
|
'@eslint-react/prefer-shorthand-fragment': 'warn',
|
|
68
68
|
|
|
69
69
|
'@eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks': 'warn',
|
|
70
|
-
'@eslint-react/hooks-extra/ensure-use-callback-has-non-empty-deps': 'warn',
|
|
71
70
|
'@eslint-react/hooks-extra/ensure-use-memo-has-non-empty-deps': 'warn',
|
|
72
71
|
'@eslint-react/hooks-extra/prefer-use-state-lazy-initialization': 'warn',
|
|
73
72
|
|
|
@@ -119,4 +118,4 @@ function react() {
|
|
|
119
118
|
};
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
|
|
121
|
+
export default react;
|
package/src/modules/storybook.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
const { globs } = require('../utils/globs');
|
|
1
|
+
import plugin from 'eslint-plugin-storybook';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
4
|
+
|
|
5
|
+
/** @return { import('eslint').Linter.Config } */
|
|
5
6
|
function storybook() {
|
|
6
7
|
return {
|
|
7
8
|
files: globs.storybook,
|
|
@@ -31,4 +32,4 @@ function storybook() {
|
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
export default storybook;
|
package/src/modules/tailwind.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/** @return { Promise<import('eslint').Linter.
|
|
2
|
-
function tailwind() {
|
|
3
|
-
const plugin =
|
|
4
|
-
|
|
1
|
+
/** @return { Promise<import('eslint').Linter.Config> } */
|
|
2
|
+
async function tailwind() {
|
|
3
|
+
const plugin = await import('eslint-plugin-tailwindcss');
|
|
5
4
|
return {
|
|
6
5
|
plugins: { tailwindcss: plugin },
|
|
7
6
|
rules: {
|
|
@@ -16,4 +15,4 @@ function tailwind() {
|
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
export default tailwind;
|
package/src/modules/tests.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-jest-formatting';
|
|
2
|
+
import globals from 'globals';
|
|
3
|
+
|
|
4
|
+
import { predicate } from '../utils/conditions.js';
|
|
5
|
+
import { globs } from '../utils/globs.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* @param {import('../
|
|
8
|
-
* @return { import('eslint').Linter.
|
|
8
|
+
* @param {import('../index.js').Options} options
|
|
9
|
+
* @return { import('eslint').Linter.Config }
|
|
9
10
|
*/
|
|
10
11
|
function tests(options = {}) {
|
|
11
12
|
return {
|
|
@@ -45,4 +46,4 @@ function tests(options = {}) {
|
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
export default tests;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { parser, plugin } from 'typescript-eslint';
|
|
2
|
+
|
|
3
|
+
import { predicate } from '../utils/conditions.js';
|
|
4
|
+
import { globs } from '../utils/globs.js';
|
|
5
|
+
import { namingConvention } from '../utils/naming-convention.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* @param {import('../
|
|
8
|
-
* @return { import('eslint').Linter.
|
|
8
|
+
* @param {import('../index.js').Options} options
|
|
9
|
+
* @return { import('eslint').Linter.Config }
|
|
9
10
|
*/
|
|
10
11
|
function typescript(options = {}) {
|
|
11
12
|
return {
|
|
@@ -36,7 +37,6 @@ function typescript(options = {}) {
|
|
|
36
37
|
},
|
|
37
38
|
],
|
|
38
39
|
'@typescript-eslint/ban-tslint-comment': 'off',
|
|
39
|
-
'@typescript-eslint/ban-types': 'error',
|
|
40
40
|
'@typescript-eslint/camelcase': 'off',
|
|
41
41
|
'@typescript-eslint/class-literal-property-style': ['error', 'getters'],
|
|
42
42
|
'@typescript-eslint/consistent-generic-constructors': ['warn', 'constructor'],
|
|
@@ -86,7 +86,6 @@ function typescript(options = {}) {
|
|
|
86
86
|
'@typescript-eslint/no-invalid-this': ['error', { capIsConstructor: false }],
|
|
87
87
|
'@typescript-eslint/no-invalid-void-type': 'error',
|
|
88
88
|
'@typescript-eslint/no-loop-func': 'error',
|
|
89
|
-
'@typescript-eslint/no-loss-of-precision': 'error',
|
|
90
89
|
'@typescript-eslint/no-magic-numbers': ['off', { ignoreEnums: true }], // Not good enough yet
|
|
91
90
|
'@typescript-eslint/no-misused-new': 'error',
|
|
92
91
|
'@typescript-eslint/no-namespace': 'error',
|
|
@@ -116,7 +115,6 @@ function typescript(options = {}) {
|
|
|
116
115
|
'@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: true }],
|
|
117
116
|
'@typescript-eslint/no-useless-constructor': 'error',
|
|
118
117
|
'@typescript-eslint/no-useless-empty-export': 'warn',
|
|
119
|
-
'@typescript-eslint/no-var-requires': 'error',
|
|
120
118
|
'@typescript-eslint/object-curly-spacing': 'warn',
|
|
121
119
|
'@typescript-eslint/parameter-properties': 'off',
|
|
122
120
|
'@typescript-eslint/prefer-as-const': 'warn',
|
|
@@ -134,27 +132,6 @@ function typescript(options = {}) {
|
|
|
134
132
|
'@typescript-eslint/prefer-ts-expect-error': 'off',
|
|
135
133
|
'@typescript-eslint/promise-function-async': 'off',
|
|
136
134
|
'@typescript-eslint/restrict-plus-operands': 'off',
|
|
137
|
-
'@typescript-eslint/sort-type-constituents': [
|
|
138
|
-
'warn',
|
|
139
|
-
{
|
|
140
|
-
checkIntersections: true,
|
|
141
|
-
checkUnions: true,
|
|
142
|
-
groupOrder: [
|
|
143
|
-
'named',
|
|
144
|
-
'keyword',
|
|
145
|
-
'operator',
|
|
146
|
-
'literal',
|
|
147
|
-
'function',
|
|
148
|
-
'import',
|
|
149
|
-
'conditional',
|
|
150
|
-
'object',
|
|
151
|
-
'tuple',
|
|
152
|
-
'intersection',
|
|
153
|
-
'union',
|
|
154
|
-
'nullish',
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
135
|
'@typescript-eslint/strict-boolean-expressions': 'off', // Annoying
|
|
159
136
|
'@typescript-eslint/space-before-blocks': 'off',
|
|
160
137
|
|
|
@@ -268,4 +245,4 @@ function typescript(options = {}) {
|
|
|
268
245
|
};
|
|
269
246
|
}
|
|
270
247
|
|
|
271
|
-
|
|
248
|
+
export default typescript;
|
package/src/modules/vitest.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import plugin from 'eslint-plugin-vitest';
|
|
2
|
+
|
|
3
|
+
import { globs } from '../utils/globs.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* @return { import('eslint').Linter.
|
|
6
|
+
* @return { import('eslint').Linter.Config }
|
|
6
7
|
*/
|
|
7
8
|
function vitest() {
|
|
8
9
|
return {
|
|
@@ -81,4 +82,4 @@ function vitest() {
|
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
export default vitest;
|
package/src/utils/compose.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { ignoreGlobs } from './globs.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @param { (options: import('eslint').Linter.
|
|
5
|
-
* @param { import('../
|
|
6
|
-
* @return { import('eslint').Linter.
|
|
4
|
+
* @param { (options: import('eslint').Linter.Config) => import('eslint').Linter.Config } module
|
|
5
|
+
* @param { import('../index.js').Options } options
|
|
6
|
+
* @return { import('eslint').Linter.Config }
|
|
7
7
|
*/
|
|
8
|
-
function compose(module, options) {
|
|
8
|
+
export function compose(module, options) {
|
|
9
9
|
const config = module(options);
|
|
10
10
|
config.ignores = [...(config.ignores ?? []), ...(options.ignores ?? []), ...(ignoreGlobs ?? [])];
|
|
11
11
|
return config;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
module.exports = compose;
|
package/src/utils/conditions.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @param {import('eslint').Linter.RuleEntry} config
|
|
4
4
|
* @returns {import('eslint').Linter.RuleEntry}
|
|
5
5
|
*/
|
|
6
|
-
const
|
|
6
|
+
export const strict = (options, config) => {
|
|
7
7
|
return options.strict ? config : 'off';
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -12,9 +12,6 @@ const strictRule = (options, config) => {
|
|
|
12
12
|
* @param {import('eslint').Linter.RulesRecord} config
|
|
13
13
|
* @returns {import('eslint').Linter.RulesRecord | undefined}
|
|
14
14
|
*/
|
|
15
|
-
const predicate = (condition, config) => {
|
|
15
|
+
export const predicate = (condition, config) => {
|
|
16
16
|
return condition ? config : undefined;
|
|
17
17
|
};
|
|
18
|
-
|
|
19
|
-
module.exports.strict = strictRule;
|
|
20
|
-
module.exports.predicate = predicate;
|
package/src/utils/globs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const srcExt = '?([cm])[jt]s?(x)';
|
|
2
2
|
|
|
3
|
-
const globs = {
|
|
3
|
+
export const globs = {
|
|
4
4
|
src: `**/*.${srcExt}`,
|
|
5
5
|
js: '**/*.?([cm])js',
|
|
6
6
|
jsx: '**/*.?([cm])jsx',
|
|
@@ -34,8 +34,8 @@ const globs = {
|
|
|
34
34
|
e2e: [`**/e2e/*.${srcExt}`],
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
const allSrc = [globs.src, globs.style, globs.allJson, globs.md, globs.svelte, globs.vue, globs.yaml, globs.xml, globs.html];
|
|
38
|
-
const ignoreGlobs = [
|
|
37
|
+
export const allSrc = [globs.src, globs.style, globs.allJson, globs.md, globs.svelte, globs.vue, globs.yaml, globs.xml, globs.html];
|
|
38
|
+
export const ignoreGlobs = [
|
|
39
39
|
'**/node_modules',
|
|
40
40
|
'**/dist',
|
|
41
41
|
'**/package-lock.json',
|
|
@@ -66,7 +66,3 @@ const ignoreGlobs = [
|
|
|
66
66
|
|
|
67
67
|
'**/__snapshots__',
|
|
68
68
|
];
|
|
69
|
-
|
|
70
|
-
module.exports.globs = globs;
|
|
71
|
-
module.exports.allSrc = allSrc;
|
|
72
|
-
module.exports.ignoreGlobs = ignoreGlobs;
|
package/src/modules/strict.js
DELETED