@dmitryrechkin/eslint-standard 1.0.7 โ 1.1.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/LICENSE +21 -674
- package/README.md +221 -70
- package/eslint-plugin-jsdoc-indent.mjs +134 -0
- package/eslint.config.mjs +66 -11
- package/package.json +40 -18
- package/tsconfig.json +0 -18
package/README.md
CHANGED
|
@@ -1,123 +1,274 @@
|
|
|
1
1
|
|
|
2
2
|
# @dmitryrechkin/eslint-standard
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
A comprehensive ESLint configuration package with TypeScript support, featuring **automatic formatting and code organization**. This configuration enforces consistent code style across projects with powerful auto-fixing capabilities for imports, class members, JSDoc comments, and more.
|
|
5
5
|
|
|
6
|
-
## Features
|
|
6
|
+
## โจ Features
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **Optimizations for Unused Imports**: Utilizes `eslint-plugin-unused-imports` to automatically detect and remove unused imports, keeping your code clean and efficient.
|
|
8
|
+
### **Auto-Fixing Capabilities**
|
|
9
|
+
- ๐ **Automatic Import Sorting**: Organizes imports with type imports and regular imports properly grouped
|
|
10
|
+
- ๐๏ธ **Class Member Ordering**: Auto-reorders class members by visibility (public โ protected โ private) and type (fields โ constructor โ methods)
|
|
11
|
+
- ๐ **JSDoc Alignment**: Automatically fixes JSDoc comment indentation and alignment with proper tab formatting
|
|
12
|
+
- ๐งน **Unused Import Removal**: Automatically detects and removes unused imports
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
### **Code Style Enforcement**
|
|
15
|
+
- **TypeScript Support**: Full integration with `@typescript-eslint` for TypeScript-specific best practices
|
|
16
|
+
- **Modern JavaScript**: Supports ECMAScript 2020 and newer features
|
|
17
|
+
- **Consistent Formatting**: Enforces Allman brace style, tab indentation, single quotes, and semicolons
|
|
18
|
+
- **Naming Conventions**: Comprehensive naming rules for variables, functions, classes, and more
|
|
19
|
+
- **Customizable**: Flexible configuration options for different project needs
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
## ๐ฆ Installation
|
|
22
|
+
|
|
23
|
+
### Install the Package and Peer Dependencies
|
|
18
24
|
|
|
19
25
|
```bash
|
|
20
|
-
npm install @dmitryrechkin/eslint-standard
|
|
26
|
+
npm install @dmitryrechkin/eslint-standard --save-dev
|
|
21
27
|
```
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
### Install Required Peer Dependencies
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc eslint-plugin-simple-import-sort eslint-plugin-perfectionist --save-dev
|
|
33
|
+
```
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
35
|
+
Or using a single command:
|
|
36
|
+
```bash
|
|
37
|
+
npm install @dmitryrechkin/eslint-standard eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc eslint-plugin-simple-import-sort eslint-plugin-perfectionist --save-dev
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
## ๐ Usage
|
|
41
|
+
|
|
42
|
+
### ESLint 9+ Flat Config (Recommended)
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
Create an `eslint.config.mjs` file in your project root:
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
```javascript
|
|
47
|
+
import eslintStandard from '@dmitryrechkin/eslint-standard';
|
|
48
|
+
|
|
49
|
+
export default eslintStandard({
|
|
50
|
+
tsconfigPath: './tsconfig.json', // Optional: specify path to your tsconfig
|
|
51
|
+
files: ['**/*.{js,jsx,ts,tsx}'], // Optional: specify file patterns
|
|
52
|
+
ignores: ['dist/**', 'node_modules/**'] // Optional: additional ignore patterns
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Advanced Configuration
|
|
38
57
|
|
|
39
58
|
```javascript
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
import eslintStandard from '@dmitryrechkin/eslint-standard';
|
|
60
|
+
|
|
61
|
+
export default eslintStandard({
|
|
62
|
+
tsconfigPath: './tsconfig.json',
|
|
63
|
+
files: ['src/**/*.{ts,tsx}', 'tests/**/*.{ts,tsx}'],
|
|
64
|
+
ignores: ['dist/**', 'coverage/**'],
|
|
65
|
+
plugins: {
|
|
66
|
+
// Add custom plugins
|
|
67
|
+
},
|
|
42
68
|
rules: {
|
|
43
|
-
//
|
|
44
|
-
'no-console': '
|
|
69
|
+
// Override or add custom rules
|
|
70
|
+
'no-console': 'warn',
|
|
71
|
+
'perfectionist/sort-classes': 'off' // Disable auto class member sorting if needed
|
|
45
72
|
}
|
|
46
|
-
};
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Multiple Configurations
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
import eslintStandard from '@dmitryrechkin/eslint-standard';
|
|
80
|
+
|
|
81
|
+
export default [
|
|
82
|
+
// Configuration for source files
|
|
83
|
+
eslintStandard({
|
|
84
|
+
tsconfigPath: './tsconfig.json',
|
|
85
|
+
files: ['src/**/*.{ts,tsx}']
|
|
86
|
+
}),
|
|
87
|
+
|
|
88
|
+
// Configuration for test files with different rules
|
|
89
|
+
eslintStandard({
|
|
90
|
+
tsconfigPath: './tsconfig.json',
|
|
91
|
+
files: ['tests/**/*.{ts,tsx}'],
|
|
92
|
+
rules: {
|
|
93
|
+
'no-console': 'off' // Allow console in tests
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
];
|
|
47
97
|
```
|
|
48
98
|
|
|
49
|
-
##
|
|
99
|
+
## ๐ ๏ธ Package.json Scripts
|
|
50
100
|
|
|
51
|
-
|
|
101
|
+
Add these scripts to your `package.json` for easy linting and formatting:
|
|
52
102
|
|
|
53
103
|
```json
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
104
|
+
{
|
|
105
|
+
"scripts": {
|
|
106
|
+
"lint": "eslint .",
|
|
107
|
+
"lint:fix": "eslint . --fix",
|
|
108
|
+
"format": "eslint . --fix"
|
|
109
|
+
}
|
|
57
110
|
}
|
|
58
111
|
```
|
|
59
112
|
|
|
60
|
-
|
|
113
|
+
### Usage Examples
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Check for linting errors
|
|
117
|
+
npm run lint
|
|
118
|
+
|
|
119
|
+
# Auto-fix all fixable issues (imports, member ordering, JSDoc alignment, etc.)
|
|
120
|
+
npm run lint:fix
|
|
121
|
+
|
|
122
|
+
# Same as lint:fix
|
|
123
|
+
npm run format
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## ๐ฏ What Gets Auto-Fixed
|
|
61
127
|
|
|
62
|
-
|
|
128
|
+
When you run `eslint --fix`, this configuration will automatically:
|
|
63
129
|
|
|
64
|
-
|
|
130
|
+
1. **๐ค Sort Imports**: Organize import statements with type imports grouped correctly
|
|
131
|
+
2. **๐ Reorder Class Members**: Arrange class members by visibility and type:
|
|
132
|
+
- Static properties โ Instance properties โ Constructor โ Static methods โ Instance methods
|
|
133
|
+
- Within each group: public โ protected โ private
|
|
134
|
+
3. **๐ Fix JSDoc Indentation**: Align JSDoc comments with proper tab indentation
|
|
135
|
+
4. **๐งน Remove Unused Imports**: Clean up unused import statements
|
|
136
|
+
5. **โจ Format Code**: Apply consistent spacing, quotes, semicolons, and brace styles
|
|
65
137
|
|
|
66
|
-
|
|
138
|
+
## ๐ Code Style Overview
|
|
67
139
|
|
|
68
|
-
|
|
69
|
-
- **Indentation**: Uses tabs for indentation.
|
|
140
|
+
### ๐ง Formatting Rules
|
|
70
141
|
|
|
71
|
-
**
|
|
142
|
+
- **Brace Style**: Allman style (braces on new lines)
|
|
143
|
+
- **Indentation**: Tabs (configurable tab width)
|
|
144
|
+
- **Quotes**: Single quotes for strings
|
|
145
|
+
- **Semicolons**: Required at statement ends
|
|
146
|
+
- **Trailing Spaces**: Automatically removed
|
|
72
147
|
|
|
73
|
-
|
|
74
|
-
|
|
148
|
+
### ๐ Before and After Examples
|
|
149
|
+
|
|
150
|
+
#### Import Sorting
|
|
151
|
+
```typescript
|
|
152
|
+
// โ Before
|
|
153
|
+
import { TypeResponse } from '../types';
|
|
154
|
+
import type { SomeInterface } from './interfaces';
|
|
155
|
+
import { EnumErrorCode } from '../enums';
|
|
156
|
+
import type { BaseConfig } from '../config';
|
|
157
|
+
|
|
158
|
+
// โ
After (auto-fixed)
|
|
159
|
+
import type { BaseConfig } from '../config';
|
|
160
|
+
import type { SomeInterface } from './interfaces';
|
|
161
|
+
import { EnumErrorCode } from '../enums';
|
|
162
|
+
import { TypeResponse } from '../types';
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### Class Member Ordering
|
|
166
|
+
```typescript
|
|
167
|
+
// โ Before
|
|
168
|
+
export class UserService
|
|
75
169
|
{
|
|
76
|
-
|
|
170
|
+
private isInitialized = false;
|
|
171
|
+
public static readonly VERSION = '1.0.0';
|
|
172
|
+
public readonly name: string;
|
|
173
|
+
|
|
174
|
+
private validateUser() { /* ... */ }
|
|
175
|
+
public async getUser() { /* ... */ }
|
|
176
|
+
public static getInstance() { /* ... */ }
|
|
177
|
+
constructor(name: string) { /* ... */ }
|
|
77
178
|
}
|
|
78
|
-
|
|
179
|
+
|
|
180
|
+
// โ
After (auto-fixed)
|
|
181
|
+
export class UserService
|
|
79
182
|
{
|
|
80
|
-
|
|
183
|
+
public static readonly VERSION = '1.0.0';
|
|
184
|
+
|
|
185
|
+
public readonly name: string;
|
|
186
|
+
private isInitialized = false;
|
|
187
|
+
|
|
188
|
+
constructor(name: string) { /* ... */ }
|
|
189
|
+
|
|
190
|
+
public static getInstance() { /* ... */ }
|
|
191
|
+
|
|
192
|
+
public async getUser() { /* ... */ }
|
|
193
|
+
|
|
194
|
+
private validateUser() { /* ... */ }
|
|
81
195
|
}
|
|
82
196
|
```
|
|
83
197
|
|
|
84
|
-
|
|
198
|
+
#### JSDoc Alignment
|
|
199
|
+
```typescript
|
|
200
|
+
// โ Before
|
|
201
|
+
/**
|
|
202
|
+
* Process user data
|
|
203
|
+
* @param userData - The user data
|
|
204
|
+
* @returns Processed result
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
// โ
After (auto-fixed)
|
|
208
|
+
/**
|
|
209
|
+
* Process user data
|
|
210
|
+
* @param userData - The user data
|
|
211
|
+
* @returns Processed result
|
|
212
|
+
*/
|
|
213
|
+
```
|
|
85
214
|
|
|
86
|
-
|
|
87
|
-
- **Classes**: PascalCase without leading underscores.
|
|
215
|
+
### ๐ท๏ธ Naming Conventions
|
|
88
216
|
|
|
89
|
-
**
|
|
217
|
+
- **Variables & Functions**: `camelCase`
|
|
218
|
+
- **Classes & Interfaces**: `PascalCase`
|
|
219
|
+
- **Constants**: `UPPER_CASE` or `camelCase`
|
|
220
|
+
- **Enum Members**: `UPPER_CASE` or `PascalCase`
|
|
221
|
+
- **Type Parameters**: `PascalCase`
|
|
90
222
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
displayInfo()
|
|
101
|
-
{
|
|
102
|
-
console.log(`User: ${this.userName}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
223
|
+
## โ ๏ธ Troubleshooting
|
|
224
|
+
|
|
225
|
+
### Peer Dependency Warnings
|
|
226
|
+
|
|
227
|
+
If you see peer dependency warnings, install all required dependencies:
|
|
228
|
+
```bash
|
|
229
|
+
npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc eslint-plugin-simple-import-sort eslint-plugin-perfectionist --save-dev
|
|
105
230
|
```
|
|
106
231
|
|
|
107
|
-
###
|
|
232
|
+
### ESLint Version Compatibility
|
|
108
233
|
|
|
109
|
-
|
|
110
|
-
- **Quotes**: Single quotes for strings.
|
|
234
|
+
This package requires **ESLint 9+** for flat config support. For older ESLint versions, please use an earlier version of this package.
|
|
111
235
|
|
|
112
|
-
|
|
236
|
+
### TypeScript Configuration
|
|
113
237
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
238
|
+
Ensure your `tsconfig.json` is properly configured and the path specified in `tsconfigPath` is correct.
|
|
239
|
+
|
|
240
|
+
## ๐ง Configuration Options
|
|
241
|
+
|
|
242
|
+
The configuration function accepts these options:
|
|
243
|
+
|
|
244
|
+
| Option | Type | Default | Description |
|
|
245
|
+
|--------|------|---------|-------------|
|
|
246
|
+
| `tsconfigPath` | `string` | `'./tsconfig.json'` | Path to your TypeScript config file |
|
|
247
|
+
| `files` | `string[]` | `['**/*.{js,jsx,ts,tsx}']` | File patterns to lint |
|
|
248
|
+
| `ignores` | `string[]` | `['node_modules/**', 'dist/**']` | Patterns to ignore |
|
|
249
|
+
| `plugins` | `object` | `{}` | Additional ESLint plugins |
|
|
250
|
+
| `rules` | `object` | `{}` | Additional or overridden rules |
|
|
251
|
+
|
|
252
|
+
## ๐ Plugin Documentation
|
|
253
|
+
|
|
254
|
+
This configuration uses several powerful ESLint plugins:
|
|
255
|
+
|
|
256
|
+
- **[@typescript-eslint](https://typescript-eslint.io/)**: TypeScript-specific linting rules
|
|
257
|
+
- **[eslint-plugin-perfectionist](https://perfectionist.dev/)**: Auto-sorting for classes, imports, and more
|
|
258
|
+
- **[eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort)**: Simple and reliable import sorting
|
|
259
|
+
- **[@stylistic/eslint-plugin](https://eslint.style/)**: Stylistic formatting rules
|
|
260
|
+
- **[eslint-plugin-unused-imports](https://github.com/sweepline/eslint-plugin-unused-imports)**: Automatic unused import removal
|
|
261
|
+
|
|
262
|
+
## ๐ค Contributing
|
|
263
|
+
|
|
264
|
+
Contributions to improve this ESLint configuration are welcome! Please feel free to:
|
|
265
|
+
|
|
266
|
+
- ๐ [Report bugs](https://github.com/dmitryrechkin/eslint-standard/issues)
|
|
267
|
+
- ๐ก [Suggest new features](https://github.com/dmitryrechkin/eslint-standard/issues)
|
|
268
|
+
- ๐ง [Submit pull requests](https://github.com/dmitryrechkin/eslint-standard/pulls)
|
|
118
269
|
|
|
119
|
-
##
|
|
270
|
+
## ๐ License
|
|
120
271
|
|
|
121
|
-
|
|
272
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
122
273
|
|
|
123
274
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom ESLint plugin to auto-fix JSDoc comment indentation and alignment
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const jsdocIndentRule = {
|
|
6
|
+
meta: {
|
|
7
|
+
type: 'layout',
|
|
8
|
+
docs: {
|
|
9
|
+
description: 'Enforce proper indentation and alignment in JSDoc comments',
|
|
10
|
+
category: 'Stylistic Issues',
|
|
11
|
+
recommended: false
|
|
12
|
+
},
|
|
13
|
+
fixable: 'whitespace',
|
|
14
|
+
schema: [
|
|
15
|
+
{
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
tabWidth: {
|
|
19
|
+
type: 'integer',
|
|
20
|
+
minimum: 1,
|
|
21
|
+
default: 4
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
create(context) {
|
|
30
|
+
const options = context.options[0] || {};
|
|
31
|
+
const tabWidth = options.tabWidth || 4;
|
|
32
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
Program() {
|
|
36
|
+
const comments = sourceCode.getAllComments();
|
|
37
|
+
|
|
38
|
+
for (const comment of comments) {
|
|
39
|
+
if (comment.type === 'Block' && comment.value.startsWith('*')) {
|
|
40
|
+
// This is a JSDoc comment
|
|
41
|
+
const lines = comment.value.split('\n');
|
|
42
|
+
|
|
43
|
+
// Get the base indentation from the comment's position
|
|
44
|
+
const commentLoc = sourceCode.getLocFromIndex(comment.range[0]);
|
|
45
|
+
const commentLine = sourceCode.getLines()[commentLoc.line - 1];
|
|
46
|
+
const baseIndentMatch = commentLine.match(/^(\s*)/);
|
|
47
|
+
const baseIndent = baseIndentMatch ? baseIndentMatch[1] : '';
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < lines.length; i++) {
|
|
50
|
+
const line = lines[i];
|
|
51
|
+
|
|
52
|
+
// Skip the opening line (/**)
|
|
53
|
+
if (i === 0) continue;
|
|
54
|
+
|
|
55
|
+
// Handle different line types
|
|
56
|
+
const trimmedLine = line.trim();
|
|
57
|
+
|
|
58
|
+
// Lines without asterisks in JSDoc (like "Text" instead of "* Text")
|
|
59
|
+
if (trimmedLine !== '' && !trimmedLine.startsWith('*') && !trimmedLine.endsWith('*/')) {
|
|
60
|
+
// This line should have an asterisk added
|
|
61
|
+
const start = comment.range[0] + 2; // +2 for "/*"
|
|
62
|
+
let lineOffset = 0;
|
|
63
|
+
for (let j = 0; j < i; j++) {
|
|
64
|
+
lineOffset += lines[j].length + 1; // +1 for \n
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
context.report({
|
|
68
|
+
node: comment,
|
|
69
|
+
loc: {
|
|
70
|
+
start: sourceCode.getLocFromIndex(start + lineOffset),
|
|
71
|
+
end: sourceCode.getLocFromIndex(start + lineOffset + line.length)
|
|
72
|
+
},
|
|
73
|
+
message: `JSDoc comment should be properly aligned`,
|
|
74
|
+
fix(fixer) {
|
|
75
|
+
return fixer.replaceTextRange(
|
|
76
|
+
[start + lineOffset, start + lineOffset + line.length],
|
|
77
|
+
baseIndent + ' * ' + trimmedLine
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
} else if (trimmedLine === '' || trimmedLine.startsWith('*')) {
|
|
82
|
+
// Check indentation for lines with asterisks
|
|
83
|
+
const leadingMatch = line.match(/^(\s*)/);
|
|
84
|
+
if (!leadingMatch) continue;
|
|
85
|
+
|
|
86
|
+
const leadingSpaces = leadingMatch[1];
|
|
87
|
+
const isClosingLine = trimmedLine === '*/';
|
|
88
|
+
const correctIndent = isClosingLine ? baseIndent : baseIndent + ' ';
|
|
89
|
+
|
|
90
|
+
// Skip if already correct to avoid circular fixes
|
|
91
|
+
if (leadingSpaces === correctIndent) continue;
|
|
92
|
+
|
|
93
|
+
// Calculate the position in the original source
|
|
94
|
+
const start = comment.range[0] + 2; // +2 for "/*"
|
|
95
|
+
let lineOffset = 0;
|
|
96
|
+
for (let j = 0; j < i; j++) {
|
|
97
|
+
lineOffset += lines[j].length + 1; // +1 for \n
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const lineStart = start + lineOffset;
|
|
101
|
+
const lineEnd = lineStart + leadingSpaces.length;
|
|
102
|
+
|
|
103
|
+
context.report({
|
|
104
|
+
node: comment,
|
|
105
|
+
loc: {
|
|
106
|
+
start: sourceCode.getLocFromIndex(lineStart),
|
|
107
|
+
end: sourceCode.getLocFromIndex(lineEnd)
|
|
108
|
+
},
|
|
109
|
+
message: `JSDoc comment should be properly aligned`,
|
|
110
|
+
fix(fixer) {
|
|
111
|
+
return fixer.replaceTextRange([lineStart, lineEnd], correctIndent);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export default {
|
|
124
|
+
rules: {
|
|
125
|
+
'jsdoc-indent': jsdocIndentRule
|
|
126
|
+
},
|
|
127
|
+
configs: {
|
|
128
|
+
recommended: {
|
|
129
|
+
rules: {
|
|
130
|
+
'jsdoc-indent/jsdoc-indent': ['error', { tabWidth: 4 }]
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
package/eslint.config.mjs
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
import tsParser from '@typescript-eslint/parser';
|
|
3
3
|
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
|
4
4
|
import unusedImportsPlugin from 'eslint-plugin-unused-imports';
|
|
5
|
+
import stylisticPlugin from '@stylistic/eslint-plugin';
|
|
6
|
+
import jsdocPlugin from 'eslint-plugin-jsdoc';
|
|
7
|
+
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
|
|
8
|
+
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
|
9
|
+
import jsdocIndentPlugin from './eslint-plugin-jsdoc-indent.mjs';
|
|
10
|
+
import interfaceBracePlugin from './eslint-plugin-interface-brace.mjs';
|
|
5
11
|
|
|
6
12
|
export default function ({
|
|
7
13
|
tsconfigPath = './tsconfig.json',
|
|
@@ -27,23 +33,37 @@ export default function ({
|
|
|
27
33
|
plugins: {
|
|
28
34
|
'@typescript-eslint': tsPlugin,
|
|
29
35
|
'unused-imports': unusedImportsPlugin,
|
|
36
|
+
'@stylistic': stylisticPlugin,
|
|
37
|
+
'jsdoc': jsdocPlugin,
|
|
38
|
+
'simple-import-sort': simpleImportSortPlugin,
|
|
39
|
+
'perfectionist': perfectionistPlugin,
|
|
40
|
+
'jsdoc-indent': jsdocIndentPlugin,
|
|
41
|
+
'interface-brace': interfaceBracePlugin,
|
|
30
42
|
...plugins,
|
|
31
43
|
},
|
|
32
44
|
rules: {
|
|
45
|
+
// Original @dmitryrechkin/eslint-standard rules
|
|
33
46
|
'@typescript-eslint/explicit-function-return-type': 'error',
|
|
34
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
47
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
35
48
|
|
|
36
|
-
// coding guidelines
|
|
37
|
-
'brace-style':
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
// Original coding guidelines
|
|
50
|
+
'brace-style': 'off', // Disabled in favor of @stylistic/brace-style
|
|
51
|
+
'@stylistic/brace-style': ['error', 'allman', { allowSingleLine: true }],
|
|
52
|
+
indent: 'off', // Disabled to avoid conflicts with @stylistic/indent and our JSDoc plugin
|
|
53
|
+
'@stylistic/indent': ['error', 'tab', { SwitchCase: 1 }],
|
|
54
|
+
quotes: 'off', // Disabled in favor of @stylistic/quotes
|
|
55
|
+
'@stylistic/quotes': ['error', 'single'],
|
|
56
|
+
semi: 'off', // Disabled in favor of @stylistic/semi
|
|
57
|
+
'@stylistic/semi': ['error', 'always'],
|
|
41
58
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
42
|
-
'no-trailing-spaces': '
|
|
43
|
-
'
|
|
44
|
-
'
|
|
59
|
+
'no-trailing-spaces': 'off', // Disabled in favor of @stylistic/no-trailing-spaces
|
|
60
|
+
'@stylistic/no-trailing-spaces': 'error',
|
|
61
|
+
'eol-last': 'off', // Disabled in favor of @stylistic/eol-last
|
|
62
|
+
'@stylistic/eol-last': ['error', 'always'],
|
|
63
|
+
'comma-dangle': 'off', // Disabled in favor of @stylistic/comma-dangle
|
|
64
|
+
'@stylistic/comma-dangle': ['error', 'never'],
|
|
45
65
|
|
|
46
|
-
// naming conventions
|
|
66
|
+
// Original naming conventions
|
|
47
67
|
'@typescript-eslint/naming-convention': [
|
|
48
68
|
'error',
|
|
49
69
|
{
|
|
@@ -94,7 +114,7 @@ export default function ({
|
|
|
94
114
|
},
|
|
95
115
|
],
|
|
96
116
|
|
|
97
|
-
// unused-imports rules
|
|
117
|
+
// Original unused-imports rules
|
|
98
118
|
'unused-imports/no-unused-imports': 'error',
|
|
99
119
|
'unused-imports/no-unused-vars': [
|
|
100
120
|
'warn',
|
|
@@ -105,6 +125,41 @@ export default function ({
|
|
|
105
125
|
argsIgnorePattern: '^_',
|
|
106
126
|
},
|
|
107
127
|
],
|
|
128
|
+
|
|
129
|
+
// Enhanced: Class member ordering with auto-fix
|
|
130
|
+
'perfectionist/sort-classes': [
|
|
131
|
+
'error',
|
|
132
|
+
{
|
|
133
|
+
type: 'natural',
|
|
134
|
+
order: 'asc',
|
|
135
|
+
groups: [
|
|
136
|
+
'index-signature',
|
|
137
|
+
'static-property',
|
|
138
|
+
'property',
|
|
139
|
+
'protected-property',
|
|
140
|
+
'private-property',
|
|
141
|
+
'constructor',
|
|
142
|
+
'static-method',
|
|
143
|
+
'method',
|
|
144
|
+
'protected-method',
|
|
145
|
+
'private-method'
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
// Enhanced: Import sorting
|
|
151
|
+
'simple-import-sort/imports': 'error',
|
|
152
|
+
'simple-import-sort/exports': 'error',
|
|
153
|
+
|
|
154
|
+
// Enhanced: JSDoc formatting with proper alignment
|
|
155
|
+
'jsdoc/check-indentation': 'off', // Disabled to avoid conflicts with our custom plugin
|
|
156
|
+
'jsdoc/tag-lines': 'off', // Disabled to avoid conflicts with our custom plugin
|
|
157
|
+
'jsdoc-indent/jsdoc-indent': ['error', { tabWidth: 4 }],
|
|
158
|
+
|
|
159
|
+
// Enhanced: Interface brace style
|
|
160
|
+
'interface-brace/interface-brace-style': 'error',
|
|
161
|
+
|
|
162
|
+
// Allow custom rules to be added
|
|
108
163
|
...rules,
|
|
109
164
|
},
|
|
110
165
|
},
|
package/package.json
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
2
|
+
"name": "@dmitryrechkin/eslint-standard",
|
|
3
|
+
"description": "This package provides a shared ESLint configuration which includes TypeScript support and a set of specific linting rules designed to ensure high-quality and consistent code style across projects.",
|
|
4
|
+
"version": "1.1.1",
|
|
5
|
+
"main": "eslint.config.mjs",
|
|
6
|
+
"files": [
|
|
7
|
+
"eslint.config.mjs",
|
|
8
|
+
"eslint-plugin-jsdoc-indent.mjs",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"postinstall": "echo 'Remember to install peer dependencies:\n npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc --save-dev\n bun add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-unused-imports @stylistic/eslint-plugin eslint-plugin-jsdoc --dev'",
|
|
14
|
+
"package:publish": "npm publish --access public",
|
|
15
|
+
"test": "npm run test:formatting",
|
|
16
|
+
"test:formatting": "node tests/test-runner.js"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
23
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
24
|
+
"eslint": "^9.0.0",
|
|
25
|
+
"eslint-plugin-unused-imports": "^4.0.0",
|
|
26
|
+
"@stylistic/eslint-plugin": "^5.0.0",
|
|
27
|
+
"eslint-plugin-jsdoc": "^50.0.0",
|
|
28
|
+
"eslint-plugin-simple-import-sort": "^12.0.0",
|
|
29
|
+
"eslint-plugin-perfectionist": "^4.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^8.36.0",
|
|
33
|
+
"@typescript-eslint/parser": "^8.36.0",
|
|
34
|
+
"eslint": "^9.31.0",
|
|
35
|
+
"eslint-plugin-unused-imports": "^4.1.4",
|
|
36
|
+
"@stylistic/eslint-plugin": "^5.1.0",
|
|
37
|
+
"eslint-plugin-jsdoc": "^50.6.0",
|
|
38
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
39
|
+
"eslint-plugin-perfectionist": "^4.15.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"strict": true,
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"lib": [
|
|
8
|
-
"ESNext"
|
|
9
|
-
]
|
|
10
|
-
},
|
|
11
|
-
"include": [
|
|
12
|
-
"src/**/*.ts",
|
|
13
|
-
"tests/**/*.ts"
|
|
14
|
-
],
|
|
15
|
-
"exclude": [
|
|
16
|
-
"node_modules"
|
|
17
|
-
]
|
|
18
|
-
}
|