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,226 @@
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.preferDependencyVersionStrategy = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.preferDependencyVersionStrategy = (0, eslint_devkit_2.createRule)({
12
+ name: 'prefer-dependency-version-strategy',
13
+ meta: {
14
+ type: 'suggestion',
15
+ docs: {
16
+ description: 'Enforce consistent version strategy (caret, tilde, exact, etc.) for package.json dependencies',
17
+ },
18
+ fixable: 'code',
19
+ messages: {
20
+ preferStrategy: (0, eslint_devkit_1.formatLLMMessage)({
21
+ icon: eslint_devkit_1.MessageIcons.PACKAGE,
22
+ issueName: 'Dependency Version Strategy',
23
+ description: 'Dependency "{{name}}" should use {{strategy}} version',
24
+ severity: 'MEDIUM',
25
+ fix: 'Change "{{current}}" to "{{expected}}" for version flexibility',
26
+ documentationLink: 'https://docs.npmjs.com/cli/v10/configuring-npm/package-json#dependencies',
27
+ }),
28
+ invalidStrategy: (0, eslint_devkit_1.formatLLMMessage)({
29
+ icon: eslint_devkit_1.MessageIcons.WARNING,
30
+ issueName: 'Invalid Version Strategy',
31
+ description: 'Strategy "{{strategy}}" is not valid',
32
+ severity: 'MEDIUM',
33
+ fix: 'Use one of: caret (^), tilde (~), exact (no prefix), range (<, >, ||), or any',
34
+ documentationLink: 'https://docs.npmjs.com/cli/v10/configuring-npm/package-json#dependencies',
35
+ }),
36
+ },
37
+ schema: [
38
+ {
39
+ type: 'object',
40
+ properties: {
41
+ strategy: {
42
+ type: 'string',
43
+ enum: ['caret', 'tilde', 'exact', 'range', 'any'],
44
+ description: 'Version strategy to enforce: caret (^), tilde (~), exact (no prefix), range (allows <, >, ||), or any (allows all)',
45
+ },
46
+ allowWorkspace: {
47
+ type: 'boolean',
48
+ description: 'Allow workspace: protocol versions',
49
+ default: true,
50
+ },
51
+ allowFile: {
52
+ type: 'boolean',
53
+ description: 'Allow file: protocol versions',
54
+ default: true,
55
+ },
56
+ allowLink: {
57
+ type: 'boolean',
58
+ description: 'Allow link: protocol versions',
59
+ default: true,
60
+ },
61
+ overrides: {
62
+ type: 'object',
63
+ additionalProperties: {
64
+ type: 'string',
65
+ enum: ['caret', 'tilde', 'exact', 'range', 'any'],
66
+ },
67
+ description: 'Package-specific strategy overrides. Key is package name, value is strategy. Example: { "react": "exact", "lodash": "tilde" }',
68
+ },
69
+ },
70
+ additionalProperties: false,
71
+ },
72
+ ],
73
+ },
74
+ defaultOptions: [
75
+ {
76
+ strategy: 'caret',
77
+ allowWorkspace: true,
78
+ allowFile: true,
79
+ allowLink: true,
80
+ overrides: {},
81
+ },
82
+ ],
83
+ create(context) {
84
+ const options = context.options[0] || {};
85
+ const { strategy = 'caret', allowWorkspace = true, allowFile = true, allowLink = true, overrides = {}, } = options;
86
+ // Validate strategy
87
+ const validStrategies = [
88
+ 'caret',
89
+ 'tilde',
90
+ 'exact',
91
+ 'range',
92
+ 'any',
93
+ ];
94
+ if (!validStrategies.includes(strategy)) {
95
+ context.report({
96
+ loc: { line: 1, column: 0 },
97
+ messageId: 'invalidStrategy',
98
+ data: { strategy },
99
+ });
100
+ return {};
101
+ }
102
+ // If strategy is 'any', allow all versions
103
+ if (strategy === 'any') {
104
+ return {};
105
+ }
106
+ function checkVersion(node, depName, version) {
107
+ // Skip special protocols
108
+ if (allowWorkspace && version.startsWith('workspace:'))
109
+ return;
110
+ if (allowFile && version.startsWith('file:'))
111
+ return;
112
+ if (allowLink && version.startsWith('link:'))
113
+ return;
114
+ // Skip if not a semantic version (allow prefixes like ^, ~)
115
+ // Match patterns like: 1.0.0, ^1.0.0, ~1.0.0, >=1.0.0, etc.
116
+ if (!version.match(/^[\^~<>=]?\d+\.\d+\.\d+/))
117
+ return;
118
+ // Check for package-specific override
119
+ const packageStrategy = overrides[depName] || strategy;
120
+ // If override is 'any', skip this package
121
+ if (packageStrategy === 'any')
122
+ return;
123
+ let expectedVersion = version;
124
+ let needsFix = false;
125
+ // Determine expected format based on strategy (package override or default)
126
+ // First, extract the base version (remove any existing prefix)
127
+ const baseVersion = version.replace(/^[\^~<>=]+/, '');
128
+ switch (packageStrategy) {
129
+ case 'caret':
130
+ if (!version.startsWith('^')) {
131
+ expectedVersion = `^${baseVersion}`;
132
+ needsFix = true;
133
+ }
134
+ break;
135
+ case 'tilde':
136
+ if (!version.startsWith('~')) {
137
+ expectedVersion = `~${baseVersion}`;
138
+ needsFix = true;
139
+ }
140
+ break;
141
+ case 'exact': {
142
+ // Remove any prefix to get exact version
143
+ if (version !== baseVersion) {
144
+ expectedVersion = baseVersion;
145
+ needsFix = true;
146
+ }
147
+ break;
148
+ }
149
+ case 'range':
150
+ // Allow ranges like ">=1.0.0 <2.0.0" or "1.0.0 || 2.0.0"
151
+ if (!version.includes('||') &&
152
+ !version.includes('>=') &&
153
+ !version.includes('<=') &&
154
+ !version.includes('>') &&
155
+ !version.includes('<') &&
156
+ !version.includes(' - ')) {
157
+ // If it's just a version, suggest caret as default for ranges
158
+ // Use baseVersion to avoid double-prefixing (e.g., ^^18.0.0)
159
+ expectedVersion = `^${baseVersion}`;
160
+ needsFix = true;
161
+ }
162
+ break;
163
+ }
164
+ if (needsFix) {
165
+ context.report({
166
+ node: node.value,
167
+ messageId: 'preferStrategy',
168
+ data: {
169
+ name: depName,
170
+ strategy: packageStrategy,
171
+ current: version,
172
+ expected: expectedVersion,
173
+ },
174
+ fix(fixer) {
175
+ return fixer.replaceText(node.value, JSON.stringify(expectedVersion));
176
+ },
177
+ });
178
+ }
179
+ }
180
+ /**
181
+ * Check an object expression for dependency version violations
182
+ */
183
+ const checkObjectExpression = (node) => {
184
+ for (const prop of node.properties) {
185
+ if (prop.type === 'Property' &&
186
+ prop.key &&
187
+ prop.value &&
188
+ prop.value.type === 'Literal') {
189
+ const depName = prop.key.type === 'Identifier'
190
+ ? prop.key.name
191
+ : prop.key.type === 'Literal'
192
+ ? String(prop.key.value)
193
+ : null;
194
+ if (depName && typeof prop.value.value === 'string') {
195
+ checkVersion(prop, depName, prop.value.value);
196
+ }
197
+ }
198
+ }
199
+ };
200
+ return {
201
+ // Check package.json dependencies properties
202
+ 'Property[key.value="dependencies"], Property[key.value="devDependencies"], Property[key.value="peerDependencies"]'(node) {
203
+ if (node.value.type !== 'ObjectExpression')
204
+ return;
205
+ checkObjectExpression(node.value);
206
+ },
207
+ // Also check object literals (for testing and general use)
208
+ ObjectExpression(node) {
209
+ // Only check if it looks like a dependencies object (has string keys and version-like values)
210
+ const hasVersionLikeValues = node.properties.some((prop) => {
211
+ if (prop.type === 'Property' && prop.value.type === 'Literal') {
212
+ const value = String(prop.value.value);
213
+ // Check if value looks like a version (starts with ^, ~, or is a semantic version)
214
+ return (/^[\^~]?\d+\.\d+\.\d+/.test(value) ||
215
+ value.startsWith('workspace:'));
216
+ }
217
+ return false;
218
+ });
219
+ if (hasVersionLikeValues) {
220
+ checkObjectExpression(node);
221
+ }
222
+ },
223
+ };
224
+ },
225
+ });
226
+ //# sourceMappingURL=prefer-dependency-version-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-dependency-version-strategy.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-dependency-version-strategy.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAaH,4DAA0E;AAC1E,4DAAsD;AAezC,QAAA,+BAA+B,GAAG,IAAA,0BAAU,EAGvD;IACA,IAAI,EAAE,oCAAoC;IAC1C,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+FAA+F;SAClG;QACD,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE;YACR,cAAc,EAAE,IAAA,gCAAgB,EAAC;gBAC/B,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,6BAA6B;gBACxC,WAAW,EAAE,uDAAuD;gBACpE,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,gEAAgE;gBACrE,iBAAiB,EACf,0EAA0E;aAC7E,CAAC;YACF,eAAe,EAAE,IAAA,gCAAgB,EAAC;gBAChC,IAAI,EAAE,4BAAY,CAAC,OAAO;gBAC1B,SAAS,EAAE,0BAA0B;gBACrC,WAAW,EAAE,sCAAsC;gBACnD,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,+EAA+E;gBACpF,iBAAiB,EACf,0EAA0E;aAC7E,CAAC;SACH;QACD,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,QAAQ,EAAE;wBACR,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC;wBACjD,WAAW,EACT,oHAAoH;qBACvH;oBACD,cAAc,EAAE;wBACd,IAAI,EAAE,SAAS;wBACf,WAAW,EAAE,oCAAoC;wBACjD,OAAO,EAAE,IAAI;qBACd;oBACD,SAAS,EAAE;wBACT,IAAI,EAAE,SAAS;wBACf,WAAW,EAAE,+BAA+B;wBAC5C,OAAO,EAAE,IAAI;qBACd;oBACD,SAAS,EAAE;wBACT,IAAI,EAAE,SAAS;wBACf,WAAW,EAAE,+BAA+B;wBAC5C,OAAO,EAAE,IAAI;qBACd;oBACD,SAAS,EAAE;wBACT,IAAI,EAAE,QAAQ;wBACd,oBAAoB,EAAE;4BACpB,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC;yBAClD;wBACD,WAAW,EACT,+HAA+H;qBAClI;iBACF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;KACF;IACD,cAAc,EAAE;QACd;YACE,QAAQ,EAAE,OAA0B;YACpC,cAAc,EAAE,IAAI;YACpB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,EAAE;SACd;KACF;IACD,MAAM,CAAC,OAAsD;QAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,EACJ,QAAQ,GAAG,OAAO,EAClB,cAAc,GAAG,IAAI,EACrB,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,EAAE,GACf,GAAG,OAAO,CAAC;QAEZ,oBAAoB;QACpB,MAAM,eAAe,GAAsB;YACzC,OAAO;YACP,OAAO;YACP,OAAO;YACP,OAAO;YACP,KAAK;SACN,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC;gBACb,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;gBAC3B,SAAS,EAAE,iBAAiB;gBAC5B,IAAI,EAAE,EAAE,QAAQ,EAAE;aACnB,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,2CAA2C;QAC3C,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACvB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,SAAS,YAAY,CACnB,IAAuB,EACvB,OAAe,EACf,OAAe;YAEf,yBAAyB;YACzB,IAAI,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,OAAO;YAC/D,IAAI,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO;YACrD,IAAI,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO;YAErD,4DAA4D;YAC5D,4DAA4D;YAC5D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC;gBAAE,OAAO;YAEtD,sCAAsC;YACtC,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;YAEvD,0CAA0C;YAC1C,IAAI,eAAe,KAAK,KAAK;gBAAE,OAAO;YAEtC,IAAI,eAAe,GAAG,OAAO,CAAC;YAC9B,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,4EAA4E;YAC5E,+DAA+D;YAC/D,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAEtD,QAAQ,eAAe,EAAE,CAAC;gBACxB,KAAK,OAAO;oBACV,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;wBACpC,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;wBACpC,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,yCAAyC;oBACzC,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;wBAC5B,eAAe,GAAG,WAAW,CAAC;wBAC9B,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;oBACD,MAAM;gBACR,CAAC;gBACD,KAAK,OAAO;oBACV,yDAAyD;oBACzD,IACE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACvB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACvB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACvB,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;wBACtB,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;wBACtB,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EACxB,CAAC;wBACD,8DAA8D;wBAC9D,6DAA6D;wBAC7D,eAAe,GAAG,IAAI,WAAW,EAAE,CAAC;wBACpC,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;oBACD,MAAM;YACV,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,IAAI,CAAC,KAAK;oBAChB,SAAS,EAAE,gBAAgB;oBAC3B,IAAI,EAAE;wBACJ,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,eAAe;wBACzB,OAAO,EAAE,OAAO;wBAChB,QAAQ,EAAE,eAAe;qBAC1B;oBACD,GAAG,CAAC,KAAyB;wBAC3B,OAAO,KAAK,CAAC,WAAW,CACtB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAChC,CAAC;oBACJ,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED;;WAEG;QACH,MAAM,qBAAqB,GAAG,CAAC,IAA+B,EAAE,EAAE;YAChE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnC,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;oBACxB,IAAI,CAAC,GAAG;oBACR,IAAI,CAAC,KAAK;oBACV,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAC7B,CAAC;oBACD,MAAM,OAAO,GACX,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY;wBAC5B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;wBACf,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS;4BAC3B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;4BACxB,CAAC,CAAC,IAAI,CAAC;oBAEb,IAAI,OAAO,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;wBACpD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,OAAO;YACL,6CAA6C;YAC7C,mHAAmH,CACjH,IAAuB;gBAEvB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,kBAAkB;oBAAE,OAAO;gBACnD,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YAED,2DAA2D;YAC3D,gBAAgB,CAAC,IAA+B;gBAC9C,8FAA8F;gBAC9F,MAAM,oBAAoB,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAC/C,CAAC,IAAgD,EAAE,EAAE;oBACnD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;wBAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;wBACvC,mFAAmF;wBACnF,OAAO,CACL,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC;4BAClC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAC/B,CAAC;oBACJ,CAAC;oBACD,OAAO,KAAK,CAAC;gBACf,CAAC,CACF,CAAC;gBAEF,IAAI,oBAAoB,EAAE,CAAC;oBACzB,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -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-dom-node-text-content
8
+ * Prefer textContent over innerText for DOM node text access
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ export declare const preferDomNodeTextContent: TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
12
+ name: string;
13
+ };
@@ -0,0 +1,147 @@
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.preferDomNodeTextContent = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.preferDomNodeTextContent = (0, eslint_devkit_1.createRule)({
12
+ name: 'prefer-dom-node-text-content',
13
+ meta: {
14
+ type: 'suggestion',
15
+ docs: {
16
+ description: 'Prefer textContent over innerText for better performance and reliability',
17
+ },
18
+ hasSuggestions: true,
19
+ messages: {
20
+ preferDomNodeTextContent: (0, eslint_devkit_2.formatLLMMessage)({
21
+ icon: eslint_devkit_2.MessageIcons.PERFORMANCE,
22
+ issueName: 'DOM Text Access',
23
+ description: 'Use textContent instead of innerText',
24
+ severity: 'MEDIUM',
25
+ fix: 'Replace innerText with textContent',
26
+ documentationLink: 'https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-text-content.md',
27
+ }),
28
+ },
29
+ schema: [
30
+ {
31
+ type: 'object',
32
+ properties: {},
33
+ additionalProperties: false,
34
+ },
35
+ ],
36
+ },
37
+ defaultOptions: [],
38
+ create(context) {
39
+ function isInAllowedContext() {
40
+ // For simplicity, we'll skip the allow option for now
41
+ return false;
42
+ }
43
+ function isLikelyDomElement(node) {
44
+ const obj = node.object;
45
+ // Check if it's a variable/identifier that might be a DOM element
46
+ if (obj.type === 'Identifier') {
47
+ const name = obj.name;
48
+ // Common DOM element variable names
49
+ if (name.match(/^(element|el|div|span|node|ref|dom|elem)$/i)) {
50
+ return true;
51
+ }
52
+ // Variables that end with common DOM suffixes
53
+ if (name.match(/(Element|Node|Ref)$/)) {
54
+ return true;
55
+ }
56
+ }
57
+ // Check for DOM method calls like document.querySelector, getElementById, etc.
58
+ if (obj.type === 'CallExpression' &&
59
+ obj.callee.type === 'MemberExpression') {
60
+ const methodName = obj.callee.property?.name;
61
+ if (methodName &&
62
+ [
63
+ 'querySelector',
64
+ 'querySelectorAll',
65
+ 'getElementById',
66
+ 'getElementsByClassName',
67
+ 'getElementsByTagName',
68
+ 'createElement',
69
+ ].includes(methodName)) {
70
+ return true;
71
+ }
72
+ }
73
+ // Check for property access on known DOM objects
74
+ if (obj.type === 'MemberExpression') {
75
+ const propName = obj.property?.name;
76
+ if (propName &&
77
+ [
78
+ 'current',
79
+ 'children',
80
+ 'childNodes',
81
+ 'parentNode',
82
+ 'element',
83
+ ].includes(propName)) {
84
+ return true;
85
+ }
86
+ }
87
+ // Check for 'this.element' pattern
88
+ if (obj.type === 'MemberExpression' &&
89
+ obj.object.type === 'ThisExpression' &&
90
+ obj.property.type === 'Identifier' &&
91
+ obj.property.name === 'element') {
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ function isInnerTextAccess(node) {
97
+ // Check if this is accessing .innerText property
98
+ if (node.property.type === 'Identifier' &&
99
+ node.property.name === 'innerText') {
100
+ return true;
101
+ }
102
+ // Also check computed property access like element["innerText"]
103
+ if (node.computed &&
104
+ node.property.type === 'Literal' &&
105
+ node.property.value === 'innerText') {
106
+ return true;
107
+ }
108
+ return false;
109
+ }
110
+ return {
111
+ MemberExpression(node) {
112
+ if (isInnerTextAccess(node) &&
113
+ isLikelyDomElement(node) &&
114
+ !isInAllowedContext()) {
115
+ context.report({
116
+ node,
117
+ messageId: 'preferDomNodeTextContent',
118
+ data: {
119
+ current: 'innerText',
120
+ fix: 'textContent',
121
+ },
122
+ suggest: [
123
+ {
124
+ messageId: 'preferDomNodeTextContent',
125
+ data: {
126
+ replacement: 'textContent',
127
+ suggestion: 'Replace with textContent',
128
+ },
129
+ fix(fixer) {
130
+ if (node.property.type === 'Identifier') {
131
+ return fixer.replaceText(node.property, 'textContent');
132
+ }
133
+ else if (node.property.type === 'Literal' &&
134
+ node.property.value === 'innerText') {
135
+ return fixer.replaceText(node.property, '"textContent"');
136
+ }
137
+ return null;
138
+ },
139
+ },
140
+ ],
141
+ });
142
+ }
143
+ },
144
+ };
145
+ },
146
+ });
147
+ //# sourceMappingURL=prefer-dom-node-text-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefer-dom-node-text-content.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/prefer-dom-node-text-content.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
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-deprecated-api
8
+ * Detects deprecated API usage with replacement context and migration timeline
9
+ */
10
+ import type { TSESLint } from '@interlace/eslint-devkit';
11
+ type MessageIds = 'deprecatedAPI' | 'useReplacement';
12
+ interface DeprecatedAPI {
13
+ name: string;
14
+ replacement: string;
15
+ deprecatedSince: string;
16
+ removalDate?: string;
17
+ reason: string;
18
+ migrationGuide?: string;
19
+ }
20
+ export interface Options {
21
+ /** Array of deprecated APIs to detect */
22
+ apis?: DeprecatedAPI[];
23
+ /** Days before removal date to start warning */
24
+ warnDaysBeforeRemoval?: number;
25
+ }
26
+ type RuleOptions = [Options?];
27
+ export declare const noDeprecatedApi: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
28
+ name: string;
29
+ };
30
+ export {};
@@ -0,0 +1,174 @@
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.noDeprecatedApi = void 0;
9
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
+ exports.noDeprecatedApi = (0, eslint_devkit_2.createRule)({
12
+ name: 'no-deprecated-api',
13
+ meta: {
14
+ type: 'problem',
15
+ docs: {
16
+ description: 'Prevent usage of deprecated APIs with migration context',
17
+ },
18
+ fixable: 'code',
19
+ hasSuggestions: true,
20
+ messages: {
21
+ // 🎯 Token optimization: 44% reduction (48→27 tokens) - removes verbose labels
22
+ deprecatedAPI: (0, eslint_devkit_1.formatLLMMessage)({
23
+ icon: eslint_devkit_1.MessageIcons.DEPRECATION,
24
+ issueName: 'Deprecated API',
25
+ cwe: 'CWE-1078',
26
+ description: 'Deprecated API detected',
27
+ severity: 'HIGH',
28
+ fix: 'Migrate to recommended alternative with timeline guidance',
29
+ documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference',
30
+ }),
31
+ useReplacement: (0, eslint_devkit_1.formatLLMMessage)({
32
+ icon: eslint_devkit_1.MessageIcons.INFO,
33
+ issueName: 'Use Replacement',
34
+ description: 'Replace with recommended API',
35
+ severity: 'LOW',
36
+ fix: 'Replace with {{replacement}}',
37
+ documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference',
38
+ }),
39
+ },
40
+ schema: [
41
+ {
42
+ type: 'object',
43
+ properties: {
44
+ apis: {
45
+ type: 'array',
46
+ items: {
47
+ type: 'object',
48
+ properties: {
49
+ name: { type: 'string' },
50
+ replacement: { type: 'string' },
51
+ deprecatedSince: { type: 'string' },
52
+ removalDate: { type: 'string' },
53
+ reason: { type: 'string' },
54
+ migrationGuide: { type: 'string' },
55
+ },
56
+ required: ['name', 'replacement', 'deprecatedSince', 'reason'],
57
+ },
58
+ },
59
+ warnDaysBeforeRemoval: {
60
+ type: 'number',
61
+ default: 90,
62
+ },
63
+ },
64
+ additionalProperties: false,
65
+ },
66
+ ],
67
+ },
68
+ defaultOptions: [
69
+ {
70
+ apis: [],
71
+ warnDaysBeforeRemoval: 90,
72
+ },
73
+ ],
74
+ create(context) {
75
+ const options = context.options[0] || {};
76
+ const { apis = [], warnDaysBeforeRemoval = 90 } = options || {};
77
+ // Early return if no deprecated APIs configured
78
+ if (!apis || apis.length === 0) {
79
+ return {};
80
+ }
81
+ /**
82
+ * Calculate days until removal
83
+ */
84
+ const calculateDaysRemaining = (removalDate) => {
85
+ if (!removalDate)
86
+ return null;
87
+ const removal = new Date(removalDate);
88
+ const now = new Date();
89
+ const diff = removal.getTime() - now.getTime();
90
+ return Math.ceil(diff / (1000 * 60 * 60 * 24));
91
+ };
92
+ /**
93
+ * Determine urgency level
94
+ */
95
+ const getUrgencyLevel = (daysRemaining) => {
96
+ if (daysRemaining === null)
97
+ return 'low';
98
+ if (daysRemaining < 0)
99
+ return 'critical'; // Already past removal date!
100
+ if (daysRemaining < 30)
101
+ return 'critical';
102
+ if (daysRemaining < warnDaysBeforeRemoval)
103
+ return 'high';
104
+ return 'medium';
105
+ };
106
+ return {
107
+ // Check member expressions (e.g., obj.deprecatedMethod())
108
+ MemberExpression(node) {
109
+ if (node.property.type !== 'Identifier')
110
+ return;
111
+ const apiName = node.property.name;
112
+ const deprecatedApi = apis.find((api) => api.name === apiName);
113
+ if (!deprecatedApi)
114
+ return;
115
+ const daysRemaining = calculateDaysRemaining(deprecatedApi.removalDate);
116
+ const urgency = getUrgencyLevel(daysRemaining);
117
+ context.report({
118
+ node,
119
+ messageId: 'deprecatedAPI',
120
+ data: {
121
+ apiName: deprecatedApi.name,
122
+ replacement: deprecatedApi.replacement,
123
+ deprecatedSince: deprecatedApi.deprecatedSince,
124
+ daysRemaining: String(daysRemaining ?? 'Unknown'),
125
+ urgency: urgency.toUpperCase(),
126
+ migrationGuide: deprecatedApi.migrationGuide || 'See documentation',
127
+ },
128
+ suggest: [
129
+ {
130
+ messageId: 'useReplacement',
131
+ data: { replacement: deprecatedApi.replacement },
132
+ fix: (fixer) => {
133
+ return fixer.replaceText(node.property, deprecatedApi.replacement);
134
+ },
135
+ },
136
+ ],
137
+ });
138
+ },
139
+ // Check call expressions (e.g., deprecatedFunction())
140
+ CallExpression(node) {
141
+ if (node.callee.type !== 'Identifier')
142
+ return;
143
+ const apiName = node.callee.name;
144
+ const deprecatedApi = apis.find((api) => api.name === apiName);
145
+ if (!deprecatedApi)
146
+ return;
147
+ const daysRemaining = calculateDaysRemaining(deprecatedApi.removalDate);
148
+ const urgency = getUrgencyLevel(daysRemaining);
149
+ context.report({
150
+ node,
151
+ messageId: 'deprecatedAPI',
152
+ data: {
153
+ apiName: deprecatedApi.name,
154
+ replacement: deprecatedApi.replacement,
155
+ deprecatedSince: deprecatedApi.deprecatedSince,
156
+ daysRemaining: String(daysRemaining ?? 'Unknown'),
157
+ urgency: urgency.toUpperCase(),
158
+ migrationGuide: deprecatedApi.migrationGuide || 'See documentation',
159
+ },
160
+ suggest: [
161
+ {
162
+ messageId: 'useReplacement',
163
+ data: { replacement: deprecatedApi.replacement },
164
+ fix: (fixer) => {
165
+ return fixer.replaceText(node.callee, deprecatedApi.replacement);
166
+ },
167
+ },
168
+ ],
169
+ });
170
+ },
171
+ };
172
+ },
173
+ });
174
+ //# sourceMappingURL=no-deprecated-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated-api.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/deprecation/no-deprecated-api.ts"],"names":[],"mappings":"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"}