@eslint-react/core 2.7.5-next.6 → 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 +57 -51
- package/dist/index.js +47 -48
- 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,6 +151,9 @@ 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 */
|
|
@@ -162,7 +164,7 @@ declare const ComponentFlag: {
|
|
|
162
164
|
//#endregion
|
|
163
165
|
//#region src/component/component-semantic-node.d.ts
|
|
164
166
|
/**
|
|
165
|
-
* Represents a React
|
|
167
|
+
* Represents a React Function Component
|
|
166
168
|
*/
|
|
167
169
|
interface FunctionComponentSemanticNode extends SemanticNode {
|
|
168
170
|
/**
|
|
@@ -211,7 +213,7 @@ interface FunctionComponentSemanticNode extends SemanticNode {
|
|
|
211
213
|
displayName: unit | TSESTree.Expression;
|
|
212
214
|
}
|
|
213
215
|
/**
|
|
214
|
-
* Represents a React
|
|
216
|
+
* Represents a React Class Component
|
|
215
217
|
*/
|
|
216
218
|
interface ClassComponentSemanticNode extends SemanticNode {
|
|
217
219
|
/**
|
|
@@ -244,7 +246,7 @@ interface ClassComponentSemanticNode extends SemanticNode {
|
|
|
244
246
|
displayName: unit | TSESTree.Expression;
|
|
245
247
|
}
|
|
246
248
|
/**
|
|
247
|
-
*
|
|
249
|
+
* Represents a React Component
|
|
248
250
|
*/
|
|
249
251
|
type ComponentSemanticNode = ClassComponentSemanticNode | FunctionComponentSemanticNode;
|
|
250
252
|
//#endregion
|
|
@@ -275,7 +277,7 @@ declare namespace useComponentCollector {
|
|
|
275
277
|
};
|
|
276
278
|
}
|
|
277
279
|
/**
|
|
278
|
-
* 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
|
|
279
281
|
* @param context The ESLint rule context
|
|
280
282
|
* @param options The options to use
|
|
281
283
|
* @returns The ctx and visitor of the collector
|
|
@@ -292,7 +294,7 @@ declare namespace useComponentCollectorLegacy {
|
|
|
292
294
|
};
|
|
293
295
|
}
|
|
294
296
|
/**
|
|
295
|
-
* 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
|
|
296
298
|
* @param context The ESLint rule context
|
|
297
299
|
* @returns The ctx and visitor of the collector
|
|
298
300
|
*/
|
|
@@ -312,7 +314,7 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
312
314
|
//#endregion
|
|
313
315
|
//#region src/component/component-definition.d.ts
|
|
314
316
|
/**
|
|
315
|
-
*
|
|
317
|
+
* Determine if a function node represents a valid React component definition
|
|
316
318
|
*
|
|
317
319
|
* @param context The rule context
|
|
318
320
|
* @param node The function node to analyze
|
|
@@ -322,9 +324,20 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
322
324
|
declare function isComponentDefinition(context: RuleContext, node: AST.TSESTreeFunction, hint: bigint): boolean;
|
|
323
325
|
//#endregion
|
|
324
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
|
+
*/
|
|
325
333
|
declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): AST.FunctionID | unit;
|
|
326
334
|
//#endregion
|
|
327
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
|
+
*/
|
|
328
341
|
declare function getComponentFlagFromInitPath(initPath: FunctionComponentSemanticNode["initPath"]): bigint;
|
|
329
342
|
//#endregion
|
|
330
343
|
//#region src/component/component-is.d.ts
|
|
@@ -337,24 +350,27 @@ declare function isClassComponent(node: TSESTree.Node): node is AST.TSESTreeClas
|
|
|
337
350
|
/**
|
|
338
351
|
* Check if a node is a React PureComponent
|
|
339
352
|
* @param node The AST node to check
|
|
340
|
-
* @returns `true` if the node is a
|
|
353
|
+
* @returns `true` if the node is a PureComponent, `false` otherwise
|
|
341
354
|
*/
|
|
342
355
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
343
356
|
//#endregion
|
|
344
357
|
//#region src/component/component-kind.d.ts
|
|
358
|
+
/**
|
|
359
|
+
* Represents the kind of a React component
|
|
360
|
+
*/
|
|
345
361
|
type ComponentKind = "classComponent" | "functionComponent";
|
|
346
362
|
//#endregion
|
|
347
363
|
//#region src/component/component-method-callback.d.ts
|
|
348
364
|
/**
|
|
349
|
-
*
|
|
350
|
-
* @param node The
|
|
351
|
-
* @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
|
|
352
368
|
*/
|
|
353
369
|
declare function isComponentDidMountCallback(node: TSESTree.Node): boolean;
|
|
354
370
|
/**
|
|
355
|
-
*
|
|
356
|
-
* @param node The
|
|
357
|
-
* @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
|
|
358
374
|
*/
|
|
359
375
|
declare function isComponentWillUnmountCallback(node: TSESTree.Node): boolean;
|
|
360
376
|
//#endregion
|
|
@@ -396,22 +412,6 @@ declare function isComponentNameLoose(name: string): boolean;
|
|
|
396
412
|
*/
|
|
397
413
|
declare function hasNoneOrLooseComponentName(context: RuleContext, fn: AST.TSESTreeFunction): boolean;
|
|
398
414
|
//#endregion
|
|
399
|
-
//#region src/component/component-phase.d.ts
|
|
400
|
-
type ComponentEffectPhaseKind = "cleanup" | "setup";
|
|
401
|
-
type ComponentLifecyclePhaseKind = "mount" | "unmount";
|
|
402
|
-
type ComponentPhaseKind = ComponentEffectPhaseKind | ComponentLifecyclePhaseKind;
|
|
403
|
-
declare const ComponentPhaseRelevance: birecord0.BiRecord<{
|
|
404
|
-
readonly mount: "unmount";
|
|
405
|
-
readonly setup: "cleanup";
|
|
406
|
-
}>;
|
|
407
|
-
//#endregion
|
|
408
|
-
//#region src/component/component-phase-helpers.d.ts
|
|
409
|
-
declare const isInversePhase: {
|
|
410
|
-
(a: ComponentPhaseKind): (b: ComponentPhaseKind) => boolean;
|
|
411
|
-
(a: ComponentPhaseKind, b: ComponentPhaseKind): boolean;
|
|
412
|
-
};
|
|
413
|
-
declare function getPhaseKindOfFunction(node: AST.TSESTreeFunction): ComponentPhaseKind | null;
|
|
414
|
-
//#endregion
|
|
415
415
|
//#region src/component/component-render-method.d.ts
|
|
416
416
|
/**
|
|
417
417
|
* Check whether given node is a render method of a class component
|
|
@@ -510,7 +510,7 @@ declare function isComponentWrapperCallbackLoose(context: RuleContext, node: TSE
|
|
|
510
510
|
//#endregion
|
|
511
511
|
//#region src/function/function-semantic-node.d.ts
|
|
512
512
|
/**
|
|
513
|
-
* Represents a React
|
|
513
|
+
* Represents a React Client Function
|
|
514
514
|
*/
|
|
515
515
|
interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
516
516
|
/**
|
|
@@ -518,12 +518,18 @@ interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
|
518
518
|
*/
|
|
519
519
|
kind: "client-function";
|
|
520
520
|
}
|
|
521
|
+
/**
|
|
522
|
+
* Represents a React Server Function
|
|
523
|
+
*/
|
|
521
524
|
interface ServerFunctionSemanticNode extends SemanticFunc {
|
|
522
525
|
/**
|
|
523
526
|
* The kind of function
|
|
524
527
|
*/
|
|
525
528
|
kind: "server-function";
|
|
526
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Represents a React Function
|
|
532
|
+
*/
|
|
527
533
|
type FunctionSemanticNode = ClientFunctionSemanticNode | ServerFunctionSemanticNode;
|
|
528
534
|
//#endregion
|
|
529
535
|
//#region src/hierarchy/find-enclosing-component-or-hook.d.ts
|
|
@@ -538,7 +544,7 @@ declare function findEnclosingComponentOrHook(node: TSESTree.Node | unit, test?:
|
|
|
538
544
|
//#endregion
|
|
539
545
|
//#region src/hierarchy/is-inside-component-or-hook.d.ts
|
|
540
546
|
/**
|
|
541
|
-
*
|
|
547
|
+
* Check if a given AST node is inside a React component or hook
|
|
542
548
|
* @param node The AST node to check
|
|
543
549
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
544
550
|
*/
|
|
@@ -546,12 +552,12 @@ declare function isInsideComponentOrHook(node: TSESTree.Node | unit): boolean;
|
|
|
546
552
|
//#endregion
|
|
547
553
|
//#region src/hook/hook-callback.d.ts
|
|
548
554
|
/**
|
|
549
|
-
*
|
|
555
|
+
* Determine if a node is the setup function passed to a useEffect-like hook
|
|
550
556
|
* @param node The AST node to check
|
|
551
557
|
*/
|
|
552
558
|
declare function isUseEffectSetupCallback(node: TSESTree.Node | unit): boolean;
|
|
553
559
|
/**
|
|
554
|
-
*
|
|
560
|
+
* Determine if a node is the cleanup function returned by a useEffect-like hook's setup function.
|
|
555
561
|
* @param node The AST node to check
|
|
556
562
|
*/
|
|
557
563
|
declare function isUseEffectCleanupCallback(node: TSESTree.Node | unit): boolean;
|
|
@@ -581,7 +587,7 @@ declare namespace useHookCollector {
|
|
|
581
587
|
};
|
|
582
588
|
}
|
|
583
589
|
/**
|
|
584
|
-
* Get a ctx and visitor for the rule to collect hooks
|
|
590
|
+
* Get a ctx and visitor object for the rule to collect hooks
|
|
585
591
|
* @param context The ESLint rule context
|
|
586
592
|
* @returns The ctx and visitor of the collector
|
|
587
593
|
*/
|
|
@@ -592,7 +598,7 @@ declare function isHookId(id: TSESTree.Node): id is TSESTree.Identifier | TSESTr
|
|
|
592
598
|
//#endregion
|
|
593
599
|
//#region src/hook/hook-is.d.ts
|
|
594
600
|
/**
|
|
595
|
-
*
|
|
601
|
+
* Determine if a function node is a React Hook based on its name.
|
|
596
602
|
* @param node The function node to check
|
|
597
603
|
* @returns True if the function is a React Hook, false otherwise
|
|
598
604
|
*/
|
|
@@ -604,21 +610,21 @@ declare function isHook(node: AST.TSESTreeFunction | unit): boolean;
|
|
|
604
610
|
*/
|
|
605
611
|
declare function isHookCall(node: TSESTree.Node | unit): node is TSESTree.CallExpression;
|
|
606
612
|
/**
|
|
607
|
-
*
|
|
613
|
+
* Check if a node is a call to a specific React hook.
|
|
608
614
|
* Returns a function that accepts a hook name to check against.
|
|
609
615
|
* @param node The AST node to check
|
|
610
616
|
* @returns A function that takes a hook name and returns boolean
|
|
611
617
|
*/
|
|
612
618
|
declare function isHookCallWithName(node: TSESTree.Node | unit): (name: string) => boolean;
|
|
613
619
|
/**
|
|
614
|
-
*
|
|
620
|
+
* Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
|
|
615
621
|
* @param node The AST node to check
|
|
616
622
|
* @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks
|
|
617
623
|
* @returns True if the node is a useEffect-like call
|
|
618
624
|
*/
|
|
619
625
|
declare function isUseEffectLikeCall(node: TSESTree.Node | unit, additionalEffectHooks?: RegExpLike): node is TSESTree.CallExpression;
|
|
620
626
|
/**
|
|
621
|
-
*
|
|
627
|
+
* Detect useState calls and variations (useCustomState, etc.) using a regex pattern
|
|
622
628
|
* @param node The AST node to check
|
|
623
629
|
* @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks
|
|
624
630
|
* @returns True if the node is a useState-like call
|
|
@@ -702,7 +708,7 @@ type JsxAttributeValue = {
|
|
|
702
708
|
toStatic(): unknown;
|
|
703
709
|
};
|
|
704
710
|
/**
|
|
705
|
-
*
|
|
711
|
+
* Resolve the static value of a JSX attribute or spread attribute
|
|
706
712
|
*
|
|
707
713
|
* @param context - The ESLint rule context
|
|
708
714
|
* @param attribute - The JSX attribute node to resolve
|
|
@@ -792,13 +798,13 @@ declare const JsxDetectionHint: {
|
|
|
792
798
|
*/
|
|
793
799
|
declare const DEFAULT_JSX_DETECTION_HINT: bigint;
|
|
794
800
|
/**
|
|
795
|
-
*
|
|
801
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
796
802
|
* @param node The AST node to check
|
|
797
803
|
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
798
804
|
*/
|
|
799
805
|
declare function isJsxText(node: TSESTree$1.Node | null | unit): node is TSESTree$1.JSXText | TSESTree$1.Literal;
|
|
800
806
|
/**
|
|
801
|
-
*
|
|
807
|
+
* Determine if a node represents JSX-like content based on heuristics
|
|
802
808
|
* Supports configuration through hint flags to customize detection behavior
|
|
803
809
|
*
|
|
804
810
|
* @param code The source code with scope lookup capability
|
|
@@ -813,7 +819,7 @@ declare function isJsxLike(code: {
|
|
|
813
819
|
//#endregion
|
|
814
820
|
//#region src/jsx/jsx-element-is.d.ts
|
|
815
821
|
/**
|
|
816
|
-
*
|
|
822
|
+
* Determine if a JSX element is a host element
|
|
817
823
|
* Host elements in React start with lowercase letters (e.g., div, span)
|
|
818
824
|
*
|
|
819
825
|
* @param context ESLint rule context
|
|
@@ -822,7 +828,7 @@ declare function isJsxLike(code: {
|
|
|
822
828
|
*/
|
|
823
829
|
declare function isJsxHostElement(context: RuleContext, node: TSESTree.Node): boolean;
|
|
824
830
|
/**
|
|
825
|
-
*
|
|
831
|
+
* Determine if a JSX element is a React Fragment
|
|
826
832
|
* Fragments can be imported from React and used like <Fragment> or <React.Fragment>
|
|
827
833
|
*
|
|
828
834
|
* @param context ESLint rule context
|
|
@@ -867,7 +873,7 @@ declare function stringifyJsx(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXNam
|
|
|
867
873
|
//#endregion
|
|
868
874
|
//#region src/ref/is-from-ref.d.ts
|
|
869
875
|
/**
|
|
870
|
-
*
|
|
876
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
871
877
|
* @param name The variable name
|
|
872
878
|
* @param initialScope The initial scope
|
|
873
879
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -876,10 +882,10 @@ declare function isInitializedFromRef(name: string, initialScope: Scope): boolea
|
|
|
876
882
|
//#endregion
|
|
877
883
|
//#region src/ref/ref-name.d.ts
|
|
878
884
|
/**
|
|
879
|
-
*
|
|
885
|
+
* Check if a given name corresponds to a ref name
|
|
880
886
|
* @param name The name to check
|
|
881
887
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
882
888
|
*/
|
|
883
889
|
declare function isRefName(name: string): boolean;
|
|
884
890
|
//#endregion
|
|
885
|
-
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,6 +879,9 @@ 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,
|
|
@@ -884,6 +892,11 @@ const ComponentFlag = {
|
|
|
884
892
|
|
|
885
893
|
//#endregion
|
|
886
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
|
+
*/
|
|
887
900
|
function getComponentFlagFromInitPath(initPath) {
|
|
888
901
|
let flag = ComponentFlag.None;
|
|
889
902
|
if (initPath != null && AST.hasCallInFunctionInitPath("memo", initPath)) flag |= ComponentFlag.Memo;
|
|
@@ -924,7 +937,7 @@ function hasNoneOrLooseComponentName(context, fn) {
|
|
|
924
937
|
//#region src/component/component-collector.ts
|
|
925
938
|
const idGen$1 = new IdGenerator("function_component_");
|
|
926
939
|
/**
|
|
927
|
-
* 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
|
|
928
941
|
* @param context The ESLint rule context
|
|
929
942
|
* @param options The options to use
|
|
930
943
|
* @returns The ctx and visitor of the collector
|
|
@@ -1044,7 +1057,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1044
1057
|
//#region src/component/component-collector-legacy.ts
|
|
1045
1058
|
const idGen = new IdGenerator("class_component_");
|
|
1046
1059
|
/**
|
|
1047
|
-
* 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
|
|
1048
1061
|
* @param context The ESLint rule context
|
|
1049
1062
|
* @returns The ctx and visitor of the collector
|
|
1050
1063
|
*/
|
|
@@ -1133,36 +1146,22 @@ const isGetDerivedStateFromError = createLifecycleChecker("getDerivedStateFromEr
|
|
|
1133
1146
|
//#endregion
|
|
1134
1147
|
//#region src/component/component-method-callback.ts
|
|
1135
1148
|
/**
|
|
1136
|
-
*
|
|
1137
|
-
* @param node The
|
|
1138
|
-
* @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
|
|
1139
1152
|
*/
|
|
1140
1153
|
function isComponentDidMountCallback(node) {
|
|
1141
1154
|
return AST.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
1142
1155
|
}
|
|
1143
1156
|
/**
|
|
1144
|
-
*
|
|
1145
|
-
* @param node The
|
|
1146
|
-
* @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
|
|
1147
1160
|
*/
|
|
1148
1161
|
function isComponentWillUnmountCallback(node) {
|
|
1149
1162
|
return AST.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
1150
1163
|
}
|
|
1151
1164
|
|
|
1152
|
-
//#endregion
|
|
1153
|
-
//#region src/component/component-phase.ts
|
|
1154
|
-
const ComponentPhaseRelevance = birecord({
|
|
1155
|
-
mount: "unmount",
|
|
1156
|
-
setup: "cleanup"
|
|
1157
|
-
});
|
|
1158
|
-
|
|
1159
|
-
//#endregion
|
|
1160
|
-
//#region src/component/component-phase-helpers.ts
|
|
1161
|
-
const isInversePhase = dual(2, (a, b) => ComponentPhaseRelevance.get(a) === b);
|
|
1162
|
-
function getPhaseKindOfFunction(node) {
|
|
1163
|
-
return match(node).when(isUseEffectSetupCallback, () => "setup").when(isUseEffectCleanupCallback, () => "cleanup").when(isComponentDidMountCallback, () => "mount").when(isComponentWillUnmountCallback, () => "unmount").otherwise(() => null);
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
1165
|
//#endregion
|
|
1167
1166
|
//#region src/component/component-render-prop.ts
|
|
1168
1167
|
/**
|
|
@@ -1262,7 +1261,7 @@ function findEnclosingComponentOrHook(node, test = (n, name) => {
|
|
|
1262
1261
|
//#endregion
|
|
1263
1262
|
//#region src/hierarchy/is-inside-component-or-hook.ts
|
|
1264
1263
|
/**
|
|
1265
|
-
*
|
|
1264
|
+
* Check if a given AST node is inside a React component or hook
|
|
1266
1265
|
* @param node The AST node to check
|
|
1267
1266
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
1268
1267
|
*/
|
|
@@ -1273,7 +1272,7 @@ function isInsideComponentOrHook(node) {
|
|
|
1273
1272
|
//#endregion
|
|
1274
1273
|
//#region src/ref/ref-name.ts
|
|
1275
1274
|
/**
|
|
1276
|
-
*
|
|
1275
|
+
* Check if a given name corresponds to a ref name
|
|
1277
1276
|
* @param name The name to check
|
|
1278
1277
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
1279
1278
|
*/
|
|
@@ -1284,7 +1283,7 @@ function isRefName(name) {
|
|
|
1284
1283
|
//#endregion
|
|
1285
1284
|
//#region src/ref/is-from-ref.ts
|
|
1286
1285
|
/**
|
|
1287
|
-
*
|
|
1286
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
1288
1287
|
* @param name The variable name
|
|
1289
1288
|
* @param initialScope The initial scope
|
|
1290
1289
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -1303,4 +1302,4 @@ function isInitializedFromRef(name, initialScope) {
|
|
|
1303
1302
|
}
|
|
1304
1303
|
|
|
1305
1304
|
//#endregion
|
|
1306
|
-
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/
|
|
41
|
-
"@eslint-react/
|
|
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",
|