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,91 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import { None, Option, Some, getFirstOption } from "../utils/option.mjs";
3
+ import path from "node:path";
4
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
5
+ //#region lib/rules/no-if-length-for.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ var no_if_length_for_default = createRule({
8
+ name,
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Forbid redundant condition for positive length before a loop",
13
+ recommended: true
14
+ },
15
+ fixable: "code",
16
+ schema: [],
17
+ messages: { noIfLengthFor: "You don't need to check that an array is not empty before a for loop" }
18
+ },
19
+ defaultOptions: [],
20
+ create(context) {
21
+ return { IfStatement(node) {
22
+ if (node.alternate) return;
23
+ const maybeIdent = getArrayIdent(node.test);
24
+ if (!maybeIdent.some) return;
25
+ const ident = maybeIdent.value;
26
+ const maybeStmt = getUniqueStatement(node.consequent);
27
+ if (!maybeStmt.some) return;
28
+ const stmt = maybeStmt.value;
29
+ if (!matchLoopWithIdent(stmt, ident)) return;
30
+ context.report({
31
+ node,
32
+ messageId: "noIfLengthFor",
33
+ fix(fixer) {
34
+ const text = context.sourceCode.getText(stmt);
35
+ return fixer.replaceText(node, text);
36
+ }
37
+ });
38
+ } };
39
+ }
40
+ });
41
+ function matchLoopWithIdent(stmt, ident) {
42
+ return matchForLoopWithIdent(stmt, ident) || matchForEachLoopWithIdent(stmt, ident);
43
+ }
44
+ function matchForLoopWithIdent(stmt, ident) {
45
+ if (stmt.type !== AST_NODE_TYPES.ForOfStatement) return false;
46
+ if (stmt.right.type !== AST_NODE_TYPES.Identifier) return false;
47
+ if (stmt.right.name !== ident) return false;
48
+ return true;
49
+ }
50
+ function matchForEachLoopWithIdent(stmt, ident) {
51
+ if (stmt.type !== AST_NODE_TYPES.ExpressionStatement) return false;
52
+ if (stmt.expression.type !== AST_NODE_TYPES.CallExpression) return false;
53
+ if (stmt.expression.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
54
+ if (stmt.expression.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
55
+ if (stmt.expression.callee.property.name !== "forEach") return false;
56
+ if (stmt.expression.callee.object.type !== AST_NODE_TYPES.Identifier) return false;
57
+ if (stmt.expression.callee.object.name !== ident) return false;
58
+ return true;
59
+ }
60
+ function getArrayIdent(test) {
61
+ return getFirstOption([extractIdentFromLengthAccess(test), extractIdentFromPositiveLengthCheck(test)]);
62
+ }
63
+ function extractIdentFromLengthAccess(test) {
64
+ if (test.type !== AST_NODE_TYPES.MemberExpression) return None;
65
+ if (test.property.type !== AST_NODE_TYPES.Identifier) return None;
66
+ if (test.property.name !== "length") return None;
67
+ if (test.object.type !== AST_NODE_TYPES.Identifier) return None;
68
+ return Some(test.object.name);
69
+ }
70
+ function extractIdentFromPositiveLengthCheck(test) {
71
+ if (test.type !== AST_NODE_TYPES.BinaryExpression) return None;
72
+ switch (test.operator) {
73
+ case "!=":
74
+ case "!==": return getFirstOption([extractIdentFromLengthComparison(test.left, test.right), extractIdentFromLengthComparison(test.right, test.left)]);
75
+ case ">": return extractIdentFromLengthComparison(test.left, test.right);
76
+ case "<": return extractIdentFromLengthComparison(test.right, test.left);
77
+ default: return None;
78
+ }
79
+ }
80
+ function extractIdentFromLengthComparison(left, right) {
81
+ if (right.type !== AST_NODE_TYPES.Literal) return None;
82
+ if (right.value !== 0) return None;
83
+ return extractIdentFromLengthAccess(left);
84
+ }
85
+ function getUniqueStatement(stmt) {
86
+ if (stmt.type !== AST_NODE_TYPES.BlockStatement) return Some(stmt);
87
+ if (stmt.body.length !== 1) return None;
88
+ return Option.fromUndef(stmt.body[0]);
89
+ }
90
+ //#endregion
91
+ export { no_if_length_for_default as default };
@@ -1,10 +1,10 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint39 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-inline-jsdoc-tag.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint39.RuleModule<"noInlineJsDocTags", [{
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noInlineJsDocTags", [{
6
6
  tags: string[];
7
- }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint39.RuleListener> & {
7
+ }], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
8
8
  name: string;
9
9
  };
10
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_TOKEN_TYPES } from "@typescript-eslint/utils";
4
-
5
4
  //#region lib/rules/no-inline-jsdoc-tag.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  const DEFAULT_ADDITIONAL_JSDOC_TAGS = [];
@@ -150,6 +149,5 @@ function getJsDocTags() {
150
149
  "yields"
151
150
  ];
152
151
  }
153
-
154
152
  //#endregion
155
- export { no_inline_jsdoc_tag_default as default };
153
+ export { no_inline_jsdoc_tag_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint41 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-invalid-date-literal.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint41.RuleModule<"noInvalidDateLiteral", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint41.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noInvalidDateLiteral", [], 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-invalid-date-literal.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  var no_invalid_date_literal_default = createRule({
@@ -17,6 +16,45 @@ var no_invalid_date_literal_default = createRule({
17
16
  },
18
17
  defaultOptions: [],
19
18
  create(context) {
19
+ function checkDateParse(node) {
20
+ const { callee } = node;
21
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) return;
22
+ if (callee.object.type !== AST_NODE_TYPES.Identifier) return;
23
+ if (callee.property.type !== AST_NODE_TYPES.Identifier) return;
24
+ if (callee.object.name !== "Date") return;
25
+ if (callee.property.name !== "parse") return;
26
+ const [arg] = node.arguments;
27
+ if (!arg) return;
28
+ if (arg.type !== AST_NODE_TYPES.Literal) return;
29
+ if (typeof arg.value === "string") {
30
+ if (isValidDateLiteral(arg.value)) return;
31
+ context.report({
32
+ node,
33
+ messageId: "noInvalidDateLiteral"
34
+ });
35
+ }
36
+ }
37
+ function checkPlainDateFrom(node) {
38
+ const { callee } = node;
39
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) return;
40
+ if (callee.object.type !== AST_NODE_TYPES.MemberExpression) return;
41
+ if (callee.property.type !== AST_NODE_TYPES.Identifier) return;
42
+ if (callee.object.object.type !== AST_NODE_TYPES.Identifier) return;
43
+ if (callee.object.property.type !== AST_NODE_TYPES.Identifier) return;
44
+ if (callee.object.object.name !== "Temporal") return;
45
+ if (callee.object.property.name !== "PlainDate") return;
46
+ if (callee.property.name !== "from") return;
47
+ const [arg] = node.arguments;
48
+ if (!arg) return;
49
+ if (arg.type !== AST_NODE_TYPES.Literal) return;
50
+ if (typeof arg.value === "string") {
51
+ if (isValidDateLiteral(arg.value)) return;
52
+ context.report({
53
+ node,
54
+ messageId: "noInvalidDateLiteral"
55
+ });
56
+ }
57
+ }
20
58
  return {
21
59
  NewExpression(node) {
22
60
  if (node.callee.type !== AST_NODE_TYPES.Identifier) return;
@@ -41,22 +79,8 @@ var no_invalid_date_literal_default = createRule({
41
79
  }
42
80
  },
43
81
  CallExpression(node) {
44
- const { callee } = node;
45
- if (callee.type !== AST_NODE_TYPES.MemberExpression) return;
46
- if (callee.object.type !== AST_NODE_TYPES.Identifier) return;
47
- if (callee.property.type !== AST_NODE_TYPES.Identifier) return;
48
- if (callee.object.name !== "Date") return;
49
- if (callee.property.name !== "parse") return;
50
- const [arg] = node.arguments;
51
- if (!arg) return;
52
- if (arg.type !== AST_NODE_TYPES.Literal) return;
53
- if (typeof arg.value === "string") {
54
- if (isValidDateLiteral(arg.value)) return;
55
- context.report({
56
- node,
57
- messageId: "noInvalidDateLiteral"
58
- });
59
- }
82
+ checkDateParse(node);
83
+ checkPlainDateFrom(node);
60
84
  }
61
85
  };
62
86
  }
@@ -65,6 +89,5 @@ function isValidDateLiteral(literal) {
65
89
  const value = new Date(literal).valueOf();
66
90
  return !Number.isNaN(value);
67
91
  }
68
-
69
92
  //#endregion
70
- export { no_invalid_date_literal_default as default };
93
+ export { no_invalid_date_literal_default as default };
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint43 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-jsx-statement.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint43.RuleModule<"noJsxExpressionStatement", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint43.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noJsxExpressionStatement", [], 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-jsx-statement.ts
6
5
  const { name } = path.parse(import.meta.filename);
7
6
  var no_jsx_statement_default = createRule({
@@ -26,6 +25,5 @@ var no_jsx_statement_default = createRule({
26
25
  } };
27
26
  }
28
27
  });
29
-
30
28
  //#endregion
31
- export { no_jsx_statement_default as default };
29
+ export { no_jsx_statement_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-lax-array-type.d.ts
5
+ declare const _default: TSESLint.RuleModule<"noLaxArrayType" | "removeType", [], WyrmPluginDocs, TSESLint.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,129 @@
1
+ import { createRule } from "../utils/createRule.mjs";
2
+ import path from "node:path";
3
+ import { ASTUtils, AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
+ import * as ts$1 from "typescript";
5
+ //#region lib/rules/no-lax-array-type.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ var no_lax_array_type_default = createRule({
8
+ name,
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Forbid declaring array types that are wider than the types of the actual elements",
13
+ requiresTypeChecking: true,
14
+ strict: true
15
+ },
16
+ hasSuggestions: true,
17
+ schema: [],
18
+ messages: {
19
+ noLaxArrayType: "This type is never used for any element, maybe you can remove it from the array type: {{unusedType}}",
20
+ removeType: "Remove {{unusedType}}"
21
+ }
22
+ },
23
+ defaultOptions: [],
24
+ create(context) {
25
+ let services;
26
+ function getServices() {
27
+ services ??= ESLintUtils.getParserServices(context);
28
+ return services;
29
+ }
30
+ let checker;
31
+ function getChecker() {
32
+ checker ??= getServices().program.getTypeChecker();
33
+ return checker;
34
+ }
35
+ return { VariableDeclarator(node) {
36
+ const { id } = node;
37
+ if (id.type !== AST_NODE_TYPES.Identifier) return;
38
+ if (node.parent.kind !== "const") return;
39
+ if (!id.typeAnnotation?.typeAnnotation) return;
40
+ if (node.init?.type !== AST_NODE_TYPES.ArrayExpression) return;
41
+ const scope = context.sourceCode.getScope(id);
42
+ const variable = ASTUtils.findVariable(scope, id);
43
+ /* v8 ignore next -- @preserve */
44
+ if (!variable) return;
45
+ if (variable.references.filter((ref) => isPossiblyMutatingReference(ref, id)).length > 1) return;
46
+ const estreeArrayTypeNode = id.typeAnnotation.typeAnnotation;
47
+ const tsArrayTypeNode = getServices().esTreeNodeToTSNodeMap.get(estreeArrayTypeNode);
48
+ const inferredElementTypes = inferAllElementTypes(node.init);
49
+ if (!inferredElementTypes.length) return;
50
+ const arrayElementsTypeNodes = getArrayElementsTypeNodes(tsArrayTypeNode);
51
+ for (const arrayTypeNode of arrayElementsTypeNodes) {
52
+ const arrayType = getChecker().getTypeFromTypeNode(arrayTypeNode);
53
+ if (inferredElementTypes.some((inferredElementType) => isAssignableTo(inferredElementType, arrayType))) continue;
54
+ const estreeNode = getServices().tsNodeToESTreeNodeMap.get(arrayTypeNode);
55
+ const typeAsString = arrayTypeNode.getText();
56
+ context.report({
57
+ node,
58
+ messageId: "noLaxArrayType",
59
+ data: { unusedType: typeAsString },
60
+ suggest: [{
61
+ messageId: "removeType",
62
+ data: { unusedType: typeAsString },
63
+ *fix(fixer) {
64
+ if (estreeNode.parent?.type === AST_NODE_TYPES.TSUnionType && estreeNode.parent.types[0] === estreeNode) {
65
+ const nextToken = context.sourceCode.getTokenAfter(estreeNode);
66
+ yield fixer.remove(estreeNode);
67
+ /* v8 ignore else -- @preserve */
68
+ if (nextToken) yield fixer.remove(nextToken);
69
+ return;
70
+ }
71
+ const previousToken = context.sourceCode.getTokenBefore(estreeNode);
72
+ yield fixer.remove(estreeNode);
73
+ /* v8 ignore else -- @preserve */
74
+ if (previousToken) yield fixer.remove(previousToken);
75
+ }
76
+ }]
77
+ });
78
+ }
79
+ } };
80
+ function inferAllElementTypes(array) {
81
+ return array.elements.map((elt) => {
82
+ if (!elt) return getChecker().getUndefinedType();
83
+ return getServices().getTypeAtLocation(elt);
84
+ });
85
+ }
86
+ function isAssignableTo(source, target) {
87
+ if (source.isUnion()) return source.types.some((t) => isAssignableTo(t, target));
88
+ return getChecker().isTypeAssignableTo(source, getChecker().getWidenedType(target));
89
+ }
90
+ }
91
+ });
92
+ function getArrayElementsTypeNodes(arrayTypeNode) {
93
+ const innerTypeNode = getArrayTypeNode(arrayTypeNode);
94
+ if (!innerTypeNode) return [];
95
+ return getUnionTypeNodes(innerTypeNode);
96
+ }
97
+ function getUnionTypeNodes(type) {
98
+ if (ts$1.isParenthesizedTypeNode(type)) return getUnionTypeNodes(type.type);
99
+ if (ts$1.isUnionTypeNode(type)) return [...type.types];
100
+ return [];
101
+ }
102
+ /** Extract the inner type node from an Array type node */
103
+ function getArrayTypeNode(arrayTypeNode) {
104
+ if (ts$1.isArrayTypeNode(arrayTypeNode)) return arrayTypeNode.elementType;
105
+ if (!ts$1.isTypeReferenceNode(arrayTypeNode)) return null;
106
+ if (!ts$1.isIdentifier(arrayTypeNode.typeName)) return null;
107
+ if (arrayTypeNode.typeName.escapedText.toString() !== "Array") return null;
108
+ const [typeArgNode] = arrayTypeNode.typeArguments ?? [];
109
+ if (!typeArgNode) return null;
110
+ return typeArgNode;
111
+ }
112
+ function isPossiblyMutatingReference(ref, id) {
113
+ if (ref.isWrite()) return true;
114
+ if (ref.identifier.parent.type !== AST_NODE_TYPES.MemberExpression || ref.identifier.parent.parent.type !== AST_NODE_TYPES.CallExpression || ref.identifier.parent.object.type !== AST_NODE_TYPES.Identifier || ref.identifier.parent.property.type !== AST_NODE_TYPES.Identifier || ref.identifier.parent.object.name !== id.name) return false;
115
+ if (ref.identifier.parent.property.name === "includes") return true;
116
+ return [
117
+ "copyWithin",
118
+ "fill",
119
+ "pop",
120
+ "push",
121
+ "reverse",
122
+ "shift",
123
+ "sort",
124
+ "splice",
125
+ "unshift"
126
+ ].includes(ref.identifier.parent.property.name);
127
+ }
128
+ //#endregion
129
+ export { no_lax_array_type_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/no-lax-return-type.d.ts
5
+ declare const _default: ESLintUtils.RuleModule<"removeType" | "noLaxReturnType", [], WyrmPluginDocs, ESLintUtils.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };
@@ -0,0 +1,138 @@
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 * as ts$1 from "typescript";
5
+ //#region lib/rules/no-lax-return-type.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ var no_lax_return_type_default = createRule({
8
+ name,
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Forbid declaring function return types that are wider than the types of the actual return values",
13
+ requiresTypeChecking: true,
14
+ strict: true
15
+ },
16
+ hasSuggestions: true,
17
+ schema: [],
18
+ messages: {
19
+ noLaxReturnType: "This type is never returned from the function, maybe you can remove it from the return type: {{unusedType}}",
20
+ removeType: "Remove {{unusedType}}"
21
+ }
22
+ },
23
+ defaultOptions: [],
24
+ create(context) {
25
+ let services;
26
+ function getServices() {
27
+ services ??= ESLintUtils.getParserServices(context);
28
+ return services;
29
+ }
30
+ let checker;
31
+ function getChecker() {
32
+ checker ??= getServices().program.getTypeChecker();
33
+ return checker;
34
+ }
35
+ return {
36
+ ArrowFunctionExpression: checkFunction,
37
+ FunctionExpression: checkFunction,
38
+ FunctionDeclaration: checkFunction
39
+ };
40
+ function inferAllReturnTypes(body, async) {
41
+ if (body.type !== AST_NODE_TYPES.BlockStatement) return [getServices().getTypeAtLocation(body)];
42
+ return getAllReturnStatements(body).map((stmt) => {
43
+ if (!stmt.argument) return getChecker().getVoidType();
44
+ const type = getServices().getTypeAtLocation(stmt.argument);
45
+ if (!async) return type;
46
+ return getChecker().getAwaitedType(type) ?? type;
47
+ });
48
+ }
49
+ function isAssignableTo(source, target) {
50
+ if (source.isUnion()) return source.types.some((t) => isAssignableTo(t, target));
51
+ return getChecker().isTypeAssignableTo(source, getChecker().getWidenedType(target));
52
+ }
53
+ function checkReturnTypeNode(returnTypeNode, inferredReturnTypes) {
54
+ const returnType = getChecker().getTypeFromTypeNode(returnTypeNode);
55
+ if (returnType.flags & ts$1.TypeFlags.Conditional) return;
56
+ if (inferredReturnTypes.some((inferredReturnType) => isAssignableTo(inferredReturnType, returnType))) return;
57
+ const estreeNode = getServices().tsNodeToESTreeNodeMap.get(returnTypeNode);
58
+ const typeAsString = returnTypeNode.getText();
59
+ context.report({
60
+ node: estreeNode,
61
+ messageId: "noLaxReturnType",
62
+ data: { unusedType: typeAsString },
63
+ suggest: [{
64
+ messageId: "removeType",
65
+ data: { unusedType: typeAsString },
66
+ *fix(fixer) {
67
+ if (estreeNode.parent?.type === AST_NODE_TYPES.TSUnionType && estreeNode.parent.types[0] === estreeNode) {
68
+ const nextToken = context.sourceCode.getTokenAfter(estreeNode);
69
+ yield fixer.remove(estreeNode);
70
+ /* v8 ignore else -- @preserve */
71
+ if (nextToken) yield fixer.remove(nextToken);
72
+ return;
73
+ }
74
+ const previousToken = context.sourceCode.getTokenBefore(estreeNode);
75
+ yield fixer.remove(estreeNode);
76
+ /* v8 ignore else -- @preserve */
77
+ if (previousToken) yield fixer.remove(previousToken);
78
+ }
79
+ }]
80
+ });
81
+ }
82
+ function checkFunction(node) {
83
+ if (!node.returnType) return;
84
+ if (node.generator) return;
85
+ if (node.parent.type === AST_NODE_TYPES.MethodDefinition) return;
86
+ const inferredReturnTypes = inferAllReturnTypes(node.body, node.async);
87
+ if (!inferredReturnTypes.length) return;
88
+ const sigs = getServices().getTypeAtLocation(node).getCallSignatures();
89
+ if (sigs.length > 1 && node.typeParameters) return;
90
+ for (const sig of sigs) {
91
+ const returnTypes = getUnionTypeNodes(sig.getDeclaration().type, node.async);
92
+ for (const returnTypeNode of returnTypes) checkReturnTypeNode(returnTypeNode, inferredReturnTypes);
93
+ }
94
+ }
95
+ }
96
+ });
97
+ function getUnionTypeNodes(type, async) {
98
+ /* v8 ignore if -- @preserve */
99
+ if (!type) return [];
100
+ if (async) {
101
+ const promiseTypeNode = getPromiseTypeNode(type);
102
+ if (!promiseTypeNode) return [];
103
+ return getUnionTypeNodes(promiseTypeNode, false);
104
+ }
105
+ if (ts$1.isUnionTypeNode(type)) return [...type.types];
106
+ return [type];
107
+ }
108
+ function getAllReturnStatements(stmt) {
109
+ if (stmt == null) return [];
110
+ switch (stmt.type) {
111
+ case AST_NODE_TYPES.ReturnStatement: return [stmt];
112
+ case AST_NODE_TYPES.BlockStatement: return stmt.body.flatMap((s) => getAllReturnStatements(s));
113
+ case AST_NODE_TYPES.IfStatement: return [...getAllReturnStatements(stmt.consequent), ...getAllReturnStatements(stmt.alternate)];
114
+ case AST_NODE_TYPES.SwitchStatement: return stmt.cases.flatMap((c) => c.consequent).flatMap((c) => getAllReturnStatements(c));
115
+ case AST_NODE_TYPES.ForInStatement:
116
+ case AST_NODE_TYPES.ForOfStatement:
117
+ case AST_NODE_TYPES.ForStatement:
118
+ case AST_NODE_TYPES.WhileStatement:
119
+ case AST_NODE_TYPES.DoWhileStatement: return getAllReturnStatements(stmt.body);
120
+ case AST_NODE_TYPES.TryStatement: return [
121
+ ...getAllReturnStatements(stmt.block),
122
+ ...getAllReturnStatements(stmt.handler?.body),
123
+ ...getAllReturnStatements(stmt.finalizer)
124
+ ];
125
+ default: return [];
126
+ }
127
+ }
128
+ /** Extract the inner type node from a Promise type node */
129
+ function getPromiseTypeNode(returnTypeNode) {
130
+ if (!ts$1.isTypeReferenceNode(returnTypeNode)) return null;
131
+ if (!ts$1.isIdentifier(returnTypeNode.typeName)) return null;
132
+ if (returnTypeNode.typeName.escapedText.toString() !== "Promise") return null;
133
+ const [typeArgNode] = returnTypeNode.typeArguments ?? [];
134
+ if (!typeArgNode) return null;
135
+ return typeArgNode;
136
+ }
137
+ //#endregion
138
+ export { no_lax_return_type_default as default };
@@ -1,9 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.mjs";
2
- import * as _typescript_eslint_utils_ts_eslint45 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-mutable-literal-fill.d.ts
5
-
6
- declare const _default: _typescript_eslint_utils_ts_eslint45.RuleModule<"noMutableLiteralFill", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint45.RuleListener> & {
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noMutableLiteralFill", [], 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-mutable-literal-fill.ts
6
5
  /**
7
6
  * @fileoverview
@@ -61,6 +60,5 @@ function isMutableLiteral(expr) {
61
60
  default: return false;
62
61
  }
63
62
  }
64
-
65
63
  //#endregion
66
- export { no_mutable_literal_fill_default as default };
64
+ export { no_mutable_literal_fill_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-nullish-ternary.d.ts
5
+ declare const _default: _$_typescript_eslint_utils_ts_eslint0.RuleModule<"noNullishTernary", [], WyrmPluginDocs, _$_typescript_eslint_utils_ts_eslint0.RuleListener> & {
6
+ name: string;
7
+ };
8
+ //#endregion
9
+ export { _default };