eslint-plugin-wyrm 0.0.6 β†’ 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.7](https://github.com/mchevestrier/eslint-plugin-wyrm/compare/eslint-plugin-wyrm-v0.0.6...eslint-plugin-wyrm-v0.0.7) (2025-11-05)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * add distribute-boolean-casts ([a6a7a1d](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/a6a7a1d34fe2dca977bd98fb27337797ce1b1200))
9
+ * add prefer-catch-method ([fb1b614](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/fb1b614f2a2e53c8e2ca197b706f458cbe73ba4a))
10
+
3
11
  ## [0.0.6](https://github.com/mchevestrier/eslint-plugin-wyrm/compare/eslint-plugin-wyrm-v0.0.5...eslint-plugin-wyrm-v0.0.6) (2025-11-04)
4
12
 
5
13
 
package/README.md CHANGED
@@ -49,21 +49,23 @@ export default defineConfig([
49
49
  πŸ’‘ Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
50
50
  πŸ’­ Requires [type information](https://typescript-eslint.io/linting/typed-linting).
51
51
 
52
- | NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  | Description | πŸ’Ό | πŸ”§ | πŸ’‘ | πŸ’­ |
53
- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- | :---------- | :-- | :-- | :-- |
54
- | [no-constant-template-expression](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-constant-template-expression.md) | Disallow constant string expressions in template literals | β˜‘οΈ | | πŸ’‘ | πŸ’­ |
55
- | [no-else-break](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-break.md) | Forbid unnecessary `else` block after a `break` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
56
- | [no-else-continue](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-continue.md) | Forbid unnecessary `else` block after a `continue` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
57
- | [no-else-throw](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-throw.md) | Forbid unnecessary `else` block after a `throw` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
58
- | [no-empty-comment](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-empty-comment.md) | Forbid empty comments | πŸŸͺ β˜‘οΈ | | | |
59
- | [no-empty-jsx-expression](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-empty-jsx-expression.md) | Forbid empty JSX expression containers | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
60
- | [no-extra-nested-boolean-cast](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-extra-nested-boolean-cast.md) | Forbid extra boolean casts in conditions and predicates | πŸŸͺ β˜‘οΈ | | | |
61
- | [no-invalid-date-literal](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-invalid-date-literal.md) | Disallow invalid date literals | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
62
- | [no-jsx-statement](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-jsx-statement.md) | Forbid JSX expression statements | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
63
- | [no-suspicious-jsx-semicolon](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-suspicious-jsx-semicolon.md) | Forbid suspicious semicolons in JSX | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
64
- | [no-ternary-return](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-ternary-return.md) | Disallow ternary conditions in return statements | πŸŸͺ β˜‘οΈ | πŸ”§ | | |
65
- | [no-useless-iife](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-useless-iife.md) | Forbid useless IIFEs | 🟩 βœ… πŸŸͺ β˜‘οΈ | | πŸ’‘ | |
66
- | [prefer-repeat](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/prefer-repeat.md) | Enforce usage of `String.prototype.repeat` | 🟩 βœ… πŸŸͺ β˜‘οΈ | | πŸ’‘ | |
67
- | [unsafe-asserted-chain](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/unsafe-asserted-chain.md) | Disallow unsafe type assertions on optional chained expressions | β˜‘οΈ | | | πŸ’­ |
52
+ | NameΒ Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  | Description | πŸ’Ό | πŸ”§ | πŸ’‘ | πŸ’­ |
53
+ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :---------- | :-- | :-- | :-- |
54
+ | [distribute-boolean-casts](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/distribute-boolean-casts.md) | Enforce that boolean casts are distributed over logical expressions | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
55
+ | [no-constant-template-expression](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-constant-template-expression.md) | Disallow constant string expressions in template literals | β˜‘οΈ | | πŸ’‘ | πŸ’­ |
56
+ | [no-else-break](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-break.md) | Forbid unnecessary `else` block after a `break` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
57
+ | [no-else-continue](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-continue.md) | Forbid unnecessary `else` block after a `continue` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
58
+ | [no-else-throw](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-else-throw.md) | Forbid unnecessary `else` block after a `throw` statement | 🟩 βœ… πŸŸͺ β˜‘οΈ | πŸ”§ | | |
59
+ | [no-empty-comment](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-empty-comment.md) | Forbid empty comments | πŸŸͺ β˜‘οΈ | | | |
60
+ | [no-empty-jsx-expression](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-empty-jsx-expression.md) | Forbid empty JSX expression containers | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
61
+ | [no-extra-nested-boolean-cast](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-extra-nested-boolean-cast.md) | Forbid extra boolean casts in conditions and predicates | πŸŸͺ β˜‘οΈ | | | |
62
+ | [no-invalid-date-literal](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-invalid-date-literal.md) | Disallow invalid date literals | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
63
+ | [no-jsx-statement](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-jsx-statement.md) | Forbid JSX expression statements | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
64
+ | [no-suspicious-jsx-semicolon](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-suspicious-jsx-semicolon.md) | Forbid suspicious semicolons in JSX | 🟩 βœ… πŸŸͺ β˜‘οΈ | | | |
65
+ | [no-ternary-return](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-ternary-return.md) | Disallow ternary conditions in return statements | πŸŸͺ β˜‘οΈ | πŸ”§ | | |
66
+ | [no-useless-iife](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-useless-iife.md) | Forbid useless IIFEs | 🟩 βœ… πŸŸͺ β˜‘οΈ | | πŸ’‘ | |
67
+ | [prefer-catch-method](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/prefer-catch-method.md) | Enforce usage of `Promise.prototype.catch()` when it improves readability | 🟩 βœ… πŸŸͺ β˜‘οΈ | | πŸ’‘ | |
68
+ | [prefer-repeat](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/prefer-repeat.md) | Enforce usage of `String.prototype.repeat` | 🟩 βœ… πŸŸͺ β˜‘οΈ | | πŸ’‘ | |
69
+ | [unsafe-asserted-chain](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/unsafe-asserted-chain.md) | Disallow unsafe type assertions on optional chained expressions | β˜‘οΈ | | | πŸ’­ |
68
70
 
69
71
  <!-- end auto-generated rules list -->
@@ -0,0 +1,7 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.js";
2
+ import * as _typescript_eslint_utils_ts_eslint1 from "@typescript-eslint/utils/ts-eslint";
3
+
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>;
6
+ //#endregion
7
+ export { _default };
@@ -0,0 +1,83 @@
1
+ import { createRule } from "../utils/createRule.js";
2
+ import { None, Some } from "../utils/option.js";
3
+ import path from "node:path";
4
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
5
+
6
+ //#region lib/rules/distribute-boolean-casts.ts
7
+ const { name } = path.parse(import.meta.filename);
8
+ var distribute_boolean_casts_default = createRule({
9
+ name,
10
+ meta: {
11
+ type: "suggestion",
12
+ docs: {
13
+ description: "Enforce that boolean casts are distributed over logical expressions",
14
+ recommended: true
15
+ },
16
+ fixable: "code",
17
+ schema: [],
18
+ messages: { distributeBooleanCast: "Distribute this boolean cast over logical expressions" }
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ return { LogicalExpression(node) {
23
+ if (node.operator === "??") return;
24
+ const parentCast = getParentBooleanCast(node);
25
+ if (!parentCast.some) return;
26
+ context.report({
27
+ node,
28
+ messageId: "distributeBooleanCast",
29
+ fix(fixer) {
30
+ const left = maybeWrapInBooleanCast(node.left);
31
+ const right = maybeWrapInBooleanCast(node.right);
32
+ const newText = `${left} ${node.operator} ${right}`;
33
+ return fixer.replaceText(parentCast.value, newText);
34
+ }
35
+ });
36
+ } };
37
+ function maybeWrapInBooleanCast(expr) {
38
+ const txt = context.sourceCode.getText(expr);
39
+ if (isBooleanLike(expr)) return txt;
40
+ return `!!(${txt})`;
41
+ }
42
+ }
43
+ });
44
+ function isBooleanLike(expr) {
45
+ if (expr.type === AST_NODE_TYPES.UnaryExpression) return expr.operator === "!";
46
+ if (expr.type === AST_NODE_TYPES.BinaryExpression) switch (expr.operator) {
47
+ case "&&":
48
+ case "||":
49
+ case "!=":
50
+ case "!==":
51
+ case "==":
52
+ case "===":
53
+ case "<":
54
+ case "<=":
55
+ case ">":
56
+ case ">=":
57
+ case "in":
58
+ case "instanceof": return true;
59
+ default: return false;
60
+ }
61
+ if (expr.type === AST_NODE_TYPES.Literal) return typeof expr.value === "boolean";
62
+ return false;
63
+ }
64
+ function getParentBooleanCast(node) {
65
+ if (!node.parent) return None;
66
+ if (node.parent.type === AST_NODE_TYPES.UnaryExpression && isDoubleNegation(node.parent)) return Some(node.parent.parent);
67
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && isBooleanCall(node.parent)) return Some(node.parent);
68
+ return None;
69
+ }
70
+ function isDoubleNegation(node) {
71
+ if (node.operator !== "!") return false;
72
+ if (node.parent.type !== AST_NODE_TYPES.UnaryExpression) return false;
73
+ if (node.parent.operator !== "!") return false;
74
+ return true;
75
+ }
76
+ function isBooleanCall(node) {
77
+ if (node.callee.type !== AST_NODE_TYPES.Identifier) return false;
78
+ if (node.callee.name !== "Boolean") return false;
79
+ return true;
80
+ }
81
+
82
+ //#endregion
83
+ export { distribute_boolean_casts_default as default };
@@ -1,21 +1,23 @@
1
- import { _default } from "./no-constant-template-expression.js";
2
- import { _default as _default$1 } from "./no-else-break.js";
3
- import { _default as _default$2 } from "./no-else-continue.js";
4
- import { _default as _default$3 } from "./no-else-throw.js";
5
- import { _default as _default$4 } from "./no-empty-comment.js";
6
- import { _default as _default$5 } from "./no-empty-jsx-expression.js";
7
- import { _default as _default$6 } from "./no-extra-nested-boolean-cast.js";
8
- import { _default as _default$7 } from "./no-invalid-date-literal.js";
9
- import { _default as _default$8 } from "./no-jsx-statement.js";
10
- import { _default as _default$9 } from "./no-suspicious-jsx-semicolon.js";
11
- import { _default as _default$10 } from "./no-ternary-return.js";
12
- import { _default as _default$11 } from "./no-useless-iife.js";
13
- import { _default as _default$12 } from "./prefer-repeat.js";
14
- import { _default as _default$13 } from "./unsafe-asserted-chain.js";
1
+ import { _default } from "./distribute-boolean-casts.js";
2
+ import { _default as _default$1 } from "./no-constant-template-expression.js";
3
+ import { _default as _default$2 } from "./no-else-break.js";
4
+ import { _default as _default$3 } from "./no-else-continue.js";
5
+ import { _default as _default$4 } from "./no-else-throw.js";
6
+ import { _default as _default$5 } from "./no-empty-comment.js";
7
+ import { _default as _default$6 } from "./no-empty-jsx-expression.js";
8
+ import { _default as _default$7 } from "./no-extra-nested-boolean-cast.js";
9
+ import { _default as _default$8 } from "./no-invalid-date-literal.js";
10
+ import { _default as _default$9 } from "./no-jsx-statement.js";
11
+ import { _default as _default$10 } from "./no-suspicious-jsx-semicolon.js";
12
+ import { _default as _default$11 } from "./no-ternary-return.js";
13
+ import { _default as _default$12 } from "./no-useless-iife.js";
14
+ import { _default as _default$13 } from "./prefer-catch-method.js";
15
+ import { _default as _default$14 } from "./prefer-repeat.js";
16
+ import { _default as _default$15 } from "./unsafe-asserted-chain.js";
15
17
 
16
18
  //#region lib/rules/index.d.ts
17
19
  declare namespace index_d_exports {
18
- export { _default as "no-constant-template-expression", _default$1 as "no-else-break", _default$2 as "no-else-continue", _default$3 as "no-else-throw", _default$4 as "no-empty-comment", _default$5 as "no-empty-jsx-expression", _default$6 as "no-extra-nested-boolean-cast", _default$7 as "no-invalid-date-literal", _default$8 as "no-jsx-statement", _default$9 as "no-suspicious-jsx-semicolon", _default$10 as "no-ternary-return", _default$11 as "no-useless-iife", _default$12 as "prefer-repeat", _default$13 as "unsafe-asserted-chain" };
20
+ export { _default as "distribute-boolean-casts", _default$1 as "no-constant-template-expression", _default$2 as "no-else-break", _default$3 as "no-else-continue", _default$4 as "no-else-throw", _default$5 as "no-empty-comment", _default$6 as "no-empty-jsx-expression", _default$7 as "no-extra-nested-boolean-cast", _default$8 as "no-invalid-date-literal", _default$9 as "no-jsx-statement", _default$10 as "no-suspicious-jsx-semicolon", _default$11 as "no-ternary-return", _default$12 as "no-useless-iife", _default$13 as "prefer-catch-method", _default$14 as "prefer-repeat", _default$15 as "unsafe-asserted-chain" };
19
21
  }
20
22
  //#endregion
21
23
  export { index_d_exports };
@@ -1,4 +1,5 @@
1
1
  import { __export } from "../_virtual/rolldown_runtime.js";
2
+ import distribute_boolean_casts_default from "./distribute-boolean-casts.js";
2
3
  import no_constant_template_expression_default from "./no-constant-template-expression.js";
3
4
  import no_else_break_default from "./no-else-break.js";
4
5
  import no_else_continue_default from "./no-else-continue.js";
@@ -11,11 +12,13 @@ import no_jsx_statement_default from "./no-jsx-statement.js";
11
12
  import no_suspicious_jsx_semicolon_default from "./no-suspicious-jsx-semicolon.js";
12
13
  import no_ternary_return_default from "./no-ternary-return.js";
13
14
  import no_useless_iife_default from "./no-useless-iife.js";
15
+ import prefer_catch_method_default from "./prefer-catch-method.js";
14
16
  import prefer_repeat_default from "./prefer-repeat.js";
15
17
  import unsafe_asserted_chain_default from "./unsafe-asserted-chain.js";
16
18
 
17
19
  //#region lib/rules/index.ts
18
20
  var rules_exports = /* @__PURE__ */ __export({
21
+ "distribute-boolean-casts": () => distribute_boolean_casts_default,
19
22
  "no-constant-template-expression": () => no_constant_template_expression_default,
20
23
  "no-else-break": () => no_else_break_default,
21
24
  "no-else-continue": () => no_else_continue_default,
@@ -28,6 +31,7 @@ var rules_exports = /* @__PURE__ */ __export({
28
31
  "no-suspicious-jsx-semicolon": () => no_suspicious_jsx_semicolon_default,
29
32
  "no-ternary-return": () => no_ternary_return_default,
30
33
  "no-useless-iife": () => no_useless_iife_default,
34
+ "prefer-catch-method": () => prefer_catch_method_default,
31
35
  "prefer-repeat": () => prefer_repeat_default,
32
36
  "unsafe-asserted-chain": () => unsafe_asserted_chain_default
33
37
  });
@@ -1,7 +1,7 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint1 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint5 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-else-continue.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint1.RuleModule<"noElseContinue", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint1.RuleListener>;
5
+ declare const _default: _typescript_eslint_utils_ts_eslint5.RuleModule<"noElseContinue", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint5.RuleListener>;
6
6
  //#endregion
7
7
  export { _default };
@@ -1,7 +1,7 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint3 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint7 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-else-throw.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint3.RuleModule<"noElseThrow", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint3.RuleListener>;
5
+ declare const _default: _typescript_eslint_utils_ts_eslint7.RuleModule<"noElseThrow", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint7.RuleListener>;
6
6
  //#endregion
7
7
  export { _default };
@@ -1,9 +1,9 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint5 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint9 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-empty-comment.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint5.RuleModule<"noEmptyComment", [{
5
+ declare const _default: _typescript_eslint_utils_ts_eslint9.RuleModule<"noEmptyComment", [{
6
6
  allowStacked: boolean;
7
- }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint5.RuleListener>;
7
+ }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint9.RuleListener>;
8
8
  //#endregion
9
9
  export { _default };
@@ -1,7 +1,7 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint7 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint11 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-empty-jsx-expression.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint7.RuleModule<"noEmptyJsxExpression", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint7.RuleListener>;
5
+ declare const _default: _typescript_eslint_utils_ts_eslint11.RuleModule<"noEmptyJsxExpression", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint11.RuleListener>;
6
6
  //#endregion
7
7
  export { _default };
@@ -38,6 +38,7 @@ var no_empty_jsx_expression_default = createRule({
38
38
  return;
39
39
  default: return;
40
40
  }
41
+ if (node.parent.type === AST_NODE_TYPES.JSXAttribute) return;
41
42
  context.report({
42
43
  node,
43
44
  messageId: "noEmptyJsxExpression"
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint9 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint15 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-extra-nested-boolean-cast.d.ts
5
5
 
6
- declare const _default: _typescript_eslint_utils_ts_eslint9.RuleModule<"noExtraBooleanCastInCondition" | "noExtraBooleanCastInPredicate" | "noExtraBooleanCastInsideAnother", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint9.RuleListener>;
6
+ declare const _default: _typescript_eslint_utils_ts_eslint15.RuleModule<"noExtraBooleanCastInCondition" | "noExtraBooleanCastInPredicate" | "noExtraBooleanCastInsideAnother", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint15.RuleListener>;
7
7
  //#endregion
8
8
  export { _default };
@@ -1,7 +1,7 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint11 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint3 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_eslint11.RuleModule<"noInvalidDateLiteral", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint11.RuleListener>;
5
+ declare const _default: _typescript_eslint_utils_ts_eslint3.RuleModule<"noInvalidDateLiteral", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint3.RuleListener>;
6
6
  //#endregion
7
7
  export { _default };
@@ -19,6 +19,8 @@ var no_invalid_date_literal_default = createRule({
19
19
  create(context) {
20
20
  return {
21
21
  NewExpression(node) {
22
+ if (node.callee.type !== AST_NODE_TYPES.Identifier) return;
23
+ if (node.callee.name !== "Date") return;
22
24
  if (node.arguments.length > 1) return;
23
25
  const [arg] = node.arguments;
24
26
  if (!arg) return;
@@ -1,8 +1,8 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint15 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint17 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-suspicious-jsx-semicolon.d.ts
5
5
 
6
- declare const _default: _typescript_eslint_utils_ts_eslint15.RuleModule<"noSuspiciousJsxSemicolon" | "noSuspiciousJsxComma", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint15.RuleListener>;
6
+ declare const _default: _typescript_eslint_utils_ts_eslint17.RuleModule<"noSuspiciousJsxSemicolon" | "noSuspiciousJsxComma", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint17.RuleListener>;
7
7
  //#endregion
8
8
  export { _default };
@@ -1,9 +1,10 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint17 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint25 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/no-ternary-return.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint17.RuleModule<"noTernaryReturn", [{
5
+
6
+ declare const _default: _typescript_eslint_utils_ts_eslint25.RuleModule<"noTernaryReturn", [{
6
7
  allowSingleLine: boolean;
7
- }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint17.RuleListener>;
8
+ }], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint25.RuleListener>;
8
9
  //#endregion
9
10
  export { _default };
@@ -0,0 +1,7 @@
1
+ import { WyrmPluginDocs } from "../utils/createRule.js";
2
+ import * as _typescript_eslint_utils_ts_eslint21 from "@typescript-eslint/utils/ts-eslint";
3
+
4
+ //#region lib/rules/prefer-catch-method.d.ts
5
+ declare const _default: _typescript_eslint_utils_ts_eslint21.RuleModule<"preferCatchMethod" | "useCatchMethod", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint21.RuleListener>;
6
+ //#endregion
7
+ export { _default };
@@ -0,0 +1,121 @@
1
+ import { createRule } from "../utils/createRule.js";
2
+ import path from "node:path";
3
+ import { ASTUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
4
+
5
+ //#region lib/rules/prefer-catch-method.ts
6
+ const { name } = path.parse(import.meta.filename);
7
+ var prefer_catch_method_default = createRule({
8
+ name,
9
+ meta: {
10
+ type: "suggestion",
11
+ docs: {
12
+ description: "Enforce usage of `Promise.prototype.catch()` when it improves readability",
13
+ recommended: true
14
+ },
15
+ hasSuggestions: true,
16
+ schema: [],
17
+ messages: {
18
+ preferCatchMethod: "Prefer the `Promise.prototype.catch()` method to avoid imperative patterns",
19
+ useCatchMethod: "Replace by `.catch()`"
20
+ }
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ return { TryStatement(node) {
25
+ const { block, handler, finalizer } = node;
26
+ if (!handler) return;
27
+ function hasReturnStatement(body) {
28
+ return body.some((stmt) => stmt.type === AST_NODE_TYPES.ReturnStatement);
29
+ }
30
+ function getAssignments(body) {
31
+ const assignments = [];
32
+ for (const stmt of body) {
33
+ if (stmt.type !== AST_NODE_TYPES.ExpressionStatement) continue;
34
+ if (stmt.expression.type !== AST_NODE_TYPES.AssignmentExpression) continue;
35
+ assignments.push(stmt.expression);
36
+ }
37
+ return assignments;
38
+ }
39
+ if (hasReturnStatement(handler.body.body)) return;
40
+ if (finalizer && hasReturnStatement(finalizer.body)) return;
41
+ const [firstBlockAssignment, ...otherBlockAssignments] = getAssignments(block.body);
42
+ if (!firstBlockAssignment) return;
43
+ if (firstBlockAssignment.right.type !== AST_NODE_TYPES.AwaitExpression) return;
44
+ if (otherBlockAssignments.some((assignment) => assignment.right.type === AST_NODE_TYPES.AwaitExpression)) return;
45
+ if (firstBlockAssignment.left.type !== AST_NODE_TYPES.Identifier) return;
46
+ const variableName = firstBlockAssignment.left.name;
47
+ const handlerAssignment = getAssignments(handler.body.body).find((assignment) => assignment.left.type === AST_NODE_TYPES.Identifier && assignment.left.name === variableName);
48
+ if (!handlerAssignment) return;
49
+ const scope = context.sourceCode.getScope(node);
50
+ const variable = ASTUtils.findVariable(scope, variableName);
51
+ if (!variable) return;
52
+ if (variable.scope !== scope) return;
53
+ const def = variable.defs.at(-1);
54
+ if (!def) return;
55
+ if (def.node.type !== AST_NODE_TYPES.VariableDeclarator) return;
56
+ if (def.node.parent.kind !== "let") return;
57
+ const decl = def.node;
58
+ if (variable.references.some((ref) => ref.isRead() && ref.identifier.range[1] < node.range[0])) return;
59
+ const indent = " ".repeat(node.loc.start.column + 2);
60
+ const indent2 = `${indent}${" ".repeat(2)}`;
61
+ function isNameInScope(identifierName, currentScope = context.sourceCode.getScope(block)) {
62
+ if (currentScope.variables.some((v) => v.name === identifierName)) return true;
63
+ if (!currentScope.upper) return false;
64
+ return isNameInScope(identifierName, currentScope.upper);
65
+ }
66
+ function getFreeVariableName(n = 0) {
67
+ const identifierName = `val${n}`;
68
+ if (isNameInScope(identifierName)) return getFreeVariableName(n + 1);
69
+ return identifierName;
70
+ }
71
+ function getAwaitThenExpression() {
72
+ if (!firstBlockAssignment) return "";
73
+ const awaitExpression = context.sourceCode.getText(firstBlockAssignment.right);
74
+ const otherStatements = block.body.filter((stmt) => stmt.type !== AST_NODE_TYPES.ExpressionStatement || stmt.expression !== firstBlockAssignment);
75
+ if (!otherStatements.length) return awaitExpression;
76
+ const statementsText = otherStatements.map((stmt) => context.sourceCode.getText(stmt)).join(`\n${indent2}`);
77
+ const resultParamName = getFreeVariableName();
78
+ return `${awaitExpression}
79
+ ${indent}.then((${resultParamName}) => {
80
+ ${indent2}${statementsText}
81
+ ${indent2}return ${resultParamName};
82
+ ${indent}})`;
83
+ }
84
+ function getErrorParameter() {
85
+ if (!handler) return "";
86
+ const { param } = handler;
87
+ if (!param) return "";
88
+ const paramText = context.sourceCode.getText(param);
89
+ if (param.typeAnnotation) return paramText;
90
+ return `${paramText}: unknown`;
91
+ }
92
+ function getHandlerText() {
93
+ if (!handler) return "";
94
+ if (!handlerAssignment) return "";
95
+ const handlerAssignmentText = `${indent}return ${context.sourceCode.getText(handlerAssignment.right)};`;
96
+ const statements = handler.body.body.filter((stmt) => stmt.type !== AST_NODE_TYPES.ExpressionStatement || stmt.expression !== handlerAssignment);
97
+ if (!statements.length) return handlerAssignmentText;
98
+ return `${indent}${statements.map((stmt) => context.sourceCode.getText(stmt)).join(`\n${indent2}`)}\n${indent}${handlerAssignmentText}`;
99
+ }
100
+ context.report({
101
+ node,
102
+ messageId: "preferCatchMethod",
103
+ suggest: [{
104
+ messageId: "useCatchMethod",
105
+ *fix(fixer) {
106
+ if (decl.parent.declarations.length > 1) yield fixer.remove(decl);
107
+ else yield fixer.remove(decl.parent);
108
+ const errorParam = getErrorParameter();
109
+ const handlerText = getHandlerText();
110
+ const awaitThenExpression = getAwaitThenExpression();
111
+ yield fixer.remove(node);
112
+ yield fixer.insertTextBefore(node, `let ${variableName} = ${awaitThenExpression}\n${indent}.catch((${errorParam}) => {\n ${handlerText}\n });`);
113
+ }
114
+ }]
115
+ });
116
+ } };
117
+ }
118
+ });
119
+
120
+ //#endregion
121
+ export { prefer_catch_method_default as default };
@@ -1,7 +1,7 @@
1
1
  import { WyrmPluginDocs } from "../utils/createRule.js";
2
- import * as _typescript_eslint_utils_ts_eslint21 from "@typescript-eslint/utils/ts-eslint";
2
+ import * as _typescript_eslint_utils_ts_eslint23 from "@typescript-eslint/utils/ts-eslint";
3
3
 
4
4
  //#region lib/rules/prefer-repeat.d.ts
5
- declare const _default: _typescript_eslint_utils_ts_eslint21.RuleModule<"preferRepeat" | "replaceByRepeat", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint21.RuleListener>;
5
+ declare const _default: _typescript_eslint_utils_ts_eslint23.RuleModule<"preferRepeat" | "replaceByRepeat", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint23.RuleListener>;
6
6
  //#endregion
7
7
  export { _default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-wyrm",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Some custom ESLint rules",
5
5
  "keywords": [
6
6
  "eslint",