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.
Files changed (32) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/LICENSE +23 -0
  3. package/README.md +116 -0
  4. package/package.json +65 -0
  5. package/src/index.d.ts +180 -0
  6. package/src/index.js +56 -0
  7. package/src/rules/error-handling/error-message.d.ts +20 -0
  8. package/src/rules/error-handling/error-message.js +146 -0
  9. package/src/rules/error-handling/no-missing-error-context.d.ts +26 -0
  10. package/src/rules/error-handling/no-missing-error-context.js +183 -0
  11. package/src/rules/error-handling/no-silent-errors.d.ts +24 -0
  12. package/src/rules/error-handling/no-silent-errors.js +178 -0
  13. package/src/rules/error-handling/no-unhandled-promise.d.ts +26 -0
  14. package/src/rules/error-handling/no-unhandled-promise.js +351 -0
  15. package/src/rules/maintainability/cognitive-complexity.d.ts +28 -0
  16. package/src/rules/maintainability/cognitive-complexity.js +381 -0
  17. package/src/rules/maintainability/consistent-function-scoping.d.ts +20 -0
  18. package/src/rules/maintainability/consistent-function-scoping.js +226 -0
  19. package/src/rules/maintainability/identical-functions.d.ts +27 -0
  20. package/src/rules/maintainability/identical-functions.js +310 -0
  21. package/src/rules/maintainability/max-parameters.d.ts +29 -0
  22. package/src/rules/maintainability/max-parameters.js +143 -0
  23. package/src/rules/maintainability/nested-complexity-hotspots.d.ts +31 -0
  24. package/src/rules/maintainability/nested-complexity-hotspots.js +190 -0
  25. package/src/rules/maintainability/no-lonely-if.d.ts +19 -0
  26. package/src/rules/maintainability/no-lonely-if.js +120 -0
  27. package/src/rules/maintainability/no-nested-ternary.d.ts +19 -0
  28. package/src/rules/maintainability/no-nested-ternary.js +165 -0
  29. package/src/rules/maintainability/no-unreadable-iife.d.ts +24 -0
  30. package/src/rules/maintainability/no-unreadable-iife.js +239 -0
  31. package/src/types/index.d.ts +48 -0
  32. 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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-secure-coding.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-pg.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL security & best practices. |
102
+ | [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-crypto.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-crypto) | NodeJS Cryptography security rules. |
103
+ | [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-jwt.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-browser-security.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-express-security.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-lambda-security.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-nestjs-security.svg?style=flat-square)](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) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-import-next.svg?style=flat-square)](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 {};