eslint-plugin-wyrm 0.0.4 → 0.0.5
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 +4 -17
- package/README.md +40 -15
- package/dist/configs/index.d.ts +2 -2
- package/dist/configs/index.js +3 -4
- package/dist/index.d.ts +5 -1
- package/dist/plugin.js +0 -2
- package/dist/rules/index.d.ts +8 -4
- package/dist/rules/index.js +8 -0
- package/dist/rules/no-constant-template-expression.d.ts +10 -0
- package/dist/rules/no-constant-template-expression.js +82 -0
- package/dist/rules/no-empty-comment.d.ts +9 -0
- package/dist/rules/no-empty-comment.js +57 -0
- package/dist/rules/no-empty-jsx-expression.d.ts +7 -0
- package/dist/rules/no-empty-jsx-expression.js +51 -0
- package/dist/rules/no-extra-nested-boolean-cast.d.ts +2 -2
- package/dist/rules/no-jsx-statement.d.ts +2 -2
- package/dist/rules/no-ternary-return.d.ts +9 -0
- package/dist/rules/no-ternary-return.js +51 -0
- package/docs/rules/no-constant-template-expression.md +83 -0
- package/docs/rules/no-empty-comment.md +70 -0
- package/docs/rules/no-empty-jsx-expression.md +77 -0
- package/docs/rules/no-extra-nested-boolean-cast.md +19 -17
- package/docs/rules/no-jsx-statement.md +7 -7
- package/docs/rules/no-ternary-return.md +46 -0
- package/docs/rules/unsafe-asserted-chain.md +11 -11
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,27 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.0.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
### Bug Fixes
|
|
7
|
-
|
|
8
|
-
* improve no-extra-nested-boolean-cast ([333d0f3](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/333d0f3bcc3aa73a329bb9ff60189490f96813cd))
|
|
9
|
-
|
|
10
|
-
## [0.0.3](https://github.com/mchevestrier/eslint-plugin-wyrm/compare/eslint-plugin-wyrm-v0.0.2...eslint-plugin-wyrm-v0.0.3) (2025-10-26)
|
|
3
|
+
## [0.0.5](https://github.com/mchevestrier/eslint-plugin-wyrm/compare/eslint-plugin-wyrm-v0.0.4...eslint-plugin-wyrm-v0.0.5) (2025-11-02)
|
|
11
4
|
|
|
12
5
|
|
|
13
6
|
### Bug Fixes
|
|
14
7
|
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
## 0.0.2 (2025-10-26)
|
|
8
|
+
* add no-ternary-return ([4e029be](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/4e029be3f157601bbbb5b9cb854a526ad88b2c1e))
|
|
18
9
|
|
|
10
|
+
## [0.0.4](https://github.com/mchevestrier/eslint-plugin-wyrm/compare/eslint-plugin-wyrm-v0.0.3...eslint-plugin-wyrm-v0.0.4) (2025-11-01)
|
|
19
11
|
|
|
20
12
|
### Bug Fixes
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
### Miscellaneous Chores
|
|
26
|
-
|
|
27
|
-
* Merge npm-publish.yml with release.yml ([fba85e8](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/fba85e8ff67e5274aedb63db60756a5a41ab010f))
|
|
14
|
+
- improve no-extra-nested-boolean-cast ([333d0f3](https://github.com/mchevestrier/eslint-plugin-wyrm/commit/333d0f3bcc3aa73a329bb9ff60189490f96813cd))
|
package/README.md
CHANGED
|
@@ -4,16 +4,35 @@
|
|
|
4
4
|
[](https://github.com/mchevestrier/eslint-plugin-wyrm/releases/latest)
|
|
5
5
|
[](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/main/LICENSE.md)
|
|
6
6
|
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
npm install --save-dev eslint eslint-plugin-wyrm
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { defineConfig } from 'eslint/config';
|
|
17
|
+
import wyrm from 'eslint-plugin-wyrm';
|
|
18
|
+
|
|
19
|
+
export default defineConfig([
|
|
20
|
+
// ...
|
|
21
|
+
|
|
22
|
+
wyrm.configs.recommended,
|
|
23
|
+
]);
|
|
24
|
+
```
|
|
25
|
+
|
|
7
26
|
## Configs
|
|
8
27
|
|
|
9
28
|
<!-- begin auto-generated configs list -->
|
|
10
29
|
|
|
11
|
-
| | Name
|
|
12
|
-
| :-- |
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
30
|
+
| | Name |
|
|
31
|
+
| :-- | :----------------------- |
|
|
32
|
+
| 🟩 | `recommended` |
|
|
33
|
+
| ✅ | `recommendedTypeChecked` |
|
|
34
|
+
| 🟪 | `strict` |
|
|
35
|
+
| ☑️ | `strictTypeChecked` |
|
|
17
36
|
|
|
18
37
|
<!-- end auto-generated configs list -->
|
|
19
38
|
|
|
@@ -22,16 +41,22 @@
|
|
|
22
41
|
<!-- begin auto-generated rules list -->
|
|
23
42
|
|
|
24
43
|
💼 Configurations enabled in.\
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
44
|
+
🟩 Set in the `recommended` configuration.\
|
|
45
|
+
✅ Set in the `recommendedTypeChecked` configuration.\
|
|
46
|
+
🟪 Set in the `strict` configuration.\
|
|
47
|
+
☑️ Set in the `strictTypeChecked` configuration.\
|
|
48
|
+
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
|
49
|
+
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\
|
|
29
50
|
💭 Requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
30
51
|
|
|
31
|
-
| Name
|
|
32
|
-
|
|
|
33
|
-
| [no-
|
|
34
|
-
| [no-
|
|
35
|
-
| [
|
|
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-empty-comment](https://github.com/mchevestrier/eslint-plugin-wyrm/blob/master/packages/eslint-plugin-wyrm/docs/rules/no-empty-comment.md) | Forbid empty comments | 🟪 ☑️ | | | |
|
|
56
|
+
| [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 | 🟩 ✅ 🟪 ☑️ | | | |
|
|
57
|
+
| [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 | 🟪 ☑️ | | | |
|
|
58
|
+
| [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 | 🟩 ✅ 🟪 ☑️ | | | |
|
|
59
|
+
| [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 | 🟪 ☑️ | 🔧 | | |
|
|
60
|
+
| [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 | ☑️ | | | 💭 |
|
|
36
61
|
|
|
37
62
|
<!-- end auto-generated rules list -->
|
package/dist/configs/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FlatConfig } from "@typescript-eslint/utils/ts-eslint";
|
|
2
2
|
|
|
3
3
|
//#region lib/configs/index.d.ts
|
|
4
4
|
declare namespace index_d_exports {
|
|
5
5
|
export { all, recommended, recommendedTypeChecked, recommendedTypeCheckedOnly, strict, strictOnly, strictTypeChecked, strictTypeCheckedOnly };
|
|
6
6
|
}
|
|
7
|
-
type Config =
|
|
7
|
+
type Config = FlatConfig.Config;
|
|
8
8
|
declare const all: Config;
|
|
9
9
|
declare const recommended: Config;
|
|
10
10
|
declare const strictOnly: Config;
|
package/dist/configs/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { __export } from "../_virtual/rolldown_runtime.js";
|
|
2
2
|
import { rules_exports } from "../rules/index.js";
|
|
3
3
|
import { plugin } from "../plugin.js";
|
|
4
|
-
import { Linter } from "eslint";
|
|
5
4
|
|
|
6
5
|
//#region lib/configs/index.ts
|
|
7
6
|
var configs_exports = /* @__PURE__ */ __export({
|
|
@@ -17,12 +16,12 @@ var configs_exports = /* @__PURE__ */ __export({
|
|
|
17
16
|
const baseConfig = { plugins: { get wyrm() {
|
|
18
17
|
return plugin;
|
|
19
18
|
} } };
|
|
20
|
-
function createConfigWithRules(initialRules,
|
|
21
|
-
const filteredRules = Object.entries(initialRules).filter(([, rule]) => pred(rule)).map(([
|
|
19
|
+
function createConfigWithRules(initialRules, configName, pred) {
|
|
20
|
+
const filteredRules = Object.entries(initialRules).filter(([, rule]) => pred(rule)).map(([ruleName]) => [`wyrm/${ruleName}`, "error"]);
|
|
22
21
|
const rules = Object.fromEntries(filteredRules);
|
|
23
22
|
return {
|
|
24
23
|
...baseConfig,
|
|
25
|
-
name: `wyrm/${
|
|
24
|
+
name: `wyrm/${configName}`,
|
|
26
25
|
rules
|
|
27
26
|
};
|
|
28
27
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,13 @@ import { index_d_exports } from "./configs/index.js";
|
|
|
2
2
|
import { index_d_exports as index_d_exports$1 } from "./rules/index.js";
|
|
3
3
|
|
|
4
4
|
//#region lib/index.d.ts
|
|
5
|
+
interface CompatibleConfig {
|
|
6
|
+
name?: string;
|
|
7
|
+
rules?: object;
|
|
8
|
+
}
|
|
5
9
|
declare const plugin: {
|
|
6
10
|
rules: typeof index_d_exports$1;
|
|
7
|
-
configs: typeof index_d_exports
|
|
11
|
+
configs: Record<keyof typeof index_d_exports, CompatibleConfig>;
|
|
8
12
|
};
|
|
9
13
|
//#endregion
|
|
10
14
|
export { plugin as default };
|
package/dist/plugin.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { rules_exports } from "./rules/index.js";
|
|
2
|
-
import { configs_exports } from "./configs/index.js";
|
|
3
2
|
import { createRequire } from "node:module";
|
|
4
3
|
|
|
5
4
|
//#region lib/plugin.ts
|
|
@@ -9,7 +8,6 @@ const plugin = {
|
|
|
9
8
|
name,
|
|
10
9
|
version
|
|
11
10
|
},
|
|
12
|
-
configs: configs_exports,
|
|
13
11
|
rules: rules_exports
|
|
14
12
|
};
|
|
15
13
|
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { _default } from "./no-
|
|
2
|
-
import { _default as _default$1 } from "./no-
|
|
3
|
-
import { _default as _default$2 } from "./
|
|
1
|
+
import { _default } from "./no-constant-template-expression.js";
|
|
2
|
+
import { _default as _default$1 } from "./no-empty-comment.js";
|
|
3
|
+
import { _default as _default$2 } from "./no-empty-jsx-expression.js";
|
|
4
|
+
import { _default as _default$3 } from "./no-extra-nested-boolean-cast.js";
|
|
5
|
+
import { _default as _default$4 } from "./no-jsx-statement.js";
|
|
6
|
+
import { _default as _default$5 } from "./no-ternary-return.js";
|
|
7
|
+
import { _default as _default$6 } from "./unsafe-asserted-chain.js";
|
|
4
8
|
|
|
5
9
|
//#region lib/rules/index.d.ts
|
|
6
10
|
declare namespace index_d_exports {
|
|
7
|
-
export { _default as "no-extra-nested-boolean-cast", _default$
|
|
11
|
+
export { _default as "no-constant-template-expression", _default$1 as "no-empty-comment", _default$2 as "no-empty-jsx-expression", _default$3 as "no-extra-nested-boolean-cast", _default$4 as "no-jsx-statement", _default$5 as "no-ternary-return", _default$6 as "unsafe-asserted-chain" };
|
|
8
12
|
}
|
|
9
13
|
//#endregion
|
|
10
14
|
export { index_d_exports };
|
package/dist/rules/index.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { __export } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import no_constant_template_expression_default from "./no-constant-template-expression.js";
|
|
3
|
+
import no_empty_comment_default from "./no-empty-comment.js";
|
|
4
|
+
import no_empty_jsx_expression_default from "./no-empty-jsx-expression.js";
|
|
2
5
|
import no_extra_nested_boolean_cast_default from "./no-extra-nested-boolean-cast.js";
|
|
3
6
|
import no_jsx_statement_default from "./no-jsx-statement.js";
|
|
7
|
+
import no_ternary_return_default from "./no-ternary-return.js";
|
|
4
8
|
import unsafe_asserted_chain_default from "./unsafe-asserted-chain.js";
|
|
5
9
|
|
|
6
10
|
//#region lib/rules/index.ts
|
|
7
11
|
var rules_exports = /* @__PURE__ */ __export({
|
|
12
|
+
"no-constant-template-expression": () => no_constant_template_expression_default,
|
|
13
|
+
"no-empty-comment": () => no_empty_comment_default,
|
|
14
|
+
"no-empty-jsx-expression": () => no_empty_jsx_expression_default,
|
|
8
15
|
"no-extra-nested-boolean-cast": () => no_extra_nested_boolean_cast_default,
|
|
9
16
|
"no-jsx-statement": () => no_jsx_statement_default,
|
|
17
|
+
"no-ternary-return": () => no_ternary_return_default,
|
|
10
18
|
"unsafe-asserted-chain": () => unsafe_asserted_chain_default
|
|
11
19
|
});
|
|
12
20
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { WyrmPluginDocs } from "../utils/createRule.js";
|
|
2
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
3
|
+
|
|
4
|
+
//#region lib/rules/no-constant-template-expression.d.ts
|
|
5
|
+
|
|
6
|
+
declare const _default: ESLintUtils.RuleModule<"noConstantTemplateExpression" | "replaceByString", [{
|
|
7
|
+
minAllowedLength: number;
|
|
8
|
+
}], WyrmPluginDocs, ESLintUtils.RuleListener>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { _default };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createRule } from "../utils/createRule.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ASTUtils, AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
|
|
4
|
+
|
|
5
|
+
//#region lib/rules/no-constant-template-expression.ts
|
|
6
|
+
const { name } = path.parse(import.meta.filename);
|
|
7
|
+
const DEFAULT_MIN_ALLOWED_LENGTH = 10;
|
|
8
|
+
var no_constant_template_expression_default = createRule({
|
|
9
|
+
name,
|
|
10
|
+
meta: {
|
|
11
|
+
type: "problem",
|
|
12
|
+
docs: {
|
|
13
|
+
description: "Disallow constant string expressions in template literals",
|
|
14
|
+
requiresTypeChecking: true,
|
|
15
|
+
strict: true
|
|
16
|
+
},
|
|
17
|
+
hasSuggestions: true,
|
|
18
|
+
schema: [{
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: { minAllowedLength: {
|
|
21
|
+
type: "number",
|
|
22
|
+
description: `Minimum string length allowed for constant expressions. Default: ${DEFAULT_MIN_ALLOWED_LENGTH}`
|
|
23
|
+
} }
|
|
24
|
+
}],
|
|
25
|
+
messages: {
|
|
26
|
+
noConstantTemplateExpression: "Replace this constant template expression by its value as a string ('{{value}}')",
|
|
27
|
+
replaceByString: "Replace by '{{value}}'"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultOptions: [{ minAllowedLength: DEFAULT_MIN_ALLOWED_LENGTH }],
|
|
31
|
+
create(context, [options]) {
|
|
32
|
+
return { TemplateLiteral(node) {
|
|
33
|
+
const services = ESLintUtils.getParserServices(context);
|
|
34
|
+
const checker = services.program.getTypeChecker();
|
|
35
|
+
const { expressions, quasis } = node;
|
|
36
|
+
if (quasis.some((quasi) => quasi.value.cooked.includes(" "))) return;
|
|
37
|
+
const scope = context.sourceCode.getScope(node);
|
|
38
|
+
for (const expr of expressions) {
|
|
39
|
+
if (expr.type === AST_NODE_TYPES.Identifier) {
|
|
40
|
+
const variable = ASTUtils.findVariable(scope, expr);
|
|
41
|
+
if (variable) {
|
|
42
|
+
const { references, defs } = variable;
|
|
43
|
+
if (references.length > 2) continue;
|
|
44
|
+
const def = defs.at(-1);
|
|
45
|
+
if (def?.parent?.type === AST_NODE_TYPES.VariableDeclaration && (def.parent.parent.type === AST_NODE_TYPES.ExportNamedDeclaration || def.parent.parent.type === AST_NODE_TYPES.ExportDefaultDeclaration)) continue;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const value = getLiteralValue(services.getTypeAtLocation(expr), checker);
|
|
49
|
+
if (value === null) continue;
|
|
50
|
+
if (value.length >= options.minAllowedLength) return;
|
|
51
|
+
context.report({
|
|
52
|
+
node: expr,
|
|
53
|
+
messageId: "noConstantTemplateExpression",
|
|
54
|
+
data: { value },
|
|
55
|
+
suggest: [{
|
|
56
|
+
messageId: "replaceByString",
|
|
57
|
+
data: { value },
|
|
58
|
+
fix(fixer) {
|
|
59
|
+
const [identStart, identEnd] = expr.range;
|
|
60
|
+
const previousQuasi = quasis.toReversed().find((quasi) => quasi.range[1] <= identStart);
|
|
61
|
+
const nextQuasi = quasis.find((quasi) => quasi.range[0] >= identEnd);
|
|
62
|
+
const start = previousQuasi?.range[1] ?? node.range[0];
|
|
63
|
+
const end = nextQuasi?.range[0] ?? node.range[1];
|
|
64
|
+
const range = [start - 2, end + 1];
|
|
65
|
+
return fixer.replaceTextRange(range, value);
|
|
66
|
+
}
|
|
67
|
+
}]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} };
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
function getLiteralValue(type, checker) {
|
|
74
|
+
if (type.isStringLiteral()) return type.value;
|
|
75
|
+
if (type.isNumberLiteral()) return type.value.toString();
|
|
76
|
+
if (type === checker.getTrueType()) return "true";
|
|
77
|
+
if (type === checker.getFalseType()) return "false";
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
export { no_constant_template_expression_default as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { WyrmPluginDocs } from "../utils/createRule.js";
|
|
2
|
+
import * as _typescript_eslint_utils_ts_eslint0 from "@typescript-eslint/utils/ts-eslint";
|
|
3
|
+
|
|
4
|
+
//#region lib/rules/no-empty-comment.d.ts
|
|
5
|
+
declare const _default: _typescript_eslint_utils_ts_eslint0.RuleModule<"noEmptyComment", [{
|
|
6
|
+
allowStacked: boolean;
|
|
7
|
+
}], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint0.RuleListener>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { _default };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createRule } from "../utils/createRule.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { AST_TOKEN_TYPES } from "@typescript-eslint/utils";
|
|
4
|
+
|
|
5
|
+
//#region lib/rules/no-empty-comment.ts
|
|
6
|
+
const { name } = path.parse(import.meta.filename);
|
|
7
|
+
const DEFAULT_ALLOW_STACKED = false;
|
|
8
|
+
var no_empty_comment_default = createRule({
|
|
9
|
+
name,
|
|
10
|
+
meta: {
|
|
11
|
+
type: "suggestion",
|
|
12
|
+
docs: {
|
|
13
|
+
description: "Forbid empty comments",
|
|
14
|
+
strict: true
|
|
15
|
+
},
|
|
16
|
+
schema: [{
|
|
17
|
+
type: "object",
|
|
18
|
+
additionalProperties: false,
|
|
19
|
+
properties: { allowStacked: {
|
|
20
|
+
type: "boolean",
|
|
21
|
+
description: `Whether to allow empty comments stacked next to non-empty comments. Default: \`${DEFAULT_ALLOW_STACKED}\``
|
|
22
|
+
} }
|
|
23
|
+
}],
|
|
24
|
+
messages: { noEmptyComment: "Remove this empty comment" }
|
|
25
|
+
},
|
|
26
|
+
defaultOptions: [{ allowStacked: DEFAULT_ALLOW_STACKED }],
|
|
27
|
+
create(context, [options]) {
|
|
28
|
+
if (typeof context.sourceCode.getAllComments === "undefined") return {};
|
|
29
|
+
const comments = context.sourceCode.getAllComments();
|
|
30
|
+
for (const comment of comments) {
|
|
31
|
+
if (!isEmptyComment(comment)) continue;
|
|
32
|
+
if (options.allowStacked && isStackedComment(comment, comments)) continue;
|
|
33
|
+
context.report({
|
|
34
|
+
node: comment,
|
|
35
|
+
messageId: "noEmptyComment"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
function isEmptyComment(comment) {
|
|
42
|
+
return !comment.value.replace(/^\*/u, "").replaceAll("*\n", "").trim();
|
|
43
|
+
}
|
|
44
|
+
function isStackedComment(comment, comments) {
|
|
45
|
+
if (comment.type !== AST_TOKEN_TYPES.Line) return false;
|
|
46
|
+
return comments.some((otherComment) => {
|
|
47
|
+
if (otherComment === comment) return false;
|
|
48
|
+
if (otherComment.type !== AST_TOKEN_TYPES.Line) return false;
|
|
49
|
+
if (isEmptyComment(otherComment)) return false;
|
|
50
|
+
if (otherComment.loc.start.line === comment.loc.start.line - 1) return true;
|
|
51
|
+
if (otherComment.loc.start.line === comment.loc.start.line + 1) return true;
|
|
52
|
+
return false;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { no_empty_comment_default as default };
|
|
@@ -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/no-empty-jsx-expression.d.ts
|
|
5
|
+
declare const _default: _typescript_eslint_utils_ts_eslint1.RuleModule<"noEmptyJsxExpression", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint1.RuleListener>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { _default };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createRule } from "../utils/createRule.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
4
|
+
|
|
5
|
+
//#region lib/rules/no-empty-jsx-expression.ts
|
|
6
|
+
const { name } = path.parse(import.meta.filename);
|
|
7
|
+
var no_empty_jsx_expression_default = createRule({
|
|
8
|
+
name,
|
|
9
|
+
meta: {
|
|
10
|
+
type: "suggestion",
|
|
11
|
+
docs: {
|
|
12
|
+
description: "Forbid empty JSX expression containers",
|
|
13
|
+
recommended: true
|
|
14
|
+
},
|
|
15
|
+
schema: [],
|
|
16
|
+
messages: { noEmptyJsxExpression: "Remove this empty JSX expression container" }
|
|
17
|
+
},
|
|
18
|
+
defaultOptions: [],
|
|
19
|
+
create(context) {
|
|
20
|
+
return {
|
|
21
|
+
JSXEmptyExpression(node) {
|
|
22
|
+
if (context.sourceCode.getCommentsInside(node).length) return;
|
|
23
|
+
context.report({
|
|
24
|
+
node,
|
|
25
|
+
messageId: "noEmptyJsxExpression"
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
JSXExpressionContainer(node) {
|
|
29
|
+
if (node.expression.type === AST_NODE_TYPES.JSXEmptyExpression) return;
|
|
30
|
+
switch (node.expression.type) {
|
|
31
|
+
case AST_NODE_TYPES.Literal:
|
|
32
|
+
if (node.expression.value === null) break;
|
|
33
|
+
if (node.expression.value === false) break;
|
|
34
|
+
if (node.expression.value === "") break;
|
|
35
|
+
return;
|
|
36
|
+
case AST_NODE_TYPES.Identifier:
|
|
37
|
+
if (node.expression.name === "undefined") break;
|
|
38
|
+
return;
|
|
39
|
+
default: return;
|
|
40
|
+
}
|
|
41
|
+
context.report({
|
|
42
|
+
node,
|
|
43
|
+
messageId: "noEmptyJsxExpression"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { no_empty_jsx_expression_default as default };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { WyrmPluginDocs } from "../utils/createRule.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _typescript_eslint_utils_ts_eslint3 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:
|
|
6
|
+
declare const _default: _typescript_eslint_utils_ts_eslint3.RuleModule<"noExtraBooleanCastInCondition" | "noExtraBooleanCastInPredicate" | "noExtraBooleanCastInsideAnother", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint3.RuleListener>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { _default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WyrmPluginDocs } from "../utils/createRule.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as _typescript_eslint_utils_ts_eslint5 from "@typescript-eslint/utils/ts-eslint";
|
|
3
3
|
|
|
4
4
|
//#region lib/rules/no-jsx-statement.d.ts
|
|
5
|
-
declare const _default:
|
|
5
|
+
declare const _default: _typescript_eslint_utils_ts_eslint5.RuleModule<"noJsxExpressionStatement", [], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint5.RuleListener>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { _default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { WyrmPluginDocs } from "../utils/createRule.js";
|
|
2
|
+
import * as _typescript_eslint_utils_ts_eslint7 from "@typescript-eslint/utils/ts-eslint";
|
|
3
|
+
|
|
4
|
+
//#region lib/rules/no-ternary-return.d.ts
|
|
5
|
+
declare const _default: _typescript_eslint_utils_ts_eslint7.RuleModule<"noTernaryReturn", [{
|
|
6
|
+
allowSingleLine: boolean;
|
|
7
|
+
}], WyrmPluginDocs, _typescript_eslint_utils_ts_eslint7.RuleListener>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { _default };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createRule } from "../utils/createRule.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
4
|
+
|
|
5
|
+
//#region lib/rules/no-ternary-return.ts
|
|
6
|
+
const { name } = path.parse(import.meta.filename);
|
|
7
|
+
const DEFAULT_ALLOW_SINGLE_LINE = false;
|
|
8
|
+
var no_ternary_return_default = createRule({
|
|
9
|
+
name,
|
|
10
|
+
meta: {
|
|
11
|
+
type: "suggestion",
|
|
12
|
+
docs: {
|
|
13
|
+
description: "Disallow ternary conditions in return statements",
|
|
14
|
+
strict: true
|
|
15
|
+
},
|
|
16
|
+
fixable: "code",
|
|
17
|
+
schema: [{
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: { allowSingleLine: {
|
|
20
|
+
type: "boolean",
|
|
21
|
+
description: `Whether to allow single line ternary conditions. Default: \`${DEFAULT_ALLOW_SINGLE_LINE}\``
|
|
22
|
+
} }
|
|
23
|
+
}],
|
|
24
|
+
messages: { noTernaryReturn: "Replace this ternary condition by multiple return statements" }
|
|
25
|
+
},
|
|
26
|
+
defaultOptions: [{ allowSingleLine: DEFAULT_ALLOW_SINGLE_LINE }],
|
|
27
|
+
create(context, [options]) {
|
|
28
|
+
return { ReturnStatement(node) {
|
|
29
|
+
const { argument } = node;
|
|
30
|
+
if (!argument) return;
|
|
31
|
+
if (argument.type !== AST_NODE_TYPES.ConditionalExpression) return;
|
|
32
|
+
if (options.allowSingleLine && argument.loc.start.line === argument.loc.end.line) return;
|
|
33
|
+
const { test, consequent, alternate } = argument;
|
|
34
|
+
context.report({
|
|
35
|
+
node,
|
|
36
|
+
messageId: "noTernaryReturn",
|
|
37
|
+
*fix(fixer) {
|
|
38
|
+
const condText = context.sourceCode.getText(test);
|
|
39
|
+
const thenText = context.sourceCode.getText(consequent);
|
|
40
|
+
const elseText = context.sourceCode.getText(alternate);
|
|
41
|
+
const indent = " ".repeat(node.loc.start.column);
|
|
42
|
+
yield fixer.replaceText(node, `if (${condText}) return ${thenText};`);
|
|
43
|
+
yield fixer.insertTextAfter(node, `\n${indent}return ${elseText};`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
} };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { no_ternary_return_default as default };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Disallow constant string expressions in template literals (`wyrm/no-constant-template-expression`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ☑️ `strictTypeChecked` config.
|
|
4
|
+
|
|
5
|
+
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
|
6
|
+
|
|
7
|
+
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
It is sometimes clearer to inline interpolated expressions when their values are constant:
|
|
12
|
+
|
|
13
|
+
### Example
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const foo = 'foobar';
|
|
17
|
+
const str = `${foo}_baz`;
|
|
18
|
+
// This would be clearer as:
|
|
19
|
+
const str = 'foobar_baz';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
By default, this rule allows constant values when they take up at least 10 characters.
|
|
23
|
+
This can be configured with the `minAllowedLength` option.
|
|
24
|
+
|
|
25
|
+
## Cases
|
|
26
|
+
|
|
27
|
+
### Incorrect ❌
|
|
28
|
+
|
|
29
|
+
Template expression with a constant string value:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
const foo = 'foobar';
|
|
33
|
+
const str = `${foo}_baz`;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Template expression with a constant number value:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
const n = 42;
|
|
40
|
+
const str = `${n}_baz`;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Template expression with a constant boolean value:
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
const bool = true;
|
|
47
|
+
const str = `${bool}_baz`;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
With a 14 character string (`minAllowedLength: 15`):
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
const foo = '12345678901234';
|
|
54
|
+
const str = `${foo}_baz`;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Correct ✅
|
|
58
|
+
|
|
59
|
+
Template expression typed as string:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
declare const foo: string;
|
|
63
|
+
const str = `${foo}_baz`;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Template expression with a 10 character string value (as long as the default `minAllowedLength` value):
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const n = 'aaaaaaaaaa';
|
|
70
|
+
const str = `${n}_baz`;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
<!-- end auto-generated rule header -->
|
|
74
|
+
|
|
75
|
+
## Options
|
|
76
|
+
|
|
77
|
+
<!-- begin auto-generated rule options list -->
|
|
78
|
+
|
|
79
|
+
| Name | Description | Type |
|
|
80
|
+
| :----------------- | :------------------------------------------------------------------ | :----- |
|
|
81
|
+
| `minAllowedLength` | Minimum string length allowed for constant expressions. Default: 10 | Number |
|
|
82
|
+
|
|
83
|
+
<!-- end auto-generated rule options list -->
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Forbid empty comments (`wyrm/no-empty-comment`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: 🟪 `strict`, ☑️ `strictTypeChecked`.
|
|
4
|
+
|
|
5
|
+
## Cases
|
|
6
|
+
|
|
7
|
+
### Incorrect ❌
|
|
8
|
+
|
|
9
|
+
Empty inline comment:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
//
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Empty block comment:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
/* */
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Empty JSDoc comment:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
/** */
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Stacked empty comments (with `allowStacked: false`):
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
//
|
|
31
|
+
// Ok
|
|
32
|
+
//
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Several stacked empty comments (with `allowStacked: true`):
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
//
|
|
39
|
+
// Ok
|
|
40
|
+
//
|
|
41
|
+
//
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Correct ✅
|
|
45
|
+
|
|
46
|
+
Not an empty comment:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
// Ok
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Stacked empty comments (with `allowStacked: true`):
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
//
|
|
56
|
+
// Ok
|
|
57
|
+
//
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<!-- end auto-generated rule header -->
|
|
61
|
+
|
|
62
|
+
## Options
|
|
63
|
+
|
|
64
|
+
<!-- begin auto-generated rule options list -->
|
|
65
|
+
|
|
66
|
+
| Name | Description | Type |
|
|
67
|
+
| :------------- | :----------------------------------------------------------------------------------- | :------ |
|
|
68
|
+
| `allowStacked` | Whether to allow empty comments stacked next to non-empty comments. Default: `false` | Boolean |
|
|
69
|
+
|
|
70
|
+
<!-- end auto-generated rule options list -->
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Forbid empty JSX expression containers (`wyrm/no-empty-jsx-expression`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: 🟩 `recommended`, ✅ `recommendedTypeChecked`, 🟪 `strict`, ☑️ `strictTypeChecked`.
|
|
4
|
+
|
|
5
|
+
## Cases
|
|
6
|
+
|
|
7
|
+
### Incorrect ❌
|
|
8
|
+
|
|
9
|
+
Empty JSX expression container:
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
function Foo() {
|
|
13
|
+
return (
|
|
14
|
+
<div>
|
|
15
|
+
{}
|
|
16
|
+
Ok
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
JSX expression container with only a literal `null`:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
function Foo() {
|
|
26
|
+
return <div>{null}</div>;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
JSX expression container with only a literal `undefined`:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
function Foo() {
|
|
34
|
+
return <div>{undefined}</div>;
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
JSX expression container with only a literal `false`:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
function Foo() {
|
|
42
|
+
return <div>{false}</div>;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
JSX expression container with only a literal empty string:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
function Foo() {
|
|
50
|
+
return <div>{''}</div>;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Correct ✅
|
|
55
|
+
|
|
56
|
+
JSX expression container is not empty:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
function Foo({ children }: PropsWithChildren) {
|
|
60
|
+
return <div>{children}</div>;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
JSX expression container with a comment:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
function Foo() {
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
{/* A comment */}
|
|
71
|
+
Ok
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
<!-- end auto-generated rule header -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Forbid extra boolean casts in conditions and predicates (`wyrm/no-extra-nested-boolean-cast`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the following configs:
|
|
3
|
+
💼 This rule is enabled in the following configs: 🟪 `strict`, ☑️ `strictTypeChecked`.
|
|
4
4
|
|
|
5
5
|
## Description
|
|
6
6
|
|
|
@@ -20,13 +20,15 @@ declare const foo: string;
|
|
|
20
20
|
const bar = !!foo ? 'ok' : 'ko';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
This rules conflicts with the [`@typescript-eslint/strict-boolean-expressions`](https://typescript-eslint.io/rules/strict-boolean-expressions/) rule.
|
|
24
|
+
|
|
23
25
|
## Cases
|
|
24
26
|
|
|
25
27
|
### Incorrect ❌
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
// Redundant double negation
|
|
29
|
+
Redundant double negation:
|
|
29
30
|
|
|
31
|
+
```tsx
|
|
30
32
|
declare const foo: string;
|
|
31
33
|
|
|
32
34
|
if (!!bar) {
|
|
@@ -34,22 +36,22 @@ if (!!bar) {
|
|
|
34
36
|
}
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
// Redundant double negation inside of another boolean cast
|
|
39
|
+
Redundant double negation inside of another boolean cast:
|
|
39
40
|
|
|
41
|
+
```tsx
|
|
40
42
|
const x = Boolean(!!foo);
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
// Redundant double negation in return of array method predicate
|
|
45
|
+
Redundant double negation in return of array method predicate:
|
|
45
46
|
|
|
47
|
+
```tsx
|
|
46
48
|
declare const arr: string[];
|
|
47
49
|
const isOkay = arr.filter((elt) => !!elt);
|
|
48
50
|
```
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
// Redundant double negations in logical sub-expressions
|
|
52
|
+
Redundant double negations in logical sub-expressions:
|
|
52
53
|
|
|
54
|
+
```tsx
|
|
53
55
|
declare const foo: string;
|
|
54
56
|
declare const bar: string;
|
|
55
57
|
declare const baz: string;
|
|
@@ -59,9 +61,9 @@ if (!!bar && (!!foo || !!baz)) {
|
|
|
59
61
|
}
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
// Redundant Boolean calls
|
|
64
|
+
Redundant Boolean calls:
|
|
64
65
|
|
|
66
|
+
```tsx
|
|
65
67
|
declare const foo: string;
|
|
66
68
|
declare const bar: string;
|
|
67
69
|
declare const baz: string;
|
|
@@ -71,9 +73,9 @@ if (Boolean(bar) && (Boolean(foo) || Boolean(baz))) {
|
|
|
71
73
|
}
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
// Redundant double negations nested in type assertions
|
|
76
|
+
Redundant double negations nested in type assertions:
|
|
76
77
|
|
|
78
|
+
```tsx
|
|
77
79
|
declare const foo: string;
|
|
78
80
|
declare const bar: string;
|
|
79
81
|
declare const baz: string;
|
|
@@ -85,9 +87,9 @@ if ((!!bar)! && ((!!foo satisfies boolean) || (!!baz as any))) {
|
|
|
85
87
|
|
|
86
88
|
### Correct ✅
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
// No extra boolean cast
|
|
90
|
+
No extra boolean cast:
|
|
90
91
|
|
|
92
|
+
```tsx
|
|
91
93
|
declare const foo: string;
|
|
92
94
|
declare const bar: string;
|
|
93
95
|
declare const baz: string;
|
|
@@ -97,9 +99,9 @@ if (bar && (foo || baz)) {
|
|
|
97
99
|
}
|
|
98
100
|
```
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
// Short-circuiting expression
|
|
102
|
+
Short-circuiting expression:
|
|
102
103
|
|
|
104
|
+
```tsx
|
|
103
105
|
declare const foo: string;
|
|
104
106
|
declare const bar: string;
|
|
105
107
|
declare const baz: string;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Forbid JSX expression statements (`wyrm/no-jsx-statement`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the following configs:
|
|
3
|
+
💼 This rule is enabled in the following configs: 🟩 `recommended`, ✅ `recommendedTypeChecked`, 🟪 `strict`, ☑️ `strictTypeChecked`.
|
|
4
4
|
|
|
5
5
|
## Cases
|
|
6
6
|
|
|
7
7
|
### Incorrect ❌
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
// JSX fragment in expression statement
|
|
9
|
+
JSX fragment in expression statement:
|
|
11
10
|
|
|
11
|
+
```tsx
|
|
12
12
|
export function MyComponent() {
|
|
13
13
|
<></>;
|
|
14
14
|
}
|
|
@@ -16,17 +16,17 @@ export function MyComponent() {
|
|
|
16
16
|
|
|
17
17
|
### Correct ✅
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
// JSX element in return statement
|
|
19
|
+
JSX element in return statement:
|
|
21
20
|
|
|
21
|
+
```tsx
|
|
22
22
|
export function MyComponent() {
|
|
23
23
|
return <div />;
|
|
24
24
|
}
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
// JSX element in variable initialization
|
|
27
|
+
JSX element in variable initialization:
|
|
29
28
|
|
|
29
|
+
```tsx
|
|
30
30
|
export function MyComponent() {
|
|
31
31
|
const jsx = <div />;
|
|
32
32
|
return jsx;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Disallow ternary conditions in return statements (`wyrm/no-ternary-return`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the following configs: 🟪 `strict`, ☑️ `strictTypeChecked`.
|
|
4
|
+
|
|
5
|
+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
7
|
+
## Cases
|
|
8
|
+
|
|
9
|
+
### Incorrect ❌
|
|
10
|
+
|
|
11
|
+
Ternary return:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
function foo(cond: boolean) {
|
|
15
|
+
return cond ? 42 : 105;
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Correct ✅
|
|
20
|
+
|
|
21
|
+
No ternary return:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
function foo(cond: boolean) {
|
|
25
|
+
if (cond) return 42;
|
|
26
|
+
return 105;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Inline arrow function:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
const foo = (cond: boolean) => (cond ? 42 : 105);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<!-- end auto-generated rule header -->
|
|
37
|
+
|
|
38
|
+
## Options
|
|
39
|
+
|
|
40
|
+
<!-- begin auto-generated rule options list -->
|
|
41
|
+
|
|
42
|
+
| Name | Description | Type |
|
|
43
|
+
| :---------------- | :---------------------------------------------------------------- | :------ |
|
|
44
|
+
| `allowSingleLine` | Whether to allow single line ternary conditions. Default: `false` | Boolean |
|
|
45
|
+
|
|
46
|
+
<!-- end auto-generated rule options list -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Disallow unsafe type assertions on optional chained expressions (`wyrm/unsafe-asserted-chain`)
|
|
2
2
|
|
|
3
|
-
💼 This rule is enabled in the
|
|
3
|
+
💼 This rule is enabled in the ☑️ `strictTypeChecked` config.
|
|
4
4
|
|
|
5
5
|
💭 This rule requires [type information](https://typescript-eslint.io/linting/typed-linting).
|
|
6
6
|
|
|
@@ -28,39 +28,39 @@ foo.bar as string;
|
|
|
28
28
|
|
|
29
29
|
### Incorrect ❌
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
// Optional chain asserted as not undefined
|
|
31
|
+
Optional chain asserted as not undefined:
|
|
33
32
|
|
|
33
|
+
```tsx
|
|
34
34
|
declare const foo: { bar: string | number } | null;
|
|
35
35
|
const str = (foo?.bar as string).toUpperCase();
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
// Optional chain call expression asserted as not undefined
|
|
38
|
+
Optional chain call expression asserted as not undefined:
|
|
40
39
|
|
|
40
|
+
```tsx
|
|
41
41
|
declare const foo: { bar: () => string | number } | null;
|
|
42
42
|
const str = (foo?.bar() as string | number)?.toString();
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
### Correct ✅
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
// Optional chain asserted as nullable
|
|
47
|
+
Optional chain asserted as nullable:
|
|
49
48
|
|
|
49
|
+
```tsx
|
|
50
50
|
declare const foo: { bar: string | number } | null;
|
|
51
51
|
const str = (foo?.bar as string | undefined)?.toUpperCase();
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
// Optional chain asserted as any
|
|
54
|
+
Optional chain asserted as any:
|
|
56
55
|
|
|
56
|
+
```tsx
|
|
57
57
|
declare const foo: { bar: string | number } | null;
|
|
58
58
|
const str = (foo?.bar as any)?.toUpperCase();
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
// Optional chain asserted as unknown
|
|
61
|
+
Optional chain asserted as unknown:
|
|
63
62
|
|
|
63
|
+
```tsx
|
|
64
64
|
declare const foo: { bar: string | number } | null;
|
|
65
65
|
const str = (foo?.bar as unknown)?.toUpperCase();
|
|
66
66
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-wyrm",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Some custom ESLint rules",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"eslint": ">=9.38.0",
|
|
37
37
|
"eslint-doc-generator": "^2.3.0",
|
|
38
38
|
"jest-diff": "^30.2.0",
|
|
39
|
+
"jiti": "^2.6.1",
|
|
39
40
|
"markdownlint-cli2": "^0.18.1",
|
|
40
41
|
"prettier": "^3.6.2",
|
|
41
42
|
"tsdown": "^0.15.9",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"fix:eslint-docs": "eslint-doc-generator",
|
|
53
54
|
"fix:format": "prettier --write .",
|
|
54
55
|
"fix:js": "eslint . --fix",
|
|
56
|
+
"preinit:eslint-docs": "pnpm run build",
|
|
55
57
|
"init:eslint-docs": "eslint-doc-generator --init-rule-docs",
|
|
56
58
|
"lint:docs": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#CHANGELOG.md\"",
|
|
57
59
|
"lint:eslint-docs": "eslint-doc-generator --check",
|