@pobammer-ts/eslint-cease-nonsense-rules 1.15.0 → 1.17.1

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/README.md CHANGED
@@ -53,6 +53,7 @@ export default [
53
53
  "cease-nonsense/no-print": "error",
54
54
  "cease-nonsense/prefer-enum-item": "error",
55
55
  "cease-nonsense/no-shorthand-names": "error",
56
+ "cease-nonsense/no-unused-imports": "error",
56
57
  "cease-nonsense/no-useless-use-spring": "error",
57
58
  "cease-nonsense/no-warn": "error",
58
59
  "cease-nonsense/prefer-class-properties": "error",
@@ -64,10 +65,12 @@ export default [
64
65
  "cease-nonsense/prefer-singular-enums": "error",
65
66
  "cease-nonsense/prefer-udim2-shorthand": "error",
66
67
  "cease-nonsense/react-hooks-strict-return": "error",
68
+ "cease-nonsense/require-module-level-instantiation": "error",
67
69
  "cease-nonsense/require-named-effect-functions": "error",
68
70
  "cease-nonsense/require-paired-calls": "error",
69
71
  "cease-nonsense/require-react-component-keys": "error",
70
72
  "cease-nonsense/require-react-display-names": "error",
73
+ "cease-nonsense/prefer-read-only-props": "error",
71
74
  "cease-nonsense/strict-component-boundaries": "error",
72
75
  "cease-nonsense/use-exhaustive-dependencies": "error",
73
76
  "cease-nonsense/use-hook-at-top-level": "error",
@@ -171,7 +174,50 @@ const props: ImageProps = { ScaleType: 1 };
171
174
  <uiflexitem FlexMode={Enum.UIFlexMode.Fill} />
172
175
 
173
176
  // Explicit enum in object
174
- const props: ImageProps = { ScaleType: Enum.ScaleType.Slice };
177
+ const props: ImageProps = { ScaleType: Enum.ScaleType.Slice };
178
+ ```
179
+
180
+ #### `no-unused-imports`
181
+
182
+ Disallow unused imports. Uses ESLint's scope analysis to detect unused imports and optionally checks JSDoc comments for references.
183
+
184
+ **Configuration**
185
+
186
+ ```typescript
187
+ {
188
+ "cease-nonsense/no-unused-imports": ["error", {
189
+ "checkJSDoc": true // Check if imports are referenced in JSDoc comments
190
+ }]
191
+ }
192
+ ```
193
+
194
+ **Features**
195
+
196
+ - ✨ Has auto-fix
197
+ - Cached JSDoc comment parsing per file
198
+ - Pre-compiled regex patterns
199
+ - Efficient scope analysis using ESLint's built-in mechanisms
200
+
201
+ **❌ Bad**
202
+
203
+ ```typescript
204
+ import { unusedFunction } from "./utils";
205
+ import { AnotherUnused } from "./types";
206
+
207
+ // unusedFunction and AnotherUnused are never used
208
+ ```
209
+
210
+ **✅ Good**
211
+
212
+ ```typescript
213
+ import { usedFunction } from "./utils";
214
+
215
+ usedFunction();
216
+
217
+ // Or used in JSDoc
218
+ /**
219
+ * @see {usedFunction}
220
+ */
175
221
  ```
176
222
 
177
223
  ### React
@@ -594,6 +640,43 @@ ErrorBoundaryContext.displayName = "ErrorBoundaryContext";
594
640
  export default ErrorBoundaryContext;
595
641
  ```
596
642
 
643
+ #### `prefer-read-only-props`
644
+
645
+ Enforce that React component props are typed as `readonly` in TypeScript, preventing accidental mutation of props.
646
+
647
+ **Features**
648
+
649
+ - ✨ Has auto-fix
650
+ - Direct AST pattern matching (no global component analysis)
651
+ - Component detection caching
652
+ - Focused on common React component patterns
653
+
654
+ **❌ Bad**
655
+
656
+ ```typescript
657
+ interface Props {
658
+ name: string;
659
+ age: number;
660
+ }
661
+
662
+ function Component({ name, age }: Props) {
663
+ // ...
664
+ }
665
+ ```
666
+
667
+ **✅ Good**
668
+
669
+ ```typescript
670
+ interface Props {
671
+ readonly name: string;
672
+ readonly age: number;
673
+ }
674
+
675
+ function Component({ name, age }: Props) {
676
+ // ...
677
+ }
678
+ ```
679
+
597
680
  #### `react-hooks-strict-return`
598
681
 
599
682
  React hooks must return a tuple of ≤2 elements or a single object. Prevents unwieldy hook return types.
@@ -1001,6 +1084,48 @@ const doubled = items.map((x) => x * 2);
1001
1084
  }
1002
1085
  ```
1003
1086
 
1087
+ #### `prevent-abbreviations`
1088
+
1089
+ Prevent abbreviations in variable and property names. Provides suggestions for replacements and can automatically fix single-replacement cases.
1090
+
1091
+ **Configuration**
1092
+
1093
+ ```typescript
1094
+ {
1095
+ "cease-nonsense/prevent-abbreviations": ["error", {
1096
+ "checkFilenames": true,
1097
+ "checkProperties": false,
1098
+ "checkVariables": true,
1099
+ "replacements": {},
1100
+ "allowList": {},
1101
+ "ignore": []
1102
+ }]
1103
+ }
1104
+ ```
1105
+
1106
+ **Features**
1107
+
1108
+ - ✨ Has auto-fix (for single replacements)
1109
+ - Aggressive caching of word and name replacements
1110
+ - Pre-compiled regex patterns
1111
+ - Early exits for constants and allow-listed names
1112
+
1113
+ **❌ Bad**
1114
+
1115
+ ```typescript
1116
+ const err = new Error();
1117
+ const fn = () => {};
1118
+ const dist = calculateDistance();
1119
+ ```
1120
+
1121
+ **✅ Good**
1122
+
1123
+ ```typescript
1124
+ const error = new Error();
1125
+ const func = () => {};
1126
+ const distance = calculateDistance();
1127
+ ```
1128
+
1004
1129
  #### `no-shorthand-names`
1005
1130
 
1006
1131
  Bans shorthand variable names in favor of descriptive full names.
@@ -1408,6 +1533,48 @@ class MyClass {
1408
1533
  }
1409
1534
  ```
1410
1535
 
1536
+ #### `require-module-level-instantiation`
1537
+
1538
+ Require certain classes to be instantiated at module level rather than inside functions.
1539
+
1540
+ Classes like Log should be instantiated once at module scope, not recreated on every function call.
1541
+
1542
+ **Configuration**
1543
+
1544
+ ```typescript
1545
+ {
1546
+ "cease-nonsense/require-module-level-instantiation": ["error", {
1547
+ "classes": {
1548
+ "Log": "@rbxts/rbxts-sleitnick-log",
1549
+ "Server": "@rbxts/net"
1550
+ }
1551
+ }]
1552
+ }
1553
+ ```
1554
+
1555
+ **❌ Bad**
1556
+
1557
+ ```typescript
1558
+ import Log from "@rbxts/rbxts-sleitnick-log";
1559
+
1560
+ function useStoryModesState() {
1561
+ const log = new Log(); // Recreated on every call!
1562
+ log.Info("Create Match clicked");
1563
+ }
1564
+ ```
1565
+
1566
+ **✅ Good**
1567
+
1568
+ ```typescript
1569
+ import Log from "@rbxts/rbxts-sleitnick-log";
1570
+
1571
+ const log = new Log(); // Module level - created once
1572
+
1573
+ function useStoryModesState() {
1574
+ log.Info("Create Match clicked");
1575
+ }
1576
+ ```
1577
+
1411
1578
  ### Module Boundaries
1412
1579
 
1413
1580
  #### `strict-component-boundaries`
@@ -1450,6 +1617,83 @@ import { Foo } from "./components/Foo";
1450
1617
 
1451
1618
  ### TypeScript
1452
1619
 
1620
+ #### `naming-convention`
1621
+
1622
+ Enforce naming conventions for TypeScript constructs. Optimized for common use cases like interface prefix checking without requiring type checking.
1623
+
1624
+ **Configuration**
1625
+
1626
+ ```typescript
1627
+ {
1628
+ "cease-nonsense/naming-convention": ["error", {
1629
+ "custom": {
1630
+ "match": false,
1631
+ "regex": "^I[A-Z]"
1632
+ },
1633
+ "format": ["PascalCase"],
1634
+ "selector": "interface"
1635
+ }]
1636
+ }
1637
+ ```
1638
+
1639
+ **Features**
1640
+
1641
+ - No type checking required (fast AST-only analysis)
1642
+ - Pre-compiled regex patterns
1643
+ - Focused on common use cases
1644
+
1645
+ **❌ Bad**
1646
+
1647
+ ```typescript
1648
+ // With custom: { match: false, regex: "^I[A-Z]" }
1649
+ interface IUser {
1650
+ name: string;
1651
+ }
1652
+ ```
1653
+
1654
+ **✅ Good**
1655
+
1656
+ ```typescript
1657
+ interface User {
1658
+ name: string;
1659
+ }
1660
+ ```
1661
+
1662
+ #### `misleading-lua-tuple-checks`
1663
+
1664
+ Disallow the use of `LuaTuple` types directly in conditional expressions, which can be misleading. Requires explicit indexing (`[0]`) or array destructuring.
1665
+
1666
+ **Features**
1667
+
1668
+ - ✨ Has auto-fix
1669
+ - Cached type queries per node
1670
+ - WeakMap-based caching for `isLuaTuple` checks
1671
+ - Cached constrained type lookups
1672
+
1673
+ **❌ Bad**
1674
+
1675
+ ```typescript
1676
+ // Direct LuaTuple in conditional
1677
+ if (getLuaTuple()) {
1678
+ // ...
1679
+ }
1680
+
1681
+ // LuaTuple in variable declaration
1682
+ const result = getLuaTuple();
1683
+ ```
1684
+
1685
+ **✅ Good**
1686
+
1687
+ ```typescript
1688
+ // Explicit indexing
1689
+ if (getLuaTuple()[0]) {
1690
+ // ...
1691
+ }
1692
+
1693
+ // Array destructuring
1694
+ const [result] = getLuaTuple();
1695
+ ```
1696
+
1453
1697
  #### `prefer-pascal-case-enums`
1454
1698
 
1455
1699
  Enum names and members must be PascalCase.
@@ -1,5 +1,5 @@
1
1
  {
2
- "commit": "02202d06fed3e5ad1ec4ef66f32874643bcbaa18",
3
- "time": "2026-01-11T20:59:08.304Z",
4
- "version": "1.15.0"
2
+ "commit": "d246a17b975b5254d9495f55653c413b52eccfde",
3
+ "time": "2026-01-17T10:14:55.964Z",
4
+ "version": "1.17.1"
5
5
  }
package/dist/index.d.ts CHANGED
@@ -2,20 +2,24 @@ import type { LooseRuleDefinition } from "@typescript-eslint/utils/ts-eslint";
2
2
  import type { ReadonlyRecord } from "./types/utility-types.d";
3
3
  export type { BanInstancesOptions } from "./rules/ban-instances";
4
4
  export type { ComplexityConfiguration } from "./rules/enforce-ianitor-check-type";
5
+ export type { NamingConventionOptions } from "./rules/naming-convention";
5
6
  export type { NoGodComponentsOptions } from "./rules/no-god-components";
6
7
  export type { NoIdentityMapOptions } from "./rules/no-identity-map";
7
8
  export type { NoInstanceMethodsOptions } from "./rules/no-instance-methods-without-this";
8
9
  export type { NoMemoChildrenOptions } from "./rules/no-memo-children";
9
10
  export type { NoShorthandOptions } from "./rules/no-shorthand-names";
11
+ export type { NoUnusedImportsOptions } from "./rules/no-unused-imports";
10
12
  export type { NoUselessUseSpringOptions } from "./rules/no-useless-use-spring";
11
13
  export type { PreferEnumItemOptions } from "./rules/prefer-enum-item";
14
+ export type { PreventAbbreviationsOptions } from "./rules/prevent-abbreviations";
15
+ export type { RequireModuleLevelInstantiationOptions } from "./rules/require-module-level-instantiation";
12
16
  export type { EffectFunctionOptions, HookConfiguration } from "./rules/require-named-effect-functions";
13
17
  export type { PairConfiguration, RequirePairedCallsOptions } from "./rules/require-paired-calls";
14
18
  export type { ReactKeysOptions } from "./rules/require-react-component-keys";
15
19
  export type { RequireReactDisplayNamesOptions } from "./rules/require-react-display-names";
16
20
  export type { HookEntry, UseExhaustiveDependenciesOptions } from "./rules/use-exhaustive-dependencies";
17
21
  export type { EnvironmentMode } from "./types/environment-mode";
18
- export { createBanInstancesOptions, createComplexityConfiguration, createEffectFunctionOptions, createHookConfiguration, createNoGodComponentsOptions, createNoInstanceMethodsOptions, createNoMemoChildrenOptions, createNoShorthandOptions, createNoUselessUseSpringOptions, createPairConfiguration, createPreferPatternReplacementsOptions, createReactKeysOptions, createRequirePairedCallsOptions, createRequireReactDisplayNamesOptions, createUseExhaustiveDependenciesOptions, createUseHookAtTopLevelOptions, defaultRobloxProfilePair, } from "./utilities/configure-utilities";
22
+ export { createBanInstancesOptions, createComplexityConfiguration, createEffectFunctionOptions, createHookConfiguration, createNamingConventionOptions, createNoGodComponentsOptions, createNoInstanceMethodsOptions, createNoMemoChildrenOptions, createNoShorthandOptions, createNoUnusedImportsOptions, createNoUselessUseSpringOptions, createPairConfiguration, createPreferEnumItemOptions, createPreferPatternReplacementsOptions, createPreventAbbreviationsOptions, createReactKeysOptions, createRequireModuleLevelInstantiationOptions, createRequirePairedCallsOptions, createRequireReactDisplayNamesOptions, createUseExhaustiveDependenciesOptions, createUseHookAtTopLevelOptions, defaultRobloxProfilePair, } from "./utilities/configure-utilities";
19
23
  export type { Pattern, PreferPatternReplacementsOptions } from "./utilities/pattern-replacement";
20
24
  export { pattern } from "./utilities/pattern-replacement";
21
25
  /**
@@ -44,6 +48,7 @@ declare const recommended: {
44
48
  readonly "cease-nonsense/ban-react-fc": "error";
45
49
  readonly "cease-nonsense/enforce-ianitor-check-type": "error";
46
50
  readonly "cease-nonsense/fast-format": "error";
51
+ readonly "cease-nonsense/misleading-lua-tuple-checks": "error";
47
52
  readonly "cease-nonsense/no-async-constructor": "error";
48
53
  readonly "cease-nonsense/no-color3-constructor": "error";
49
54
  readonly "cease-nonsense/no-god-components": "error";
@@ -52,7 +57,9 @@ declare const recommended: {
52
57
  readonly "cease-nonsense/no-memo-children": "error";
53
58
  readonly "cease-nonsense/no-print": "error";
54
59
  readonly "cease-nonsense/no-shorthand-names": "error";
60
+ readonly "cease-nonsense/no-unused-imports": "error";
55
61
  readonly "cease-nonsense/no-warn": "error";
62
+ readonly "cease-nonsense/prefer-read-only-props": "error";
56
63
  readonly "cease-nonsense/prefer-sequence-overloads": "error";
57
64
  readonly "cease-nonsense/prefer-udim2-shorthand": "error";
58
65
  readonly "cease-nonsense/require-named-effect-functions": "error";