eslint-plugin-react-x 4.0.1-beta.1 → 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.
Files changed (2) hide show
  1. package/dist/index.js +26 -16
  2. 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.1-beta.1";
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 true when `id` is a direct (non-destructured) props parameter at
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 True if `id` is a props parameter, false otherwise.
1397
+ * @returns The function node where `id` is the first parameter, or `null`.
1394
1398
  */
1395
- function isPropsObject(id) {
1399
+ function getPropsDefiningFunction(id) {
1396
1400
  const variable = findVariable(context.sourceCode.getScope(id), id);
1397
- if (variable == null) return false;
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 firstParam = def.node.params.at(0);
1402
- return firstParam?.type === AST_NODE_TYPES.Identifier && firstParam.name === id.name;
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 false;
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 isProps = isPropsObject(rootId);
1419
- if (!isState && !isProps) return;
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 isProps = isPropsObject(rootId);
1439
- if (!isState && !isProps) return;
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.1-beta.1",
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.1-beta.1",
49
- "@eslint-react/core": "4.0.1-beta.1",
50
- "@eslint-react/var": "4.0.1-beta.1",
51
- "@eslint-react/shared": "4.0.1-beta.1",
52
- "@eslint-react/jsx": "4.0.1-beta.1"
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",