eslint-plugin-wyrm 0.0.10 → 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 (234) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +114 -58
  3. package/bin/wyrm.mjs +3 -0
  4. package/dist/_virtual/_rolldown/runtime.mjs +14 -0
  5. package/dist/cli.d.mts +1 -0
  6. package/dist/cli.mjs +23 -0
  7. package/dist/configs/index.d.mts +2 -1
  8. package/dist/configs/index.mjs +6 -6
  9. package/dist/index.mjs +1 -4
  10. package/dist/plugin.mjs +1 -3
  11. package/dist/rules/array-from-array.d.mts +9 -0
  12. package/dist/rules/array-from-array.mjs +56 -0
  13. package/dist/rules/as-unknown-as.d.mts +9 -0
  14. package/dist/rules/as-unknown-as.mjs +30 -0
  15. package/dist/rules/await-promise-resolve.d.mts +9 -0
  16. package/dist/rules/await-promise-resolve.mjs +41 -0
  17. package/dist/rules/boolean-coalescing.d.mts +9 -0
  18. package/dist/rules/boolean-coalescing.mjs +141 -0
  19. package/dist/rules/comment-duplicate-leading-space.d.mts +9 -0
  20. package/dist/rules/comment-duplicate-leading-space.mjs +34 -0
  21. package/dist/rules/conditional-boolean.d.mts +9 -0
  22. package/dist/rules/conditional-boolean.mjs +70 -0
  23. package/dist/rules/constant-boolean-cast.d.mts +9 -0
  24. package/dist/rules/constant-boolean-cast.mjs +203 -0
  25. package/dist/rules/de-morgan.d.mts +2 -2
  26. package/dist/rules/de-morgan.mjs +1 -3
  27. package/dist/rules/discarded-expression-statement.d.mts +14 -0
  28. package/dist/rules/discarded-expression-statement.mjs +243 -0
  29. package/dist/rules/distribute-boolean-casts.d.mts +2 -2
  30. package/dist/rules/distribute-boolean-casts.mjs +3 -3
  31. package/dist/rules/duplicate-destructuring.d.mts +2 -2
  32. package/dist/rules/duplicate-destructuring.mjs +1 -3
  33. package/dist/rules/duplicate-object-spread.d.mts +9 -0
  34. package/dist/rules/duplicate-object-spread.mjs +44 -0
  35. package/dist/rules/e.d.mts +11 -0
  36. package/dist/rules/e.mjs +87 -0
  37. package/dist/rules/empty-for.d.mts +9 -0
  38. package/dist/rules/empty-for.mjs +34 -0
  39. package/dist/rules/enum-member.d.mts +9 -0
  40. package/dist/rules/enum-member.mjs +51 -0
  41. package/dist/rules/eqeq-null.d.mts +9 -0
  42. package/dist/rules/eqeq-null.mjs +101 -0
  43. package/dist/rules/exact-string-regex.d.mts +9 -0
  44. package/dist/rules/exact-string-regex.mjs +83 -0
  45. package/dist/rules/export-using.d.mts +9 -0
  46. package/dist/rules/export-using.mjs +58 -0
  47. package/dist/rules/generic-constructor-with-hook.d.mts +11 -0
  48. package/dist/rules/generic-constructor-with-hook.mjs +103 -0
  49. package/dist/rules/idiomatic-cast.mjs +7 -10
  50. package/dist/rules/index.d.mts +112 -57
  51. package/dist/rules/index.mjs +113 -5
  52. package/dist/rules/inferable-type-predicate.d.mts +9 -0
  53. package/dist/rules/inferable-type-predicate.mjs +100 -0
  54. package/dist/rules/inner-as-const.d.mts +9 -0
  55. package/dist/rules/inner-as-const.mjs +70 -0
  56. package/dist/rules/jsx-tostring.d.mts +9 -0
  57. package/dist/rules/jsx-tostring.mjs +120 -0
  58. package/dist/rules/literal-destructuring.d.mts +9 -0
  59. package/dist/rules/literal-destructuring.mjs +102 -0
  60. package/dist/rules/named-export-with-side-effects.d.mts +11 -0
  61. package/dist/rules/named-export-with-side-effects.mjs +72 -0
  62. package/dist/rules/nested-reduce.d.mts +9 -0
  63. package/dist/rules/nested-reduce.mjs +46 -0
  64. package/dist/rules/nested-try-catch.d.mts +9 -0
  65. package/dist/rules/nested-try-catch.mjs +37 -0
  66. package/dist/rules/no-commented-out-comment.d.mts +9 -0
  67. package/dist/rules/no-commented-out-comment.mjs +31 -0
  68. package/dist/rules/no-constant-template-expression.d.mts +3 -4
  69. package/dist/rules/no-constant-template-expression.mjs +12 -9
  70. package/dist/rules/no-constructed-error-cause.d.mts +9 -0
  71. package/dist/rules/no-constructed-error-cause.mjs +75 -0
  72. package/dist/rules/no-convoluted-boolean-expressions.d.mts +9 -0
  73. package/dist/rules/no-convoluted-boolean-expressions.mjs +130 -0
  74. package/dist/rules/no-convoluted-logical-expressions.d.mts +2 -2
  75. package/dist/rules/no-convoluted-logical-expressions.mjs +1 -3
  76. package/dist/rules/no-custom-url-parsing.d.mts +2 -3
  77. package/dist/rules/no-custom-url-parsing.mjs +1 -3
  78. package/dist/rules/no-disallowed-warning-comments.d.mts +2 -2
  79. package/dist/rules/no-disallowed-warning-comments.mjs +1 -3
  80. package/dist/rules/no-duplicated-return.d.mts +2 -2
  81. package/dist/rules/no-duplicated-return.mjs +2 -3
  82. package/dist/rules/no-else-break.d.mts +2 -2
  83. package/dist/rules/no-else-break.mjs +3 -5
  84. package/dist/rules/no-else-continue.d.mts +2 -2
  85. package/dist/rules/no-else-continue.mjs +3 -5
  86. package/dist/rules/no-else-never.d.mts +9 -0
  87. package/dist/rules/no-else-never.mjs +75 -0
  88. package/dist/rules/no-else-return.d.mts +2 -3
  89. package/dist/rules/no-else-return.mjs +4 -5
  90. package/dist/rules/no-else-throw.d.mts +2 -2
  91. package/dist/rules/no-else-throw.mjs +3 -5
  92. package/dist/rules/no-empty-attribute.d.mts +3 -3
  93. package/dist/rules/no-empty-attribute.mjs +1 -3
  94. package/dist/rules/no-empty-comment.d.mts +3 -3
  95. package/dist/rules/no-empty-comment.mjs +1 -3
  96. package/dist/rules/no-empty-jsx-expression.d.mts +2 -2
  97. package/dist/rules/no-empty-jsx-expression.mjs +1 -3
  98. package/dist/rules/no-empty-literal-iteration.d.mts +2 -2
  99. package/dist/rules/no-empty-literal-iteration.mjs +1 -3
  100. package/dist/rules/no-extra-false-fallback.d.mts +2 -3
  101. package/dist/rules/no-extra-false-fallback.mjs +1 -3
  102. package/dist/rules/no-extra-nested-boolean-cast.d.mts +2 -3
  103. package/dist/rules/no-extra-nested-boolean-cast.mjs +2 -3
  104. package/dist/rules/no-first-last.d.mts +2 -2
  105. package/dist/rules/no-first-last.mjs +2 -5
  106. package/dist/rules/no-float-length-check.d.mts +2 -2
  107. package/dist/rules/no-float-length-check.mjs +1 -3
  108. package/dist/rules/no-huge-try-block.d.mts +3 -3
  109. package/dist/rules/no-huge-try-block.mjs +1 -3
  110. package/dist/rules/no-huge-useeffect.d.mts +11 -0
  111. package/dist/rules/no-huge-useeffect.mjs +52 -0
  112. package/dist/rules/no-if-length-for.d.mts +9 -0
  113. package/dist/rules/no-if-length-for.mjs +91 -0
  114. package/dist/rules/no-inline-jsdoc-tag.d.mts +3 -3
  115. package/dist/rules/no-inline-jsdoc-tag.mjs +1 -3
  116. package/dist/rules/no-invalid-date-literal.d.mts +2 -2
  117. package/dist/rules/no-invalid-date-literal.mjs +42 -19
  118. package/dist/rules/no-jsx-statement.d.mts +2 -2
  119. package/dist/rules/no-jsx-statement.mjs +1 -3
  120. package/dist/rules/no-lax-array-type.d.mts +9 -0
  121. package/dist/rules/no-lax-array-type.mjs +129 -0
  122. package/dist/rules/no-lax-return-type.d.mts +9 -0
  123. package/dist/rules/no-lax-return-type.mjs +138 -0
  124. package/dist/rules/no-mutable-literal-fill.d.mts +2 -3
  125. package/dist/rules/no-mutable-literal-fill.mjs +1 -3
  126. package/dist/rules/no-nullish-ternary.d.mts +9 -0
  127. package/dist/rules/no-nullish-ternary.mjs +121 -0
  128. package/dist/rules/no-numbered-comments.d.mts +2 -2
  129. package/dist/rules/no-numbered-comments.mjs +1 -3
  130. package/dist/rules/no-obvious-any.mjs +35 -27
  131. package/dist/rules/no-optional-type-guard-param.d.mts +2 -3
  132. package/dist/rules/no-optional-type-guard-param.mjs +1 -3
  133. package/dist/rules/no-out-of-order-comments.d.mts +2 -2
  134. package/dist/rules/no-out-of-order-comments.mjs +4 -8
  135. package/dist/rules/no-possibly-nullish-equality.d.mts +0 -1
  136. package/dist/rules/no-possibly-nullish-equality.mjs +6 -13
  137. package/dist/rules/no-redundant-function-declaration.d.mts +2 -2
  138. package/dist/rules/no-redundant-function-declaration.mjs +1 -3
  139. package/dist/rules/no-return-to-void.mjs +2 -4
  140. package/dist/rules/no-self-object-assign.d.mts +2 -2
  141. package/dist/rules/no-self-object-assign.mjs +1 -3
  142. package/dist/rules/no-sloppy-length-check.d.mts +2 -3
  143. package/dist/rules/no-sloppy-length-check.mjs +35 -37
  144. package/dist/rules/no-suspicious-jsx-semicolon.d.mts +2 -3
  145. package/dist/rules/no-suspicious-jsx-semicolon.mjs +2 -4
  146. package/dist/rules/no-ternary-return.d.mts +3 -4
  147. package/dist/rules/no-ternary-return.mjs +1 -3
  148. package/dist/rules/no-type-guard.d.mts +9 -0
  149. package/dist/rules/no-type-guard.mjs +36 -0
  150. package/dist/rules/no-unassigned-todo.d.mts +2 -2
  151. package/dist/rules/no-unassigned-todo.mjs +1 -3
  152. package/dist/rules/no-unbound-catch-error.d.mts +2 -2
  153. package/dist/rules/no-unbound-catch-error.mjs +1 -3
  154. package/dist/rules/no-unused-mutually-referential.d.mts +9 -0
  155. package/dist/rules/no-unused-mutually-referential.mjs +215 -0
  156. package/dist/rules/no-unused-param-read.d.mts +2 -2
  157. package/dist/rules/no-unused-param-read.mjs +1 -3
  158. package/dist/rules/no-useless-computed-key.d.mts +2 -2
  159. package/dist/rules/no-useless-computed-key.mjs +1 -3
  160. package/dist/rules/no-useless-iife.d.mts +2 -2
  161. package/dist/rules/no-useless-iife.mjs +2 -3
  162. package/dist/rules/no-useless-logical-fallback.d.mts +0 -1
  163. package/dist/rules/no-useless-logical-fallback.mjs +32 -24
  164. package/dist/rules/no-useless-return-undefined.mjs +11 -11
  165. package/dist/rules/no-useless-ts-check.d.mts +9 -0
  166. package/dist/rules/no-useless-ts-check.mjs +34 -0
  167. package/dist/rules/no-useless-use-strict.d.mts +2 -2
  168. package/dist/rules/no-useless-use-strict.mjs +1 -3
  169. package/dist/rules/no-useless-usememo.d.mts +2 -2
  170. package/dist/rules/no-useless-usememo.mjs +8 -6
  171. package/dist/rules/no-whitespace-property.d.mts +2 -2
  172. package/dist/rules/no-whitespace-property.mjs +1 -3
  173. package/dist/rules/nullish-object-spread.d.mts +9 -0
  174. package/dist/rules/nullish-object-spread.mjs +38 -0
  175. package/dist/rules/optional-call-expression.d.mts +2 -2
  176. package/dist/rules/optional-call-expression.mjs +20 -3
  177. package/dist/rules/prefer-array-from.d.mts +9 -0
  178. package/dist/rules/prefer-array-from.mjs +87 -0
  179. package/dist/rules/prefer-catch-method.d.mts +2 -2
  180. package/dist/rules/prefer-catch-method.mjs +9 -12
  181. package/dist/rules/prefer-early-return.d.mts +2 -2
  182. package/dist/rules/prefer-early-return.mjs +23 -20
  183. package/dist/rules/prefer-eqeq-null.d.mts +9 -0
  184. package/dist/rules/prefer-eqeq-null.mjs +122 -0
  185. package/dist/rules/prefer-finally.d.mts +9 -0
  186. package/dist/rules/prefer-finally.mjs +129 -0
  187. package/dist/rules/prefer-getorinsert.d.mts +9 -0
  188. package/dist/rules/prefer-getorinsert.mjs +180 -0
  189. package/dist/rules/prefer-has.d.mts +9 -0
  190. package/dist/rules/prefer-has.mjs +69 -0
  191. package/dist/rules/prefer-in.d.mts +9 -0
  192. package/dist/rules/prefer-in.mjs +81 -0
  193. package/dist/rules/prefer-object-keys-values.d.mts +9 -0
  194. package/dist/rules/prefer-object-keys-values.mjs +78 -0
  195. package/dist/rules/prefer-repeat.d.mts +2 -2
  196. package/dist/rules/prefer-repeat.mjs +1 -5
  197. package/dist/rules/prefer-satisfies.d.mts +9 -0
  198. package/dist/rules/prefer-satisfies.mjs +86 -0
  199. package/dist/rules/prefer-string-join.d.mts +9 -0
  200. package/dist/rules/prefer-string-join.mjs +67 -0
  201. package/dist/rules/primitive-valueof.mjs +6 -8
  202. package/dist/rules/slim-try.d.mts +9 -0
  203. package/dist/rules/slim-try.mjs +150 -0
  204. package/dist/rules/styled-button-has-type.d.mts +9 -0
  205. package/dist/rules/styled-button-has-type.mjs +82 -0
  206. package/dist/rules/styled-transient-props.d.mts +9 -0
  207. package/dist/rules/styled-transient-props.mjs +52 -0
  208. package/dist/rules/suspicious-map-length.d.mts +2 -2
  209. package/dist/rules/suspicious-map-length.mjs +1 -3
  210. package/dist/rules/template-tostring.d.mts +9 -0
  211. package/dist/rules/template-tostring.mjs +48 -0
  212. package/dist/rules/unsafe-asserted-chain.d.mts +0 -1
  213. package/dist/rules/unsafe-asserted-chain.mjs +5 -8
  214. package/dist/rules/unused-object-assign.d.mts +2 -2
  215. package/dist/rules/unused-object-assign.mjs +1 -3
  216. package/dist/rules/unused-object-freeze.d.mts +9 -0
  217. package/dist/rules/unused-object-freeze.mjs +37 -0
  218. package/dist/rules/useless-as-const.d.mts +9 -0
  219. package/dist/rules/useless-as-const.mjs +59 -0
  220. package/dist/rules/useless-assign.d.mts +11 -0
  221. package/dist/rules/useless-assign.mjs +69 -0
  222. package/dist/rules/useless-conditional-assign.d.mts +9 -0
  223. package/dist/rules/useless-conditional-assign.mjs +58 -0
  224. package/dist/rules/useless-intermediary-variable.mjs +18 -21
  225. package/dist/rules/useless-mock.d.mts +9 -0
  226. package/dist/rules/useless-mock.mjs +180 -0
  227. package/dist/rules/useless-required.d.mts +9 -0
  228. package/dist/rules/useless-required.mjs +257 -0
  229. package/dist/utils/compareTokens.mjs +1 -3
  230. package/dist/utils/createRule.mjs +1 -3
  231. package/dist/utils/negateExpression.mjs +1 -3
  232. package/dist/utils/option.mjs +5 -2
  233. package/package.json +30 -23
  234. package/dist/_virtual/rolldown_runtime.mjs +0 -20
@@ -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_eslint1 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_eslint1.RuleModule<"distributeBooleanCast", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint1.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_eslint3 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_eslint3.RuleModule<"duplicateKey", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint3.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 };
@@ -0,0 +1,11 @@
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/e.d.ts
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noE" | "useOther", [{
6
+ alternatives: string[];
7
+ }], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
8
+ name: string;
9
+ };
10
+ //#endregion
11
+ export { _default };
@@ -0,0 +1,87 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { ASTUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
4
+ //#region lib/rules/e.ts
5
+ /**
6
+ * @fileoverview
7
+ *
8
+ * In JS, the parameter name `e` is semantically overloaded: it is often used for errors, events, elements...
9
+ * This rule forbids using `e` as a parameter name, in favor of more explicit identifiers like `err`, `evt` or `elt`.
10
+ */
11
+ const { name } = path.parse(import.meta.filename);
12
+ const DEFAULT_ALTERNATIVES = [
13
+ "err",
14
+ "evt",
15
+ "elt"
16
+ ];
17
+ var e_default = createRule({
18
+ name,
19
+ meta: {
20
+ type: "suggestion",
21
+ docs: {
22
+ description: "Forbid using `e` as a parameter name",
23
+ strict: true
24
+ },
25
+ hasSuggestions: true,
26
+ schema: [{
27
+ type: "object",
28
+ properties: { alternatives: {
29
+ description: `Suggested alternatives for identifier names. Default: \`${JSON.stringify(DEFAULT_ALTERNATIVES)}\``,
30
+ type: "array",
31
+ items: { type: "string" }
32
+ } }
33
+ }],
34
+ messages: {
35
+ noE: "Do not use `e` as a parameter name. Use a less ambiguous name.",
36
+ useOther: "Use `{{ ident }}` instead"
37
+ }
38
+ },
39
+ defaultOptions: [{ alternatives: DEFAULT_ALTERNATIVES }],
40
+ create(context, [options]) {
41
+ return {
42
+ ArrowFunctionExpression: checkFunction,
43
+ FunctionExpression: checkFunction,
44
+ FunctionDeclaration: checkFunction,
45
+ TSDeclareFunction: checkFunction,
46
+ TSFunctionType: checkFunction,
47
+ TSCallSignatureDeclaration: checkFunction,
48
+ CatchClause(node) {
49
+ if (node.param?.type !== AST_NODE_TYPES.Identifier) return;
50
+ checkParam(node.param);
51
+ }
52
+ };
53
+ function checkFunction(node) {
54
+ for (const param of node.params) {
55
+ if (param.type !== AST_NODE_TYPES.Identifier) return;
56
+ checkParam(param);
57
+ }
58
+ }
59
+ function checkParam(param) {
60
+ if (param.name !== "e") return;
61
+ const scope = context.sourceCode.getScope(param);
62
+ const variable = ASTUtils.findVariable(scope, param);
63
+ /* v8 ignore if -- @preserve */
64
+ if (!variable) return;
65
+ const { alternatives } = options;
66
+ context.report({
67
+ node: param,
68
+ messageId: "noE",
69
+ suggest: alternatives.map((alternative) => ({
70
+ messageId: "useOther",
71
+ data: { ident: alternative },
72
+ *fix(fixer) {
73
+ for (const ref of variable.references) yield fixer.replaceText(ref.identifier, alternative);
74
+ if (param.typeAnnotation) {
75
+ const rng = [param.range[0], param.typeAnnotation.range[0]];
76
+ yield fixer.replaceTextRange(rng, alternative);
77
+ return;
78
+ }
79
+ yield fixer.replaceText(param, alternative);
80
+ }
81
+ }))
82
+ });
83
+ }
84
+ }
85
+ });
86
+ //#endregion
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 };