eslint-plugin-react-x 4.0.2-beta.0 → 4.0.2-beta.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 +26 -16
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -147,7 +147,7 @@ const rules$7 = {
|
|
|
147
147
|
//#endregion
|
|
148
148
|
//#region package.json
|
|
149
149
|
var name$6 = "eslint-plugin-react-x";
|
|
150
|
-
var version = "4.0.2-beta.
|
|
150
|
+
var version = "4.0.2-beta.1";
|
|
151
151
|
|
|
152
152
|
//#endregion
|
|
153
153
|
//#region src/utils/create-rule.ts
|
|
@@ -1377,8 +1377,12 @@ function create$54(context) {
|
|
|
1377
1377
|
return declarator.id.elements.findIndex((el) => el?.type === AST_NODE_TYPES.Identifier && el.name === id.name) === 0;
|
|
1378
1378
|
}
|
|
1379
1379
|
/**
|
|
1380
|
-
* Return
|
|
1381
|
-
* position 0 of any ancestor function
|
|
1380
|
+
* Return the function node when `id` is a direct (non-destructured) props
|
|
1381
|
+
* parameter at position 0 of any ancestor function; otherwise return `null`.
|
|
1382
|
+
*
|
|
1383
|
+
* The caller must later verify (at Program:exit) that the returned function
|
|
1384
|
+
* is actually a component or hook — event handler parameters share the same
|
|
1385
|
+
* syntactic shape but should **not** be treated as React props.
|
|
1382
1386
|
*
|
|
1383
1387
|
* Uses scope resolution so that references to `props` inside nested arrow
|
|
1384
1388
|
* functions (ex: event handlers) are correctly traced back to the component
|
|
@@ -1390,18 +1394,19 @@ function create$54(context) {
|
|
|
1390
1394
|
* };
|
|
1391
1395
|
* }
|
|
1392
1396
|
* @param id The identifier to check. May be a reference to the props parameter, e.g. used inside an event handler nested in the component body — scope resolution will trace it back to the original declaration.
|
|
1393
|
-
* @returns
|
|
1397
|
+
* @returns The function node where `id` is the first parameter, or `null`.
|
|
1394
1398
|
*/
|
|
1395
|
-
function
|
|
1399
|
+
function getPropsDefiningFunction(id) {
|
|
1396
1400
|
const variable = findVariable(context.sourceCode.getScope(id), id);
|
|
1397
|
-
if (variable == null) return
|
|
1401
|
+
if (variable == null) return null;
|
|
1398
1402
|
for (const def of variable.defs) {
|
|
1399
1403
|
if (def.type !== DefinitionType.Parameter) continue;
|
|
1400
1404
|
if (!ast.isFunction(def.node)) continue;
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1405
|
+
const fn = def.node;
|
|
1406
|
+
const firstParam = fn.params.at(0);
|
|
1407
|
+
if (firstParam?.type === AST_NODE_TYPES.Identifier && firstParam.name === id.name) return fn;
|
|
1403
1408
|
}
|
|
1404
|
-
return
|
|
1409
|
+
return null;
|
|
1405
1410
|
}
|
|
1406
1411
|
return defineRuleListener(hCollector.visitor, cCollector.visitor, {
|
|
1407
1412
|
CallExpression(node) {
|
|
@@ -1415,8 +1420,8 @@ function create$54(context) {
|
|
|
1415
1420
|
const enclosingFn = ast.findParent(node, ast.isFunction);
|
|
1416
1421
|
if (enclosingFn == null) return;
|
|
1417
1422
|
const isState = isStateValue(rootId);
|
|
1418
|
-
const
|
|
1419
|
-
if (!isState &&
|
|
1423
|
+
const propsDefiningFunc = !isState ? getPropsDefiningFunction(rootId) : null;
|
|
1424
|
+
if (!isState && propsDefiningFunc == null) return;
|
|
1420
1425
|
violations.push({
|
|
1421
1426
|
data: {
|
|
1422
1427
|
name: context.sourceCode.getText(object),
|
|
@@ -1424,7 +1429,8 @@ function create$54(context) {
|
|
|
1424
1429
|
},
|
|
1425
1430
|
func: enclosingFn,
|
|
1426
1431
|
messageId: "mutatingArrayMethod",
|
|
1427
|
-
node
|
|
1432
|
+
node,
|
|
1433
|
+
...propsDefiningFunc != null ? { propsDefiningFunc } : {}
|
|
1428
1434
|
});
|
|
1429
1435
|
},
|
|
1430
1436
|
AssignmentExpression(node) {
|
|
@@ -1435,20 +1441,21 @@ function create$54(context) {
|
|
|
1435
1441
|
const enclosingFn = ast.findParent(node, ast.isFunction);
|
|
1436
1442
|
if (enclosingFn == null) return;
|
|
1437
1443
|
const isState = isStateValue(rootId);
|
|
1438
|
-
const
|
|
1439
|
-
if (!isState &&
|
|
1444
|
+
const propsDefiningFunc = !isState ? getPropsDefiningFunction(rootId) : null;
|
|
1445
|
+
if (!isState && propsDefiningFunc == null) return;
|
|
1440
1446
|
violations.push({
|
|
1441
1447
|
data: { name: context.sourceCode.getText(node.left.object) },
|
|
1442
1448
|
func: enclosingFn,
|
|
1443
1449
|
messageId: "mutatingAssignment",
|
|
1444
|
-
node
|
|
1450
|
+
node,
|
|
1451
|
+
...propsDefiningFunc != null ? { propsDefiningFunc } : {}
|
|
1445
1452
|
});
|
|
1446
1453
|
},
|
|
1447
1454
|
"Program:exit"(node) {
|
|
1448
1455
|
const comps = cCollector.api.getAllComponents(node);
|
|
1449
1456
|
const hooks = hCollector.api.getAllHooks(node);
|
|
1450
1457
|
const funcs = [...comps, ...hooks];
|
|
1451
|
-
for (const { data, func, messageId, node } of violations) {
|
|
1458
|
+
for (const { data, func, messageId, node, propsDefiningFunc } of violations) {
|
|
1452
1459
|
let current = func;
|
|
1453
1460
|
let insideComponentOrHook = false;
|
|
1454
1461
|
while (current != null) {
|
|
@@ -1459,6 +1466,9 @@ function create$54(context) {
|
|
|
1459
1466
|
current = ast.findParent(current, ast.isFunction);
|
|
1460
1467
|
}
|
|
1461
1468
|
if (!insideComponentOrHook) continue;
|
|
1469
|
+
if (propsDefiningFunc != null) {
|
|
1470
|
+
if (!funcs.some((f) => f.node === propsDefiningFunc)) continue;
|
|
1471
|
+
}
|
|
1462
1472
|
context.report({
|
|
1463
1473
|
data,
|
|
1464
1474
|
messageId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "4.0.2-beta.
|
|
3
|
+
"version": "4.0.2-beta.1",
|
|
4
4
|
"description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"string-ts": "^2.3.1",
|
|
46
46
|
"ts-api-utils": "^2.5.0",
|
|
47
47
|
"ts-pattern": "^5.9.0",
|
|
48
|
-
"@eslint-react/ast": "4.0.2-beta.
|
|
49
|
-
"@eslint-react/core": "4.0.2-beta.
|
|
50
|
-
"@eslint-react/shared": "4.0.2-beta.
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/
|
|
48
|
+
"@eslint-react/ast": "4.0.2-beta.1",
|
|
49
|
+
"@eslint-react/core": "4.0.2-beta.1",
|
|
50
|
+
"@eslint-react/shared": "4.0.2-beta.1",
|
|
51
|
+
"@eslint-react/jsx": "4.0.2-beta.1",
|
|
52
|
+
"@eslint-react/var": "4.0.2-beta.1"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/react": "^19.2.14",
|