eslint-plugin-react-x 5.7.8-next.0 → 5.7.9-beta.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 +35 -14
  2. package/package.json +9 -9
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ const rules$6 = {
143
143
  //#endregion
144
144
  //#region package.json
145
145
  var name$6 = "eslint-plugin-react-x";
146
- var version = "5.7.8-next.0";
146
+ var version = "5.7.9-beta.0";
147
147
 
148
148
  //#endregion
149
149
  //#region src/utils/create-rule.ts
@@ -169,11 +169,26 @@ var error_boundaries_default = createRule({
169
169
  create: create$50,
170
170
  defaultOptions: []
171
171
  });
172
+ /**
173
+ * Finds the nearest TryStatement whose `try` block (not catch/finally)
174
+ * encloses the given node.
175
+ * @param node The node to check.
176
+ * @returns The enclosing TryStatement, or null if none is found.
177
+ */
172
178
  function getEnclosingTryBlock(node) {
173
- const tryStmt = Traverse.findParent(node, is(AST_NODE_TYPES.TryStatement));
174
- if (tryStmt == null) return null;
175
- if (Traverse.findParent(node, (n) => n === tryStmt.block) != null) return tryStmt;
176
- return getEnclosingTryBlock(tryStmt);
179
+ let current = node.parent;
180
+ while (current != null) {
181
+ if (current.type === AST_NODE_TYPES.TryStatement) {
182
+ let n = node;
183
+ while (n != null && n !== current) {
184
+ if (n === current.block) return current;
185
+ n = n.parent;
186
+ }
187
+ }
188
+ if (current.type === "Program") return null;
189
+ current = current.parent;
190
+ }
191
+ return null;
177
192
  }
178
193
  function create$50(context) {
179
194
  if (!context.sourceCode.text.includes("try")) return {};
@@ -1282,6 +1297,7 @@ const MUTATING_ARRAY_METHODS = new Set([
1282
1297
  /**
1283
1298
  * Check if a name is ref-like ("ref" or ends with "Ref").
1284
1299
  * Refs are mutable by design and exempted from immutability checks.
1300
+ * @param name
1285
1301
  */
1286
1302
  function isRefLikeName(name) {
1287
1303
  return name === "ref" || name.endsWith("Ref");
@@ -1289,6 +1305,7 @@ function isRefLikeName(name) {
1289
1305
  /**
1290
1306
  * Check if any identifier or property name in a member-expression chain
1291
1307
  * is ref-like.
1308
+ * @param node
1292
1309
  */
1293
1310
  function hasRefLikeNameInChain(node) {
1294
1311
  if (node.type === AST_NODE_TYPES.Identifier) return isRefLikeName(node.name);
@@ -2616,16 +2633,16 @@ function create$27(context) {
2616
2633
  * @param node The AST node to inspect
2617
2634
  * @returns A report descriptor if a problem is found, otherwise `null`
2618
2635
  */
2619
- function getReportDescriptor(node) {
2636
+ function getReportDescriptor(node, visited = /* @__PURE__ */ new Set()) {
2620
2637
  if (node == null) return null;
2621
- if (is(AST_NODE_TYPES.JSXExpressionContainer)(node)) return getReportDescriptor(node.expression);
2638
+ if (is(AST_NODE_TYPES.JSXExpressionContainer)(node)) return getReportDescriptor(node.expression, visited);
2622
2639
  if (Check.isJSX(node)) return null;
2623
- if (Check.isTypeExpression(node)) return getReportDescriptor(node.expression);
2640
+ if (Check.isTypeExpression(node)) return getReportDescriptor(node.expression, visited);
2624
2641
  return match(node).with({
2625
2642
  type: AST_NODE_TYPES.LogicalExpression,
2626
2643
  operator: "&&"
2627
2644
  }, ({ left, right }) => {
2628
- if (left.type === AST_NODE_TYPES.UnaryExpression && left.operator === "!") return getReportDescriptor(right);
2645
+ if (left.type === AST_NODE_TYPES.UnaryExpression && left.operator === "!") return getReportDescriptor(right, visited);
2629
2646
  const initialScope = context.sourceCode.getScope(left);
2630
2647
  if (Check.isIdentifier("NaN")(left) || getStaticValue(left, initialScope)?.value === "NaN") return {
2631
2648
  data: { value: context.sourceCode.getText(left) },
@@ -2634,17 +2651,19 @@ function create$27(context) {
2634
2651
  };
2635
2652
  const leftType = getConstrainedTypeAtLocation(services, left);
2636
2653
  const leftTypeVariants = core.getTypeVariants(unionConstituents(leftType));
2637
- if (Array.from(leftTypeVariants.values()).every((type) => allowedVariants.some((allowed) => allowed === type))) return getReportDescriptor(right);
2654
+ if (Array.from(leftTypeVariants.values()).every((type) => allowedVariants.some((allowed) => allowed === type))) return getReportDescriptor(right, visited);
2638
2655
  return {
2639
2656
  data: { value: context.sourceCode.getText(left) },
2640
2657
  messageId: "default",
2641
2658
  node: left
2642
2659
  };
2643
2660
  }).with({ type: AST_NODE_TYPES.ConditionalExpression }, ({ alternate, consequent }) => {
2644
- return getReportDescriptor(consequent) ?? getReportDescriptor(alternate);
2661
+ return getReportDescriptor(consequent, visited) ?? getReportDescriptor(alternate, visited);
2645
2662
  }).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
2663
+ if (visited.has(n.name)) return null;
2664
+ visited.add(n.name);
2646
2665
  const variableDefNode = findVariable(context.sourceCode.getScope(n), n.name)?.defs.at(0)?.node;
2647
- return match(variableDefNode).with({ init: P.select({ type: P.not(AST_NODE_TYPES.VariableDeclaration) }) }, getReportDescriptor).otherwise(() => null);
2666
+ return match(variableDefNode).with({ init: P.select({ type: P.not(AST_NODE_TYPES.VariableDeclaration) }) }, (init) => getReportDescriptor(init, visited)).otherwise(() => null);
2648
2667
  }).otherwise(() => null);
2649
2668
  }
2650
2669
  return merge({ JSXExpressionContainer: flow(getReportDescriptor, report$1(context)) });
@@ -6674,7 +6693,9 @@ function isHookDecl(node) {
6674
6693
  default: return false;
6675
6694
  }
6676
6695
  }
6677
- function isInitializedFromRef(context, name, initialScope) {
6696
+ function isInitializedFromRef(context, name, initialScope, visited = /* @__PURE__ */ new Set()) {
6697
+ if (visited.has(name)) return false;
6698
+ visited.add(name);
6678
6699
  for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
6679
6700
  if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
6680
6701
  const init = node.init;
@@ -6682,7 +6703,7 @@ function isInitializedFromRef(context, name, initialScope) {
6682
6703
  switch (true) {
6683
6704
  case init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier && (init.object.name === "ref" || init.object.name.endsWith("Ref")): return true;
6684
6705
  case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefCall(context, init): return true;
6685
- case init.type === AST_NODE_TYPES.CallExpression: return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id.name, context.sourceCode.getScope(id)));
6706
+ case init.type === AST_NODE_TYPES.CallExpression: return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id.name, context.sourceCode.getScope(id), visited));
6686
6707
  }
6687
6708
  }
6688
6709
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "5.7.8-next.0",
3
+ "version": "5.7.9-beta.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",
@@ -45,12 +45,12 @@
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": "5.7.8-next.0",
49
- "@eslint-react/core": "5.7.8-next.0",
50
- "@eslint-react/jsx": "5.7.8-next.0",
51
- "@eslint-react/eslint": "5.7.8-next.0",
52
- "@eslint-react/shared": "5.7.8-next.0",
53
- "@eslint-react/var": "5.7.8-next.0"
48
+ "@eslint-react/ast": "5.7.9-beta.0",
49
+ "@eslint-react/eslint": "5.7.9-beta.0",
50
+ "@eslint-react/core": "5.7.9-beta.0",
51
+ "@eslint-react/shared": "5.7.9-beta.0",
52
+ "@eslint-react/jsx": "5.7.9-beta.0",
53
+ "@eslint-react/var": "5.7.9-beta.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/react": "^19.2.14",
@@ -63,8 +63,8 @@
63
63
  "tsl": "^1.0.30",
64
64
  "tsl-dx": "^0.12.1",
65
65
  "typescript": "^6.0.3",
66
- "@local/configs": "0.0.0",
67
- "@local/eff": "3.0.0-beta.72"
66
+ "@local/eff": "3.0.0-beta.72",
67
+ "@local/configs": "0.0.0"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "eslint": "^10.3.0",