@zilero/eslint 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -0
- package/README.md +112 -0
- package/eslint.config.js +462 -0
- package/index.d.ts +32 -0
- package/index.js +3 -0
- package/package.json +73 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Aleksandr
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# 🎯 @zilero/eslint
|
2
|
+
|
3
|
+
<p align="center">
|
4
|
+
<a href="https://github.com/Zilero232/dev-config-hub">
|
5
|
+
<img src="https://img.shields.io/github/actions/workflow/status/Zilero232/dev-config-hub/integrate.yaml?label=CI&logo=GitHub" alt="CI status">
|
6
|
+
</a>
|
7
|
+
<a href="https://www.npmjs.com/package/@zilero/eslint">
|
8
|
+
<img src="https://img.shields.io/npm/dm/@zilero/eslint?logo=NPM" alt="npm downloads">
|
9
|
+
</a>
|
10
|
+
<a href="https://github.com/Zilero232/cli">
|
11
|
+
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="npm license">
|
12
|
+
</a>
|
13
|
+
<a href="https://github.com/Zilero232/dev-config-hub/tree/main/tools/eslint">
|
14
|
+
<img src="https://img.shields.io/npm/v/@zilero/eslint?label=version" alt="version">
|
15
|
+
</a>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
> ✨ Comprehensive ESLint configuration for React and Node.js projects with TypeScript support
|
19
|
+
|
20
|
+
## ✨ Features
|
21
|
+
|
22
|
+
- 📦 Ready - made configuration out of the box
|
23
|
+
- 🚀 Optimized for React and Node.js
|
24
|
+
- 💪 Full TypeScript support
|
25
|
+
- 🎨 Integration with Prettier
|
26
|
+
- ⚡ High performance
|
27
|
+
- 🔧 Easy setup
|
28
|
+
- 📱 Next support.JS
|
29
|
+
- 🎭 JSX/TSX compatibility
|
30
|
+
|
31
|
+
## 📥 Installation
|
32
|
+
|
33
|
+
### Using npm
|
34
|
+
|
35
|
+
```bash
|
36
|
+
npm install --save-dev @zilero/eslint
|
37
|
+
```
|
38
|
+
### Using yarn
|
39
|
+
|
40
|
+
```bash
|
41
|
+
yarn add -D @zilero/eslint
|
42
|
+
```
|
43
|
+
|
44
|
+
### Using pnpm
|
45
|
+
|
46
|
+
```bash
|
47
|
+
pnpm install -D @zilero/eslint
|
48
|
+
```
|
49
|
+
|
50
|
+
## 🚀 Quick start
|
51
|
+
|
52
|
+
Create the `.eslint.config.js` at the root of your project:
|
53
|
+
|
54
|
+
```javascript
|
55
|
+
import { eslint } from '@zilero/eslint';
|
56
|
+
|
57
|
+
export default eslint({
|
58
|
+
typescript: true
|
59
|
+
});
|
60
|
+
```
|
61
|
+
|
62
|
+
Add scripts to your `package.json`:
|
63
|
+
|
64
|
+
```json
|
65
|
+
"scripts": {
|
66
|
+
"lint:check": "eslint",
|
67
|
+
"lint:fix": "eslint --fix",
|
68
|
+
}
|
69
|
+
```
|
70
|
+
|
71
|
+
## 🤝 Contributing
|
72
|
+
|
73
|
+
We'd love for you to contribute to `@zilero/eslint`! Whether it's reporting bugs, suggesting features, or submitting pull requests, your help is always appreciated.
|
74
|
+
|
75
|
+
### How to contribute:
|
76
|
+
|
77
|
+
1. Fork the repository.
|
78
|
+
2. Create a new branch (`git checkout -b feature/your-feature`).
|
79
|
+
3. Make your changes.
|
80
|
+
4. Commit your changes (`git commit -am 'Add new feature'`).
|
81
|
+
5. Push to the branch (`git push origin feature/your-feature`).
|
82
|
+
6. Open a pull request.
|
83
|
+
|
84
|
+
## 📜 Code of Conduct
|
85
|
+
|
86
|
+
Please follow our [Code of Conduct](CODE_OF_CONDUCT.md) when participating in this project to ensure a welcoming and productive atmosphere.
|
87
|
+
|
88
|
+
## 🔒 Security Policy
|
89
|
+
|
90
|
+
Security is our priority. If you encounter any issues, please read our full [Security Policy](SECURITY.md) to report vulnerabilities safely and responsibly.
|
91
|
+
|
92
|
+
## 👥 Team
|
93
|
+
|
94
|
+
These folks keep the project moving and are resources for help.
|
95
|
+
|
96
|
+
<table>
|
97
|
+
<tbody>
|
98
|
+
<tr>
|
99
|
+
<td align="center" valign="top" width="11%">
|
100
|
+
<a href="https://career.habr.com/zilero">
|
101
|
+
<img src="https://avatars.githubusercontent.com/u/68345676?s=400&u=eb7df22c29a8aca48def78ec54a7526601c9fd8f&v=4" width="100" height="100" alt="Artemev Alexandr - Avatar">
|
102
|
+
<br />
|
103
|
+
Artemev A. A.
|
104
|
+
</a>
|
105
|
+
</td>
|
106
|
+
</tr>
|
107
|
+
</tbody>
|
108
|
+
</table>
|
109
|
+
|
110
|
+
## 📄 License
|
111
|
+
|
112
|
+
License `@zilero/eslint` is licensed under the [MIT License](LICENSE).
|
package/eslint.config.js
ADDED
@@ -0,0 +1,462 @@
|
|
1
|
+
import antfu from '@antfu/eslint-config';
|
2
|
+
import pluginNext from '@next/eslint-plugin-next';
|
3
|
+
import pluginJsxA11y from 'eslint-plugin-jsx-a11y';
|
4
|
+
import pluginReact from 'eslint-plugin-react';
|
5
|
+
import { transformRules } from './utils/transformRules';
|
6
|
+
|
7
|
+
/** @type {import('@zilero/eslint').Eslint} */
|
8
|
+
export const eslint = ({ jsxA11y = false, next = false, sort = false, ...options }, ...configs) => {
|
9
|
+
const stylistic = options?.stylistic ?? false;
|
10
|
+
|
11
|
+
if (next) {
|
12
|
+
configs.unshift({
|
13
|
+
name: 'eslint/next',
|
14
|
+
plugins: {
|
15
|
+
'eslint-next': pluginNext,
|
16
|
+
},
|
17
|
+
rules: {
|
18
|
+
...transformRules(pluginNext.configs.recommended.rules, '@next/next', 'eslint-next'),
|
19
|
+
},
|
20
|
+
});
|
21
|
+
}
|
22
|
+
|
23
|
+
if (jsxA11y) {
|
24
|
+
configs.unshift({
|
25
|
+
name: 'eslint/jsx-a11y',
|
26
|
+
plugins: {
|
27
|
+
'eslint-jsx-a11y': pluginJsxA11y,
|
28
|
+
},
|
29
|
+
rules: {
|
30
|
+
...transformRules(pluginJsxA11y.flatConfigs.recommended.rules, 'jsx-a11y', 'eslint-jsx-a11y'),
|
31
|
+
},
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
if (options.react) {
|
36
|
+
configs.unshift({
|
37
|
+
name: 'eslint/react',
|
38
|
+
plugins: {
|
39
|
+
'eslint-react': pluginReact,
|
40
|
+
},
|
41
|
+
rules: {
|
42
|
+
...transformRules(pluginReact.configs.recommended.rules, 'react', 'eslint-react'),
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Enforce arrow functions for React components
|
46
|
+
* @example
|
47
|
+
* // ✓ Good
|
48
|
+
* const Component = () => { return <div />; }
|
49
|
+
* // ✗ Bad
|
50
|
+
* function Component() { return <div />; }
|
51
|
+
*/
|
52
|
+
'eslint-react/function-component-definition': [
|
53
|
+
'error',
|
54
|
+
{
|
55
|
+
namedComponents: ['arrow-function'], // For named components
|
56
|
+
unnamedComponents: 'arrow-function', // For anonymous components
|
57
|
+
},
|
58
|
+
],
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Disable PropTypes validation
|
62
|
+
* Use TypeScript types instead of runtime checks
|
63
|
+
*/
|
64
|
+
'eslint-react/prop-types': 'off',
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Disable React import requirement
|
68
|
+
* Not needed in modern React with new JSX transform
|
69
|
+
* @example
|
70
|
+
* // ✓ Good
|
71
|
+
* const App = () => <div />
|
72
|
+
* // Old way (no longer needed)
|
73
|
+
* import React from 'react'
|
74
|
+
*/
|
75
|
+
'eslint-react/react-in-jsx-scope': 'off',
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Enforce destructuring for props and state
|
79
|
+
* @example
|
80
|
+
* // ✓ Good
|
81
|
+
* const { name, age } = props;
|
82
|
+
* // ✗ Bad
|
83
|
+
* const name = props.name;
|
84
|
+
*/
|
85
|
+
'eslint-react/destructuring-assignment': ['error', 'always'],
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Enforce consistent naming for hooks
|
89
|
+
* @example
|
90
|
+
* // ✓ Good
|
91
|
+
* const useCustomHook = () => {};
|
92
|
+
* // ✗ Bad
|
93
|
+
* const customHook = () => {};
|
94
|
+
*/
|
95
|
+
'eslint-react/hook-naming-convention': [
|
96
|
+
'error',
|
97
|
+
{
|
98
|
+
prefix: 'use',
|
99
|
+
},
|
100
|
+
],
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Enforce consistent naming for boolean props
|
104
|
+
* @example
|
105
|
+
* // ✓ Good
|
106
|
+
* <Component isVisible={true} hasData={false} />
|
107
|
+
* // ✗ Bad
|
108
|
+
* <Component visible={true} data={false} />
|
109
|
+
*/
|
110
|
+
'eslint-react/boolean-prop-naming': ['error', { prefix: 'is|has|should|can|will|did' }],
|
111
|
+
},
|
112
|
+
|
113
|
+
// React-specific settings
|
114
|
+
settings: {
|
115
|
+
react: {
|
116
|
+
version: 'detect', // Automatically detect React version
|
117
|
+
},
|
118
|
+
},
|
119
|
+
});
|
120
|
+
}
|
121
|
+
|
122
|
+
if (stylistic) {
|
123
|
+
configs.unshift({
|
124
|
+
name: 'eslint/formatter',
|
125
|
+
rules: {
|
126
|
+
/**
|
127
|
+
* Always require parentheses around arrow function arguments
|
128
|
+
* @example
|
129
|
+
* // ✓ Good
|
130
|
+
* (x) => x
|
131
|
+
* // ✗ Bad
|
132
|
+
* x => x
|
133
|
+
*/
|
134
|
+
'style/arrow-parens': ['error', 'always'],
|
135
|
+
|
136
|
+
/**
|
137
|
+
* Brace style for blocks - disabled to avoid conflicts
|
138
|
+
* Let other rules handle this
|
139
|
+
*/
|
140
|
+
'style/brace-style': 'off',
|
141
|
+
|
142
|
+
/**
|
143
|
+
* Disallow trailing commas
|
144
|
+
* @example
|
145
|
+
* // ✓ Good
|
146
|
+
* { a: 1, b: 2 }
|
147
|
+
* // ✗ Bad
|
148
|
+
* { a: 1, b: 2, }
|
149
|
+
*/
|
150
|
+
'style/comma-dangle': ['error', 'never'],
|
151
|
+
|
152
|
+
/**
|
153
|
+
* Enforce 2 spaces indentation with 1 space for switch cases
|
154
|
+
* @example
|
155
|
+
* // ✓ Good
|
156
|
+
* function foo() {
|
157
|
+
* if (bar) {
|
158
|
+
* baz();
|
159
|
+
* }
|
160
|
+
* }
|
161
|
+
*/
|
162
|
+
'style/indent': ['error', 2, { SwitchCase: 1 }],
|
163
|
+
|
164
|
+
/**
|
165
|
+
* JSX newline formatting - disabled for better readability
|
166
|
+
*/
|
167
|
+
'style/jsx-curly-newline': 'off',
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Allow multiple JSX expressions per line
|
171
|
+
*/
|
172
|
+
'style/jsx-one-expression-per-line': 'off',
|
173
|
+
|
174
|
+
/**
|
175
|
+
* Use single quotes in JSX
|
176
|
+
* @example
|
177
|
+
* // ✓ Good
|
178
|
+
* <div className='foo'>
|
179
|
+
* // ✗ Bad
|
180
|
+
* <div className="foo">
|
181
|
+
*/
|
182
|
+
'style/jsx-quotes': ['error', 'prefer-single'],
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Enforce Unix linebreaks (LF)
|
186
|
+
* Prevents issues with different operating systems
|
187
|
+
*/
|
188
|
+
'style/linebreak-style': ['error', 'unix'],
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Maximum line length of 150 characters
|
192
|
+
* Ignores comments, strings, and template literals
|
193
|
+
* @example
|
194
|
+
* // ✓ Good: Lines under 150 characters
|
195
|
+
* // ✗ Bad: Lines over 150 characters (with exceptions)
|
196
|
+
*/
|
197
|
+
'style/max-len': [
|
198
|
+
'error',
|
199
|
+
150,
|
200
|
+
2,
|
201
|
+
{
|
202
|
+
ignoreComments: true, // Ignore comments when checking length
|
203
|
+
ignoreStrings: true, // Ignore strings when checking length
|
204
|
+
ignoreTemplateLiterals: true, // Ignore template literals when checking length
|
205
|
+
},
|
206
|
+
],
|
207
|
+
|
208
|
+
/**
|
209
|
+
* TypeScript interface/type member delimiter style - disabled
|
210
|
+
*/
|
211
|
+
'style/member-delimiter-style': 'off',
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Allow flexible multiline ternary expressions
|
215
|
+
*/
|
216
|
+
'style/multiline-ternary': 'off',
|
217
|
+
|
218
|
+
/**
|
219
|
+
* Disallow tabs in favor of spaces
|
220
|
+
*/
|
221
|
+
'style/no-tabs': 'error',
|
222
|
+
|
223
|
+
/**
|
224
|
+
* Allow flexible operator linebreaks
|
225
|
+
*/
|
226
|
+
'style/operator-linebreak': 'off',
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Quotation marks for object properties - disabled
|
230
|
+
*/
|
231
|
+
'style/quote-props': 'off',
|
232
|
+
|
233
|
+
/**
|
234
|
+
* Use single quotes for strings, allow template literals
|
235
|
+
* @example
|
236
|
+
* // ✓ Good
|
237
|
+
* const str = 'string'
|
238
|
+
* const template = `template`
|
239
|
+
* // ✗ Bad
|
240
|
+
* const str = "string"
|
241
|
+
*/
|
242
|
+
'style/quotes': ['error', 'single', { allowTemplateLiterals: true }],
|
243
|
+
|
244
|
+
/**
|
245
|
+
* Require semicolons at the end of statements
|
246
|
+
* @example
|
247
|
+
* // ✓ Good
|
248
|
+
* const foo = 'bar';
|
249
|
+
* // ✗ Bad
|
250
|
+
* const foo = 'bar'
|
251
|
+
*/
|
252
|
+
'style/semi': ['error', 'always'],
|
253
|
+
},
|
254
|
+
});
|
255
|
+
}
|
256
|
+
|
257
|
+
if (sort) {
|
258
|
+
configs.unshift({
|
259
|
+
name: 'eslint/sort',
|
260
|
+
rules: {
|
261
|
+
/**
|
262
|
+
* Sort array includes calls alphabetically
|
263
|
+
* @example
|
264
|
+
* // ✓ Good
|
265
|
+
* ['a', 'b', 'c'].includes(x)
|
266
|
+
* // ✗ Bad
|
267
|
+
* ['c', 'a', 'b'].includes(x)
|
268
|
+
*/
|
269
|
+
'perfectionist/sort-array-includes': [
|
270
|
+
'error',
|
271
|
+
{
|
272
|
+
order: 'asc', // Ascending order
|
273
|
+
type: 'alphabetical', // Sort alphabetically
|
274
|
+
},
|
275
|
+
],
|
276
|
+
|
277
|
+
/**
|
278
|
+
* Enforce consistent import ordering
|
279
|
+
* Groups:
|
280
|
+
* 1. Type imports
|
281
|
+
* 2. Built-in & external modules
|
282
|
+
* 3. Internal type imports
|
283
|
+
* 4. Internal modules
|
284
|
+
* 5. Parent/sibling type imports
|
285
|
+
* 6. Parent/sibling modules
|
286
|
+
* 7. Object imports
|
287
|
+
* 8. Style imports
|
288
|
+
* 9. Side effect styles
|
289
|
+
* 10. Unknown
|
290
|
+
*/
|
291
|
+
'perfectionist/sort-imports': [
|
292
|
+
'error',
|
293
|
+
{
|
294
|
+
groups: [
|
295
|
+
'type', // Type imports first
|
296
|
+
['builtin', 'external'], // Node.js and external packages
|
297
|
+
'internal-type', // Internal type imports
|
298
|
+
['internal'], // Internal modules
|
299
|
+
['parent-type', 'sibling-type', 'index-type'], // Relative type imports
|
300
|
+
['parent', 'sibling', 'index'], // Relative module imports
|
301
|
+
'object', // Object imports
|
302
|
+
'style', // Style imports
|
303
|
+
'side-effect-style', // Side effect styles
|
304
|
+
'unknown', // Everything else
|
305
|
+
],
|
306
|
+
internalPattern: ['^~/.*', '^@/.*'], // Internal module patterns
|
307
|
+
newlinesBetween: 'always', // Always add newlines between groups
|
308
|
+
order: 'asc', // Ascending order
|
309
|
+
type: 'natural', // Natural sort order
|
310
|
+
},
|
311
|
+
],
|
312
|
+
|
313
|
+
/**
|
314
|
+
* Sort interface members
|
315
|
+
* @example
|
316
|
+
* // ✓ Good
|
317
|
+
* interface User {
|
318
|
+
* age: number;
|
319
|
+
* name: string;
|
320
|
+
* sayHello(): void;
|
321
|
+
* }
|
322
|
+
*/
|
323
|
+
'perfectionist/sort-interfaces': [
|
324
|
+
'error',
|
325
|
+
{
|
326
|
+
groups: ['unknown', 'method', 'multiline'], // Group by type
|
327
|
+
order: 'asc', // Ascending order
|
328
|
+
type: 'alphabetical', // Sort alphabetically
|
329
|
+
},
|
330
|
+
],
|
331
|
+
|
332
|
+
/**
|
333
|
+
* Sort JSX props in consistent order
|
334
|
+
* @example
|
335
|
+
* // ✓ Good
|
336
|
+
* <Button
|
337
|
+
* ref={ref}
|
338
|
+
* disabled
|
339
|
+
* label="Click me"
|
340
|
+
* onClick={handleClick}
|
341
|
+
* />
|
342
|
+
*/
|
343
|
+
'perfectionist/sort-jsx-props': [
|
344
|
+
'error',
|
345
|
+
{
|
346
|
+
customGroups: {
|
347
|
+
callback: 'on*', // Event handlers
|
348
|
+
reserved: ['key', 'ref'], // React special props
|
349
|
+
},
|
350
|
+
groups: [
|
351
|
+
'shorthand', // Boolean props
|
352
|
+
'reserved', // React special props
|
353
|
+
'multiline', // Multiline props
|
354
|
+
'unknown', // Other props
|
355
|
+
'callback', // Event handlers
|
356
|
+
],
|
357
|
+
order: 'asc', // Ascending order
|
358
|
+
type: 'alphabetical', // Sort alphabetically
|
359
|
+
},
|
360
|
+
],
|
361
|
+
|
362
|
+
/**
|
363
|
+
* Sort union types consistently
|
364
|
+
* @example
|
365
|
+
* // ✓ Good
|
366
|
+
* type Status = 'error' | 'loading' | 'success';
|
367
|
+
* type Value = boolean | null | number | string;
|
368
|
+
*/
|
369
|
+
'perfectionist/sort-union-types': [
|
370
|
+
'error',
|
371
|
+
{
|
372
|
+
groups: [
|
373
|
+
'conditional', // Conditional types
|
374
|
+
'function', // Function types
|
375
|
+
'import', // Import types
|
376
|
+
'intersection', // Intersection types
|
377
|
+
'keyword', // TypeScript keywords
|
378
|
+
'literal', // Literal types
|
379
|
+
'named', // Named types
|
380
|
+
'object', // Object types
|
381
|
+
'operator', // Operator types
|
382
|
+
'tuple', // Tuple types
|
383
|
+
'union', // Union types
|
384
|
+
'nullish', // null/undefined
|
385
|
+
],
|
386
|
+
order: 'asc', // Ascending order
|
387
|
+
specialCharacters: 'keep', // Keep special characters
|
388
|
+
type: 'alphabetical', // Sort alphabetically
|
389
|
+
},
|
390
|
+
],
|
391
|
+
},
|
392
|
+
});
|
393
|
+
}
|
394
|
+
|
395
|
+
return antfu(
|
396
|
+
{ ...options, stylistic },
|
397
|
+
{
|
398
|
+
name: 'eslint/rewrite',
|
399
|
+
rules: {
|
400
|
+
/**
|
401
|
+
* Disable requirement for curly braces
|
402
|
+
* Allows single-line if statements without braces
|
403
|
+
* @example
|
404
|
+
* // Both are allowed:
|
405
|
+
* if (foo) bar();
|
406
|
+
* if (foo) { bar(); }
|
407
|
+
*/
|
408
|
+
'antfu/curly': 'off',
|
409
|
+
|
410
|
+
/**
|
411
|
+
* Disable forced newline after if statement
|
412
|
+
* Allows more flexible formatting
|
413
|
+
* @example
|
414
|
+
* // Both are allowed:
|
415
|
+
* if (foo) bar();
|
416
|
+
* if (foo)
|
417
|
+
* bar();
|
418
|
+
*/
|
419
|
+
'antfu/if-newline': 'off',
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Disable top-level function requirements
|
423
|
+
* Allows both named and anonymous functions at top level
|
424
|
+
* @example
|
425
|
+
* // Both are allowed:
|
426
|
+
* function foo() {}
|
427
|
+
* export default () => {}
|
428
|
+
*/
|
429
|
+
'antfu/top-level-function': 'off',
|
430
|
+
|
431
|
+
/**
|
432
|
+
* Warn on console statements
|
433
|
+
* Helps identify debugging code that shouldn't be in production
|
434
|
+
* @example
|
435
|
+
* // ⚠️ Warns:
|
436
|
+
* console.log('debug');
|
437
|
+
*/
|
438
|
+
'no-console': 'warn',
|
439
|
+
|
440
|
+
/**
|
441
|
+
* Disable exhaustive dependencies check for React hooks
|
442
|
+
* Allows manual control over hook dependencies
|
443
|
+
* @example
|
444
|
+
* // Allowed:
|
445
|
+
* useEffect(() => {}, [selectedDeps])
|
446
|
+
*/
|
447
|
+
'react-hooks/exhaustive-deps': 'off',
|
448
|
+
|
449
|
+
/**
|
450
|
+
* Disable lowercase test title requirement
|
451
|
+
* Allows more flexible test naming
|
452
|
+
* @example
|
453
|
+
* // Both are allowed:
|
454
|
+
* test('my test')
|
455
|
+
* test('My Test')
|
456
|
+
*/
|
457
|
+
'test/prefer-lowercase-title': 'off',
|
458
|
+
},
|
459
|
+
},
|
460
|
+
...configs,
|
461
|
+
);
|
462
|
+
};
|
package/index.d.ts
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import type { Awaitable, ConfigNames, OptionsConfig, TypedFlatConfigItem } from '@antfu/eslint-config';
|
2
|
+
import type { Linter } from 'eslint';
|
3
|
+
import type { FlatConfigComposer } from 'eslint-flat-config-utils';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Basic configuration options.
|
7
|
+
*/
|
8
|
+
interface ConfigOptions extends OptionsConfig, TypedFlatConfigItem {
|
9
|
+
/** Enables accessibility rules for JSX */
|
10
|
+
jsxA11y?: boolean;
|
11
|
+
/** Adds support for Next.js */
|
12
|
+
next?: boolean;
|
13
|
+
/** Sorts rules alphabetically */
|
14
|
+
sort?: boolean;
|
15
|
+
}
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Types of user configurations.
|
19
|
+
*/
|
20
|
+
type UserConfig = Awaitable<FlatConfigComposer<any, any> | TypedFlatConfigItem | TypedFlatConfigItem[] | Linter.Config[]>;
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Main configuration function for ESLint.
|
24
|
+
*/
|
25
|
+
type ConfigFunction = (options?: ConfigOptions, ...userConfigs: UserConfig[]) => FlatConfigComposer<TypedFlatConfigItem, ConfigNames>;
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Exported module.
|
29
|
+
*/
|
30
|
+
declare module '@zilero/eslint' {
|
31
|
+
export const Eslint: ConfigFunction;
|
32
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
{
|
2
|
+
"name": "@zilero/eslint",
|
3
|
+
"icon": "🎯",
|
4
|
+
"displayName": "✨ Zilero ESLint Config",
|
5
|
+
"description": "🎯 Comprehensive ESLint configuration for React and Node.js projects",
|
6
|
+
"license": "MIT",
|
7
|
+
"version": "1.0.0",
|
8
|
+
"keywords": [
|
9
|
+
"eslint",
|
10
|
+
"eslint-config",
|
11
|
+
"react",
|
12
|
+
"node",
|
13
|
+
"typescript",
|
14
|
+
"javascript",
|
15
|
+
"linting",
|
16
|
+
"prettier",
|
17
|
+
"style-guide",
|
18
|
+
"code-quality"
|
19
|
+
],
|
20
|
+
"author": {
|
21
|
+
"name": "Artemev Alexandr",
|
22
|
+
"url": "https://github.com/Zilero232",
|
23
|
+
"email": "sasha.artemev.1002@mail.ru"
|
24
|
+
},
|
25
|
+
"bugs": {
|
26
|
+
"url": "https://github.com/Zilero232/dev-config-hub/issues"
|
27
|
+
},
|
28
|
+
"homepage": "https://github.com/Zilero232/dev-config-hub",
|
29
|
+
"repository": {
|
30
|
+
"url": "git+https://github.com/Zilero232/dev-config-hub.git"
|
31
|
+
},
|
32
|
+
"publishConfig": {
|
33
|
+
"access": "public"
|
34
|
+
},
|
35
|
+
"files": [
|
36
|
+
"index.d.ts",
|
37
|
+
"eslint.config.js",
|
38
|
+
"index.js"
|
39
|
+
],
|
40
|
+
"main": "index.js",
|
41
|
+
"peerDependencies": {
|
42
|
+
"eslint": "^9.0.0"
|
43
|
+
},
|
44
|
+
"engines": {
|
45
|
+
"node": ">=16.0.0",
|
46
|
+
"npm": ">=7.0.0"
|
47
|
+
},
|
48
|
+
"funding": {
|
49
|
+
"type": "github",
|
50
|
+
"url": "https://github.com/sponsors/Zilero232"
|
51
|
+
},
|
52
|
+
"categories": [
|
53
|
+
"Formatters",
|
54
|
+
"Linters"
|
55
|
+
],
|
56
|
+
"contributors": [
|
57
|
+
{
|
58
|
+
"name": "Artemev Alexandr",
|
59
|
+
"url": "https://github.com/Zilero232"
|
60
|
+
}
|
61
|
+
],
|
62
|
+
"dependencies": {
|
63
|
+
"@antfu/eslint-config": "3.12.1",
|
64
|
+
"@eslint-react/eslint-plugin": "1.23.1",
|
65
|
+
"@next/eslint-plugin-next": "15.1.3",
|
66
|
+
"@vue/compiler-sfc": "3.5.13",
|
67
|
+
"eslint": "9.17.0",
|
68
|
+
"eslint-plugin-jsx-a11y": "6.10.2",
|
69
|
+
"eslint-plugin-react": "7.37.3",
|
70
|
+
"eslint-plugin-react-hooks": "5.1.0",
|
71
|
+
"eslint-plugin-react-refresh": "0.4.16"
|
72
|
+
}
|
73
|
+
}
|