@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 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': 'error',
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.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.2.2",
40
- "@typescript-eslint/eslint-plugin": "^8.38.0",
41
- "@typescript-eslint/parser": "^8.38.0",
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-plugin-functional": "^7.3.0",
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-import-resolver-typescript": "^3.6.3",
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": "^1.1.2",
49
- "eslint-plugin-perfectionist": "^4.15.0",
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.9.0",
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.4",
56
- "eslint-plugin-unicorn": "^56.0.1",
57
- "eslint-plugin-unused-imports": "^4.1.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.1",
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.32.0",
68
- "prettier": "^3.6.2"
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
  };