@eslint-react/core 2.7.5-next.5 → 2.7.5-next.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/dist/index.d.ts +58 -53
- package/dist/index.js +48 -50
- package/package.json +5 -6
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,12 @@ import { unit } from "@eslint-react/eff";
|
|
|
3
3
|
import { TSESTree } from "@typescript-eslint/types";
|
|
4
4
|
import { RegExpLike, RuleContext } from "@eslint-react/shared";
|
|
5
5
|
import { ESLintUtils, TSESTree as TSESTree$1 } from "@typescript-eslint/utils";
|
|
6
|
-
import * as birecord0 from "birecord";
|
|
7
6
|
import { Scope } from "@typescript-eslint/scope-manager";
|
|
8
7
|
import * as typescript0 from "typescript";
|
|
9
8
|
|
|
10
9
|
//#region src/api/is-from-react.d.ts
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
11
|
+
* Check if a variable is initialized from React import
|
|
13
12
|
* @param name The variable name
|
|
14
13
|
* @param initialScope The initial scope
|
|
15
14
|
* @param importSource Alternative import source of React (e.g., "preact/compat")
|
|
@@ -19,7 +18,7 @@ declare function isInitializedFromReact(name: string, initialScope: Scope, impor
|
|
|
19
18
|
//#endregion
|
|
20
19
|
//#region src/api/is-from-react-native.d.ts
|
|
21
20
|
/**
|
|
22
|
-
*
|
|
21
|
+
* if a variable is initialized from React Native import
|
|
23
22
|
* @param name The variable name
|
|
24
23
|
* @param initialScope The initial scope
|
|
25
24
|
* @param importSource Alternative import source of React Native (e.g., "react-native-web")
|
|
@@ -35,7 +34,7 @@ declare namespace isReactAPI {
|
|
|
35
34
|
};
|
|
36
35
|
}
|
|
37
36
|
/**
|
|
38
|
-
*
|
|
37
|
+
* Check if the node is a React API identifier or member expression
|
|
39
38
|
* @param api The React API name to check against (e.g., "useState", "React.memo")
|
|
40
39
|
* @returns A predicate function to check if a node matches the API
|
|
41
40
|
*/
|
|
@@ -47,7 +46,7 @@ declare namespace isReactAPICall {
|
|
|
47
46
|
};
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
|
-
*
|
|
49
|
+
* Check if the node is a call expression to a specific React API
|
|
51
50
|
* @param api The React API name to check against
|
|
52
51
|
* @returns A predicate function to check if a node is a call to the API
|
|
53
52
|
*/
|
|
@@ -152,18 +151,20 @@ interface SemanticFunc extends SemanticNode {
|
|
|
152
151
|
//#endregion
|
|
153
152
|
//#region src/component/component-flag.d.ts
|
|
154
153
|
type ComponentFlag = bigint;
|
|
154
|
+
/**
|
|
155
|
+
* Component flag constants
|
|
156
|
+
*/
|
|
155
157
|
declare const ComponentFlag: {
|
|
156
158
|
/** No flags set */None: bigint; /** Indicates the component is a pure component (e.g., extends PureComponent) */
|
|
157
159
|
PureComponent: bigint; /** Indicates the component creates elements using `createElement` instead of JSX */
|
|
158
160
|
CreateElement: bigint; /** Indicates the component is memoized (e.g., React.memo) */
|
|
159
161
|
Memo: bigint; /** Indicates the component forwards a ref (e.g., React.forwardRef) */
|
|
160
|
-
ForwardRef: bigint;
|
|
161
|
-
Async: bigint;
|
|
162
|
+
ForwardRef: bigint;
|
|
162
163
|
};
|
|
163
164
|
//#endregion
|
|
164
165
|
//#region src/component/component-semantic-node.d.ts
|
|
165
166
|
/**
|
|
166
|
-
* Represents a React
|
|
167
|
+
* Represents a React Function Component
|
|
167
168
|
*/
|
|
168
169
|
interface FunctionComponentSemanticNode extends SemanticNode {
|
|
169
170
|
/**
|
|
@@ -212,7 +213,7 @@ interface FunctionComponentSemanticNode extends SemanticNode {
|
|
|
212
213
|
displayName: unit | TSESTree.Expression;
|
|
213
214
|
}
|
|
214
215
|
/**
|
|
215
|
-
* Represents a React
|
|
216
|
+
* Represents a React Class Component
|
|
216
217
|
*/
|
|
217
218
|
interface ClassComponentSemanticNode extends SemanticNode {
|
|
218
219
|
/**
|
|
@@ -245,7 +246,7 @@ interface ClassComponentSemanticNode extends SemanticNode {
|
|
|
245
246
|
displayName: unit | TSESTree.Expression;
|
|
246
247
|
}
|
|
247
248
|
/**
|
|
248
|
-
*
|
|
249
|
+
* Represents a React Component
|
|
249
250
|
*/
|
|
250
251
|
type ComponentSemanticNode = ClassComponentSemanticNode | FunctionComponentSemanticNode;
|
|
251
252
|
//#endregion
|
|
@@ -276,7 +277,7 @@ declare namespace useComponentCollector {
|
|
|
276
277
|
};
|
|
277
278
|
}
|
|
278
279
|
/**
|
|
279
|
-
* Get a ctx and visitor for the rule to collect function components
|
|
280
|
+
* Get a ctx and visitor object for the rule to collect function components
|
|
280
281
|
* @param context The ESLint rule context
|
|
281
282
|
* @param options The options to use
|
|
282
283
|
* @returns The ctx and visitor of the collector
|
|
@@ -293,7 +294,7 @@ declare namespace useComponentCollectorLegacy {
|
|
|
293
294
|
};
|
|
294
295
|
}
|
|
295
296
|
/**
|
|
296
|
-
* Get a ctx and visitor object for the rule to collect class
|
|
297
|
+
* Get a ctx and visitor object for the rule to collect class componentss
|
|
297
298
|
* @param context The ESLint rule context
|
|
298
299
|
* @returns The ctx and visitor of the collector
|
|
299
300
|
*/
|
|
@@ -313,7 +314,7 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
313
314
|
//#endregion
|
|
314
315
|
//#region src/component/component-definition.d.ts
|
|
315
316
|
/**
|
|
316
|
-
*
|
|
317
|
+
* Determine if a function node represents a valid React component definition
|
|
317
318
|
*
|
|
318
319
|
* @param context The rule context
|
|
319
320
|
* @param node The function node to analyze
|
|
@@ -323,9 +324,20 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
323
324
|
declare function isComponentDefinition(context: RuleContext, node: AST.TSESTreeFunction, hint: bigint): boolean;
|
|
324
325
|
//#endregion
|
|
325
326
|
//#region src/component/component-id.d.ts
|
|
327
|
+
/**
|
|
328
|
+
* Get function component identifier from `const Component = memo(() => {});`
|
|
329
|
+
* @param context The rule context
|
|
330
|
+
* @param node The function node to analyze
|
|
331
|
+
* @returns The function identifier or `unit` if not found
|
|
332
|
+
*/
|
|
326
333
|
declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): AST.FunctionID | unit;
|
|
327
334
|
//#endregion
|
|
328
335
|
//#region src/component/component-init-path.d.ts
|
|
336
|
+
/**
|
|
337
|
+
* Get component flag from init path
|
|
338
|
+
* @param initPath The init path of the function component
|
|
339
|
+
* @returns The component flag
|
|
340
|
+
*/
|
|
329
341
|
declare function getComponentFlagFromInitPath(initPath: FunctionComponentSemanticNode["initPath"]): bigint;
|
|
330
342
|
//#endregion
|
|
331
343
|
//#region src/component/component-is.d.ts
|
|
@@ -338,24 +350,27 @@ declare function isClassComponent(node: TSESTree.Node): node is AST.TSESTreeClas
|
|
|
338
350
|
/**
|
|
339
351
|
* Check if a node is a React PureComponent
|
|
340
352
|
* @param node The AST node to check
|
|
341
|
-
* @returns `true` if the node is a
|
|
353
|
+
* @returns `true` if the node is a PureComponent, `false` otherwise
|
|
342
354
|
*/
|
|
343
355
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
344
356
|
//#endregion
|
|
345
357
|
//#region src/component/component-kind.d.ts
|
|
358
|
+
/**
|
|
359
|
+
* Represents the kind of a React component
|
|
360
|
+
*/
|
|
346
361
|
type ComponentKind = "classComponent" | "functionComponent";
|
|
347
362
|
//#endregion
|
|
348
363
|
//#region src/component/component-method-callback.d.ts
|
|
349
364
|
/**
|
|
350
|
-
*
|
|
351
|
-
* @param node The
|
|
352
|
-
* @returns
|
|
365
|
+
* Check if the given node is a componentDidMount callback
|
|
366
|
+
* @param node The node to check
|
|
367
|
+
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
353
368
|
*/
|
|
354
369
|
declare function isComponentDidMountCallback(node: TSESTree.Node): boolean;
|
|
355
370
|
/**
|
|
356
|
-
*
|
|
357
|
-
* @param node The
|
|
358
|
-
* @returns
|
|
371
|
+
* Check if the given node is a componentWillUnmount callback
|
|
372
|
+
* @param node The node to check
|
|
373
|
+
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
359
374
|
*/
|
|
360
375
|
declare function isComponentWillUnmountCallback(node: TSESTree.Node): boolean;
|
|
361
376
|
//#endregion
|
|
@@ -397,22 +412,6 @@ declare function isComponentNameLoose(name: string): boolean;
|
|
|
397
412
|
*/
|
|
398
413
|
declare function hasNoneOrLooseComponentName(context: RuleContext, fn: AST.TSESTreeFunction): boolean;
|
|
399
414
|
//#endregion
|
|
400
|
-
//#region src/component/component-phase.d.ts
|
|
401
|
-
type ComponentEffectPhaseKind = "cleanup" | "setup";
|
|
402
|
-
type ComponentLifecyclePhaseKind = "mount" | "unmount";
|
|
403
|
-
type ComponentPhaseKind = ComponentEffectPhaseKind | ComponentLifecyclePhaseKind;
|
|
404
|
-
declare const ComponentPhaseRelevance: birecord0.BiRecord<{
|
|
405
|
-
readonly mount: "unmount";
|
|
406
|
-
readonly setup: "cleanup";
|
|
407
|
-
}>;
|
|
408
|
-
//#endregion
|
|
409
|
-
//#region src/component/component-phase-helpers.d.ts
|
|
410
|
-
declare const isInversePhase: {
|
|
411
|
-
(a: ComponentPhaseKind): (b: ComponentPhaseKind) => boolean;
|
|
412
|
-
(a: ComponentPhaseKind, b: ComponentPhaseKind): boolean;
|
|
413
|
-
};
|
|
414
|
-
declare function getPhaseKindOfFunction(node: AST.TSESTreeFunction): ComponentPhaseKind | null;
|
|
415
|
-
//#endregion
|
|
416
415
|
//#region src/component/component-render-method.d.ts
|
|
417
416
|
/**
|
|
418
417
|
* Check whether given node is a render method of a class component
|
|
@@ -511,7 +510,7 @@ declare function isComponentWrapperCallbackLoose(context: RuleContext, node: TSE
|
|
|
511
510
|
//#endregion
|
|
512
511
|
//#region src/function/function-semantic-node.d.ts
|
|
513
512
|
/**
|
|
514
|
-
* Represents a React
|
|
513
|
+
* Represents a React Client Function
|
|
515
514
|
*/
|
|
516
515
|
interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
517
516
|
/**
|
|
@@ -519,12 +518,18 @@ interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
|
519
518
|
*/
|
|
520
519
|
kind: "client-function";
|
|
521
520
|
}
|
|
521
|
+
/**
|
|
522
|
+
* Represents a React Server Function
|
|
523
|
+
*/
|
|
522
524
|
interface ServerFunctionSemanticNode extends SemanticFunc {
|
|
523
525
|
/**
|
|
524
526
|
* The kind of function
|
|
525
527
|
*/
|
|
526
528
|
kind: "server-function";
|
|
527
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Represents a React Function
|
|
532
|
+
*/
|
|
528
533
|
type FunctionSemanticNode = ClientFunctionSemanticNode | ServerFunctionSemanticNode;
|
|
529
534
|
//#endregion
|
|
530
535
|
//#region src/hierarchy/find-enclosing-component-or-hook.d.ts
|
|
@@ -539,7 +544,7 @@ declare function findEnclosingComponentOrHook(node: TSESTree.Node | unit, test?:
|
|
|
539
544
|
//#endregion
|
|
540
545
|
//#region src/hierarchy/is-inside-component-or-hook.d.ts
|
|
541
546
|
/**
|
|
542
|
-
*
|
|
547
|
+
* Check if a given AST node is inside a React component or hook
|
|
543
548
|
* @param node The AST node to check
|
|
544
549
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
545
550
|
*/
|
|
@@ -547,12 +552,12 @@ declare function isInsideComponentOrHook(node: TSESTree.Node | unit): boolean;
|
|
|
547
552
|
//#endregion
|
|
548
553
|
//#region src/hook/hook-callback.d.ts
|
|
549
554
|
/**
|
|
550
|
-
*
|
|
555
|
+
* Determine if a node is the setup function passed to a useEffect-like hook
|
|
551
556
|
* @param node The AST node to check
|
|
552
557
|
*/
|
|
553
558
|
declare function isUseEffectSetupCallback(node: TSESTree.Node | unit): boolean;
|
|
554
559
|
/**
|
|
555
|
-
*
|
|
560
|
+
* Determine if a node is the cleanup function returned by a useEffect-like hook's setup function.
|
|
556
561
|
* @param node The AST node to check
|
|
557
562
|
*/
|
|
558
563
|
declare function isUseEffectCleanupCallback(node: TSESTree.Node | unit): boolean;
|
|
@@ -582,7 +587,7 @@ declare namespace useHookCollector {
|
|
|
582
587
|
};
|
|
583
588
|
}
|
|
584
589
|
/**
|
|
585
|
-
* Get a ctx and visitor for the rule to collect hooks
|
|
590
|
+
* Get a ctx and visitor object for the rule to collect hooks
|
|
586
591
|
* @param context The ESLint rule context
|
|
587
592
|
* @returns The ctx and visitor of the collector
|
|
588
593
|
*/
|
|
@@ -593,7 +598,7 @@ declare function isHookId(id: TSESTree.Node): id is TSESTree.Identifier | TSESTr
|
|
|
593
598
|
//#endregion
|
|
594
599
|
//#region src/hook/hook-is.d.ts
|
|
595
600
|
/**
|
|
596
|
-
*
|
|
601
|
+
* Determine if a function node is a React Hook based on its name.
|
|
597
602
|
* @param node The function node to check
|
|
598
603
|
* @returns True if the function is a React Hook, false otherwise
|
|
599
604
|
*/
|
|
@@ -605,21 +610,21 @@ declare function isHook(node: AST.TSESTreeFunction | unit): boolean;
|
|
|
605
610
|
*/
|
|
606
611
|
declare function isHookCall(node: TSESTree.Node | unit): node is TSESTree.CallExpression;
|
|
607
612
|
/**
|
|
608
|
-
*
|
|
613
|
+
* Check if a node is a call to a specific React hook.
|
|
609
614
|
* Returns a function that accepts a hook name to check against.
|
|
610
615
|
* @param node The AST node to check
|
|
611
616
|
* @returns A function that takes a hook name and returns boolean
|
|
612
617
|
*/
|
|
613
618
|
declare function isHookCallWithName(node: TSESTree.Node | unit): (name: string) => boolean;
|
|
614
619
|
/**
|
|
615
|
-
*
|
|
620
|
+
* Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
|
|
616
621
|
* @param node The AST node to check
|
|
617
622
|
* @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks
|
|
618
623
|
* @returns True if the node is a useEffect-like call
|
|
619
624
|
*/
|
|
620
625
|
declare function isUseEffectLikeCall(node: TSESTree.Node | unit, additionalEffectHooks?: RegExpLike): node is TSESTree.CallExpression;
|
|
621
626
|
/**
|
|
622
|
-
*
|
|
627
|
+
* Detect useState calls and variations (useCustomState, etc.) using a regex pattern
|
|
623
628
|
* @param node The AST node to check
|
|
624
629
|
* @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks
|
|
625
630
|
* @returns True if the node is a useState-like call
|
|
@@ -703,7 +708,7 @@ type JsxAttributeValue = {
|
|
|
703
708
|
toStatic(): unknown;
|
|
704
709
|
};
|
|
705
710
|
/**
|
|
706
|
-
*
|
|
711
|
+
* Resolve the static value of a JSX attribute or spread attribute
|
|
707
712
|
*
|
|
708
713
|
* @param context - The ESLint rule context
|
|
709
714
|
* @param attribute - The JSX attribute node to resolve
|
|
@@ -793,13 +798,13 @@ declare const JsxDetectionHint: {
|
|
|
793
798
|
*/
|
|
794
799
|
declare const DEFAULT_JSX_DETECTION_HINT: bigint;
|
|
795
800
|
/**
|
|
796
|
-
*
|
|
801
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
797
802
|
* @param node The AST node to check
|
|
798
803
|
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
799
804
|
*/
|
|
800
805
|
declare function isJsxText(node: TSESTree$1.Node | null | unit): node is TSESTree$1.JSXText | TSESTree$1.Literal;
|
|
801
806
|
/**
|
|
802
|
-
*
|
|
807
|
+
* Determine if a node represents JSX-like content based on heuristics
|
|
803
808
|
* Supports configuration through hint flags to customize detection behavior
|
|
804
809
|
*
|
|
805
810
|
* @param code The source code with scope lookup capability
|
|
@@ -814,7 +819,7 @@ declare function isJsxLike(code: {
|
|
|
814
819
|
//#endregion
|
|
815
820
|
//#region src/jsx/jsx-element-is.d.ts
|
|
816
821
|
/**
|
|
817
|
-
*
|
|
822
|
+
* Determine if a JSX element is a host element
|
|
818
823
|
* Host elements in React start with lowercase letters (e.g., div, span)
|
|
819
824
|
*
|
|
820
825
|
* @param context ESLint rule context
|
|
@@ -823,7 +828,7 @@ declare function isJsxLike(code: {
|
|
|
823
828
|
*/
|
|
824
829
|
declare function isJsxHostElement(context: RuleContext, node: TSESTree.Node): boolean;
|
|
825
830
|
/**
|
|
826
|
-
*
|
|
831
|
+
* Determine if a JSX element is a React Fragment
|
|
827
832
|
* Fragments can be imported from React and used like <Fragment> or <React.Fragment>
|
|
828
833
|
*
|
|
829
834
|
* @param context ESLint rule context
|
|
@@ -868,7 +873,7 @@ declare function stringifyJsx(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXNam
|
|
|
868
873
|
//#endregion
|
|
869
874
|
//#region src/ref/is-from-ref.d.ts
|
|
870
875
|
/**
|
|
871
|
-
*
|
|
876
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
872
877
|
* @param name The variable name
|
|
873
878
|
* @param initialScope The initial scope
|
|
874
879
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -877,10 +882,10 @@ declare function isInitializedFromRef(name: string, initialScope: Scope): boolea
|
|
|
877
882
|
//#endregion
|
|
878
883
|
//#region src/ref/ref-name.d.ts
|
|
879
884
|
/**
|
|
880
|
-
*
|
|
885
|
+
* Check if a given name corresponds to a ref name
|
|
881
886
|
* @param name The name to check
|
|
882
887
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
883
888
|
*/
|
|
884
889
|
declare function isRefName(name: string): boolean;
|
|
885
890
|
//#endregion
|
|
886
|
-
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint,
|
|
891
|
+
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentKind, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FindEnclosingComponentOrHookFilter, FunctionComponentSemanticNode, FunctionSemanticNode, HookSemanticNode, JsxAttributeValue, JsxConfig, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveJsxAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,10 @@ import { IdGenerator, RE_ANNOTATION_JSX, RE_ANNOTATION_JSX_FRAG, RE_ANNOTATION_J
|
|
|
6
6
|
import { getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
7
7
|
import { P, match } from "ts-pattern";
|
|
8
8
|
import { AST_NODE_TYPES as AST_NODE_TYPES$1 } from "@typescript-eslint/utils";
|
|
9
|
-
import birecord from "birecord";
|
|
10
9
|
|
|
11
10
|
//#region src/api/is-from-react.ts
|
|
12
11
|
/**
|
|
13
|
-
*
|
|
12
|
+
* Check if a variable is initialized from React import
|
|
14
13
|
* @param name The variable name
|
|
15
14
|
* @param initialScope The initial scope
|
|
16
15
|
* @param importSource Alternative import source of React (e.g., "preact/compat")
|
|
@@ -23,7 +22,7 @@ function isInitializedFromReact(name, initialScope, importSource = "react") {
|
|
|
23
22
|
//#endregion
|
|
24
23
|
//#region src/api/is-from-react-native.ts
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
25
|
+
* if a variable is initialized from React Native import
|
|
27
26
|
* @param name The variable name
|
|
28
27
|
* @param initialScope The initial scope
|
|
29
28
|
* @param importSource Alternative import source of React Native (e.g., "react-native-web")
|
|
@@ -40,7 +39,7 @@ function isInitializedFromReactNative(name, initialScope, importSource = "react-
|
|
|
40
39
|
//#endregion
|
|
41
40
|
//#region src/api/is-react-api.ts
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
42
|
+
* Check if the node is a React API identifier or member expression
|
|
44
43
|
* @param api The React API name to check against (e.g., "useState", "React.memo")
|
|
45
44
|
* @returns A predicate function to check if a node matches the API
|
|
46
45
|
*/
|
|
@@ -56,7 +55,7 @@ function isReactAPI(api) {
|
|
|
56
55
|
return dual(2, func);
|
|
57
56
|
}
|
|
58
57
|
/**
|
|
59
|
-
*
|
|
58
|
+
* Check if the node is a call expression to a specific React API
|
|
60
59
|
* @param api The React API name to check against
|
|
61
60
|
* @returns A predicate function to check if a node is a call to the API
|
|
62
61
|
*/
|
|
@@ -131,7 +130,7 @@ function isHookName(name) {
|
|
|
131
130
|
//#endregion
|
|
132
131
|
//#region src/hook/hook-is.ts
|
|
133
132
|
/**
|
|
134
|
-
*
|
|
133
|
+
* Determine if a function node is a React Hook based on its name.
|
|
135
134
|
* @param node The function node to check
|
|
136
135
|
* @returns True if the function is a React Hook, false otherwise
|
|
137
136
|
*/
|
|
@@ -157,7 +156,7 @@ function isHookCall(node) {
|
|
|
157
156
|
return false;
|
|
158
157
|
}
|
|
159
158
|
/**
|
|
160
|
-
*
|
|
159
|
+
* Check if a node is a call to a specific React hook.
|
|
161
160
|
* Returns a function that accepts a hook name to check against.
|
|
162
161
|
* @param node The AST node to check
|
|
163
162
|
* @returns A function that takes a hook name and returns boolean
|
|
@@ -173,7 +172,7 @@ function isHookCallWithName(node) {
|
|
|
173
172
|
};
|
|
174
173
|
}
|
|
175
174
|
/**
|
|
176
|
-
*
|
|
175
|
+
* Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
|
|
177
176
|
* @param node The AST node to check
|
|
178
177
|
* @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks
|
|
179
178
|
* @returns True if the node is a useEffect-like call
|
|
@@ -188,7 +187,7 @@ function isUseEffectLikeCall(node, additionalEffectHooks = { test: constFalse })
|
|
|
188
187
|
});
|
|
189
188
|
}
|
|
190
189
|
/**
|
|
191
|
-
*
|
|
190
|
+
* Detect useState calls and variations (useCustomState, etc.) using a regex pattern
|
|
192
191
|
* @param node The AST node to check
|
|
193
192
|
* @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks
|
|
194
193
|
* @returns True if the node is a useState-like call
|
|
@@ -225,7 +224,7 @@ const isUseTransitionCall = flip(isHookCallWithName)("useTransition");
|
|
|
225
224
|
//#endregion
|
|
226
225
|
//#region src/hook/hook-callback.ts
|
|
227
226
|
/**
|
|
228
|
-
*
|
|
227
|
+
* Determine if a node is the setup function passed to a useEffect-like hook
|
|
229
228
|
* @param node The AST node to check
|
|
230
229
|
*/
|
|
231
230
|
function isUseEffectSetupCallback(node) {
|
|
@@ -233,7 +232,7 @@ function isUseEffectSetupCallback(node) {
|
|
|
233
232
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.arguments.at(0) === node && isUseEffectLikeCall(node.parent);
|
|
234
233
|
}
|
|
235
234
|
/**
|
|
236
|
-
*
|
|
235
|
+
* Determine if a node is the cleanup function returned by a useEffect-like hook's setup function.
|
|
237
236
|
* @param node The AST node to check
|
|
238
237
|
*/
|
|
239
238
|
function isUseEffectCleanupCallback(node) {
|
|
@@ -258,7 +257,7 @@ function isHookId(id) {
|
|
|
258
257
|
//#region src/hook/hook-collector.ts
|
|
259
258
|
const idGen$2 = new IdGenerator("hook_");
|
|
260
259
|
/**
|
|
261
|
-
* Get a ctx and visitor for the rule to collect hooks
|
|
260
|
+
* Get a ctx and visitor object for the rule to collect hooks
|
|
262
261
|
* @param context The ESLint rule context
|
|
263
262
|
* @returns The ctx and visitor of the collector
|
|
264
263
|
*/
|
|
@@ -388,7 +387,7 @@ function getJsxAttribute(context, node, initialScope) {
|
|
|
388
387
|
//#endregion
|
|
389
388
|
//#region src/jsx/jsx-attribute-value.ts
|
|
390
389
|
/**
|
|
391
|
-
*
|
|
390
|
+
* Resolve the static value of a JSX attribute or spread attribute
|
|
392
391
|
*
|
|
393
392
|
* @param context - The ESLint rule context
|
|
394
393
|
* @param attribute - The JSX attribute node to resolve
|
|
@@ -536,7 +535,7 @@ const JsxDetectionHint = {
|
|
|
536
535
|
*/
|
|
537
536
|
const DEFAULT_JSX_DETECTION_HINT = 0n | JsxDetectionHint.SkipUndefined | JsxDetectionHint.SkipBooleanLiteral;
|
|
538
537
|
/**
|
|
539
|
-
*
|
|
538
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
540
539
|
* @param node The AST node to check
|
|
541
540
|
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
542
541
|
*/
|
|
@@ -545,7 +544,7 @@ function isJsxText(node) {
|
|
|
545
544
|
return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
|
|
546
545
|
}
|
|
547
546
|
/**
|
|
548
|
-
*
|
|
547
|
+
* Determine if a node represents JSX-like content based on heuristics
|
|
549
548
|
* Supports configuration through hint flags to customize detection behavior
|
|
550
549
|
*
|
|
551
550
|
* @param code The source code with scope lookup capability
|
|
@@ -627,7 +626,7 @@ function getJsxElementType(context, node) {
|
|
|
627
626
|
//#endregion
|
|
628
627
|
//#region src/jsx/jsx-element-is.ts
|
|
629
628
|
/**
|
|
630
|
-
*
|
|
629
|
+
* Determine if a JSX element is a host element
|
|
631
630
|
* Host elements in React start with lowercase letters (e.g., div, span)
|
|
632
631
|
*
|
|
633
632
|
* @param context ESLint rule context
|
|
@@ -638,7 +637,7 @@ function isJsxHostElement(context, node) {
|
|
|
638
637
|
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
|
|
639
638
|
}
|
|
640
639
|
/**
|
|
641
|
-
*
|
|
640
|
+
* Determine if a JSX element is a React Fragment
|
|
642
641
|
* Fragments can be imported from React and used like <Fragment> or <React.Fragment>
|
|
643
642
|
*
|
|
644
643
|
* @param context ESLint rule context
|
|
@@ -709,7 +708,7 @@ function isClassComponent(node) {
|
|
|
709
708
|
/**
|
|
710
709
|
* Check if a node is a React PureComponent
|
|
711
710
|
* @param node The AST node to check
|
|
712
|
-
* @returns `true` if the node is a
|
|
711
|
+
* @returns `true` if the node is a PureComponent, `false` otherwise
|
|
713
712
|
*/
|
|
714
713
|
function isPureComponent(node) {
|
|
715
714
|
if ("superClass" in node && node.superClass != null) {
|
|
@@ -743,7 +742,7 @@ function isRenderMethodLike(node) {
|
|
|
743
742
|
//#endregion
|
|
744
743
|
//#region src/component/component-definition.ts
|
|
745
744
|
/**
|
|
746
|
-
*
|
|
745
|
+
* Check if the given node is a function within a render method of a class component.
|
|
747
746
|
*
|
|
748
747
|
* @param node The AST node to check
|
|
749
748
|
* @returns `true` if the node is a render function inside a class component
|
|
@@ -761,7 +760,7 @@ function isRenderMethodCallback(node) {
|
|
|
761
760
|
return greatGrandparent != null && isRenderMethodLike(parent) && isClassComponent(greatGrandparent);
|
|
762
761
|
}
|
|
763
762
|
/**
|
|
764
|
-
*
|
|
763
|
+
* Check if a function node should be excluded based on provided detection hints
|
|
765
764
|
*
|
|
766
765
|
* @param node The function node to check
|
|
767
766
|
* @param hint Component detection hints as bit flags
|
|
@@ -779,7 +778,7 @@ function shouldExcludeBasedOnHint(node, hint) {
|
|
|
779
778
|
return false;
|
|
780
779
|
}
|
|
781
780
|
/**
|
|
782
|
-
*
|
|
781
|
+
* Determine if the node is an argument within `createElement`'s children list (3rd argument onwards)
|
|
783
782
|
*
|
|
784
783
|
* @param context The rule context
|
|
785
784
|
* @param node The AST node to check
|
|
@@ -792,7 +791,7 @@ function isChildrenOfCreateElement(context, node) {
|
|
|
792
791
|
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
793
792
|
}
|
|
794
793
|
/**
|
|
795
|
-
*
|
|
794
|
+
* Determine if a function node represents a valid React component definition
|
|
796
795
|
*
|
|
797
796
|
* @param context The rule context
|
|
798
797
|
* @param node The function node to analyze
|
|
@@ -863,6 +862,12 @@ function isComponentWrapperCallbackLoose(context, node) {
|
|
|
863
862
|
|
|
864
863
|
//#endregion
|
|
865
864
|
//#region src/component/component-id.ts
|
|
865
|
+
/**
|
|
866
|
+
* Get function component identifier from `const Component = memo(() => {});`
|
|
867
|
+
* @param context The rule context
|
|
868
|
+
* @param node The function node to analyze
|
|
869
|
+
* @returns The function identifier or `unit` if not found
|
|
870
|
+
*/
|
|
866
871
|
function getFunctionComponentId(context, node) {
|
|
867
872
|
const functionId = AST.getFunctionId(node);
|
|
868
873
|
if (functionId != null) return functionId;
|
|
@@ -874,17 +879,24 @@ function getFunctionComponentId(context, node) {
|
|
|
874
879
|
|
|
875
880
|
//#endregion
|
|
876
881
|
//#region src/component/component-flag.ts
|
|
882
|
+
/**
|
|
883
|
+
* Component flag constants
|
|
884
|
+
*/
|
|
877
885
|
const ComponentFlag = {
|
|
878
886
|
None: 0n,
|
|
879
887
|
PureComponent: 1n << 0n,
|
|
880
888
|
CreateElement: 1n << 1n,
|
|
881
889
|
Memo: 1n << 2n,
|
|
882
|
-
ForwardRef: 1n << 3n
|
|
883
|
-
Async: 1n << 4n
|
|
890
|
+
ForwardRef: 1n << 3n
|
|
884
891
|
};
|
|
885
892
|
|
|
886
893
|
//#endregion
|
|
887
894
|
//#region src/component/component-init-path.ts
|
|
895
|
+
/**
|
|
896
|
+
* Get component flag from init path
|
|
897
|
+
* @param initPath The init path of the function component
|
|
898
|
+
* @returns The component flag
|
|
899
|
+
*/
|
|
888
900
|
function getComponentFlagFromInitPath(initPath) {
|
|
889
901
|
let flag = ComponentFlag.None;
|
|
890
902
|
if (initPath != null && AST.hasCallInFunctionInitPath("memo", initPath)) flag |= ComponentFlag.Memo;
|
|
@@ -925,7 +937,7 @@ function hasNoneOrLooseComponentName(context, fn) {
|
|
|
925
937
|
//#region src/component/component-collector.ts
|
|
926
938
|
const idGen$1 = new IdGenerator("function_component_");
|
|
927
939
|
/**
|
|
928
|
-
* Get a ctx and visitor for the rule to collect function components
|
|
940
|
+
* Get a ctx and visitor object for the rule to collect function components
|
|
929
941
|
* @param context The ESLint rule context
|
|
930
942
|
* @param options The options to use
|
|
931
943
|
* @returns The ctx and visitor of the collector
|
|
@@ -1045,7 +1057,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1045
1057
|
//#region src/component/component-collector-legacy.ts
|
|
1046
1058
|
const idGen = new IdGenerator("class_component_");
|
|
1047
1059
|
/**
|
|
1048
|
-
* Get a ctx and visitor object for the rule to collect class
|
|
1060
|
+
* Get a ctx and visitor object for the rule to collect class componentss
|
|
1049
1061
|
* @param context The ESLint rule context
|
|
1050
1062
|
* @returns The ctx and visitor of the collector
|
|
1051
1063
|
*/
|
|
@@ -1134,36 +1146,22 @@ const isGetDerivedStateFromError = createLifecycleChecker("getDerivedStateFromEr
|
|
|
1134
1146
|
//#endregion
|
|
1135
1147
|
//#region src/component/component-method-callback.ts
|
|
1136
1148
|
/**
|
|
1137
|
-
*
|
|
1138
|
-
* @param node The
|
|
1139
|
-
* @returns
|
|
1149
|
+
* Check if the given node is a componentDidMount callback
|
|
1150
|
+
* @param node The node to check
|
|
1151
|
+
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
1140
1152
|
*/
|
|
1141
1153
|
function isComponentDidMountCallback(node) {
|
|
1142
1154
|
return AST.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
1143
1155
|
}
|
|
1144
1156
|
/**
|
|
1145
|
-
*
|
|
1146
|
-
* @param node The
|
|
1147
|
-
* @returns
|
|
1157
|
+
* Check if the given node is a componentWillUnmount callback
|
|
1158
|
+
* @param node The node to check
|
|
1159
|
+
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
1148
1160
|
*/
|
|
1149
1161
|
function isComponentWillUnmountCallback(node) {
|
|
1150
1162
|
return AST.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
1151
1163
|
}
|
|
1152
1164
|
|
|
1153
|
-
//#endregion
|
|
1154
|
-
//#region src/component/component-phase.ts
|
|
1155
|
-
const ComponentPhaseRelevance = birecord({
|
|
1156
|
-
mount: "unmount",
|
|
1157
|
-
setup: "cleanup"
|
|
1158
|
-
});
|
|
1159
|
-
|
|
1160
|
-
//#endregion
|
|
1161
|
-
//#region src/component/component-phase-helpers.ts
|
|
1162
|
-
const isInversePhase = dual(2, (a, b) => ComponentPhaseRelevance.get(a) === b);
|
|
1163
|
-
function getPhaseKindOfFunction(node) {
|
|
1164
|
-
return match(node).when(isUseEffectSetupCallback, () => "setup").when(isUseEffectCleanupCallback, () => "cleanup").when(isComponentDidMountCallback, () => "mount").when(isComponentWillUnmountCallback, () => "unmount").otherwise(() => null);
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
1165
|
//#endregion
|
|
1168
1166
|
//#region src/component/component-render-prop.ts
|
|
1169
1167
|
/**
|
|
@@ -1263,7 +1261,7 @@ function findEnclosingComponentOrHook(node, test = (n, name) => {
|
|
|
1263
1261
|
//#endregion
|
|
1264
1262
|
//#region src/hierarchy/is-inside-component-or-hook.ts
|
|
1265
1263
|
/**
|
|
1266
|
-
*
|
|
1264
|
+
* Check if a given AST node is inside a React component or hook
|
|
1267
1265
|
* @param node The AST node to check
|
|
1268
1266
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
1269
1267
|
*/
|
|
@@ -1274,7 +1272,7 @@ function isInsideComponentOrHook(node) {
|
|
|
1274
1272
|
//#endregion
|
|
1275
1273
|
//#region src/ref/ref-name.ts
|
|
1276
1274
|
/**
|
|
1277
|
-
*
|
|
1275
|
+
* Check if a given name corresponds to a ref name
|
|
1278
1276
|
* @param name The name to check
|
|
1279
1277
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
1280
1278
|
*/
|
|
@@ -1285,7 +1283,7 @@ function isRefName(name) {
|
|
|
1285
1283
|
//#endregion
|
|
1286
1284
|
//#region src/ref/is-from-ref.ts
|
|
1287
1285
|
/**
|
|
1288
|
-
*
|
|
1286
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
1289
1287
|
* @param name The variable name
|
|
1290
1288
|
* @param initialScope The initial scope
|
|
1291
1289
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -1304,4 +1302,4 @@ function isInitializedFromRef(name, initialScope) {
|
|
|
1304
1302
|
}
|
|
1305
1303
|
|
|
1306
1304
|
//#endregion
|
|
1307
|
-
export { ComponentDetectionHint, ComponentFlag,
|
|
1305
|
+
export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, findEnclosingComponentOrHook, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isInsideComponentOrHook, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveJsxAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "2.7.5-next.
|
|
3
|
+
"version": "2.7.5-next.7",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -33,12 +33,11 @@
|
|
|
33
33
|
"@typescript-eslint/scope-manager": "^8.54.0",
|
|
34
34
|
"@typescript-eslint/types": "^8.54.0",
|
|
35
35
|
"@typescript-eslint/utils": "^8.54.0",
|
|
36
|
-
"birecord": "^0.1.1",
|
|
37
36
|
"ts-pattern": "^5.9.0",
|
|
38
|
-
"@eslint-react/ast": "2.7.5-next.
|
|
39
|
-
"@eslint-react/eff": "2.7.5-next.
|
|
40
|
-
"@eslint-react/shared": "2.7.5-next.
|
|
41
|
-
"@eslint-react/var": "2.7.5-next.
|
|
37
|
+
"@eslint-react/ast": "2.7.5-next.7",
|
|
38
|
+
"@eslint-react/eff": "2.7.5-next.7",
|
|
39
|
+
"@eslint-react/shared": "2.7.5-next.7",
|
|
40
|
+
"@eslint-react/var": "2.7.5-next.7"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"tsdown": "^0.20.1",
|