Skip to content

Commit ed5c73e

Browse files
committed
refactor: move context detection utilities to kit package
1 parent 79256e1 commit ed5c73e

File tree

11 files changed

+106
-9
lines changed

11 files changed

+106
-9
lines changed

packages/plugins/eslint-plugin-react-x/src/rules/no-misused-capture-owner-stack.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as AST from "@eslint-react/ast";
22
import * as ER from "@eslint-react/core";
3-
import { type RuleContext, type RuleFeature } from "@eslint-react/kit";
3+
import { ContextDetection, type RuleContext, type RuleFeature } from "@eslint-react/kit";
44
import { getSettingsFromContext } from "@eslint-react/shared";
55
import { AST_NODE_TYPES as T, type TSESTree } from "@typescript-eslint/types";
66
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
@@ -71,6 +71,6 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
7171

7272
function isDevelopmentOnlyCheck(node: TSESTree.Node) {
7373
if (node.type !== T.IfStatement) return false;
74-
if (AST.isProcessEnvNodeEnvCompare(node.test, "!==", "production")) return true;
74+
if (ContextDetection.isProcessEnvNodeEnvCompare(node.test, "!==", "production")) return true;
7575
return false;
7676
}

packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-prefix.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as AST from "@eslint-react/ast";
22
import * as ER from "@eslint-react/core";
33
import type { RuleContext, RuleFeature } from "@eslint-react/kit";
4+
import { ContextDetection } from "@eslint-react/kit";
45
import type { TSESTree } from "@typescript-eslint/types";
56
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint";
67
import type { CamelCase } from "string-ts";
@@ -65,7 +66,7 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
6566
continue;
6667
}
6768
// Skip hooks that are in a vi mock callback
68-
if (ER.isInViMockCallback(context, node)) {
69+
if (AST.findParentNode(node, ContextDetection.isViMockCallback) != null) {
6970
continue;
7071
}
7172
context.report({

packages/utilities/ast/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@ export * from "./ast-node-equal";
1212
export * from "./ast-node-format";
1313
export * from "./ast-node-is";
1414
export type * from "./ast-node-types";
15-
export * from "./ast-process-env";
1615
export * from "./ast-property-name";
1716
export * from "./ast-then";
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[**@eslint-react/kit**](../../../README.md)
2+
3+
***
4+
5+
[@eslint-react/kit](../../../README.md) / ContextDetection
6+
7+
# ContextDetection
8+
9+
## Functions
10+
11+
- [isProcessEnvNodeEnv](functions/isProcessEnvNodeEnv.md)
12+
- [isProcessEnvNodeEnvCompare](functions/isProcessEnvNodeEnvCompare.md)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[**@eslint-react/kit**](../../../../README.md)
2+
3+
***
4+
5+
[@eslint-react/kit](../../../../README.md) / [ContextDetection](../README.md) / isProcessEnvNodeEnv
6+
7+
# Function: isProcessEnvNodeEnv()
8+
9+
> **isProcessEnvNodeEnv**(`node`): `node is MemberExpression`
10+
11+
Check if the given node is a member expression that accesses `process.env.NODE_ENV`
12+
13+
## Parameters
14+
15+
### node
16+
17+
The AST node
18+
19+
`undefined` | `null` | `Node`
20+
21+
## Returns
22+
23+
`node is MemberExpression`
24+
25+
True if the node is a member expression that accesses `process.env.NODE_ENV`, false otherwise
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[**@eslint-react/kit**](../../../../README.md)
2+
3+
***
4+
5+
[@eslint-react/kit](../../../../README.md) / [ContextDetection](../README.md) / isProcessEnvNodeEnvCompare
6+
7+
# Function: isProcessEnvNodeEnvCompare()
8+
9+
> **isProcessEnvNodeEnvCompare**(`node`, `operator`, `value`): `node is BinaryExpression`
10+
11+
Check if the given node is a binary expression that compares `process.env.NODE_ENV` with a string literal
12+
13+
## Parameters
14+
15+
### node
16+
17+
The AST node
18+
19+
`undefined` | `null` | `Node`
20+
21+
### operator
22+
23+
The operator used in the comparison
24+
25+
`"==="` | `"!=="`
26+
27+
### value
28+
29+
The string literal value to compare against
30+
31+
`"development"` | `"production"`
32+
33+
## Returns
34+
35+
`node is BinaryExpression`
36+
37+
True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise

packages/utilities/kit/docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
## Namespaces
88

9+
- [ContextDetection](@eslint-react/namespaces/ContextDetection/README.md)
910
- [JsxConfig](@eslint-react/namespaces/JsxConfig/README.md)
1011
- [LanguagePreference](@eslint-react/namespaces/LanguagePreference/README.md)
1112
- [RegExp](@eslint-react/namespaces/RegExp/README.md)

packages/utilities/kit/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
},
3636
"dependencies": {
3737
"@eslint-react/eff": "workspace:*",
38+
"@eslint-react/ast": "workspace:*",
3839
"@typescript-eslint/utils": "^8.40.0",
3940
"ts-pattern": "^5.8.0",
4041
"zod": "^4.0.17"

packages/utilities/ast/src/ast-process-env.ts renamed to packages/utilities/kit/src/ContextDetection.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
import * as AST from "@eslint-react/ast";
12
import type { unit } from "@eslint-react/eff";
2-
import type { TSESTree } from "@typescript-eslint/types";
3-
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
4-
import { isLiteral } from "./ast-literal-is";
3+
import { AST_NODE_TYPES as T, type TSESTree } from "@typescript-eslint/types";
54

65
/**
76
* Check if the given node is a member expression that accesses `process.env.NODE_ENV`
@@ -35,11 +34,29 @@ export function isProcessEnvNodeEnvCompare(
3534
if (node == null) return false;
3635
if (node.type !== T.BinaryExpression) return false;
3736
if (node.operator !== operator) return false;
38-
if (isProcessEnvNodeEnv(node.left) && isLiteral(node.right, "string")) {
37+
if (isProcessEnvNodeEnv(node.left) && AST.isLiteral(node.right, "string")) {
3938
return node.right.value === value;
4039
}
41-
if (isLiteral(node.left, "string") && isProcessEnvNodeEnv(node.right)) {
40+
if (AST.isLiteral(node.left, "string") && isProcessEnvNodeEnv(node.right)) {
4241
return node.left.value === value;
4342
}
4443
return false;
4544
}
45+
46+
/**
47+
* Checks if the given node is a `vi.mock` callback.
48+
* @param node The node to check
49+
* @returns `true` if the node is a `vi.mock` callback, otherwise `false`.
50+
* @internal
51+
*/
52+
export function isViMockCallback(node: TSESTree.Node | null | unit): node is TSESTree.FunctionExpression {
53+
return node != null
54+
&& node.type === T.FunctionExpression
55+
&& node.parent.type === T.CallExpression
56+
&& node.parent.callee.type === T.MemberExpression
57+
&& node.parent.callee.object.type === T.Identifier
58+
&& node.parent.callee.object.name === "vi"
59+
&& node.parent.callee.property.type === T.Identifier
60+
&& node.parent.callee.property.name === "mock"
61+
&& node.parent.arguments[1] === node;
62+
}

packages/utilities/kit/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * as ContextDetection from "./ContextDetection";
12
export * as JsxConfig from "./JsxConfig";
23
export * as LanguagePreference from "./LanguagePreference";
34
export * as RegExp from "./RegExp";

0 commit comments

Comments
 (0)