eslint-plugin-conventions 4.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 (35) hide show
  1. package/README.md +80 -0
  2. package/package.json +55 -0
  3. package/src/index.d.ts +198 -0
  4. package/src/index.js +60 -0
  5. package/src/index.js.map +1 -0
  6. package/src/lib/eslint-plugin-conventions.d.ts +1 -0
  7. package/src/lib/eslint-plugin-conventions.js +7 -0
  8. package/src/lib/eslint-plugin-conventions.js.map +1 -0
  9. package/src/rules/conventions/consistent-existence-index-check.d.ts +19 -0
  10. package/src/rules/conventions/consistent-existence-index-check.js +141 -0
  11. package/src/rules/conventions/consistent-existence-index-check.js.map +1 -0
  12. package/src/rules/conventions/expiring-todo-comments.d.ts +24 -0
  13. package/src/rules/conventions/expiring-todo-comments.js +307 -0
  14. package/src/rules/conventions/expiring-todo-comments.js.map +1 -0
  15. package/src/rules/conventions/filename-case.d.ts +32 -0
  16. package/src/rules/conventions/filename-case.js +264 -0
  17. package/src/rules/conventions/filename-case.js.map +1 -0
  18. package/src/rules/conventions/no-commented-code.d.ts +26 -0
  19. package/src/rules/conventions/no-commented-code.js +278 -0
  20. package/src/rules/conventions/no-commented-code.js.map +1 -0
  21. package/src/rules/conventions/no-console-spaces.d.ts +13 -0
  22. package/src/rules/conventions/no-console-spaces.js +128 -0
  23. package/src/rules/conventions/no-console-spaces.js.map +1 -0
  24. package/src/rules/conventions/prefer-code-point.d.ts +13 -0
  25. package/src/rules/conventions/prefer-code-point.js +95 -0
  26. package/src/rules/conventions/prefer-code-point.js.map +1 -0
  27. package/src/rules/conventions/prefer-dependency-version-strategy.d.ts +29 -0
  28. package/src/rules/conventions/prefer-dependency-version-strategy.js +226 -0
  29. package/src/rules/conventions/prefer-dependency-version-strategy.js.map +1 -0
  30. package/src/rules/conventions/prefer-dom-node-text-content.d.ts +13 -0
  31. package/src/rules/conventions/prefer-dom-node-text-content.js +147 -0
  32. package/src/rules/conventions/prefer-dom-node-text-content.js.map +1 -0
  33. package/src/rules/deprecation/no-deprecated-api.d.ts +30 -0
  34. package/src/rules/deprecation/no-deprecated-api.js +174 -0
  35. package/src/rules/deprecation/no-deprecated-api.js.map +1 -0
package/README.md ADDED
@@ -0,0 +1,80 @@
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 conventions and style enforcement for JavaScript/TypeScript teams.
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/eslint-plugin-conventions" target="_blank"><img src="https://img.shields.io/npm/v/eslint-plugin-conventions.svg" alt="NPM Version" /></a>
11
+ <a href="https://www.npmjs.com/package/eslint-plugin-conventions" target="_blank"><img src="https://img.shields.io/npm/dm/eslint-plugin-conventions.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
+ </p>
14
+
15
+ ## Description
16
+
17
+ This plugin enforces consistent code conventions and style patterns across JavaScript and TypeScript projects. It helps teams maintain clean, readable, and maintainable codebases by detecting commented-out code, expired TODOs, deprecated API usage, and inconsistent naming patterns.
18
+
19
+ ## Philosophy
20
+
21
+ **Interlace** fosters **strength through integration**. We believe conventions should be enforced automatically, not debated endlessly. These rules capture best practices from top engineering teams and enforce them consistently across your codebase.
22
+
23
+ ## Getting Started
24
+
25
+ - To check out the [guide](https://eslint.interlace.tools/docs/conventions), visit [eslint.interlace.tools](https://eslint.interlace.tools). 📚
26
+
27
+ ```bash
28
+ npm install eslint-plugin-conventions --save-dev
29
+ ```
30
+
31
+ ## ⚙️ Configuration Presets
32
+
33
+ | Preset | Description |
34
+ | :------------ | :---------------------------------- |
35
+ | `recommended` | Balanced conventions for most teams |
36
+
37
+ ---
38
+
39
+ ## 🏢 Usage Example
40
+
41
+ ```js
42
+ // eslint.config.js
43
+ import conventions from 'eslint-plugin-conventions';
44
+
45
+ export default [conventions.configs.recommended];
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Rules
51
+
52
+ | Rule | Description | 💼 | ⚠️ |
53
+ | :--------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :-: | :-: |
54
+ | [no-commented-code](./docs/rules/no-commented-code.md) | Disallow commented-out code blocks | 💼 | ⚠️ |
55
+ | [expiring-todo-comments](./docs/rules/expiring-todo-comments.md) | Enforce expiration dates on TODO comments | 💼 | ⚠️ |
56
+ | [prefer-code-point](./docs/rules/prefer-code-point.md) | Prefer `codePointAt` over `charCodeAt` for Unicode safety | | |
57
+ | [prefer-dom-node-text-content](./docs/rules/prefer-dom-node-text-content.md) | Prefer `textContent` over `innerText` for performance | | |
58
+ | [no-console-spaces](./docs/rules/no-console-spaces.md) | Disallow leading/trailing spaces in console calls | | |
59
+ | [no-deprecated-api](./docs/rules/no-deprecated-api.md) | Disallow usage of deprecated Node.js APIs | 💼 | ⚠️ |
60
+ | [prefer-dependency-version-strategy](./docs/rules/prefer-dependency-version-strategy.md) | Enforce consistent version strategies in package.json | | |
61
+ | [filename-case](./docs/rules/filename-case.md) | Enforce consistent file naming conventions | | |
62
+ | [consistent-existence-index-check](./docs/rules/consistent-existence-index-check.md) | Enforce consistent array index existence checks | | |
63
+
64
+ **Legend**: 💼 Recommended | ⚠️ Warns (not error)
65
+
66
+ ---
67
+
68
+ ## 🔗 Related ESLint Plugins
69
+
70
+ Part of the **Interlace ESLint Ecosystem** — AI-native quality plugins with LLM-optimized error messages:
71
+
72
+ | Plugin | Description |
73
+ | :--------------------------------------------------------------------------------------------- | :---------------------------------- |
74
+ | [`eslint-plugin-maintainability`](https://www.npmjs.com/package/eslint-plugin-maintainability) | Cognitive complexity & code quality |
75
+ | [`eslint-plugin-reliability`](https://www.npmjs.com/package/eslint-plugin-reliability) | Error handling & null safety |
76
+ | [`eslint-plugin-operability`](https://www.npmjs.com/package/eslint-plugin-operability) | Production readiness & debug code |
77
+
78
+ ## 📄 License
79
+
80
+ MIT © [Ofri Peretz](https://github.com/ofri-peretz)
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "eslint-plugin-conventions",
3
+ "version": "4.0.0",
4
+ "description": "ESLint rules for team-specific disciplinary patterns and code conventions.",
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
+ },
14
+ "author": "Ofri Peretz <ofriperetzdev@gmail.com>",
15
+ "license": "MIT",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "src/",
21
+ "dist/",
22
+ "README.md",
23
+ "LICENSE",
24
+ "CHANGELOG.md"
25
+ ],
26
+ "keywords": [
27
+ "eslint",
28
+ "eslint-plugin",
29
+ "interlace-quality",
30
+ "conventions",
31
+ "clean-code",
32
+ "consistency",
33
+ "llm-optimized"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "dependencies": {
39
+ "tslib": "^2.3.0",
40
+ "@interlace/eslint-devkit": "*"
41
+ },
42
+ "devDependencies": {
43
+ "@typescript-eslint/parser": "^8.46.2",
44
+ "@typescript-eslint/rule-tester": "^8.46.2"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/ofri-peretz/eslint",
49
+ "directory": "packages/eslint-plugin-conventions"
50
+ },
51
+ "homepage": "https://github.com/ofri-peretz/eslint/tree/main/packages/eslint-plugin-conventions#readme",
52
+ "bugs": {
53
+ "url": "https://github.com/ofri-peretz/eslint/issues"
54
+ }
55
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,198 @@
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
+ 'no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
9
+ name: string;
10
+ };
11
+ 'expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
12
+ name: string;
13
+ };
14
+ 'prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
15
+ name: string;
16
+ };
17
+ 'prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
18
+ name: string;
19
+ };
20
+ 'no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
21
+ name: string;
22
+ };
23
+ 'no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
24
+ name: string;
25
+ };
26
+ 'prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
27
+ name: string;
28
+ };
29
+ 'filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
30
+ name: string;
31
+ };
32
+ 'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
33
+ name: string;
34
+ };
35
+ 'conventions/no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
36
+ name: string;
37
+ };
38
+ 'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
39
+ name: string;
40
+ };
41
+ 'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
42
+ name: string;
43
+ };
44
+ 'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
45
+ name: string;
46
+ };
47
+ 'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
48
+ name: string;
49
+ };
50
+ 'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
51
+ name: string;
52
+ };
53
+ 'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
54
+ name: string;
55
+ };
56
+ 'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
57
+ name: string;
58
+ };
59
+ 'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
60
+ name: string;
61
+ };
62
+ };
63
+ export declare const plugin: {
64
+ meta: {
65
+ name: string;
66
+ version: string;
67
+ };
68
+ rules: {
69
+ 'no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
70
+ name: string;
71
+ };
72
+ 'expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
73
+ name: string;
74
+ };
75
+ 'prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
76
+ name: string;
77
+ };
78
+ 'prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
79
+ name: string;
80
+ };
81
+ 'no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
82
+ name: string;
83
+ };
84
+ 'no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
85
+ name: string;
86
+ };
87
+ 'prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
88
+ name: string;
89
+ };
90
+ 'filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
91
+ name: string;
92
+ };
93
+ 'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
94
+ name: string;
95
+ };
96
+ 'conventions/no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
97
+ name: string;
98
+ };
99
+ 'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
100
+ name: string;
101
+ };
102
+ 'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
103
+ name: string;
104
+ };
105
+ 'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
106
+ name: string;
107
+ };
108
+ 'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
109
+ name: string;
110
+ };
111
+ 'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
112
+ name: string;
113
+ };
114
+ 'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
115
+ name: string;
116
+ };
117
+ 'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
118
+ name: string;
119
+ };
120
+ 'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
121
+ name: string;
122
+ };
123
+ };
124
+ };
125
+ export declare const configs: {
126
+ recommended: {
127
+ plugins: {
128
+ '@interlace/conventions': {
129
+ meta: {
130
+ name: string;
131
+ version: string;
132
+ };
133
+ rules: {
134
+ 'no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
135
+ name: string;
136
+ };
137
+ 'expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
138
+ name: string;
139
+ };
140
+ 'prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
141
+ name: string;
142
+ };
143
+ 'prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
144
+ name: string;
145
+ };
146
+ 'no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
147
+ name: string;
148
+ };
149
+ 'no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
150
+ name: string;
151
+ };
152
+ 'prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
153
+ name: string;
154
+ };
155
+ 'filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
156
+ name: string;
157
+ };
158
+ 'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
159
+ name: string;
160
+ };
161
+ 'conventions/no-commented-code': TSESLint.RuleModule<"commentedCode" | "removeCode" | "useVersionControl", [(import("./rules/conventions/no-commented-code").Options | undefined)?], unknown, TSESLint.RuleListener> & {
162
+ name: string;
163
+ };
164
+ 'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
165
+ name: string;
166
+ };
167
+ 'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
168
+ name: string;
169
+ };
170
+ 'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
171
+ name: string;
172
+ };
173
+ 'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
174
+ name: string;
175
+ };
176
+ 'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
177
+ name: string;
178
+ };
179
+ 'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
180
+ name: string;
181
+ };
182
+ 'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
183
+ name: string;
184
+ };
185
+ 'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
186
+ name: string;
187
+ };
188
+ };
189
+ };
190
+ };
191
+ rules: {
192
+ '@interlace/conventions/conventions/no-commented-code': "warn";
193
+ '@interlace/conventions/conventions/expiring-todo-comments': "warn";
194
+ '@interlace/conventions/deprecation/no-deprecated-api': "warn";
195
+ };
196
+ };
197
+ };
198
+ export default plugin;
package/src/index.js ADDED
@@ -0,0 +1,60 @@
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
+ // Conventions rules
10
+ const no_commented_code_1 = require("./rules/conventions/no-commented-code");
11
+ const expiring_todo_comments_1 = require("./rules/conventions/expiring-todo-comments");
12
+ const prefer_code_point_1 = require("./rules/conventions/prefer-code-point");
13
+ const prefer_dom_node_text_content_1 = require("./rules/conventions/prefer-dom-node-text-content");
14
+ const no_console_spaces_1 = require("./rules/conventions/no-console-spaces");
15
+ const no_deprecated_api_1 = require("./rules/deprecation/no-deprecated-api");
16
+ const prefer_dependency_version_strategy_1 = require("./rules/conventions/prefer-dependency-version-strategy");
17
+ const filename_case_1 = require("./rules/conventions/filename-case");
18
+ const consistent_existence_index_check_1 = require("./rules/conventions/consistent-existence-index-check");
19
+ exports.rules = {
20
+ 'no-commented-code': no_commented_code_1.noCommentedCode,
21
+ 'expiring-todo-comments': expiring_todo_comments_1.expiringTodoComments,
22
+ 'prefer-code-point': prefer_code_point_1.preferCodePoint,
23
+ 'prefer-dom-node-text-content': prefer_dom_node_text_content_1.preferDomNodeTextContent,
24
+ 'no-console-spaces': no_console_spaces_1.noConsoleSpaces,
25
+ 'no-deprecated-api': no_deprecated_api_1.noDeprecatedApi,
26
+ 'prefer-dependency-version-strategy': prefer_dependency_version_strategy_1.preferDependencyVersionStrategy,
27
+ 'filename-case': filename_case_1.filenameCase,
28
+ 'consistent-existence-index-check': consistent_existence_index_check_1.consistentExistenceIndexCheck,
29
+ // Categorized names
30
+ 'conventions/no-commented-code': no_commented_code_1.noCommentedCode,
31
+ 'conventions/expiring-todo-comments': expiring_todo_comments_1.expiringTodoComments,
32
+ 'conventions/prefer-code-point': prefer_code_point_1.preferCodePoint,
33
+ 'conventions/prefer-dom-node-text-content': prefer_dom_node_text_content_1.preferDomNodeTextContent,
34
+ 'conventions/no-console-spaces': no_console_spaces_1.noConsoleSpaces,
35
+ 'deprecation/no-deprecated-api': no_deprecated_api_1.noDeprecatedApi,
36
+ 'conventions/prefer-dependency-version-strategy': prefer_dependency_version_strategy_1.preferDependencyVersionStrategy,
37
+ 'conventions/filename-case': filename_case_1.filenameCase,
38
+ 'conventions/consistent-existence-index-check': consistent_existence_index_check_1.consistentExistenceIndexCheck,
39
+ };
40
+ exports.plugin = {
41
+ meta: {
42
+ name: 'eslint-plugin-conventions',
43
+ version: '1.0.0',
44
+ },
45
+ rules: exports.rules,
46
+ };
47
+ exports.configs = {
48
+ recommended: {
49
+ plugins: {
50
+ '@interlace/conventions': exports.plugin,
51
+ },
52
+ rules: {
53
+ '@interlace/conventions/conventions/no-commented-code': 'warn',
54
+ '@interlace/conventions/conventions/expiring-todo-comments': 'warn',
55
+ '@interlace/conventions/deprecation/no-deprecated-api': 'warn',
56
+ },
57
+ },
58
+ };
59
+ exports.default = exports.plugin;
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin-conventions/src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,oBAAoB;AACpB,6EAAwE;AACxE,uFAAkF;AAClF,6EAAwE;AACxE,mGAA4F;AAC5F,6EAAwE;AACxE,6EAAwE;AACxE,+GAAyG;AACzG,qEAAiE;AACjE,2GAAqG;AAExF,QAAA,KAAK,GAAG;IACnB,mBAAmB,EAAE,mCAAe;IACpC,wBAAwB,EAAE,6CAAoB;IAC9C,mBAAmB,EAAE,mCAAe;IACpC,8BAA8B,EAAE,uDAAwB;IACxD,mBAAmB,EAAE,mCAAe;IACpC,mBAAmB,EAAE,mCAAe;IACpC,oCAAoC,EAAE,oEAA+B;IACrE,eAAe,EAAE,4BAAY;IAC7B,kCAAkC,EAAE,gEAA6B;IAEjE,oBAAoB;IACpB,+BAA+B,EAAE,mCAAe;IAChD,oCAAoC,EAAE,6CAAoB;IAC1D,+BAA+B,EAAE,mCAAe;IAChD,0CAA0C,EAAE,uDAAwB;IACpE,+BAA+B,EAAE,mCAAe;IAChD,+BAA+B,EAAE,mCAAe;IAChD,gDAAgD,EAAE,oEAA+B;IACjF,2BAA2B,EAAE,4BAAY;IACzC,8CAA8C,EAAE,gEAA6B;CACJ,CAAC;AAE/D,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE;QACJ,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,OAAO;KACjB;IACD,KAAK,EAAL,aAAK;CAC+B,CAAC;AAE1B,QAAA,OAAO,GAAG;IACrB,WAAW,EAAE;QACX,OAAO,EAAE;YACP,wBAAwB,EAAE,cAAM;SACjC;QACD,KAAK,EAAE;YACL,sDAAsD,EAAE,MAAM;YAC9D,2DAA2D,EAAE,MAAM;YACnE,sDAAsD,EAAE,MAAM;SAC/D;KACmC;CACc,CAAC;AAEvD,kBAAe,cAAM,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function eslintPluginConventions(): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eslintPluginConventions = eslintPluginConventions;
4
+ function eslintPluginConventions() {
5
+ return 'eslint-plugin-conventions';
6
+ }
7
+ //# sourceMappingURL=eslint-plugin-conventions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint-plugin-conventions.js","sourceRoot":"","sources":["../../../../../packages/eslint-plugin-conventions/src/lib/eslint-plugin-conventions.ts"],"names":[],"mappings":";;AAAA,0DAEC;AAFD,SAAgB,uBAAuB;IACrC,OAAO,2BAA2B,CAAC;AACrC,CAAC"}
@@ -0,0 +1,19 @@
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: consistent-existence-index-check
8
+ * Enforce consistent style for checking object property existence
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ export interface Options {
12
+ /** Preferred method for checking property existence */
13
+ preferred?: 'in' | 'hasOwnProperty' | 'Object.hasOwn';
14
+ }
15
+ type RuleOptions = [Options?];
16
+ export declare const consistentExistenceIndexCheck: TSESLint.RuleModule<"consistentExistenceCheck", RuleOptions, unknown, TSESLint.RuleListener> & {
17
+ name: string;
18
+ };
19
+ export {};
@@ -0,0 +1,141 @@
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.consistentExistenceIndexCheck = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.consistentExistenceIndexCheck = (0, eslint_devkit_1.createRule)({
12
+ name: 'consistent-existence-index-check',
13
+ meta: {
14
+ type: 'suggestion',
15
+ docs: {
16
+ description: 'Enforce consistent style for checking object property existence',
17
+ },
18
+ fixable: 'code',
19
+ hasSuggestions: true,
20
+ messages: {
21
+ consistentExistenceCheck: (0, eslint_devkit_2.formatLLMMessage)({
22
+ icon: eslint_devkit_2.MessageIcons.WARNING,
23
+ issueName: 'Inconsistent Property Check',
24
+ description: 'Use consistent method for property existence checks',
25
+ severity: 'MEDIUM',
26
+ fix: 'Use "{{preferred}}" instead of "{{current}}" for property checks',
27
+ documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in',
28
+ }),
29
+ },
30
+ schema: [
31
+ {
32
+ type: 'object',
33
+ properties: {
34
+ preferred: {
35
+ type: 'string',
36
+ enum: ['in', 'hasOwnProperty', 'Object.hasOwn'],
37
+ default: 'in',
38
+ },
39
+ },
40
+ additionalProperties: false,
41
+ },
42
+ ],
43
+ },
44
+ defaultOptions: [{ preferred: 'in' }],
45
+ create(context) {
46
+ const [options] = context.options;
47
+ const { preferred = 'in' } = options || {};
48
+ function reportInconsistentCheck(node, currentMethod, object, property) {
49
+ let fix;
50
+ // Only provide fixes for standalone expressions, not when part of larger expressions
51
+ const parent = node.parent;
52
+ const isStandaloneExpression = !parent ||
53
+ parent.type === 'ExpressionStatement' ||
54
+ (parent.type === 'VariableDeclarator' && parent.init === node) ||
55
+ (parent.type === 'AssignmentExpression' && parent.right === node) ||
56
+ (parent.type === 'ReturnStatement' && parent.argument === node) ||
57
+ (parent.type === 'ArrowFunctionExpression' && parent.body === node) ||
58
+ (parent.type === 'IfStatement' && parent.test === node) ||
59
+ (parent.type === 'WhileStatement' && parent.test === node) ||
60
+ (parent.type === 'DoWhileStatement' && parent.test === node) ||
61
+ (parent.type === 'ForStatement' && parent.test === node) ||
62
+ (parent.type === 'ConditionalExpression' && parent.test === node);
63
+ if (preferred === 'in' && isStandaloneExpression) {
64
+ fix = function (fixer) {
65
+ const objectText = context.sourceCode.getText(object);
66
+ const propertyText = context.sourceCode.getText(property);
67
+ return fixer.replaceText(node, `${propertyText} in ${objectText}`);
68
+ };
69
+ }
70
+ else if (preferred === 'hasOwnProperty' && isStandaloneExpression) {
71
+ fix = function (fixer) {
72
+ const objectText = context.sourceCode.getText(object);
73
+ const propertyText = context.sourceCode.getText(property);
74
+ return fixer.replaceText(node, `${objectText}.hasOwnProperty(${propertyText})`);
75
+ };
76
+ }
77
+ else if (preferred === 'Object.hasOwn' && isStandaloneExpression) {
78
+ fix = function (fixer) {
79
+ const objectText = context.sourceCode.getText(object);
80
+ const propertyText = context.sourceCode.getText(property);
81
+ return fixer.replaceText(node, `Object.hasOwn(${objectText}, ${propertyText})`);
82
+ };
83
+ }
84
+ context.report({
85
+ node,
86
+ messageId: 'consistentExistenceCheck',
87
+ data: {
88
+ current: currentMethod,
89
+ preferred,
90
+ },
91
+ fix,
92
+ });
93
+ }
94
+ return {
95
+ // Check for hasOwnProperty calls
96
+ CallExpression(node) {
97
+ // Direct hasOwnProperty calls: obj.hasOwnProperty(prop)
98
+ if (node.callee.type === 'MemberExpression' &&
99
+ node.callee.property.type === 'Identifier' &&
100
+ node.callee.property.name === 'hasOwnProperty' &&
101
+ node.arguments.length === 1 &&
102
+ preferred !== 'hasOwnProperty') {
103
+ reportInconsistentCheck(node, 'hasOwnProperty', node.callee.object, node.arguments[0]);
104
+ }
105
+ // Object.prototype.hasOwnProperty.call(obj, prop)
106
+ if (node.callee.type === 'MemberExpression' &&
107
+ node.callee.object.type === 'MemberExpression' &&
108
+ node.callee.object.object.type === 'MemberExpression' &&
109
+ node.callee.object.object.object.type === 'Identifier' &&
110
+ node.callee.object.object.object.name === 'Object' &&
111
+ node.callee.object.object.property.type === 'Identifier' &&
112
+ node.callee.object.object.property.name === 'prototype' &&
113
+ node.callee.object.property.type === 'Identifier' &&
114
+ node.callee.object.property.name === 'hasOwnProperty' &&
115
+ node.callee.property.type === 'Identifier' &&
116
+ node.callee.property.name === 'call' &&
117
+ node.arguments.length >= 2 &&
118
+ preferred !== 'hasOwnProperty') {
119
+ reportInconsistentCheck(node, 'Object.prototype.hasOwnProperty.call', node.arguments[0], node.arguments[1]);
120
+ }
121
+ // Object.hasOwn(obj, prop)
122
+ if (node.callee.type === 'MemberExpression' &&
123
+ node.callee.object.type === 'Identifier' &&
124
+ node.callee.object.name === 'Object' &&
125
+ node.callee.property.type === 'Identifier' &&
126
+ node.callee.property.name === 'hasOwn' &&
127
+ node.arguments.length === 2 &&
128
+ preferred !== 'Object.hasOwn') {
129
+ reportInconsistentCheck(node, 'Object.hasOwn', node.arguments[0], node.arguments[1]);
130
+ }
131
+ },
132
+ // Check for 'in' operator usage
133
+ BinaryExpression(node) {
134
+ if (node.operator === 'in' && preferred !== 'in') {
135
+ reportInconsistentCheck(node, 'in', node.right, node.left);
136
+ }
137
+ },
138
+ };
139
+ },
140
+ });
141
+ //# sourceMappingURL=consistent-existence-index-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-existence-index-check.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/consistent-existence-index-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
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: expiring-todo-comments
8
+ * Add expiration conditions to TODO comments to prevent forgotten tasks
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ type MessageIds = 'expiringTodoComment' | 'invalidTodoCondition' | 'multipleTodoConditions';
12
+ export interface Options {
13
+ /** Terms to check for (default: ['TODO', 'FIXME', 'XXX']) */
14
+ terms?: string[];
15
+ /** Date format for expiry dates */
16
+ dateFormat?: string;
17
+ /** Allow warnings for expired TODOs */
18
+ allowWarningComments?: boolean;
19
+ }
20
+ type RuleOptions = [Options?];
21
+ export declare const expiringTodoComments: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
22
+ name: string;
23
+ };
24
+ export {};