eslint-plugin-react-x 5.19.1 → 5.20.0

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 +25 -5
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -145,7 +145,7 @@ const rules$6 = {
145
145
  //#endregion
146
146
  //#region package.json
147
147
  var name$6 = "eslint-plugin-react-x";
148
- var version = "5.19.1";
148
+ var version = "5.20.0";
149
149
 
150
150
  //#endregion
151
151
  //#region src/utils/create-rule.ts
@@ -1581,11 +1581,12 @@ function createImmutabilityCollector() {
1581
1581
  /**
1582
1582
  * Classify whether a variable ultimately holds a value that must be treated as
1583
1583
  * immutable: a component's props, a state value returned from `useState`-like or
1584
- * `useReducer` calls, or a shallow copy (spread literal) of either.
1584
+ * `useReducer` calls, a shallow copy (spread literal) of either, or a `for...of`
1585
+ * iterator variable whose iterated collection resolves to one of those.
1585
1586
  * @param context The rule context.
1586
1587
  * @param variable The variable to classify.
1587
1588
  * @param components The confirmed function component nodes in the file.
1588
- * @param seen Variables already visited during spread recursion.
1589
+ * @param seen Variables already visited during spread/iterator recursion.
1589
1590
  * @returns The frozen origin, or `null` when the variable is not derived from one.
1590
1591
  */
1591
1592
  function classifyFrozenOrigin(context, variable, components, seen = /* @__PURE__ */ new Set()) {
@@ -1599,8 +1600,21 @@ function classifyFrozenOrigin(context, variable, components, seen = /* @__PURE__
1599
1600
  name: origin.name
1600
1601
  };
1601
1602
  if (def.type !== DefinitionType.Variable) return null;
1602
- const init = def.node.init == null ? null : Extract.unwrap(def.node.init);
1603
- if (init == null) return null;
1603
+ if (def.node.init == null) {
1604
+ const loop = def.node.parent.parent;
1605
+ if (loop.type !== AST_NODE_TYPES.ForOfStatement || loop.left !== def.node.parent) return null;
1606
+ const root = Extract.getIdentifierAt(loop.right, 0);
1607
+ if (root == null) return null;
1608
+ const source = findVariable(context.sourceCode.getScope(root), root);
1609
+ if (source == null) return null;
1610
+ const inner = classifyFrozenOrigin(context, source, components, seen);
1611
+ return inner == null ? null : {
1612
+ kind: "iterator",
1613
+ name: origin.name,
1614
+ original: inner.name
1615
+ };
1616
+ }
1617
+ const init = Extract.unwrap(def.node.init);
1604
1618
  switch (init.type) {
1605
1619
  case AST_NODE_TYPES.CallExpression: {
1606
1620
  const hook = getStateHookName(context, init);
@@ -1704,6 +1718,12 @@ function inferDirectMutations(context, mutations, components) {
1704
1718
  detail: `It is a shallow copy of '${origin.original}'; mutating nested values through it mutates '${origin.original}' in place.`,
1705
1719
  node: mutation.node
1706
1720
  });
1721
+ break;
1722
+ case "iterator": directMutations.push({
1723
+ name: origin.name,
1724
+ detail: `It is an element of '${origin.original}' and must be treated as immutable.`,
1725
+ node: mutation.node
1726
+ });
1707
1727
  }
1708
1728
  }
1709
1729
  return directMutations;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "5.19.1",
3
+ "version": "5.20.0",
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",
@@ -36,12 +36,12 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@eslint-react/ast": "5.19.1",
40
- "@eslint-react/core": "5.19.1",
41
- "@eslint-react/eslint": "5.19.1",
42
- "@eslint-react/jsx": "5.19.1",
43
- "@eslint-react/shared": "5.19.1",
44
- "@eslint-react/var": "5.19.1",
39
+ "@eslint-react/ast": "5.20.0",
40
+ "@eslint-react/core": "5.20.0",
41
+ "@eslint-react/eslint": "5.20.0",
42
+ "@eslint-react/jsx": "5.20.0",
43
+ "@eslint-react/shared": "5.20.0",
44
+ "@eslint-react/var": "5.20.0",
45
45
  "@typescript-eslint/scope-manager": "^8.70.0",
46
46
  "@typescript-eslint/type-utils": "^8.70.0",
47
47
  "@typescript-eslint/types": "^8.70.0",
@@ -63,7 +63,7 @@
63
63
  "react-dom": "^19.3.0",
64
64
  "tsdown": "^0.23.0",
65
65
  "tsl": "^1.0.30",
66
- "tsl-dx": "^0.13.3",
66
+ "tsl-dx": "^0.13.5",
67
67
  "typescript": "6.0.3"
68
68
  },
69
69
  "peerDependencies": {