@eslint-react/core 3.0.0-next.69 → 3.0.0-next.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +184 -117
  2. package/dist/index.js +299 -219
  3. package/package.json +5 -5
package/dist/index.d.ts CHANGED
@@ -620,25 +620,6 @@ declare const REACT_BUILTIN_HOOK_NAMES: readonly ["use", "useActionState", "useC
620
620
  */
621
621
  declare function isHookName(name: string): boolean;
622
622
  //#endregion
623
- //#region src/jsx/jsx-attribute.d.ts
624
- /**
625
- * Creates a helper function to find a specific JSX attribute by name
626
- * Handles direct attributes and spread attributes (variables or object literals)
627
- * @param context The ESLint rule context
628
- * @param node The JSX element node
629
- * @param initialScope (Optional) The initial scope to use for variable resolution
630
- */
631
- declare function getJsxAttribute(context: RuleContext, node: TSESTree.JSXElement, initialScope?: Scope): (name: string) => TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute | undefined;
632
- //#endregion
633
- //#region src/jsx/jsx-attribute-name.d.ts
634
- /**
635
- * Get the stringified name of a JSX attribute
636
- * @param context The ESLint rule context
637
- * @param node The JSX attribute node
638
- * @returns The name of the attribute
639
- */
640
- declare function getJsxAttributeName(context: RuleContext, node: TSESTree$1.JSXAttribute): string;
641
- //#endregion
642
623
  //#region src/jsx/jsx-attribute-value.d.ts
643
624
  /**
644
625
  * Represents possible JSX attribute value types that can be resolved
@@ -664,57 +645,14 @@ type JsxAttributeValue = {
664
645
  toStatic(): unknown;
665
646
  } | {
666
647
  kind: "spreadProps";
648
+ getProperty(name: string): unknown;
667
649
  node: TSESTree.JSXSpreadAttribute["argument"];
668
650
  toStatic(): unknown;
669
- getProperty(name: string): unknown;
670
651
  } | {
671
652
  kind: "spreadChild";
653
+ getChildren(at: number): unknown;
672
654
  node: TSESTree.JSXSpreadChild["expression"];
673
655
  toStatic(): unknown;
674
- getChildren(at: number): unknown;
675
- };
676
- /**
677
- * Resolve the static value of a JSX attribute or spread attribute
678
- *
679
- * @param context - The ESLint rule context
680
- * @param attribute - The JSX attribute node to resolve
681
- * @returns An object containing the value kind, the node (if applicable), and a `toStatic` helper
682
- */
683
- declare function resolveJsxAttributeValue(context: RuleContext, attribute: ast.TSESTreeJSXAttributeLike): {
684
- readonly kind: "boolean";
685
- readonly toStatic: () => true;
686
- readonly node?: never;
687
- readonly getChildren?: never;
688
- } | {
689
- readonly kind: "literal";
690
- readonly node: TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral;
691
- readonly toStatic: () => string | number | bigint | boolean | RegExp | null;
692
- readonly getChildren?: never;
693
- } | {
694
- readonly kind: "missing";
695
- readonly node: TSESTree.JSXEmptyExpression;
696
- readonly toStatic: () => "{}";
697
- readonly getChildren?: never;
698
- } | {
699
- readonly kind: "expression";
700
- readonly node: TSESTree.Expression;
701
- readonly toStatic: () => unknown;
702
- readonly getChildren?: never;
703
- } | {
704
- readonly kind: "element";
705
- readonly node: TSESTree.JSXElement;
706
- readonly toStatic: () => null;
707
- readonly getChildren?: never;
708
- } | {
709
- readonly kind: "spreadChild";
710
- readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
711
- readonly toStatic: () => unknown;
712
- readonly getChildren: (at: number) => null;
713
- } | {
714
- readonly kind: "spreadProps";
715
- readonly node: TSESTree.Expression;
716
- readonly toStatic: () => unknown;
717
- readonly getProperty: (name: string) => unknown;
718
656
  };
719
657
  //#endregion
720
658
  //#region src/jsx/jsx-config.d.ts
@@ -774,12 +712,6 @@ declare const JsxDetectionHint: {
774
712
  * Skips undefined and boolean literals (common in React)
775
713
  */
776
714
  declare const DEFAULT_JSX_DETECTION_HINT: bigint;
777
- /**
778
- * Check if a node is a `JSXText` or a `Literal` node
779
- * @param node The AST node to check
780
- * @returns `true` if the node is a `JSXText` or a `Literal` node
781
- */
782
- declare function isJsxText(node: TSESTree$1.Node | null): node is TSESTree$1.JSXText | TSESTree$1.Literal;
783
715
  /**
784
716
  * Determine if a node represents JSX-like content based on heuristics
785
717
  * Supports configuration through hint flags to customize detection behavior
@@ -791,59 +723,194 @@ declare function isJsxText(node: TSESTree$1.Node | null): node is TSESTree$1.JSX
791
723
  */
792
724
  declare function isJsxLike(context: RuleContext, node: TSESTree$1.Node | null, hint?: JsxDetectionHint): boolean;
793
725
  //#endregion
794
- //#region src/jsx/jsx-element-is.d.ts
726
+ //#region src/jsx/jsx-inspector.d.ts
795
727
  /**
796
- * Determine if a JSX element is a host element
797
- * Host elements in React start with lowercase letters (e.g., div, span)
728
+ * A stateful helper that binds an ESLint `RuleContext` once and exposes
729
+ * ergonomic methods for the most common JSX inspection tasks that rules need.
798
730
  *
799
- * @param context ESLint rule context
800
- * @param node AST node to check
801
- * @returns boolean indicating if the element is a host element
802
- */
803
- declare function isJsxHostElement(context: RuleContext, node: TSESTree.Node): boolean;
804
- /**
805
- * Determine if a JSX element is a React Fragment
806
- * Fragments can be imported from React and used like <Fragment> or <React.Fragment>
731
+ * ### Typical usage inside a rule's `create` function
807
732
  *
808
- * @param context ESLint rule context
809
- * @param node AST node to check
810
- * @param jsxConfig Optional JSX configuration
811
- * @param jsxConfig.jsxFragmentFactory Name of the fragment factory (e.g., React.Fragment)
812
- * @returns boolean indicating if the element is a Fragment
813
- */
814
- declare function isJsxFragmentElement(context: RuleContext, node: TSESTree.Node, jsxConfig?: Pick<JsxConfig, "jsxFragmentFactory">): boolean;
815
- //#endregion
816
- //#region src/jsx/jsx-element-type.d.ts
817
- /**
818
- * Extracts the element type name from a JSX element or fragment
819
- * For JSX elements, returns the stringified name (e.g., "div", "Button", "React.Fragment")
820
- * For JSX fragments, returns an empty string
733
+ * ```ts
734
+ * export function create(context: RuleContext) {
735
+ * const jsx = JsxInspector.from(context);
821
736
  *
822
- * @param context ESLint rule context
823
- * @param node JSX element or fragment node
824
- * @returns String representation of the element type
825
- */
826
- declare function getJsxElementType(context: RuleContext, node: TSESTree.JSXElement | TSESTree.JSXFragment): string;
827
- //#endregion
828
- //#region src/jsx/jsx-hierarchy.d.ts
829
- /**
830
- * Traverses up the AST to find a parent JSX attribute node that matches a given test
737
+ * return defineRuleListener({
738
+ * JSXElement(node) {
739
+ * // element type
740
+ * const type = jsx.getElementType(node); // "div" | "React.Fragment" | …
831
741
  *
832
- * @param node The starting AST node
833
- * @param test Optional predicate function to test if the attribute meets criteria
834
- * Defaults to always returning true (matches any attribute)
835
- * @returns The first matching JSX attribute node found when traversing upwards, or null
836
- */
837
- declare function findParentJsxAttribute(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | null;
838
- //#endregion
839
- //#region src/jsx/jsx-stringify.d.ts
840
- /**
841
- * Incomplete but sufficient stringification of JSX nodes for common use cases
742
+ * // attribute lookup + value resolution in one step
743
+ * const val = jsx.getAttributeValue(node, "sandbox");
744
+ * if (typeof val?.getStatic() === "string") { }
842
745
  *
843
- * @param node JSX node from TypeScript ESTree
844
- * @returns String representation of the JSX node
746
+ * // simple boolean checks
747
+ * if (jsx.isHostElement(node)) { }
748
+ * if (jsx.isFragmentElement(node)) { … }
749
+ * if (jsx.hasAttribute(node, "key")) { … }
750
+ * },
751
+ * });
752
+ * }
753
+ * ```
845
754
  */
846
- declare function stringifyJsx(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXNamespacedName | TSESTree$1.JSXMemberExpression | TSESTree$1.JSXOpeningElement | TSESTree$1.JSXClosingElement | TSESTree$1.JSXOpeningFragment | TSESTree$1.JSXClosingFragment | TSESTree$1.JSXText): string;
755
+ declare class JsxInspector {
756
+ #private;
757
+ readonly context: RuleContext;
758
+ /**
759
+ * Merged JSX configuration (tsconfig compiler options + pragma annotations).
760
+ * The result is lazily computed and cached for the lifetime of this inspector.
761
+ */
762
+ get jsxConfig(): Required<JsxConfig>;
763
+ private constructor();
764
+ /**
765
+ * Walk **up** the AST from `node` to find the nearest ancestor that is a
766
+ * `JSXAttribute` and passes the optional `test` predicate.
767
+ * @param node The starting node for the search.
768
+ * @param test A predicate function to test each ancestor node.
769
+ */
770
+ static findParentAttribute(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | null;
771
+ /**
772
+ * Create a new `JsxInspector` bound to the given rule context.
773
+ * @param context The ESLint rule context to bind to this inspector instance.
774
+ */
775
+ static from(context: RuleContext): JsxInspector;
776
+ /**
777
+ * Whether the node is a `JSXText` or a `Literal` node.
778
+ * @param node The node to check.
779
+ */
780
+ static isJsxText(node: TSESTree.Node | null): node is TSESTree.JSXText | TSESTree.Literal;
781
+ /**
782
+ * Find a JSX attribute (or spread attribute containing the property) by name
783
+ * on a given element.
784
+ *
785
+ * Returns the **last** matching attribute (to mirror React's behaviour where
786
+ * later props win), or `undefined` if not found.
787
+ * @param node The JSX element to search for the attribute.
788
+ * @param name The name of the attribute to find (e.g. `"className"`).
789
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided,
790
+ */
791
+ findAttribute(node: TSESTree.JSXElement, name: string, initialScope?: Scope): ast.TSESTreeJSXAttributeLike | undefined;
792
+ /**
793
+ * Get the stringified name of a `JSXAttribute` node
794
+ * (e.g. `"className"`, `"aria-label"`, `"xml:space"`).
795
+ * @param node The `JSXAttribute` node to extract the name from.
796
+ * @returns The stringified name of the attribute.
797
+ */
798
+ getAttributeName(node: TSESTree.JSXAttribute): string;
799
+ /**
800
+ * Resolve the static value of an attribute, automatically handling the
801
+ * `spreadProps` case by extracting the named property.
802
+ *
803
+ * This eliminates the repetitive pattern:
804
+ * ```ts
805
+ * const v = core.resolveJsxAttributeValue(ctx, attr);
806
+ * const s = v.kind === "spreadProps" ? v.getProperty(name) : v.toStatic();
807
+ * ```
808
+ *
809
+ * Returns `undefined` when the attribute is not present or its value
810
+ * cannot be statically determined.
811
+ * @param node The JSX element to search for the attribute.
812
+ * @param name The name of the attribute to resolve (e.g. `"className"`).
813
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
814
+ * @returns The static value of the attribute, or `undefined` if not found or not statically resolvable.
815
+ */
816
+ getAttributeStaticValue(node: TSESTree.JSXElement, name: string, initialScope?: Scope): unknown;
817
+ /**
818
+ * **All-in-one helper** – find an attribute by name on an element *and*
819
+ * resolve its value in a single call.
820
+ *
821
+ * Returns `undefined` when the attribute is not present.
822
+ * @param node The JSX element to search for the attribute.
823
+ * @param name The name of the attribute to find and resolve (e.g. `"className"`).
824
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
825
+ * @returns A descriptor of the attribute's value that can be further inspected, or `undefined` if the attribute is not found.
826
+ */
827
+ getAttributeValue(node: TSESTree.JSXElement, name: string, initialScope?: Scope): JsxAttributeValue | undefined;
828
+ /**
829
+ * Get the **self name** (last segment) of a JSX element type.
830
+ *
831
+ * - `<Foo.Bar.Baz>` → `"Baz"`
832
+ * - `<div>` → `"div"`
833
+ * - `<></>` → `""`
834
+ * @param node The JSX element or fragment to extract the self name from.
835
+ */
836
+ getElementSelfName(node: TSESTree.JSXElement | TSESTree.JSXFragment): string;
837
+ /**
838
+ * Get the string representation of a JSX element's type.
839
+ *
840
+ * - `<div>` → `"div"`
841
+ * - `<Foo.Bar>` → `"Foo.Bar"`
842
+ * - `<React.Fragment>` → `"React.Fragment"`
843
+ * - `<></>` (JSXFragment) → `""`
844
+ * @param node The JSX element or fragment to extract the type from.
845
+ */
846
+ getElementType(node: TSESTree.JSXElement | TSESTree.JSXFragment): string;
847
+ /**
848
+ * Shorthand: check whether an attribute exists on the element.
849
+ * @param node The JSX element to check for the attribute.
850
+ * @param name The name of the attribute to check for (e.g. `"className"`).
851
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
852
+ * @returns `true` if the attribute exists on the element, `false` otherwise.
853
+ */
854
+ hasAttribute(node: TSESTree.JSXElement, name: string, initialScope?: Scope): boolean;
855
+ /**
856
+ * Whether the node is a React **Fragment** element (either `<Fragment>` /
857
+ * `<React.Fragment>` or the shorthand `<>` syntax).
858
+ *
859
+ * The check honours the configured `jsxFragmentFactory`.
860
+ * @param node The node to check.
861
+ */
862
+ isFragmentElement(node: TSESTree.Node): node is TSESTree.JSXElement | TSESTree.JSXFragment;
863
+ /**
864
+ * Whether the node is a **host** (intrinsic / DOM) element – i.e. its tag
865
+ * name starts with a lowercase letter.
866
+ * @param node The node to check.
867
+ */
868
+ isHostElement(node: TSESTree.Node): node is TSESTree.JSXElement;
869
+ /**
870
+ * Resolve the *value* of a JSX attribute (or spread attribute) into a
871
+ * descriptor that can be inspected further.
872
+ *
873
+ * See {@link JsxAttributeValue} for the full set of `kind` discriminants.
874
+ * @param attribute The attribute node to resolve the value of.
875
+ * @returns A descriptor of the attribute's value that can be further inspected.
876
+ */
877
+ resolveAttributeValue(attribute: ast.TSESTreeJSXAttributeLike): {
878
+ readonly kind: "boolean";
879
+ readonly toStatic: () => true;
880
+ readonly node?: never;
881
+ readonly getChildren?: never;
882
+ } | {
883
+ readonly kind: "literal";
884
+ readonly node: TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral;
885
+ readonly toStatic: () => string | number | bigint | boolean | RegExp | null;
886
+ readonly getChildren?: never;
887
+ } | {
888
+ readonly kind: "missing";
889
+ readonly node: TSESTree.JSXEmptyExpression;
890
+ readonly toStatic: () => "{}";
891
+ readonly getChildren?: never;
892
+ } | {
893
+ readonly kind: "expression";
894
+ readonly node: TSESTree.Expression;
895
+ readonly toStatic: () => unknown;
896
+ readonly getChildren?: never;
897
+ } | {
898
+ readonly kind: "element";
899
+ readonly node: TSESTree.JSXElement;
900
+ readonly toStatic: () => null;
901
+ readonly getChildren?: never;
902
+ } | {
903
+ readonly kind: "spreadChild";
904
+ readonly getChildren: (_at: number) => null;
905
+ readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
906
+ readonly toStatic: () => unknown;
907
+ } | {
908
+ readonly kind: "spreadProps";
909
+ readonly getProperty: (name: string) => unknown;
910
+ readonly node: TSESTree.Expression;
911
+ readonly toStatic: () => unknown;
912
+ };
913
+ }
847
914
  //#endregion
848
915
  //#region src/ref/ref-id.d.ts
849
916
  declare function isRefId(node: TSESTree.Expression | TSESTree.PrivateIdentifier): boolean;
@@ -872,4 +939,4 @@ declare function getRefInit(name: string, initialScope: Scope): TSESTree$1.Expre
872
939
  */
873
940
  declare function isRefLikeName(name: string): boolean;
874
941
  //#endregion
875
- export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FunctionComponentSemanticNode, FunctionKind, FunctionSemanticNode, HookSemanticNode, JsxAttributeValue, JsxConfig, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findImportSource, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, 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, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderMethodCallback, isRenderMethodLike, 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 };
942
+ export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FunctionComponentSemanticNode, FunctionKind, FunctionSemanticNode, HookSemanticNode, JsxAttributeValue, JsxConfig, JsxDetectionHint, JsxEmit, JsxInspector, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findImportSource, getComponentFlagFromInitPath, getFunctionComponentId, getJsxConfigFromAnnotation, getJsxConfigFromContext, getRefInit, 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, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isJsxLike, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderMethodCallback, isRenderMethodLike, 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, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as ast from "@eslint-react/ast";
2
- import { constFalse, constTrue, dual, flip, getOrElseUpdate, identity } from "@eslint-react/eff";
2
+ import { constFalse, dual, flip, getOrElseUpdate, identity } from "@eslint-react/eff";
3
3
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
4
4
  import { findVariable, getStaticValue } from "@typescript-eslint/utils/ast-utils";
5
5
  import { P, match } from "ts-pattern";
@@ -358,165 +358,6 @@ function useHookCollector(context) {
358
358
  };
359
359
  }
360
360
 
361
- //#endregion
362
- //#region src/jsx/jsx-stringify.ts
363
- /**
364
- * Incomplete but sufficient stringification of JSX nodes for common use cases
365
- *
366
- * @param node JSX node from TypeScript ESTree
367
- * @returns String representation of the JSX node
368
- */
369
- function stringifyJsx(node) {
370
- switch (node.type) {
371
- case AST_NODE_TYPES.JSXIdentifier: return node.name;
372
- case AST_NODE_TYPES.JSXNamespacedName: return `${node.namespace.name}:${node.name.name}`;
373
- case AST_NODE_TYPES.JSXMemberExpression: return `${stringifyJsx(node.object)}.${stringifyJsx(node.property)}`;
374
- case AST_NODE_TYPES.JSXText: return node.value;
375
- case AST_NODE_TYPES.JSXOpeningElement: return `<${stringifyJsx(node.name)}>`;
376
- case AST_NODE_TYPES.JSXClosingElement: return `</${stringifyJsx(node.name)}>`;
377
- case AST_NODE_TYPES.JSXOpeningFragment: return "<>";
378
- case AST_NODE_TYPES.JSXClosingFragment: return "</>";
379
- }
380
- }
381
-
382
- //#endregion
383
- //#region src/jsx/jsx-attribute-name.ts
384
- /**
385
- * Get the stringified name of a JSX attribute
386
- * @param context The ESLint rule context
387
- * @param node The JSX attribute node
388
- * @returns The name of the attribute
389
- */
390
- function getJsxAttributeName(context, node) {
391
- return stringifyJsx(node.name);
392
- }
393
-
394
- //#endregion
395
- //#region src/jsx/jsx-attribute.ts
396
- /**
397
- * Creates a helper function to find a specific JSX attribute by name
398
- * Handles direct attributes and spread attributes (variables or object literals)
399
- * @param context The ESLint rule context
400
- * @param node The JSX element node
401
- * @param initialScope (Optional) The initial scope to use for variable resolution
402
- */
403
- function getJsxAttribute(context, node, initialScope) {
404
- initialScope ?? context.sourceCode.getScope(node);
405
- const attributes = node.openingElement.attributes;
406
- /**
407
- * Finds the last occurrence of a specific attribute
408
- * @param name The attribute name to search for
409
- */
410
- return (name) => {
411
- return attributes.findLast((attr) => {
412
- if (attr.type === AST_NODE_TYPES.JSXAttribute) return getJsxAttributeName(context, attr) === name;
413
- switch (attr.argument.type) {
414
- case AST_NODE_TYPES.Identifier: {
415
- const initNode = resolve(context, attr.argument);
416
- if (initNode?.type === AST_NODE_TYPES.ObjectExpression) return ast.findProperty(initNode.properties, name) != null;
417
- return false;
418
- }
419
- case AST_NODE_TYPES.ObjectExpression: return ast.findProperty(attr.argument.properties, name) != null;
420
- }
421
- return false;
422
- });
423
- };
424
- }
425
-
426
- //#endregion
427
- //#region src/jsx/jsx-attribute-value.ts
428
- /**
429
- * Resolve the static value of a JSX attribute or spread attribute
430
- *
431
- * @param context - The ESLint rule context
432
- * @param attribute - The JSX attribute node to resolve
433
- * @returns An object containing the value kind, the node (if applicable), and a `toStatic` helper
434
- */
435
- function resolveJsxAttributeValue(context, attribute) {
436
- const initialScope = context.sourceCode.getScope(attribute);
437
- /**
438
- * Handles standard JSX attributes (e.g., prop="value", prop={value}, prop)
439
- * @param node The JSX attribute node
440
- */
441
- function handleJsxAttribute(node) {
442
- if (node.value == null) return {
443
- kind: "boolean",
444
- toStatic() {
445
- return true;
446
- }
447
- };
448
- switch (node.value.type) {
449
- case AST_NODE_TYPES.Literal: {
450
- const staticValue = node.value.value;
451
- return {
452
- kind: "literal",
453
- node: node.value,
454
- toStatic() {
455
- return staticValue;
456
- }
457
- };
458
- }
459
- case AST_NODE_TYPES.JSXExpressionContainer: {
460
- const expr = node.value.expression;
461
- if (expr.type === AST_NODE_TYPES.JSXEmptyExpression) return {
462
- kind: "missing",
463
- node: expr,
464
- toStatic() {
465
- return "{}";
466
- }
467
- };
468
- return {
469
- kind: "expression",
470
- node: expr,
471
- toStatic() {
472
- return getStaticValue(expr, initialScope)?.value;
473
- }
474
- };
475
- }
476
- case AST_NODE_TYPES.JSXElement: return {
477
- kind: "element",
478
- node: node.value,
479
- toStatic() {
480
- return null;
481
- }
482
- };
483
- case AST_NODE_TYPES.JSXSpreadChild: {
484
- const expr = node.value.expression;
485
- return {
486
- kind: "spreadChild",
487
- node: node.value.expression,
488
- toStatic() {
489
- return getStaticValue(expr, initialScope)?.value;
490
- },
491
- getChildren(at) {
492
- return null;
493
- }
494
- };
495
- }
496
- }
497
- }
498
- /**
499
- * Handles JSX spread attributes (e.g., {...props})
500
- * @param node The JSX spread attribute node
501
- */
502
- function handleJsxSpreadAttribute(node) {
503
- return {
504
- kind: "spreadProps",
505
- node: node.argument,
506
- toStatic() {
507
- return getStaticValue(node.argument, initialScope)?.value;
508
- },
509
- getProperty(name) {
510
- return match(getStaticValue(node.argument, initialScope)?.value).with({ [name]: P.select(P.any) }, identity).otherwise(() => null);
511
- }
512
- };
513
- }
514
- switch (attribute.type) {
515
- case AST_NODE_TYPES.JSXAttribute: return handleJsxAttribute(attribute);
516
- case AST_NODE_TYPES.JSXSpreadAttribute: return handleJsxSpreadAttribute(attribute);
517
- }
518
- }
519
-
520
361
  //#endregion
521
362
  //#region src/jsx/jsx-config.ts
522
363
  const JsxEmit = {
@@ -589,15 +430,6 @@ const JsxDetectionHint = {
589
430
  */
590
431
  const DEFAULT_JSX_DETECTION_HINT = 0n | JsxDetectionHint.DoNotIncludeJsxWithNumberValue | JsxDetectionHint.DoNotIncludeJsxWithBigIntValue | JsxDetectionHint.DoNotIncludeJsxWithBooleanValue | JsxDetectionHint.DoNotIncludeJsxWithStringValue | JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue;
591
432
  /**
592
- * Check if a node is a `JSXText` or a `Literal` node
593
- * @param node The AST node to check
594
- * @returns `true` if the node is a `JSXText` or a `Literal` node
595
- */
596
- function isJsxText(node) {
597
- if (node == null) return false;
598
- return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
599
- }
600
- /**
601
433
  * Determine if a node represents JSX-like content based on heuristics
602
434
  * Supports configuration through hint flags to customize detection behavior
603
435
  *
@@ -659,66 +491,314 @@ function isJsxLike(context, node, hint = DEFAULT_JSX_DETECTION_HINT) {
659
491
  }
660
492
 
661
493
  //#endregion
662
- //#region src/jsx/jsx-element-type.ts
494
+ //#region src/jsx/jsx-stringify.ts
663
495
  /**
664
- * Extracts the element type name from a JSX element or fragment
665
- * For JSX elements, returns the stringified name (e.g., "div", "Button", "React.Fragment")
666
- * For JSX fragments, returns an empty string
496
+ * Incomplete but sufficient stringification of JSX nodes for common use cases
667
497
  *
668
- * @param context ESLint rule context
669
- * @param node JSX element or fragment node
670
- * @returns String representation of the element type
498
+ * @param node JSX node from TypeScript ESTree
499
+ * @returns String representation of the JSX node
671
500
  */
672
- function getJsxElementType(context, node) {
673
- if (node.type === AST_NODE_TYPES.JSXFragment) return "";
674
- return stringifyJsx(node.openingElement.name);
501
+ function stringifyJsx(node) {
502
+ switch (node.type) {
503
+ case AST_NODE_TYPES.JSXIdentifier: return node.name;
504
+ case AST_NODE_TYPES.JSXNamespacedName: return `${node.namespace.name}:${node.name.name}`;
505
+ case AST_NODE_TYPES.JSXMemberExpression: return `${stringifyJsx(node.object)}.${stringifyJsx(node.property)}`;
506
+ case AST_NODE_TYPES.JSXText: return node.value;
507
+ case AST_NODE_TYPES.JSXOpeningElement: return `<${stringifyJsx(node.name)}>`;
508
+ case AST_NODE_TYPES.JSXClosingElement: return `</${stringifyJsx(node.name)}>`;
509
+ case AST_NODE_TYPES.JSXOpeningFragment: return "<>";
510
+ case AST_NODE_TYPES.JSXClosingFragment: return "</>";
511
+ }
675
512
  }
676
513
 
677
514
  //#endregion
678
- //#region src/jsx/jsx-element-is.ts
515
+ //#region src/jsx/jsx-inspector.ts
679
516
  /**
680
- * Determine if a JSX element is a host element
681
- * Host elements in React start with lowercase letters (e.g., div, span)
517
+ * A stateful helper that binds an ESLint `RuleContext` once and exposes
518
+ * ergonomic methods for the most common JSX inspection tasks that rules need.
682
519
  *
683
- * @param context ESLint rule context
684
- * @param node AST node to check
685
- * @returns boolean indicating if the element is a host element
686
- */
687
- function isJsxHostElement(context, node) {
688
- return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
689
- }
690
- /**
691
- * Determine if a JSX element is a React Fragment
692
- * Fragments can be imported from React and used like <Fragment> or <React.Fragment>
520
+ * ### Typical usage inside a rule's `create` function
693
521
  *
694
- * @param context ESLint rule context
695
- * @param node AST node to check
696
- * @param jsxConfig Optional JSX configuration
697
- * @param jsxConfig.jsxFragmentFactory Name of the fragment factory (e.g., React.Fragment)
698
- * @returns boolean indicating if the element is a Fragment
699
- */
700
- function isJsxFragmentElement(context, node, jsxConfig) {
701
- if (node.type !== AST_NODE_TYPES.JSXElement) return false;
702
- const fragment = jsxConfig?.jsxFragmentFactory?.split(".").at(-1) ?? "Fragment";
703
- return getJsxElementType(context, node).split(".").at(-1) === fragment;
704
- }
705
-
706
- //#endregion
707
- //#region src/jsx/jsx-hierarchy.ts
708
- /**
709
- * Traverses up the AST to find a parent JSX attribute node that matches a given test
522
+ * ```ts
523
+ * export function create(context: RuleContext) {
524
+ * const jsx = JsxInspector.from(context);
525
+ *
526
+ * return defineRuleListener({
527
+ * JSXElement(node) {
528
+ * // element type
529
+ * const type = jsx.getElementType(node); // "div" | "React.Fragment" | …
530
+ *
531
+ * // attribute lookup + value resolution in one step
532
+ * const val = jsx.getAttributeValue(node, "sandbox");
533
+ * if (typeof val?.getStatic() === "string") { … }
710
534
  *
711
- * @param node The starting AST node
712
- * @param test Optional predicate function to test if the attribute meets criteria
713
- * Defaults to always returning true (matches any attribute)
714
- * @returns The first matching JSX attribute node found when traversing upwards, or null
535
+ * // simple boolean checks
536
+ * if (jsx.isHostElement(node)) { }
537
+ * if (jsx.isFragmentElement(node)) { }
538
+ * if (jsx.hasAttribute(node, "key")) { }
539
+ * },
540
+ * });
541
+ * }
542
+ * ```
715
543
  */
716
- function findParentJsxAttribute(node, test = constTrue) {
717
- const guard = (node) => {
718
- return node.type === AST_NODE_TYPES.JSXAttribute && test(node);
719
- };
720
- return ast.findParentNode(node, guard);
721
- }
544
+ var JsxInspector = class JsxInspector {
545
+ context;
546
+ /**
547
+ * Merged JSX configuration (tsconfig compiler options + pragma annotations).
548
+ * The result is lazily computed and cached for the lifetime of this inspector.
549
+ */
550
+ get jsxConfig() {
551
+ return this.#jsxConfig ??= {
552
+ ...getJsxConfigFromContext(this.context),
553
+ ...getJsxConfigFromAnnotation(this.context)
554
+ };
555
+ }
556
+ /**
557
+ * Lazily resolved & cached JSX configuration (merged from tsconfig +
558
+ * pragma annotations). Use {@link jsxConfig} to access.
559
+ */
560
+ #jsxConfig;
561
+ constructor(context) {
562
+ this.context = context;
563
+ }
564
+ /**
565
+ * Walk **up** the AST from `node` to find the nearest ancestor that is a
566
+ * `JSXAttribute` and passes the optional `test` predicate.
567
+ * @param node The starting node for the search.
568
+ * @param test A predicate function to test each ancestor node.
569
+ */
570
+ static findParentAttribute(node, test = () => true) {
571
+ const guard = (n) => {
572
+ return n.type === AST_NODE_TYPES.JSXAttribute && test(n);
573
+ };
574
+ return ast.findParentNode(node, guard);
575
+ }
576
+ /**
577
+ * Create a new `JsxInspector` bound to the given rule context.
578
+ * @param context The ESLint rule context to bind to this inspector instance.
579
+ */
580
+ static from(context) {
581
+ return new JsxInspector(context);
582
+ }
583
+ /**
584
+ * Whether the node is a `JSXText` or a `Literal` node.
585
+ * @param node The node to check.
586
+ */
587
+ static isJsxText(node) {
588
+ if (node == null) return false;
589
+ return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
590
+ }
591
+ /**
592
+ * Find a JSX attribute (or spread attribute containing the property) by name
593
+ * on a given element.
594
+ *
595
+ * Returns the **last** matching attribute (to mirror React's behaviour where
596
+ * later props win), or `undefined` if not found.
597
+ * @param node The JSX element to search for the attribute.
598
+ * @param name The name of the attribute to find (e.g. `"className"`).
599
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided,
600
+ */
601
+ findAttribute(node, name, initialScope) {
602
+ initialScope ?? this.context.sourceCode.getScope(node);
603
+ return node.openingElement.attributes.findLast((attr) => {
604
+ if (attr.type === AST_NODE_TYPES.JSXAttribute) return stringifyJsx(attr.name) === name;
605
+ switch (attr.argument.type) {
606
+ case AST_NODE_TYPES.Identifier: {
607
+ const initNode = resolve(this.context, attr.argument);
608
+ if (initNode?.type === AST_NODE_TYPES.ObjectExpression) return ast.findProperty(initNode.properties, name) != null;
609
+ return false;
610
+ }
611
+ case AST_NODE_TYPES.ObjectExpression: return ast.findProperty(attr.argument.properties, name) != null;
612
+ }
613
+ return false;
614
+ });
615
+ }
616
+ /**
617
+ * Get the stringified name of a `JSXAttribute` node
618
+ * (e.g. `"className"`, `"aria-label"`, `"xml:space"`).
619
+ * @param node The `JSXAttribute` node to extract the name from.
620
+ * @returns The stringified name of the attribute.
621
+ */
622
+ getAttributeName(node) {
623
+ return stringifyJsx(node.name);
624
+ }
625
+ /**
626
+ * Resolve the static value of an attribute, automatically handling the
627
+ * `spreadProps` case by extracting the named property.
628
+ *
629
+ * This eliminates the repetitive pattern:
630
+ * ```ts
631
+ * const v = core.resolveJsxAttributeValue(ctx, attr);
632
+ * const s = v.kind === "spreadProps" ? v.getProperty(name) : v.toStatic();
633
+ * ```
634
+ *
635
+ * Returns `undefined` when the attribute is not present or its value
636
+ * cannot be statically determined.
637
+ * @param node The JSX element to search for the attribute.
638
+ * @param name The name of the attribute to resolve (e.g. `"className"`).
639
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
640
+ * @returns The static value of the attribute, or `undefined` if not found or not statically resolvable.
641
+ */
642
+ getAttributeStaticValue(node, name, initialScope) {
643
+ const attr = this.findAttribute(node, name, initialScope);
644
+ if (attr == null) return void 0;
645
+ const resolved = this.resolveAttributeValue(attr);
646
+ if (resolved.kind === "spreadProps") return resolved.getProperty(name);
647
+ return resolved.toStatic();
648
+ }
649
+ /**
650
+ * **All-in-one helper** – find an attribute by name on an element *and*
651
+ * resolve its value in a single call.
652
+ *
653
+ * Returns `undefined` when the attribute is not present.
654
+ * @param node The JSX element to search for the attribute.
655
+ * @param name The name of the attribute to find and resolve (e.g. `"className"`).
656
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
657
+ * @returns A descriptor of the attribute's value that can be further inspected, or `undefined` if the attribute is not found.
658
+ */
659
+ getAttributeValue(node, name, initialScope) {
660
+ const attr = this.findAttribute(node, name, initialScope);
661
+ if (attr == null) return void 0;
662
+ return this.resolveAttributeValue(attr);
663
+ }
664
+ /**
665
+ * Get the **self name** (last segment) of a JSX element type.
666
+ *
667
+ * - `<Foo.Bar.Baz>` → `"Baz"`
668
+ * - `<div>` → `"div"`
669
+ * - `<></>` → `""`
670
+ * @param node The JSX element or fragment to extract the self name from.
671
+ */
672
+ getElementSelfName(node) {
673
+ return this.getElementType(node).split(".").at(-1) ?? "";
674
+ }
675
+ /**
676
+ * Get the string representation of a JSX element's type.
677
+ *
678
+ * - `<div>` → `"div"`
679
+ * - `<Foo.Bar>` → `"Foo.Bar"`
680
+ * - `<React.Fragment>` → `"React.Fragment"`
681
+ * - `<></>` (JSXFragment) → `""`
682
+ * @param node The JSX element or fragment to extract the type from.
683
+ */
684
+ getElementType(node) {
685
+ if (node.type === AST_NODE_TYPES.JSXFragment) return "";
686
+ return stringifyJsx(node.openingElement.name);
687
+ }
688
+ /**
689
+ * Shorthand: check whether an attribute exists on the element.
690
+ * @param node The JSX element to check for the attribute.
691
+ * @param name The name of the attribute to check for (e.g. `"className"`).
692
+ * @param initialScope An optional scope to use for resolving spread attributes. If not provided, the scope will be determined from the context of the attribute node.
693
+ * @returns `true` if the attribute exists on the element, `false` otherwise.
694
+ */
695
+ hasAttribute(node, name, initialScope) {
696
+ return this.findAttribute(node, name, initialScope) != null;
697
+ }
698
+ /**
699
+ * Whether the node is a React **Fragment** element (either `<Fragment>` /
700
+ * `<React.Fragment>` or the shorthand `<>` syntax).
701
+ *
702
+ * The check honours the configured `jsxFragmentFactory`.
703
+ * @param node The node to check.
704
+ */
705
+ isFragmentElement(node) {
706
+ if (node.type === AST_NODE_TYPES.JSXFragment) return true;
707
+ if (node.type !== AST_NODE_TYPES.JSXElement) return false;
708
+ const fragment = this.jsxConfig.jsxFragmentFactory.split(".").at(-1) ?? "Fragment";
709
+ return this.getElementType(node).split(".").at(-1) === fragment;
710
+ }
711
+ /**
712
+ * Whether the node is a **host** (intrinsic / DOM) element – i.e. its tag
713
+ * name starts with a lowercase letter.
714
+ * @param node The node to check.
715
+ */
716
+ isHostElement(node) {
717
+ return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
718
+ }
719
+ /**
720
+ * Resolve the *value* of a JSX attribute (or spread attribute) into a
721
+ * descriptor that can be inspected further.
722
+ *
723
+ * See {@link JsxAttributeValue} for the full set of `kind` discriminants.
724
+ * @param attribute The attribute node to resolve the value of.
725
+ * @returns A descriptor of the attribute's value that can be further inspected.
726
+ */
727
+ resolveAttributeValue(attribute) {
728
+ const initialScope = this.context.sourceCode.getScope(attribute);
729
+ if (attribute.type === AST_NODE_TYPES.JSXAttribute) return this.#resolveJsxAttribute(attribute, initialScope);
730
+ return this.#resolveJsxSpreadAttribute(attribute, initialScope);
731
+ }
732
+ #resolveJsxAttribute(node, initialScope) {
733
+ if (node.value == null) return {
734
+ kind: "boolean",
735
+ toStatic() {
736
+ return true;
737
+ }
738
+ };
739
+ switch (node.value.type) {
740
+ case AST_NODE_TYPES.Literal: {
741
+ const staticValue = node.value.value;
742
+ return {
743
+ kind: "literal",
744
+ node: node.value,
745
+ toStatic() {
746
+ return staticValue;
747
+ }
748
+ };
749
+ }
750
+ case AST_NODE_TYPES.JSXExpressionContainer: {
751
+ const expr = node.value.expression;
752
+ if (expr.type === AST_NODE_TYPES.JSXEmptyExpression) return {
753
+ kind: "missing",
754
+ node: expr,
755
+ toStatic() {
756
+ return "{}";
757
+ }
758
+ };
759
+ return {
760
+ kind: "expression",
761
+ node: expr,
762
+ toStatic() {
763
+ return getStaticValue(expr, initialScope)?.value;
764
+ }
765
+ };
766
+ }
767
+ case AST_NODE_TYPES.JSXElement: return {
768
+ kind: "element",
769
+ node: node.value,
770
+ toStatic() {
771
+ return null;
772
+ }
773
+ };
774
+ case AST_NODE_TYPES.JSXSpreadChild: {
775
+ const expr = node.value.expression;
776
+ return {
777
+ kind: "spreadChild",
778
+ getChildren(_at) {
779
+ return null;
780
+ },
781
+ node: node.value.expression,
782
+ toStatic() {
783
+ return getStaticValue(expr, initialScope)?.value;
784
+ }
785
+ };
786
+ }
787
+ }
788
+ }
789
+ #resolveJsxSpreadAttribute(node, initialScope) {
790
+ return {
791
+ kind: "spreadProps",
792
+ getProperty(name) {
793
+ return match(getStaticValue(node.argument, initialScope)?.value).with({ [name]: P.select(P.any) }, identity).otherwise(() => null);
794
+ },
795
+ node: node.argument,
796
+ toStatic() {
797
+ return getStaticValue(node.argument, initialScope)?.value;
798
+ }
799
+ };
800
+ }
801
+ };
722
802
 
723
803
  //#endregion
724
804
  //#region src/component/component-detection-legacy.ts
@@ -1222,4 +1302,4 @@ function getRefInit(name, initialScope) {
1222
1302
  }
1223
1303
 
1224
1304
  //#endregion
1225
- export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JsxDetectionHint, JsxEmit, REACT_BUILTIN_HOOK_NAMES, findImportSource, findParentJsxAttribute, getComponentFlagFromInitPath, getFunctionComponentId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, getRefInit, 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, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isJsxFragmentElement, isJsxHostElement, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderMethodCallback, isRenderMethodLike, 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 };
1305
+ export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JsxDetectionHint, JsxEmit, JsxInspector, REACT_BUILTIN_HOOK_NAMES, findImportSource, getComponentFlagFromInitPath, getFunctionComponentId, getJsxConfigFromAnnotation, getJsxConfigFromContext, getRefInit, 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, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHook, isHookCall, isHookCallWithName, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isInitializedFromRef, isJsxLike, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRefId, isRefLikeName, isRender, isRenderMethodCallback, isRenderMethodLike, 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, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/core",
3
- "version": "3.0.0-next.69",
3
+ "version": "3.0.0-next.70",
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": {
@@ -34,10 +34,10 @@
34
34
  "@typescript-eslint/types": "canary",
35
35
  "@typescript-eslint/utils": "canary",
36
36
  "ts-pattern": "^5.9.0",
37
- "@eslint-react/ast": "3.0.0-next.69",
38
- "@eslint-react/shared": "3.0.0-next.69",
39
- "@eslint-react/eff": "3.0.0-next.69",
40
- "@eslint-react/var": "3.0.0-next.69"
37
+ "@eslint-react/ast": "3.0.0-next.70",
38
+ "@eslint-react/eff": "3.0.0-next.70",
39
+ "@eslint-react/var": "3.0.0-next.70",
40
+ "@eslint-react/shared": "3.0.0-next.70"
41
41
  },
42
42
  "devDependencies": {
43
43
  "tsdown": "^0.21.0-beta.2",