@dmitryrechkin/eslint-standard 1.4.2 → 1.4.3

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
@@ -18,7 +18,10 @@ import unicornPlugin from 'eslint-plugin-unicorn';
18
18
  import noSecretsPlugin from 'eslint-plugin-no-secrets';
19
19
  import regexpPlugin from 'eslint-plugin-regexp';
20
20
  import functionalPlugin from 'eslint-plugin-functional';
21
-
21
+ // eslint-disable-next-line import/no-extraneous-dependencies
22
+ import prettierConfig from 'eslint-config-prettier';
23
+ // eslint-disable-next-line import/no-extraneous-dependencies
24
+ import prettierPlugin from 'eslint-plugin-prettier';
22
25
  export default function ({
23
26
  tsconfigPath = './tsconfig.json',
24
27
  ignores = [],
@@ -30,8 +33,10 @@ export default function ({
30
33
  {
31
34
  ignores: ['node_modules/**', 'dist/**', ...ignores],
32
35
  },
36
+ // Add Prettier integration
37
+ prettierConfig,
33
38
  {
34
- files: ['**/*.{js,jsx,ts,tsx}', ...files],
39
+ files: ['**/*.{js,ts}', ...files], // Exclude jsx, tsx, and astro files from main config
35
40
  languageOptions: {
36
41
  parser: tsParser,
37
42
  parserOptions: {
@@ -59,6 +64,7 @@ export default function ({
59
64
  'no-secrets': noSecretsPlugin,
60
65
  'regexp': regexpPlugin,
61
66
  'functional': functionalPlugin,
67
+ 'prettier': prettierPlugin,
62
68
  ...plugins,
63
69
  },
64
70
  settings: {
@@ -73,6 +79,11 @@ export default function ({
73
79
  'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
74
80
  },
75
81
  rules: {
82
+ // Prettier integration
83
+ 'prettier/prettier': 'error',
84
+ // Disable rules that conflict with prettier
85
+ 'switch-case-brace/switch-case-brace-style': 'off',
86
+
76
87
  // Original @dmitryrechkin/eslint-standard rules
77
88
  '@typescript-eslint/explicit-function-return-type': 'error',
78
89
  '@typescript-eslint/no-explicit-any': 'error', // Ban 'any' type for type safety
@@ -540,7 +551,10 @@ export default function ({
540
551
  devDependencies: ['**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/test/**', '**/tests/**', '**/__tests__/**']
541
552
  }],
542
553
  'import/no-mutable-exports': 'error',
543
- 'import/no-unused-modules': 'off', // Disabled due to .eslintrc requirement in flat config
554
+ 'import/no-unused-modules': ['error', {
555
+ missingExports: true, // Find files with no exports
556
+ unusedExports: true // Find unused exports
557
+ }],
544
558
  'import/unambiguous': 'off',
545
559
  'import/no-commonjs': 'off',
546
560
  'import/no-amd': 'error',
@@ -780,12 +794,39 @@ export default function ({
780
794
  'unicorn/prevent-abbreviations': 'off', // Allow abbreviations for domain-specific terms
781
795
 
782
796
  // Allow custom rules to be added
783
- ...rules,
797
+ ...rules
784
798
  },
785
799
  },
800
+ // Prettier config for TypeScript/JavaScript files with Allman brace style
801
+ {
802
+ files: ['**/*.{tsx,jsx,ts,js}'],
803
+ rules: {
804
+ 'prettier/prettier': [
805
+ 'error',
806
+ {
807
+ parser: 'typescript',
808
+ plugins: ['prettier-plugin-brace-style'],
809
+ braceStyle: 'allman'
810
+ }
811
+ ]
812
+ }
813
+ },
814
+ // Prettier config for Astro files
815
+ {
816
+ files: ['**/*.astro'],
817
+ rules: {
818
+ 'prettier/prettier': [
819
+ 'error',
820
+ {
821
+ parser: 'astro',
822
+ plugins: ['prettier-plugin-astro']
823
+ }
824
+ ]
825
+ }
826
+ },
786
827
  // Test file specific overrides
787
828
  {
788
- files: ['**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/tests/**/*.{js,jsx,ts,tsx}'],
829
+ files: ['**/*.test.{js,ts}', '**/*.spec.{js,ts}', '**/tests/**/*.{js,ts}'],
789
830
  ignores: ['**/tests/fixtures/**/*'], // Don't apply test overrides to fixture files
790
831
  rules: {
791
832
  // Disable function scoping rule for test helpers
package/package.json CHANGED
@@ -1,32 +1,36 @@
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.4.2",
4
+ "version": "1.4.3",
5
5
  "main": "eslint.config.mjs",
6
+ "exports": {
7
+ ".": "./eslint.config.mjs"
8
+ },
6
9
  "bin": {
7
10
  "eslint-standard": "./src/cli/index.mjs"
8
11
  },
9
12
  "files": [
10
13
  "eslint.config.mjs",
11
14
  "src/",
12
- "docs/",
13
15
  "README.md",
14
16
  "LICENSE"
15
17
  ],
16
18
  "scripts": {
17
19
  "postinstall": "node src/cli/postinstall.mjs",
18
20
  "package:publish": "npm publish --access public",
19
- "test": "node tests/test-all-rules.js",
20
- "test:all": "node tests/test-all-rules.js",
21
- "test:formatting": "node tests/test-runner.js",
22
- "test:complexity": "node tests/test-complexity-rules.js",
23
- "test:safety": "node tests/test-safety-rules.js",
24
- "test:security": "node tests/test-security-rules.js",
25
- "test:sonarjs": "node tests/test-sonarjs-rules.js",
26
- "test:unicorn": "node tests/test-unicorn-rules.js",
27
- "test:switch-case": "node tests/test-switch-case-simple.js",
28
- "test:cli": "node tests/test-cli.js",
29
- "test:install": "node tests/test-install-simulation.js"
21
+ "test": "node tests/test-all-rules.mjs",
22
+ "test:all": "node tests/test-all-rules.mjs",
23
+ "test:formatting": "node tests/test-runner.mjs",
24
+ "test:simple": "node tests/simple-test.mjs",
25
+ "test:debug": "node tests/debug-test.mjs",
26
+ "test:complexity": "node tests/test-complexity-rules.mjs",
27
+ "test:safety": "node tests/test-safety-rules.mjs",
28
+ "test:security": "node tests/test-security-rules.mjs",
29
+ "test:sonarjs": "node tests/test-sonarjs-rules.mjs",
30
+ "test:unicorn": "node tests/test-unicorn-rules.mjs",
31
+ "test:switch-case": "node tests/test-switch-case-simple.mjs",
32
+ "test:cli": "node tests/test-cli.mjs",
33
+ "test:install": "node tests/test-install-simulation.mjs"
30
34
  },
31
35
  "keywords": [],
32
36
  "author": "",
@@ -36,6 +40,7 @@
36
40
  "@typescript-eslint/eslint-plugin": "^8.0.0",
37
41
  "@typescript-eslint/parser": "^8.0.0",
38
42
  "eslint": "^9.0.0",
43
+ "eslint-config-prettier": "^10.0.0",
39
44
  "eslint-plugin-functional": "^7.0.0",
40
45
  "eslint-plugin-import": "^2.0.0",
41
46
  "eslint-import-resolver-typescript": "^3.0.0",
@@ -43,19 +48,23 @@
43
48
  "eslint-plugin-jsx-a11y": "^6.0.0",
44
49
  "eslint-plugin-no-secrets": "^1.0.0",
45
50
  "eslint-plugin-perfectionist": "^4.0.0",
51
+ "eslint-plugin-prettier": "^5.0.0",
46
52
  "eslint-plugin-promise": "^7.0.0",
47
53
  "eslint-plugin-regexp": "^2.0.0",
48
54
  "eslint-plugin-security": "^3.0.0",
49
55
  "eslint-plugin-simple-import-sort": "^12.0.0",
50
56
  "eslint-plugin-sonarjs": "^3.0.0",
51
57
  "eslint-plugin-unicorn": "^56.0.0",
52
- "eslint-plugin-unused-imports": "^4.0.0"
58
+ "eslint-plugin-unused-imports": "^4.0.0",
59
+ "prettier-plugin-astro": "^0.14.0",
60
+ "prettier-plugin-brace-style": "^0.8.0"
53
61
  },
54
62
  "devDependencies": {
55
63
  "@stylistic/eslint-plugin": "^5.2.2",
56
64
  "@typescript-eslint/eslint-plugin": "^8.38.0",
57
65
  "@typescript-eslint/parser": "^8.38.0",
58
66
  "eslint": "^9.32.0",
67
+ "eslint-config-prettier": "^10.1.8",
59
68
  "eslint-plugin-functional": "^7.3.0",
60
69
  "eslint-plugin-import": "^2.32.0",
61
70
  "eslint-import-resolver-typescript": "^3.6.3",
@@ -63,12 +72,15 @@
63
72
  "eslint-plugin-jsx-a11y": "^6.10.2",
64
73
  "eslint-plugin-no-secrets": "^1.1.2",
65
74
  "eslint-plugin-perfectionist": "^4.15.0",
75
+ "eslint-plugin-prettier": "^5.5.3",
66
76
  "eslint-plugin-promise": "^7.2.1",
67
77
  "eslint-plugin-regexp": "^2.9.0",
68
78
  "eslint-plugin-security": "^3.0.1",
69
79
  "eslint-plugin-simple-import-sort": "^12.1.1",
70
80
  "eslint-plugin-sonarjs": "^3.0.4",
71
81
  "eslint-plugin-unicorn": "^56.0.1",
72
- "eslint-plugin-unused-imports": "^4.1.4"
82
+ "eslint-plugin-unused-imports": "^4.1.4",
83
+ "prettier-plugin-astro": "^0.14.1",
84
+ "prettier-plugin-brace-style": "^0.8.1"
73
85
  }
74
86
  }
package/src/cli/index.mjs CHANGED
@@ -20,10 +20,10 @@ Usage:
20
20
  npx @dmitryrechkin/eslint-standard <command>
21
21
 
22
22
  Commands:
23
- install-deps Install all peer dependencies
24
- check-deps Check if all peer dependencies are installed
25
- check-deps --install Auto-install missing dependencies if any
26
- help Show this help message
23
+ install-deps Install all peer dependencies
24
+ check-deps Check if all peer dependencies are installed
25
+ check-deps --install Auto-install missing dependencies if any
26
+ help Show this help message
27
27
 
28
28
  Examples:
29
29
  npx @dmitryrechkin/eslint-standard install-deps
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @file CLI Setup for Aggressive Unused Code Detection
5
+ *
6
+ * This CLI tool helps set up aggressive unused code detection and cleanup
7
+ * in your project with external tools and optimal configurations.
8
+ *
9
+ * @author PageFast Team
10
+ * @version 1.0.0
11
+ */
12
+
13
+ import { setupAggressiveCleanup } from '../configs/external-tools-setup.mjs';
14
+
15
+ // Simple command line argument parsing (avoiding external dependencies)
16
+ const args = process.argv.slice(2);
17
+ const options = {
18
+ global: args.includes('--global') || args.includes('-g'),
19
+ packageManager: args.find((arg, i) => (args[i-1] === '--package-manager' || args[i-1] === '-p')) || 'npm',
20
+ dryRun: args.includes('--dry-run'),
21
+ help: args.includes('--help') || args.includes('-h')
22
+ };
23
+
24
+ /**
25
+ * Main CLI program for setting up aggressive cleanup
26
+ */
27
+ async function main()
28
+ {
29
+ try
30
+ {
31
+ if (options.help)
32
+ {
33
+ console.log(`
34
+ @dmitryrechkin/eslint-standard - Aggressive Cleanup Setup
35
+
36
+ Usage:
37
+ npx @dmitryrechkin/eslint-standard setup-aggressive-cleanup [options]
38
+
39
+ Options:
40
+ -g, --global Install cleanup tools globally
41
+ -p, --package-manager <type> Package manager to use (npm, pnpm, yarn)
42
+ --dry-run Show what would be done without making changes
43
+ -h, --help Show this help message
44
+
45
+ Examples:
46
+ npx @dmitryrechkin/eslint-standard setup-aggressive-cleanup
47
+ npx @dmitryrechkin/eslint-standard setup-aggressive-cleanup --global
48
+ npx @dmitryrechkin/eslint-standard setup-aggressive-cleanup -p pnpm
49
+ npx @dmitryrechkin/eslint-standard setup-aggressive-cleanup --dry-run
50
+ `);
51
+ return;
52
+ }
53
+
54
+ if (options.dryRun)
55
+ {
56
+ console.log('🔍 DRY RUN - Would perform the following actions:\n');
57
+ console.log('1. Install external cleanup tools:');
58
+ console.log(' - ts-prune (find unused exports)');
59
+ console.log(' - unimported (find unused files)');
60
+ console.log(' - knip (advanced dead code elimination)');
61
+ console.log(' - depcheck (find unused dependencies)');
62
+ console.log(' - ts-remove-unused (remove unused imports)');
63
+ console.log('\n2. Add cleanup scripts to package.json');
64
+ console.log('\n3. Create optimal tsconfig.json for unused code detection');
65
+ console.log('\n4. Create knip.json configuration');
66
+ console.log('\nRun without --dry-run to actually perform setup.');
67
+ return;
68
+ }
69
+
70
+ await setupAggressiveCleanup({
71
+ packageManager: options.packageManager,
72
+ globalTools: options.global
73
+ });
74
+
75
+ console.log('\n🎉 Setup complete! Next steps:');
76
+ console.log('\n1. Enable aggressive cleanup in your ESLint config:');
77
+ console.log(' ```javascript');
78
+ console.log(' import baseConfig from "@dmitryrechkin/eslint-standard";');
79
+ console.log(' export default baseConfig({');
80
+ console.log(' aggressiveCleanup: true // 🔥 Enable aggressive mode');
81
+ console.log(' });');
82
+ console.log(' ```');
83
+ console.log('\n2. Run cleanup check:');
84
+ console.log(' npm run cleanup:check');
85
+ console.log('\n3. Review and fix issues:');
86
+ console.log(' npm run cleanup:fix');
87
+
88
+ }
89
+ catch (error)
90
+ {
91
+ console.error('\n❌ Setup failed:', error.message);
92
+ process.exit(1);
93
+ }
94
+ }
95
+
96
+ // Run the main function
97
+ main();
@@ -1,50 +0,0 @@
1
- # Auto-Installation Options
2
-
3
- ## Manual Installation (Default - Recommended)
4
-
5
- By default, peer dependencies are NOT auto-installed. After installing the package, run:
6
-
7
- ```bash
8
- npx @dmitryrechkin/eslint-standard check-deps --install
9
- ```
10
-
11
- ## Environment Variable Control
12
-
13
- You can control the installation behavior using environment variables:
14
-
15
- ### Enable Auto-Install
16
-
17
- ```bash
18
- # One-time auto-install
19
- ESLINT_STANDARD_AUTO_INSTALL=true npm install @dmitryrechkin/eslint-standard
20
-
21
- # Or add to .npmrc for project
22
- echo "ESLINT_STANDARD_AUTO_INSTALL=true" >> .npmrc
23
- ```
24
-
25
- ### Disable All Postinstall Messages
26
-
27
- ```bash
28
- # Skip all postinstall scripts
29
- ESLINT_STANDARD_SKIP_INSTALL=true npm install @dmitryrechkin/eslint-standard
30
-
31
- # Or globally
32
- npm install --ignore-scripts
33
- ```
34
-
35
- ## CI/CD Environments
36
-
37
- The postinstall script automatically detects CI environments and skips execution to avoid issues.
38
-
39
- ## Security Considerations
40
-
41
- - Auto-installation is **opt-in only** via environment variable
42
- - Respects npm's `--ignore-scripts` flag
43
- - Skips in CI environments
44
- - Never modifies files without user consent
45
-
46
- ## Best Practices
47
-
48
- 1. **Development**: Use `check-deps --install` for quick setup
49
- 2. **Production**: Explicitly install peer dependencies in package.json
50
- 3. **CI/CD**: Add peer dependencies to your package.json for reproducible builds
@@ -1,200 +0,0 @@
1
- # Built-in Complexity Rules
2
-
3
- `@dmitryrechkin/eslint-standard` includes industry-standard complexity rules by default to ensure code maintainability and readability. These rules help detect code quality issues like deep nesting, large functions, and violations of SOLID principles.
4
-
5
- ## Available Rules
6
-
7
- ### 1. Cyclomatic Complexity
8
- ```javascript
9
- 'complexity': ['error', 10]
10
- ```
11
- - Limits the number of linearly independent paths through a function
12
- - Default: 10 (strict mode: 5)
13
- - Helps identify functions that are doing too much
14
-
15
- ### 2. Function Length
16
- ```javascript
17
- 'max-lines-per-function': ['error', {
18
- max: 100,
19
- skipBlankLines: true,
20
- skipComments: true
21
- }]
22
- ```
23
- - Limits function length to 100 lines (pragmatic for complex business logic)
24
- - Encourages reasonably sized, focused functions
25
- - Balances Single Responsibility with real-world needs
26
-
27
- ### 3. Maximum Statements
28
- ```javascript
29
- 'max-statements': ['error', 20]
30
- ```
31
- - Limits the number of statements in a function
32
- - Default: 20 (strict mode: 10)
33
- - Forces decomposition of complex logic
34
-
35
- ### 4. Nesting Depth
36
- ```javascript
37
- 'max-depth': ['error', { max: 3 }]
38
- ```
39
- - Limits block nesting to 3 levels (strict mode: 2)
40
- - Prevents deeply nested if/else chains
41
- - Encourages early returns and guard clauses
42
-
43
- ### 5. Callback Nesting
44
- ```javascript
45
- 'max-nested-callbacks': ['error', 3]
46
- ```
47
- - Limits callback nesting depth
48
- - Encourages use of async/await or promises
49
- - Prevents "callback hell"
50
-
51
- ### 6. Parameter Count
52
- ```javascript
53
- 'max-params': ['error', 4]
54
- ```
55
- - Limits function parameters to 4 (strict mode: 3)
56
- - Encourages parameter objects for complex functions
57
- - Improves function signatures
58
-
59
- ### 7. File Size
60
- ```javascript
61
- 'max-lines': ['warn', {
62
- max: 300,
63
- skipBlankLines: true,
64
- skipComments: true
65
- }]
66
- ```
67
- - Warns when files exceed 300 lines
68
- - Encourages modular code organization
69
- - Helps maintain Single Responsibility for modules
70
-
71
- ## Customizing Rules
72
-
73
- The complexity rules are included by default. You can customize them by overriding specific rules:
74
-
75
- ```javascript
76
- import eslintStandard from '@dmitryrechkin/eslint-standard';
77
-
78
- export default eslintStandard({
79
- tsconfigPath: './tsconfig.json',
80
- rules: {
81
- // Make complexity stricter
82
- 'complexity': ['error', 8],
83
- 'max-lines-per-function': ['error', { max: 40 }],
84
- 'max-depth': ['error', { max: 2 }],
85
-
86
- // Or relax for legacy code
87
- 'complexity': ['warn', 15],
88
- 'max-lines-per-function': ['warn', { max: 100 }],
89
-
90
- // Or disable specific rules
91
- 'max-lines': 'off'
92
- }
93
- });
94
- ```
95
-
96
- ## Examples of Violations
97
-
98
- ### 1. High Cyclomatic Complexity
99
- ```typescript
100
- // ❌ BAD: Complexity > 10
101
- function processOrder(order: Order): Result {
102
- if (order.status === 'pending') {
103
- if (order.payment) {
104
- if (order.payment.method === 'credit') {
105
- if (order.payment.verified) {
106
- // ... more conditions
107
- }
108
- } else if (order.payment.method === 'debit') {
109
- // ... more branches
110
- }
111
- }
112
- } else if (order.status === 'processing') {
113
- // ... more branches
114
- }
115
- // Total complexity: 15+
116
- }
117
-
118
- // ✅ GOOD: Break into smaller functions
119
- function processOrder(order: Order): Result {
120
- if (!isOrderReady(order)) {
121
- return { error: 'Order not ready' };
122
- }
123
-
124
- const payment = processPayment(order.payment);
125
- if (!payment.success) {
126
- return { error: payment.error };
127
- }
128
-
129
- return completeOrder(order, payment);
130
- }
131
- ```
132
-
133
- ### 2. Deep Nesting
134
- ```typescript
135
- // ❌ BAD: Nesting depth > 3
136
- function validateData(data: any): boolean {
137
- if (data) {
138
- if (data.user) {
139
- if (data.user.profile) {
140
- if (data.user.profile.email) {
141
- return validateEmail(data.user.profile.email);
142
- }
143
- }
144
- }
145
- }
146
- return false;
147
- }
148
-
149
- // ✅ GOOD: Use early returns
150
- function validateData(data: any): boolean {
151
- if (!data?.user?.profile?.email) {
152
- return false;
153
- }
154
- return validateEmail(data.user.profile.email);
155
- }
156
- ```
157
-
158
- ### 3. Long Functions
159
- ```typescript
160
- // ❌ BAD: Function > 50 lines
161
- function generateReport(data: Data): Report {
162
- // 100+ lines of code doing multiple things:
163
- // - Data validation
164
- // - Data transformation
165
- // - Calculations
166
- // - Formatting
167
- // - File generation
168
- }
169
-
170
- // ✅ GOOD: Split into focused functions
171
- function generateReport(data: Data): Report {
172
- const validatedData = validateReportData(data);
173
- const transformedData = transformReportData(validatedData);
174
- const calculations = calculateReportMetrics(transformedData);
175
- const formatted = formatReportData(calculations);
176
- return createReportFile(formatted);
177
- }
178
- ```
179
-
180
- ## Benefits
181
-
182
- 1. **Improved Readability**: Smaller functions are easier to understand
183
- 2. **Better Testability**: Simple functions are easier to test
184
- 3. **Reduced Bugs**: Less complex code has fewer places for bugs to hide
185
- 4. **Easier Maintenance**: Changes are localized to smaller units
186
- 5. **Team Collaboration**: Consistent complexity limits across the codebase
187
-
188
- ## Migration Strategy
189
-
190
- 1. **Start with Warnings**: Use `warn` instead of `error` initially
191
- 2. **Fix Incrementally**: Address the worst violations first
192
- 3. **Set Realistic Goals**: Gradually tighten limits over time
193
- 4. **Document Exceptions**: Use `eslint-disable` comments sparingly with explanations
194
-
195
- ## Related Tools
196
-
197
- - **SonarQube**: For comprehensive code quality metrics
198
- - **CodeClimate**: For tracking technical debt
199
- - **Lizard**: For cyclomatic complexity analysis
200
- - **JSComplexity**: Visual complexity reports