eslint-plugin-maintainability 3.0.0
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/CHANGELOG.md +63 -0
- package/LICENSE +23 -0
- package/README.md +116 -0
- package/package.json +65 -0
- package/src/index.d.ts +180 -0
- package/src/index.js +56 -0
- package/src/rules/error-handling/error-message.d.ts +20 -0
- package/src/rules/error-handling/error-message.js +146 -0
- package/src/rules/error-handling/no-missing-error-context.d.ts +26 -0
- package/src/rules/error-handling/no-missing-error-context.js +183 -0
- package/src/rules/error-handling/no-silent-errors.d.ts +24 -0
- package/src/rules/error-handling/no-silent-errors.js +178 -0
- package/src/rules/error-handling/no-unhandled-promise.d.ts +26 -0
- package/src/rules/error-handling/no-unhandled-promise.js +351 -0
- package/src/rules/maintainability/cognitive-complexity.d.ts +28 -0
- package/src/rules/maintainability/cognitive-complexity.js +381 -0
- package/src/rules/maintainability/consistent-function-scoping.d.ts +20 -0
- package/src/rules/maintainability/consistent-function-scoping.js +226 -0
- package/src/rules/maintainability/identical-functions.d.ts +27 -0
- package/src/rules/maintainability/identical-functions.js +310 -0
- package/src/rules/maintainability/max-parameters.d.ts +29 -0
- package/src/rules/maintainability/max-parameters.js +143 -0
- package/src/rules/maintainability/nested-complexity-hotspots.d.ts +31 -0
- package/src/rules/maintainability/nested-complexity-hotspots.js +190 -0
- package/src/rules/maintainability/no-lonely-if.d.ts +19 -0
- package/src/rules/maintainability/no-lonely-if.js +120 -0
- package/src/rules/maintainability/no-nested-ternary.d.ts +19 -0
- package/src/rules/maintainability/no-nested-ternary.js +165 -0
- package/src/rules/maintainability/no-unreadable-iife.d.ts +24 -0
- package/src/rules/maintainability/no-unreadable-iife.js +239 -0
- package/src/types/index.d.ts +48 -0
- package/src/types/index.js +7 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@interlace/eslint-plugin-maintainability` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Documentation
|
|
11
|
+
|
|
12
|
+
- 📘 Launched new documentation site: [eslint.interlace.tools](https://eslint.interlace.tools/)
|
|
13
|
+
- 📝 Achieved 100% documentation parity (both .md and .mdx files)
|
|
14
|
+
|
|
15
|
+
## [1.0.0] - 2026-01-26
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Initial stable release with 12 maintainability rules
|
|
20
|
+
- LLM-optimized error messages for AI-assisted development
|
|
21
|
+
- 100% test coverage across all rules
|
|
22
|
+
- ESLint 9 flat config support
|
|
23
|
+
- TypeScript type definitions for all rule options
|
|
24
|
+
|
|
25
|
+
### Rules
|
|
26
|
+
|
|
27
|
+
#### Complexity Rules
|
|
28
|
+
|
|
29
|
+
| Rule | Description |
|
|
30
|
+
| :-------------------------- | :------------------------------- |
|
|
31
|
+
| `max-cognitive-complexity` | Limit cognitive complexity score |
|
|
32
|
+
| `max-cyclomatic-complexity` | Limit cyclomatic complexity |
|
|
33
|
+
| `max-depth` | Limit nesting depth |
|
|
34
|
+
| `max-lines` | Limit file length |
|
|
35
|
+
| `max-lines-per-function` | Limit function length |
|
|
36
|
+
| `max-params` | Limit function parameters |
|
|
37
|
+
|
|
38
|
+
#### Code Smell Rules
|
|
39
|
+
|
|
40
|
+
| Rule | Description |
|
|
41
|
+
| :------------------------- | :---------------------------------- |
|
|
42
|
+
| `no-magic-numbers` | Disallow magic numbers |
|
|
43
|
+
| `no-nested-ternary` | Disallow nested ternary expressions |
|
|
44
|
+
| `no-deep-callback-nesting` | Disallow deeply nested callbacks |
|
|
45
|
+
| `no-long-parameter-list` | Disallow long parameter lists |
|
|
46
|
+
|
|
47
|
+
#### Clean Code Rules
|
|
48
|
+
|
|
49
|
+
| Rule | Description |
|
|
50
|
+
| :-------------------- | :------------------------------------------ |
|
|
51
|
+
| `prefer-early-return` | Prefer early returns over nested conditions |
|
|
52
|
+
| `no-duplicate-logic` | Detect duplicated logic blocks (DRY) |
|
|
53
|
+
|
|
54
|
+
### Presets
|
|
55
|
+
|
|
56
|
+
- `recommended` - Balanced maintainability thresholds
|
|
57
|
+
|
|
58
|
+
### SOLID Principles Mapping
|
|
59
|
+
|
|
60
|
+
Rules are annotated with SOLID principle alignment:
|
|
61
|
+
|
|
62
|
+
- Single Responsibility: `max-lines-per-function`, `max-lines`
|
|
63
|
+
- Open/Closed: `prefer-early-return`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://eslint.interlace.tools" target="blank"><img src="https://eslint.interlace.tools/eslint-interlace-logo-light.svg" alt="ESLint Interlace Logo" width="120" /></a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
Code quality, maintainability standards, and cognitive complexity limits.
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://www.npmjs.com/package/eslint-plugin-maintainability" target="_blank"><img src="https://img.shields.io/npm/v/eslint-plugin-maintainability.svg" alt="NPM Version" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/eslint-plugin-maintainability" target="_blank"><img src="https://img.shields.io/npm/dm/eslint-plugin-maintainability.svg" alt="NPM Downloads" /></a>
|
|
12
|
+
<a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="Package License" /></a>
|
|
13
|
+
<a href="https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=quality" target="_blank"><img src="https://codecov.io/gh/ofri-peretz/eslint/graph/badge.svg?component=quality" alt="Codecov" /></a>
|
|
14
|
+
<a href="https://github.com/ofri-peretz/eslint" target="_blank"><img src="https://img.shields.io/badge/Since-Dec_2025-blue?logo=rocket&logoColor=white" alt="Since Dec 2025" /></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## Description
|
|
18
|
+
|
|
19
|
+
This plugin elevates your codebase by enforcing high standards for code quality, maintainability, and cognitive complexity. It helps you identify and refactor complex logic that can lead to bugs and technical debt, promoting cleaner and more readable code. By integrating these checks, you ensure that your application remains scalable and easy to maintain for the long term.
|
|
20
|
+
|
|
21
|
+
## Philosophy
|
|
22
|
+
|
|
23
|
+
**Interlace** fosters **strength through integration**. Instead of stacking isolated rules, we **interlace** security directly into your workflow to create a resilient fabric of code. We believe tools should **guide rather than gatekeep**, providing educational feedback that strengthens the developer with every interaction.
|
|
24
|
+
|
|
25
|
+
## Getting Started
|
|
26
|
+
|
|
27
|
+
- To check out the [guide](https://eslint.interlace.tools/docs/quality), visit [eslint.interlace.tools](https://eslint.interlace.tools). 📚
|
|
28
|
+
- 要查看中文 [指南](https://eslint.interlace.tools/docs/quality), 请访问 [eslint.interlace.tools](https://eslint.interlace.tools). 📚
|
|
29
|
+
- [가이드](https://eslint.interlace.tools/docs/quality) 문서는 [eslint.interlace.tools](https://eslint.interlace.tools)에서 확인하실 수 있습니다. 📚
|
|
30
|
+
- [ガイド](https://eslint.interlace.tools/docs/quality)は [eslint.interlace.tools](https://eslint.interlace.tools)でご確認ください。 📚
|
|
31
|
+
- Para ver la [guía](https://eslint.interlace.tools/docs/quality), visita [eslint.interlace.tools](https://eslint.interlace.tools). 📚
|
|
32
|
+
- للاطلاع على [الدليل](https://eslint.interlace.tools/docs/quality)، قم بزيارة [eslint.interlace.tools](https://eslint.interlace.tools). 📚
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install eslint-plugin-maintainability --save-dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## ⚙️ Configuration Presets
|
|
39
|
+
|
|
40
|
+
| Preset | Description |
|
|
41
|
+
| :------------ | :----------------------------------------- |
|
|
42
|
+
| `recommended` | Recommended code quality rules as warnings |
|
|
43
|
+
|
|
44
|
+
## AI-Optimized Messages
|
|
45
|
+
|
|
46
|
+
This plugin is optimized for ESLint's [Model Context Protocol (MCP)](https://eslint.org/docs/latest/use/mcp), enabling AI assistants like **Cursor**, **GitHub Copilot**, and **Claude** to:
|
|
47
|
+
|
|
48
|
+
- Understand the exact vulnerability type via CWE references
|
|
49
|
+
- Apply the correct fix using structured guidance
|
|
50
|
+
- Provide educational context to developers
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
// .cursor/mcp.json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"eslint": {
|
|
57
|
+
"command": "npx",
|
|
58
|
+
"args": ["@eslint/mcp@latest"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
By providing this structured context (CWE, OWASP, Fix), we enable AI tools to **reason** about the security flaw rather than hallucinating. This allows Copilot/Cursor to suggest the _exact_ correct fix immediately.
|
|
65
|
+
|
|
66
|
+
## Rules
|
|
67
|
+
|
|
68
|
+
**Legend**
|
|
69
|
+
|
|
70
|
+
| Icon | Description |
|
|
71
|
+
| :--: | :----------------------------------------------------------------- |
|
|
72
|
+
| 💼 | **Recommended**: Included in the recommended preset. |
|
|
73
|
+
| ⚠️ | **Warns**: Set to warn in recommended preset. |
|
|
74
|
+
| 🔧 | **Auto-fixable**: Automatically fixable by the `--fix` CLI option. |
|
|
75
|
+
| 💡 | **Suggestions**: Providing code suggestions in IDE. |
|
|
76
|
+
| 🚫 | **Deprecated**: This rule is deprecated. |
|
|
77
|
+
|
|
78
|
+
| Rule | Pattern/Concept | Description | 💼 | ⚠️ | 🔧 | 💡 | 🚫 |
|
|
79
|
+
| :--------------------------------------------------------------------------------------------------------------- | :-------------- | :-------------------------------- | :-: | :-: | :-: | :-: | :-: |
|
|
80
|
+
| [`expiring-todo-comments`](https://eslint.interlace.tools/docs/quality/rules/expiring-todo-comments) | Quality | Enforce expiry for TODO comments | | | | | |
|
|
81
|
+
| [`max-parameters`](https://eslint.interlace.tools/docs/quality/rules/max-parameters) | Complexity | Limit function parameters | | | | | |
|
|
82
|
+
| [`no-commented-code`](https://eslint.interlace.tools/docs/quality/rules/no-commented-code) | Quality | Disallow commented code | 💼 | ⚠️ | | | |
|
|
83
|
+
| [`no-lonely-if`](https://eslint.interlace.tools/docs/quality/rules/no-lonely-if) | Quality | Disallow lonely if statements | | | 🔧 | | |
|
|
84
|
+
| [`no-missing-null-checks`](https://eslint.interlace.tools/docs/quality/rules/no-missing-null-checks) | Quality | Enforce null checking | | | | | |
|
|
85
|
+
| [`no-nested-ternary`](https://eslint.interlace.tools/docs/quality/rules/no-nested-ternary) | Complexity | Disallow nested ternaries | | | | | |
|
|
86
|
+
| [`no-unsafe-type-narrowing`](https://eslint.interlace.tools/docs/quality/rules/no-unsafe-type-narrowing) | Type Safety | Prevent unsafe type narrowing | | | | | |
|
|
87
|
+
| [`prefer-code-point`](https://eslint.interlace.tools/docs/quality/rules/prefer-code-point) | Best Practice | Prefer Code Point over Char Code | | | 🔧 | | |
|
|
88
|
+
| [`prefer-dom-node-text-content`](https://eslint.interlace.tools/docs/quality/rules/prefer-dom-node-text-content) | Quality | Prefer textContent over innerText | | | 🔧 | | |
|
|
89
|
+
| [`cognitive-complexity`](https://eslint.interlace.tools/docs/quality/rules/cognitive-complexity) | Complexity | Limit cognitive complexity | 💼 | ⚠️ | | | |
|
|
90
|
+
| [`nested-complexity-hotspots`](https://eslint.interlace.tools/docs/quality/rules/nested-complexity-hotspots) | Complexity | Detect nested complexity hotpots | | | | | |
|
|
91
|
+
| [`error-message`](https://eslint.interlace.tools/docs/quality/rules/error-message) | Error Handling | Enforce error message conventions | | | | | |
|
|
92
|
+
| [`no-missing-error-context`](https://eslint.interlace.tools/docs/quality/rules/no-missing-error-context) | Error Handling | Ensure errors have context | | | | | |
|
|
93
|
+
| [`no-silent-errors`](https://eslint.interlace.tools/docs/quality/rules/no-silent-errors) | Error Handling | Disallow silent error swallowing | 💼 | ⚠️ | | | |
|
|
94
|
+
| [`no-unhandled-promise`](https://eslint.interlace.tools/docs/quality/rules/no-unhandled-promise) | Error Handling | Ensure all promises are handled | | | | | |
|
|
95
|
+
|
|
96
|
+
Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with LLM-optimized error messages:
|
|
97
|
+
|
|
98
|
+
| Plugin | Downloads | Description |
|
|
99
|
+
| :----------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------ |
|
|
100
|
+
| [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | [](https://www.npmjs.com/package/eslint-plugin-secure-coding) | General security rules & OWASP guidelines. |
|
|
101
|
+
| [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | [](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL security & best practices. |
|
|
102
|
+
| [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | [](https://www.npmjs.com/package/eslint-plugin-crypto) | NodeJS Cryptography security rules. |
|
|
103
|
+
| [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | [](https://www.npmjs.com/package/eslint-plugin-jwt) | JWT security & best practices. |
|
|
104
|
+
| [`eslint-plugin-browser-security`](https://www.npmjs.com/package/eslint-plugin-browser-security) | [](https://www.npmjs.com/package/eslint-plugin-browser-security) | Browser-specific security & XSS prevention. |
|
|
105
|
+
| [`eslint-plugin-express-security`](https://www.npmjs.com/package/eslint-plugin-express-security) | [](https://www.npmjs.com/package/eslint-plugin-express-security) | Express.js security hardening rules. |
|
|
106
|
+
| [`eslint-plugin-lambda-security`](https://www.npmjs.com/package/eslint-plugin-lambda-security) | [](https://www.npmjs.com/package/eslint-plugin-lambda-security) | AWS Lambda security best practices. |
|
|
107
|
+
| [`eslint-plugin-nestjs-security`](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | [](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | NestJS security rules & patterns. |
|
|
108
|
+
| [`eslint-plugin-import-next`](https://www.npmjs.com/package/eslint-plugin-import-next) | [](https://www.npmjs.com/package/eslint-plugin-import-next) | Next-gen import sorting & architecture. |
|
|
109
|
+
|
|
110
|
+
## 📄 License
|
|
111
|
+
|
|
112
|
+
MIT © [Ofri Peretz](https://github.com/ofri-peretz)
|
|
113
|
+
|
|
114
|
+
<p align="center">
|
|
115
|
+
<a href="https://eslint.interlace.tools/docs/quality"><img src="https://eslint.interlace.tools/images/og-quality.png" alt="ESLint Interlace Plugin" width="300" /></a>
|
|
116
|
+
</p>
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eslint-plugin-maintainability",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "ESLint rules for reducing cognitive load and ensuring code readability.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"types": "./src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./types": {
|
|
14
|
+
"types": "./src/types/index.d.ts",
|
|
15
|
+
"default": "./src/types/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"author": "Ofri Peretz <ofriperetzdev@gmail.com>",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"src/",
|
|
25
|
+
"dist/",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"CHANGELOG.md"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"eslint",
|
|
32
|
+
"eslint-plugin",
|
|
33
|
+
"interlace-quality",
|
|
34
|
+
"code-quality",
|
|
35
|
+
"clean-code",
|
|
36
|
+
"maintainability",
|
|
37
|
+
"llm-optimized"
|
|
38
|
+
],
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"typescript": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"tslib": "^2.3.0",
|
|
50
|
+
"@interlace/eslint-devkit": "*"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
54
|
+
"@typescript-eslint/rule-tester": "^8.46.2"
|
|
55
|
+
},
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": "https://github.com/ofri-peretz/eslint",
|
|
59
|
+
"directory": "packages/eslint-plugin-maintainability"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/ofri-peretz/eslint/tree/main/packages/eslint-plugin-maintainability#readme",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/ofri-peretz/eslint/issues"
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
7
|
+
export declare const rules: {
|
|
8
|
+
'cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
'nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
14
|
+
'identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
15
|
+
name: string;
|
|
16
|
+
};
|
|
17
|
+
'max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
'no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
'no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
24
|
+
name: string;
|
|
25
|
+
};
|
|
26
|
+
'consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
'no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
30
|
+
name: string;
|
|
31
|
+
};
|
|
32
|
+
'maintainability/cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
33
|
+
name: string;
|
|
34
|
+
};
|
|
35
|
+
'maintainability/nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
36
|
+
name: string;
|
|
37
|
+
};
|
|
38
|
+
'maintainability/identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
39
|
+
name: string;
|
|
40
|
+
};
|
|
41
|
+
'maintainability/max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
42
|
+
name: string;
|
|
43
|
+
};
|
|
44
|
+
'maintainability/no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
'maintainability/no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
48
|
+
name: string;
|
|
49
|
+
};
|
|
50
|
+
'maintainability/consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
51
|
+
name: string;
|
|
52
|
+
};
|
|
53
|
+
'maintainability/no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
54
|
+
name: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export declare const plugin: {
|
|
58
|
+
meta: {
|
|
59
|
+
name: string;
|
|
60
|
+
version: string;
|
|
61
|
+
};
|
|
62
|
+
rules: {
|
|
63
|
+
'cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
'nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
67
|
+
name: string;
|
|
68
|
+
};
|
|
69
|
+
'identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
70
|
+
name: string;
|
|
71
|
+
};
|
|
72
|
+
'max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
73
|
+
name: string;
|
|
74
|
+
};
|
|
75
|
+
'no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
76
|
+
name: string;
|
|
77
|
+
};
|
|
78
|
+
'no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
79
|
+
name: string;
|
|
80
|
+
};
|
|
81
|
+
'consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
82
|
+
name: string;
|
|
83
|
+
};
|
|
84
|
+
'no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
85
|
+
name: string;
|
|
86
|
+
};
|
|
87
|
+
'maintainability/cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
88
|
+
name: string;
|
|
89
|
+
};
|
|
90
|
+
'maintainability/nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
91
|
+
name: string;
|
|
92
|
+
};
|
|
93
|
+
'maintainability/identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
94
|
+
name: string;
|
|
95
|
+
};
|
|
96
|
+
'maintainability/max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
97
|
+
name: string;
|
|
98
|
+
};
|
|
99
|
+
'maintainability/no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
100
|
+
name: string;
|
|
101
|
+
};
|
|
102
|
+
'maintainability/no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
103
|
+
name: string;
|
|
104
|
+
};
|
|
105
|
+
'maintainability/consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
'maintainability/no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
109
|
+
name: string;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
export declare const configs: {
|
|
114
|
+
recommended: {
|
|
115
|
+
plugins: {
|
|
116
|
+
'@interlace/maintainability': {
|
|
117
|
+
meta: {
|
|
118
|
+
name: string;
|
|
119
|
+
version: string;
|
|
120
|
+
};
|
|
121
|
+
rules: {
|
|
122
|
+
'cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
123
|
+
name: string;
|
|
124
|
+
};
|
|
125
|
+
'nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
126
|
+
name: string;
|
|
127
|
+
};
|
|
128
|
+
'identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
129
|
+
name: string;
|
|
130
|
+
};
|
|
131
|
+
'max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
132
|
+
name: string;
|
|
133
|
+
};
|
|
134
|
+
'no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
135
|
+
name: string;
|
|
136
|
+
};
|
|
137
|
+
'no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
138
|
+
name: string;
|
|
139
|
+
};
|
|
140
|
+
'consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
141
|
+
name: string;
|
|
142
|
+
};
|
|
143
|
+
'no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
144
|
+
name: string;
|
|
145
|
+
};
|
|
146
|
+
'maintainability/cognitive-complexity': TSESLint.RuleModule<"highCognitiveComplexity" | "extractMethod" | "simplifyLogic" | "useStrategy", [(import("./rules/maintainability/cognitive-complexity").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
147
|
+
name: string;
|
|
148
|
+
};
|
|
149
|
+
'maintainability/nested-complexity-hotspots': TSESLint.RuleModule<"extractMethod" | "nestedComplexity" | "useEarlyReturn" | "useGuardClauses", [(import("./rules/maintainability/nested-complexity-hotspots").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
150
|
+
name: string;
|
|
151
|
+
};
|
|
152
|
+
'maintainability/identical-functions': TSESLint.RuleModule<"identicalFunctions" | "extractGeneric" | "useHigherOrder" | "applyInheritance", [(import("./rules/maintainability/identical-functions").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
153
|
+
name: string;
|
|
154
|
+
};
|
|
155
|
+
'maintainability/max-parameters': TSESLint.RuleModule<"tooManyParameters" | "useObjectParameter" | "extractToClass" | "splitFunction", [(import("./rules/maintainability/max-parameters").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
156
|
+
name: string;
|
|
157
|
+
};
|
|
158
|
+
'maintainability/no-lonely-if': TSESLint.RuleModule<"noLonelyIf", [(import("./rules/maintainability/no-lonely-if").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
159
|
+
name: string;
|
|
160
|
+
};
|
|
161
|
+
'maintainability/no-nested-ternary': TSESLint.RuleModule<"noNestedTernary", [(import("./rules/maintainability/no-nested-ternary").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
162
|
+
name: string;
|
|
163
|
+
};
|
|
164
|
+
'maintainability/consistent-function-scoping': TSESLint.RuleModule<"inconsistentFunctionScoping" | "moveToModuleScope", [(import("./rules/maintainability/consistent-function-scoping").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
165
|
+
name: string;
|
|
166
|
+
};
|
|
167
|
+
'maintainability/no-unreadable-iife': TSESLint.RuleModule<"unreadableIIFE" | "suggestNamedFunction" | "suggestBlockScope" | "complexIIFE", [(import("./rules/maintainability/no-unreadable-iife").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
168
|
+
name: string;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
rules: {
|
|
174
|
+
'@interlace/maintainability/maintainability/cognitive-complexity': "warn";
|
|
175
|
+
'@interlace/maintainability/maintainability/identical-functions': "warn";
|
|
176
|
+
'@interlace/maintainability/maintainability/max-parameters': "warn";
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
export default plugin;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.configs = exports.plugin = exports.rules = void 0;
|
|
9
|
+
// Maintainability rules
|
|
10
|
+
const cognitive_complexity_1 = require("./rules/maintainability/cognitive-complexity");
|
|
11
|
+
const nested_complexity_hotspots_1 = require("./rules/maintainability/nested-complexity-hotspots");
|
|
12
|
+
const identical_functions_1 = require("./rules/maintainability/identical-functions");
|
|
13
|
+
const max_parameters_1 = require("./rules/maintainability/max-parameters");
|
|
14
|
+
const no_lonely_if_1 = require("./rules/maintainability/no-lonely-if");
|
|
15
|
+
const no_nested_ternary_1 = require("./rules/maintainability/no-nested-ternary");
|
|
16
|
+
const consistent_function_scoping_1 = require("./rules/maintainability/consistent-function-scoping");
|
|
17
|
+
const no_unreadable_iife_1 = require("./rules/maintainability/no-unreadable-iife");
|
|
18
|
+
exports.rules = {
|
|
19
|
+
'cognitive-complexity': cognitive_complexity_1.cognitiveComplexity,
|
|
20
|
+
'nested-complexity-hotspots': nested_complexity_hotspots_1.nestedComplexityHotspots,
|
|
21
|
+
'identical-functions': identical_functions_1.identicalFunctions,
|
|
22
|
+
'max-parameters': max_parameters_1.maxParameters,
|
|
23
|
+
'no-lonely-if': no_lonely_if_1.noLonelyIf,
|
|
24
|
+
'no-nested-ternary': no_nested_ternary_1.noNestedTernary,
|
|
25
|
+
'consistent-function-scoping': consistent_function_scoping_1.consistentFunctionScoping,
|
|
26
|
+
'no-unreadable-iife': no_unreadable_iife_1.noUnreadableIife,
|
|
27
|
+
// Categorized names
|
|
28
|
+
'maintainability/cognitive-complexity': cognitive_complexity_1.cognitiveComplexity,
|
|
29
|
+
'maintainability/nested-complexity-hotspots': nested_complexity_hotspots_1.nestedComplexityHotspots,
|
|
30
|
+
'maintainability/identical-functions': identical_functions_1.identicalFunctions,
|
|
31
|
+
'maintainability/max-parameters': max_parameters_1.maxParameters,
|
|
32
|
+
'maintainability/no-lonely-if': no_lonely_if_1.noLonelyIf,
|
|
33
|
+
'maintainability/no-nested-ternary': no_nested_ternary_1.noNestedTernary,
|
|
34
|
+
'maintainability/consistent-function-scoping': consistent_function_scoping_1.consistentFunctionScoping,
|
|
35
|
+
'maintainability/no-unreadable-iife': no_unreadable_iife_1.noUnreadableIife,
|
|
36
|
+
};
|
|
37
|
+
exports.plugin = {
|
|
38
|
+
meta: {
|
|
39
|
+
name: '@interlace/eslint-plugin-maintainability',
|
|
40
|
+
version: '1.0.0',
|
|
41
|
+
},
|
|
42
|
+
rules: exports.rules,
|
|
43
|
+
};
|
|
44
|
+
exports.configs = {
|
|
45
|
+
recommended: {
|
|
46
|
+
plugins: {
|
|
47
|
+
'@interlace/maintainability': exports.plugin,
|
|
48
|
+
},
|
|
49
|
+
rules: {
|
|
50
|
+
'@interlace/maintainability/maintainability/cognitive-complexity': 'warn',
|
|
51
|
+
'@interlace/maintainability/maintainability/identical-functions': 'warn',
|
|
52
|
+
'@interlace/maintainability/maintainability/max-parameters': 'warn',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
exports.default = exports.plugin;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: error-message
|
|
8
|
+
* Enforces providing a message when creating built-in Error objects
|
|
9
|
+
*/
|
|
10
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
11
|
+
type MessageIds = 'missingErrorMessage' | 'addErrorMessage';
|
|
12
|
+
export interface Options {
|
|
13
|
+
/** Allow Error() without message (not recommended) */
|
|
14
|
+
allowEmptyCatch?: boolean;
|
|
15
|
+
}
|
|
16
|
+
type RuleOptions = [Options?];
|
|
17
|
+
export declare const errorMessage: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
export {};
|