@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 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
@@ -0,0 +1,5 @@
1
+ # eslint-cease-nonsense-rules
2
+
3
+ A bunch of lints to prevent idiot mistakes I encounter with frequency.
4
+
5
+ Note: You said to create a README now; if you'd like a different structure or badges, say so and I’ll update it.
@@ -0,0 +1,9 @@
1
+ import type { Linter, Rule } from "eslint";
2
+ interface Plugin {
3
+ readonly rules: Readonly<Record<string, Rule.RuleModule>>;
4
+ readonly configs: Readonly<{
5
+ readonly recommended: Linter.Config;
6
+ }>;
7
+ }
8
+ declare const plugin: Plugin;
9
+ export default plugin;
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,3 @@
1
+ import type { Rule } from "eslint";
2
+ declare const enforceIanitorCheckType: Rule.RuleModule;
3
+ export default enforceIanitorCheckType;
@@ -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":"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"}
@@ -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,3 @@
1
+ import type { Rule } from "eslint";
2
+ declare const requireReactComponentKeys: Rule.RuleModule;
3
+ export default requireReactComponentKeys;
@@ -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
+ }