eslint-plugin-react-x 5.27.1 → 5.27.3

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 +73 -70
  2. package/package.json +9 -7
package/dist/index.js CHANGED
@@ -135,7 +135,7 @@ const rules$6 = {
135
135
  //#endregion
136
136
  //#region package.json
137
137
  var name$6 = "eslint-plugin-react-x";
138
- var version = "5.27.1";
138
+ var version = "5.27.3";
139
139
  //#endregion
140
140
  //#region src/utils/create-rule.ts
141
141
  function getDocsUrl(ruleName) {
@@ -6422,7 +6422,8 @@ function isHookDecl(node) {
6422
6422
  if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
6423
6423
  if (!Check.isIdentifier(node.id)) return false;
6424
6424
  const init = node.init;
6425
- if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
6425
+ if (init == null) return false;
6426
+ if (init.type !== AST_NODE_TYPES.CallExpression) return false;
6426
6427
  const name = Extract.getCalleeName(init);
6427
6428
  return name != null && core.isHookName(name);
6428
6429
  }
@@ -6462,13 +6463,11 @@ function createFactCollector$3(additionalStateHooks, additionalEffectHooks) {
6462
6463
  }
6463
6464
  function getFunctionKind(node) {
6464
6465
  const parent = Traverse.findParent(node, not(Check.isTypeExpression)) ?? node.parent;
6465
- switch (true) {
6466
- case node.async:
6467
- case parent.type === AST_NODE_TYPES.CallExpression && isThenCall(parent): return "deferred";
6468
- case node.type !== AST_NODE_TYPES.FunctionDeclaration && parent.type === AST_NODE_TYPES.CallExpression && parent.callee === node: return "immediate";
6469
- case isUseEffectSetupCallback(node): return "setup";
6470
- default: return "other";
6471
- }
6466
+ if (node.async) return "deferred";
6467
+ if (parent.type === AST_NODE_TYPES.CallExpression && isThenCall(parent)) return "deferred";
6468
+ if (node.type !== AST_NODE_TYPES.FunctionDeclaration && parent.type === AST_NODE_TYPES.CallExpression && parent.callee === node) return "immediate";
6469
+ if (isUseEffectSetupCallback(node)) return "setup";
6470
+ return "other";
6472
6471
  }
6473
6472
  return {
6474
6473
  facts,
@@ -6488,7 +6487,8 @@ function createFactCollector$3(additionalStateHooks, additionalEffectHooks) {
6488
6487
  },
6489
6488
  CallExpression(node) {
6490
6489
  const entry = functionEntries.at(-1);
6491
- if (entry == null || entry.node.async) return;
6490
+ if (entry == null) return;
6491
+ if (entry.node.async) return;
6492
6492
  if (isUseStateCall(node)) return;
6493
6493
  if (isUseEffectCall(node)) {
6494
6494
  const setup = node.arguments.at(0);
@@ -6504,20 +6504,17 @@ function createFactCollector$3(additionalStateHooks, additionalEffectHooks) {
6504
6504
  },
6505
6505
  Identifier(node) {
6506
6506
  if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
6507
- switch (node.parent.type) {
6508
- case AST_NODE_TYPES.ArrowFunctionExpression:
6509
- if (node === node.parent.body) facts.setStateReferences.push({
6510
- kind: "callback-body",
6511
- node
6512
- });
6513
- return;
6514
- case AST_NODE_TYPES.CallExpression:
6515
- if (node === node.parent.arguments.at(0)) facts.setStateReferences.push({
6516
- kind: "call-argument",
6517
- node
6518
- });
6519
- return;
6507
+ if (node.parent.type === AST_NODE_TYPES.ArrowFunctionExpression && node === node.parent.body) {
6508
+ facts.setStateReferences.push({
6509
+ kind: "callback-body",
6510
+ node
6511
+ });
6512
+ return;
6520
6513
  }
6514
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && node === node.parent.arguments.at(0)) facts.setStateReferences.push({
6515
+ kind: "call-argument",
6516
+ node
6517
+ });
6521
6518
  }
6522
6519
  }
6523
6520
  };
@@ -6547,9 +6544,9 @@ function createSetStateResolver$1(context) {
6547
6544
  const innerCallee = Extract.unwrap(callee.callee);
6548
6545
  if (innerCallee.type !== AST_NODE_TYPES.MemberExpression) return false;
6549
6546
  if (!hasProperty(innerCallee.object, "name")) return false;
6550
- const isAt = Extract.getCalleeName(callee) === "at";
6547
+ if (!(Extract.getCalleeName(callee) === "at")) return false;
6551
6548
  const [index] = callee.arguments;
6552
- if (!isAt || index == null) return false;
6549
+ if (index == null) return false;
6553
6550
  const indexScope = context.sourceCode.getScope(node);
6554
6551
  return getStaticValue(index, indexScope)?.value === 1 && isSetStateId(innerCallee.object);
6555
6552
  }
@@ -6591,32 +6588,30 @@ function isInitializedFromRef(context, id, refParams, seen = /* @__PURE__ */ new
6591
6588
  const writeExpr = reference.writeExpr == null ? null : Extract.unwrap(reference.writeExpr);
6592
6589
  if (writeExpr == null) continue;
6593
6590
  if (writeExpr.range[1] > id.range[0]) continue;
6594
- if (Traverse.findParent(writeExpr, and(Check.isFunction, (n) => !Traverse.hasParent(id, (m) => m === n))) != null) continue;
6591
+ if (Traverse.hasParent(writeExpr, and(Check.isFunction, (n) => !Traverse.hasParent(id, (m) => m === n)))) continue;
6595
6592
  if (isExpressionFromRef(context, writeExpr, refParams, seen)) return true;
6596
6593
  }
6597
6594
  return false;
6598
6595
  }
6599
6596
  function isExpressionFromRef(context, init, refParams, seen) {
6600
6597
  const { additionalRefHooks } = getSettingsFromContext(context);
6601
- switch (true) {
6602
- case init.type === AST_NODE_TYPES.MemberExpression: {
6603
- let current = init;
6604
- while (current.type === AST_NODE_TYPES.MemberExpression) {
6605
- const property = Extract.unwrap(current.property);
6606
- const object = Extract.unwrap(current.object);
6607
- if (!current.computed && Check.isIdentifier(property, "current")) {
6608
- const sourceName = getRefSourceName(object);
6609
- if (sourceName === "ref" || sourceName?.endsWith("Ref") === true) return true;
6610
- if (object.type === AST_NODE_TYPES.Identifier && isParameterId(context, object)) return true;
6611
- }
6612
- current = object;
6598
+ if (init.type === AST_NODE_TYPES.CallExpression && core.isUseRefLikeCall(init, additionalRefHooks)) return true;
6599
+ if (init.type === AST_NODE_TYPES.MemberExpression) {
6600
+ let current = init;
6601
+ while (current.type === AST_NODE_TYPES.MemberExpression) {
6602
+ const property = Extract.unwrap(current.property);
6603
+ const object = Extract.unwrap(current.object);
6604
+ if (!current.computed && Check.isIdentifier(property, "current")) {
6605
+ const sourceName = getRefSourceName(object);
6606
+ if (sourceName === "ref" || sourceName?.endsWith("Ref") === true) return true;
6607
+ if (object.type === AST_NODE_TYPES.Identifier && isParameterId(context, object)) return true;
6613
6608
  }
6614
- if (Check.isIdentifier(current) && (current.name === "ref" || current.name.endsWith("Ref"))) return true;
6615
- return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id, refParams, seen));
6609
+ current = object;
6616
6610
  }
6617
- case init.type === AST_NODE_TYPES.CallExpression && core.isUseRefLikeCall(init, additionalRefHooks): return true;
6618
- default: return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id, refParams, seen));
6611
+ if (Check.isIdentifier(current) && (current.name === "ref" || current.name.endsWith("Ref"))) return true;
6612
+ return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id, refParams, seen));
6619
6613
  }
6614
+ return getNestedIdentifiers(init).some((id) => isInitializedFromRef(context, id, refParams, seen));
6620
6615
  }
6621
6616
  function isArgumentUsingRefValue(context, node, refParams) {
6622
6617
  const isUsingRefValue = (n) => {
@@ -6708,11 +6703,14 @@ function inferViolations$2(context, facts) {
6708
6703
  for (const { enclosingFunction, enclosingFunctionKind, node, setupFunction } of facts.calls) {
6709
6704
  if (isUseStateOrThenCall(node)) continue;
6710
6705
  if (!resolver.isSetStateCall(node)) {
6711
- if (setupFunction != null && enclosingFunction === setupFunction) trackedFnCalls.push(node);
6706
+ if (setupFunction == null) continue;
6707
+ if (enclosingFunction !== setupFunction) continue;
6708
+ trackedFnCalls.push(node);
6712
6709
  continue;
6713
6710
  }
6714
6711
  if (enclosingFunctionKind === "deferred") continue;
6715
- if (setupFunction != null && (enclosingFunction === setupFunction || enclosingFunctionKind === "immediate" && Traverse.findParent(enclosingFunction, Check.isFunction) === setupFunction)) {
6712
+ const syncEnclosingFunction = enclosingFunctionKind === "immediate" ? Traverse.findParent(enclosingFunction, Check.isFunction) : enclosingFunction;
6713
+ if (setupFunction != null && syncEnclosingFunction === setupFunction) {
6716
6714
  const args0 = node.arguments.at(0);
6717
6715
  if (args0 == null) continue;
6718
6716
  if (isArgumentUsingRefValue(context, args0)) continue;
@@ -6755,7 +6753,8 @@ function inferViolations$2(context, facts) {
6755
6753
  };
6756
6754
  const getRefDerivedParams = (call, callee) => {
6757
6755
  const origin = resolveOrigin(context, callee);
6758
- if (origin == null || !Check.isFunction(origin)) return void 0;
6756
+ if (origin == null) return void 0;
6757
+ if (!Check.isFunction(origin)) return void 0;
6759
6758
  const refParams = /* @__PURE__ */ new Set();
6760
6759
  origin.params.forEach((param, index) => {
6761
6760
  const paramId = param.type === AST_NODE_TYPES.Identifier ? param : param.type === AST_NODE_TYPES.AssignmentPattern && param.left.type === AST_NODE_TYPES.Identifier ? param.left : null;
@@ -6819,9 +6818,9 @@ var set_state_in_effect_default = createRule({
6819
6818
  function create$5(context) {
6820
6819
  if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
6821
6820
  const { additionalEffectHooks, additionalStateHooks } = getSettingsFromContext(context);
6822
- const facts = createFactCollector$3(additionalStateHooks, additionalEffectHooks);
6823
- return merge(facts.visitor, { "Program:exit"() {
6824
- for (const violation of inferViolations$2(context, facts.facts)) context.report({
6821
+ const { facts, visitor } = createFactCollector$3(additionalStateHooks, additionalEffectHooks);
6822
+ return merge(visitor, { "Program:exit"() {
6823
+ for (const violation of inferViolations$2(context, facts)) context.report({
6825
6824
  data: { name: violation.name },
6826
6825
  messageId: "default",
6827
6826
  node: violation.node
@@ -6901,7 +6900,8 @@ function createFactCollector$2(context) {
6901
6900
  const componentFn = componentFnStack.at(-1);
6902
6901
  if (componentFn == null) return;
6903
6902
  const entry = functionEntries.at(-1);
6904
- if (entry == null || entry.node !== componentFn) return;
6903
+ if (entry == null) return;
6904
+ if (entry.node !== componentFn) return;
6905
6905
  if (componentFn.body.type !== AST_NODE_TYPES.BlockStatement) return;
6906
6906
  const body = componentFn.body.body;
6907
6907
  let stmt = node;
@@ -6943,9 +6943,9 @@ function createSetStateResolver(context) {
6943
6943
  const innerCallee = Extract.unwrap(callee.callee);
6944
6944
  if (innerCallee.type !== AST_NODE_TYPES.MemberExpression) return false;
6945
6945
  if (!hasProperty(innerCallee.object, "name")) return false;
6946
- const isAt = Extract.getCalleeName(callee) === "at";
6946
+ if (!(Extract.getCalleeName(callee) === "at")) return false;
6947
6947
  const [index] = callee.arguments;
6948
- if (!isAt || index == null) return false;
6948
+ if (index == null) return false;
6949
6949
  const indexScope = context.sourceCode.getScope(node);
6950
6950
  return getStaticValue(index, indexScope)?.value === 1 && isSetStateId(innerCallee.object);
6951
6951
  }
@@ -6997,9 +6997,9 @@ var set_state_in_render_default = createRule({
6997
6997
  create: create$4
6998
6998
  });
6999
6999
  function create$4(context) {
7000
- const facts = createFactCollector$2(context);
7001
- return merge(facts.visitor, { "Program:exit"() {
7002
- for (const violation of inferViolations$1(context, facts.facts)) context.report({
7000
+ const { facts, visitor } = createFactCollector$2(context);
7001
+ return merge(visitor, { "Program:exit"() {
7002
+ for (const violation of inferViolations$1(context, facts)) context.report({
7003
7003
  data: { name: violation.name },
7004
7004
  messageId: "default",
7005
7005
  node: violation.node
@@ -7061,7 +7061,8 @@ function findReassignmentCreationSite(context, variable, isInsideRender, seen) {
7061
7061
  for (const ref of variable.references) {
7062
7062
  if (!ref.isWrite()) continue;
7063
7063
  const { identifier } = ref;
7064
- if (identifier.parent.type !== AST_NODE_TYPES.AssignmentExpression || identifier.parent.left !== identifier) continue;
7064
+ if (identifier.parent.type !== AST_NODE_TYPES.AssignmentExpression) continue;
7065
+ if (identifier.parent.left !== identifier) continue;
7065
7066
  const source = findDynamicCreationSite(context, identifier.parent.right, isInsideRender, seen);
7066
7067
  if (source != null) return source;
7067
7068
  }
@@ -7081,11 +7082,13 @@ function resolveDynamicComponentOrigin(context, variable, isInsideRender, seen =
7081
7082
  isDynamic: true
7082
7083
  };
7083
7084
  if (defNode.type !== AST_NODE_TYPES.VariableDeclarator) continue;
7084
- const initSource = defNode.init == null ? null : findDynamicCreationSite(context, defNode.init, isInsideRender, seen);
7085
- if (initSource != null) return {
7086
- creationNode: initSource,
7087
- isDynamic: true
7088
- };
7085
+ if (defNode.init != null) {
7086
+ const initSource = findDynamicCreationSite(context, defNode.init, isInsideRender, seen);
7087
+ if (initSource != null) return {
7088
+ creationNode: initSource,
7089
+ isDynamic: true
7090
+ };
7091
+ }
7089
7092
  const reassignmentSource = findReassignmentCreationSite(context, variable, isInsideRender, seen);
7090
7093
  if (reassignmentSource != null) return {
7091
7094
  creationNode: reassignmentSource,
@@ -7134,22 +7137,22 @@ function create$3(context) {
7134
7137
  const hint = core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.FunctionComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.FunctionComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayPatternElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayExpressionElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
7135
7138
  const fc = core.getFunctionComponentCollector(context, { hint });
7136
7139
  const cc = core.getClassComponentCollector(context);
7137
- const facts = createFactCollector$1();
7138
- return merge(fc.visitor, cc.visitor, facts.visitor, { "Program:exit"(program) {
7140
+ const { facts, visitor } = createFactCollector$1();
7141
+ return merge(fc.visitor, cc.visitor, visitor, { "Program:exit"(program) {
7139
7142
  const isInsideRender = createRenderBoundaryChecker([...fc.api.getAllComponents(program), ...cc.api.getAllComponents(program)].map((component) => component.node));
7140
7143
  const reportedCreations = /* @__PURE__ */ new Set();
7141
- for (const effect of inferCreatedComponents(context, facts.facts.componentUsages, isInsideRender)) {
7144
+ for (const effect of inferCreatedComponents(context, facts.componentUsages, isInsideRender)) {
7142
7145
  context.report({
7143
7146
  messageId: "default",
7144
7147
  node: effect.node
7145
7148
  });
7146
- if (effect.creationNode != null && !reportedCreations.has(effect.creationNode)) {
7147
- reportedCreations.add(effect.creationNode);
7148
- context.report({
7149
- messageId: "created-here",
7150
- node: effect.creationNode
7151
- });
7152
- }
7149
+ if (effect.creationNode == null) continue;
7150
+ if (reportedCreations.has(effect.creationNode)) continue;
7151
+ reportedCreations.add(effect.creationNode);
7152
+ context.report({
7153
+ messageId: "created-here",
7154
+ node: effect.creationNode
7155
+ });
7153
7156
  }
7154
7157
  } });
7155
7158
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "5.27.1",
3
+ "version": "5.27.3",
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.27.1",
40
- "@eslint-react/core": "5.27.1",
41
- "@eslint-react/eslint": "5.27.1",
42
- "@eslint-react/jsx": "5.27.1",
43
- "@eslint-react/shared": "5.27.1",
44
- "@eslint-react/var": "5.27.1",
39
+ "@eslint-react/ast": "5.27.3",
40
+ "@eslint-react/core": "5.27.3",
41
+ "@eslint-react/eslint": "5.27.3",
42
+ "@eslint-react/jsx": "5.27.3",
43
+ "@eslint-react/shared": "5.27.3",
44
+ "@eslint-react/var": "5.27.3",
45
45
  "@typescript-eslint/scope-manager": "^8.71.2",
46
46
  "@typescript-eslint/types": "^8.71.2",
47
47
  "@typescript-eslint/typescript-estree": "^8.71.2",
@@ -56,6 +56,8 @@
56
56
  "@local/eff": "0.0.0",
57
57
  "@local/testkit": "0.0.0",
58
58
  "@rbxts/react": "17.3.7-ts.2",
59
+ "@tsconfig/node20": "^20.1.10",
60
+ "@types/node": "^20.19.43",
59
61
  "@types/react": "^19.3.0",
60
62
  "@types/react-dom": "^19.3.0",
61
63
  "dedent": "^1.7.2",