eslint-plugin-wyrm 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +114 -78
  3. package/bin/wyrm.mjs +3 -0
  4. package/dist/_virtual/_rolldown/runtime.mjs +7 -13
  5. package/dist/cli.d.mts +1 -0
  6. package/dist/cli.mjs +23 -0
  7. package/dist/configs/index.mjs +1 -3
  8. package/dist/index.mjs +1 -3
  9. package/dist/plugin.mjs +1 -3
  10. package/dist/rules/array-from-array.d.mts +9 -0
  11. package/dist/rules/array-from-array.mjs +56 -0
  12. package/dist/rules/as-unknown-as.d.mts +9 -0
  13. package/dist/rules/as-unknown-as.mjs +30 -0
  14. package/dist/rules/await-promise-resolve.d.mts +9 -0
  15. package/dist/rules/await-promise-resolve.mjs +41 -0
  16. package/dist/rules/boolean-coalescing.d.mts +9 -0
  17. package/dist/rules/boolean-coalescing.mjs +141 -0
  18. package/dist/rules/comment-duplicate-leading-space.d.mts +9 -0
  19. package/dist/rules/comment-duplicate-leading-space.mjs +34 -0
  20. package/dist/rules/conditional-boolean.d.mts +9 -0
  21. package/dist/rules/conditional-boolean.mjs +70 -0
  22. package/dist/rules/constant-boolean-cast.d.mts +9 -0
  23. package/dist/rules/constant-boolean-cast.mjs +203 -0
  24. package/dist/rules/de-morgan.d.mts +2 -2
  25. package/dist/rules/de-morgan.mjs +1 -3
  26. package/dist/rules/discarded-expression-statement.d.mts +14 -0
  27. package/dist/rules/discarded-expression-statement.mjs +243 -0
  28. package/dist/rules/distribute-boolean-casts.d.mts +2 -2
  29. package/dist/rules/distribute-boolean-casts.mjs +3 -3
  30. package/dist/rules/duplicate-destructuring.d.mts +2 -2
  31. package/dist/rules/duplicate-destructuring.mjs +1 -3
  32. package/dist/rules/duplicate-object-spread.d.mts +9 -0
  33. package/dist/rules/duplicate-object-spread.mjs +44 -0
  34. package/dist/rules/e.d.mts +3 -3
  35. package/dist/rules/e.mjs +4 -3
  36. package/dist/rules/empty-for.d.mts +9 -0
  37. package/dist/rules/empty-for.mjs +34 -0
  38. package/dist/rules/enum-member.d.mts +9 -0
  39. package/dist/rules/enum-member.mjs +51 -0
  40. package/dist/rules/eqeq-null.d.mts +9 -0
  41. package/dist/rules/eqeq-null.mjs +101 -0
  42. package/dist/rules/exact-string-regex.d.mts +2 -2
  43. package/dist/rules/exact-string-regex.mjs +1 -3
  44. package/dist/rules/export-using.mjs +1 -3
  45. package/dist/rules/generic-constructor-with-hook.d.mts +3 -3
  46. package/dist/rules/generic-constructor-with-hook.mjs +1 -3
  47. package/dist/rules/idiomatic-cast.mjs +6 -8
  48. package/dist/rules/index.d.mts +112 -77
  49. package/dist/rules/index.mjs +71 -3
  50. package/dist/rules/inferable-type-predicate.d.mts +9 -0
  51. package/dist/rules/inferable-type-predicate.mjs +100 -0
  52. package/dist/rules/inner-as-const.d.mts +9 -0
  53. package/dist/rules/inner-as-const.mjs +70 -0
  54. package/dist/rules/jsx-tostring.d.mts +9 -0
  55. package/dist/rules/jsx-tostring.mjs +120 -0
  56. package/dist/rules/literal-destructuring.d.mts +9 -0
  57. package/dist/rules/literal-destructuring.mjs +102 -0
  58. package/dist/rules/named-export-with-side-effects.d.mts +3 -3
  59. package/dist/rules/named-export-with-side-effects.mjs +1 -3
  60. package/dist/rules/nested-reduce.d.mts +9 -0
  61. package/dist/rules/nested-reduce.mjs +46 -0
  62. package/dist/rules/nested-try-catch.d.mts +9 -0
  63. package/dist/rules/nested-try-catch.mjs +37 -0
  64. package/dist/rules/no-commented-out-comment.d.mts +2 -2
  65. package/dist/rules/no-commented-out-comment.mjs +1 -3
  66. package/dist/rules/no-constant-template-expression.mjs +9 -6
  67. package/dist/rules/no-constructed-error-cause.d.mts +2 -2
  68. package/dist/rules/no-constructed-error-cause.mjs +1 -3
  69. package/dist/rules/no-convoluted-boolean-expressions.d.mts +9 -0
  70. package/dist/rules/no-convoluted-boolean-expressions.mjs +130 -0
  71. package/dist/rules/no-convoluted-logical-expressions.d.mts +2 -2
  72. package/dist/rules/no-convoluted-logical-expressions.mjs +1 -3
  73. package/dist/rules/no-custom-url-parsing.d.mts +2 -2
  74. package/dist/rules/no-custom-url-parsing.mjs +1 -3
  75. package/dist/rules/no-disallowed-warning-comments.d.mts +2 -2
  76. package/dist/rules/no-disallowed-warning-comments.mjs +1 -3
  77. package/dist/rules/no-duplicated-return.d.mts +2 -2
  78. package/dist/rules/no-duplicated-return.mjs +1 -3
  79. package/dist/rules/no-else-break.d.mts +2 -2
  80. package/dist/rules/no-else-break.mjs +1 -3
  81. package/dist/rules/no-else-continue.d.mts +2 -2
  82. package/dist/rules/no-else-continue.mjs +1 -3
  83. package/dist/rules/no-else-never.d.mts +9 -0
  84. package/dist/rules/no-else-never.mjs +75 -0
  85. package/dist/rules/no-else-return.d.mts +2 -2
  86. package/dist/rules/no-else-return.mjs +1 -3
  87. package/dist/rules/no-else-throw.d.mts +2 -2
  88. package/dist/rules/no-else-throw.mjs +1 -3
  89. package/dist/rules/no-empty-attribute.d.mts +3 -3
  90. package/dist/rules/no-empty-attribute.mjs +1 -3
  91. package/dist/rules/no-empty-comment.d.mts +3 -3
  92. package/dist/rules/no-empty-comment.mjs +1 -3
  93. package/dist/rules/no-empty-jsx-expression.d.mts +2 -2
  94. package/dist/rules/no-empty-jsx-expression.mjs +1 -3
  95. package/dist/rules/no-empty-literal-iteration.d.mts +2 -2
  96. package/dist/rules/no-empty-literal-iteration.mjs +1 -3
  97. package/dist/rules/no-extra-false-fallback.d.mts +2 -2
  98. package/dist/rules/no-extra-false-fallback.mjs +1 -3
  99. package/dist/rules/no-extra-nested-boolean-cast.d.mts +2 -2
  100. package/dist/rules/no-extra-nested-boolean-cast.mjs +2 -3
  101. package/dist/rules/no-first-last.d.mts +2 -2
  102. package/dist/rules/no-first-last.mjs +2 -4
  103. package/dist/rules/no-float-length-check.d.mts +2 -2
  104. package/dist/rules/no-float-length-check.mjs +1 -3
  105. package/dist/rules/no-huge-try-block.d.mts +3 -3
  106. package/dist/rules/no-huge-try-block.mjs +1 -3
  107. package/dist/rules/no-huge-useeffect.d.mts +3 -3
  108. package/dist/rules/no-huge-useeffect.mjs +1 -3
  109. package/dist/rules/no-if-length-for.d.mts +2 -2
  110. package/dist/rules/no-if-length-for.mjs +1 -3
  111. package/dist/rules/no-inline-jsdoc-tag.d.mts +3 -3
  112. package/dist/rules/no-inline-jsdoc-tag.mjs +1 -3
  113. package/dist/rules/no-invalid-date-literal.d.mts +2 -2
  114. package/dist/rules/no-invalid-date-literal.mjs +1 -3
  115. package/dist/rules/no-jsx-statement.d.mts +2 -2
  116. package/dist/rules/no-jsx-statement.mjs +1 -3
  117. package/dist/rules/no-lax-array-type.mjs +7 -9
  118. package/dist/rules/no-lax-return-type.mjs +7 -8
  119. package/dist/rules/no-mutable-literal-fill.d.mts +2 -2
  120. package/dist/rules/no-mutable-literal-fill.mjs +1 -3
  121. package/dist/rules/no-nullish-ternary.d.mts +9 -0
  122. package/dist/rules/no-nullish-ternary.mjs +121 -0
  123. package/dist/rules/no-numbered-comments.d.mts +2 -2
  124. package/dist/rules/no-numbered-comments.mjs +1 -3
  125. package/dist/rules/no-obvious-any.mjs +9 -12
  126. package/dist/rules/no-optional-type-guard-param.d.mts +2 -2
  127. package/dist/rules/no-optional-type-guard-param.mjs +1 -3
  128. package/dist/rules/no-out-of-order-comments.d.mts +2 -2
  129. package/dist/rules/no-out-of-order-comments.mjs +3 -8
  130. package/dist/rules/no-possibly-nullish-equality.mjs +6 -12
  131. package/dist/rules/no-redundant-function-declaration.d.mts +2 -2
  132. package/dist/rules/no-redundant-function-declaration.mjs +1 -3
  133. package/dist/rules/no-return-to-void.mjs +1 -3
  134. package/dist/rules/no-self-object-assign.d.mts +2 -2
  135. package/dist/rules/no-self-object-assign.mjs +1 -3
  136. package/dist/rules/no-sloppy-length-check.d.mts +2 -2
  137. package/dist/rules/no-sloppy-length-check.mjs +25 -27
  138. package/dist/rules/no-suspicious-jsx-semicolon.d.mts +2 -2
  139. package/dist/rules/no-suspicious-jsx-semicolon.mjs +2 -4
  140. package/dist/rules/no-ternary-return.d.mts +3 -3
  141. package/dist/rules/no-ternary-return.mjs +1 -3
  142. package/dist/rules/no-type-guard.d.mts +9 -0
  143. package/dist/rules/no-type-guard.mjs +36 -0
  144. package/dist/rules/no-unassigned-todo.d.mts +2 -2
  145. package/dist/rules/no-unassigned-todo.mjs +1 -3
  146. package/dist/rules/no-unbound-catch-error.d.mts +2 -2
  147. package/dist/rules/no-unbound-catch-error.mjs +1 -3
  148. package/dist/rules/no-unused-mutually-referential.mjs +10 -15
  149. package/dist/rules/no-unused-param-read.d.mts +2 -2
  150. package/dist/rules/no-unused-param-read.mjs +1 -3
  151. package/dist/rules/no-useless-computed-key.d.mts +2 -2
  152. package/dist/rules/no-useless-computed-key.mjs +1 -3
  153. package/dist/rules/no-useless-iife.d.mts +2 -2
  154. package/dist/rules/no-useless-iife.mjs +2 -3
  155. package/dist/rules/no-useless-logical-fallback.mjs +7 -12
  156. package/dist/rules/no-useless-return-undefined.mjs +1 -3
  157. package/dist/rules/no-useless-ts-check.d.mts +2 -2
  158. package/dist/rules/no-useless-ts-check.mjs +1 -3
  159. package/dist/rules/no-useless-use-strict.d.mts +2 -2
  160. package/dist/rules/no-useless-use-strict.mjs +1 -3
  161. package/dist/rules/no-useless-usememo.d.mts +2 -2
  162. package/dist/rules/no-useless-usememo.mjs +1 -3
  163. package/dist/rules/no-whitespace-property.d.mts +2 -2
  164. package/dist/rules/no-whitespace-property.mjs +1 -3
  165. package/dist/rules/nullish-object-spread.d.mts +2 -2
  166. package/dist/rules/nullish-object-spread.mjs +7 -6
  167. package/dist/rules/optional-call-expression.d.mts +2 -2
  168. package/dist/rules/optional-call-expression.mjs +1 -3
  169. package/dist/rules/prefer-array-from.d.mts +9 -0
  170. package/dist/rules/prefer-array-from.mjs +87 -0
  171. package/dist/rules/prefer-catch-method.d.mts +2 -2
  172. package/dist/rules/prefer-catch-method.mjs +2 -3
  173. package/dist/rules/prefer-early-return.d.mts +2 -2
  174. package/dist/rules/prefer-early-return.mjs +1 -3
  175. package/dist/rules/prefer-eqeq-null.d.mts +9 -0
  176. package/dist/rules/prefer-eqeq-null.mjs +122 -0
  177. package/dist/rules/prefer-finally.d.mts +2 -2
  178. package/dist/rules/prefer-finally.mjs +1 -3
  179. package/dist/rules/prefer-getorinsert.d.mts +2 -2
  180. package/dist/rules/prefer-getorinsert.mjs +1 -3
  181. package/dist/rules/prefer-has.d.mts +2 -2
  182. package/dist/rules/prefer-has.mjs +1 -3
  183. package/dist/rules/prefer-in.d.mts +9 -0
  184. package/dist/rules/prefer-in.mjs +81 -0
  185. package/dist/rules/prefer-object-keys-values.d.mts +2 -2
  186. package/dist/rules/prefer-object-keys-values.mjs +1 -3
  187. package/dist/rules/prefer-repeat.d.mts +2 -2
  188. package/dist/rules/prefer-repeat.mjs +1 -3
  189. package/dist/rules/prefer-satisfies.d.mts +9 -0
  190. package/dist/rules/prefer-satisfies.mjs +86 -0
  191. package/dist/rules/prefer-string-join.d.mts +9 -0
  192. package/dist/rules/prefer-string-join.mjs +67 -0
  193. package/dist/rules/primitive-valueof.mjs +6 -8
  194. package/dist/rules/slim-try.d.mts +2 -2
  195. package/dist/rules/slim-try.mjs +9 -11
  196. package/dist/rules/styled-button-has-type.d.mts +9 -0
  197. package/dist/rules/styled-button-has-type.mjs +82 -0
  198. package/dist/rules/styled-transient-props.d.mts +9 -0
  199. package/dist/rules/styled-transient-props.mjs +52 -0
  200. package/dist/rules/suspicious-map-length.d.mts +2 -2
  201. package/dist/rules/suspicious-map-length.mjs +1 -3
  202. package/dist/rules/template-tostring.d.mts +9 -0
  203. package/dist/rules/template-tostring.mjs +48 -0
  204. package/dist/rules/unsafe-asserted-chain.mjs +5 -7
  205. package/dist/rules/unused-object-assign.d.mts +2 -2
  206. package/dist/rules/unused-object-assign.mjs +1 -3
  207. package/dist/rules/unused-object-freeze.d.mts +9 -0
  208. package/dist/rules/unused-object-freeze.mjs +37 -0
  209. package/dist/rules/useless-as-const.d.mts +9 -0
  210. package/dist/rules/useless-as-const.mjs +59 -0
  211. package/dist/rules/useless-assign.d.mts +11 -0
  212. package/dist/rules/useless-assign.mjs +69 -0
  213. package/dist/rules/useless-conditional-assign.d.mts +9 -0
  214. package/dist/rules/useless-conditional-assign.mjs +58 -0
  215. package/dist/rules/useless-intermediary-variable.mjs +1 -3
  216. package/dist/rules/useless-mock.d.mts +9 -0
  217. package/dist/rules/useless-mock.mjs +180 -0
  218. package/dist/rules/useless-required.mjs +10 -12
  219. package/dist/utils/compareTokens.mjs +1 -3
  220. package/dist/utils/createRule.mjs +1 -3
  221. package/dist/utils/negateExpression.mjs +1 -3
  222. package/dist/utils/option.mjs +1 -2
  223. package/package.json +29 -23
@@ -0,0 +1,243 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
+ import ts from "typescript";
5
+ //#region lib/rules/discarded-expression-statement.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ const DEFAULT_IGNORE_PROMISES = true;
8
+ const DEFAULT_IGNORED_FUNCTIONS = [];
9
+ const DEFAULT_IGNORED_OBJECTS = [];
10
+ const DEFAULT_IGNORED_METHODS = [];
11
+ var discarded_expression_statement_default = createRule({
12
+ name,
13
+ meta: {
14
+ type: "problem",
15
+ docs: {
16
+ description: "Forbid discarding the result of expression statements",
17
+ pedantic: true,
18
+ requiresTypeChecking: true
19
+ },
20
+ schema: [{
21
+ type: "object",
22
+ properties: {
23
+ ignorePromises: {
24
+ description: `Whether to ignore floating promises. Default: \`${DEFAULT_IGNORE_PROMISES}\``,
25
+ type: "boolean"
26
+ },
27
+ ignoredFunctions: {
28
+ description: `Names of functions to ignore. Default: \`${JSON.stringify(DEFAULT_IGNORED_FUNCTIONS)}\``,
29
+ type: "array",
30
+ items: { type: "string" }
31
+ },
32
+ ignoredObjects: {
33
+ description: `Names of objects to ignore in method calls. Default: \`${JSON.stringify(DEFAULT_IGNORED_OBJECTS)}\``,
34
+ type: "array",
35
+ items: { type: "string" }
36
+ },
37
+ ignoredMethods: {
38
+ description: `Names of methods to ignore. Default: \`${JSON.stringify(DEFAULT_IGNORED_METHODS)}\``,
39
+ type: "array",
40
+ items: { type: "string" }
41
+ }
42
+ }
43
+ }],
44
+ messages: { unusedExpression: "This expression is unused." }
45
+ },
46
+ defaultOptions: [{
47
+ ignorePromises: DEFAULT_IGNORE_PROMISES,
48
+ ignoredFunctions: DEFAULT_IGNORED_FUNCTIONS,
49
+ ignoredObjects: DEFAULT_IGNORED_OBJECTS,
50
+ ignoredMethods: DEFAULT_IGNORED_METHODS
51
+ }],
52
+ create(context, [options]) {
53
+ let services;
54
+ function getServices() {
55
+ services ??= ESLintUtils.getParserServices(context);
56
+ return services;
57
+ }
58
+ let checker;
59
+ function getChecker() {
60
+ checker ??= getServices().program.getTypeChecker();
61
+ return checker;
62
+ }
63
+ const windowMethods = [
64
+ "open",
65
+ "requestAnimationFrame",
66
+ "setInterval",
67
+ "setTimeout"
68
+ ];
69
+ const ALWAYS_ALLOWED_FUNCTIONS = [
70
+ ...windowMethods,
71
+ "describe",
72
+ "onRefetch",
73
+ "refetch",
74
+ "render",
75
+ "set",
76
+ "setInterval",
77
+ "setTimeout"
78
+ ];
79
+ const dateMethods = [
80
+ "setDate",
81
+ "setFullYear",
82
+ "setHours",
83
+ "setMilliseconds",
84
+ "setMinutes",
85
+ "setMonth",
86
+ "setSeconds",
87
+ "setTime",
88
+ "setUTCDate",
89
+ "setUTCFullYear",
90
+ "setUTCHours",
91
+ "setUTCMilliseconds",
92
+ "setUTCMinutes",
93
+ "setUTCMonth",
94
+ "setUTCSeconds"
95
+ ];
96
+ const testingMethods = [
97
+ "mock",
98
+ "mockClear",
99
+ "mockImplementation",
100
+ "spyOn",
101
+ "unmock"
102
+ ];
103
+ const testingLibraryQueries = [
104
+ "ByRole",
105
+ "ByLabelText",
106
+ "ByPlaceholderText",
107
+ "ByText",
108
+ "ByDisplayValue",
109
+ "ByAltText",
110
+ "ByTitle",
111
+ "ByTestId"
112
+ ];
113
+ const testingLibraryMethodsPrefixes = [
114
+ "get",
115
+ "query",
116
+ "getAll",
117
+ "queryAll",
118
+ "find",
119
+ "findAll"
120
+ ];
121
+ const testingLibraryMethods = testingLibraryQueries.flatMap((query) => testingLibraryMethodsPrefixes.map((prefix) => `${prefix}${query}`));
122
+ const ALWAYS_ALLOWED_METHODS = [
123
+ "add",
124
+ "assign",
125
+ "defineProperties",
126
+ "defineProperty",
127
+ "delete",
128
+ "fill",
129
+ "freeze",
130
+ "measure",
131
+ "open",
132
+ "pop",
133
+ "push",
134
+ "reduce",
135
+ "set",
136
+ "setQueryData",
137
+ "splice",
138
+ "unshift",
139
+ ...dateMethods,
140
+ ...windowMethods,
141
+ ...testingMethods,
142
+ ...testingLibraryMethods
143
+ ];
144
+ const allowedFunctions = new Set([...options.ignoredFunctions, ...ALWAYS_ALLOWED_FUNCTIONS]);
145
+ const allowedObjects = new Set(options.ignoredObjects);
146
+ const allowedMethods = new Set([...options.ignoredMethods, ...ALWAYS_ALLOWED_METHODS]);
147
+ return { ExpressionStatement(stmt) {
148
+ const expr = stmt.expression;
149
+ switch (expr.type) {
150
+ case AST_NODE_TYPES.AssignmentExpression:
151
+ case AST_NODE_TYPES.BinaryExpression:
152
+ case AST_NODE_TYPES.ConditionalExpression:
153
+ case AST_NODE_TYPES.LogicalExpression:
154
+ case AST_NODE_TYPES.NewExpression:
155
+ case AST_NODE_TYPES.SequenceExpression:
156
+ case AST_NODE_TYPES.TSSatisfiesExpression:
157
+ case AST_NODE_TYPES.UpdateExpression:
158
+ case AST_NODE_TYPES.YieldExpression:
159
+ case AST_NODE_TYPES.ArrayExpression:
160
+ case AST_NODE_TYPES.ArrayPattern:
161
+ case AST_NODE_TYPES.ArrowFunctionExpression:
162
+ case AST_NODE_TYPES.ClassExpression:
163
+ case AST_NODE_TYPES.FunctionExpression:
164
+ case AST_NODE_TYPES.Identifier:
165
+ case AST_NODE_TYPES.ImportExpression:
166
+ case AST_NODE_TYPES.JSXElement:
167
+ case AST_NODE_TYPES.JSXFragment:
168
+ case AST_NODE_TYPES.MemberExpression:
169
+ case AST_NODE_TYPES.MetaProperty:
170
+ case AST_NODE_TYPES.ObjectExpression:
171
+ case AST_NODE_TYPES.ObjectPattern:
172
+ case AST_NODE_TYPES.Super:
173
+ case AST_NODE_TYPES.TaggedTemplateExpression:
174
+ case AST_NODE_TYPES.TemplateLiteral:
175
+ case AST_NODE_TYPES.ThisExpression:
176
+ case AST_NODE_TYPES.TSAsExpression:
177
+ case AST_NODE_TYPES.TSInstantiationExpression:
178
+ case AST_NODE_TYPES.TSNonNullExpression:
179
+ case AST_NODE_TYPES.TSTypeAssertion: return;
180
+ case AST_NODE_TYPES.UnaryExpression:
181
+ if (expr.operator === "delete" || expr.operator === "void") return;
182
+ break;
183
+ case AST_NODE_TYPES.Literal:
184
+ if (typeof expr.value === "string" && expr.value.startsWith("use ")) return;
185
+ break;
186
+ case AST_NODE_TYPES.CallExpression:
187
+ if (shouldIgnoreCallExpression(expr, allowedFunctions, allowedObjects, allowedMethods)) return;
188
+ break;
189
+ case AST_NODE_TYPES.ChainExpression:
190
+ if (expr.expression.type !== AST_NODE_TYPES.CallExpression) break;
191
+ if (shouldIgnoreCallExpression(expr.expression, allowedFunctions, allowedObjects, allowedMethods)) return;
192
+ break;
193
+ case AST_NODE_TYPES.AwaitExpression:
194
+ if (expr.argument.type !== AST_NODE_TYPES.CallExpression) break;
195
+ if (shouldIgnoreCallExpression(expr.argument, allowedFunctions, allowedObjects, allowedMethods)) return;
196
+ break;
197
+ default: break;
198
+ }
199
+ if (isVoidExpr(stmt.expression)) return;
200
+ context.report({
201
+ node: stmt.expression,
202
+ messageId: "unusedExpression"
203
+ });
204
+ } };
205
+ function isVoidExpr(expression) {
206
+ const type = getServices().getTypeAtLocation(expression);
207
+ if (isVoidType(type)) return true;
208
+ if (expression.type === AST_NODE_TYPES.CallExpression && expression.callee.type === AST_NODE_TYPES.MemberExpression) {
209
+ const objectType = getServices().getTypeAtLocation(expression.callee.object);
210
+ if (getChecker().isTypeAssignableTo(type, objectType)) return true;
211
+ }
212
+ return false;
213
+ }
214
+ function isVoidType(type) {
215
+ if (type.isUnionOrIntersection()) {
216
+ if (options.ignorePromises && type.types.some((t) => isPromiseType(t))) return true;
217
+ return type.types.every((t) => isVoidType(t));
218
+ }
219
+ if (getChecker().isArrayType(type) || getChecker().isTupleType(type)) return getChecker().getTypeArguments(type).every((t) => isVoidType(t));
220
+ if (options.ignorePromises && isPromiseType(type)) return true;
221
+ const flags = ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Null | ts.TypeFlags.Unknown | ts.TypeFlags.Any;
222
+ return (type.getFlags() & flags) !== 0;
223
+ }
224
+ }
225
+ });
226
+ function isPromiseType(type) {
227
+ return type.getSymbol()?.getName() === "Promise";
228
+ }
229
+ function shouldIgnoreCallExpression(expr, allowedFunctions, allowedObjects, allowedMethods) {
230
+ switch (expr.callee.type) {
231
+ case AST_NODE_TYPES.Identifier: return allowedFunctions.has(expr.callee.name);
232
+ case AST_NODE_TYPES.MemberExpression: {
233
+ const obj = expr.callee.object;
234
+ const isAllowedObject = obj.type === AST_NODE_TYPES.Identifier && allowedObjects.has(obj.name);
235
+ const prop = expr.callee.property;
236
+ const isAllowedMethod = prop.type === AST_NODE_TYPES.Identifier && allowedMethods.has(prop.name);
237
+ return isAllowedObject || isAllowedMethod;
238
+ }
239
+ default: return false;
240
+ }
241
+ }
242
+ //#endregion
243
+ export { discarded_expression_statement_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/distribute-boolean-casts.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint0.RuleModule<"distributeBooleanCast", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint0.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"distributeBooleanCast", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
6
  name: string;
7
7
  };
8
8
  //#endregion
@@ -2,7 +2,6 @@ import { createRule } from "../utils/createRule.mjs";
2
2
  import { None, Some } from "../utils/option.mjs";
3
3
  import path from "node:path";
4
4
  import { AST_NODE_TYPES } from "@typescript-eslint/utils";
5
-
6
5
  //#region lib/rules/distribute-boolean-casts.ts
7
6
  const { name } = path.parse(import.meta.filename);
8
7
  var distribute_boolean_casts_default = createRule({
@@ -53,7 +52,9 @@ var distribute_boolean_casts_default = createRule({
53
52
  function isBooleanLike(expr) {
54
53
  if (expr.type === AST_NODE_TYPES.UnaryExpression) return expr.operator === "!";
55
54
  if (expr.type === AST_NODE_TYPES.BinaryExpression) switch (expr.operator) {
55
+ /* v8 ignore next -- @preserve */
56
56
  case "&&": return true;
57
+ /* v8 ignore next -- @preserve */
57
58
  case "||": return true;
58
59
  case "!=":
59
60
  case "!==":
@@ -86,6 +87,5 @@ function isBooleanCall(node) {
86
87
  if (node.callee.name !== "Boolean") return false;
87
88
  return true;
88
89
  }
89
-
90
90
  //#endregion
91
- export { distribute_boolean_casts_default as default };
91
+ export { distribute_boolean_casts_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/duplicate-destructuring.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint0.RuleModule<"duplicateKey", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint0.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"duplicateKey", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
6
  name: string;
7
7
  };
8
8
  //#endregion
@@ -1,7 +1,6 @@
1
1
  import { createRule } from "../utils/createRule.mjs";
2
2
  import path from "node:path";
3
3
  import { AST_NODE_TYPES } from "@typescript-eslint/utils";
4
-
5
4
  //#region lib/rules/duplicate-destructuring.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  var duplicate_destructuring_default = createRule({
@@ -41,6 +40,5 @@ function extractKeyValue(key) {
41
40
  if (key.value === null) return "null";
42
41
  return key.value.toString();
43
42
  }
44
-
45
43
  //#endregion
46
- export { duplicate_destructuring_default as default };
44
+ export { duplicate_destructuring_default as default };
@@ -0,0 +1,9 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
+
4
+ //#region lib/rules/duplicate-object-spread.d.ts
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"duplicateSpread", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,44 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { AST_NODE_TYPES, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
4
+ //#region lib/rules/duplicate-object-spread.ts
5
+ const { name } = path.parse(import.meta.filename);
6
+ var duplicate_object_spread_default = createRule({
7
+ name,
8
+ meta: {
9
+ type: "suggestion",
10
+ docs: {
11
+ description: "Forbid duplicate spread elements in object literals",
12
+ recommended: true
13
+ },
14
+ fixable: "code",
15
+ schema: [],
16
+ messages: { duplicateSpread: "This variable is already spread into the object literal" }
17
+ },
18
+ defaultOptions: [],
19
+ create(context) {
20
+ return { ObjectExpression(node) {
21
+ const seen = /* @__PURE__ */ new Set();
22
+ for (const prop of node.properties) {
23
+ if (prop.type !== AST_NODE_TYPES.SpreadElement) continue;
24
+ if (prop.argument.type !== AST_NODE_TYPES.Identifier) continue;
25
+ const value = prop.argument.name;
26
+ if (!seen.has(value)) {
27
+ seen.add(value);
28
+ continue;
29
+ }
30
+ context.report({
31
+ node: prop,
32
+ messageId: "duplicateSpread",
33
+ *fix(fixer) {
34
+ yield fixer.remove(prop);
35
+ const commaToken = context.sourceCode.getTokenAfter(prop);
36
+ if (commaToken?.type === AST_TOKEN_TYPES.Punctuator && commaToken.value === ",") yield fixer.remove(commaToken);
37
+ }
38
+ });
39
+ }
40
+ } };
41
+ }
42
+ });
43
+ //#endregion
44
+ export { duplicate_object_spread_default as default };
@@ -1,10 +1,10 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/e.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint0.RuleModule<"noE" | "useOther", [{
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noE" | "useOther", [{
6
6
  alternatives: string[];
7
- }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint0.RuleListener> & {
7
+ }], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
8
8
  name: string;
9
9
  };
10
10
  //#endregion
package/dist/rules/e.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import { createRule } from "../utils/createRule.mjs";
2
2
  import path from "node:path";
3
3
  import { ASTUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
4
-
5
4
  //#region lib/rules/e.ts
6
5
  /**
7
6
  * @fileoverview
@@ -43,6 +42,9 @@ var e_default = createRule({
43
42
  ArrowFunctionExpression: checkFunction,
44
43
  FunctionExpression: checkFunction,
45
44
  FunctionDeclaration: checkFunction,
45
+ TSDeclareFunction: checkFunction,
46
+ TSFunctionType: checkFunction,
47
+ TSCallSignatureDeclaration: checkFunction,
46
48
  CatchClause(node) {
47
49
  if (node.param?.type !== AST_NODE_TYPES.Identifier) return;
48
50
  checkParam(node.param);
@@ -81,6 +83,5 @@ var e_default = createRule({
81
83
  }
82
84
  }
83
85
  });
84
-
85
86
  //#endregion
86
- export { e_default as default };
87
+ export { e_default as default };
@@ -0,0 +1,9 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
+
4
+ //#region lib/rules/empty-for.d.ts
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noEmptyFor", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,34 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ //#region lib/rules/empty-for.ts
4
+ const { name } = path.parse(import.meta.filename);
5
+ var empty_for_default = createRule({
6
+ name,
7
+ meta: {
8
+ type: "suggestion",
9
+ docs: {
10
+ description: "Forbid using `for (;;)`",
11
+ recommended: true
12
+ },
13
+ fixable: "code",
14
+ schema: [],
15
+ messages: { noEmptyFor: "Use `while (true)` instead of `for (;;)`" }
16
+ },
17
+ defaultOptions: [],
18
+ create(context) {
19
+ return { ForStatement(node) {
20
+ if (node.init) return;
21
+ if (node.test) return;
22
+ if (node.update) return;
23
+ context.report({
24
+ node,
25
+ messageId: "noEmptyFor",
26
+ fix(fixer) {
27
+ return fixer.replaceTextRange([node.range[0], node.body.range[0]], "while (true) ");
28
+ }
29
+ });
30
+ } };
31
+ }
32
+ });
33
+ //#endregion
34
+ export { empty_for_default as default };
@@ -0,0 +1,9 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
+ import { ESLintUtils } from "@typescript-eslint/utils";
3
+
4
+ //#region lib/rules/enum-member.d.ts
5
+ declare const _default: ESLintUtils.RuleModule<"preferEnumMember", [], WyrmPluginDocs, ESLintUtils.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,51 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
+ import ts from "typescript";
5
+ //#region lib/rules/enum-member.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ var enum_member_default = createRule({
8
+ name,
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Prefer enum members to literals asserted as enum",
13
+ recommended: true,
14
+ requiresTypeChecking: true
15
+ },
16
+ fixable: "code",
17
+ schema: [],
18
+ messages: { preferEnumMember: "Use `satisfies` instead of `as`" }
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ let services;
23
+ function getServices() {
24
+ services ??= ESLintUtils.getParserServices(context);
25
+ return services;
26
+ }
27
+ return { TSAsExpression(node) {
28
+ if (node.expression.type !== AST_NODE_TYPES.Literal) return;
29
+ const { value } = node.expression;
30
+ if (typeof value !== "string" && typeof value !== "number") return;
31
+ const assertedType = getServices().getTypeFromTypeNode(node.typeAnnotation);
32
+ if ((assertedType.flags & ts.TypeFlags.EnumLike) === 0) return;
33
+ if (!assertedType.isUnion()) return;
34
+ const enumName = assertedType.getSymbol()?.getEscapedName().toString();
35
+ if (enumName === void 0) return;
36
+ const member = assertedType.types.filter((t) => t.isStringLiteral() || t.isNumberLiteral()).find((t) => t.value === value);
37
+ if (member === void 0) return;
38
+ const memberName = member.getSymbol()?.getEscapedName().toString();
39
+ if (memberName === void 0) return;
40
+ context.report({
41
+ node,
42
+ messageId: "preferEnumMember",
43
+ fix(fixer) {
44
+ return fixer.replaceText(node, `${enumName}.${memberName}`);
45
+ }
46
+ });
47
+ } };
48
+ }
49
+ });
50
+ //#endregion
51
+ export { enum_member_default as default };
@@ -0,0 +1,9 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
+ import { ESLintUtils } from "@typescript-eslint/utils";
3
+
4
+ //#region lib/rules/eqeq-null.d.ts
5
+ declare const _default: ESLintUtils.RuleModule<"useEqEqEqNull" | "useEqEqEqUndefined" | "constantEquality" | "constantInequality", [], WyrmPluginDocs, ESLintUtils.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,101 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import { None, Some } from "../utils/option.mjs";
3
+ import path from "node:path";
4
+ import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
5
+ import * as ts$1 from "typescript";
6
+ //#region lib/rules/eqeq-null.ts
7
+ const { name } = path.parse(import.meta.filename);
8
+ var eqeq_null_default = createRule({
9
+ name,
10
+ meta: {
11
+ type: "suggestion",
12
+ docs: {
13
+ description: "Forbid using `x == null` when equivalent to `x === null`",
14
+ strict: true,
15
+ requiresTypeChecking: true
16
+ },
17
+ fixable: "code",
18
+ schema: [],
19
+ messages: {
20
+ useEqEqEqNull: "Use {{ op }} null",
21
+ useEqEqEqUndefined: "Use {{ op }} undefined",
22
+ constantEquality: "`== null` or `== undefined` will always be true because undefined == null",
23
+ constantInequality: "`!= null` or `!= undefined` will always be false because undefined == null"
24
+ }
25
+ },
26
+ defaultOptions: [],
27
+ create(context) {
28
+ let services;
29
+ function getServices() {
30
+ services ??= ESLintUtils.getParserServices(context);
31
+ return services;
32
+ }
33
+ return { BinaryExpression(node) {
34
+ if (node.operator !== "==" && node.operator !== "!=") return;
35
+ const maybeExpr = getNullishedComparedNode(node);
36
+ if (!maybeExpr.some) return;
37
+ const type = getServices().getTypeAtLocation(maybeExpr.value);
38
+ const text = context.sourceCode.getText(maybeExpr.value);
39
+ const strictOperator = node.operator === "==" ? "===" : "!==";
40
+ if (isNull(type) && !isUndefined(type)) {
41
+ context.report({
42
+ node,
43
+ messageId: "useEqEqEqNull",
44
+ data: { op: strictOperator },
45
+ fix(fixer) {
46
+ return fixer.replaceText(node, `${text} ${strictOperator} null`);
47
+ }
48
+ });
49
+ return;
50
+ }
51
+ if (!isNull(type) && isUndefined(type)) {
52
+ context.report({
53
+ node,
54
+ messageId: "useEqEqEqUndefined",
55
+ data: { op: strictOperator },
56
+ fix(fixer) {
57
+ return fixer.replaceText(node, `${text} ${strictOperator} undefined`);
58
+ }
59
+ });
60
+ return;
61
+ }
62
+ if (!isOnlyNullish(type)) return;
63
+ if (node.operator === "==") context.report({
64
+ node,
65
+ messageId: "constantEquality"
66
+ });
67
+ else context.report({
68
+ node,
69
+ messageId: "constantInequality"
70
+ });
71
+ } };
72
+ }
73
+ });
74
+ function isNull(type) {
75
+ if (type.isUnion()) return type.types.some((t) => isNull(t));
76
+ return (type.getFlags() & ts$1.TypeFlags.Null) !== 0;
77
+ }
78
+ function isUndefined(type) {
79
+ if (type.isUnion()) return type.types.some((t) => isUndefined(t));
80
+ return (type.getFlags() & ts$1.TypeFlags.Undefined) !== 0;
81
+ }
82
+ function isOnlyNullish(type) {
83
+ if (!type.isUnion()) return false;
84
+ return type.types.every((t) => isNull(t) || isUndefined(t));
85
+ }
86
+ function getNullishedComparedNode(node) {
87
+ if (isNullishLiteral(node.left)) return Some(node.right);
88
+ if (isNullishLiteral(node.right)) return Some(node.left);
89
+ return None;
90
+ }
91
+ function isNullishLiteral(node) {
92
+ return isUndefinedLiteral(node) || isNullLiteral(node);
93
+ }
94
+ function isUndefinedLiteral(node) {
95
+ return node.type === AST_NODE_TYPES.Identifier && node.name === "undefined";
96
+ }
97
+ function isNullLiteral(node) {
98
+ return node.type === AST_NODE_TYPES.Literal && node.value === null;
99
+ }
100
+ //#endregion
101
+ export { eqeq_null_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _$_typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/exact-string-regex.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint0.RuleModule<"preferEquality", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint0.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"preferEquality", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
6
  name: string;
7
7
  };
8
8
  //#endregion
@@ -2,7 +2,6 @@ import { createRule } from "../utils/createRule.mjs";
2
2
  import { None, Some, getFirstOption } from "../utils/option.mjs";
3
3
  import path from "node:path";
4
4
  import { AST_NODE_TYPES } from "@typescript-eslint/utils";
5
-
6
5
  //#region lib/rules/exact-string-regex.ts
7
6
  const { name } = path.parse(import.meta.filename);
8
7
  var exact_string_regex_default = createRule({
@@ -80,6 +79,5 @@ function getExactEqualityPattern(re) {
80
79
  if (!content) return None;
81
80
  return Some(content);
82
81
  }
83
-
84
82
  //#endregion
85
- export { exact_string_regex_default as default };
83
+ export { exact_string_regex_default as default };
@@ -1,7 +1,6 @@
1
1
  import { createRule } from "../utils/createRule.mjs";
2
2
  import path from "node:path";
3
3
  import { ASTUtils, AST_NODE_TYPES, TSESLint } from "@typescript-eslint/utils";
4
-
5
4
  //#region lib/rules/export-using.ts
6
5
  /**
7
6
  * @fileoverview
@@ -55,6 +54,5 @@ var export_using_default = createRule({
55
54
  }
56
55
  }
57
56
  });
58
-
59
57
  //#endregion
60
- export { export_using_default as default };
58
+ export { export_using_default as default };