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
@@ -0,0 +1,278 @@
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.noCommentedCode = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ /**
12
+ * Check if a comment block contains code-like patterns
13
+ */
14
+ function looksLikeCode(comment, isBlockComment) {
15
+ // Remove comment markers for pattern matching
16
+ let text = comment;
17
+ if (isBlockComment) {
18
+ // Remove /* and */ markers and any leading * on each line
19
+ text = text.replace(/^\s*\/\*+/, '').replace(/\*+\/\s*$/, '');
20
+ // Remove leading * from each line in block comments
21
+ text = text
22
+ .split('\n')
23
+ .map((line) => line.replace(/^\s*\*+\s*/, ''))
24
+ .join('\n');
25
+ }
26
+ else {
27
+ // Remove // markers
28
+ text = text
29
+ .split('\n')
30
+ .map((line) => line.replace(/^\s*\/\/+\s*/, ''))
31
+ .join('\n');
32
+ }
33
+ // Split into lines and check each line
34
+ const lines = text
35
+ .split('\n')
36
+ .map((line) => line.trim())
37
+ .filter((line) => line.length > 0);
38
+ if (lines.length === 0) {
39
+ return false;
40
+ }
41
+ const codePatterns = [
42
+ /^(const|let|var|function|class|if|for|while|return|import|export)\s+/,
43
+ /^[a-zA-Z_$][a-zA-Z0-9_$]*\s*[=:]\s*/,
44
+ /^[a-zA-Z_$][a-zA-Z0-9_$]*\s*\(/,
45
+ /^[{}[\]]/,
46
+ ];
47
+ // Count how many lines look like code
48
+ let codeLikeLines = 0;
49
+ // Check if any line looks like code (but not a TODO comment)
50
+ for (const line of lines) {
51
+ // Skip TODO/FIXME comments
52
+ if (/^(TODO|FIXME|HACK|XXX)/i.test(line)) {
53
+ continue;
54
+ }
55
+ // Check if line matches code patterns
56
+ for (const pattern of codePatterns) {
57
+ if (pattern.test(line)) {
58
+ codeLikeLines++;
59
+ break; // Count each line only once
60
+ }
61
+ }
62
+ }
63
+ // Consider it code if at least one line looks like code
64
+ return codeLikeLines > 0;
65
+ }
66
+ /**
67
+ * Count lines in a comment
68
+ * For single-line comments, the value doesn't include newlines, so we count 1
69
+ * For multi-line comments, we count the newlines in the value + 1
70
+ */
71
+ function countCommentLines(comment) {
72
+ if (!comment)
73
+ return 0;
74
+ const newlineCount = (comment.match(/\n/g) || []).length;
75
+ // If there are newlines, it's a multi-line comment (newlineCount + 1 lines)
76
+ // If no newlines, it's a single-line comment (1 line)
77
+ return newlineCount > 0 ? newlineCount + 1 : 1;
78
+ }
79
+ exports.noCommentedCode = (0, eslint_devkit_2.createRule)({
80
+ name: 'no-commented-code',
81
+ meta: {
82
+ type: 'suggestion',
83
+ docs: {
84
+ description: 'Detects commented-out code blocks',
85
+ },
86
+ hasSuggestions: true,
87
+ messages: {
88
+ commentedCode: (0, eslint_devkit_1.formatLLMMessage)({
89
+ icon: eslint_devkit_1.MessageIcons.WARNING,
90
+ issueName: 'Commented code',
91
+ description: 'Commented-out code detected ({{lines}} lines)',
92
+ severity: 'LOW',
93
+ fix: 'Remove commented code or use version control for history',
94
+ documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-125/',
95
+ }),
96
+ removeCode: (0, eslint_devkit_1.formatLLMMessage)({
97
+ icon: eslint_devkit_1.MessageIcons.INFO,
98
+ issueName: 'Remove Code',
99
+ description: 'Remove commented code block',
100
+ severity: 'LOW',
101
+ fix: 'Delete the commented code block',
102
+ documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-125/',
103
+ }),
104
+ useVersionControl: (0, eslint_devkit_1.formatLLMMessage)({
105
+ icon: eslint_devkit_1.MessageIcons.INFO,
106
+ issueName: 'Use Git',
107
+ description: 'Use version control for code history',
108
+ severity: 'LOW',
109
+ fix: 'Delete commented code and use git history instead',
110
+ documentationLink: 'https://git-scm.com/docs/git-log',
111
+ }),
112
+ },
113
+ schema: [
114
+ {
115
+ type: 'object',
116
+ properties: {
117
+ ignoreSingleLine: {
118
+ type: 'boolean',
119
+ default: false,
120
+ description: 'Ignore single-line comments',
121
+ },
122
+ ignoreInTests: {
123
+ type: 'boolean',
124
+ default: true,
125
+ description: 'Ignore comments in test files',
126
+ },
127
+ minLines: {
128
+ type: 'number',
129
+ default: 1,
130
+ minimum: 1,
131
+ description: 'Minimum lines of commented code to trigger',
132
+ },
133
+ },
134
+ additionalProperties: false,
135
+ },
136
+ ],
137
+ },
138
+ defaultOptions: [
139
+ {
140
+ ignoreSingleLine: false,
141
+ ignoreInTests: true,
142
+ minLines: 1,
143
+ },
144
+ ],
145
+ create(context, [options = {}]) {
146
+ const { ignoreSingleLine = false, ignoreInTests = true, minLines = 1, } = options || {};
147
+ const filename = context.getFilename();
148
+ const isTestFile = ignoreInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
149
+ if (isTestFile) {
150
+ return {};
151
+ }
152
+ const sourceCode = context.sourceCode || context.sourceCode;
153
+ /**
154
+ * Check comment nodes
155
+ */
156
+ function checkComment(node) {
157
+ try {
158
+ const commentText = node.value || '';
159
+ const isBlockComment = node.type === 'Block';
160
+ const lines = countCommentLines(commentText);
161
+ // Skip single-line comments if configured
162
+ if (ignoreSingleLine && lines === 1 && !isBlockComment) {
163
+ return;
164
+ }
165
+ // Skip if below minimum lines
166
+ if (lines < minLines) {
167
+ return;
168
+ }
169
+ // Check if it looks like code
170
+ if (looksLikeCode(commentText, isBlockComment)) {
171
+ context.report({
172
+ node,
173
+ messageId: 'commentedCode',
174
+ data: {
175
+ lines: String(lines),
176
+ },
177
+ suggest: [
178
+ {
179
+ messageId: 'removeCode',
180
+ fix: (fixer) => {
181
+ try {
182
+ // Remove the entire comment
183
+ return fixer.remove(node);
184
+ }
185
+ catch {
186
+ return null;
187
+ }
188
+ },
189
+ },
190
+ {
191
+ messageId: 'useVersionControl',
192
+ fix: () => null,
193
+ },
194
+ ],
195
+ });
196
+ }
197
+ }
198
+ catch {
199
+ // Silently skip if there's an error processing the comment
200
+ return;
201
+ }
202
+ }
203
+ return {
204
+ Program() {
205
+ const comments = sourceCode.getAllComments();
206
+ // Group consecutive comments that look like code
207
+ const groupedComments = [];
208
+ let currentGroup = [];
209
+ for (let i = 0; i < comments.length; i++) {
210
+ const comment = comments[i];
211
+ const commentText = comment.value || '';
212
+ const isBlockComment = comment.type === 'Block';
213
+ // Check if this comment looks like code
214
+ if (looksLikeCode(commentText, isBlockComment)) {
215
+ currentGroup.push(comment);
216
+ }
217
+ else {
218
+ // If current group has comments, add it to grouped comments
219
+ if (currentGroup.length > 0) {
220
+ groupedComments.push([...currentGroup]);
221
+ currentGroup = [];
222
+ }
223
+ }
224
+ }
225
+ // Handle any remaining group
226
+ if (currentGroup.length > 0) {
227
+ groupedComments.push(currentGroup);
228
+ }
229
+ // Process each group
230
+ groupedComments.forEach((group) => {
231
+ if (group.length === 1) {
232
+ // Single comment - use the standard checkComment function
233
+ checkComment(group[0]);
234
+ }
235
+ else {
236
+ // Multiple consecutive comments - report as one error
237
+ const firstComment = group[0];
238
+ const totalLines = group.reduce((sum, comment) => {
239
+ const commentText = comment.value || '';
240
+ return sum + countCommentLines(commentText);
241
+ }, 0);
242
+ if (totalLines >= minLines) {
243
+ context.report({
244
+ node: firstComment,
245
+ messageId: 'commentedCode',
246
+ data: {
247
+ lines: String(totalLines),
248
+ },
249
+ suggest: [
250
+ {
251
+ messageId: 'removeCode',
252
+ fix: (fixer) => {
253
+ try {
254
+ // Remove the entire range of consecutive comments
255
+ return fixer.removeRange([
256
+ group[0].range[0],
257
+ group[group.length - 1].range[1],
258
+ ]);
259
+ }
260
+ catch {
261
+ return null;
262
+ }
263
+ },
264
+ },
265
+ {
266
+ messageId: 'useVersionControl',
267
+ fix: () => null,
268
+ },
269
+ ],
270
+ });
271
+ }
272
+ }
273
+ });
274
+ },
275
+ };
276
+ },
277
+ });
278
+ //# sourceMappingURL=no-commented-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-commented-code.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/no-commented-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
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: no-console-spaces
8
+ * Prevent leading/trailing space between console.log parameters
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ export declare const noConsoleSpaces: TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
12
+ name: string;
13
+ };
@@ -0,0 +1,128 @@
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.noConsoleSpaces = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.noConsoleSpaces = (0, eslint_devkit_1.createRule)({
12
+ name: 'no-console-spaces',
13
+ meta: {
14
+ type: 'problem',
15
+ docs: {
16
+ description: 'Prevent leading/trailing space between console.log parameters',
17
+ },
18
+ fixable: 'code',
19
+ hasSuggestions: true,
20
+ messages: {
21
+ noConsoleSpaces: (0, eslint_devkit_2.formatLLMMessage)({
22
+ icon: eslint_devkit_2.MessageIcons.WARNING,
23
+ issueName: 'Console Spaces',
24
+ description: 'Remove leading/trailing spaces in console method parameters',
25
+ severity: 'MEDIUM',
26
+ fix: 'Remove spaces from console method arguments',
27
+ documentationLink: 'https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-console-spaces.md',
28
+ }),
29
+ },
30
+ schema: [],
31
+ },
32
+ defaultOptions: [],
33
+ create(context) {
34
+ // Console methods that join parameters with spaces
35
+ const consoleMethods = new Set([
36
+ 'log',
37
+ 'debug',
38
+ 'info',
39
+ 'warn',
40
+ 'error',
41
+ 'table',
42
+ 'trace',
43
+ 'group',
44
+ 'groupCollapsed',
45
+ ]);
46
+ function isInAllowedContext() {
47
+ // For simplicity, we'll skip the allow option for now
48
+ return false;
49
+ }
50
+ function isConsoleMethodCall(node) {
51
+ // Check if this is a call to a console method
52
+ if (node.callee.type === 'MemberExpression' &&
53
+ node.callee.object.type === 'Identifier' &&
54
+ node.callee.object.name === 'console' &&
55
+ node.callee.property.type === 'Identifier' &&
56
+ consoleMethods.has(node.callee.property.name)) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ function getConsoleMethodName(node) {
62
+ // Safe extraction of console method name
63
+ if (node.callee.type === 'MemberExpression' &&
64
+ node.callee.property.type === 'Identifier') {
65
+ return node.callee.property.name;
66
+ }
67
+ return 'console';
68
+ }
69
+ function hasLeadingOrTrailingSpaces(text) {
70
+ // Check if string starts or ends with whitespace, but not if it's only whitespace
71
+ // Only flag if there's actual content with leading/trailing spaces
72
+ const trimmed = text.trim();
73
+ return trimmed.length > 0 && /^\s|\s$/.test(text);
74
+ }
75
+ function hasLeadingOrTrailingSpacesInTemplate(text) {
76
+ // For template literals, even whitespace-only quasis should be flagged
77
+ return /^\s|\s$/.test(text);
78
+ }
79
+ return {
80
+ CallExpression(node) {
81
+ if (isConsoleMethodCall(node) && !isInAllowedContext()) {
82
+ // Check each argument for leading/trailing spaces
83
+ for (const arg of node.arguments) {
84
+ if (arg.type === 'Literal' && typeof arg.value === 'string') {
85
+ if (hasLeadingOrTrailingSpaces(arg.value)) {
86
+ context.report({
87
+ node: arg,
88
+ messageId: 'noConsoleSpaces',
89
+ data: {
90
+ method: getConsoleMethodName(node),
91
+ arg: arg.value,
92
+ },
93
+ fix(fixer) {
94
+ const trimmed = arg.value.trim();
95
+ return fixer.replaceText(arg, `'${trimmed}'`);
96
+ },
97
+ });
98
+ }
99
+ }
100
+ else if (arg.type === 'TemplateLiteral') {
101
+ // Check template literal quasi values for leading/trailing spaces
102
+ let hasSpacesInTemplate = false;
103
+ for (const quasi of arg.quasis) {
104
+ if (hasLeadingOrTrailingSpacesInTemplate(quasi.value.raw)) {
105
+ hasSpacesInTemplate = true;
106
+ break;
107
+ }
108
+ }
109
+ if (hasSpacesInTemplate) {
110
+ context.report({
111
+ node: arg,
112
+ messageId: 'noConsoleSpaces',
113
+ data: {
114
+ method: getConsoleMethodName(node),
115
+ arg: 'template literal with spaces',
116
+ },
117
+ // Template literals are harder to fix automatically
118
+ fix: null,
119
+ });
120
+ }
121
+ }
122
+ }
123
+ }
124
+ },
125
+ };
126
+ },
127
+ });
128
+ //# sourceMappingURL=no-console-spaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-console-spaces.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/no-console-spaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
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: prefer-code-point
8
+ * Prefer codePointAt over charCodeAt for proper Unicode handling
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ export declare const preferCodePoint: TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
12
+ name: string;
13
+ };
@@ -0,0 +1,95 @@
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.preferCodePoint = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.preferCodePoint = (0, eslint_devkit_1.createRule)({
12
+ name: 'prefer-code-point',
13
+ meta: {
14
+ type: 'suggestion',
15
+ docs: {
16
+ description: 'Prefer codePointAt over charCodeAt for proper Unicode character handling',
17
+ },
18
+ messages: {
19
+ preferCodePoint: (0, eslint_devkit_2.formatLLMMessage)({
20
+ icon: eslint_devkit_2.MessageIcons.WARNING,
21
+ issueName: 'Prefer codePointAt',
22
+ description: 'Use codePointAt instead of charCodeAt for Unicode safety',
23
+ severity: 'MEDIUM',
24
+ fix: 'Replace charCodeAt() with codePointAt()',
25
+ documentationLink: 'https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-code-point.md',
26
+ }),
27
+ },
28
+ schema: [
29
+ {
30
+ type: 'object',
31
+ properties: {},
32
+ additionalProperties: false,
33
+ },
34
+ ],
35
+ },
36
+ defaultOptions: [],
37
+ create(context) {
38
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
39
+ function isInAllowedContext(node) {
40
+ // For simplicity, we'll skip the allow option for now
41
+ // This would require more complex logic to check comments/code context
42
+ return false;
43
+ }
44
+ function shouldIgnoreCall(node) {
45
+ // The unicorn rule flags ALL charCodeAt calls, but allows some contexts
46
+ if (node.callee.type === 'MemberExpression') {
47
+ // Allow optional chaining
48
+ if (node.callee.optional) {
49
+ return true;
50
+ }
51
+ // Allow computed property access where the property is a variable (not literal)
52
+ // This means obj[method] is ignored, but obj['charCodeAt'] is still flagged
53
+ if (node.callee.computed &&
54
+ node.callee.property.type === 'Identifier') {
55
+ return true;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ function isCharCodeAtCall(node) {
61
+ // Check if this is a call to charCodeAt method
62
+ if (node.callee.type === 'MemberExpression') {
63
+ // Direct property access: obj.charCodeAt
64
+ if (node.callee.property.type === 'Identifier' &&
65
+ node.callee.property.name === 'charCodeAt') {
66
+ return true;
67
+ }
68
+ // Computed property access: obj['charCodeAt']
69
+ if (node.callee.computed &&
70
+ node.callee.property.type === 'Literal' &&
71
+ node.callee.property.value === 'charCodeAt') {
72
+ return true;
73
+ }
74
+ }
75
+ return false;
76
+ }
77
+ return {
78
+ CallExpression(node) {
79
+ if (isCharCodeAtCall(node) &&
80
+ !isInAllowedContext(node) &&
81
+ !shouldIgnoreCall(node)) {
82
+ context.report({
83
+ node,
84
+ messageId: 'preferCodePoint',
85
+ data: {
86
+ current: 'charCodeAt()',
87
+ fix: 'codePointAt()',
88
+ },
89
+ });
90
+ }
91
+ },
92
+ };
93
+ },
94
+ });
95
+ //# sourceMappingURL=prefer-code-point.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-code-point.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-code-point.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAOH,4DAAsD;AACtD,4DAA0E;AAM7D,QAAA,eAAe,GAAG,IAAA,0BAAU,EAA0B;IACjE,IAAI,EAAE,mBAAmB;IACzB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,0EAA0E;SAC7E;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,IAAA,gCAAgB,EAAC;gBAChC,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,oBAAoB;gBAC/B,WAAW,EAAE,0DAA0D;gBACvE,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,yCAAyC;gBAC9C,iBAAiB,EACf,iGAAiG;aACpG,CAAC;SACH;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE,EAAE;IAElB,MAAM,CAAC,OAAsD;QAC3D,6DAA6D;QAC7D,SAAS,kBAAkB,CAAC,IAA6B;YACvD,sDAAsD;YACtD,uEAAuE;YACvE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,gBAAgB,CAAC,IAA6B;YACrD,wEAAwE;YAExE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,0BAA0B;gBAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,gFAAgF;gBAChF,4EAA4E;gBAC5E,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,gBAAgB,CAAC,IAA6B;YACrD,+CAA+C;YAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,yCAAyC;gBACzC,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;oBAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAC1C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,8CAA8C;gBAC9C,IACE,IAAI,CAAC,MAAM,CAAC,QAAQ;oBACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;oBACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,YAAY,EAC3C,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO;YACL,cAAc,CAAC,IAA6B;gBAC1C,IACE,gBAAgB,CAAC,IAAI,CAAC;oBACtB,CAAC,kBAAkB,CAAC,IAAI,CAAC;oBACzB,CAAC,gBAAgB,CAAC,IAAI,CAAC,EACvB,CAAC;oBACD,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI;wBACJ,SAAS,EAAE,iBAAiB;wBAC5B,IAAI,EAAE;4BACJ,OAAO,EAAE,cAAc;4BACvB,GAAG,EAAE,eAAe;yBACrB;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,29 @@
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
+ * prefer-dependency-version-strategy
8
+ *
9
+ * Enforces a consistent version strategy (caret, tilde, exact, etc.) for package.json dependencies.
10
+ * Works alongside @nx/dependency-checks to ensure both version alignment and strategy consistency.
11
+ *
12
+ * This rule is designed to complement @nx/dependency-checks, which validates that dependencies
13
+ * match the lockfile. This rule ensures the version specifier format is consistent.
14
+ */
15
+ import type { TSESLint } from '@interlace/eslint-devkit';
16
+ type VersionStrategy = 'caret' | 'tilde' | 'exact' | 'range' | 'any';
17
+ export interface Options {
18
+ strategy?: VersionStrategy;
19
+ allowWorkspace?: boolean;
20
+ allowFile?: boolean;
21
+ allowLink?: boolean;
22
+ overrides?: Record<string, VersionStrategy>;
23
+ }
24
+ type RuleOptions = [Options?];
25
+ type MessageIds = 'preferStrategy' | 'invalidStrategy';
26
+ export declare const preferDependencyVersionStrategy: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
27
+ name: string;
28
+ };
29
+ export {};