eslint-plugin-function 0.0.27 → 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.
Files changed (2) hide show
  1. package/dist/index.js +86 -6
  2. package/package.json +9 -10
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 { RegExp } from "@eslint-react/kit";
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.27";
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 = RegExp.toRegExp(opts?.pattern ?? defaultPattern);
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 = [...ER.getTypeVariants(unionConstituents(returnType))];
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.27",
3
+ "version": "0.0.28",
4
4
  "private": false,
5
5
  "description": "(WIP) The ESLint plugin for function-related rules.",
6
6
  "license": "MIT",
@@ -19,13 +19,12 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@eslint-react/ast": "^2.0.0-next.182",
22
- "@eslint-react/core": "^2.0.0-next.182",
23
22
  "@eslint-react/eff": "^2.0.0-next.182",
24
23
  "@eslint-react/kit": "^2.0.0-next.182",
25
- "@typescript-eslint/scope-manager": "^8.43.0",
26
- "@typescript-eslint/type-utils": "^8.43.0",
27
- "@typescript-eslint/types": "^8.43.0",
28
- "@typescript-eslint/utils": "^8.43.0",
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,8 +32,8 @@
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.4.0",
37
- "@typescript-eslint/rule-tester": "^8.43.0",
35
+ "@types/node": "^24.5.0",
36
+ "@typescript-eslint/rule-tester": "^8.44.0",
38
37
  "dedent": "^1.7.0",
39
38
  "dprint": "^0.50.2",
40
39
  "eslint": "^9.35.0",
@@ -43,8 +42,8 @@
43
42
  "jiti": "^2.5.1",
44
43
  "publint": "^0.3.12",
45
44
  "skott": "^0.35.6",
46
- "tsdown": "^0.15.1",
47
- "typescript-eslint": "^8.43.0",
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
  },