@pobammer-ts/eslint-cease-nonsense-rules 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/enforce-ianitor-check-type.d.ts +3 -0
- package/dist/rules/enforce-ianitor-check-type.js +331 -0
- package/dist/rules/enforce-ianitor-check-type.js.map +1 -0
- package/dist/rules/no-color3-constructor.d.ts +20 -0
- package/dist/rules/no-color3-constructor.js +69 -0
- package/dist/rules/no-color3-constructor.js.map +1 -0
- package/dist/rules/no-print.d.ts +18 -0
- package/dist/rules/no-print.js +48 -0
- package/dist/rules/no-print.js.map +1 -0
- package/dist/rules/no-shorthand-names.d.ts +27 -0
- package/dist/rules/no-shorthand-names.js +133 -0
- package/dist/rules/no-shorthand-names.js.map +1 -0
- package/dist/rules/no-warn.d.ts +18 -0
- package/dist/rules/no-warn.js +48 -0
- package/dist/rules/no-warn.js.map +1 -0
- package/dist/rules/require-react-component-keys.d.ts +3 -0
- package/dist/rules/require-react-component-keys.js +98 -0
- package/dist/rules/require-react-component-keys.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 HowManySmall
|
|
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.
|
package/README.md
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import enforceIanitorCheckType from "./rules/enforce-ianitor-check-type";
|
|
2
|
+
import noColor3Constructor from "./rules/no-color3-constructor";
|
|
3
|
+
import noPrint from "./rules/no-print";
|
|
4
|
+
import noShorthandNames from "./rules/no-shorthand-names";
|
|
5
|
+
import noWarn from "./rules/no-warn";
|
|
6
|
+
import requireReactComponentKeys from "./rules/require-react-component-keys";
|
|
7
|
+
/**
|
|
8
|
+
* ESLint plugin entry for eslint-cease-nonsense-rules.
|
|
9
|
+
*
|
|
10
|
+
* Exposes rule implementations and configuration presets for ESLint flat config.
|
|
11
|
+
*/
|
|
12
|
+
const rules = {
|
|
13
|
+
"enforce-ianitor-check-type": enforceIanitorCheckType,
|
|
14
|
+
"no-color3-constructor": noColor3Constructor,
|
|
15
|
+
"no-print": noPrint,
|
|
16
|
+
"no-shorthand-names": noShorthandNames,
|
|
17
|
+
"no-warn": noWarn,
|
|
18
|
+
"require-react-component-keys": requireReactComponentKeys,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Recommended configuration for ESLint flat config.
|
|
22
|
+
*
|
|
23
|
+
* Enables all rules with recommended settings. Users should import this
|
|
24
|
+
* configuration and add it to their flat config array.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import ceaseNonsense from '@pobammer-ts/eslint-cease-nonsense-rules';
|
|
29
|
+
*
|
|
30
|
+
* export default [
|
|
31
|
+
* ceaseNonsense.configs.recommended,
|
|
32
|
+
* // ... other configs
|
|
33
|
+
* ];
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
const recommended = {
|
|
37
|
+
plugins: {
|
|
38
|
+
"cease-nonsense": {
|
|
39
|
+
rules,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
rules: {
|
|
43
|
+
"cease-nonsense/enforce-ianitor-check-type": "error",
|
|
44
|
+
"cease-nonsense/no-color3-constructor": "error",
|
|
45
|
+
"cease-nonsense/no-print": "error",
|
|
46
|
+
"cease-nonsense/no-shorthand-names": "error",
|
|
47
|
+
"cease-nonsense/no-warn": "error",
|
|
48
|
+
"cease-nonsense/require-react-component-keys": "error",
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const plugin = {
|
|
52
|
+
configs: { recommended },
|
|
53
|
+
rules,
|
|
54
|
+
};
|
|
55
|
+
export default plugin;
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,MAAM,oCAAoC,CAAC;AACzE,OAAO,mBAAmB,MAAM,+BAA+B,CAAC;AAChE,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAC1D,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,yBAAyB,MAAM,sCAAsC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,KAAK,GAA8C;IACxD,4BAA4B,EAAE,uBAAuB;IACrD,uBAAuB,EAAE,mBAAmB;IAC5C,UAAU,EAAE,OAAO;IACnB,oBAAoB,EAAE,gBAAgB;IACtC,SAAS,EAAE,MAAM;IACjB,8BAA8B,EAAE,yBAAyB;CAChD,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,GAAkB;IAClC,OAAO,EAAE;QACR,gBAAgB,EAAE;YACjB,KAAK;SACL;KACD;IACD,KAAK,EAAE;QACN,2CAA2C,EAAE,OAAO;QACpD,sCAAsC,EAAE,OAAO;QAC/C,yBAAyB,EAAE,OAAO;QAClC,mCAAmC,EAAE,OAAO;QAC5C,wBAAwB,EAAE,OAAO;QACjC,6CAA6C,EAAE,OAAO;KACtD;CACQ,CAAC;AASX,MAAM,MAAM,GAAW;IACtB,OAAO,EAAE,EAAE,WAAW,EAAE;IACxB,KAAK;CACI,CAAC;AAEX,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default configuration values for the rule.
|
|
3
|
+
*/
|
|
4
|
+
const DEFAULT_CONFIG = {
|
|
5
|
+
baseThreshold: 10,
|
|
6
|
+
errorThreshold: 25,
|
|
7
|
+
interfacePenalty: 20,
|
|
8
|
+
performanceMode: true,
|
|
9
|
+
warnThreshold: 15,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a node has a type annotation.
|
|
13
|
+
*
|
|
14
|
+
* @param node - The node to check.
|
|
15
|
+
* @returns True if the node has a type annotation.
|
|
16
|
+
*/
|
|
17
|
+
function hasTypeAnnotation(node) {
|
|
18
|
+
const nodeObj = node;
|
|
19
|
+
if (nodeObj.type === "VariableDeclarator") {
|
|
20
|
+
const id = nodeObj.id;
|
|
21
|
+
return !!(id && "typeAnnotation" in id && id.typeAnnotation);
|
|
22
|
+
}
|
|
23
|
+
if (nodeObj.type === "FunctionDeclaration" || nodeObj.type === "FunctionExpression")
|
|
24
|
+
return !!nodeObj.returnType;
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Extracts the type name from a TypeScript type node.
|
|
29
|
+
*
|
|
30
|
+
* @param node - The TypeScript AST node.
|
|
31
|
+
* @returns The type name or null if not applicable.
|
|
32
|
+
*/
|
|
33
|
+
function getTypeName(node) {
|
|
34
|
+
if (node.type === "TSInterfaceDeclaration")
|
|
35
|
+
return node.id.name;
|
|
36
|
+
if (node.type === "TSTypeAliasDeclaration")
|
|
37
|
+
return node.id.name;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Checks if a node is an Ianitor validator call.
|
|
42
|
+
*
|
|
43
|
+
* @param node - The node to check.
|
|
44
|
+
* @returns True if the node is an Ianitor validator.
|
|
45
|
+
*/
|
|
46
|
+
function isIanitorValidator(node) {
|
|
47
|
+
if (node.type !== "CallExpression")
|
|
48
|
+
return false;
|
|
49
|
+
const callee = node.callee;
|
|
50
|
+
if (callee && callee.type === "MemberExpression") {
|
|
51
|
+
const object = callee.object;
|
|
52
|
+
if (object && object.type === "Identifier" && object.name === "Ianitor")
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Calculates the complexity score of an Ianitor validator.
|
|
59
|
+
*
|
|
60
|
+
* @param node - The Ianitor validator node.
|
|
61
|
+
* @returns The complexity score.
|
|
62
|
+
*/
|
|
63
|
+
function calculateIanitorComplexity(node) {
|
|
64
|
+
const callNode = node;
|
|
65
|
+
const callee = callNode.callee;
|
|
66
|
+
let score = 0;
|
|
67
|
+
if (callee?.type === "MemberExpression" && callee.property && callee.property.type === "Identifier") {
|
|
68
|
+
const method = callee.property.name;
|
|
69
|
+
switch (method) {
|
|
70
|
+
case "interface":
|
|
71
|
+
case "strictInterface": {
|
|
72
|
+
const props = callNode.arguments?.[0];
|
|
73
|
+
// Skip recursive property calculation for now to avoid type issues
|
|
74
|
+
if (props && props.type === "ObjectExpression")
|
|
75
|
+
score = 10 + (props.properties?.length || 0) * 3;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case "optional":
|
|
79
|
+
case "array":
|
|
80
|
+
score = 2;
|
|
81
|
+
break;
|
|
82
|
+
case "record":
|
|
83
|
+
case "map":
|
|
84
|
+
score = 3;
|
|
85
|
+
break;
|
|
86
|
+
case "union":
|
|
87
|
+
case "intersection":
|
|
88
|
+
score = (callNode.arguments?.length || 0) * 2;
|
|
89
|
+
break;
|
|
90
|
+
case "string":
|
|
91
|
+
case "number":
|
|
92
|
+
case "boolean":
|
|
93
|
+
score = 1;
|
|
94
|
+
break;
|
|
95
|
+
case "instanceIsA":
|
|
96
|
+
case "instanceOf":
|
|
97
|
+
score = 2;
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
score = 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return score;
|
|
104
|
+
}
|
|
105
|
+
const enforceIanitorCheckType = {
|
|
106
|
+
/**
|
|
107
|
+
* Creates the ESLint rule visitor.
|
|
108
|
+
*
|
|
109
|
+
* @param context - The ESLint rule context.
|
|
110
|
+
* @returns The visitor object with AST node handlers.
|
|
111
|
+
*/
|
|
112
|
+
create(context) {
|
|
113
|
+
const config = { ...DEFAULT_CONFIG, ...context.options[0] };
|
|
114
|
+
const cache = {
|
|
115
|
+
nodeCache: new WeakMap(),
|
|
116
|
+
visitedNodes: new WeakSet(),
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Calculates the structural complexity of a TypeScript type.
|
|
120
|
+
*
|
|
121
|
+
* @param node - The TypeScript AST node.
|
|
122
|
+
* @param depth - The current depth in the type tree.
|
|
123
|
+
* @returns The complexity score.
|
|
124
|
+
*/
|
|
125
|
+
function calculateStructuralComplexity(node, depth = 0) {
|
|
126
|
+
// Performance: Cache everything
|
|
127
|
+
if (cache.nodeCache.has(node))
|
|
128
|
+
return cache.nodeCache.get(node);
|
|
129
|
+
// Cycle detection without TypeChecker
|
|
130
|
+
if (cache.visitedNodes.has(node))
|
|
131
|
+
return 50;
|
|
132
|
+
cache.visitedNodes.add(node);
|
|
133
|
+
let score = 0;
|
|
134
|
+
switch (node.type) {
|
|
135
|
+
// Primitives
|
|
136
|
+
case "TSStringKeyword":
|
|
137
|
+
case "TSNumberKeyword":
|
|
138
|
+
case "TSBooleanKeyword":
|
|
139
|
+
case "TSNullKeyword":
|
|
140
|
+
case "TSUndefinedKeyword":
|
|
141
|
+
case "TSVoidKeyword":
|
|
142
|
+
case "TSSymbolKeyword":
|
|
143
|
+
case "TSBigIntKeyword":
|
|
144
|
+
score = 1;
|
|
145
|
+
break;
|
|
146
|
+
// Short-circuits
|
|
147
|
+
case "TSNeverKeyword":
|
|
148
|
+
case "TSUnknownKeyword":
|
|
149
|
+
case "TSAnyKeyword":
|
|
150
|
+
score = 0;
|
|
151
|
+
break;
|
|
152
|
+
// INTERFACES - ALWAYS COMPLEX
|
|
153
|
+
case "TSInterfaceDeclaration": {
|
|
154
|
+
const iface = node;
|
|
155
|
+
score = config.interfacePenalty; // Base penalty
|
|
156
|
+
// Add for extends
|
|
157
|
+
if (iface.extends && iface.extends.length > 0)
|
|
158
|
+
score += iface.extends.length * 5;
|
|
159
|
+
// Add for members
|
|
160
|
+
score += iface.body.body.length * 2;
|
|
161
|
+
// Recurse on member types
|
|
162
|
+
for (const member of iface.body.body)
|
|
163
|
+
if ("typeAnnotation" in member && member.typeAnnotation)
|
|
164
|
+
score += calculateStructuralComplexity(member.typeAnnotation.typeAnnotation, depth + 1);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
// Type literals (object types)
|
|
168
|
+
case "TSTypeLiteral": {
|
|
169
|
+
const literal = node;
|
|
170
|
+
score = 2;
|
|
171
|
+
score += literal.members.length * 0.5;
|
|
172
|
+
for (const member of literal.members)
|
|
173
|
+
if ("typeAnnotation" in member && member.typeAnnotation)
|
|
174
|
+
score += calculateStructuralComplexity(member.typeAnnotation.typeAnnotation, depth + 1);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
// Unions
|
|
178
|
+
case "TSUnionType": {
|
|
179
|
+
const union = node;
|
|
180
|
+
for (const type of union.types)
|
|
181
|
+
score += calculateStructuralComplexity(type, depth + 1);
|
|
182
|
+
score += 2 * (union.types.length - 1); // Branch penalty
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
// Intersections
|
|
186
|
+
case "TSIntersectionType": {
|
|
187
|
+
const intersection = node;
|
|
188
|
+
for (const type of intersection.types) {
|
|
189
|
+
score += calculateStructuralComplexity(type, depth + 1);
|
|
190
|
+
}
|
|
191
|
+
score += 3 * intersection.types.length; // Overlap resolution penalty
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
// Arrays
|
|
195
|
+
case "TSArrayType": {
|
|
196
|
+
const array = node;
|
|
197
|
+
score = calculateStructuralComplexity(array.elementType, depth + 1) + 1;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
// Tuples
|
|
201
|
+
case "TSTupleType": {
|
|
202
|
+
const tuple = node;
|
|
203
|
+
score = 1;
|
|
204
|
+
for (const element of tuple.elementTypes)
|
|
205
|
+
if (element.type !== "TSRestType" && element.type !== "TSOptionalType")
|
|
206
|
+
score += calculateStructuralComplexity(element, depth + 1);
|
|
207
|
+
score += 1.5 * tuple.elementTypes.length;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
// Type references (including generics)
|
|
211
|
+
case "TSTypeReference": {
|
|
212
|
+
const ref = node;
|
|
213
|
+
score = 2;
|
|
214
|
+
if (ref.typeArguments)
|
|
215
|
+
for (const param of ref.typeArguments.params)
|
|
216
|
+
score += calculateStructuralComplexity(param, depth + 1) + 2;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
// Conditional types
|
|
220
|
+
case "TSConditionalType": {
|
|
221
|
+
const conditional = node;
|
|
222
|
+
score = 3;
|
|
223
|
+
score += calculateStructuralComplexity(conditional.checkType, depth + 1);
|
|
224
|
+
score += calculateStructuralComplexity(conditional.extendsType, depth + 1);
|
|
225
|
+
score += calculateStructuralComplexity(conditional.trueType, depth + 1);
|
|
226
|
+
score += calculateStructuralComplexity(conditional.falseType, depth + 1);
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
// Mapped types
|
|
230
|
+
case "TSMappedType": {
|
|
231
|
+
const mapped = node;
|
|
232
|
+
score = 5;
|
|
233
|
+
if (mapped.typeParameter?.constraint)
|
|
234
|
+
score += calculateStructuralComplexity(mapped.typeParameter.constraint, depth + 1);
|
|
235
|
+
if (mapped.typeAnnotation)
|
|
236
|
+
score += calculateStructuralComplexity(mapped.typeAnnotation, depth + 1);
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
// Function types
|
|
240
|
+
case "TSFunctionType":
|
|
241
|
+
case "TSMethodSignature": {
|
|
242
|
+
const func = node;
|
|
243
|
+
score = 2;
|
|
244
|
+
for (const param of func.params)
|
|
245
|
+
if ("typeAnnotation" in param && param.typeAnnotation)
|
|
246
|
+
score += calculateStructuralComplexity(param.typeAnnotation.typeAnnotation, depth + 1);
|
|
247
|
+
if (func.returnType)
|
|
248
|
+
score += calculateStructuralComplexity(func.returnType.typeAnnotation, depth + 1);
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
default:
|
|
252
|
+
score = 1;
|
|
253
|
+
}
|
|
254
|
+
// Apply depth multiplier (logarithmic to prevent explosion)
|
|
255
|
+
score *= Math.log2(depth + 1);
|
|
256
|
+
// Cache and return
|
|
257
|
+
cache.nodeCache.set(node, score);
|
|
258
|
+
cache.visitedNodes.delete(node);
|
|
259
|
+
return score;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
// Check interface declarations
|
|
263
|
+
TSInterfaceDeclaration(node) {
|
|
264
|
+
const complexity = calculateStructuralComplexity(node);
|
|
265
|
+
const name = getTypeName(node);
|
|
266
|
+
if (complexity >= config.interfacePenalty) {
|
|
267
|
+
context.report({
|
|
268
|
+
data: { name: name || "unknown" },
|
|
269
|
+
messageId: "complexInterfaceNeedsCheck",
|
|
270
|
+
node,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
// Check type alias declarations
|
|
275
|
+
TSTypeAliasDeclaration(node) {
|
|
276
|
+
const complexity = calculateStructuralComplexity(node.typeAnnotation);
|
|
277
|
+
if (complexity < config.baseThreshold)
|
|
278
|
+
return;
|
|
279
|
+
context.report({
|
|
280
|
+
data: { score: complexity.toFixed(1) },
|
|
281
|
+
messageId: "missingIanitorCheckType",
|
|
282
|
+
node,
|
|
283
|
+
});
|
|
284
|
+
},
|
|
285
|
+
// Check variable declarations with Ianitor validators
|
|
286
|
+
VariableDeclarator(node) {
|
|
287
|
+
if (!node.init || node.init.type !== "CallExpression")
|
|
288
|
+
return;
|
|
289
|
+
if (!isIanitorValidator(node.init))
|
|
290
|
+
return;
|
|
291
|
+
if (hasTypeAnnotation(node))
|
|
292
|
+
return;
|
|
293
|
+
const complexity = calculateIanitorComplexity(node.init);
|
|
294
|
+
if (complexity < config.baseThreshold)
|
|
295
|
+
return;
|
|
296
|
+
context.report({
|
|
297
|
+
data: { score: complexity.toFixed(1) },
|
|
298
|
+
messageId: "missingIanitorCheckType",
|
|
299
|
+
node,
|
|
300
|
+
});
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
},
|
|
304
|
+
meta: {
|
|
305
|
+
docs: {
|
|
306
|
+
description: "Enforce Ianitor.Check<T> type annotations on complex TypeScript types",
|
|
307
|
+
recommended: false,
|
|
308
|
+
},
|
|
309
|
+
fixable: undefined,
|
|
310
|
+
messages: {
|
|
311
|
+
complexInterfaceNeedsCheck: "Interface '{{name}}' requires Ianitor.Check<T> annotation (interfaces always need explicit checking)",
|
|
312
|
+
missingIanitorCheckType: "Complex type (score: {{score}}) requires Ianitor.Check<T> annotation for type safety",
|
|
313
|
+
},
|
|
314
|
+
schema: [
|
|
315
|
+
{
|
|
316
|
+
additionalProperties: false,
|
|
317
|
+
properties: {
|
|
318
|
+
baseThreshold: { minimum: 1, type: "number" },
|
|
319
|
+
errorThreshold: { minimum: 1, type: "number" },
|
|
320
|
+
interfacePenalty: { minimum: 1, type: "number" },
|
|
321
|
+
performanceMode: { type: "boolean" },
|
|
322
|
+
warnThreshold: { minimum: 1, type: "number" },
|
|
323
|
+
},
|
|
324
|
+
type: "object",
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
type: "problem",
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
export default enforceIanitorCheckType;
|
|
331
|
+
//# sourceMappingURL=enforce-ianitor-check-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enforce-ianitor-check-type.js","sourceRoot":"","sources":["../../src/rules/enforce-ianitor-check-type.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Bans use of `new Color3(...)` except for `new Color3()` or `new Color3(0, 0, 0)`.
|
|
4
|
+
*
|
|
5
|
+
* The `new Color3()` constructor uses float values [0-1] and performs worse than
|
|
6
|
+
* `Color3.fromRGB()` which uses integer values [0-255].
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Reports
|
|
10
|
+
* new Color3(255, 128, 64);
|
|
11
|
+
* new Color3(0.5);
|
|
12
|
+
* new Color3(1, 0);
|
|
13
|
+
*
|
|
14
|
+
* // ✅ OK
|
|
15
|
+
* new Color3();
|
|
16
|
+
* new Color3(0, 0, 0);
|
|
17
|
+
* Color3.fromRGB(255, 128, 64);
|
|
18
|
+
*/
|
|
19
|
+
declare const noColor3Constructor: Rule.RuleModule;
|
|
20
|
+
export default noColor3Constructor;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bans use of `new Color3(...)` except for `new Color3()` or `new Color3(0, 0, 0)`.
|
|
3
|
+
*
|
|
4
|
+
* The `new Color3()` constructor uses float values [0-1] and performs worse than
|
|
5
|
+
* `Color3.fromRGB()` which uses integer values [0-255].
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // ❌ Reports
|
|
9
|
+
* new Color3(255, 128, 64);
|
|
10
|
+
* new Color3(0.5);
|
|
11
|
+
* new Color3(1, 0);
|
|
12
|
+
*
|
|
13
|
+
* // ✅ OK
|
|
14
|
+
* new Color3();
|
|
15
|
+
* new Color3(0, 0, 0);
|
|
16
|
+
* Color3.fromRGB(255, 128, 64);
|
|
17
|
+
*/
|
|
18
|
+
const noColor3Constructor = {
|
|
19
|
+
/**
|
|
20
|
+
* Creates the ESLint rule visitor.
|
|
21
|
+
*
|
|
22
|
+
* @param context - The ESLint rule context.
|
|
23
|
+
* @returns The visitor object with AST node handlers.
|
|
24
|
+
*/
|
|
25
|
+
create(context) {
|
|
26
|
+
return {
|
|
27
|
+
NewExpression(node) {
|
|
28
|
+
if (node.callee.type !== "Identifier" || node.callee.name !== "Color3")
|
|
29
|
+
return;
|
|
30
|
+
const args = node.arguments;
|
|
31
|
+
// No arguments is allowed: new Color3()
|
|
32
|
+
if (args.length === 0)
|
|
33
|
+
return;
|
|
34
|
+
// 1 or 2 arguments - always flag
|
|
35
|
+
if (args.length === 1 || args.length === 2) {
|
|
36
|
+
context.report({
|
|
37
|
+
messageId: "useFromRGB",
|
|
38
|
+
node,
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// 3 arguments - only allow if all are literal 0
|
|
43
|
+
if (args.length === 3) {
|
|
44
|
+
const allZero = args.every((arg) => arg.type === "Literal" && arg.value === 0);
|
|
45
|
+
if (!allZero) {
|
|
46
|
+
context.report({
|
|
47
|
+
messageId: "onlyZeroArgs",
|
|
48
|
+
node,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
meta: {
|
|
56
|
+
docs: {
|
|
57
|
+
description: "Ban new Color3(...) except new Color3() or new Color3(0, 0, 0). Use Color3.fromRGB() instead.",
|
|
58
|
+
recommended: false,
|
|
59
|
+
},
|
|
60
|
+
messages: {
|
|
61
|
+
onlyZeroArgs: "Use Color3.fromRGB() instead of new Color3(). new Color3() uses floats [0-1] and performs worse than Color3.fromRGB() which uses [0-255]. Only 'new Color3()' or 'new Color3(0, 0, 0)' are allowed.",
|
|
62
|
+
useFromRGB: "Use Color3.fromRGB() instead of new Color3(). new Color3() uses floats [0-1] and performs worse than Color3.fromRGB() which uses [0-255].",
|
|
63
|
+
},
|
|
64
|
+
schema: [],
|
|
65
|
+
type: "problem",
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export default noColor3Constructor;
|
|
69
|
+
//# sourceMappingURL=no-color3-constructor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-color3-constructor.js","sourceRoot":"","sources":["../../src/rules/no-color3-constructor.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,mBAAmB,GAAoB;IAC5C;;;;;OAKG;IACH,MAAM,CAAC,OAAO;QACb,OAAO;YACN,aAAa,CAAC,IAAI;gBACjB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBAE/E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAE5B,wCAAwC;gBACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO;gBAE9B,iCAAiC;gBACjC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC5C,OAAO,CAAC,MAAM,CAAC;wBACd,SAAS,EAAE,YAAY;wBACvB,IAAI;qBACJ,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,gDAAgD;gBAChD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;oBAE/E,IAAI,CAAC,OAAO,EAAE,CAAC;wBACd,OAAO,CAAC,MAAM,CAAC;4BACd,SAAS,EAAE,cAAc;4BACzB,IAAI;yBACJ,CAAC,CAAC;oBACJ,CAAC;gBACF,CAAC;YACF,CAAC;SACD,CAAC;IACH,CAAC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,WAAW,EACV,+FAA+F;YAChG,WAAW,EAAE,KAAK;SAClB;QACD,QAAQ,EAAE;YACT,YAAY,EACX,qMAAqM;YACtM,UAAU,EACT,2IAA2I;SAC5I;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,SAAS;KACf;CACD,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Bans use of `print()` function calls. Use `Log` instead.
|
|
4
|
+
*
|
|
5
|
+
* The `print()` function is deprecated or discouraged in favor of a proper
|
|
6
|
+
* logging system like `Log`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Reports
|
|
10
|
+
* print("Hello");
|
|
11
|
+
* print(value);
|
|
12
|
+
*
|
|
13
|
+
* // ✅ OK
|
|
14
|
+
* Log.info("Hello");
|
|
15
|
+
* Log.debug(value);
|
|
16
|
+
*/
|
|
17
|
+
declare const noPrint: Rule.RuleModule;
|
|
18
|
+
export default noPrint;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bans use of `print()` function calls. Use `Log` instead.
|
|
3
|
+
*
|
|
4
|
+
* The `print()` function is deprecated or discouraged in favor of a proper
|
|
5
|
+
* logging system like `Log`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // ❌ Reports
|
|
9
|
+
* print("Hello");
|
|
10
|
+
* print(value);
|
|
11
|
+
*
|
|
12
|
+
* // ✅ OK
|
|
13
|
+
* Log.info("Hello");
|
|
14
|
+
* Log.debug(value);
|
|
15
|
+
*/
|
|
16
|
+
const noPrint = {
|
|
17
|
+
/**
|
|
18
|
+
* Creates the ESLint rule visitor.
|
|
19
|
+
*
|
|
20
|
+
* @param context - The ESLint rule context.
|
|
21
|
+
* @returns The visitor object with AST node handlers.
|
|
22
|
+
*/
|
|
23
|
+
create(context) {
|
|
24
|
+
return {
|
|
25
|
+
CallExpression(node) {
|
|
26
|
+
if (node.callee.type !== "Identifier" || node.callee.name !== "print")
|
|
27
|
+
return;
|
|
28
|
+
context.report({
|
|
29
|
+
messageId: "useLog",
|
|
30
|
+
node,
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
meta: {
|
|
36
|
+
docs: {
|
|
37
|
+
description: "Ban print() function calls. Use Log instead.",
|
|
38
|
+
recommended: false,
|
|
39
|
+
},
|
|
40
|
+
messages: {
|
|
41
|
+
useLog: "Use Log instead of print()",
|
|
42
|
+
},
|
|
43
|
+
schema: [],
|
|
44
|
+
type: "problem",
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export default noPrint;
|
|
48
|
+
//# sourceMappingURL=no-print.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-print.js","sourceRoot":"","sources":["../../src/rules/no-print.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,GAAoB;IAChC;;;;;OAKG;IACH,MAAM,CAAC,OAAO;QACb,OAAO;YACN,cAAc,CAAC,IAAI;gBAClB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;oBAAE,OAAO;gBAE9E,OAAO,CAAC,MAAM,CAAC;oBACd,SAAS,EAAE,QAAQ;oBACnB,IAAI;iBACJ,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,WAAW,EAAE,8CAA8C;YAC3D,WAAW,EAAE,KAAK;SAClB;QACD,QAAQ,EAAE;YACT,MAAM,EAAE,4BAA4B;SACpC;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,SAAS;KACf;CACD,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Bans shorthand variable names in favor of descriptive full names.
|
|
4
|
+
*
|
|
5
|
+
* Enforces:
|
|
6
|
+
* - `plr` → `player` (or `localPlayer` for Players.LocalPlayer assignments)
|
|
7
|
+
* - `args` → `parameters`
|
|
8
|
+
* - `dt` → `deltaTime`
|
|
9
|
+
* - `char` → `character` (except when used as property access)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // ❌ Reports
|
|
13
|
+
* const plr = getPlayer();
|
|
14
|
+
* const args = [1, 2, 3];
|
|
15
|
+
* const dt = 0.016;
|
|
16
|
+
* const char = getCharacter();
|
|
17
|
+
*
|
|
18
|
+
* // ✅ OK
|
|
19
|
+
* const player = getPlayer();
|
|
20
|
+
* const localPlayer = Players.LocalPlayer;
|
|
21
|
+
* const parameters = [1, 2, 3];
|
|
22
|
+
* const deltaTime = 0.016;
|
|
23
|
+
* const character = getCharacter();
|
|
24
|
+
* const model = entity.char; // property access is allowed
|
|
25
|
+
*/
|
|
26
|
+
declare const noShorthandNames: Rule.RuleModule;
|
|
27
|
+
export default noShorthandNames;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const SHORTHANDS = [
|
|
2
|
+
{ messageId: "useParameters", replacement: "parameters", shorthand: "args" },
|
|
3
|
+
{ messageId: "useDeltaTime", replacement: "deltaTime", shorthand: "dt" },
|
|
4
|
+
{ messageId: "useCharacter", replacement: "character", shorthand: "char" },
|
|
5
|
+
];
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a node is Players.LocalPlayer member expression.
|
|
8
|
+
*
|
|
9
|
+
* @param node - The node to check.
|
|
10
|
+
* @returns True if node is Players.LocalPlayer.
|
|
11
|
+
*/
|
|
12
|
+
function isPlayersLocalPlayer(node) {
|
|
13
|
+
if (!node || typeof node !== "object")
|
|
14
|
+
return false;
|
|
15
|
+
const n = node;
|
|
16
|
+
if (n.type !== "MemberExpression")
|
|
17
|
+
return false;
|
|
18
|
+
const obj = n.object;
|
|
19
|
+
const prop = n.property;
|
|
20
|
+
if (!obj || typeof obj !== "object" || !prop || typeof prop !== "object")
|
|
21
|
+
return false;
|
|
22
|
+
const objNode = obj;
|
|
23
|
+
const propNode = prop;
|
|
24
|
+
return (objNode.type === "Identifier" &&
|
|
25
|
+
objNode.name === "Players" &&
|
|
26
|
+
propNode.type === "Identifier" &&
|
|
27
|
+
propNode.name === "LocalPlayer");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Checks if an identifier is used as a property access.
|
|
31
|
+
*
|
|
32
|
+
* @param node - The identifier node to check.
|
|
33
|
+
* @returns True if the identifier is a property in a member expression.
|
|
34
|
+
*/
|
|
35
|
+
function isPropertyAccess(node) {
|
|
36
|
+
const parent = node.parent;
|
|
37
|
+
if (!parent || typeof parent !== "object")
|
|
38
|
+
return false;
|
|
39
|
+
const p = parent;
|
|
40
|
+
return p.type === "MemberExpression" && p.property === node;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Bans shorthand variable names in favor of descriptive full names.
|
|
44
|
+
*
|
|
45
|
+
* Enforces:
|
|
46
|
+
* - `plr` → `player` (or `localPlayer` for Players.LocalPlayer assignments)
|
|
47
|
+
* - `args` → `parameters`
|
|
48
|
+
* - `dt` → `deltaTime`
|
|
49
|
+
* - `char` → `character` (except when used as property access)
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // ❌ Reports
|
|
53
|
+
* const plr = getPlayer();
|
|
54
|
+
* const args = [1, 2, 3];
|
|
55
|
+
* const dt = 0.016;
|
|
56
|
+
* const char = getCharacter();
|
|
57
|
+
*
|
|
58
|
+
* // ✅ OK
|
|
59
|
+
* const player = getPlayer();
|
|
60
|
+
* const localPlayer = Players.LocalPlayer;
|
|
61
|
+
* const parameters = [1, 2, 3];
|
|
62
|
+
* const deltaTime = 0.016;
|
|
63
|
+
* const character = getCharacter();
|
|
64
|
+
* const model = entity.char; // property access is allowed
|
|
65
|
+
*/
|
|
66
|
+
const noShorthandNames = {
|
|
67
|
+
/**
|
|
68
|
+
* Creates the ESLint rule visitor.
|
|
69
|
+
*
|
|
70
|
+
* @param context - The ESLint rule context.
|
|
71
|
+
* @returns The visitor object with AST node handlers.
|
|
72
|
+
*/
|
|
73
|
+
create(context) {
|
|
74
|
+
return {
|
|
75
|
+
Identifier(node) {
|
|
76
|
+
const name = node.name;
|
|
77
|
+
// Special case: plr
|
|
78
|
+
if (name === "plr") {
|
|
79
|
+
// Skip if it's a property access
|
|
80
|
+
if (isPropertyAccess(node))
|
|
81
|
+
return;
|
|
82
|
+
// Check if this is a variable declarator with Players.LocalPlayer
|
|
83
|
+
const parent = node.parent;
|
|
84
|
+
if (parent?.type === "VariableDeclarator" &&
|
|
85
|
+
parent.id === node &&
|
|
86
|
+
isPlayersLocalPlayer(parent.init)) {
|
|
87
|
+
context.report({
|
|
88
|
+
messageId: "useLocalPlayer",
|
|
89
|
+
node,
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Default case: use player
|
|
94
|
+
context.report({
|
|
95
|
+
messageId: "usePlayer",
|
|
96
|
+
node,
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Check other shorthands
|
|
101
|
+
for (const { messageId, shorthand } of SHORTHANDS) {
|
|
102
|
+
if (name === shorthand) {
|
|
103
|
+
// Special case: char - skip property access
|
|
104
|
+
if (shorthand === "char" && isPropertyAccess(node))
|
|
105
|
+
continue;
|
|
106
|
+
context.report({
|
|
107
|
+
messageId,
|
|
108
|
+
node,
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
meta: {
|
|
117
|
+
docs: {
|
|
118
|
+
description: "Ban shorthand variable names. Use descriptive full names instead.",
|
|
119
|
+
recommended: false,
|
|
120
|
+
},
|
|
121
|
+
messages: {
|
|
122
|
+
useCharacter: "Use 'character' instead of 'char' shorthand",
|
|
123
|
+
useDeltaTime: "Use 'deltaTime' instead of 'dt' shorthand",
|
|
124
|
+
useLocalPlayer: "Use 'localPlayer' instead of 'plr' when assigning Players.LocalPlayer",
|
|
125
|
+
useParameters: "Use 'parameters' instead of 'args' shorthand",
|
|
126
|
+
usePlayer: "Use 'player' instead of 'plr' shorthand",
|
|
127
|
+
},
|
|
128
|
+
schema: [],
|
|
129
|
+
type: "suggestion",
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
export default noShorthandNames;
|
|
133
|
+
//# sourceMappingURL=no-shorthand-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-shorthand-names.js","sourceRoot":"","sources":["../../src/rules/no-shorthand-names.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAA6B;IAC5C,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE;IAC5E,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE;IACxE,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;CACjE,CAAC;AAEX;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,IAAa;IAC1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,CAAC,GAAG,IAA+D,CAAC;IAC1E,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB;QAAE,OAAO,KAAK,CAAC;IAEhD,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC;IACxB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEvF,MAAM,OAAO,GAAG,GAAuC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAwC,CAAC;IAE1D,OAAO,CACN,OAAO,CAAC,IAAI,KAAK,YAAY;QAC7B,OAAO,CAAC,IAAI,KAAK,SAAS;QAC1B,QAAQ,CAAC,IAAI,KAAK,YAAY;QAC9B,QAAQ,CAAC,IAAI,KAAK,aAAa,CAC/B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,IAA0B;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAExD,MAAM,CAAC,GAAG,MAA+C,CAAC;IAC1D,OAAO,CAAC,CAAC,IAAI,KAAK,kBAAkB,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,gBAAgB,GAAoB;IACzC;;;;;OAKG;IACH,MAAM,CAAC,OAAO;QACb,OAAO;YACN,UAAU,CAAC,IAAI;gBACd,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;gBAEvB,oBAAoB;gBACpB,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;oBACpB,iCAAiC;oBACjC,IAAI,gBAAgB,CAAC,IAAI,CAAC;wBAAE,OAAO;oBAEnC,kEAAkE;oBAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC3B,IACC,MAAM,EAAE,IAAI,KAAK,oBAAoB;wBACrC,MAAM,CAAC,EAAE,KAAK,IAAI;wBAClB,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,EAChC,CAAC;wBACF,OAAO,CAAC,MAAM,CAAC;4BACd,SAAS,EAAE,gBAAgB;4BAC3B,IAAI;yBACJ,CAAC,CAAC;wBACH,OAAO;oBACR,CAAC;oBAED,2BAA2B;oBAC3B,OAAO,CAAC,MAAM,CAAC;wBACd,SAAS,EAAE,WAAW;wBACtB,IAAI;qBACJ,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,yBAAyB;gBACzB,KAAK,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,UAAU,EAAE,CAAC;oBACnD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;wBACxB,4CAA4C;wBAC5C,IAAI,SAAS,KAAK,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC;4BAAE,SAAS;wBAE7D,OAAO,CAAC,MAAM,CAAC;4BACd,SAAS;4BACT,IAAI;yBACJ,CAAC,CAAC;wBACH,OAAO;oBACR,CAAC;gBACF,CAAC;YACF,CAAC;SACD,CAAC;IACH,CAAC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,WAAW,EAAE,mEAAmE;YAChF,WAAW,EAAE,KAAK;SAClB;QACD,QAAQ,EAAE;YACT,YAAY,EAAE,6CAA6C;YAC3D,YAAY,EAAE,2CAA2C;YACzD,cAAc,EAAE,uEAAuE;YACvF,aAAa,EAAE,8CAA8C;YAC7D,SAAS,EAAE,yCAAyC;SACpD;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,YAAY;KAClB;CACD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
/**
|
|
3
|
+
* Bans use of `warn()` function calls. Use `Log` instead.
|
|
4
|
+
*
|
|
5
|
+
* The `warn()` function is deprecated or discouraged in favor of a proper
|
|
6
|
+
* logging system like `Log`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Reports
|
|
10
|
+
* warn("Warning");
|
|
11
|
+
* warn(error);
|
|
12
|
+
*
|
|
13
|
+
* // ✅ OK
|
|
14
|
+
* Log.warn("Warning");
|
|
15
|
+
* Log.error(error);
|
|
16
|
+
*/
|
|
17
|
+
declare const noWarn: Rule.RuleModule;
|
|
18
|
+
export default noWarn;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bans use of `warn()` function calls. Use `Log` instead.
|
|
3
|
+
*
|
|
4
|
+
* The `warn()` function is deprecated or discouraged in favor of a proper
|
|
5
|
+
* logging system like `Log`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // ❌ Reports
|
|
9
|
+
* warn("Warning");
|
|
10
|
+
* warn(error);
|
|
11
|
+
*
|
|
12
|
+
* // ✅ OK
|
|
13
|
+
* Log.warn("Warning");
|
|
14
|
+
* Log.error(error);
|
|
15
|
+
*/
|
|
16
|
+
const noWarn = {
|
|
17
|
+
/**
|
|
18
|
+
* Creates the ESLint rule visitor.
|
|
19
|
+
*
|
|
20
|
+
* @param context - The ESLint rule context.
|
|
21
|
+
* @returns The visitor object with AST node handlers.
|
|
22
|
+
*/
|
|
23
|
+
create(context) {
|
|
24
|
+
return {
|
|
25
|
+
CallExpression(node) {
|
|
26
|
+
if (node.callee.type !== "Identifier" || node.callee.name !== "warn")
|
|
27
|
+
return;
|
|
28
|
+
context.report({
|
|
29
|
+
messageId: "useLog",
|
|
30
|
+
node,
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
meta: {
|
|
36
|
+
docs: {
|
|
37
|
+
description: "Ban warn() function calls. Use Log instead.",
|
|
38
|
+
recommended: false,
|
|
39
|
+
},
|
|
40
|
+
messages: {
|
|
41
|
+
useLog: "Use Log instead of warn()",
|
|
42
|
+
},
|
|
43
|
+
schema: [],
|
|
44
|
+
type: "problem",
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export default noWarn;
|
|
48
|
+
//# sourceMappingURL=no-warn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-warn.js","sourceRoot":"","sources":["../../src/rules/no-warn.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,GAAoB;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,OAAO;QACb,OAAO;YACN,cAAc,CAAC,IAAI;gBAClB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;oBAAE,OAAO;gBAE7E,OAAO,CAAC,MAAM,CAAC;oBACd,SAAS,EAAE,QAAQ;oBACnB,IAAI;iBACJ,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,WAAW,EAAE,6CAA6C;YAC1D,WAAW,EAAE,KAAK;SAClB;QACD,QAAQ,EAAE;YACT,MAAM,EAAE,2BAA2B;SACnC;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,SAAS;KACf;CACD,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a JSX element has a key attribute.
|
|
3
|
+
*
|
|
4
|
+
* @param node - The JSX element to check.
|
|
5
|
+
* @returns True if the element has a key attribute.
|
|
6
|
+
*/
|
|
7
|
+
function hasKeyAttribute(node) {
|
|
8
|
+
return node.openingElement.attributes.some((attr) => attr.type === "JSXAttribute" && attr.name.name === "key");
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Checks if a JSX element is a top-level return from a component.
|
|
12
|
+
*
|
|
13
|
+
* @param node - The JSX element or fragment to check.
|
|
14
|
+
* @returns True if the element is directly returned from a component.
|
|
15
|
+
*/
|
|
16
|
+
function isTopLevelReturn(node) {
|
|
17
|
+
// Check if this element is a direct child of a return statement
|
|
18
|
+
let parent = node.parent;
|
|
19
|
+
if (!parent)
|
|
20
|
+
return false;
|
|
21
|
+
// Handle return with parentheses: return (<div>...)
|
|
22
|
+
if (parent.type === "JSXExpressionContainer")
|
|
23
|
+
parent = parent.parent;
|
|
24
|
+
// Handle direct return
|
|
25
|
+
if (parent?.type === "ReturnStatement")
|
|
26
|
+
return true;
|
|
27
|
+
// Handle arrow function direct return: () => <div>
|
|
28
|
+
if (parent?.type === "ArrowFunctionExpression")
|
|
29
|
+
return true;
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const requireReactComponentKeys = {
|
|
33
|
+
/**
|
|
34
|
+
* Creates the ESLint rule visitor.
|
|
35
|
+
*
|
|
36
|
+
* @param context - The ESLint rule context.
|
|
37
|
+
* @returns The visitor object with AST node handlers.
|
|
38
|
+
*/
|
|
39
|
+
create(context) {
|
|
40
|
+
const returnStack = new Array();
|
|
41
|
+
/**
|
|
42
|
+
* Checks a JSX element or fragment for required key prop.
|
|
43
|
+
*
|
|
44
|
+
* @param node - The JSX element or fragment to check.
|
|
45
|
+
*/
|
|
46
|
+
function checkElement(node) {
|
|
47
|
+
// Top-level return doesn't need key
|
|
48
|
+
if (isTopLevelReturn(node))
|
|
49
|
+
return;
|
|
50
|
+
// Fragments always need keys when not top-level
|
|
51
|
+
if (node.type === "JSXFragment") {
|
|
52
|
+
context.report({
|
|
53
|
+
messageId: "missingKey",
|
|
54
|
+
node,
|
|
55
|
+
});
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Check if element has key
|
|
59
|
+
if (hasKeyAttribute(node))
|
|
60
|
+
return;
|
|
61
|
+
context.report({
|
|
62
|
+
messageId: "missingKey",
|
|
63
|
+
node,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
// Track function/component boundaries for top-level detection
|
|
68
|
+
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression"(node) {
|
|
69
|
+
returnStack.push({ depth: returnStack.length, node });
|
|
70
|
+
},
|
|
71
|
+
"FunctionDeclaration, FunctionExpression, ArrowFunctionExpression:exit"() {
|
|
72
|
+
returnStack.pop();
|
|
73
|
+
},
|
|
74
|
+
// Check JSX elements
|
|
75
|
+
JSXElement(node) {
|
|
76
|
+
checkElement(node);
|
|
77
|
+
},
|
|
78
|
+
// Check JSX fragments
|
|
79
|
+
JSXFragment(node) {
|
|
80
|
+
checkElement(node);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
meta: {
|
|
85
|
+
docs: {
|
|
86
|
+
description: "Enforce key props on all React elements except top-level returns",
|
|
87
|
+
recommended: false,
|
|
88
|
+
},
|
|
89
|
+
fixable: undefined,
|
|
90
|
+
messages: {
|
|
91
|
+
missingKey: "All React elements except top-level returns require a key prop",
|
|
92
|
+
},
|
|
93
|
+
schema: [],
|
|
94
|
+
type: "problem",
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
export default requireReactComponentKeys;
|
|
98
|
+
//# sourceMappingURL=require-react-component-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-react-component-keys.js","sourceRoot":"","sources":["../../src/rules/require-react-component-keys.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,SAAS,eAAe,CAAC,IAAyB;IACjD,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;AAChH,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,IAAgD;IACzE,gEAAgE;IAChE,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,oDAAoD;IACpD,IAAI,MAAM,CAAC,IAAI,KAAK,wBAAwB;QAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAErE,uBAAuB;IACvB,IAAI,MAAM,EAAE,IAAI,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAEpD,mDAAmD;IACnD,IAAI,MAAM,EAAE,IAAI,KAAK,yBAAyB;QAAE,OAAO,IAAI,CAAC;IAE5D,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,yBAAyB,GAAoB;IAClD;;;;;OAKG;IACH,MAAM,CAAC,OAAO;QACb,MAAM,WAAW,GAAG,IAAI,KAAK,EAA0C,CAAC;QAExE;;;;WAIG;QACH,SAAS,YAAY,CAAC,IAAgD;YACrE,oCAAoC;YACpC,IAAI,gBAAgB,CAAC,IAAI,CAAC;gBAAE,OAAO;YAEnC,gDAAgD;YAChD,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACjC,OAAO,CAAC,MAAM,CAAC;oBACd,SAAS,EAAE,YAAY;oBACvB,IAAI;iBACJ,CAAC,CAAC;gBACH,OAAO;YACR,CAAC;YAED,2BAA2B;YAC3B,IAAI,eAAe,CAAC,IAAI,CAAC;gBAAE,OAAO;YAClC,OAAO,CAAC,MAAM,CAAC;gBACd,SAAS,EAAE,YAAY;gBACvB,IAAI;aACJ,CAAC,CAAC;QACJ,CAAC;QAED,OAAO;YACN,8DAA8D;YAC9D,kEAAkE,CAAC,IAAmB;gBACrF,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,uEAAuE;gBACtE,WAAW,CAAC,GAAG,EAAE,CAAC;YACnB,CAAC;YAED,qBAAqB;YACrB,UAAU,CAAC,IAAI;gBACd,YAAY,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;YAED,sBAAsB;YACtB,WAAW,CAAC,IAAI;gBACf,YAAY,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;SACD,CAAC;IACH,CAAC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,WAAW,EAAE,kEAAkE;YAC/E,WAAW,EAAE,KAAK;SAClB;QACD,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE;YACT,UAAU,EAAE,gEAAgE;SAC5E;QACD,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,SAAS;KACf;CACD,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "HowManySmall",
|
|
3
|
+
"description": "A bunch of lints to prevent idiot mistakes I encounter with frequency.",
|
|
4
|
+
"devDependencies": {
|
|
5
|
+
"@biomejs/biome": "^2.2.4",
|
|
6
|
+
"@mitata/counters": "^0.0.8",
|
|
7
|
+
"@types/bun": "1.2.22",
|
|
8
|
+
"@types/node": "^20.14.11",
|
|
9
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
10
|
+
"@typescript-eslint/types": "^8.0.0",
|
|
11
|
+
"@typescript-eslint/utils": "^8.0.0",
|
|
12
|
+
"eslint": "9.35.0",
|
|
13
|
+
"jiti": "^2.4.2",
|
|
14
|
+
"knip": "^5.63.1",
|
|
15
|
+
"mitata": "^1.0.34",
|
|
16
|
+
"oxlint": "^1.15.0",
|
|
17
|
+
"oxlint-tsgolint": "^0.2.0",
|
|
18
|
+
"typescript": "^5.6.3"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"bun": ">=1.1.0",
|
|
22
|
+
"node": ">=18.18"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"default": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": ["dist"],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"main": "./dist/index.js",
|
|
33
|
+
"name": "@pobammer-ts/eslint-cease-nonsense-rules",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
36
|
+
"@typescript-eslint/utils": "^8.0.0",
|
|
37
|
+
"eslint": "^9.35.0"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/howmanysmall/eslint-cease-nonsense-rules.git"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"add-tsgolint": "bun add -D oxlint-tsgolint@latest",
|
|
48
|
+
"biome": "bun x --bun biome lint",
|
|
49
|
+
"biome:ci": "bun x --bun biome ci",
|
|
50
|
+
"build": "bunx --bun tsc -p tsconfig.json",
|
|
51
|
+
"dev": "bunx --bun tsc -w",
|
|
52
|
+
"format": "bun x --bun. biome format --fix",
|
|
53
|
+
"format:report": "bun x --bun. biome format",
|
|
54
|
+
"lint": "bun x --bun oxlint . && bun x --bun biome lint .",
|
|
55
|
+
"oxc": "bun x --bun oxlint --type-aware",
|
|
56
|
+
"prepublishOnly": "bun run build",
|
|
57
|
+
"test": "bun test",
|
|
58
|
+
"typecheck": "bunx --bun tsc --noEmit"
|
|
59
|
+
},
|
|
60
|
+
"sideEffects": false,
|
|
61
|
+
"type": "module",
|
|
62
|
+
"types": "./dist/index.d.ts",
|
|
63
|
+
"version": "0.0.0"
|
|
64
|
+
}
|