eslint-plugin-react-x 2.0.1-next.3 → 2.0.1
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.js +145 -146
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@ import { isFalseLiteralType, isTrueLiteralType, isTypeFlagSet, unionConstituents
|
|
|
5
5
|
import { P, isMatching, match } from "ts-pattern";
|
|
6
6
|
import ts from "typescript";
|
|
7
7
|
import * as AST from "@eslint-react/ast";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import { ConstructionDetectionHint, findVariable, getChildScopes, getConstruction, getVariableDefinitionNode } from "@eslint-react/var";
|
|
9
|
+
import { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, JsxEmit, findParentAttribute, getAttribute, getAttributeName, getElementType, getInstanceId, getJsxConfigFromAnnotation, getJsxConfigFromContext, hasAttribute, isAssignmentToThisState, isCaptureOwnerStackCall, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUpdate, isCreateContextCall, isCreateElementCall, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRefCall, isFragmentElement, isGetDerivedStateFromError, isGetDerivedStateFromProps, isHostElement, isInitializedFromReact, isInstanceIdEqual, isJsxText, isLazyCall, isReactHookCall, isReactHookName, isRenderMethodLike, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseCall, isUseCallbackCall, isUseContextCall, isUseMemoCall, isUseStateCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector } from "@eslint-react/core";
|
|
10
10
|
import { report, toRegExp } from "@eslint-react/kit";
|
|
11
11
|
import { constFalse, constTrue, flow, getOrElseUpdate, identity, unit } from "@eslint-react/eff";
|
|
12
12
|
import { compare } from "compare-versions";
|
|
@@ -115,7 +115,7 @@ const settings = { ...settings$1 };
|
|
|
115
115
|
//#endregion
|
|
116
116
|
//#region package.json
|
|
117
117
|
var name = "eslint-plugin-react-x";
|
|
118
|
-
var version = "2.0.1
|
|
118
|
+
var version = "2.0.1";
|
|
119
119
|
|
|
120
120
|
//#endregion
|
|
121
121
|
//#region src/utils/create-rule.ts
|
|
@@ -373,7 +373,7 @@ function create$57(context) {
|
|
|
373
373
|
if (name$4 == null) return;
|
|
374
374
|
if (name$4 === "this") return;
|
|
375
375
|
if (/^[a-z]/u.test(name$4)) return;
|
|
376
|
-
if (
|
|
376
|
+
if (findVariable(name$4, context.sourceCode.getScope(node)) == null) context.report({
|
|
377
377
|
messageId: "jsxNoUndef",
|
|
378
378
|
node,
|
|
379
379
|
data: { name: name$4 }
|
|
@@ -409,7 +409,7 @@ function create$56(context) {
|
|
|
409
409
|
const policy = context.options[0] ?? defaultOptions$3[0];
|
|
410
410
|
return { JSXAttribute(node) {
|
|
411
411
|
const { value } = node;
|
|
412
|
-
const propName =
|
|
412
|
+
const propName = getAttributeName(context, node);
|
|
413
413
|
switch (true) {
|
|
414
414
|
case policy === 1 && value?.type === AST_NODE_TYPES.JSXExpressionContainer && value.expression.type === AST_NODE_TYPES.Literal && value.expression.value === true:
|
|
415
415
|
context.report({
|
|
@@ -458,11 +458,11 @@ var jsx_shorthand_fragment_default = createRule({
|
|
|
458
458
|
function create$55(context) {
|
|
459
459
|
const policy = context.options[0] ?? defaultOptions$2[0];
|
|
460
460
|
const { jsxFragmentFactory } = {
|
|
461
|
-
...
|
|
462
|
-
...
|
|
461
|
+
...getJsxConfigFromContext(context),
|
|
462
|
+
...getJsxConfigFromAnnotation(context)
|
|
463
463
|
};
|
|
464
464
|
return match(policy).with(1, () => ({ JSXElement(node) {
|
|
465
|
-
if (!
|
|
465
|
+
if (!isFragmentElement(context, node)) return;
|
|
466
466
|
if (node.openingElement.attributes.length > 0) return;
|
|
467
467
|
context.report({
|
|
468
468
|
messageId: "jsxShorthandFragment",
|
|
@@ -481,7 +481,7 @@ function create$55(context) {
|
|
|
481
481
|
data: { message: "Use 'Fragment' component instead of fragment shorthand syntax." },
|
|
482
482
|
fix: (fixer) => {
|
|
483
483
|
const { closingFragment, openingFragment } = node;
|
|
484
|
-
return [fixer.replaceTextRange([openingFragment.range[0], openingFragment.range[1]],
|
|
484
|
+
return [fixer.replaceTextRange([openingFragment.range[0], openingFragment.range[1]], `<${jsxFragmentFactory}>`), fixer.replaceTextRange([closingFragment.range[0], closingFragment.range[1]], `</${jsxFragmentFactory}>`)];
|
|
485
485
|
}
|
|
486
486
|
});
|
|
487
487
|
} })).otherwise(() => ({}));
|
|
@@ -489,7 +489,6 @@ function create$55(context) {
|
|
|
489
489
|
|
|
490
490
|
//#endregion
|
|
491
491
|
//#region src/rules/jsx-uses-react.ts
|
|
492
|
-
const JsxEmit = ER.JsxEmit;
|
|
493
492
|
const RULE_NAME$54 = "jsx-uses-react";
|
|
494
493
|
const RULE_FEATURES$52 = [];
|
|
495
494
|
var jsx_uses_react_default = createRule({
|
|
@@ -508,8 +507,8 @@ var jsx_uses_react_default = createRule({
|
|
|
508
507
|
});
|
|
509
508
|
function create$54(context) {
|
|
510
509
|
const { jsx, jsxFactory, jsxFragmentFactory } = {
|
|
511
|
-
...
|
|
512
|
-
...
|
|
510
|
+
...getJsxConfigFromContext(context),
|
|
511
|
+
...getJsxConfigFromAnnotation(context)
|
|
513
512
|
};
|
|
514
513
|
if (jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev) return {};
|
|
515
514
|
function handleJsxElement(node) {
|
|
@@ -600,21 +599,21 @@ function create$52(context) {
|
|
|
600
599
|
const setStateEntries = [];
|
|
601
600
|
return {
|
|
602
601
|
CallExpression(node) {
|
|
603
|
-
if (!
|
|
602
|
+
if (!isThisSetState(node)) return;
|
|
604
603
|
setStateEntries.push([node, false]);
|
|
605
604
|
},
|
|
606
605
|
"CallExpression:exit"(node) {
|
|
607
|
-
if (!
|
|
606
|
+
if (!isThisSetState(node)) return;
|
|
608
607
|
setStateEntries.pop();
|
|
609
608
|
},
|
|
610
609
|
ClassDeclaration(node) {
|
|
611
|
-
classEntries.push([node,
|
|
610
|
+
classEntries.push([node, isClassComponent(node)]);
|
|
612
611
|
},
|
|
613
612
|
"ClassDeclaration:exit"() {
|
|
614
613
|
classEntries.pop();
|
|
615
614
|
},
|
|
616
615
|
ClassExpression(node) {
|
|
617
|
-
classEntries.push([node,
|
|
616
|
+
classEntries.push([node, isClassComponent(node)]);
|
|
618
617
|
},
|
|
619
618
|
"ClassExpression:exit"() {
|
|
620
619
|
classEntries.pop();
|
|
@@ -677,7 +676,7 @@ function isUsingReactChildren(context, node) {
|
|
|
677
676
|
if (!isReactChildrenMethod(callee.property.name)) return false;
|
|
678
677
|
const initialScope = context.sourceCode.getScope(node);
|
|
679
678
|
if (callee.object.type === AST_NODE_TYPES.Identifier && callee.object.name === "Children") return true;
|
|
680
|
-
if (callee.object.type === AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) return
|
|
679
|
+
if (callee.object.type === AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) return isInitializedFromReact(callee.object.object.name, importSource, initialScope);
|
|
681
680
|
return false;
|
|
682
681
|
}
|
|
683
682
|
function getMapIndexParamName(context, node) {
|
|
@@ -720,7 +719,7 @@ function create$51(context) {
|
|
|
720
719
|
return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name$4) => name$4 != null && name$4 === node.name);
|
|
721
720
|
}
|
|
722
721
|
function isCreateOrCloneElementCall(node) {
|
|
723
|
-
return
|
|
722
|
+
return isCreateElementCall(context, node) || isCloneElementCall(context, node);
|
|
724
723
|
}
|
|
725
724
|
function getReportDescriptors(node) {
|
|
726
725
|
switch (node.type) {
|
|
@@ -798,7 +797,7 @@ var no_children_count_default = createRule({
|
|
|
798
797
|
});
|
|
799
798
|
function create$50(context) {
|
|
800
799
|
return { MemberExpression(node) {
|
|
801
|
-
if (
|
|
800
|
+
if (isChildrenCount(context, node)) context.report({
|
|
802
801
|
messageId: "noChildrenCount",
|
|
803
802
|
node: node.property
|
|
804
803
|
});
|
|
@@ -825,7 +824,7 @@ var no_children_for_each_default = createRule({
|
|
|
825
824
|
});
|
|
826
825
|
function create$49(context) {
|
|
827
826
|
return { MemberExpression(node) {
|
|
828
|
-
if (
|
|
827
|
+
if (isChildrenForEach(context, node)) context.report({
|
|
829
828
|
messageId: "noChildrenForEach",
|
|
830
829
|
node: node.property
|
|
831
830
|
});
|
|
@@ -852,7 +851,7 @@ var no_children_map_default = createRule({
|
|
|
852
851
|
});
|
|
853
852
|
function create$48(context) {
|
|
854
853
|
return { MemberExpression(node) {
|
|
855
|
-
if (
|
|
854
|
+
if (isChildrenMap(context, node)) context.report({
|
|
856
855
|
messageId: "noChildrenMap",
|
|
857
856
|
node: node.property
|
|
858
857
|
});
|
|
@@ -879,7 +878,7 @@ var no_children_only_default = createRule({
|
|
|
879
878
|
});
|
|
880
879
|
function create$47(context) {
|
|
881
880
|
return { MemberExpression(node) {
|
|
882
|
-
if (
|
|
881
|
+
if (isChildrenOnly(context, node)) context.report({
|
|
883
882
|
messageId: "noChildrenOnly",
|
|
884
883
|
node: node.property
|
|
885
884
|
});
|
|
@@ -906,7 +905,7 @@ var no_children_prop_default = createRule({
|
|
|
906
905
|
});
|
|
907
906
|
function create$46(context) {
|
|
908
907
|
return { JSXElement(node) {
|
|
909
|
-
const childrenProp =
|
|
908
|
+
const childrenProp = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node))("children");
|
|
910
909
|
if (childrenProp != null) context.report({
|
|
911
910
|
messageId: "noChildrenProp",
|
|
912
911
|
node: childrenProp
|
|
@@ -934,7 +933,7 @@ var no_children_to_array_default = createRule({
|
|
|
934
933
|
});
|
|
935
934
|
function create$45(context) {
|
|
936
935
|
return { MemberExpression(node) {
|
|
937
|
-
if (
|
|
936
|
+
if (isChildrenToArray(context, node)) context.report({
|
|
938
937
|
messageId: "noChildrenToArray",
|
|
939
938
|
node: node.property
|
|
940
939
|
});
|
|
@@ -961,13 +960,13 @@ var no_class_component_default = createRule({
|
|
|
961
960
|
});
|
|
962
961
|
function create$44(context) {
|
|
963
962
|
if (!context.sourceCode.text.includes("Component")) return {};
|
|
964
|
-
const { ctx, listeners } =
|
|
963
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
965
964
|
return {
|
|
966
965
|
...listeners,
|
|
967
966
|
"Program:exit"(program) {
|
|
968
967
|
const components = ctx.getAllComponents(program);
|
|
969
968
|
for (const { name: name$4 = "anonymous", node: component } of components.values()) {
|
|
970
|
-
if (component.body.body.some((m) =>
|
|
969
|
+
if (component.body.body.some((m) => isComponentDidCatch(m) || isGetDerivedStateFromError(m))) continue;
|
|
971
970
|
context.report({
|
|
972
971
|
messageId: "noClassComponent",
|
|
973
972
|
node: component,
|
|
@@ -998,7 +997,7 @@ var no_clone_element_default = createRule({
|
|
|
998
997
|
});
|
|
999
998
|
function create$43(context) {
|
|
1000
999
|
return { CallExpression(node) {
|
|
1001
|
-
if (
|
|
1000
|
+
if (isCloneElementCall(context, node)) context.report({
|
|
1002
1001
|
messageId: "noCloneElement",
|
|
1003
1002
|
node
|
|
1004
1003
|
});
|
|
@@ -1026,14 +1025,14 @@ var no_component_will_mount_default = createRule({
|
|
|
1026
1025
|
});
|
|
1027
1026
|
function create$42(context) {
|
|
1028
1027
|
if (!context.sourceCode.text.includes("componentWillMount")) return {};
|
|
1029
|
-
const { ctx, listeners } =
|
|
1028
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
1030
1029
|
return {
|
|
1031
1030
|
...listeners,
|
|
1032
1031
|
"Program:exit"(program) {
|
|
1033
1032
|
const components = ctx.getAllComponents(program);
|
|
1034
1033
|
for (const { node: component } of components.values()) {
|
|
1035
1034
|
const { body } = component.body;
|
|
1036
|
-
for (const member of body) if (
|
|
1035
|
+
for (const member of body) if (isComponentWillMount(member)) context.report({
|
|
1037
1036
|
messageId: "noComponentWillMount",
|
|
1038
1037
|
node: member,
|
|
1039
1038
|
fix(fixer) {
|
|
@@ -1067,14 +1066,14 @@ var no_component_will_receive_props_default = createRule({
|
|
|
1067
1066
|
});
|
|
1068
1067
|
function create$41(context) {
|
|
1069
1068
|
if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
|
|
1070
|
-
const { ctx, listeners } =
|
|
1069
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
1071
1070
|
return {
|
|
1072
1071
|
...listeners,
|
|
1073
1072
|
"Program:exit"(program) {
|
|
1074
1073
|
const components = ctx.getAllComponents(program);
|
|
1075
1074
|
for (const { node: component } of components.values()) {
|
|
1076
1075
|
const { body } = component.body;
|
|
1077
|
-
for (const member of body) if (
|
|
1076
|
+
for (const member of body) if (isComponentWillReceiveProps(member)) context.report({
|
|
1078
1077
|
messageId: "noComponentWillReceiveProps",
|
|
1079
1078
|
node: member,
|
|
1080
1079
|
fix(fixer) {
|
|
@@ -1108,14 +1107,14 @@ var no_component_will_update_default = createRule({
|
|
|
1108
1107
|
});
|
|
1109
1108
|
function create$40(context) {
|
|
1110
1109
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
1111
|
-
const { ctx, listeners } =
|
|
1110
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
1112
1111
|
return {
|
|
1113
1112
|
...listeners,
|
|
1114
1113
|
"Program:exit"(program) {
|
|
1115
1114
|
const components = ctx.getAllComponents(program);
|
|
1116
1115
|
for (const { node: component } of components.values()) {
|
|
1117
1116
|
const { body } = component.body;
|
|
1118
|
-
for (const member of body) if (
|
|
1117
|
+
for (const member of body) if (isComponentWillUpdate(member)) context.report({
|
|
1119
1118
|
messageId: "noComponentWillUpdate",
|
|
1120
1119
|
node: member,
|
|
1121
1120
|
fix(fixer) {
|
|
@@ -1152,7 +1151,7 @@ function create$39(context) {
|
|
|
1152
1151
|
const { version: version$1 } = getSettingsFromContext(context);
|
|
1153
1152
|
if (compare(version$1, "19.0.0", "<")) return {};
|
|
1154
1153
|
return { JSXElement(node) {
|
|
1155
|
-
const parts =
|
|
1154
|
+
const parts = getElementType(context, node).split(".");
|
|
1156
1155
|
const selfName = parts.pop();
|
|
1157
1156
|
const contextFullName = parts.join(".");
|
|
1158
1157
|
const contextSelfName = parts.pop();
|
|
@@ -1162,7 +1161,7 @@ function create$39(context) {
|
|
|
1162
1161
|
messageId: "noContextProvider",
|
|
1163
1162
|
node,
|
|
1164
1163
|
fix(fixer) {
|
|
1165
|
-
if (!
|
|
1164
|
+
if (!isComponentNameLoose(contextSelfName)) return null;
|
|
1166
1165
|
const openingElement = node.openingElement;
|
|
1167
1166
|
const closingElement = node.closingElement;
|
|
1168
1167
|
if (closingElement == null) return fixer.replaceText(openingElement.name, contextFullName);
|
|
@@ -1192,7 +1191,7 @@ var no_create_ref_default = createRule({
|
|
|
1192
1191
|
});
|
|
1193
1192
|
function create$38(context) {
|
|
1194
1193
|
return { CallExpression(node) {
|
|
1195
|
-
if (
|
|
1194
|
+
if (isCreateRefCall(context, node) && AST.findParentNode(node, isClassComponent) == null) context.report({
|
|
1196
1195
|
messageId: "noCreateRef",
|
|
1197
1196
|
node
|
|
1198
1197
|
});
|
|
@@ -1224,9 +1223,9 @@ function create$37(context) {
|
|
|
1224
1223
|
const { object, property } = node.left;
|
|
1225
1224
|
if (object.type !== AST_NODE_TYPES.Identifier) return;
|
|
1226
1225
|
if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "defaultProps") return;
|
|
1227
|
-
if (!
|
|
1228
|
-
const variable =
|
|
1229
|
-
const variableNode =
|
|
1226
|
+
if (!isComponentNameLoose(object.name)) return;
|
|
1227
|
+
const variable = findVariable(object.name, context.sourceCode.getScope(node));
|
|
1228
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
1230
1229
|
if (variableNode == null) return;
|
|
1231
1230
|
if (!AST.isFunction(variableNode)) return;
|
|
1232
1231
|
context.report({
|
|
@@ -1259,10 +1258,10 @@ var no_direct_mutation_state_default = createRule({
|
|
|
1259
1258
|
});
|
|
1260
1259
|
function create$36(context) {
|
|
1261
1260
|
return { AssignmentExpression(node) {
|
|
1262
|
-
if (!
|
|
1261
|
+
if (!isAssignmentToThisState(node)) return;
|
|
1263
1262
|
const parentClass = AST.findParentNode(node, AST.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
|
|
1264
1263
|
if (parentClass == null) return;
|
|
1265
|
-
if (
|
|
1264
|
+
if (isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== AST.findParentNode(node, isConstructorFunction)) context.report({
|
|
1266
1265
|
messageId: "noDirectMutationState",
|
|
1267
1266
|
node
|
|
1268
1267
|
});
|
|
@@ -1441,7 +1440,7 @@ function create$33(context) {
|
|
|
1441
1440
|
const { version: version$1 } = getSettingsFromContext(context);
|
|
1442
1441
|
if (compare(version$1, "19.0.0", "<")) return {};
|
|
1443
1442
|
return { CallExpression(node) {
|
|
1444
|
-
if (!
|
|
1443
|
+
if (!isForwardRefCall(context, node)) return;
|
|
1445
1444
|
const id = AST.getFunctionId(node);
|
|
1446
1445
|
const fix = canFix$1(context, node) ? getFix$1(context, node) : null;
|
|
1447
1446
|
context.report({
|
|
@@ -1463,8 +1462,8 @@ function canFix$1(context, node) {
|
|
|
1463
1462
|
const { importSource } = getSettingsFromContext(context);
|
|
1464
1463
|
const initialScope = context.sourceCode.getScope(node);
|
|
1465
1464
|
switch (node.callee.type) {
|
|
1466
|
-
case AST_NODE_TYPES.Identifier: return
|
|
1467
|
-
case AST_NODE_TYPES.MemberExpression: return node.callee.object.type === AST_NODE_TYPES.Identifier &&
|
|
1465
|
+
case AST_NODE_TYPES.Identifier: return isInitializedFromReact(node.callee.name, importSource, initialScope);
|
|
1466
|
+
case AST_NODE_TYPES.MemberExpression: return node.callee.object.type === AST_NODE_TYPES.Identifier && isInitializedFromReact(node.callee.object.name, importSource, initialScope);
|
|
1468
1467
|
default: return false;
|
|
1469
1468
|
}
|
|
1470
1469
|
}
|
|
@@ -1536,7 +1535,7 @@ var no_implicit_key_default = createRule({
|
|
|
1536
1535
|
function create$32(context) {
|
|
1537
1536
|
return { JSXOpeningElement(node) {
|
|
1538
1537
|
const initialScope = context.sourceCode.getScope(node);
|
|
1539
|
-
const keyProp =
|
|
1538
|
+
const keyProp = getAttribute(context, node.attributes, initialScope)("key");
|
|
1540
1539
|
const isKeyPropOnElement = node.attributes.some((n) => n.type === AST_NODE_TYPES.JSXAttribute && n.name.type === AST_NODE_TYPES.JSXIdentifier && n.name.name === "key");
|
|
1541
1540
|
if (keyProp != null && !isKeyPropOnElement) context.report({
|
|
1542
1541
|
messageId: "noImplicitKey",
|
|
@@ -1606,7 +1605,7 @@ function create$31(context) {
|
|
|
1606
1605
|
}).with({ type: AST_NODE_TYPES.ConditionalExpression }, ({ alternate, consequent }) => {
|
|
1607
1606
|
return getReportDescriptor(consequent) ?? getReportDescriptor(alternate);
|
|
1608
1607
|
}).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
1609
|
-
const variableDefNode =
|
|
1608
|
+
const variableDefNode = findVariable(n.name, context.sourceCode.getScope(n))?.defs.at(0)?.node;
|
|
1610
1609
|
return match(variableDefNode).with({ init: P.select({ type: P.not(AST_NODE_TYPES.VariableDeclaration) }) }, getReportDescriptor).otherwise(() => unit);
|
|
1611
1610
|
}).otherwise(() => unit);
|
|
1612
1611
|
}
|
|
@@ -1633,17 +1632,17 @@ var no_missing_component_display_name_default = createRule({
|
|
|
1633
1632
|
});
|
|
1634
1633
|
function create$30(context) {
|
|
1635
1634
|
if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
|
|
1636
|
-
const { ctx, listeners } =
|
|
1635
|
+
const { ctx, listeners } = useComponentCollector(context, {
|
|
1637
1636
|
collectDisplayName: true,
|
|
1638
1637
|
collectHookCalls: false,
|
|
1639
|
-
hint:
|
|
1638
|
+
hint: DEFAULT_COMPONENT_DETECTION_HINT
|
|
1640
1639
|
});
|
|
1641
1640
|
return {
|
|
1642
1641
|
...listeners,
|
|
1643
1642
|
"Program:exit"(program) {
|
|
1644
1643
|
const components = ctx.getAllComponents(program);
|
|
1645
1644
|
for (const { node, displayName, flag } of components.values()) {
|
|
1646
|
-
const isMemoOrForwardRef = (flag & (
|
|
1645
|
+
const isMemoOrForwardRef = (flag & (ComponentFlag.ForwardRef | ComponentFlag.Memo)) > 0n;
|
|
1647
1646
|
if (AST.getFunctionId(node) != null) continue;
|
|
1648
1647
|
if (!isMemoOrForwardRef) continue;
|
|
1649
1648
|
if (displayName == null) {
|
|
@@ -1686,12 +1685,12 @@ function create$29(context) {
|
|
|
1686
1685
|
displayNameAssignments.push(node);
|
|
1687
1686
|
},
|
|
1688
1687
|
CallExpression(node) {
|
|
1689
|
-
if (!
|
|
1688
|
+
if (!isCreateContextCall(context, node)) return;
|
|
1690
1689
|
createCalls.push(node);
|
|
1691
1690
|
},
|
|
1692
1691
|
"Program:exit"() {
|
|
1693
1692
|
for (const call of createCalls) {
|
|
1694
|
-
const id =
|
|
1693
|
+
const id = getInstanceId(call);
|
|
1695
1694
|
if (id == null) {
|
|
1696
1695
|
context.report({
|
|
1697
1696
|
messageId: "noMissingContextDisplayName",
|
|
@@ -1703,7 +1702,7 @@ function create$29(context) {
|
|
|
1703
1702
|
const left = node.left;
|
|
1704
1703
|
if (left.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
1705
1704
|
const object = left.object;
|
|
1706
|
-
return
|
|
1705
|
+
return isInstanceIdEqual(context, id, object);
|
|
1707
1706
|
})) context.report({
|
|
1708
1707
|
messageId: "noMissingContextDisplayName",
|
|
1709
1708
|
node: id,
|
|
@@ -1754,7 +1753,7 @@ function create$28(context) {
|
|
|
1754
1753
|
switch (node.type) {
|
|
1755
1754
|
case AST_NODE_TYPES.JSXElement: {
|
|
1756
1755
|
const initialScope = context.sourceCode.getScope(node);
|
|
1757
|
-
if (!
|
|
1756
|
+
if (!hasAttribute(context, "key", node.openingElement.attributes, initialScope)) return {
|
|
1758
1757
|
messageId: "missingKey",
|
|
1759
1758
|
node
|
|
1760
1759
|
};
|
|
@@ -1795,13 +1794,13 @@ function create$28(context) {
|
|
|
1795
1794
|
const elements = node.elements.filter(AST.is(AST_NODE_TYPES.JSXElement));
|
|
1796
1795
|
if (elements.length === 0) return;
|
|
1797
1796
|
const initialScope = context.sourceCode.getScope(node);
|
|
1798
|
-
for (const element of elements) if (!
|
|
1797
|
+
for (const element of elements) if (!hasAttribute(context, "key", element.openingElement.attributes, initialScope)) context.report({
|
|
1799
1798
|
messageId: "missingKey",
|
|
1800
1799
|
node: element
|
|
1801
1800
|
});
|
|
1802
1801
|
},
|
|
1803
1802
|
CallExpression(node) {
|
|
1804
|
-
state.isWithinChildrenToArray ||=
|
|
1803
|
+
state.isWithinChildrenToArray ||= isChildrenToArrayCall(context, node);
|
|
1805
1804
|
if (state.isWithinChildrenToArray) return;
|
|
1806
1805
|
const callback = match(node).when(AST.isArrayMapCall, (n) => n.arguments[0]).when(AST.isArrayFromCall, (n) => n.arguments[1]).otherwise(() => null);
|
|
1807
1806
|
if (!AST.isFunction(callback)) return;
|
|
@@ -1813,7 +1812,7 @@ function create$28(context) {
|
|
|
1813
1812
|
report(context)(checkExpression(body));
|
|
1814
1813
|
},
|
|
1815
1814
|
"CallExpression:exit"(node) {
|
|
1816
|
-
if (!
|
|
1815
|
+
if (!isChildrenToArrayCall(context, node)) return;
|
|
1817
1816
|
state.isWithinChildrenToArray = false;
|
|
1818
1817
|
},
|
|
1819
1818
|
JSXFragment(node) {
|
|
@@ -1853,7 +1852,7 @@ function create$27(context) {
|
|
|
1853
1852
|
const { importSource } = getSettingsFromContext(context);
|
|
1854
1853
|
return {
|
|
1855
1854
|
CallExpression(node) {
|
|
1856
|
-
if (!
|
|
1855
|
+
if (!isCaptureOwnerStackCall(context, node)) return;
|
|
1857
1856
|
if (AST.findParentNode(node, isDevelopmentOnlyCheck) == null) context.report({
|
|
1858
1857
|
messageId: "missingDevelopmentOnlyCheck",
|
|
1859
1858
|
node
|
|
@@ -1897,9 +1896,9 @@ var no_nested_component_definitions_default = createRule({
|
|
|
1897
1896
|
defaultOptions: []
|
|
1898
1897
|
});
|
|
1899
1898
|
function create$26(context) {
|
|
1900
|
-
const hint =
|
|
1901
|
-
const collector =
|
|
1902
|
-
const collectorLegacy =
|
|
1899
|
+
const hint = ComponentDetectionHint.SkipArrayMapArgument | ComponentDetectionHint.SkipNullLiteral | ComponentDetectionHint.SkipUndefined | ComponentDetectionHint.SkipBooleanLiteral | ComponentDetectionHint.SkipStringLiteral | ComponentDetectionHint.SkipNumberLiteral | ComponentDetectionHint.StrictLogical | ComponentDetectionHint.StrictConditional;
|
|
1900
|
+
const collector = useComponentCollector(context, { hint });
|
|
1901
|
+
const collectorLegacy = useComponentCollectorLegacy();
|
|
1903
1902
|
return {
|
|
1904
1903
|
...collector.listeners,
|
|
1905
1904
|
...collectorLegacy.listeners,
|
|
@@ -1909,14 +1908,14 @@ function create$26(context) {
|
|
|
1909
1908
|
const isFunctionComponent = (node) => {
|
|
1910
1909
|
return AST.isFunction(node) && functionComponents.some((component) => component.node === node);
|
|
1911
1910
|
};
|
|
1912
|
-
const isClassComponent = (node) => {
|
|
1911
|
+
const isClassComponent$1 = (node) => {
|
|
1913
1912
|
return AST.isClass(node) && classComponents.some((component) => component.node === node);
|
|
1914
1913
|
};
|
|
1915
1914
|
for (const { name: name$4, node: component } of functionComponents) {
|
|
1916
1915
|
if (name$4 == null) continue;
|
|
1917
|
-
if (
|
|
1916
|
+
if (isDirectValueOfRenderPropertyLoose(component)) continue;
|
|
1918
1917
|
if (isInsideJSXAttributeValue(component)) {
|
|
1919
|
-
if (!
|
|
1918
|
+
if (!isDeclaredInRenderPropLoose(component)) context.report({
|
|
1920
1919
|
messageId: "noNestedComponentDefinitions",
|
|
1921
1920
|
node: component,
|
|
1922
1921
|
data: {
|
|
@@ -1938,7 +1937,7 @@ function create$26(context) {
|
|
|
1938
1937
|
continue;
|
|
1939
1938
|
}
|
|
1940
1939
|
const parentComponent = AST.findParentNode(component, isFunctionComponent);
|
|
1941
|
-
if (parentComponent != null && !
|
|
1940
|
+
if (parentComponent != null && !isDirectValueOfRenderPropertyLoose(parentComponent)) {
|
|
1942
1941
|
context.report({
|
|
1943
1942
|
messageId: "noNestedComponentDefinitions",
|
|
1944
1943
|
node: component,
|
|
@@ -1959,7 +1958,7 @@ function create$26(context) {
|
|
|
1959
1958
|
});
|
|
1960
1959
|
}
|
|
1961
1960
|
for (const { name: name$4 = "unknown", node: component } of classComponents) {
|
|
1962
|
-
if (AST.findParentNode(component, (n) => isClassComponent(n) || isFunctionComponent(n)) == null) continue;
|
|
1961
|
+
if (AST.findParentNode(component, (n) => isClassComponent$1(n) || isFunctionComponent(n)) == null) continue;
|
|
1963
1962
|
context.report({
|
|
1964
1963
|
messageId: "noNestedComponentDefinitions",
|
|
1965
1964
|
node: component,
|
|
@@ -1978,7 +1977,7 @@ function create$26(context) {
|
|
|
1978
1977
|
* @returns `true` if the node is inside JSX attribute value
|
|
1979
1978
|
*/
|
|
1980
1979
|
function isInsideJSXAttributeValue(node) {
|
|
1981
|
-
return node.parent.type === AST_NODE_TYPES.JSXAttribute ||
|
|
1980
|
+
return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
1982
1981
|
}
|
|
1983
1982
|
/**
|
|
1984
1983
|
* Check whether given node is declared inside class component's render block
|
|
@@ -1996,7 +1995,7 @@ function isInsideJSXAttributeValue(node) {
|
|
|
1996
1995
|
* @returns `true` if node is inside class component's render block, `false` if not
|
|
1997
1996
|
*/
|
|
1998
1997
|
function isInsideRenderMethod(node) {
|
|
1999
|
-
return AST.findParentNode(node, (n) =>
|
|
1998
|
+
return AST.findParentNode(node, (n) => isRenderMethodLike(n) && isClassComponent(n.parent.parent)) != null;
|
|
2000
1999
|
}
|
|
2001
2000
|
/**
|
|
2002
2001
|
* Determines whether inside `createElement`'s props.
|
|
@@ -2005,7 +2004,7 @@ function isInsideRenderMethod(node) {
|
|
|
2005
2004
|
* @returns `true` if the node is inside createElement's props
|
|
2006
2005
|
*/
|
|
2007
2006
|
function isInsideCreateElementProps(context, node) {
|
|
2008
|
-
const call = AST.findParentNode(node,
|
|
2007
|
+
const call = AST.findParentNode(node, isCreateElementCall(context));
|
|
2009
2008
|
if (call == null) return false;
|
|
2010
2009
|
const prop = AST.findParentNode(node, AST.is(AST_NODE_TYPES.ObjectExpression));
|
|
2011
2010
|
if (prop == null) return false;
|
|
@@ -2031,15 +2030,15 @@ var no_nested_lazy_component_declarations_default = createRule({
|
|
|
2031
2030
|
defaultOptions: []
|
|
2032
2031
|
});
|
|
2033
2032
|
function create$25(context) {
|
|
2034
|
-
const hint =
|
|
2035
|
-
const collector =
|
|
2036
|
-
const collectorLegacy =
|
|
2033
|
+
const hint = ComponentDetectionHint.None;
|
|
2034
|
+
const collector = useComponentCollector(context, { hint });
|
|
2035
|
+
const collectorLegacy = useComponentCollectorLegacy();
|
|
2037
2036
|
const lazyComponentDeclarations = /* @__PURE__ */ new Set();
|
|
2038
2037
|
return {
|
|
2039
2038
|
...collector.listeners,
|
|
2040
2039
|
...collectorLegacy.listeners,
|
|
2041
2040
|
ImportExpression(node) {
|
|
2042
|
-
const lazyCall = AST.findParentNode(node, (n) =>
|
|
2041
|
+
const lazyCall = AST.findParentNode(node, (n) => isLazyCall(context, n));
|
|
2043
2042
|
if (lazyCall != null) lazyComponentDeclarations.add(lazyCall);
|
|
2044
2043
|
},
|
|
2045
2044
|
"Program:exit"(program) {
|
|
@@ -2047,7 +2046,7 @@ function create$25(context) {
|
|
|
2047
2046
|
const classComponents = [...collectorLegacy.ctx.getAllComponents(program).values()];
|
|
2048
2047
|
for (const lazy of lazyComponentDeclarations) if (AST.findParentNode(lazy, (n) => {
|
|
2049
2048
|
if (AST.isJSX(n)) return true;
|
|
2050
|
-
if (n.type === AST_NODE_TYPES.CallExpression) return
|
|
2049
|
+
if (n.type === AST_NODE_TYPES.CallExpression) return isReactHookCall(n) || isCreateElementCall(context, n) || isCreateContextCall(context, n);
|
|
2051
2050
|
if (AST.isFunction(n)) return functionComponents.some((c) => c.node === n);
|
|
2052
2051
|
if (AST.isClass(n)) return classComponents.some((c) => c.node === n);
|
|
2053
2052
|
return false;
|
|
@@ -2085,16 +2084,16 @@ function create$24(context) {
|
|
|
2085
2084
|
const { object, property } = node.left;
|
|
2086
2085
|
if (object.type !== AST_NODE_TYPES.Identifier) return;
|
|
2087
2086
|
if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "propTypes") return;
|
|
2088
|
-
if (!
|
|
2089
|
-
const variable =
|
|
2090
|
-
const variableNode =
|
|
2091
|
-
if (variableNode != null && (AST.isFunction(variableNode) ||
|
|
2087
|
+
if (!isComponentNameLoose(object.name)) return;
|
|
2088
|
+
const variable = findVariable(object.name, context.sourceCode.getScope(node));
|
|
2089
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
2090
|
+
if (variableNode != null && (AST.isFunction(variableNode) || isClassComponent(variableNode))) context.report({
|
|
2092
2091
|
messageId: "noPropTypes",
|
|
2093
2092
|
node: property
|
|
2094
2093
|
});
|
|
2095
2094
|
},
|
|
2096
2095
|
PropertyDefinition(node) {
|
|
2097
|
-
if (!
|
|
2096
|
+
if (!isClassComponent(node.parent.parent)) return;
|
|
2098
2097
|
if (!node.static || node.key.type !== AST_NODE_TYPES.Identifier || node.key.name !== "propTypes") return;
|
|
2099
2098
|
context.report({
|
|
2100
2099
|
messageId: "noPropTypes",
|
|
@@ -2127,13 +2126,13 @@ var no_redundant_should_component_update_default = createRule({
|
|
|
2127
2126
|
});
|
|
2128
2127
|
function create$23(context) {
|
|
2129
2128
|
if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
|
|
2130
|
-
const { ctx, listeners } =
|
|
2129
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
2131
2130
|
return {
|
|
2132
2131
|
...listeners,
|
|
2133
2132
|
"Program:exit"(program) {
|
|
2134
2133
|
const components = ctx.getAllComponents(program);
|
|
2135
2134
|
for (const { name: name$4 = "PureComponent", node: component, flag } of components.values()) {
|
|
2136
|
-
if ((flag &
|
|
2135
|
+
if ((flag & ComponentFlag.PureComponent) === 0n) continue;
|
|
2137
2136
|
const { body } = component.body;
|
|
2138
2137
|
for (const member of body) if (isShouldComponentUpdate(member)) context.report({
|
|
2139
2138
|
messageId: "noRedundantShouldComponentUpdate",
|
|
@@ -2166,9 +2165,9 @@ var no_set_state_in_component_did_mount_default = createRule({
|
|
|
2166
2165
|
function create$22(context) {
|
|
2167
2166
|
if (!context.sourceCode.text.includes("componentDidMount")) return {};
|
|
2168
2167
|
return { CallExpression(node) {
|
|
2169
|
-
if (!
|
|
2170
|
-
const clazz = AST.findParentNode(node,
|
|
2171
|
-
const method = AST.findParentNode(node, (n) => n === clazz ||
|
|
2168
|
+
if (!isThisSetState(node)) return;
|
|
2169
|
+
const clazz = AST.findParentNode(node, isClassComponent);
|
|
2170
|
+
const method = AST.findParentNode(node, (n) => n === clazz || isComponentDidMount(n));
|
|
2172
2171
|
if (clazz == null || method == null || method === clazz) return;
|
|
2173
2172
|
const methodScope = context.sourceCode.getScope(method);
|
|
2174
2173
|
const upperScope = context.sourceCode.getScope(node).upper;
|
|
@@ -2200,9 +2199,9 @@ var no_set_state_in_component_did_update_default = createRule({
|
|
|
2200
2199
|
function create$21(context) {
|
|
2201
2200
|
if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
|
|
2202
2201
|
return { CallExpression(node) {
|
|
2203
|
-
if (!
|
|
2204
|
-
const clazz = AST.findParentNode(node,
|
|
2205
|
-
const method = AST.findParentNode(node, (n) => n === clazz ||
|
|
2202
|
+
if (!isThisSetState(node)) return;
|
|
2203
|
+
const clazz = AST.findParentNode(node, isClassComponent);
|
|
2204
|
+
const method = AST.findParentNode(node, (n) => n === clazz || isComponentDidUpdate(n));
|
|
2206
2205
|
if (clazz == null || method == null || method === clazz) return;
|
|
2207
2206
|
const methodScope = context.sourceCode.getScope(method);
|
|
2208
2207
|
const upperScope = context.sourceCode.getScope(node).upper;
|
|
@@ -2234,9 +2233,9 @@ var no_set_state_in_component_will_update_default = createRule({
|
|
|
2234
2233
|
function create$20(context) {
|
|
2235
2234
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
2236
2235
|
return { CallExpression(node) {
|
|
2237
|
-
if (!
|
|
2238
|
-
const clazz = AST.findParentNode(node,
|
|
2239
|
-
const method = AST.findParentNode(node, (n) => n === clazz ||
|
|
2236
|
+
if (!isThisSetState(node)) return;
|
|
2237
|
+
const clazz = AST.findParentNode(node, isClassComponent);
|
|
2238
|
+
const method = AST.findParentNode(node, (n) => n === clazz || isComponentWillUpdate(n));
|
|
2240
2239
|
if (clazz == null || method == null || method === clazz) return;
|
|
2241
2240
|
const methodScope = context.sourceCode.getScope(method);
|
|
2242
2241
|
const upperScope = context.sourceCode.getScope(node).upper;
|
|
@@ -2269,7 +2268,7 @@ var no_string_refs_default = createRule({
|
|
|
2269
2268
|
function create$19(context) {
|
|
2270
2269
|
const state = { isWithinClassComponent: false };
|
|
2271
2270
|
function onClassBodyEnter(node) {
|
|
2272
|
-
if (
|
|
2271
|
+
if (isClassComponent(node.parent)) state.isWithinClassComponent = true;
|
|
2273
2272
|
}
|
|
2274
2273
|
function onClassBodyExit() {
|
|
2275
2274
|
state.isWithinClassComponent = false;
|
|
@@ -2367,15 +2366,15 @@ var no_unnecessary_use_callback_default = createRule({
|
|
|
2367
2366
|
function create$17(context) {
|
|
2368
2367
|
if (!context.sourceCode.text.includes("useCallback")) return {};
|
|
2369
2368
|
return { CallExpression(node) {
|
|
2370
|
-
if (!
|
|
2369
|
+
if (!isUseCallbackCall(node)) return;
|
|
2371
2370
|
const initialScope = context.sourceCode.getScope(node);
|
|
2372
2371
|
const component = context.sourceCode.getScope(node).block;
|
|
2373
2372
|
if (!AST.isFunction(component)) return;
|
|
2374
2373
|
const [arg0, arg1] = node.arguments;
|
|
2375
2374
|
if (arg0 == null || arg1 == null) return;
|
|
2376
2375
|
if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2377
|
-
const variable =
|
|
2378
|
-
const variableNode =
|
|
2376
|
+
const variable = findVariable(n.name, initialScope);
|
|
2377
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
2379
2378
|
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
|
|
2380
2379
|
return variableNode.elements.length === 0;
|
|
2381
2380
|
}).otherwise(() => false)) return;
|
|
@@ -2383,14 +2382,14 @@ function create$17(context) {
|
|
|
2383
2382
|
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
|
|
2384
2383
|
return n;
|
|
2385
2384
|
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2386
|
-
const variable =
|
|
2387
|
-
const variableNode =
|
|
2385
|
+
const variable = findVariable(n.name, initialScope);
|
|
2386
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
2388
2387
|
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
|
|
2389
2388
|
return variableNode;
|
|
2390
2389
|
}).otherwise(() => null);
|
|
2391
2390
|
if (arg0Node == null) return;
|
|
2392
2391
|
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
2393
|
-
if (!
|
|
2392
|
+
if (!getChildScopes(arg0NodeScope).flatMap((x) => x.references).some((x) => x.resolved?.scope.block === component)) context.report({
|
|
2394
2393
|
messageId: "noUnnecessaryUseCallback",
|
|
2395
2394
|
node
|
|
2396
2395
|
});
|
|
@@ -2419,15 +2418,15 @@ function create$16(context) {
|
|
|
2419
2418
|
if (!context.sourceCode.text.includes("useMemo")) return {};
|
|
2420
2419
|
return { CallExpression(node) {
|
|
2421
2420
|
const initialScope = context.sourceCode.getScope(node);
|
|
2422
|
-
if (!
|
|
2421
|
+
if (!isUseMemoCall(node)) return;
|
|
2423
2422
|
const component = context.sourceCode.getScope(node).block;
|
|
2424
2423
|
if (!AST.isFunction(component)) return;
|
|
2425
2424
|
const [arg0, arg1] = node.arguments;
|
|
2426
2425
|
if (arg0 == null || arg1 == null) return;
|
|
2427
2426
|
if (AST.isFunction(arg0) && [...AST.getNestedCallExpressions(arg0.body), ...AST.getNestedNewExpressions(arg0.body)].length > 0) return;
|
|
2428
2427
|
if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2429
|
-
const variable =
|
|
2430
|
-
const variableNode =
|
|
2428
|
+
const variable = findVariable(n.name, initialScope);
|
|
2429
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
2431
2430
|
if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
|
|
2432
2431
|
return variableNode.elements.length === 0;
|
|
2433
2432
|
}).otherwise(() => false)) return;
|
|
@@ -2435,14 +2434,14 @@ function create$16(context) {
|
|
|
2435
2434
|
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
|
|
2436
2435
|
return n;
|
|
2437
2436
|
}).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
2438
|
-
const variable =
|
|
2439
|
-
const variableNode =
|
|
2437
|
+
const variable = findVariable(n.name, initialScope);
|
|
2438
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
2440
2439
|
if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
|
|
2441
2440
|
return variableNode;
|
|
2442
2441
|
}).otherwise(() => null);
|
|
2443
2442
|
if (arg0Node == null) return;
|
|
2444
2443
|
const arg0NodeScope = context.sourceCode.getScope(arg0Node);
|
|
2445
|
-
if (!
|
|
2444
|
+
if (!getChildScopes(arg0NodeScope).flatMap((x) => x.references).some((x) => x.resolved?.scope.block === component)) context.report({
|
|
2446
2445
|
messageId: "noUnnecessaryUseMemo",
|
|
2447
2446
|
node
|
|
2448
2447
|
});
|
|
@@ -2472,7 +2471,7 @@ var no_unnecessary_use_prefix_default = createRule({
|
|
|
2472
2471
|
defaultOptions: []
|
|
2473
2472
|
});
|
|
2474
2473
|
function create$15(context) {
|
|
2475
|
-
const { ctx, listeners } =
|
|
2474
|
+
const { ctx, listeners } = useHookCollector();
|
|
2476
2475
|
return {
|
|
2477
2476
|
...listeners,
|
|
2478
2477
|
"Program:exit"(program) {
|
|
@@ -2513,14 +2512,14 @@ var no_unsafe_component_will_mount_default = createRule({
|
|
|
2513
2512
|
});
|
|
2514
2513
|
function create$14(context) {
|
|
2515
2514
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
|
|
2516
|
-
const { ctx, listeners } =
|
|
2515
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
2517
2516
|
return {
|
|
2518
2517
|
...listeners,
|
|
2519
2518
|
"Program:exit"(program) {
|
|
2520
2519
|
const components = ctx.getAllComponents(program);
|
|
2521
2520
|
for (const { node: component } of components.values()) {
|
|
2522
2521
|
const { body } = component.body;
|
|
2523
|
-
for (const member of body) if (
|
|
2522
|
+
for (const member of body) if (isUnsafeComponentWillMount(member)) context.report({
|
|
2524
2523
|
messageId: "noUnsafeComponentWillMount",
|
|
2525
2524
|
node: member
|
|
2526
2525
|
});
|
|
@@ -2549,14 +2548,14 @@ var no_unsafe_component_will_receive_props_default = createRule({
|
|
|
2549
2548
|
});
|
|
2550
2549
|
function create$13(context) {
|
|
2551
2550
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
|
|
2552
|
-
const { ctx, listeners } =
|
|
2551
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
2553
2552
|
return {
|
|
2554
2553
|
...listeners,
|
|
2555
2554
|
"Program:exit"(program) {
|
|
2556
2555
|
const components = ctx.getAllComponents(program);
|
|
2557
2556
|
for (const { node: component } of components.values()) {
|
|
2558
2557
|
const { body } = component.body;
|
|
2559
|
-
for (const member of body) if (
|
|
2558
|
+
for (const member of body) if (isUnsafeComponentWillReceiveProps(member)) context.report({
|
|
2560
2559
|
messageId: "noUnsafeComponentWillReceiveProps",
|
|
2561
2560
|
node: member
|
|
2562
2561
|
});
|
|
@@ -2585,14 +2584,14 @@ var no_unsafe_component_will_update_default = createRule({
|
|
|
2585
2584
|
});
|
|
2586
2585
|
function create$12(context) {
|
|
2587
2586
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
|
|
2588
|
-
const { ctx, listeners } =
|
|
2587
|
+
const { ctx, listeners } = useComponentCollectorLegacy();
|
|
2589
2588
|
return {
|
|
2590
2589
|
...listeners,
|
|
2591
2590
|
"Program:exit"(program) {
|
|
2592
2591
|
const components = ctx.getAllComponents(program);
|
|
2593
2592
|
for (const { node: component } of components.values()) {
|
|
2594
2593
|
const { body } = component.body;
|
|
2595
|
-
for (const member of body) if (
|
|
2594
|
+
for (const member of body) if (isUnsafeComponentWillUpdate(member)) context.report({
|
|
2596
2595
|
messageId: "noUnsafeComponentWillUpdate",
|
|
2597
2596
|
node: member
|
|
2598
2597
|
});
|
|
@@ -2622,12 +2621,12 @@ var no_unstable_context_value_default = createRule({
|
|
|
2622
2621
|
function create$11(context) {
|
|
2623
2622
|
const { version: version$1 } = getSettingsFromContext(context);
|
|
2624
2623
|
const isReact18OrBelow = compare(version$1, "19.0.0", "<");
|
|
2625
|
-
const { ctx, listeners } =
|
|
2624
|
+
const { ctx, listeners } = useComponentCollector(context);
|
|
2626
2625
|
const constructions = /* @__PURE__ */ new WeakMap();
|
|
2627
2626
|
return {
|
|
2628
2627
|
...listeners,
|
|
2629
2628
|
JSXOpeningElement(node) {
|
|
2630
|
-
const selfName =
|
|
2629
|
+
const selfName = getElementType(context, node.parent).split(".").at(-1);
|
|
2631
2630
|
if (selfName == null) return;
|
|
2632
2631
|
if (!isContextName(selfName, isReact18OrBelow)) return;
|
|
2633
2632
|
const functionEntry = ctx.getCurrentEntry();
|
|
@@ -2638,9 +2637,9 @@ function create$11(context) {
|
|
|
2638
2637
|
if (value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
|
|
2639
2638
|
const valueExpression = value.expression;
|
|
2640
2639
|
const initialScope = context.sourceCode.getScope(valueExpression);
|
|
2641
|
-
const construction =
|
|
2640
|
+
const construction = getConstruction(valueExpression, initialScope);
|
|
2642
2641
|
if (construction == null) return;
|
|
2643
|
-
if (
|
|
2642
|
+
if (isReactHookCall(construction.node)) return;
|
|
2644
2643
|
getOrElseUpdate(constructions, functionEntry.node, () => []).push(construction);
|
|
2645
2644
|
},
|
|
2646
2645
|
"Program:exit"(program) {
|
|
@@ -2685,7 +2684,7 @@ var no_unstable_default_props_default = createRule({
|
|
|
2685
2684
|
defaultOptions: []
|
|
2686
2685
|
});
|
|
2687
2686
|
function create$10(context) {
|
|
2688
|
-
const { ctx, listeners } =
|
|
2687
|
+
const { ctx, listeners } = useComponentCollector(context);
|
|
2689
2688
|
const declarators = /* @__PURE__ */ new WeakMap();
|
|
2690
2689
|
return {
|
|
2691
2690
|
...listeners,
|
|
@@ -2708,9 +2707,9 @@ function create$10(context) {
|
|
|
2708
2707
|
const { value } = prop;
|
|
2709
2708
|
const { right } = value;
|
|
2710
2709
|
const initialScope = context.sourceCode.getScope(value);
|
|
2711
|
-
const construction =
|
|
2710
|
+
const construction = getConstruction(value, initialScope, ConstructionDetectionHint.StrictCallExpression);
|
|
2712
2711
|
if (construction == null) continue;
|
|
2713
|
-
if (
|
|
2712
|
+
if (isReactHookCall(construction.node)) continue;
|
|
2714
2713
|
const forbiddenType = AST.toDelimiterFormat(right);
|
|
2715
2714
|
context.report({
|
|
2716
2715
|
messageId: "noUnstableDefaultProps",
|
|
@@ -2771,13 +2770,13 @@ function create$9(context) {
|
|
|
2771
2770
|
const propertyUsages = /* @__PURE__ */ new WeakMap();
|
|
2772
2771
|
function classEnter(node) {
|
|
2773
2772
|
classEntries.push(node);
|
|
2774
|
-
if (!
|
|
2773
|
+
if (!isClassComponent(node)) return;
|
|
2775
2774
|
propertyDefs.set(node, /* @__PURE__ */ new Set());
|
|
2776
2775
|
propertyUsages.set(node, /* @__PURE__ */ new Set());
|
|
2777
2776
|
}
|
|
2778
2777
|
function classExit() {
|
|
2779
2778
|
const currentClass = classEntries.pop();
|
|
2780
|
-
if (currentClass == null || !
|
|
2779
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2781
2780
|
const className = AST.getClassId(currentClass)?.name;
|
|
2782
2781
|
const defs = propertyDefs.get(currentClass);
|
|
2783
2782
|
const usages = propertyUsages.get(currentClass);
|
|
@@ -2799,7 +2798,7 @@ function create$9(context) {
|
|
|
2799
2798
|
function methodEnter(node) {
|
|
2800
2799
|
methodEntries.push(node);
|
|
2801
2800
|
const currentClass = classEntries.at(-1);
|
|
2802
|
-
if (currentClass == null || !
|
|
2801
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2803
2802
|
if (node.static) return;
|
|
2804
2803
|
if (isKeyLiteral$1(node, node.key)) propertyDefs.get(currentClass)?.add(node.key);
|
|
2805
2804
|
}
|
|
@@ -2815,7 +2814,7 @@ function create$9(context) {
|
|
|
2815
2814
|
const currentClass = classEntries.at(-1);
|
|
2816
2815
|
const currentMethod = methodEntries.at(-1);
|
|
2817
2816
|
if (currentClass == null || currentMethod == null) return;
|
|
2818
|
-
if (!
|
|
2817
|
+
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2819
2818
|
if (!AST.isThisExpression(node.object) || !isKeyLiteral$1(node, node.property)) return;
|
|
2820
2819
|
if (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.left === node) {
|
|
2821
2820
|
propertyDefs.get(currentClass)?.add(node.property);
|
|
@@ -2832,7 +2831,7 @@ function create$9(context) {
|
|
|
2832
2831
|
const currentClass = classEntries.at(-1);
|
|
2833
2832
|
const currentMethod = methodEntries.at(-1);
|
|
2834
2833
|
if (currentClass == null || currentMethod == null) return;
|
|
2835
|
-
if (!
|
|
2834
|
+
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2836
2835
|
if (node.init != null && AST.isThisExpression(node.init) && node.id.type === AST_NODE_TYPES.ObjectPattern) {
|
|
2837
2836
|
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral$1(prop, prop.key)) {
|
|
2838
2837
|
const keyName = AST.getPropertyName(prop.key);
|
|
@@ -2863,7 +2862,7 @@ var no_unused_props_default = createRule({
|
|
|
2863
2862
|
});
|
|
2864
2863
|
function create$8(context) {
|
|
2865
2864
|
const services = ESLintUtils.getParserServices(context, false);
|
|
2866
|
-
const { ctx, listeners } =
|
|
2865
|
+
const { ctx, listeners } = useComponentCollector(context);
|
|
2867
2866
|
return {
|
|
2868
2867
|
...listeners,
|
|
2869
2868
|
"Program:exit"(program) {
|
|
@@ -2995,7 +2994,7 @@ function create$7(context) {
|
|
|
2995
2994
|
}
|
|
2996
2995
|
function classExit() {
|
|
2997
2996
|
const currentClass = classEntries.pop();
|
|
2998
|
-
if (currentClass == null || !
|
|
2997
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2999
2998
|
const className = AST.getClassId(currentClass)?.name;
|
|
3000
2999
|
const { node: defNode, isUsed = false } = stateDefs.get(currentClass) ?? {};
|
|
3001
3000
|
if (defNode == null || isUsed) return;
|
|
@@ -3008,9 +3007,9 @@ function create$7(context) {
|
|
|
3008
3007
|
function methodEnter(node) {
|
|
3009
3008
|
methodEntries.push(node);
|
|
3010
3009
|
const currentClass = classEntries.at(-1);
|
|
3011
|
-
if (currentClass == null || !
|
|
3010
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
3012
3011
|
if (node.static) {
|
|
3013
|
-
if (
|
|
3012
|
+
if (isGetDerivedStateFromProps(node) && isMatching({ params: [P.nonNullable, ...P.array()] })(node.value)) {
|
|
3014
3013
|
const defNode = stateDefs.get(currentClass)?.node;
|
|
3015
3014
|
stateDefs.set(currentClass, {
|
|
3016
3015
|
node: defNode,
|
|
@@ -3035,9 +3034,9 @@ function create$7(context) {
|
|
|
3035
3034
|
}
|
|
3036
3035
|
return {
|
|
3037
3036
|
AssignmentExpression(node) {
|
|
3038
|
-
if (!
|
|
3037
|
+
if (!isAssignmentToThisState(node)) return;
|
|
3039
3038
|
const currentClass = classEntries.at(-1);
|
|
3040
|
-
if (currentClass == null || !
|
|
3039
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
3041
3040
|
const currentConstructor = constructorEntries.at(-1);
|
|
3042
3041
|
if (currentConstructor == null || !currentClass.body.body.includes(currentConstructor)) return;
|
|
3043
3042
|
const isUsed = stateDefs.get(currentClass)?.isUsed ?? false;
|
|
@@ -3054,7 +3053,7 @@ function create$7(context) {
|
|
|
3054
3053
|
if (!AST.isThisExpression(node.object)) return;
|
|
3055
3054
|
if (AST.getPropertyName(node.property) !== "state") return;
|
|
3056
3055
|
const currentClass = classEntries.at(-1);
|
|
3057
|
-
if (currentClass == null || !
|
|
3056
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
3058
3057
|
const currentMethod = methodEntries.at(-1);
|
|
3059
3058
|
if (currentMethod == null || currentMethod.static) return;
|
|
3060
3059
|
if (currentMethod === constructorEntries.at(-1)) return;
|
|
@@ -3073,7 +3072,7 @@ function create$7(context) {
|
|
|
3073
3072
|
"PropertyDefinition:exit": methodExit,
|
|
3074
3073
|
VariableDeclarator(node) {
|
|
3075
3074
|
const currentClass = classEntries.at(-1);
|
|
3076
|
-
if (currentClass == null || !
|
|
3075
|
+
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
3077
3076
|
const currentMethod = methodEntries.at(-1);
|
|
3078
3077
|
if (currentMethod == null || currentMethod.static) return;
|
|
3079
3078
|
if (currentMethod === constructorEntries.at(-1)) return;
|
|
@@ -3118,7 +3117,7 @@ function create$6(context) {
|
|
|
3118
3117
|
const hookCalls = /* @__PURE__ */ new Set();
|
|
3119
3118
|
return {
|
|
3120
3119
|
CallExpression(node) {
|
|
3121
|
-
if (!
|
|
3120
|
+
if (!isReactHookCall(node)) return;
|
|
3122
3121
|
hookCalls.add(node);
|
|
3123
3122
|
},
|
|
3124
3123
|
ImportDeclaration(node) {
|
|
@@ -3149,7 +3148,7 @@ function create$6(context) {
|
|
|
3149
3148
|
},
|
|
3150
3149
|
"Program:exit"() {
|
|
3151
3150
|
for (const node of hookCalls) {
|
|
3152
|
-
if (!
|
|
3151
|
+
if (!isUseContextCall(node)) continue;
|
|
3153
3152
|
context.report({
|
|
3154
3153
|
messageId: "noUseContext",
|
|
3155
3154
|
node: node.callee,
|
|
@@ -3194,7 +3193,7 @@ var no_useless_forward_ref_default = createRule({
|
|
|
3194
3193
|
});
|
|
3195
3194
|
function create$5(context) {
|
|
3196
3195
|
return { CallExpression(node) {
|
|
3197
|
-
if (!
|
|
3196
|
+
if (!isForwardRefCall(context, node)) return;
|
|
3198
3197
|
const [component] = node.arguments;
|
|
3199
3198
|
if (component == null || !AST.isFunction(component)) return;
|
|
3200
3199
|
if (component.params[1] != null) return;
|
|
@@ -3233,7 +3232,7 @@ function create$4(context, [option]) {
|
|
|
3233
3232
|
const { allowExpressions = true } = option;
|
|
3234
3233
|
return {
|
|
3235
3234
|
JSXElement(node) {
|
|
3236
|
-
if (!
|
|
3235
|
+
if (!isFragmentElement(context, node)) return;
|
|
3237
3236
|
checkNode(context, node, allowExpressions);
|
|
3238
3237
|
},
|
|
3239
3238
|
JSXFragment(node) {
|
|
@@ -3251,7 +3250,7 @@ function isWhiteSpace(node) {
|
|
|
3251
3250
|
* Check if a node is padding spaces (whitespace with line breaks)
|
|
3252
3251
|
*/
|
|
3253
3252
|
function isPaddingSpaces(node) {
|
|
3254
|
-
return
|
|
3253
|
+
return isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n");
|
|
3255
3254
|
}
|
|
3256
3255
|
/**
|
|
3257
3256
|
* Trim whitespace like React would in JSX
|
|
@@ -3268,8 +3267,8 @@ function trimLikeReact(text) {
|
|
|
3268
3267
|
*/
|
|
3269
3268
|
function checkNode(context, node, allowExpressions) {
|
|
3270
3269
|
const initialScope = context.sourceCode.getScope(node);
|
|
3271
|
-
if (node.type === AST_NODE_TYPES.JSXElement &&
|
|
3272
|
-
if (
|
|
3270
|
+
if (node.type === AST_NODE_TYPES.JSXElement && hasAttribute(context, "key", node.openingElement.attributes, initialScope)) return;
|
|
3271
|
+
if (isHostElement(context, node.parent)) context.report({
|
|
3273
3272
|
messageId: "uselessFragment",
|
|
3274
3273
|
node,
|
|
3275
3274
|
data: { reason: "placed inside a host component" },
|
|
@@ -3286,7 +3285,7 @@ function checkNode(context, node, allowExpressions) {
|
|
|
3286
3285
|
}
|
|
3287
3286
|
const isChildElement = AST.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent);
|
|
3288
3287
|
switch (true) {
|
|
3289
|
-
case allowExpressions && !isChildElement && node.children.length === 1 &&
|
|
3288
|
+
case allowExpressions && !isChildElement && node.children.length === 1 && isJsxText(node.children.at(0)): return;
|
|
3290
3289
|
case !allowExpressions && isChildElement:
|
|
3291
3290
|
context.report({
|
|
3292
3291
|
messageId: "uselessFragment",
|
|
@@ -3329,9 +3328,9 @@ function getFix(context, node) {
|
|
|
3329
3328
|
* Check if it's safe to automatically fix the fragment
|
|
3330
3329
|
*/
|
|
3331
3330
|
function canFix(context, node) {
|
|
3332
|
-
if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return
|
|
3331
|
+
if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return isHostElement(context, node.parent);
|
|
3333
3332
|
if (node.children.length === 0) return false;
|
|
3334
|
-
return !node.children.some((child) =>
|
|
3333
|
+
return !node.children.some((child) => isJsxText(child) && !isWhiteSpace(child) || AST.is(AST_NODE_TYPES.JSXExpressionContainer)(child));
|
|
3335
3334
|
}
|
|
3336
3335
|
|
|
3337
3336
|
//#endregion
|
|
@@ -3356,7 +3355,7 @@ var prefer_destructuring_assignment_default = createRule({
|
|
|
3356
3355
|
defaultOptions: []
|
|
3357
3356
|
});
|
|
3358
3357
|
function create$3(context) {
|
|
3359
|
-
const { ctx, listeners } =
|
|
3358
|
+
const { ctx, listeners } = useComponentCollector(context);
|
|
3360
3359
|
const memberExpressionWithNames = [];
|
|
3361
3360
|
return {
|
|
3362
3361
|
...listeners,
|
|
@@ -3371,7 +3370,7 @@ function create$3(context) {
|
|
|
3371
3370
|
function isFunctionComponent(block) {
|
|
3372
3371
|
if (!AST.isFunction(block)) return false;
|
|
3373
3372
|
const id = AST.getFunctionId(block);
|
|
3374
|
-
return id != null &&
|
|
3373
|
+
return id != null && isComponentNameLoose(id.name) && components.some((component) => component.node === block);
|
|
3375
3374
|
}
|
|
3376
3375
|
for (const [initialScope, memberExpression] of memberExpressionWithNames) {
|
|
3377
3376
|
let scope = initialScope;
|
|
@@ -3461,7 +3460,7 @@ var prefer_read_only_props_default = createRule({
|
|
|
3461
3460
|
});
|
|
3462
3461
|
function create$1(context) {
|
|
3463
3462
|
const services = ESLintUtils.getParserServices(context, false);
|
|
3464
|
-
const { ctx, listeners } =
|
|
3463
|
+
const { ctx, listeners } = useComponentCollector(context);
|
|
3465
3464
|
return {
|
|
3466
3465
|
...listeners,
|
|
3467
3466
|
"Program:exit"(program) {
|
|
@@ -3516,13 +3515,13 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
3516
3515
|
});
|
|
3517
3516
|
function create(context) {
|
|
3518
3517
|
return { CallExpression(node) {
|
|
3519
|
-
if (!
|
|
3518
|
+
if (!isUseStateCall(node)) return;
|
|
3520
3519
|
const [useStateInput] = node.arguments;
|
|
3521
3520
|
if (useStateInput == null) return;
|
|
3522
3521
|
for (const expr of AST.getNestedNewExpressions(useStateInput)) {
|
|
3523
3522
|
if (!("name" in expr.callee)) continue;
|
|
3524
3523
|
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3525
|
-
if (AST.findParentNode(expr,
|
|
3524
|
+
if (AST.findParentNode(expr, isUseCall) != null) continue;
|
|
3526
3525
|
context.report({
|
|
3527
3526
|
messageId: "preferUseStateLazyInitialization",
|
|
3528
3527
|
node: expr
|
|
@@ -3530,9 +3529,9 @@ function create(context) {
|
|
|
3530
3529
|
}
|
|
3531
3530
|
for (const expr of AST.getNestedCallExpressions(useStateInput)) {
|
|
3532
3531
|
if (!("name" in expr.callee)) continue;
|
|
3533
|
-
if (
|
|
3532
|
+
if (isReactHookName(expr.callee.name)) continue;
|
|
3534
3533
|
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3535
|
-
if (AST.findParentNode(expr,
|
|
3534
|
+
if (AST.findParentNode(expr, isUseCall) != null) continue;
|
|
3536
3535
|
context.report({
|
|
3537
3536
|
messageId: "preferUseStateLazyInitialization",
|
|
3538
3537
|
node: expr
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "2.0.1
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "A set of composable ESLint rules for for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"is-immutable-type": "^5.0.1",
|
|
43
43
|
"string-ts": "^2.2.1",
|
|
44
44
|
"ts-pattern": "^5.8.0",
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/
|
|
49
|
-
"@eslint-react/
|
|
50
|
-
"@eslint-react/
|
|
45
|
+
"@eslint-react/core": "2.0.1",
|
|
46
|
+
"@eslint-react/ast": "2.0.1",
|
|
47
|
+
"@eslint-react/eff": "2.0.1",
|
|
48
|
+
"@eslint-react/shared": "2.0.1",
|
|
49
|
+
"@eslint-react/kit": "2.0.1",
|
|
50
|
+
"@eslint-react/var": "2.0.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/react": "^19.1.14",
|