@dmitryrechkin/eslint-standard 1.5.5 → 1.5.6
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/eslint.config.mjs +19 -2
- package/package.json +18 -17
- package/src/plugins/interface-brace.mjs +13 -48
package/eslint.config.mjs
CHANGED
|
@@ -123,14 +123,31 @@ export default function ({
|
|
|
123
123
|
'@typescript-eslint/no-useless-constructor': 'error',
|
|
124
124
|
'@typescript-eslint/no-empty-function': 'warn',
|
|
125
125
|
'@typescript-eslint/no-empty-interface': 'warn',
|
|
126
|
-
'@typescript-eslint/class-methods-use-this': 'error', // Alternative to no-useless-this
|
|
127
126
|
'@typescript-eslint/no-invalid-this': 'error',
|
|
127
|
+
'no-unused-private-class-members': 'error', // Catches unused #private ES2022 fields
|
|
128
128
|
'no-undef-init': 'error',
|
|
129
129
|
'no-unreachable': 'error',
|
|
130
130
|
'no-constant-condition': 'error',
|
|
131
131
|
'no-else-return': 'error',
|
|
132
132
|
'no-return-assign': 'error',
|
|
133
133
|
'no-var': 'error',
|
|
134
|
+
|
|
135
|
+
// Code spacing rules (autofix) - prevents dense code
|
|
136
|
+
'@stylistic/padding-line-between-statements': [
|
|
137
|
+
'error',
|
|
138
|
+
{ blankLine: 'always', prev: '*', next: 'return' },
|
|
139
|
+
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
|
|
140
|
+
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
|
|
141
|
+
{ blankLine: 'always', prev: 'directive', next: '*' },
|
|
142
|
+
{ blankLine: 'always', prev: ['case', 'default'], next: '*' },
|
|
143
|
+
{ blankLine: 'always', prev: '*', next: ['if', 'switch', 'try', 'while', 'for', 'do'] },
|
|
144
|
+
{ blankLine: 'always', prev: ['if', 'switch', 'try', 'while', 'for', 'do'], next: '*' },
|
|
145
|
+
{ blankLine: 'always', prev: '*', next: 'function' },
|
|
146
|
+
{ blankLine: 'always', prev: 'function', next: '*' },
|
|
147
|
+
{ blankLine: 'always', prev: 'import', next: '*' },
|
|
148
|
+
{ blankLine: 'any', prev: 'import', next: 'import' }
|
|
149
|
+
],
|
|
150
|
+
'@stylistic/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
|
|
134
151
|
'no-trailing-spaces': 'off', // Handled by prettier
|
|
135
152
|
'@stylistic/no-trailing-spaces': 'off', // Handled by prettier
|
|
136
153
|
'eol-last': 'off', // Handled by prettier
|
|
@@ -711,7 +728,7 @@ export default function ({
|
|
|
711
728
|
'unicorn/no-unnecessary-await': 'error',
|
|
712
729
|
'unicorn/no-unreadable-array-destructuring': 'error',
|
|
713
730
|
'unicorn/no-unreadable-iife': 'error',
|
|
714
|
-
'unicorn/no-unsafe-regex'
|
|
731
|
+
// 'unicorn/no-unsafe-regex' removed in v62 - covered by regexp/no-super-linear-backtracking
|
|
715
732
|
'unicorn/no-unused-properties': 'off',
|
|
716
733
|
'unicorn/no-useless-fallback-in-spread': 'error',
|
|
717
734
|
'unicorn/no-useless-length-check': 'error',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dmitryrechkin/eslint-standard",
|
|
3
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.5.
|
|
4
|
+
"version": "1.5.6",
|
|
5
5
|
"main": "eslint.config.mjs",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./eslint.config.mjs"
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"test:security": "node tests/test-security-rules.mjs",
|
|
29
29
|
"test:sonarjs": "node tests/test-sonarjs-rules.mjs",
|
|
30
30
|
"test:unicorn": "node tests/test-unicorn-rules.mjs",
|
|
31
|
+
"test:spacing": "node tests/test-spacing-rules.mjs",
|
|
31
32
|
"test:switch-case": "node tests/test-switch-case-simple.mjs",
|
|
32
33
|
"test:cli": "node tests/test-cli.mjs",
|
|
33
34
|
"test:install": "node tests/test-install-simulation.mjs"
|
|
@@ -36,35 +37,35 @@
|
|
|
36
37
|
"author": "",
|
|
37
38
|
"license": "MIT",
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"@stylistic/eslint-plugin": "^5.
|
|
40
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
41
|
-
"@typescript-eslint/parser": "^8.
|
|
40
|
+
"@stylistic/eslint-plugin": "^5.6.1",
|
|
41
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
42
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
42
43
|
"eslint-config-prettier": "^10.1.8",
|
|
43
|
-
"eslint-
|
|
44
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
45
|
+
"eslint-plugin-functional": "^9.0.2",
|
|
44
46
|
"eslint-plugin-import": "^2.32.0",
|
|
45
|
-
"eslint-
|
|
46
|
-
"eslint-plugin-jsdoc": "^50.8.0",
|
|
47
|
+
"eslint-plugin-jsdoc": "^61.5.0",
|
|
47
48
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
48
|
-
"eslint-plugin-no-secrets": "^
|
|
49
|
-
"eslint-plugin-perfectionist": "^4.15.
|
|
49
|
+
"eslint-plugin-no-secrets": "^2.2.1",
|
|
50
|
+
"eslint-plugin-perfectionist": "^4.15.1",
|
|
50
51
|
"eslint-plugin-prettier": "^5.5.3",
|
|
51
52
|
"eslint-plugin-promise": "^7.2.1",
|
|
52
|
-
"eslint-plugin-regexp": "^2.
|
|
53
|
+
"eslint-plugin-regexp": "^2.10.0",
|
|
53
54
|
"eslint-plugin-security": "^3.0.1",
|
|
54
55
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
55
|
-
"eslint-plugin-sonarjs": "^3.0.
|
|
56
|
-
"eslint-plugin-unicorn": "^
|
|
57
|
-
"eslint-plugin-unused-imports": "^4.
|
|
56
|
+
"eslint-plugin-sonarjs": "^3.0.5",
|
|
57
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
58
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
58
59
|
"prettier-plugin-astro": "^0.14.1",
|
|
59
|
-
"prettier-plugin-brace-style": "^0.8.
|
|
60
|
-
"prettier-plugin-merge": "^0.8.0"
|
|
60
|
+
"prettier-plugin-brace-style": "^0.8.2"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"eslint": "^9.0.0",
|
|
64
64
|
"prettier": "^3.0.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"eslint": "^9.
|
|
68
|
-
"prettier": "^3.
|
|
67
|
+
"eslint": "^9.39.2",
|
|
68
|
+
"prettier": "^3.7.4",
|
|
69
|
+
"prettier-plugin-merge": "^0.8.0"
|
|
69
70
|
}
|
|
70
71
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom ESLint plugin to enforce Allman brace style for TypeScript interfaces
|
|
3
|
+
*
|
|
4
|
+
* Note: Only handles interface declarations, not type aliases.
|
|
5
|
+
* Type aliases are left to prettier-plugin-brace-style which keeps short
|
|
6
|
+
* object types on a single line (by design).
|
|
3
7
|
*/
|
|
4
8
|
|
|
5
9
|
const interfaceBraceRule = {
|
|
@@ -23,7 +27,7 @@ const interfaceBraceRule = {
|
|
|
23
27
|
const interfaceId = node.id;
|
|
24
28
|
const typeParams = node.typeParameters;
|
|
25
29
|
const extendsClause = node.extends;
|
|
26
|
-
|
|
30
|
+
|
|
27
31
|
// Find the opening brace
|
|
28
32
|
let tokenBeforeBrace;
|
|
29
33
|
if (node.heritage && node.heritage.length > 0) {
|
|
@@ -39,16 +43,16 @@ const interfaceBraceRule = {
|
|
|
39
43
|
// Simple interface
|
|
40
44
|
tokenBeforeBrace = interfaceId;
|
|
41
45
|
}
|
|
42
|
-
|
|
46
|
+
|
|
43
47
|
// Get the opening brace token
|
|
44
48
|
const openingBrace = sourceCode.getTokenAfter(tokenBeforeBrace, token => token.type === 'Punctuator' && token.value === '{');
|
|
45
|
-
|
|
49
|
+
|
|
46
50
|
if (!openingBrace) return;
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
// Check if there's a newline before the opening brace
|
|
49
53
|
const tokenBefore = sourceCode.getTokenBefore(openingBrace);
|
|
50
54
|
const textBetween = sourceCode.text.slice(tokenBefore.range[1], openingBrace.range[0]);
|
|
51
|
-
|
|
55
|
+
|
|
52
56
|
// Check if brace is on the same line
|
|
53
57
|
if (!textBetween.includes('\n')) {
|
|
54
58
|
context.report({
|
|
@@ -59,57 +63,18 @@ const interfaceBraceRule = {
|
|
|
59
63
|
const interfaceLine = sourceCode.getLines()[node.loc.start.line - 1];
|
|
60
64
|
const baseIndentMatch = interfaceLine.match(/^(\s*)/);
|
|
61
65
|
const baseIndent = baseIndentMatch ? baseIndentMatch[1] : '';
|
|
62
|
-
|
|
66
|
+
|
|
63
67
|
// Replace the space before the brace with a newline and proper indentation
|
|
64
68
|
return fixer.replaceTextRange(
|
|
65
|
-
[tokenBefore.range[1], openingBrace.range[0]],
|
|
69
|
+
[tokenBefore.range[1], openingBrace.range[0]],
|
|
66
70
|
'\n' + baseIndent
|
|
67
71
|
);
|
|
68
72
|
}
|
|
69
73
|
});
|
|
70
74
|
}
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
// Also handle TSTypeAliasDeclaration with object type
|
|
74
|
-
TSTypeAliasDeclaration(node) {
|
|
75
|
-
if (node.typeAnnotation && node.typeAnnotation.type === 'TSTypeLiteral') {
|
|
76
|
-
const typeParams = node.typeParameters;
|
|
77
|
-
const tokenBeforeBrace = typeParams ? typeParams : node.id;
|
|
78
|
-
|
|
79
|
-
// Find the equals sign
|
|
80
|
-
const equalsToken = sourceCode.getTokenAfter(tokenBeforeBrace, token => token.type === 'Punctuator' && token.value === '=');
|
|
81
|
-
|
|
82
|
-
if (!equalsToken) return;
|
|
83
|
-
|
|
84
|
-
// Get the opening brace token
|
|
85
|
-
const openingBrace = sourceCode.getTokenAfter(equalsToken, token => token.type === 'Punctuator' && token.value === '{');
|
|
86
|
-
|
|
87
|
-
if (!openingBrace) return;
|
|
88
|
-
|
|
89
|
-
// Check if there's a newline before the opening brace
|
|
90
|
-
const textBetween = sourceCode.text.slice(equalsToken.range[1], openingBrace.range[0]);
|
|
91
|
-
|
|
92
|
-
// Check if brace is on the same line
|
|
93
|
-
if (!textBetween.includes('\n')) {
|
|
94
|
-
context.report({
|
|
95
|
-
node: openingBrace,
|
|
96
|
-
message: 'Opening brace should be on a new line (Allman style)',
|
|
97
|
-
fix(fixer) {
|
|
98
|
-
// Get the base indentation
|
|
99
|
-
const typeLine = sourceCode.getLines()[node.loc.start.line - 1];
|
|
100
|
-
const baseIndentMatch = typeLine.match(/^(\s*)/);
|
|
101
|
-
const baseIndent = baseIndentMatch ? baseIndentMatch[1] : '';
|
|
102
|
-
|
|
103
|
-
// Replace the space before the brace with a newline and proper indentation
|
|
104
|
-
return fixer.replaceTextRange(
|
|
105
|
-
[equalsToken.range[1], openingBrace.range[0]],
|
|
106
|
-
'\n' + baseIndent
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
75
|
}
|
|
76
|
+
// Note: TSTypeAliasDeclaration handling removed to avoid conflict with prettier-plugin-brace-style
|
|
77
|
+
// which keeps short object type literals on a single line
|
|
113
78
|
};
|
|
114
79
|
}
|
|
115
80
|
};
|