eslint-plugin-react-x 2.0.5-beta.2 → 2.0.5-beta.6
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 +83 -70
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { P, isMatching, match } from "ts-pattern";
|
|
|
6
6
|
import ts from "typescript";
|
|
7
7
|
import * as AST from "@eslint-react/ast";
|
|
8
8
|
import { ConstructionDetectionHint, findVariable, getChildScopes, getConstruction, getVariableDefinitionNode } from "@eslint-react/var";
|
|
9
|
-
import { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, JsxEmit, findParentJsxAttribute, getInstanceId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType,
|
|
9
|
+
import { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, JsxEmit, findParentJsxAttribute, getInstanceId, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, isAssignmentToThisState, isCaptureOwnerStackCall, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUpdate, isCreateContextCall, isCreateElementCall, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRefCall, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInstanceIdEqual, isJsxFragmentElement, isJsxHostElement, 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.5-beta.
|
|
118
|
+
var version = "2.0.5-beta.6";
|
|
119
119
|
|
|
120
120
|
//#endregion
|
|
121
121
|
//#region src/utils/create-rule.ts
|
|
@@ -208,10 +208,10 @@ var jsx_key_before_spread_default = createRule({
|
|
|
208
208
|
meta: {
|
|
209
209
|
type: "problem",
|
|
210
210
|
docs: {
|
|
211
|
-
description: "Enforces that the 'key'
|
|
211
|
+
description: "Enforces that the 'key' prop is placed before the spread prop in JSX elements.",
|
|
212
212
|
[Symbol.for("rule_features")]: RULE_FEATURES$59
|
|
213
213
|
},
|
|
214
|
-
messages: { jsxKeyBeforeSpread: "The 'key'
|
|
214
|
+
messages: { jsxKeyBeforeSpread: "The 'key' prop must be placed before any spread props." },
|
|
215
215
|
schema: []
|
|
216
216
|
},
|
|
217
217
|
name: RULE_NAME$61,
|
|
@@ -220,16 +220,16 @@ var jsx_key_before_spread_default = createRule({
|
|
|
220
220
|
});
|
|
221
221
|
function create$61(context) {
|
|
222
222
|
return { JSXOpeningElement(node) {
|
|
223
|
-
let
|
|
224
|
-
for (const [index,
|
|
225
|
-
if (
|
|
226
|
-
|
|
223
|
+
let firstSpreadPropIndex = null;
|
|
224
|
+
for (const [index, prop] of node.attributes.entries()) {
|
|
225
|
+
if (prop.type === AST_NODE_TYPES.JSXSpreadAttribute) {
|
|
226
|
+
firstSpreadPropIndex ??= index;
|
|
227
227
|
continue;
|
|
228
228
|
}
|
|
229
|
-
if (
|
|
230
|
-
if (
|
|
229
|
+
if (firstSpreadPropIndex == null) continue;
|
|
230
|
+
if (prop.name.name === "key" && index > firstSpreadPropIndex) context.report({
|
|
231
231
|
messageId: "jsxKeyBeforeSpread",
|
|
232
|
-
node:
|
|
232
|
+
node: prop
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
235
|
} };
|
|
@@ -262,7 +262,6 @@ function create$60(context) {
|
|
|
262
262
|
const visitorFunction = (node) => {
|
|
263
263
|
if (!AST.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent)) return;
|
|
264
264
|
if (!hasCommentLike(node)) return;
|
|
265
|
-
if (!node.parent.type.includes("JSX")) return;
|
|
266
265
|
context.report({
|
|
267
266
|
messageId: "jsxNoCommentTextnodes",
|
|
268
267
|
node
|
|
@@ -905,7 +904,7 @@ var no_children_prop_default = createRule({
|
|
|
905
904
|
});
|
|
906
905
|
function create$46(context) {
|
|
907
906
|
return { JSXElement(node) {
|
|
908
|
-
const childrenProp = getJsxAttribute(context, node
|
|
907
|
+
const childrenProp = getJsxAttribute(context, node)("children");
|
|
909
908
|
if (childrenProp != null) context.report({
|
|
910
909
|
messageId: "noChildrenProp",
|
|
911
910
|
node: childrenProp
|
|
@@ -1287,7 +1286,7 @@ var no_duplicate_key_default = createRule({
|
|
|
1287
1286
|
defaultOptions: []
|
|
1288
1287
|
});
|
|
1289
1288
|
function create$35(context) {
|
|
1290
|
-
if (!context.sourceCode.
|
|
1289
|
+
if (!context.sourceCode.text.includes("key=")) return {};
|
|
1291
1290
|
const keyedEntries = /* @__PURE__ */ new Map();
|
|
1292
1291
|
function isKeyValueEqual(a, b) {
|
|
1293
1292
|
const aValue = a.value;
|
|
@@ -1452,11 +1451,11 @@ function create$33(context) {
|
|
|
1452
1451
|
}
|
|
1453
1452
|
/**
|
|
1454
1453
|
* Determines whether the given CallExpression can be safely auto-fixed by replacing
|
|
1455
|
-
* the usage of `forwardRef` with passing `ref` as a prop
|
|
1454
|
+
* the usage of `forwardRef` with passing `ref` as a prop
|
|
1456
1455
|
*
|
|
1457
|
-
* @param context - The rule context object
|
|
1458
|
-
* @param node - The CallExpression node to check
|
|
1459
|
-
* @returns True if the call can be auto-fixed, false otherwise
|
|
1456
|
+
* @param context - The rule context object
|
|
1457
|
+
* @param node - The CallExpression node to check
|
|
1458
|
+
* @returns True if the call can be auto-fixed, false otherwise
|
|
1460
1459
|
*/
|
|
1461
1460
|
function canFix$1(context, node) {
|
|
1462
1461
|
const { importSource } = getSettingsFromContext(context);
|
|
@@ -1467,6 +1466,12 @@ function canFix$1(context, node) {
|
|
|
1467
1466
|
default: return false;
|
|
1468
1467
|
}
|
|
1469
1468
|
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Generates the fix for the `forwardRef` call
|
|
1471
|
+
* @param context - The rule context
|
|
1472
|
+
* @param node - The `forwardRef` call expression
|
|
1473
|
+
* @returns A fixer function that applies the changes
|
|
1474
|
+
*/
|
|
1470
1475
|
function getFix$1(context, node) {
|
|
1471
1476
|
return (fixer) => {
|
|
1472
1477
|
const [componentNode] = node.arguments;
|
|
@@ -1478,6 +1483,14 @@ function getFix$1(context, node) {
|
|
|
1478
1483
|
];
|
|
1479
1484
|
};
|
|
1480
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* Generates fixes for the component's props and ref arguments
|
|
1488
|
+
* @param context - The rule context
|
|
1489
|
+
* @param fixer - The rule fixer
|
|
1490
|
+
* @param node - The function component node
|
|
1491
|
+
* @param typeArguments - The type arguments from the `forwardRef` call
|
|
1492
|
+
* @returns An array of fixes for the component's signature
|
|
1493
|
+
*/
|
|
1481
1494
|
function getComponentPropsFixes(context, fixer, node, typeArguments) {
|
|
1482
1495
|
const getText = (node$1) => context.sourceCode.getText(node$1);
|
|
1483
1496
|
const [arg0, arg1] = node.params;
|
|
@@ -1534,8 +1547,7 @@ var no_implicit_key_default = createRule({
|
|
|
1534
1547
|
});
|
|
1535
1548
|
function create$32(context) {
|
|
1536
1549
|
return { JSXOpeningElement(node) {
|
|
1537
|
-
const
|
|
1538
|
-
const keyProp = getJsxAttribute(context, node.attributes, initialScope)("key");
|
|
1550
|
+
const keyProp = getJsxAttribute(context, node.parent)("key");
|
|
1539
1551
|
const isKeyPropOnElement = node.attributes.some((n) => n.type === AST_NODE_TYPES.JSXAttribute && n.name.type === AST_NODE_TYPES.JSXIdentifier && n.name.name === "key");
|
|
1540
1552
|
if (keyProp != null && !isKeyPropOnElement) context.report({
|
|
1541
1553
|
messageId: "noImplicitKey",
|
|
@@ -1578,6 +1590,11 @@ function create$31(context) {
|
|
|
1578
1590
|
...compare(version$1, "18.0.0", "<") ? [] : ["string", "falsy string"]
|
|
1579
1591
|
];
|
|
1580
1592
|
const services = ESLintUtils.getParserServices(context, false);
|
|
1593
|
+
/**
|
|
1594
|
+
* Recursively inspects a node to find potential leaked conditional rendering
|
|
1595
|
+
* @param node The AST node to inspect
|
|
1596
|
+
* @returns A report descriptor if a problem is found, otherwise `unit`
|
|
1597
|
+
*/
|
|
1581
1598
|
function getReportDescriptor(node) {
|
|
1582
1599
|
if (node == null) return unit;
|
|
1583
1600
|
if (AST.is(AST_NODE_TYPES.JSXExpressionContainer)(node)) return getReportDescriptor(node.expression);
|
|
@@ -1751,14 +1768,12 @@ function create$28(context) {
|
|
|
1751
1768
|
const state = { isWithinChildrenToArray: false };
|
|
1752
1769
|
function checkIteratorElement(node) {
|
|
1753
1770
|
switch (node.type) {
|
|
1754
|
-
case AST_NODE_TYPES.JSXElement:
|
|
1755
|
-
|
|
1756
|
-
if (!hasJsxAttribute(context, "key", node.openingElement.attributes, initialScope)) return {
|
|
1771
|
+
case AST_NODE_TYPES.JSXElement:
|
|
1772
|
+
if (getJsxAttribute(context, node)("key") == null) return {
|
|
1757
1773
|
messageId: "missingKey",
|
|
1758
1774
|
node
|
|
1759
1775
|
};
|
|
1760
1776
|
return null;
|
|
1761
|
-
}
|
|
1762
1777
|
case AST_NODE_TYPES.JSXFragment: return {
|
|
1763
1778
|
messageId: "unexpectedFragmentSyntax",
|
|
1764
1779
|
node
|
|
@@ -1794,7 +1809,7 @@ function create$28(context) {
|
|
|
1794
1809
|
const elements = node.elements.filter(AST.is(AST_NODE_TYPES.JSXElement));
|
|
1795
1810
|
if (elements.length === 0) return;
|
|
1796
1811
|
const initialScope = context.sourceCode.getScope(node);
|
|
1797
|
-
for (const element of elements) if (
|
|
1812
|
+
for (const element of elements) if (getJsxAttribute(context, element, initialScope)("key") == null) context.report({
|
|
1798
1813
|
messageId: "missingKey",
|
|
1799
1814
|
node: element
|
|
1800
1815
|
});
|
|
@@ -1838,8 +1853,8 @@ var no_misused_capture_owner_stack_default = createRule({
|
|
|
1838
1853
|
},
|
|
1839
1854
|
fixable: "code",
|
|
1840
1855
|
messages: {
|
|
1841
|
-
|
|
1842
|
-
|
|
1856
|
+
missingDevelopmentOnlyCheck: `Don't call 'captureOwnerStack' directly. Use 'if (process.env.NODE_ENV !== "production") {...}' to conditionally access it.`,
|
|
1857
|
+
useNamespaceImport: "Don't use named imports of 'captureOwnerStack' in files that are bundled for development and production. Use a namespace import instead."
|
|
1843
1858
|
},
|
|
1844
1859
|
schema: []
|
|
1845
1860
|
},
|
|
@@ -1980,28 +1995,19 @@ function isInsideJSXAttributeValue(node) {
|
|
|
1980
1995
|
return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentJsxAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
1981
1996
|
}
|
|
1982
1997
|
/**
|
|
1983
|
-
*
|
|
1984
|
-
*
|
|
1985
|
-
* class Component extends React.Component {
|
|
1986
|
-
* render() {
|
|
1987
|
-
* class NestedClassComponent extends React.Component {
|
|
1988
|
-
* render() { return <div />; }
|
|
1989
|
-
* }
|
|
1990
|
-
* const nestedFunctionComponent = () => <div />;
|
|
1991
|
-
* }
|
|
1992
|
-
* }
|
|
1993
|
-
* ```
|
|
1998
|
+
* Checks whether a given node is declared inside a class component's render block
|
|
1999
|
+
* Ex: class C extends React.Component { render() { const Nested = () => <div />; } }
|
|
1994
2000
|
* @param node The AST node being checked
|
|
1995
|
-
* @returns `true` if node is inside class component's render block
|
|
2001
|
+
* @returns `true` if the node is inside a class component's render block
|
|
1996
2002
|
*/
|
|
1997
2003
|
function isInsideRenderMethod(node) {
|
|
1998
2004
|
return AST.findParentNode(node, (n) => isRenderMethodLike(n) && isClassComponent(n.parent.parent)) != null;
|
|
1999
2005
|
}
|
|
2000
2006
|
/**
|
|
2001
|
-
* Determines whether inside `createElement`'s props
|
|
2007
|
+
* Determines whether the node is inside `createElement`'s props argument
|
|
2002
2008
|
* @param context The rule context
|
|
2003
2009
|
* @param node The AST node to check
|
|
2004
|
-
* @returns `true` if the node is inside createElement's props
|
|
2010
|
+
* @returns `true` if the node is inside `createElement`'s props
|
|
2005
2011
|
*/
|
|
2006
2012
|
function isInsideCreateElementProps(context, node) {
|
|
2007
2013
|
const call = AST.findParentNode(node, isCreateElementCall(context));
|
|
@@ -2166,12 +2172,12 @@ function create$22(context) {
|
|
|
2166
2172
|
if (!context.sourceCode.text.includes("componentDidMount")) return {};
|
|
2167
2173
|
return { CallExpression(node) {
|
|
2168
2174
|
if (!isThisSetState(node)) return;
|
|
2169
|
-
const
|
|
2170
|
-
const
|
|
2171
|
-
if (
|
|
2172
|
-
const
|
|
2173
|
-
const
|
|
2174
|
-
if (
|
|
2175
|
+
const enclosingClassNode = AST.findParentNode(node, isClassComponent);
|
|
2176
|
+
const enclosingMethodNode = AST.findParentNode(node, (n) => n === enclosingClassNode || isComponentDidMount(n));
|
|
2177
|
+
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
2178
|
+
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
2179
|
+
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
2180
|
+
if (enclosingMethodNode.parent === enclosingClassNode.body && setStateCallParentScope === enclosingMethodScope) context.report({
|
|
2175
2181
|
messageId: "noSetStateInComponentDidMount",
|
|
2176
2182
|
node
|
|
2177
2183
|
});
|
|
@@ -2200,12 +2206,12 @@ function create$21(context) {
|
|
|
2200
2206
|
if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
|
|
2201
2207
|
return { CallExpression(node) {
|
|
2202
2208
|
if (!isThisSetState(node)) return;
|
|
2203
|
-
const
|
|
2204
|
-
const
|
|
2205
|
-
if (
|
|
2206
|
-
const
|
|
2207
|
-
const
|
|
2208
|
-
if (
|
|
2209
|
+
const enclosingClassNode = AST.findParentNode(node, isClassComponent);
|
|
2210
|
+
const enclosingMethodNode = AST.findParentNode(node, (n) => n === enclosingClassNode || isComponentDidUpdate(n));
|
|
2211
|
+
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
2212
|
+
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
2213
|
+
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
2214
|
+
if (enclosingMethodNode.parent === enclosingClassNode.body && setStateCallParentScope === enclosingMethodScope) context.report({
|
|
2209
2215
|
messageId: "noSetStateInComponentDidUpdate",
|
|
2210
2216
|
node
|
|
2211
2217
|
});
|
|
@@ -2220,7 +2226,7 @@ var no_set_state_in_component_will_update_default = createRule({
|
|
|
2220
2226
|
meta: {
|
|
2221
2227
|
type: "problem",
|
|
2222
2228
|
docs: {
|
|
2223
|
-
description: "
|
|
2229
|
+
description: "Disallow calling `this.setState` in `componentWillUpdate` outside of functions, such as callbacks.",
|
|
2224
2230
|
[Symbol.for("rule_features")]: RULE_FEATURES$19
|
|
2225
2231
|
},
|
|
2226
2232
|
messages: { noSetStateInComponentWillUpdate: "Do not call `this.setState` in `componentWillUpdate` outside of functions, such as callbacks." },
|
|
@@ -2234,12 +2240,12 @@ function create$20(context) {
|
|
|
2234
2240
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
2235
2241
|
return { CallExpression(node) {
|
|
2236
2242
|
if (!isThisSetState(node)) return;
|
|
2237
|
-
const
|
|
2238
|
-
const
|
|
2239
|
-
if (
|
|
2240
|
-
const
|
|
2241
|
-
const
|
|
2242
|
-
if (
|
|
2243
|
+
const enclosingClassNode = AST.findParentNode(node, isClassComponent);
|
|
2244
|
+
const enclosingMethodNode = AST.findParentNode(node, (n) => n === enclosingClassNode || isComponentWillUpdate(n));
|
|
2245
|
+
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
2246
|
+
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
2247
|
+
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
2248
|
+
if (enclosingMethodNode.parent === enclosingClassNode.body && setStateCallParentScope === enclosingMethodScope) context.report({
|
|
2243
2249
|
messageId: "noSetStateInComponentWillUpdate",
|
|
2244
2250
|
node
|
|
2245
2251
|
});
|
|
@@ -2278,21 +2284,27 @@ function create$19(context) {
|
|
|
2278
2284
|
"ClassBody:exit": onClassBodyExit,
|
|
2279
2285
|
JSXAttribute(node) {
|
|
2280
2286
|
if (node.name.name !== "ref") return;
|
|
2281
|
-
const
|
|
2282
|
-
if (
|
|
2287
|
+
const refName = getJsxAttributeValueText(context, node.value);
|
|
2288
|
+
if (refName == null) return;
|
|
2283
2289
|
context.report({
|
|
2284
2290
|
messageId: "noStringRefs",
|
|
2285
2291
|
node,
|
|
2286
2292
|
fix(fixer) {
|
|
2287
2293
|
if (node.value == null) return null;
|
|
2288
2294
|
if (!state.isWithinClassComponent) return null;
|
|
2289
|
-
return fixer.replaceText(node.value, `{(ref) => { this.refs[${
|
|
2295
|
+
return fixer.replaceText(node.value, `{(ref) => { this.refs[${refName}] = ref; }}`);
|
|
2290
2296
|
}
|
|
2291
2297
|
});
|
|
2292
2298
|
}
|
|
2293
2299
|
};
|
|
2294
2300
|
}
|
|
2295
|
-
|
|
2301
|
+
/**
|
|
2302
|
+
* Extracts the text content from a JSX attribute's value
|
|
2303
|
+
* @param context - The rule context
|
|
2304
|
+
* @param node - The JSX attribute value node
|
|
2305
|
+
* @returns The text of the attribute value, or null if not a string-like value
|
|
2306
|
+
*/
|
|
2307
|
+
function getJsxAttributeValueText(context, node) {
|
|
2296
2308
|
if (node == null) return null;
|
|
2297
2309
|
switch (true) {
|
|
2298
2310
|
case node.type === AST_NODE_TYPES.Literal && typeof node.value === "string": return context.sourceCode.getText(node);
|
|
@@ -2339,6 +2351,11 @@ function create$18(context) {
|
|
|
2339
2351
|
});
|
|
2340
2352
|
} };
|
|
2341
2353
|
}
|
|
2354
|
+
/**
|
|
2355
|
+
* Checks if a node is a callback function passed to an array's `.map()` method
|
|
2356
|
+
* @param node The node to check
|
|
2357
|
+
* @returns `true` if the node is a map callback, `false` otherwise
|
|
2358
|
+
*/
|
|
2342
2359
|
function isMapCallback(node) {
|
|
2343
2360
|
if (node.parent == null) return false;
|
|
2344
2361
|
if (!AST.isArrayMapCall(node.parent)) return false;
|
|
@@ -2784,7 +2801,7 @@ function create$9(context) {
|
|
|
2784
2801
|
for (const def of defs) {
|
|
2785
2802
|
const methodName = AST.getPropertyName(def);
|
|
2786
2803
|
if (methodName == null) continue;
|
|
2787
|
-
if (usages?.has(methodName) || LIFECYCLE_METHODS.has(methodName)) continue;
|
|
2804
|
+
if ((usages?.has(methodName) ?? false) || LIFECYCLE_METHODS.has(methodName)) continue;
|
|
2788
2805
|
context.report({
|
|
2789
2806
|
messageId: "noUnusedClassComponentMembers",
|
|
2790
2807
|
node: def,
|
|
@@ -3266,8 +3283,7 @@ function trimLikeReact(text) {
|
|
|
3266
3283
|
* Check if a fragment node is useless and should be reported
|
|
3267
3284
|
*/
|
|
3268
3285
|
function checkNode(context, node, allowExpressions) {
|
|
3269
|
-
|
|
3270
|
-
if (node.type === AST_NODE_TYPES.JSXElement && hasJsxAttribute(context, "key", node.openingElement.attributes, initialScope)) return;
|
|
3286
|
+
if (node.type === AST_NODE_TYPES.JSXElement && getJsxAttribute(context, node)("key") != null) return;
|
|
3271
3287
|
if (isJsxHostElement(context, node.parent)) context.report({
|
|
3272
3288
|
messageId: "uselessFragment",
|
|
3273
3289
|
node,
|
|
@@ -3312,9 +3328,6 @@ function checkNode(context, node, allowExpressions) {
|
|
|
3312
3328
|
fix: getFix(context, node)
|
|
3313
3329
|
});
|
|
3314
3330
|
}
|
|
3315
|
-
/**
|
|
3316
|
-
* Generate fix for removing useless fragment
|
|
3317
|
-
*/
|
|
3318
3331
|
function getFix(context, node) {
|
|
3319
3332
|
if (!canFix(context, node)) return null;
|
|
3320
3333
|
return (fixer) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "2.0.5-beta.
|
|
3
|
+
"version": "2.0.5-beta.6",
|
|
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",
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"string-ts": "^2.2.1",
|
|
44
44
|
"ts-api-utils": "^2.1.0",
|
|
45
45
|
"ts-pattern": "^5.8.0",
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/eff": "2.0.5-beta.
|
|
49
|
-
"@eslint-react/kit": "2.0.5-beta.
|
|
50
|
-
"@eslint-react/shared": "2.0.5-beta.
|
|
51
|
-
"@eslint-react/var": "2.0.5-beta.
|
|
46
|
+
"@eslint-react/ast": "2.0.5-beta.6",
|
|
47
|
+
"@eslint-react/core": "2.0.5-beta.6",
|
|
48
|
+
"@eslint-react/eff": "2.0.5-beta.6",
|
|
49
|
+
"@eslint-react/kit": "2.0.5-beta.6",
|
|
50
|
+
"@eslint-react/shared": "2.0.5-beta.6",
|
|
51
|
+
"@eslint-react/var": "2.0.5-beta.6"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@types/react": "^19.
|
|
55
|
-
"@types/react-dom": "^19.
|
|
54
|
+
"@types/react": "^19.2.0",
|
|
55
|
+
"@types/react-dom": "^19.2.0",
|
|
56
56
|
"tsdown": "^0.15.6",
|
|
57
57
|
"@local/configs": "0.0.0"
|
|
58
58
|
},
|