@dmitryrechkin/eslint-standard 1.3.4 → 1.3.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 +18 -4
- package/package.json +2 -1
- package/src/plugins/switch-case-brace.mjs +86 -0
package/eslint.config.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
|
|
|
8
8
|
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
|
9
9
|
import jsdocIndentPlugin from './src/plugins/jsdoc-indent.mjs';
|
|
10
10
|
import interfaceBracePlugin from './src/plugins/interface-brace.mjs';
|
|
11
|
+
import switchCaseBracePlugin from './src/plugins/switch-case-brace.mjs';
|
|
11
12
|
import securityPlugin from 'eslint-plugin-security';
|
|
12
13
|
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
|
|
13
14
|
import promisePlugin from 'eslint-plugin-promise';
|
|
@@ -48,6 +49,7 @@ export default function ({
|
|
|
48
49
|
'perfectionist': perfectionistPlugin,
|
|
49
50
|
'jsdoc-indent': jsdocIndentPlugin,
|
|
50
51
|
'interface-brace': interfaceBracePlugin,
|
|
52
|
+
'switch-case-brace': switchCaseBracePlugin,
|
|
51
53
|
'security': securityPlugin,
|
|
52
54
|
'jsx-a11y': jsxA11yPlugin,
|
|
53
55
|
'promise': promisePlugin,
|
|
@@ -77,7 +79,8 @@ export default function ({
|
|
|
77
79
|
|
|
78
80
|
// Original coding guidelines
|
|
79
81
|
'brace-style': 'off', // Disabled in favor of @stylistic/brace-style
|
|
80
|
-
'@stylistic/brace-style': ['error', 'allman', { allowSingleLine:
|
|
82
|
+
'@stylistic/brace-style': ['error', 'allman', { allowSingleLine: false }],
|
|
83
|
+
'@stylistic/block-spacing': ['error', 'never'], // Enforce consistent spacing inside blocks
|
|
81
84
|
indent: 'off', // Disabled to avoid conflicts with @stylistic/indent and our JSDoc plugin
|
|
82
85
|
'@stylistic/indent': ['error', 'tab', { SwitchCase: 1 }],
|
|
83
86
|
quotes: 'off', // Disabled in favor of @stylistic/quotes
|
|
@@ -181,6 +184,9 @@ export default function ({
|
|
|
181
184
|
|
|
182
185
|
// Enhanced: Interface brace style
|
|
183
186
|
'interface-brace/interface-brace-style': 'error',
|
|
187
|
+
|
|
188
|
+
// Enhanced: Switch case brace style - Allman style for case blocks
|
|
189
|
+
'switch-case-brace/switch-case-brace-style': 'error',
|
|
184
190
|
|
|
185
191
|
// Additional naming conventions based on coding standards
|
|
186
192
|
'@typescript-eslint/naming-convention': [
|
|
@@ -794,6 +800,7 @@ export default function ({
|
|
|
794
800
|
// Test file specific overrides
|
|
795
801
|
{
|
|
796
802
|
files: ['**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/tests/**/*.{js,jsx,ts,tsx}'],
|
|
803
|
+
ignores: ['**/tests/fixtures/**/*'], // Don't apply test overrides to fixture files
|
|
797
804
|
rules: {
|
|
798
805
|
// Disable function scoping rule for test helpers
|
|
799
806
|
'unicorn/consistent-function-scoping': 'off',
|
|
@@ -807,9 +814,16 @@ export default function ({
|
|
|
807
814
|
exceptions: ['id', 'fn']
|
|
808
815
|
}],
|
|
809
816
|
|
|
810
|
-
//
|
|
811
|
-
'
|
|
812
|
-
'functional/no-
|
|
817
|
+
// Disable rules inappropriate for test files
|
|
818
|
+
'functional/no-loop-statements': 'off', // Loops are often clearer than functional alternatives in tests
|
|
819
|
+
'functional/no-let': 'off', // Test setup requires mutable variables
|
|
820
|
+
'functional/immutable-data': 'off', // Test mocking requires object mutations
|
|
821
|
+
'security/detect-non-literal-fs-filename': 'off', // Tests legitimately need dynamic file paths
|
|
822
|
+
'unicorn/prefer-module': 'off', // Tests may need __dirname for reliable paths
|
|
823
|
+
|
|
824
|
+
// Keep as warnings - still worth improving when possible
|
|
825
|
+
'unicorn/no-null': 'off', // APIs often use null, but const can be better
|
|
826
|
+
'sonarjs/no-duplicate-string': 'off', // Test strings repeat, but constants still help readability
|
|
813
827
|
},
|
|
814
828
|
},
|
|
815
829
|
];
|
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.3.
|
|
4
|
+
"version": "1.3.6",
|
|
5
5
|
"main": "eslint.config.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"eslint-standard": "./src/cli/index.mjs"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test:security": "node tests/test-security-rules.js",
|
|
25
25
|
"test:sonarjs": "node tests/test-sonarjs-rules.js",
|
|
26
26
|
"test:unicorn": "node tests/test-unicorn-rules.js",
|
|
27
|
+
"test:switch-case": "node tests/test-switch-case-simple.js",
|
|
27
28
|
"test:cli": "node tests/test-cli.js",
|
|
28
29
|
"test:install": "node tests/test-install-simulation.js"
|
|
29
30
|
},
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom ESLint plugin rule to enforce Allman-style brace placement for switch case blocks
|
|
3
|
+
* Forces case block opening braces to be on new lines
|
|
4
|
+
*
|
|
5
|
+
* Example:
|
|
6
|
+
* case 'VALUE':
|
|
7
|
+
* {
|
|
8
|
+
* // code here
|
|
9
|
+
* }
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const switchCaseBraceRule = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: 'layout',
|
|
15
|
+
docs: {
|
|
16
|
+
description: 'Enforce Allman-style brace placement for switch case blocks',
|
|
17
|
+
category: 'Stylistic Issues',
|
|
18
|
+
recommended: false
|
|
19
|
+
},
|
|
20
|
+
fixable: 'whitespace',
|
|
21
|
+
schema: [],
|
|
22
|
+
messages: {
|
|
23
|
+
expectedNewlineBeforeOpeningBrace: 'Expected a newline before opening brace in case block.',
|
|
24
|
+
expectedNewlineAfterOpeningBrace: 'Expected a newline after opening brace in case block.'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
create(context) {
|
|
29
|
+
const sourceCode = context.getSourceCode();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Check if a case clause has a block statement and enforce proper brace placement
|
|
33
|
+
* @param {ASTNode} node - The SwitchCase node
|
|
34
|
+
*/
|
|
35
|
+
function checkCaseClause(node) {
|
|
36
|
+
// Only process case clauses that have a single BlockStatement
|
|
37
|
+
if (node.consequent.length !== 1 || node.consequent[0].type !== 'BlockStatement') {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const blockStatement = node.consequent[0];
|
|
42
|
+
const openingBrace = sourceCode.getFirstToken(blockStatement);
|
|
43
|
+
const closingBrace = sourceCode.getLastToken(blockStatement);
|
|
44
|
+
|
|
45
|
+
// Get the colon token after case label
|
|
46
|
+
const colonToken = sourceCode.getTokenAfter(node.test || sourceCode.getFirstToken(node));
|
|
47
|
+
|
|
48
|
+
// Check if opening brace is on the same line as the colon
|
|
49
|
+
if (colonToken.loc.end.line === openingBrace.loc.start.line) {
|
|
50
|
+
context.report({
|
|
51
|
+
node: blockStatement,
|
|
52
|
+
messageId: 'expectedNewlineBeforeOpeningBrace',
|
|
53
|
+
fix(fixer) {
|
|
54
|
+
// Add newline and proper indentation before opening brace
|
|
55
|
+
const indentation = '\t'.repeat(getIndentLevel(node) + 1);
|
|
56
|
+
return fixer.replaceTextRange(
|
|
57
|
+
[colonToken.range[1], openingBrace.range[0]],
|
|
58
|
+
`\n${indentation}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get the indentation level for a node
|
|
67
|
+
* @param {ASTNode} node - The node to check
|
|
68
|
+
* @returns {number} The indentation level
|
|
69
|
+
*/
|
|
70
|
+
function getIndentLevel(node) {
|
|
71
|
+
const line = sourceCode.lines[node.loc.start.line - 1];
|
|
72
|
+
const match = line.match(/^(\t*)/);
|
|
73
|
+
return match ? match[1].length : 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
SwitchCase: checkCaseClause
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default {
|
|
83
|
+
rules: {
|
|
84
|
+
'switch-case-brace-style': switchCaseBraceRule
|
|
85
|
+
}
|
|
86
|
+
};
|