@eslint-react/core 2.7.5-beta.5 → 2.7.5-beta.9
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 +59 -62
- package/dist/index.js +81 -122
- 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,20 +246,13 @@ 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
|
|
252
253
|
//#region src/component/component-collector.d.ts
|
|
253
|
-
type FunctionEntry$1 = {
|
|
254
|
-
key: string;
|
|
255
|
-
node: AST.TSESTreeFunction;
|
|
256
|
-
hookCalls: TSESTree.CallExpression[];
|
|
257
|
-
isComponent: boolean;
|
|
254
|
+
type FunctionEntry$1 = FunctionComponentSemanticNode & {
|
|
258
255
|
isComponentDefinition: boolean;
|
|
259
|
-
isExportDefault: boolean;
|
|
260
|
-
isExportDefaultDeclaration: boolean;
|
|
261
|
-
rets: TSESTree.ReturnStatement["argument"][];
|
|
262
256
|
};
|
|
263
257
|
declare namespace useComponentCollector {
|
|
264
258
|
type Options = {
|
|
@@ -276,7 +270,7 @@ declare namespace useComponentCollector {
|
|
|
276
270
|
};
|
|
277
271
|
}
|
|
278
272
|
/**
|
|
279
|
-
* Get a ctx and visitor for the rule to collect function components
|
|
273
|
+
* Get a ctx and visitor object for the rule to collect function components
|
|
280
274
|
* @param context The ESLint rule context
|
|
281
275
|
* @param options The options to use
|
|
282
276
|
* @returns The ctx and visitor of the collector
|
|
@@ -293,7 +287,7 @@ declare namespace useComponentCollectorLegacy {
|
|
|
293
287
|
};
|
|
294
288
|
}
|
|
295
289
|
/**
|
|
296
|
-
* Get a ctx and visitor object for the rule to collect class
|
|
290
|
+
* Get a ctx and visitor object for the rule to collect class componentss
|
|
297
291
|
* @param context The ESLint rule context
|
|
298
292
|
* @returns The ctx and visitor of the collector
|
|
299
293
|
*/
|
|
@@ -313,7 +307,7 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
313
307
|
//#endregion
|
|
314
308
|
//#region src/component/component-definition.d.ts
|
|
315
309
|
/**
|
|
316
|
-
*
|
|
310
|
+
* Determine if a function node represents a valid React component definition
|
|
317
311
|
*
|
|
318
312
|
* @param context The rule context
|
|
319
313
|
* @param node The function node to analyze
|
|
@@ -323,9 +317,20 @@ declare function isAssignmentToThisState(node: TSESTree$1.AssignmentExpression):
|
|
|
323
317
|
declare function isComponentDefinition(context: RuleContext, node: AST.TSESTreeFunction, hint: bigint): boolean;
|
|
324
318
|
//#endregion
|
|
325
319
|
//#region src/component/component-id.d.ts
|
|
320
|
+
/**
|
|
321
|
+
* Get function component identifier from `const Component = memo(() => {});`
|
|
322
|
+
* @param context The rule context
|
|
323
|
+
* @param node The function node to analyze
|
|
324
|
+
* @returns The function identifier or `unit` if not found
|
|
325
|
+
*/
|
|
326
326
|
declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): AST.FunctionID | unit;
|
|
327
327
|
//#endregion
|
|
328
328
|
//#region src/component/component-init-path.d.ts
|
|
329
|
+
/**
|
|
330
|
+
* Get component flag from init path
|
|
331
|
+
* @param initPath The init path of the function component
|
|
332
|
+
* @returns The component flag
|
|
333
|
+
*/
|
|
329
334
|
declare function getComponentFlagFromInitPath(initPath: FunctionComponentSemanticNode["initPath"]): bigint;
|
|
330
335
|
//#endregion
|
|
331
336
|
//#region src/component/component-is.d.ts
|
|
@@ -338,24 +343,27 @@ declare function isClassComponent(node: TSESTree.Node): node is AST.TSESTreeClas
|
|
|
338
343
|
/**
|
|
339
344
|
* Check if a node is a React PureComponent
|
|
340
345
|
* @param node The AST node to check
|
|
341
|
-
* @returns `true` if the node is a
|
|
346
|
+
* @returns `true` if the node is a PureComponent, `false` otherwise
|
|
342
347
|
*/
|
|
343
348
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
344
349
|
//#endregion
|
|
345
350
|
//#region src/component/component-kind.d.ts
|
|
351
|
+
/**
|
|
352
|
+
* Represents the kind of a React component
|
|
353
|
+
*/
|
|
346
354
|
type ComponentKind = "classComponent" | "functionComponent";
|
|
347
355
|
//#endregion
|
|
348
356
|
//#region src/component/component-method-callback.d.ts
|
|
349
357
|
/**
|
|
350
|
-
*
|
|
351
|
-
* @param node The
|
|
352
|
-
* @returns
|
|
358
|
+
* Check if the given node is a componentDidMount callback
|
|
359
|
+
* @param node The node to check
|
|
360
|
+
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
353
361
|
*/
|
|
354
362
|
declare function isComponentDidMountCallback(node: TSESTree.Node): boolean;
|
|
355
363
|
/**
|
|
356
|
-
*
|
|
357
|
-
* @param node The
|
|
358
|
-
* @returns
|
|
364
|
+
* Check if the given node is a componentWillUnmount callback
|
|
365
|
+
* @param node The node to check
|
|
366
|
+
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
359
367
|
*/
|
|
360
368
|
declare function isComponentWillUnmountCallback(node: TSESTree.Node): boolean;
|
|
361
369
|
//#endregion
|
|
@@ -397,22 +405,6 @@ declare function isComponentNameLoose(name: string): boolean;
|
|
|
397
405
|
*/
|
|
398
406
|
declare function hasNoneOrLooseComponentName(context: RuleContext, fn: AST.TSESTreeFunction): boolean;
|
|
399
407
|
//#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
408
|
//#region src/component/component-render-method.d.ts
|
|
417
409
|
/**
|
|
418
410
|
* Check whether given node is a render method of a class component
|
|
@@ -511,7 +503,7 @@ declare function isComponentWrapperCallbackLoose(context: RuleContext, node: TSE
|
|
|
511
503
|
//#endregion
|
|
512
504
|
//#region src/function/function-semantic-node.d.ts
|
|
513
505
|
/**
|
|
514
|
-
* Represents a React
|
|
506
|
+
* Represents a React Client Function
|
|
515
507
|
*/
|
|
516
508
|
interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
517
509
|
/**
|
|
@@ -519,12 +511,18 @@ interface ClientFunctionSemanticNode extends SemanticFunc {
|
|
|
519
511
|
*/
|
|
520
512
|
kind: "client-function";
|
|
521
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Represents a React Server Function
|
|
516
|
+
*/
|
|
522
517
|
interface ServerFunctionSemanticNode extends SemanticFunc {
|
|
523
518
|
/**
|
|
524
519
|
* The kind of function
|
|
525
520
|
*/
|
|
526
521
|
kind: "server-function";
|
|
527
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Represents a React Function
|
|
525
|
+
*/
|
|
528
526
|
type FunctionSemanticNode = ClientFunctionSemanticNode | ServerFunctionSemanticNode;
|
|
529
527
|
//#endregion
|
|
530
528
|
//#region src/hierarchy/find-enclosing-component-or-hook.d.ts
|
|
@@ -539,7 +537,7 @@ declare function findEnclosingComponentOrHook(node: TSESTree.Node | unit, test?:
|
|
|
539
537
|
//#endregion
|
|
540
538
|
//#region src/hierarchy/is-inside-component-or-hook.d.ts
|
|
541
539
|
/**
|
|
542
|
-
*
|
|
540
|
+
* Check if a given AST node is inside a React component or hook
|
|
543
541
|
* @param node The AST node to check
|
|
544
542
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
545
543
|
*/
|
|
@@ -547,12 +545,12 @@ declare function isInsideComponentOrHook(node: TSESTree.Node | unit): boolean;
|
|
|
547
545
|
//#endregion
|
|
548
546
|
//#region src/hook/hook-callback.d.ts
|
|
549
547
|
/**
|
|
550
|
-
*
|
|
548
|
+
* Determine if a node is the setup function passed to a useEffect-like hook
|
|
551
549
|
* @param node The AST node to check
|
|
552
550
|
*/
|
|
553
551
|
declare function isUseEffectSetupCallback(node: TSESTree.Node | unit): boolean;
|
|
554
552
|
/**
|
|
555
|
-
*
|
|
553
|
+
* Determine if a node is the cleanup function returned by a useEffect-like hook's setup function.
|
|
556
554
|
* @param node The AST node to check
|
|
557
555
|
*/
|
|
558
556
|
declare function isUseEffectCleanupCallback(node: TSESTree.Node | unit): boolean;
|
|
@@ -569,7 +567,6 @@ interface HookSemanticNode extends SemanticNode {
|
|
|
569
567
|
type FunctionEntry = {
|
|
570
568
|
key: string;
|
|
571
569
|
node: AST.TSESTreeFunction;
|
|
572
|
-
isHook: boolean;
|
|
573
570
|
};
|
|
574
571
|
declare namespace useHookCollector {
|
|
575
572
|
type ReturnType = {
|
|
@@ -582,7 +579,7 @@ declare namespace useHookCollector {
|
|
|
582
579
|
};
|
|
583
580
|
}
|
|
584
581
|
/**
|
|
585
|
-
* Get a ctx and visitor for the rule to collect hooks
|
|
582
|
+
* Get a ctx and visitor object for the rule to collect hooks
|
|
586
583
|
* @param context The ESLint rule context
|
|
587
584
|
* @returns The ctx and visitor of the collector
|
|
588
585
|
*/
|
|
@@ -593,7 +590,7 @@ declare function isHookId(id: TSESTree.Node): id is TSESTree.Identifier | TSESTr
|
|
|
593
590
|
//#endregion
|
|
594
591
|
//#region src/hook/hook-is.d.ts
|
|
595
592
|
/**
|
|
596
|
-
*
|
|
593
|
+
* Determine if a function node is a React Hook based on its name.
|
|
597
594
|
* @param node The function node to check
|
|
598
595
|
* @returns True if the function is a React Hook, false otherwise
|
|
599
596
|
*/
|
|
@@ -605,21 +602,21 @@ declare function isHook(node: AST.TSESTreeFunction | unit): boolean;
|
|
|
605
602
|
*/
|
|
606
603
|
declare function isHookCall(node: TSESTree.Node | unit): node is TSESTree.CallExpression;
|
|
607
604
|
/**
|
|
608
|
-
*
|
|
605
|
+
* Check if a node is a call to a specific React hook.
|
|
609
606
|
* Returns a function that accepts a hook name to check against.
|
|
610
607
|
* @param node The AST node to check
|
|
611
608
|
* @returns A function that takes a hook name and returns boolean
|
|
612
609
|
*/
|
|
613
610
|
declare function isHookCallWithName(node: TSESTree.Node | unit): (name: string) => boolean;
|
|
614
611
|
/**
|
|
615
|
-
*
|
|
612
|
+
* Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
|
|
616
613
|
* @param node The AST node to check
|
|
617
614
|
* @param additionalEffectHooks Regex pattern matching custom hooks that should be treated as effect hooks
|
|
618
615
|
* @returns True if the node is a useEffect-like call
|
|
619
616
|
*/
|
|
620
617
|
declare function isUseEffectLikeCall(node: TSESTree.Node | unit, additionalEffectHooks?: RegExpLike): node is TSESTree.CallExpression;
|
|
621
618
|
/**
|
|
622
|
-
*
|
|
619
|
+
* Detect useState calls and variations (useCustomState, etc.) using a regex pattern
|
|
623
620
|
* @param node The AST node to check
|
|
624
621
|
* @param additionalStateHooks Regex pattern matching custom hooks that should be treated as state hooks
|
|
625
622
|
* @returns True if the node is a useState-like call
|
|
@@ -703,7 +700,7 @@ type JsxAttributeValue = {
|
|
|
703
700
|
toStatic(): unknown;
|
|
704
701
|
};
|
|
705
702
|
/**
|
|
706
|
-
*
|
|
703
|
+
* Resolve the static value of a JSX attribute or spread attribute
|
|
707
704
|
*
|
|
708
705
|
* @param context - The ESLint rule context
|
|
709
706
|
* @param attribute - The JSX attribute node to resolve
|
|
@@ -793,13 +790,13 @@ declare const JsxDetectionHint: {
|
|
|
793
790
|
*/
|
|
794
791
|
declare const DEFAULT_JSX_DETECTION_HINT: bigint;
|
|
795
792
|
/**
|
|
796
|
-
*
|
|
793
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
797
794
|
* @param node The AST node to check
|
|
798
795
|
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
799
796
|
*/
|
|
800
797
|
declare function isJsxText(node: TSESTree$1.Node | null | unit): node is TSESTree$1.JSXText | TSESTree$1.Literal;
|
|
801
798
|
/**
|
|
802
|
-
*
|
|
799
|
+
* Determine if a node represents JSX-like content based on heuristics
|
|
803
800
|
* Supports configuration through hint flags to customize detection behavior
|
|
804
801
|
*
|
|
805
802
|
* @param code The source code with scope lookup capability
|
|
@@ -814,7 +811,7 @@ declare function isJsxLike(code: {
|
|
|
814
811
|
//#endregion
|
|
815
812
|
//#region src/jsx/jsx-element-is.d.ts
|
|
816
813
|
/**
|
|
817
|
-
*
|
|
814
|
+
* Determine if a JSX element is a host element
|
|
818
815
|
* Host elements in React start with lowercase letters (e.g., div, span)
|
|
819
816
|
*
|
|
820
817
|
* @param context ESLint rule context
|
|
@@ -823,7 +820,7 @@ declare function isJsxLike(code: {
|
|
|
823
820
|
*/
|
|
824
821
|
declare function isJsxHostElement(context: RuleContext, node: TSESTree.Node): boolean;
|
|
825
822
|
/**
|
|
826
|
-
*
|
|
823
|
+
* Determine if a JSX element is a React Fragment
|
|
827
824
|
* Fragments can be imported from React and used like <Fragment> or <React.Fragment>
|
|
828
825
|
*
|
|
829
826
|
* @param context ESLint rule context
|
|
@@ -868,7 +865,7 @@ declare function stringifyJsx(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXNam
|
|
|
868
865
|
//#endregion
|
|
869
866
|
//#region src/ref/is-from-ref.d.ts
|
|
870
867
|
/**
|
|
871
|
-
*
|
|
868
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
872
869
|
* @param name The variable name
|
|
873
870
|
* @param initialScope The initial scope
|
|
874
871
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -877,10 +874,10 @@ declare function isInitializedFromRef(name: string, initialScope: Scope): boolea
|
|
|
877
874
|
//#endregion
|
|
878
875
|
//#region src/ref/ref-name.d.ts
|
|
879
876
|
/**
|
|
880
|
-
*
|
|
877
|
+
* Check if a given name corresponds to a ref name
|
|
881
878
|
* @param name The name to check
|
|
882
879
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
883
880
|
*/
|
|
884
881
|
declare function isRefName(name: string): boolean;
|
|
885
882
|
//#endregion
|
|
886
|
-
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint,
|
|
883
|
+
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
|
*/
|
|
@@ -270,28 +269,20 @@ function useHookCollector(context) {
|
|
|
270
269
|
const onFunctionEnter = (node) => {
|
|
271
270
|
const id = AST.getFunctionId(node);
|
|
272
271
|
const key = idGen$2.next();
|
|
273
|
-
if (id != null && isHookId(id)) {
|
|
274
|
-
functionEntries.push({
|
|
275
|
-
key,
|
|
276
|
-
node,
|
|
277
|
-
isHook: true
|
|
278
|
-
});
|
|
279
|
-
hooks.set(key, {
|
|
280
|
-
id,
|
|
281
|
-
key,
|
|
282
|
-
kind: "function",
|
|
283
|
-
name: AST.toStringFormat(id, getText),
|
|
284
|
-
node,
|
|
285
|
-
flag: 0n,
|
|
286
|
-
hint: 0n,
|
|
287
|
-
hookCalls: []
|
|
288
|
-
});
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
272
|
functionEntries.push({
|
|
292
273
|
key,
|
|
274
|
+
node
|
|
275
|
+
});
|
|
276
|
+
if (id == null || !isHookId(id)) return;
|
|
277
|
+
hooks.set(key, {
|
|
278
|
+
id,
|
|
279
|
+
key,
|
|
280
|
+
kind: "function",
|
|
281
|
+
name: AST.toStringFormat(id, getText),
|
|
293
282
|
node,
|
|
294
|
-
|
|
283
|
+
flag: 0n,
|
|
284
|
+
hint: 0n,
|
|
285
|
+
hookCalls: []
|
|
295
286
|
});
|
|
296
287
|
};
|
|
297
288
|
const onFunctionExit = () => {
|
|
@@ -310,11 +301,9 @@ function useHookCollector(context) {
|
|
|
310
301
|
":function:exit": onFunctionExit,
|
|
311
302
|
CallExpression(node) {
|
|
312
303
|
if (!isHookCall(node)) return;
|
|
313
|
-
const
|
|
314
|
-
if (
|
|
315
|
-
|
|
316
|
-
if (hook == null) return;
|
|
317
|
-
hook.hookCalls.push(node);
|
|
304
|
+
const entry = getCurrentEntry();
|
|
305
|
+
if (entry == null) return;
|
|
306
|
+
hooks.get(entry.key)?.hookCalls.push(node);
|
|
318
307
|
}
|
|
319
308
|
}
|
|
320
309
|
};
|
|
@@ -388,7 +377,7 @@ function getJsxAttribute(context, node, initialScope) {
|
|
|
388
377
|
//#endregion
|
|
389
378
|
//#region src/jsx/jsx-attribute-value.ts
|
|
390
379
|
/**
|
|
391
|
-
*
|
|
380
|
+
* Resolve the static value of a JSX attribute or spread attribute
|
|
392
381
|
*
|
|
393
382
|
* @param context - The ESLint rule context
|
|
394
383
|
* @param attribute - The JSX attribute node to resolve
|
|
@@ -536,7 +525,7 @@ const JsxDetectionHint = {
|
|
|
536
525
|
*/
|
|
537
526
|
const DEFAULT_JSX_DETECTION_HINT = 0n | JsxDetectionHint.SkipUndefined | JsxDetectionHint.SkipBooleanLiteral;
|
|
538
527
|
/**
|
|
539
|
-
*
|
|
528
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
540
529
|
* @param node The AST node to check
|
|
541
530
|
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
542
531
|
*/
|
|
@@ -545,7 +534,7 @@ function isJsxText(node) {
|
|
|
545
534
|
return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
|
|
546
535
|
}
|
|
547
536
|
/**
|
|
548
|
-
*
|
|
537
|
+
* Determine if a node represents JSX-like content based on heuristics
|
|
549
538
|
* Supports configuration through hint flags to customize detection behavior
|
|
550
539
|
*
|
|
551
540
|
* @param code The source code with scope lookup capability
|
|
@@ -627,7 +616,7 @@ function getJsxElementType(context, node) {
|
|
|
627
616
|
//#endregion
|
|
628
617
|
//#region src/jsx/jsx-element-is.ts
|
|
629
618
|
/**
|
|
630
|
-
*
|
|
619
|
+
* Determine if a JSX element is a host element
|
|
631
620
|
* Host elements in React start with lowercase letters (e.g., div, span)
|
|
632
621
|
*
|
|
633
622
|
* @param context ESLint rule context
|
|
@@ -638,7 +627,7 @@ function isJsxHostElement(context, node) {
|
|
|
638
627
|
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
|
|
639
628
|
}
|
|
640
629
|
/**
|
|
641
|
-
*
|
|
630
|
+
* Determine if a JSX element is a React Fragment
|
|
642
631
|
* Fragments can be imported from React and used like <Fragment> or <React.Fragment>
|
|
643
632
|
*
|
|
644
633
|
* @param context ESLint rule context
|
|
@@ -709,7 +698,7 @@ function isClassComponent(node) {
|
|
|
709
698
|
/**
|
|
710
699
|
* Check if a node is a React PureComponent
|
|
711
700
|
* @param node The AST node to check
|
|
712
|
-
* @returns `true` if the node is a
|
|
701
|
+
* @returns `true` if the node is a PureComponent, `false` otherwise
|
|
713
702
|
*/
|
|
714
703
|
function isPureComponent(node) {
|
|
715
704
|
if ("superClass" in node && node.superClass != null) {
|
|
@@ -743,7 +732,7 @@ function isRenderMethodLike(node) {
|
|
|
743
732
|
//#endregion
|
|
744
733
|
//#region src/component/component-definition.ts
|
|
745
734
|
/**
|
|
746
|
-
*
|
|
735
|
+
* Check if the given node is a function within a render method of a class component.
|
|
747
736
|
*
|
|
748
737
|
* @param node The AST node to check
|
|
749
738
|
* @returns `true` if the node is a render function inside a class component
|
|
@@ -761,7 +750,7 @@ function isRenderMethodCallback(node) {
|
|
|
761
750
|
return greatGrandparent != null && isRenderMethodLike(parent) && isClassComponent(greatGrandparent);
|
|
762
751
|
}
|
|
763
752
|
/**
|
|
764
|
-
*
|
|
753
|
+
* Check if a function node should be excluded based on provided detection hints
|
|
765
754
|
*
|
|
766
755
|
* @param node The function node to check
|
|
767
756
|
* @param hint Component detection hints as bit flags
|
|
@@ -779,7 +768,7 @@ function shouldExcludeBasedOnHint(node, hint) {
|
|
|
779
768
|
return false;
|
|
780
769
|
}
|
|
781
770
|
/**
|
|
782
|
-
*
|
|
771
|
+
* Determine if the node is an argument within `createElement`'s children list (3rd argument onwards)
|
|
783
772
|
*
|
|
784
773
|
* @param context The rule context
|
|
785
774
|
* @param node The AST node to check
|
|
@@ -792,7 +781,7 @@ function isChildrenOfCreateElement(context, node) {
|
|
|
792
781
|
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
793
782
|
}
|
|
794
783
|
/**
|
|
795
|
-
*
|
|
784
|
+
* Determine if a function node represents a valid React component definition
|
|
796
785
|
*
|
|
797
786
|
* @param context The rule context
|
|
798
787
|
* @param node The function node to analyze
|
|
@@ -863,6 +852,12 @@ function isComponentWrapperCallbackLoose(context, node) {
|
|
|
863
852
|
|
|
864
853
|
//#endregion
|
|
865
854
|
//#region src/component/component-id.ts
|
|
855
|
+
/**
|
|
856
|
+
* Get function component identifier from `const Component = memo(() => {});`
|
|
857
|
+
* @param context The rule context
|
|
858
|
+
* @param node The function node to analyze
|
|
859
|
+
* @returns The function identifier or `unit` if not found
|
|
860
|
+
*/
|
|
866
861
|
function getFunctionComponentId(context, node) {
|
|
867
862
|
const functionId = AST.getFunctionId(node);
|
|
868
863
|
if (functionId != null) return functionId;
|
|
@@ -874,17 +869,24 @@ function getFunctionComponentId(context, node) {
|
|
|
874
869
|
|
|
875
870
|
//#endregion
|
|
876
871
|
//#region src/component/component-flag.ts
|
|
872
|
+
/**
|
|
873
|
+
* Component flag constants
|
|
874
|
+
*/
|
|
877
875
|
const ComponentFlag = {
|
|
878
876
|
None: 0n,
|
|
879
877
|
PureComponent: 1n << 0n,
|
|
880
878
|
CreateElement: 1n << 1n,
|
|
881
879
|
Memo: 1n << 2n,
|
|
882
|
-
ForwardRef: 1n << 3n
|
|
883
|
-
Async: 1n << 4n
|
|
880
|
+
ForwardRef: 1n << 3n
|
|
884
881
|
};
|
|
885
882
|
|
|
886
883
|
//#endregion
|
|
887
884
|
//#region src/component/component-init-path.ts
|
|
885
|
+
/**
|
|
886
|
+
* Get component flag from init path
|
|
887
|
+
* @param initPath The init path of the function component
|
|
888
|
+
* @returns The component flag
|
|
889
|
+
*/
|
|
888
890
|
function getComponentFlagFromInitPath(initPath) {
|
|
889
891
|
let flag = ComponentFlag.None;
|
|
890
892
|
if (initPath != null && AST.hasCallInFunctionInitPath("memo", initPath)) flag |= ComponentFlag.Memo;
|
|
@@ -925,7 +927,7 @@ function hasNoneOrLooseComponentName(context, fn) {
|
|
|
925
927
|
//#region src/component/component-collector.ts
|
|
926
928
|
const idGen$1 = new IdGenerator("function_component_");
|
|
927
929
|
/**
|
|
928
|
-
* Get a ctx and visitor for the rule to collect function components
|
|
930
|
+
* Get a ctx and visitor object for the rule to collect function components
|
|
929
931
|
* @param context The ESLint rule context
|
|
930
932
|
* @param options The options to use
|
|
931
933
|
* @returns The ctx and visitor of the collector
|
|
@@ -941,12 +943,21 @@ function useComponentCollector(context, options = {}) {
|
|
|
941
943
|
const exp = AST.findParentNode(node, (n) => n.type === AST_NODE_TYPES.ExportDefaultDeclaration);
|
|
942
944
|
const isExportDefault = exp != null;
|
|
943
945
|
const isExportDefaultDeclaration = exp != null && AST.getUnderlyingExpression(exp.declaration) === node;
|
|
946
|
+
const id = getFunctionComponentId(context, node);
|
|
947
|
+
const name = id == null ? unit : AST.toStringFormat(id, getText);
|
|
948
|
+
const initPath = AST.getFunctionInitPath(node);
|
|
944
949
|
functionEntries.push({
|
|
950
|
+
id: getFunctionComponentId(context, node),
|
|
945
951
|
key,
|
|
952
|
+
kind: "function",
|
|
953
|
+
name,
|
|
946
954
|
node,
|
|
955
|
+
displayName: unit,
|
|
956
|
+
flag: getComponentFlagFromInitPath(initPath),
|
|
957
|
+
hint,
|
|
947
958
|
hookCalls: [],
|
|
948
|
-
|
|
949
|
-
isComponentDefinition: isComponentDefinition(context, node, hint),
|
|
959
|
+
initPath,
|
|
960
|
+
isComponentDefinition: hasNoneOrLooseComponentName(context, node) && isComponentDefinition(context, node, hint),
|
|
950
961
|
isExportDefault,
|
|
951
962
|
isExportDefaultDeclaration,
|
|
952
963
|
rets: []
|
|
@@ -971,29 +982,12 @@ function useComponentCollector(context, options = {}) {
|
|
|
971
982
|
"ArrowFunctionExpression[body.type!='BlockStatement']"() {
|
|
972
983
|
const entry = getCurrentEntry();
|
|
973
984
|
if (entry == null) return;
|
|
974
|
-
if (!entry.isComponentDefinition) return;
|
|
975
985
|
const { body } = entry.node;
|
|
976
986
|
if (body.type === AST_NODE_TYPES.BlockStatement) return;
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
const name = id == null ? unit : AST.toStringFormat(id, getText);
|
|
982
|
-
components.set(key, {
|
|
983
|
-
id,
|
|
984
|
-
key,
|
|
985
|
-
kind: "function",
|
|
986
|
-
name,
|
|
987
|
-
node: entry.node,
|
|
988
|
-
displayName: unit,
|
|
989
|
-
flag: getComponentFlagFromInitPath(initPath),
|
|
990
|
-
hint,
|
|
991
|
-
hookCalls: entry.hookCalls,
|
|
992
|
-
initPath,
|
|
993
|
-
isExportDefault: entry.isExportDefault,
|
|
994
|
-
isExportDefaultDeclaration: entry.isExportDefaultDeclaration,
|
|
995
|
-
rets: [body]
|
|
996
|
-
});
|
|
987
|
+
entry.rets.push(body);
|
|
988
|
+
if (!entry.isComponentDefinition) return;
|
|
989
|
+
if (!components.has(entry.key) && !isJsxLike(context.sourceCode, body, hint)) return;
|
|
990
|
+
components.set(entry.key, entry);
|
|
997
991
|
},
|
|
998
992
|
...collectDisplayName ? { [AST.SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
|
|
999
993
|
const { left, right } = node;
|
|
@@ -1012,30 +1006,11 @@ function useComponentCollector(context, options = {}) {
|
|
|
1012
1006
|
ReturnStatement(node) {
|
|
1013
1007
|
const entry = getCurrentEntry();
|
|
1014
1008
|
if (entry == null) return;
|
|
1009
|
+
entry.rets.push(node.argument);
|
|
1015
1010
|
if (!entry.isComponentDefinition) return;
|
|
1016
1011
|
const { argument } = node;
|
|
1017
|
-
entry.
|
|
1018
|
-
|
|
1019
|
-
entry.isComponent = true;
|
|
1020
|
-
const initPath = AST.getFunctionInitPath(entry.node);
|
|
1021
|
-
const id = getFunctionComponentId(context, entry.node);
|
|
1022
|
-
const key = entry.key;
|
|
1023
|
-
const name = id == null ? unit : AST.toStringFormat(id, getText);
|
|
1024
|
-
components.set(key, {
|
|
1025
|
-
id,
|
|
1026
|
-
key,
|
|
1027
|
-
kind: "function",
|
|
1028
|
-
name,
|
|
1029
|
-
node: entry.node,
|
|
1030
|
-
displayName: unit,
|
|
1031
|
-
flag: getComponentFlagFromInitPath(initPath),
|
|
1032
|
-
hint,
|
|
1033
|
-
hookCalls: entry.hookCalls,
|
|
1034
|
-
initPath,
|
|
1035
|
-
isExportDefault: entry.isExportDefault,
|
|
1036
|
-
isExportDefaultDeclaration: entry.isExportDefaultDeclaration,
|
|
1037
|
-
rets: entry.rets
|
|
1038
|
-
});
|
|
1012
|
+
if (!components.has(entry.key) && !isJsxLike(context.sourceCode, argument, hint)) return;
|
|
1013
|
+
components.set(entry.key, entry);
|
|
1039
1014
|
}
|
|
1040
1015
|
}
|
|
1041
1016
|
};
|
|
@@ -1045,7 +1020,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1045
1020
|
//#region src/component/component-collector-legacy.ts
|
|
1046
1021
|
const idGen = new IdGenerator("class_component_");
|
|
1047
1022
|
/**
|
|
1048
|
-
* Get a ctx and visitor object for the rule to collect class
|
|
1023
|
+
* Get a ctx and visitor object for the rule to collect class componentss
|
|
1049
1024
|
* @param context The ESLint rule context
|
|
1050
1025
|
* @returns The ctx and visitor of the collector
|
|
1051
1026
|
*/
|
|
@@ -1108,9 +1083,7 @@ function isAssignmentToThisState(node) {
|
|
|
1108
1083
|
* @param isStatic Whether the method is static
|
|
1109
1084
|
*/
|
|
1110
1085
|
function createLifecycleChecker(methodName, isStatic = false) {
|
|
1111
|
-
return
|
|
1112
|
-
return AST.isMethodOrProperty(node) && node.static === isStatic && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === methodName;
|
|
1113
|
-
};
|
|
1086
|
+
return (node) => AST.isMethodOrProperty(node) && node.static === isStatic && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === methodName;
|
|
1114
1087
|
}
|
|
1115
1088
|
const isRender = createLifecycleChecker("render");
|
|
1116
1089
|
const isComponentDidCatch = createLifecycleChecker("componentDidCatch");
|
|
@@ -1134,36 +1107,22 @@ const isGetDerivedStateFromError = createLifecycleChecker("getDerivedStateFromEr
|
|
|
1134
1107
|
//#endregion
|
|
1135
1108
|
//#region src/component/component-method-callback.ts
|
|
1136
1109
|
/**
|
|
1137
|
-
*
|
|
1138
|
-
* @param node The
|
|
1139
|
-
* @returns
|
|
1110
|
+
* Check if the given node is a componentDidMount callback
|
|
1111
|
+
* @param node The node to check
|
|
1112
|
+
* @returns True if the node is a componentDidMount callback, false otherwise
|
|
1140
1113
|
*/
|
|
1141
1114
|
function isComponentDidMountCallback(node) {
|
|
1142
1115
|
return AST.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
1143
1116
|
}
|
|
1144
1117
|
/**
|
|
1145
|
-
*
|
|
1146
|
-
* @param node The
|
|
1147
|
-
* @returns
|
|
1118
|
+
* Check if the given node is a componentWillUnmount callback
|
|
1119
|
+
* @param node The node to check
|
|
1120
|
+
* @returns True if the node is a componentWillUnmount callback, false otherwise
|
|
1148
1121
|
*/
|
|
1149
1122
|
function isComponentWillUnmountCallback(node) {
|
|
1150
1123
|
return AST.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
1151
1124
|
}
|
|
1152
1125
|
|
|
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
1126
|
//#endregion
|
|
1168
1127
|
//#region src/component/component-render-prop.ts
|
|
1169
1128
|
/**
|
|
@@ -1263,7 +1222,7 @@ function findEnclosingComponentOrHook(node, test = (n, name) => {
|
|
|
1263
1222
|
//#endregion
|
|
1264
1223
|
//#region src/hierarchy/is-inside-component-or-hook.ts
|
|
1265
1224
|
/**
|
|
1266
|
-
*
|
|
1225
|
+
* Check if a given AST node is inside a React component or hook
|
|
1267
1226
|
* @param node The AST node to check
|
|
1268
1227
|
* @returns True if the node is inside a component or hook, false otherwise
|
|
1269
1228
|
*/
|
|
@@ -1274,7 +1233,7 @@ function isInsideComponentOrHook(node) {
|
|
|
1274
1233
|
//#endregion
|
|
1275
1234
|
//#region src/ref/ref-name.ts
|
|
1276
1235
|
/**
|
|
1277
|
-
*
|
|
1236
|
+
* Check if a given name corresponds to a ref name
|
|
1278
1237
|
* @param name The name to check
|
|
1279
1238
|
* @returns True if the name is "ref" or ends with "Ref"
|
|
1280
1239
|
*/
|
|
@@ -1285,7 +1244,7 @@ function isRefName(name) {
|
|
|
1285
1244
|
//#endregion
|
|
1286
1245
|
//#region src/ref/is-from-ref.ts
|
|
1287
1246
|
/**
|
|
1288
|
-
*
|
|
1247
|
+
* Check if the variable with the given name is initialized or derived from a ref
|
|
1289
1248
|
* @param name The variable name
|
|
1290
1249
|
* @param initialScope The initial scope
|
|
1291
1250
|
* @returns True if the variable is derived from a ref, false otherwise
|
|
@@ -1304,4 +1263,4 @@ function isInitializedFromRef(name, initialScope) {
|
|
|
1304
1263
|
}
|
|
1305
1264
|
|
|
1306
1265
|
//#endregion
|
|
1307
|
-
export { ComponentDetectionHint, ComponentFlag,
|
|
1266
|
+
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-beta.
|
|
3
|
+
"version": "2.7.5-beta.9",
|
|
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/
|
|
39
|
-
"@eslint-react/
|
|
40
|
-
"@eslint-react/var": "2.7.5-beta.
|
|
41
|
-
"@eslint-react/
|
|
37
|
+
"@eslint-react/eff": "2.7.5-beta.9",
|
|
38
|
+
"@eslint-react/ast": "2.7.5-beta.9",
|
|
39
|
+
"@eslint-react/var": "2.7.5-beta.9",
|
|
40
|
+
"@eslint-react/shared": "2.7.5-beta.9"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"tsdown": "^0.20.1",
|