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
@@ -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/no-sloppy-length-check.ts
7
6
  /**
8
7
  * @fileoverview
@@ -58,7 +57,8 @@ var no_sloppy_length_check_default = createRule({
58
57
  checkFlags(flags, info, node);
59
58
  }
60
59
  function getFlagsForLogicalOrBinaryExpression(node) {
61
- if (isSymmetricBinaryExpression(node)) return getFlagsForBinaryExpression(node);
60
+ const expr = getSymmetricBinaryExpression(node);
61
+ if (expr) return getFlagsForBinaryExpression(expr);
62
62
  if (node.type === AST_NODE_TYPES.LogicalExpression) return getFlagsForLogicalExpression(node);
63
63
  return None;
64
64
  }
@@ -95,15 +95,16 @@ var no_sloppy_length_check_default = createRule({
95
95
  checkLogicalExpression(node);
96
96
  },
97
97
  BinaryExpression(node) {
98
- if (!isSymmetricBinaryExpression(node)) return;
99
- checkBinaryExpression(node);
98
+ const expr = getSymmetricBinaryExpression(node);
99
+ if (!expr) return;
100
+ checkBinaryExpression(expr);
100
101
  }
101
102
  };
102
103
  }
103
104
  });
104
105
  function getFlagsForBinaryExpression(node) {
105
- const { operator } = node;
106
- if (!isComparisonOperator(operator)) return None;
106
+ const operator = getComparisonOperator(node.operator);
107
+ if (!operator) return None;
107
108
  const maybeInfo = extractComparisonInfo({
108
109
  ...node,
109
110
  operator
@@ -114,12 +115,12 @@ function getFlagsForBinaryExpression(node) {
114
115
  info: maybeInfo.value
115
116
  });
116
117
  }
117
- var Flags = /* @__PURE__ */ function(Flags$1) {
118
- Flags$1[Flags$1["UNKNOWN"] = 0] = "UNKNOWN";
119
- Flags$1[Flags$1["INFERIOR_TO_ZERO"] = 1] = "INFERIOR_TO_ZERO";
120
- Flags$1[Flags$1["EQUAL_TO_ZERO"] = 2] = "EQUAL_TO_ZERO";
121
- Flags$1[Flags$1["SUPERIOR_TO_ZERO"] = 4] = "SUPERIOR_TO_ZERO";
122
- return Flags$1;
118
+ var Flags = /* @__PURE__ */ function(Flags) {
119
+ Flags[Flags["UNKNOWN"] = 0] = "UNKNOWN";
120
+ Flags[Flags["INFERIOR_TO_ZERO"] = 1] = "INFERIOR_TO_ZERO";
121
+ Flags[Flags["EQUAL_TO_ZERO"] = 2] = "EQUAL_TO_ZERO";
122
+ Flags[Flags["SUPERIOR_TO_ZERO"] = 4] = "SUPERIOR_TO_ZERO";
123
+ return Flags;
123
124
  }(Flags || {});
124
125
  function getFlags(info) {
125
126
  const { op, value } = info;
@@ -135,11 +136,10 @@ function getFlags(info) {
135
136
  case ">": return Flags.SUPERIOR_TO_ZERO;
136
137
  case "<=": return Flags.EQUAL_TO_ZERO | Flags.INFERIOR_TO_ZERO;
137
138
  case ">=": return Flags.EQUAL_TO_ZERO | Flags.SUPERIOR_TO_ZERO;
138
- default: {
139
- const check = op;
140
- console.error(`Unexpected binary operator: ${check}`);
139
+ /* v8 ignore next -- @preserve */
140
+ default:
141
+ console.error(`[wyrm] Unexpected binary operator: ${op}`);
141
142
  return Flags.UNKNOWN;
142
- }
143
143
  }
144
144
  }
145
145
  function extractNumberLiteralValue(node) {
@@ -153,10 +153,10 @@ function extractNumberLiteralValue(node) {
153
153
  if (!n.some) return None;
154
154
  return Some(-n.value);
155
155
  }
156
- var SizeProperty = /* @__PURE__ */ function(SizeProperty$1) {
157
- SizeProperty$1["SIZE"] = "size";
158
- SizeProperty$1["LENGTH"] = "length";
159
- return SizeProperty$1;
156
+ var SizeProperty = /* @__PURE__ */ function(SizeProperty) {
157
+ SizeProperty["SIZE"] = "size";
158
+ SizeProperty["LENGTH"] = "length";
159
+ return SizeProperty;
160
160
  }(SizeProperty || {});
161
161
  function getSizeProperty(propertyName) {
162
162
  switch (propertyName) {
@@ -176,11 +176,10 @@ function reverseOperator(op) {
176
176
  case "<=": return ">=";
177
177
  case ">": return "<";
178
178
  case ">=": return "<=";
179
- default: {
180
- const check = op;
181
- console.error(`Unexpected binary operator: ${check}`);
179
+ /* v8 ignore next -- @preserve */
180
+ default:
181
+ console.error(`[wyrm] Unexpected binary operator: ${op}`);
182
182
  return op;
183
- }
184
183
  }
185
184
  }
186
185
  function extractComparisonInfo(node, reversed = false) {
@@ -207,11 +206,12 @@ function extractComparisonInfo(node, reversed = false) {
207
206
  op: reversed ? reverseOperator(operator) : operator
208
207
  });
209
208
  }
210
- function isSymmetricBinaryExpression(node) {
211
- if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
212
- return node.operator !== "in";
209
+ function getSymmetricBinaryExpression(node) {
210
+ if (node.type !== AST_NODE_TYPES.BinaryExpression) return null;
211
+ if (node.operator === "in") return null;
212
+ return node;
213
213
  }
214
- function isComparisonOperator(operator) {
214
+ function getComparisonOperator(operator) {
215
215
  switch (operator) {
216
216
  case "%":
217
217
  case "&":
@@ -228,7 +228,7 @@ function isComparisonOperator(operator) {
228
228
  case ">>>":
229
229
  case "^":
230
230
  case "in":
231
- case "instanceof": return false;
231
+ case "instanceof": return null;
232
232
  case "!=":
233
233
  case "!==":
234
234
  case "<":
@@ -236,14 +236,12 @@ function isComparisonOperator(operator) {
236
236
  case "==":
237
237
  case "===":
238
238
  case ">":
239
- case ">=": return true;
240
- default: {
241
- const check = operator;
242
- console.error(`Unexpected binary operator: ${check}`);
243
- return false;
244
- }
239
+ case ">=": return operator;
240
+ /* v8 ignore next -- @preserve */
241
+ default:
242
+ console.error(`[wyrm] Unexpected binary operator: ${operator}`);
243
+ return null;
245
244
  }
246
245
  }
247
-
248
246
  //#endregion
249
- export { no_sloppy_length_check_default as default };
247
+ export { no_sloppy_length_check_default as default };
@@ -1,9 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint59 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/no-suspicious-jsx-semicolon.d.ts
5
-
6
- declare const _default: _typescript_eslint_utils_ts_eslint59.RuleModule<"noSuspiciousJsxSemicolon" | "noSuspiciousJsxComma", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint59.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noSuspiciousJsxSemicolon" | "noSuspiciousJsxComma", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
7
6
  name: string;
8
7
  };
9
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/no-suspicious-jsx-semicolon.ts
6
5
  /**
7
6
  * @fileoverview
@@ -28,7 +27,7 @@ var no_suspicious_jsx_semicolon_default = createRule({
28
27
  return { JSXText(node) {
29
28
  /* v8 ignore if -- @preserve */
30
29
  if (node.parent.type !== AST_NODE_TYPES.JSXElement && node.parent.type !== AST_NODE_TYPES.JSXFragment) {
31
- const msg = `Did not expect JSXText node to be a child of ${node.parent.type}`;
30
+ const msg = `[wyrm] Did not expect JSXText node to be a child of ${node.parent.type}`;
32
31
  console.warn(msg);
33
32
  return;
34
33
  }
@@ -52,6 +51,5 @@ var no_suspicious_jsx_semicolon_default = createRule({
52
51
  } };
53
52
  }
54
53
  });
55
-
56
54
  //#endregion
57
- export { no_suspicious_jsx_semicolon_default as default };
55
+ export { no_suspicious_jsx_semicolon_default as default };
@@ -1,11 +1,10 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint61 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/no-ternary-return.d.ts
5
-
6
- declare const _default: _typescript_eslint_utils_ts_eslint61.RuleModule<"noTernaryReturn", [{
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noTernaryReturn", [{
7
6
  allowSingleLine: boolean;
8
- }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint61.RuleListener> & {
7
+ }], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
9
8
  name: string;
10
9
  };
11
10
  //#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/no-ternary-return.ts
6
5
  /**
7
6
  * @fileoverview
@@ -55,6 +54,5 @@ var no_ternary_return_default = createRule({
55
54
  } };
56
55
  }
57
56
  });
58
-
59
57
  //#endregion
60
- export { no_ternary_return_default as default };
58
+ export { no_ternary_return_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/no-type-guard.d.ts
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noTypeGuard", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,36 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
4
+ //#region lib/rules/no-type-guard.ts
5
+ const { name } = path.parse(import.meta.filename);
6
+ var no_type_guard_default = createRule({
7
+ name,
8
+ meta: {
9
+ type: "suggestion",
10
+ docs: {
11
+ description: "Forbid type guards",
12
+ pedantic: true
13
+ },
14
+ schema: [],
15
+ messages: { noTypeGuard: "Type guards are forbidden." }
16
+ },
17
+ defaultOptions: [],
18
+ create(context) {
19
+ return {
20
+ FunctionDeclaration: checkFunction,
21
+ FunctionExpression: checkFunction,
22
+ ArrowFunctionExpression: checkFunction
23
+ };
24
+ function checkFunction(fn) {
25
+ if (fn.parent.type === AST_NODE_TYPES.CallExpression) return;
26
+ if (!fn.returnType) return;
27
+ if (fn.returnType.typeAnnotation.type !== AST_NODE_TYPES.TSTypePredicate) return;
28
+ context.report({
29
+ node: fn,
30
+ messageId: "noTypeGuard"
31
+ });
32
+ }
33
+ }
34
+ });
35
+ //#endregion
36
+ export { no_type_guard_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint63 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/no-unassigned-todo.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint63.RuleModule<"noUnassignedComment", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint63.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noUnassignedComment", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
6
  name: string;
7
7
  };
8
8
  //#endregion
@@ -1,6 +1,5 @@
1
1
  import { createRule } from "../utils/createRule.mjs";
2
2
  import path from "node:path";
3
-
4
3
  //#region lib/rules/no-unassigned-todo.ts
5
4
  const { name } = path.parse(import.meta.filename);
6
5
  var no_unassigned_todo_default = createRule({
@@ -33,6 +32,5 @@ function hasUnassignedTodo(line) {
33
32
  if (!/^todo(?:\W|$)/u.test(value)) return false;
34
33
  return !/^todo\([^)]+\)/u.test(value);
35
34
  }
36
-
37
35
  //#endregion
38
- export { no_unassigned_todo_default as default };
36
+ export { no_unassigned_todo_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint65 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/no-unbound-catch-error.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint65.RuleModule<"noUnboundError", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint65.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noUnboundError", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
6
  name: string;
7
7
  };
8
8
  //#endregion
@@ -1,6 +1,5 @@
1
1
  import { createRule } from "../utils/createRule.mjs";
2
2
  import path from "node:path";
3
-
4
3
  //#region lib/rules/no-unbound-catch-error.ts
5
4
  const { name } = path.parse(import.meta.filename);
6
5
  var no_unbound_catch_error_default = createRule({
@@ -25,6 +24,5 @@ var no_unbound_catch_error_default = createRule({
25
24
  } };
26
25
  }
27
26
  });
28
-
29
27
  //#endregion
30
- export { no_unbound_catch_error_default as default };
28
+ export { no_unbound_catch_error_default as default };
@@ -0,0 +1,9 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
+ import { TSESLint } from "@typescript-eslint/utils";
3
+
4
+ //#region lib/rules/no-unused-mutually-referential.d.ts
5
+ declare const _default: TSESLint.RuleModule<"noUnusedMutuallyReferential", [], WyrmPluginDocs, TSESLint.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,215 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import { None, Some } from "../utils/option.mjs";
3
+ import path from "node:path";
4
+ import { ASTUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
5
+ //#region lib/rules/no-unused-mutually-referential.ts
6
+ /**
7
+ * @fileoverview
8
+ *
9
+ * If two functions both reference each other but are not used anywhere else,
10
+ * tools like TypeScript or ESLint will not mark them as unused.
11
+ *
12
+ * This rule forbids all unused functions, even if they mutually reference each other.
13
+ */
14
+ const { name } = path.parse(import.meta.filename);
15
+ var no_unused_mutually_referential_default = createRule({
16
+ name,
17
+ meta: {
18
+ type: "problem",
19
+ docs: {
20
+ description: "Forbid unused functions, even if mutually referential",
21
+ strict: true
22
+ },
23
+ schema: [],
24
+ messages: { noUnusedMutuallyReferential: "This function `{{id}}` is probably unused" }
25
+ },
26
+ defaultOptions: [],
27
+ create(context) {
28
+ function getScope(node) {
29
+ return context.sourceCode.getScope(node);
30
+ }
31
+ function checkFunctionNode(node) {
32
+ const maybeFn = getIdentifiedFunction(node);
33
+ if (!maybeFn.value) return;
34
+ const fn = maybeFn.value;
35
+ if (!isFunctionUnused(fn, getScope)) return;
36
+ context.report({
37
+ node,
38
+ messageId: "noUnusedMutuallyReferential",
39
+ data: { id: fn.id.name }
40
+ });
41
+ }
42
+ return {
43
+ FunctionDeclaration: checkFunctionNode,
44
+ FunctionExpression: checkFunctionNode,
45
+ ArrowFunctionExpression: checkFunctionNode
46
+ };
47
+ }
48
+ });
49
+ var UsageKind = /* @__PURE__ */ function(UsageKind) {
50
+ UsageKind["DEFINITELY_USED"] = "DEFINITELY_USED";
51
+ UsageKind["DEFINITELY_UNUSED"] = "DEFINITELY_UNUSED";
52
+ UsageKind["IT_DEPENDS"] = "IT_DEPENDS";
53
+ return UsageKind;
54
+ }(UsageKind || {});
55
+ const DEFINITELY_USED = {
56
+ kind: UsageKind.DEFINITELY_USED,
57
+ isUnused: false
58
+ };
59
+ const DEFINITELY_UNUSED = {
60
+ kind: UsageKind.DEFINITELY_UNUSED,
61
+ isUnused: true
62
+ };
63
+ function itDepends(usedIn) {
64
+ return {
65
+ kind: UsageKind.IT_DEPENDS,
66
+ usedIn
67
+ };
68
+ }
69
+ function getFunctionUsage(fn, getScope, cache) {
70
+ const cached = cache.get(fn.id);
71
+ if (cached !== void 0) return cached;
72
+ if (isExported(fn)) return DEFINITELY_USED;
73
+ const variable = ASTUtils.findVariable(getScope(fn.id), fn.id);
74
+ /* v8 ignore if -- @preserve */
75
+ if (!variable) return DEFINITELY_UNUSED;
76
+ const readReferences = variable.references.filter((ref) => ref.isRead());
77
+ const usedIn = /* @__PURE__ */ new Map();
78
+ for (const ref of readReferences) {
79
+ const maybeParentFn = getParentFunction(ref.identifier);
80
+ if (!maybeParentFn.some) {
81
+ if (getIdentUsage(ref.identifier, getScope).kind === UsageKind.DEFINITELY_USED) return DEFINITELY_USED;
82
+ continue;
83
+ }
84
+ const parentFn = maybeParentFn.value;
85
+ if (parentFn.node === fn.node) continue;
86
+ usedIn.set(parentFn.id, parentFn.node);
87
+ }
88
+ if (!usedIn.size) return DEFINITELY_UNUSED;
89
+ return itDepends(usedIn);
90
+ }
91
+ function isFunctionUnused(fn, getScope) {
92
+ const cache = /* @__PURE__ */ new WeakMap();
93
+ const usage = getFunctionUsage(fn, getScope, cache);
94
+ cache.set(fn.id, usage);
95
+ if (usage.kind !== UsageKind.IT_DEPENDS) return usage.isUnused;
96
+ const usedIn = new Map(usage.usedIn);
97
+ const unusedFunctions = /* @__PURE__ */ new Set();
98
+ let gas = 1e3;
99
+ while (usedIn.size && gas > 0) {
100
+ gas--;
101
+ let newFuncsAdded = false;
102
+ for (const [id, func] of usedIn) {
103
+ const funcUsage = getFunctionUsage({
104
+ id,
105
+ node: func
106
+ }, getScope, cache);
107
+ cache.set(id, funcUsage);
108
+ const { kind } = funcUsage;
109
+ switch (kind) {
110
+ case UsageKind.DEFINITELY_USED: return false;
111
+ case UsageKind.DEFINITELY_UNUSED:
112
+ usedIn.delete(id);
113
+ unusedFunctions.add(func);
114
+ continue;
115
+ case UsageKind.IT_DEPENDS:
116
+ for (const [newId, newFunc] of funcUsage.usedIn) {
117
+ if (usedIn.has(newId)) continue;
118
+ if (unusedFunctions.has(newFunc)) continue;
119
+ usedIn.set(newId, newFunc);
120
+ newFuncsAdded = true;
121
+ }
122
+ continue;
123
+ /* v8 ignore next -- @preserve */
124
+ default:
125
+ console.error(`[wyrm] Unexpected UsageKind: ${kind} (wyrm/no-unused-mutually-referential rule)`);
126
+ return false;
127
+ }
128
+ }
129
+ if (!newFuncsAdded) break;
130
+ }
131
+ /* v8 ignore if -- @preserve */
132
+ if (gas === 0) console.error("[wyrm] Ran out of gas, which should probably never happen. This is probably an infinite loop bug in eslint-plugin-wyrm (wyrm/no-unused-mutually-referential rule)");
133
+ return true;
134
+ }
135
+ function getIdentUsage(node, getScope) {
136
+ if (node.type === AST_NODE_TYPES.JSXIdentifier) return DEFINITELY_USED;
137
+ switch (node.parent.type) {
138
+ case AST_NODE_TYPES.ExportSpecifier:
139
+ case AST_NODE_TYPES.ExportDefaultDeclaration: return DEFINITELY_USED;
140
+ case AST_NODE_TYPES.ExpressionStatement: return DEFINITELY_UNUSED;
141
+ case AST_NODE_TYPES.CallExpression: return DEFINITELY_USED;
142
+ case AST_NODE_TYPES.VariableDeclarator:
143
+ if (node.parent.id === node) {
144
+ const scope = getScope(node);
145
+ const variable = ASTUtils.findVariable(scope, node);
146
+ /* v8 ignore if -- @preserve */
147
+ if (!variable) return DEFINITELY_UNUSED;
148
+ if (!variable.references.some((ref) => ref.isRead())) return DEFINITELY_UNUSED;
149
+ return DEFINITELY_USED;
150
+ }
151
+ if (node.parent.id.type === AST_NODE_TYPES.Identifier) return getIdentUsage(node.parent.id, getScope);
152
+ return DEFINITELY_USED;
153
+ default: return DEFINITELY_USED;
154
+ }
155
+ }
156
+ function getIdentifiedFunction(node) {
157
+ const { type } = node;
158
+ switch (type) {
159
+ case AST_NODE_TYPES.FunctionDeclaration: return getIdentifiedFunctionDecl(node);
160
+ case AST_NODE_TYPES.FunctionExpression:
161
+ case AST_NODE_TYPES.ArrowFunctionExpression: return getIdentifiedFunctionExpr(node);
162
+ /* v8 ignore next -- @preserve */
163
+ default:
164
+ console.error(`[wyrm] Unexpected type: ${type} (wyrm/no-unused-mutually-referential rule)`);
165
+ return None;
166
+ }
167
+ }
168
+ function getIdentifiedFunctionDecl(decl) {
169
+ if (!decl.id) return None;
170
+ return Some({
171
+ id: decl.id,
172
+ node: decl
173
+ });
174
+ }
175
+ function getIdentifiedFunctionExpr(expr) {
176
+ if (expr.parent.type !== AST_NODE_TYPES.VariableDeclarator) return None;
177
+ if (expr.parent.id.type !== AST_NODE_TYPES.Identifier) return None;
178
+ return Some({
179
+ id: expr.parent.id,
180
+ node: expr
181
+ });
182
+ }
183
+ function isExported(fn) {
184
+ const { type } = fn.node;
185
+ switch (type) {
186
+ case AST_NODE_TYPES.FunctionDeclaration: return fn.node.parent.type === AST_NODE_TYPES.ExportNamedDeclaration || fn.node.parent.type === AST_NODE_TYPES.ExportDefaultDeclaration;
187
+ case AST_NODE_TYPES.FunctionExpression:
188
+ case AST_NODE_TYPES.ArrowFunctionExpression: {
189
+ let node = fn.node;
190
+ while (node) {
191
+ if (node.type === AST_NODE_TYPES.ExportNamedDeclaration) return true;
192
+ node = node.parent;
193
+ }
194
+ return false;
195
+ }
196
+ /* v8 ignore next -- @preserve */
197
+ default:
198
+ console.error(`[wyrm] Unexpected type: ${type} (wyrm/no-unused-mutually-referential rule)`);
199
+ return false;
200
+ }
201
+ }
202
+ function getParentFunction(node) {
203
+ let currentNode = node;
204
+ let gas = 1e3;
205
+ while (currentNode && gas > 0) {
206
+ gas--;
207
+ if (currentNode.type === AST_NODE_TYPES.FunctionDeclaration || currentNode.type === AST_NODE_TYPES.FunctionExpression || currentNode.type === AST_NODE_TYPES.ArrowFunctionExpression) return getIdentifiedFunction(currentNode);
208
+ currentNode = currentNode.parent;
209
+ }
210
+ /* v8 ignore if -- @preserve */
211
+ if (gas === 0) console.error("[wyrm] Ran out of gas while climbing up the parent chain. Unless your AST is extremely nested, this is probably an infinite loop bug in eslint-plugin-wyrm (wyrm/no-unused-mutually-referential rule)");
212
+ return None;
213
+ }
214
+ //#endregion
215
+ export { no_unused_mutually_referential_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint67 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/no-unused-param-read.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint67.RuleModule<"noUnusedParamRead", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint67.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noUnusedParamRead", [], 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/no-unused-param-read.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  var no_unused_param_read_default = createRule({
@@ -29,6 +28,5 @@ var no_unused_param_read_default = createRule({
29
28
  } };
30
29
  }
31
30
  });
32
-
33
31
  //#endregion
34
- export { no_unused_param_read_default as default };
32
+ export { no_unused_param_read_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint69 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/no-useless-computed-key.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint69.RuleModule<"noUselessComputedKey", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint69.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noUselessComputedKey", [], 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/no-useless-computed-key.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  var no_useless_computed_key_default = createRule({
@@ -34,6 +33,5 @@ var no_useless_computed_key_default = createRule({
34
33
  } };
35
34
  }
36
35
  });
37
-
38
36
  //#endregion
39
- export { no_useless_computed_key_default as default };
37
+ export { no_useless_computed_key_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint71 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/no-useless-iife.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint71.RuleModule<"noUselessIIFE" | "removeIIFE", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint71.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noUselessIIFE" | "removeIIFE", [], 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/no-useless-iife.ts
7
6
  const { name } = path.parse(import.meta.filename);
8
7
  var no_useless_iife_default = createRule({
@@ -163,11 +162,11 @@ function nodeHasAwait(node) {
163
162
  case AST_NODE_TYPES.ExportAllDeclaration:
164
163
  case AST_NODE_TYPES.ExportSpecifier:
165
164
  case AST_NODE_TYPES.ExportDefaultDeclaration: return false;
165
+ /* v8 ignore next -- @preserve */
166
166
  default:
167
167
  if (process.env["NODE_ENV"] === "test") console.error(node.type);
168
168
  return true;
169
169
  }
170
170
  }
171
-
172
171
  //#endregion
173
- export { no_useless_iife_default as default };
172
+ export { no_useless_iife_default as default };
@@ -2,7 +2,6 @@ import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
2
  import { ESLintUtils } from "@typescript-eslint/utils";
3
3
 
4
4
  //#region lib/rules/no-useless-logical-fallback.d.ts
5
-
6
5
  declare const _default: ESLintUtils.RuleModule<"noConstantExpression" | "noUselessLogicalFallback" | "removeLogicalFallback" | "noNumberOrZero" | "replaceByIsNaNCheck" | "replaceByTrue", [], WyrmPluginDocs, ESLintUtils.RuleListener> & {
7
6
  name: string;
8
7
  };