eslint-plugin-function 0.0.26 → 0.0.28
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/dist/index.js +86 -6
- package/package.json +14 -15
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
|
+
import { isFalseLiteralType, isTrueLiteralType, isTypeFlagSet, unionConstituents } from "ts-api-utils";
|
|
3
|
+
import { P, isMatching, match } from "ts-pattern";
|
|
4
|
+
import ts from "typescript";
|
|
2
5
|
import * as AST from "@eslint-react/ast";
|
|
3
|
-
import * as ER from "@eslint-react/core";
|
|
4
6
|
import "@eslint-react/eff";
|
|
5
|
-
import {
|
|
7
|
+
import { toRegExp } from "@eslint-react/kit";
|
|
6
8
|
import { getConstrainedTypeAtLocation } from "@typescript-eslint/type-utils";
|
|
7
9
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
8
|
-
import { unionConstituents } from "ts-api-utils";
|
|
9
10
|
|
|
10
11
|
//#region package.json
|
|
11
12
|
var name = "eslint-plugin-function";
|
|
12
|
-
var version = "0.0.
|
|
13
|
+
var version = "0.0.28";
|
|
13
14
|
|
|
14
15
|
//#endregion
|
|
15
16
|
//#region src/utils/create-rule.ts
|
|
@@ -18,6 +19,85 @@ function getDocsUrl() {
|
|
|
18
19
|
}
|
|
19
20
|
const createRule = ESLintUtils.RuleCreator(getDocsUrl);
|
|
20
21
|
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/utils/type-is.ts
|
|
24
|
+
/** @internal */
|
|
25
|
+
const isAnyType = (type) => isTypeFlagSet(type, ts.TypeFlags.TypeParameter | ts.TypeFlags.Any);
|
|
26
|
+
/** @internal */
|
|
27
|
+
const isBigIntType = (type) => isTypeFlagSet(type, ts.TypeFlags.BigIntLike);
|
|
28
|
+
/** @internal */
|
|
29
|
+
const isBooleanType = (type) => isTypeFlagSet(type, ts.TypeFlags.BooleanLike);
|
|
30
|
+
/** @internal */
|
|
31
|
+
const isEnumType = (type) => isTypeFlagSet(type, ts.TypeFlags.EnumLike);
|
|
32
|
+
/** @internal */
|
|
33
|
+
const isFalsyBigIntType = (type) => type.isLiteral() && isMatching({ value: { base10Value: "0" } }, type);
|
|
34
|
+
/** @internal */
|
|
35
|
+
const isFalsyNumberType = (type) => type.isNumberLiteral() && type.value === 0;
|
|
36
|
+
/** @internal */
|
|
37
|
+
const isFalsyStringType = (type) => type.isStringLiteral() && type.value === "";
|
|
38
|
+
/** @internal */
|
|
39
|
+
const isNeverType = (type) => isTypeFlagSet(type, ts.TypeFlags.Never);
|
|
40
|
+
/** @internal */
|
|
41
|
+
const isNullishType = (type) => isTypeFlagSet(type, ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike);
|
|
42
|
+
/** @internal */
|
|
43
|
+
const isNumberType = (type) => isTypeFlagSet(type, ts.TypeFlags.NumberLike);
|
|
44
|
+
/** @internal */
|
|
45
|
+
const isObjectType = (type) => !isTypeFlagSet(type, ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.VoidLike | ts.TypeFlags.BooleanLike | ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.TypeParameter | ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never);
|
|
46
|
+
/** @internal */
|
|
47
|
+
const isStringType = (type) => isTypeFlagSet(type, ts.TypeFlags.StringLike);
|
|
48
|
+
/** @internal */
|
|
49
|
+
const isTruthyBigIntType = (type) => type.isLiteral() && isMatching({ value: { base10Value: P.not("0") } }, type);
|
|
50
|
+
/** @internal */
|
|
51
|
+
const isTruthyNumberType = (type) => type.isNumberLiteral() && type.value !== 0;
|
|
52
|
+
/** @internal */
|
|
53
|
+
const isTruthyStringType = (type) => type.isStringLiteral() && type.value !== "";
|
|
54
|
+
/** @internal */
|
|
55
|
+
const isUnknownType = (type) => isTypeFlagSet(type, ts.TypeFlags.Unknown);
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/utils/type-variant.ts
|
|
59
|
+
/**
|
|
60
|
+
* Ported from https://github.com/typescript-eslint/typescript-eslint/blob/eb736bbfc22554694400e6a4f97051d845d32e0b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts#L826 with some enhancements
|
|
61
|
+
* Get the variants of an array of types.
|
|
62
|
+
* @param types The types to get the variants of
|
|
63
|
+
* @returns The variants of the types
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
function getTypeVariants(types) {
|
|
67
|
+
const variants = /* @__PURE__ */ new Set();
|
|
68
|
+
if (types.some(isUnknownType)) {
|
|
69
|
+
variants.add("unknown");
|
|
70
|
+
return variants;
|
|
71
|
+
}
|
|
72
|
+
if (types.some(isNullishType)) variants.add("nullish");
|
|
73
|
+
const booleans = types.filter(isBooleanType);
|
|
74
|
+
const boolean0 = booleans[0];
|
|
75
|
+
if (booleans.length === 1 && boolean0 != null) {
|
|
76
|
+
if (isFalseLiteralType(boolean0)) variants.add("falsy boolean");
|
|
77
|
+
else if (isTrueLiteralType(boolean0)) variants.add("truthy boolean");
|
|
78
|
+
} else if (booleans.length === 2) variants.add("boolean");
|
|
79
|
+
const strings = types.filter(isStringType);
|
|
80
|
+
if (strings.length > 0) {
|
|
81
|
+
const evaluated = match(strings).when((types$1) => types$1.every(isTruthyStringType), () => "truthy string").when((types$1) => types$1.every(isFalsyStringType), () => "falsy string").otherwise(() => "string");
|
|
82
|
+
variants.add(evaluated);
|
|
83
|
+
}
|
|
84
|
+
const bigints = types.filter(isBigIntType);
|
|
85
|
+
if (bigints.length > 0) {
|
|
86
|
+
const evaluated = match(bigints).when((types$1) => types$1.every(isTruthyBigIntType), () => "truthy bigint").when((types$1) => types$1.every(isFalsyBigIntType), () => "falsy bigint").otherwise(() => "bigint");
|
|
87
|
+
variants.add(evaluated);
|
|
88
|
+
}
|
|
89
|
+
const numbers = types.filter(isNumberType);
|
|
90
|
+
if (numbers.length > 0) {
|
|
91
|
+
const evaluated = match(numbers).when((types$1) => types$1.every(isTruthyNumberType), () => "truthy number").when((types$1) => types$1.every(isFalsyNumberType), () => "falsy number").otherwise(() => "number");
|
|
92
|
+
variants.add(evaluated);
|
|
93
|
+
}
|
|
94
|
+
if (types.some(isEnumType)) variants.add("enum");
|
|
95
|
+
if (types.some(isObjectType)) variants.add("object");
|
|
96
|
+
if (types.some(isAnyType)) variants.add("any");
|
|
97
|
+
if (types.some(isNeverType)) variants.add("never");
|
|
98
|
+
return variants;
|
|
99
|
+
}
|
|
100
|
+
|
|
21
101
|
//#endregion
|
|
22
102
|
//#region src/rules/function-definition.ts
|
|
23
103
|
const RULE_NAME$2 = "function-definition";
|
|
@@ -97,7 +177,7 @@ var function_return_boolean_default = createRule({
|
|
|
97
177
|
});
|
|
98
178
|
function create(context, [opts]) {
|
|
99
179
|
const services = ESLintUtils.getParserServices(context, false);
|
|
100
|
-
const pattern =
|
|
180
|
+
const pattern = toRegExp(opts?.pattern ?? defaultPattern);
|
|
101
181
|
const functionEntries = [];
|
|
102
182
|
function handleReturnExpression(context$1, returnExpression, onViolation) {
|
|
103
183
|
if (returnExpression == null) {
|
|
@@ -105,7 +185,7 @@ function create(context, [opts]) {
|
|
|
105
185
|
return;
|
|
106
186
|
}
|
|
107
187
|
const returnType = getConstrainedTypeAtLocation(services, returnExpression);
|
|
108
|
-
const parts = [...
|
|
188
|
+
const parts = [...getTypeVariants(unionConstituents(returnType))];
|
|
109
189
|
if (parts.every((part) => allowedVariants.some((allowed) => part === allowed))) return;
|
|
110
190
|
onViolation(returnExpression, { variants: [...parts].map((part) => `'${part}'`).join(", ") });
|
|
111
191
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-function",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "(WIP) The ESLint plugin for function-related rules.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,14 +18,13 @@
|
|
|
18
18
|
"package.json"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@eslint-react/ast": "^2.0.0-
|
|
22
|
-
"@eslint-react/
|
|
23
|
-
"@eslint-react/
|
|
24
|
-
"@eslint-
|
|
25
|
-
"@typescript-eslint/
|
|
26
|
-
"@typescript-eslint/
|
|
27
|
-
"@typescript-eslint/
|
|
28
|
-
"@typescript-eslint/utils": "^8.43.0",
|
|
21
|
+
"@eslint-react/ast": "^2.0.0-next.182",
|
|
22
|
+
"@eslint-react/eff": "^2.0.0-next.182",
|
|
23
|
+
"@eslint-react/kit": "^2.0.0-next.182",
|
|
24
|
+
"@typescript-eslint/scope-manager": "^8.44.0",
|
|
25
|
+
"@typescript-eslint/type-utils": "^8.44.0",
|
|
26
|
+
"@typescript-eslint/types": "^8.44.0",
|
|
27
|
+
"@typescript-eslint/utils": "^8.44.0",
|
|
29
28
|
"string-ts": "^2.2.1",
|
|
30
29
|
"ts-pattern": "^5.8.0"
|
|
31
30
|
},
|
|
@@ -33,18 +32,18 @@
|
|
|
33
32
|
"@eslint/markdown": "^7.2.0",
|
|
34
33
|
"@tsconfig/node22": "^22.0.2",
|
|
35
34
|
"@tsconfig/strictest": "^2.0.5",
|
|
36
|
-
"@types/node": "^24.
|
|
37
|
-
"@typescript-eslint/rule-tester": "^8.
|
|
35
|
+
"@types/node": "^24.5.0",
|
|
36
|
+
"@typescript-eslint/rule-tester": "^8.44.0",
|
|
38
37
|
"dedent": "^1.7.0",
|
|
39
|
-
"dprint": "^0.50.
|
|
38
|
+
"dprint": "^0.50.2",
|
|
40
39
|
"eslint": "^9.35.0",
|
|
41
40
|
"eslint-config-flat-gitignore": "^2.1.0",
|
|
42
41
|
"eslint-plugin-vitest": "^0.5.4",
|
|
43
42
|
"jiti": "^2.5.1",
|
|
44
43
|
"publint": "^0.3.12",
|
|
45
|
-
"skott": "^0.35.
|
|
46
|
-
"tsdown": "^0.15.
|
|
47
|
-
"typescript-eslint": "^8.
|
|
44
|
+
"skott": "^0.35.6",
|
|
45
|
+
"tsdown": "^0.15.2",
|
|
46
|
+
"typescript-eslint": "^8.44.0",
|
|
48
47
|
"vitest": "^3.2.4",
|
|
49
48
|
"@local/configs": "0.0.0"
|
|
50
49
|
},
|