eslint-plugin-react-x 5.3.4-beta.1 → 5.4.0-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 +481 -232
  2. package/package.json +9 -9
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ const rules$7 = {
143
143
  //#endregion
144
144
  //#region package.json
145
145
  var name$6 = "eslint-plugin-react-x";
146
- var version = "5.3.4-beta.1";
146
+ var version = "5.4.0-beta.0";
147
147
 
148
148
  //#endregion
149
149
  //#region src/rules/component-hook-factories/lib.ts
@@ -199,7 +199,7 @@ const createRule = ESLintUtils.RuleCreator(getDocsUrl);
199
199
 
200
200
  //#endregion
201
201
  //#region src/rules/component-hook-factories/component-hook-factories.ts
202
- const RULE_NAME$49 = "component-hook-factories";
202
+ const RULE_NAME$50 = "component-hook-factories";
203
203
  var component_hook_factories_default = createRule({
204
204
  meta: {
205
205
  type: "problem",
@@ -210,11 +210,11 @@ var component_hook_factories_default = createRule({
210
210
  },
211
211
  schema: []
212
212
  },
213
- name: RULE_NAME$49,
214
- create: create$49,
213
+ name: RULE_NAME$50,
214
+ create: create$50,
215
215
  defaultOptions: []
216
216
  });
217
- function create$49(context) {
217
+ function create$50(context) {
218
218
  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;
219
219
  const fc = core.getFunctionComponentCollector(context, { hint });
220
220
  const cc = core.getClassComponentCollector(context);
@@ -265,7 +265,7 @@ function create$49(context) {
265
265
 
266
266
  //#endregion
267
267
  //#region src/rules/error-boundaries/error-boundaries.ts
268
- const RULE_NAME$48 = "error-boundaries";
268
+ const RULE_NAME$49 = "error-boundaries";
269
269
  var error_boundaries_default = createRule({
270
270
  meta: {
271
271
  type: "problem",
@@ -276,11 +276,11 @@ var error_boundaries_default = createRule({
276
276
  },
277
277
  schema: []
278
278
  },
279
- name: RULE_NAME$48,
280
- create: create$48,
279
+ name: RULE_NAME$49,
280
+ create: create$49,
281
281
  defaultOptions: []
282
282
  });
283
- function create$48(context) {
283
+ function create$49(context) {
284
284
  if (!context.sourceCode.text.includes("try")) return {};
285
285
  const hint = JsxDetectionHint.DoNotIncludeJsxWithNullValue | JsxDetectionHint.DoNotIncludeJsxWithNumberValue | JsxDetectionHint.DoNotIncludeJsxWithBigIntValue | JsxDetectionHint.DoNotIncludeJsxWithStringValue | JsxDetectionHint.DoNotIncludeJsxWithBooleanValue | JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue | JsxDetectionHint.DoNotIncludeJsxWithEmptyArrayValue;
286
286
  const fc = core.getFunctionComponentCollector(context);
@@ -1249,7 +1249,7 @@ const MUTATING_ARRAY_METHODS$1 = new Set([
1249
1249
 
1250
1250
  //#endregion
1251
1251
  //#region src/rules/globals/globals.ts
1252
- const RULE_NAME$47 = "globals";
1252
+ const RULE_NAME$48 = "globals";
1253
1253
  var globals_default = createRule({
1254
1254
  meta: {
1255
1255
  type: "problem",
@@ -1261,11 +1261,11 @@ var globals_default = createRule({
1261
1261
  },
1262
1262
  schema: []
1263
1263
  },
1264
- name: RULE_NAME$47,
1265
- create: create$47,
1264
+ name: RULE_NAME$48,
1265
+ create: create$48,
1266
1266
  defaultOptions: []
1267
1267
  });
1268
- function create$47(context) {
1268
+ function create$48(context) {
1269
1269
  const hc = core.getHookCollector(context);
1270
1270
  const fc = core.getFunctionComponentCollector(context);
1271
1271
  const violations = [];
@@ -1387,7 +1387,7 @@ const MUTATING_ARRAY_METHODS = new Set([
1387
1387
 
1388
1388
  //#endregion
1389
1389
  //#region src/rules/immutability/immutability.ts
1390
- const RULE_NAME$46 = "immutability";
1390
+ const RULE_NAME$47 = "immutability";
1391
1391
  var immutability_default = createRule({
1392
1392
  meta: {
1393
1393
  type: "problem",
@@ -1398,11 +1398,11 @@ var immutability_default = createRule({
1398
1398
  },
1399
1399
  schema: []
1400
1400
  },
1401
- name: RULE_NAME$46,
1402
- create: create$46,
1401
+ name: RULE_NAME$47,
1402
+ create: create$47,
1403
1403
  defaultOptions: []
1404
1404
  });
1405
- function create$46(context) {
1405
+ function create$47(context) {
1406
1406
  const { additionalStateHooks } = getSettingsFromContext(context);
1407
1407
  const hc = core.getHookCollector(context);
1408
1408
  const fc = core.getFunctionComponentCollector(context);
@@ -1414,49 +1414,78 @@ function create$46(context) {
1414
1414
  function isUseStateCall(node) {
1415
1415
  return core.isUseStateLikeCall(node, additionalStateHooks);
1416
1416
  }
1417
+ function isUseReducerCall(node) {
1418
+ const callee = Extract.unwrap(node.callee);
1419
+ if (callee.type === AST_NODE_TYPES.Identifier) return callee.name === "useReducer";
1420
+ if (callee.type === AST_NODE_TYPES.MemberExpression) {
1421
+ if (Extract.getRootIdentifier(callee)?.name === "React") return Extract.getPropertyName(callee.property) === "useReducer";
1422
+ }
1423
+ return false;
1424
+ }
1417
1425
  /**
1418
1426
  * Return true when `id` is the *value* variable (index 0) produced by a
1419
- * `useState(…)` call, i.e. the first element of `const [value, setter] = useState(…)`.
1427
+ * `useState(…)` or `useReducer(…)` call.
1420
1428
  * @param id The identifier to check. May be a reference to the state variable, e.g. used inside an event handler nested in the component body — scope resolution will trace it back to the original declaration.
1421
1429
  * @returns True if `id` is a state variable, false otherwise.
1422
1430
  */
1423
1431
  function isStateValue(id) {
1424
1432
  const initNode = resolve(context, id);
1425
1433
  if (initNode == null || initNode.type !== AST_NODE_TYPES.CallExpression) return false;
1426
- if (!isUseStateCall(initNode)) return false;
1434
+ if (!isUseStateCall(initNode) && !isUseReducerCall(initNode)) return false;
1427
1435
  const declarator = initNode.parent;
1428
1436
  if (!("id" in declarator) || declarator.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
1429
1437
  return declarator.id.elements.findIndex((el) => el?.type === AST_NODE_TYPES.Identifier && el.name === id.name) === 0;
1430
1438
  }
1431
1439
  /**
1432
- * Return the function node when `id` is a direct (non-destructured) props
1433
- * parameter at position 0 of any ancestor function; otherwise return `null`.
1440
+ * Check if `name` appears anywhere inside a parameter pattern.
1441
+ * @param pattern
1442
+ * @param name
1443
+ */
1444
+ function identifierExistsInPattern(pattern, name) {
1445
+ switch (pattern.type) {
1446
+ case AST_NODE_TYPES.Identifier: return pattern.name === name;
1447
+ case AST_NODE_TYPES.ObjectPattern: return pattern.properties.some((p) => {
1448
+ if (p.type === AST_NODE_TYPES.Property) return identifierExistsInPattern(p.value, name);
1449
+ if (p.type === AST_NODE_TYPES.RestElement) return identifierExistsInPattern(p.argument, name);
1450
+ return false;
1451
+ });
1452
+ case AST_NODE_TYPES.ArrayPattern: return pattern.elements.some((el) => el != null && identifierExistsInPattern(el, name));
1453
+ case AST_NODE_TYPES.RestElement: return identifierExistsInPattern(pattern.argument, name);
1454
+ case AST_NODE_TYPES.AssignmentPattern: return identifierExistsInPattern(pattern.left, name);
1455
+ case AST_NODE_TYPES.MemberExpression: return Extract.getRootIdentifier(pattern)?.name === name;
1456
+ default: return false;
1457
+ }
1458
+ }
1459
+ /**
1460
+ * Return the function node when `id` is a parameter of any position in any
1461
+ * ancestor function; otherwise return `null`.
1434
1462
  *
1435
1463
  * The caller must later verify (at Program:exit) that the returned function
1436
1464
  * is actually a component or hook — event handler parameters share the same
1437
1465
  * syntactic shape but should **not** be treated as React props.
1438
1466
  *
1439
- * Uses scope resolution so that references to `props` inside nested arrow
1440
- * functions (ex: event handlers) are correctly traced back to the component
1441
- * parameter, e.g.:
1467
+ * Uses scope resolution so that references to parameters inside nested arrow
1468
+ * functions are correctly traced back to the declaring function, e.g.:
1442
1469
  *
1443
- * function Component(props) { // ← props defined here
1470
+ * function Component({ items }) { // ← items defined here
1444
1471
  * const handleClick = () => {
1445
- * props.items.push(4); // ← props resolved via scope to Component's param
1472
+ * items.push(4); // ← items resolved via scope to Component's param
1446
1473
  * };
1447
1474
  * }
1448
- * @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.
1449
- * @returns The function node where `id` is the first parameter, or `null`.
1475
+ * @param id The identifier to check.
1476
+ * @returns The function node where `id` is a parameter, or `null`.
1450
1477
  */
1451
1478
  function getPropsDefiningFunction(id) {
1452
1479
  const variable = findVariable(context.sourceCode.getScope(id), id);
1453
1480
  if (variable == null) return null;
1454
1481
  for (const def of variable.defs) {
1455
1482
  if (def.type !== DefinitionType.Parameter) continue;
1456
- if (!Check.isFunction(def.node)) continue;
1457
- const fn = def.node;
1458
- const firstParam = fn.params.at(0);
1459
- if (firstParam?.type === AST_NODE_TYPES.Identifier && firstParam.name === id.name) return fn;
1483
+ if (def.node == null) continue;
1484
+ let fn = def.node;
1485
+ while (fn != null && !Check.isFunction(fn)) fn = fn.parent ?? null;
1486
+ if (fn == null) continue;
1487
+ const func = fn;
1488
+ if (func.params.some((param) => identifierExistsInPattern(param, id.name))) return func;
1460
1489
  }
1461
1490
  return null;
1462
1491
  }
@@ -1729,7 +1758,7 @@ function getOrInsertComputed(map, key, callback) {
1729
1758
 
1730
1759
  //#endregion
1731
1760
  //#region src/rules/no-access-state-in-setstate/no-access-state-in-setstate.ts
1732
- const RULE_NAME$45 = "no-access-state-in-setstate";
1761
+ const RULE_NAME$46 = "no-access-state-in-setstate";
1733
1762
  function isKeyLiteral$1(node, key) {
1734
1763
  return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
1735
1764
  type: AST_NODE_TYPES.TemplateLiteral,
@@ -1743,11 +1772,11 @@ var no_access_state_in_setstate_default = createRule({
1743
1772
  messages: { default: "Do not access 'this.state' within 'setState'. Use the update function instead." },
1744
1773
  schema: []
1745
1774
  },
1746
- name: RULE_NAME$45,
1747
- create: create$45,
1775
+ name: RULE_NAME$46,
1776
+ create: create$46,
1748
1777
  defaultOptions: []
1749
1778
  });
1750
- function create$45(context) {
1779
+ function create$46(context) {
1751
1780
  if (!context.sourceCode.text.includes("setState")) return {};
1752
1781
  const classStack = [];
1753
1782
  const methodStack = [];
@@ -1869,7 +1898,7 @@ function getIdentifiersFromBinaryExpression(side) {
1869
1898
 
1870
1899
  //#endregion
1871
1900
  //#region src/rules/no-array-index-key/no-array-index-key.ts
1872
- const RULE_NAME$44 = "no-array-index-key";
1901
+ const RULE_NAME$45 = "no-array-index-key";
1873
1902
  var no_array_index_key_default = createRule({
1874
1903
  meta: {
1875
1904
  type: "suggestion",
@@ -1877,11 +1906,11 @@ var no_array_index_key_default = createRule({
1877
1906
  messages: { default: "Do not use item index in the array as its key." },
1878
1907
  schema: []
1879
1908
  },
1880
- name: RULE_NAME$44,
1881
- create: create$44,
1909
+ name: RULE_NAME$45,
1910
+ create: create$45,
1882
1911
  defaultOptions: []
1883
1912
  });
1884
- function create$44(context) {
1913
+ function create$45(context) {
1885
1914
  const indexParamNames = [];
1886
1915
  function isArrayIndex(node) {
1887
1916
  return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
@@ -1947,7 +1976,7 @@ function create$44(context) {
1947
1976
 
1948
1977
  //#endregion
1949
1978
  //#region src/rules/no-children-count/no-children-count.ts
1950
- const RULE_NAME$43 = "no-children-count";
1979
+ const RULE_NAME$44 = "no-children-count";
1951
1980
  var no_children_count_default = createRule({
1952
1981
  meta: {
1953
1982
  type: "suggestion",
@@ -1955,11 +1984,11 @@ var no_children_count_default = createRule({
1955
1984
  messages: { default: "Using 'Children.count' is uncommon and can lead to fragile code. Use alternatives instead." },
1956
1985
  schema: []
1957
1986
  },
1958
- name: RULE_NAME$43,
1959
- create: create$43,
1987
+ name: RULE_NAME$44,
1988
+ create: create$44,
1960
1989
  defaultOptions: []
1961
1990
  });
1962
- function create$43(context) {
1991
+ function create$44(context) {
1963
1992
  return merge({ MemberExpression(node) {
1964
1993
  if (core.isChildrenCount(context, node)) context.report({
1965
1994
  messageId: "default",
@@ -1970,7 +1999,7 @@ function create$43(context) {
1970
1999
 
1971
2000
  //#endregion
1972
2001
  //#region src/rules/no-children-for-each/no-children-for-each.ts
1973
- const RULE_NAME$42 = "no-children-for-each";
2002
+ const RULE_NAME$43 = "no-children-for-each";
1974
2003
  var no_children_for_each_default = createRule({
1975
2004
  meta: {
1976
2005
  type: "suggestion",
@@ -1978,11 +2007,11 @@ var no_children_for_each_default = createRule({
1978
2007
  messages: { default: "Using 'Children.forEach' is uncommon and can lead to fragile code. Use alternatives instead." },
1979
2008
  schema: []
1980
2009
  },
1981
- name: RULE_NAME$42,
1982
- create: create$42,
2010
+ name: RULE_NAME$43,
2011
+ create: create$43,
1983
2012
  defaultOptions: []
1984
2013
  });
1985
- function create$42(context) {
2014
+ function create$43(context) {
1986
2015
  return merge({ MemberExpression(node) {
1987
2016
  if (core.isChildrenForEach(context, node)) context.report({
1988
2017
  messageId: "default",
@@ -1993,7 +2022,7 @@ function create$42(context) {
1993
2022
 
1994
2023
  //#endregion
1995
2024
  //#region src/rules/no-children-map/no-children-map.ts
1996
- const RULE_NAME$41 = "no-children-map";
2025
+ const RULE_NAME$42 = "no-children-map";
1997
2026
  var no_children_map_default = createRule({
1998
2027
  meta: {
1999
2028
  type: "suggestion",
@@ -2001,11 +2030,11 @@ var no_children_map_default = createRule({
2001
2030
  messages: { default: "Using 'Children.map' is uncommon and can lead to fragile code. Use alternatives instead." },
2002
2031
  schema: []
2003
2032
  },
2004
- name: RULE_NAME$41,
2005
- create: create$41,
2033
+ name: RULE_NAME$42,
2034
+ create: create$42,
2006
2035
  defaultOptions: []
2007
2036
  });
2008
- function create$41(context) {
2037
+ function create$42(context) {
2009
2038
  return merge({ MemberExpression(node) {
2010
2039
  if (core.isChildrenMap(context, node)) context.report({
2011
2040
  messageId: "default",
@@ -2016,7 +2045,7 @@ function create$41(context) {
2016
2045
 
2017
2046
  //#endregion
2018
2047
  //#region src/rules/no-children-only/no-children-only.ts
2019
- const RULE_NAME$40 = "no-children-only";
2048
+ const RULE_NAME$41 = "no-children-only";
2020
2049
  var no_children_only_default = createRule({
2021
2050
  meta: {
2022
2051
  type: "suggestion",
@@ -2024,11 +2053,11 @@ var no_children_only_default = createRule({
2024
2053
  messages: { default: "Using 'Children.only' is uncommon and can lead to fragile code. Use alternatives instead." },
2025
2054
  schema: []
2026
2055
  },
2027
- name: RULE_NAME$40,
2028
- create: create$40,
2056
+ name: RULE_NAME$41,
2057
+ create: create$41,
2029
2058
  defaultOptions: []
2030
2059
  });
2031
- function create$40(context) {
2060
+ function create$41(context) {
2032
2061
  return merge({ MemberExpression(node) {
2033
2062
  if (core.isChildrenOnly(context, node)) context.report({
2034
2063
  messageId: "default",
@@ -2039,7 +2068,7 @@ function create$40(context) {
2039
2068
 
2040
2069
  //#endregion
2041
2070
  //#region src/rules/no-children-to-array/no-children-to-array.ts
2042
- const RULE_NAME$39 = "no-children-to-array";
2071
+ const RULE_NAME$40 = "no-children-to-array";
2043
2072
  var no_children_to_array_default = createRule({
2044
2073
  meta: {
2045
2074
  type: "suggestion",
@@ -2047,11 +2076,11 @@ var no_children_to_array_default = createRule({
2047
2076
  messages: { default: "Using 'Children.toArray' is uncommon and can lead to fragile code. Use alternatives instead." },
2048
2077
  schema: []
2049
2078
  },
2050
- name: RULE_NAME$39,
2051
- create: create$39,
2079
+ name: RULE_NAME$40,
2080
+ create: create$40,
2052
2081
  defaultOptions: []
2053
2082
  });
2054
- function create$39(context) {
2083
+ function create$40(context) {
2055
2084
  return merge({ MemberExpression(node) {
2056
2085
  if (core.isChildrenToArray(context, node)) context.report({
2057
2086
  messageId: "default",
@@ -2062,7 +2091,7 @@ function create$39(context) {
2062
2091
 
2063
2092
  //#endregion
2064
2093
  //#region src/rules/no-class-component/no-class-component.ts
2065
- const RULE_NAME$38 = "no-class-component";
2094
+ const RULE_NAME$39 = "no-class-component";
2066
2095
  var no_class_component_default = createRule({
2067
2096
  meta: {
2068
2097
  type: "suggestion",
@@ -2070,11 +2099,11 @@ var no_class_component_default = createRule({
2070
2099
  messages: { default: "Avoid using class components. Use function components instead." },
2071
2100
  schema: []
2072
2101
  },
2073
- name: RULE_NAME$38,
2074
- create: create$38,
2102
+ name: RULE_NAME$39,
2103
+ create: create$39,
2075
2104
  defaultOptions: []
2076
2105
  });
2077
- function create$38(context) {
2106
+ function create$39(context) {
2078
2107
  if (!context.sourceCode.text.includes("Component")) return {};
2079
2108
  const { api, visitor } = core.getClassComponentCollector(context);
2080
2109
  return merge(visitor, { "Program:exit"(program) {
@@ -2091,7 +2120,7 @@ function create$38(context) {
2091
2120
 
2092
2121
  //#endregion
2093
2122
  //#region src/rules/no-clone-element/no-clone-element.ts
2094
- const RULE_NAME$37 = "no-clone-element";
2123
+ const RULE_NAME$38 = "no-clone-element";
2095
2124
  var no_clone_element_default = createRule({
2096
2125
  meta: {
2097
2126
  type: "suggestion",
@@ -2099,11 +2128,11 @@ var no_clone_element_default = createRule({
2099
2128
  messages: { default: "Using 'cloneElement' is uncommon and can lead to fragile code. Use alternatives instead." },
2100
2129
  schema: []
2101
2130
  },
2102
- name: RULE_NAME$37,
2103
- create: create$37,
2131
+ name: RULE_NAME$38,
2132
+ create: create$38,
2104
2133
  defaultOptions: []
2105
2134
  });
2106
- function create$37(context) {
2135
+ function create$38(context) {
2107
2136
  return merge({ CallExpression(node) {
2108
2137
  if (core.isCloneElementCall(context, node)) context.report({
2109
2138
  messageId: "default",
@@ -2114,7 +2143,7 @@ function create$37(context) {
2114
2143
 
2115
2144
  //#endregion
2116
2145
  //#region src/rules/no-component-will-mount/no-component-will-mount.ts
2117
- const RULE_NAME$36 = "no-component-will-mount";
2146
+ const RULE_NAME$37 = "no-component-will-mount";
2118
2147
  var no_component_will_mount_default = createRule({
2119
2148
  meta: {
2120
2149
  type: "problem",
@@ -2123,11 +2152,11 @@ var no_component_will_mount_default = createRule({
2123
2152
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillMount' instead." },
2124
2153
  schema: []
2125
2154
  },
2126
- name: RULE_NAME$36,
2127
- create: create$36,
2155
+ name: RULE_NAME$37,
2156
+ create: create$37,
2128
2157
  defaultOptions: []
2129
2158
  });
2130
- function create$36(context) {
2159
+ function create$37(context) {
2131
2160
  if (!context.sourceCode.text.includes("componentWillMount")) return {};
2132
2161
  const { api, visitor } = core.getClassComponentCollector(context);
2133
2162
  return merge(visitor, { "Program:exit"(program) {
@@ -2147,7 +2176,7 @@ function create$36(context) {
2147
2176
 
2148
2177
  //#endregion
2149
2178
  //#region src/rules/no-component-will-receive-props/no-component-will-receive-props.ts
2150
- const RULE_NAME$35 = "no-component-will-receive-props";
2179
+ const RULE_NAME$36 = "no-component-will-receive-props";
2151
2180
  var no_component_will_receive_props_default = createRule({
2152
2181
  meta: {
2153
2182
  type: "problem",
@@ -2156,11 +2185,11 @@ var no_component_will_receive_props_default = createRule({
2156
2185
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillReceiveProps' instead." },
2157
2186
  schema: []
2158
2187
  },
2159
- name: RULE_NAME$35,
2160
- create: create$35,
2188
+ name: RULE_NAME$36,
2189
+ create: create$36,
2161
2190
  defaultOptions: []
2162
2191
  });
2163
- function create$35(context) {
2192
+ function create$36(context) {
2164
2193
  if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
2165
2194
  const { api, visitor } = core.getClassComponentCollector(context);
2166
2195
  return merge(visitor, { "Program:exit"(program) {
@@ -2180,7 +2209,7 @@ function create$35(context) {
2180
2209
 
2181
2210
  //#endregion
2182
2211
  //#region src/rules/no-component-will-update/no-component-will-update.ts
2183
- const RULE_NAME$34 = "no-component-will-update";
2212
+ const RULE_NAME$35 = "no-component-will-update";
2184
2213
  var no_component_will_update_default = createRule({
2185
2214
  meta: {
2186
2215
  type: "problem",
@@ -2189,11 +2218,11 @@ var no_component_will_update_default = createRule({
2189
2218
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillUpdate' instead." },
2190
2219
  schema: []
2191
2220
  },
2192
- name: RULE_NAME$34,
2193
- create: create$34,
2221
+ name: RULE_NAME$35,
2222
+ create: create$35,
2194
2223
  defaultOptions: []
2195
2224
  });
2196
- function create$34(context) {
2225
+ function create$35(context) {
2197
2226
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
2198
2227
  const { api, visitor } = core.getClassComponentCollector(context);
2199
2228
  return merge(visitor, { "Program:exit"(program) {
@@ -2213,7 +2242,7 @@ function create$34(context) {
2213
2242
 
2214
2243
  //#endregion
2215
2244
  //#region src/rules/no-context-provider/no-context-provider.ts
2216
- const RULE_NAME$33 = "no-context-provider";
2245
+ const RULE_NAME$34 = "no-context-provider";
2217
2246
  var no_context_provider_default = createRule({
2218
2247
  meta: {
2219
2248
  type: "suggestion",
@@ -2226,11 +2255,11 @@ var no_context_provider_default = createRule({
2226
2255
  },
2227
2256
  schema: []
2228
2257
  },
2229
- name: RULE_NAME$33,
2230
- create: create$33,
2258
+ name: RULE_NAME$34,
2259
+ create: create$34,
2231
2260
  defaultOptions: []
2232
2261
  });
2233
- function create$33(context) {
2262
+ function create$34(context) {
2234
2263
  if (!context.sourceCode.text.includes("Provider")) return {};
2235
2264
  const { version } = getSettingsFromContext(context);
2236
2265
  if (compare(version, "19.0.0", "<")) return {};
@@ -2260,7 +2289,7 @@ function create$33(context) {
2260
2289
 
2261
2290
  //#endregion
2262
2291
  //#region src/rules/no-create-ref/no-create-ref.ts
2263
- const RULE_NAME$32 = "no-create-ref";
2292
+ const RULE_NAME$33 = "no-create-ref";
2264
2293
  var no_create_ref_default = createRule({
2265
2294
  meta: {
2266
2295
  type: "suggestion",
@@ -2268,11 +2297,11 @@ var no_create_ref_default = createRule({
2268
2297
  messages: { default: "[Deprecated] Use 'useRef' instead." },
2269
2298
  schema: []
2270
2299
  },
2271
- name: RULE_NAME$32,
2272
- create: create$32,
2300
+ name: RULE_NAME$33,
2301
+ create: create$33,
2273
2302
  defaultOptions: []
2274
2303
  });
2275
- function create$32(context) {
2304
+ function create$33(context) {
2276
2305
  return merge({ CallExpression(node) {
2277
2306
  if (core.isCreateRefCall(context, node) && Traverse.findParent(node, core.isClassComponent) == null) context.report({
2278
2307
  messageId: "default",
@@ -2283,7 +2312,7 @@ function create$32(context) {
2283
2312
 
2284
2313
  //#endregion
2285
2314
  //#region src/rules/no-direct-mutation-state/no-direct-mutation-state.ts
2286
- const RULE_NAME$31 = "no-direct-mutation-state";
2315
+ const RULE_NAME$32 = "no-direct-mutation-state";
2287
2316
  function isConstructorFunction(node) {
2288
2317
  return isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && Check.isPropertyOrMethod(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
2289
2318
  }
@@ -2294,11 +2323,11 @@ var no_direct_mutation_state_default = createRule({
2294
2323
  messages: { default: "Do not mutate state directly. Use 'setState()' instead." },
2295
2324
  schema: []
2296
2325
  },
2297
- name: RULE_NAME$31,
2298
- create: create$31,
2326
+ name: RULE_NAME$32,
2327
+ create: create$32,
2299
2328
  defaultOptions: []
2300
2329
  });
2301
- function create$31(context) {
2330
+ function create$32(context) {
2302
2331
  return merge({ AssignmentExpression(node) {
2303
2332
  if (!core.isAssignmentToThisState(node)) return;
2304
2333
  const parentClass = Traverse.findParent(node, isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
@@ -2312,7 +2341,7 @@ function create$31(context) {
2312
2341
 
2313
2342
  //#endregion
2314
2343
  //#region src/rules/no-duplicate-key/no-duplicate-key.ts
2315
- const RULE_NAME$30 = "no-duplicate-key";
2344
+ const RULE_NAME$31 = "no-duplicate-key";
2316
2345
  var no_duplicate_key_default = createRule({
2317
2346
  meta: {
2318
2347
  type: "problem",
@@ -2320,11 +2349,11 @@ var no_duplicate_key_default = createRule({
2320
2349
  messages: { default: "The 'key' prop must be unique to its sibling elements." },
2321
2350
  schema: []
2322
2351
  },
2323
- name: RULE_NAME$30,
2324
- create: create$30,
2352
+ name: RULE_NAME$31,
2353
+ create: create$31,
2325
2354
  defaultOptions: []
2326
2355
  });
2327
- function create$30(context) {
2356
+ function create$31(context) {
2328
2357
  if (!context.sourceCode.text.includes("key=")) return {};
2329
2358
  const keyedEntries = /* @__PURE__ */ new Map();
2330
2359
  function isKeyValueEqual(a, b) {
@@ -2379,7 +2408,7 @@ function create$30(context) {
2379
2408
 
2380
2409
  //#endregion
2381
2410
  //#region src/rules/no-forward-ref/no-forward-ref.ts
2382
- const RULE_NAME$29 = "no-forward-ref";
2411
+ const RULE_NAME$30 = "no-forward-ref";
2383
2412
  var no_forward_ref_default = createRule({
2384
2413
  meta: {
2385
2414
  type: "suggestion",
@@ -2392,11 +2421,11 @@ var no_forward_ref_default = createRule({
2392
2421
  },
2393
2422
  schema: []
2394
2423
  },
2395
- name: RULE_NAME$29,
2396
- create: create$29,
2424
+ name: RULE_NAME$30,
2425
+ create: create$30,
2397
2426
  defaultOptions: []
2398
2427
  });
2399
- function create$29(context) {
2428
+ function create$30(context) {
2400
2429
  if (!context.sourceCode.text.includes("forwardRef")) return {};
2401
2430
  const { version } = getSettingsFromContext(context);
2402
2431
  if (compare(version, "19.0.0", "<")) return {};
@@ -2501,7 +2530,7 @@ function getComponentPropsFixes(context, fixer, node, typeArguments) {
2501
2530
 
2502
2531
  //#endregion
2503
2532
  //#region src/rules/no-implicit-children/no-implicit-children.ts
2504
- const RULE_NAME$28 = "no-implicit-children";
2533
+ const RULE_NAME$29 = "no-implicit-children";
2505
2534
  const RE_REACT_CHILDREN_TYPE = /react\.(reactnode|reactelement|reactportal)$/i;
2506
2535
  var no_implicit_children_default = createRule({
2507
2536
  meta: {
@@ -2510,11 +2539,11 @@ var no_implicit_children_default = createRule({
2510
2539
  messages: { default: "This spread attribute implicitly passes the 'children' prop to a component, this could lead to unexpected behavior. If you intend to pass the 'children' prop, use 'children={value}'." },
2511
2540
  schema: []
2512
2541
  },
2513
- name: RULE_NAME$28,
2514
- create: create$28,
2542
+ name: RULE_NAME$29,
2543
+ create: create$29,
2515
2544
  defaultOptions: []
2516
2545
  });
2517
- function create$28(context) {
2546
+ function create$29(context) {
2518
2547
  const services = ESLintUtils.getParserServices(context, false);
2519
2548
  const checker = services.program.getTypeChecker();
2520
2549
  return merge({ JSXSpreadAttribute(node) {
@@ -2539,7 +2568,7 @@ function create$28(context) {
2539
2568
 
2540
2569
  //#endregion
2541
2570
  //#region src/rules/no-implicit-key/no-implicit-key.ts
2542
- const RULE_NAME$27 = "no-implicit-key";
2571
+ const RULE_NAME$28 = "no-implicit-key";
2543
2572
  var no_implicit_key_default = createRule({
2544
2573
  meta: {
2545
2574
  type: "problem",
@@ -2547,11 +2576,11 @@ var no_implicit_key_default = createRule({
2547
2576
  messages: { default: "This spread attribute implicitly passes the 'key' prop to a component, this could lead to unexpected behavior. If you intend to pass the 'key' prop, use 'key={value}'." },
2548
2577
  schema: []
2549
2578
  },
2550
- name: RULE_NAME$27,
2551
- create: create$27,
2579
+ name: RULE_NAME$28,
2580
+ create: create$28,
2552
2581
  defaultOptions: []
2553
2582
  });
2554
- function create$27(context) {
2583
+ function create$28(context) {
2555
2584
  const services = ESLintUtils.getParserServices(context, false);
2556
2585
  const checker = services.program.getTypeChecker();
2557
2586
  return merge({ JSXSpreadAttribute(node) {
@@ -2573,7 +2602,7 @@ function create$27(context) {
2573
2602
 
2574
2603
  //#endregion
2575
2604
  //#region src/rules/no-implicit-ref/no-implicit-ref.ts
2576
- const RULE_NAME$26 = "no-implicit-ref";
2605
+ const RULE_NAME$27 = "no-implicit-ref";
2577
2606
  const RE_REACT_REF_TYPE = /react\.(ref|legacyref|refcallback|refobject)$/i;
2578
2607
  var no_implicit_ref_default = createRule({
2579
2608
  meta: {
@@ -2582,11 +2611,11 @@ var no_implicit_ref_default = createRule({
2582
2611
  messages: { default: "This spread attribute implicitly passes the 'ref' prop to a component, this could lead to unexpected behavior. If you intend to pass the 'ref' prop, use 'ref={value}'." },
2583
2612
  schema: []
2584
2613
  },
2585
- name: RULE_NAME$26,
2586
- create: create$26,
2614
+ name: RULE_NAME$27,
2615
+ create: create$27,
2587
2616
  defaultOptions: []
2588
2617
  });
2589
- function create$26(context) {
2618
+ function create$27(context) {
2590
2619
  const services = ESLintUtils.getParserServices(context, false);
2591
2620
  const checker = services.program.getTypeChecker();
2592
2621
  return merge({ JSXSpreadAttribute(node) {
@@ -2624,7 +2653,7 @@ function report$1(context) {
2624
2653
 
2625
2654
  //#endregion
2626
2655
  //#region src/rules/no-leaked-conditional-rendering/no-leaked-conditional-rendering.ts
2627
- const RULE_NAME$25 = "no-leaked-conditional-rendering";
2656
+ const RULE_NAME$26 = "no-leaked-conditional-rendering";
2628
2657
  var no_leaked_conditional_rendering_default = createRule({
2629
2658
  meta: {
2630
2659
  type: "problem",
@@ -2632,11 +2661,11 @@ var no_leaked_conditional_rendering_default = createRule({
2632
2661
  messages: { default: "Potential leaked value {{value}} that might cause unintentionally rendered values or rendering crashes." },
2633
2662
  schema: []
2634
2663
  },
2635
- name: RULE_NAME$25,
2636
- create: create$25,
2664
+ name: RULE_NAME$26,
2665
+ create: create$26,
2637
2666
  defaultOptions: []
2638
2667
  });
2639
- function create$25(context) {
2668
+ function create$26(context) {
2640
2669
  if (!context.sourceCode.text.includes("&&")) return {};
2641
2670
  const { version } = getSettingsFromContext(context);
2642
2671
  const allowedVariants = [
@@ -2694,7 +2723,7 @@ function create$25(context) {
2694
2723
 
2695
2724
  //#endregion
2696
2725
  //#region src/rules/no-missing-component-display-name/no-missing-component-display-name.ts
2697
- const RULE_NAME$24 = "no-missing-component-display-name";
2726
+ const RULE_NAME$25 = "no-missing-component-display-name";
2698
2727
  var no_missing_component_display_name_default = createRule({
2699
2728
  meta: {
2700
2729
  type: "suggestion",
@@ -2702,11 +2731,11 @@ var no_missing_component_display_name_default = createRule({
2702
2731
  messages: { default: "Add missing 'displayName' for component." },
2703
2732
  schema: []
2704
2733
  },
2705
- name: RULE_NAME$24,
2706
- create: create$24,
2734
+ name: RULE_NAME$25,
2735
+ create: create$25,
2707
2736
  defaultOptions: []
2708
2737
  });
2709
- function create$24(context) {
2738
+ function create$25(context) {
2710
2739
  if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
2711
2740
  const { api, visitor } = core.getFunctionComponentCollector(context, {
2712
2741
  collectDisplayName: true,
@@ -2728,7 +2757,7 @@ function create$24(context) {
2728
2757
 
2729
2758
  //#endregion
2730
2759
  //#region src/rules/no-missing-context-display-name/no-missing-context-display-name.ts
2731
- const RULE_NAME$23 = "no-missing-context-display-name";
2760
+ const RULE_NAME$24 = "no-missing-context-display-name";
2732
2761
  var no_missing_context_display_name_default = createRule({
2733
2762
  meta: {
2734
2763
  type: "suggestion",
@@ -2737,11 +2766,11 @@ var no_missing_context_display_name_default = createRule({
2737
2766
  messages: { default: "Add missing 'displayName' for context." },
2738
2767
  schema: []
2739
2768
  },
2740
- name: RULE_NAME$23,
2741
- create: create$23,
2769
+ name: RULE_NAME$24,
2770
+ create: create$24,
2742
2771
  defaultOptions: []
2743
2772
  });
2744
- function create$23(context) {
2773
+ function create$24(context) {
2745
2774
  if (!context.sourceCode.text.includes("createContext")) return {};
2746
2775
  const createCalls = [];
2747
2776
  const displayNameAssignments = [];
@@ -2822,7 +2851,7 @@ function getNestedReturnStatements(node) {
2822
2851
 
2823
2852
  //#endregion
2824
2853
  //#region src/rules/no-missing-key/no-missing-key.ts
2825
- const RULE_NAME$22 = "no-missing-key";
2854
+ const RULE_NAME$23 = "no-missing-key";
2826
2855
  var no_missing_key_default = createRule({
2827
2856
  meta: {
2828
2857
  type: "problem",
@@ -2833,11 +2862,11 @@ var no_missing_key_default = createRule({
2833
2862
  },
2834
2863
  schema: []
2835
2864
  },
2836
- name: RULE_NAME$22,
2837
- create: create$22,
2865
+ name: RULE_NAME$23,
2866
+ create: create$23,
2838
2867
  defaultOptions: []
2839
2868
  });
2840
- function create$22(context) {
2869
+ function create$23(context) {
2841
2870
  let inChildrenToArray = false;
2842
2871
  function check(node) {
2843
2872
  if (node.type === AST_NODE_TYPES.JSXElement) return !hasAttribute(context, node, "key") ? {
@@ -2937,7 +2966,7 @@ function isDevelopmentOnlyCheck(node) {
2937
2966
 
2938
2967
  //#endregion
2939
2968
  //#region src/rules/no-misused-capture-owner-stack/no-misused-capture-owner-stack.ts
2940
- const RULE_NAME$21 = "no-misused-capture-owner-stack";
2969
+ const RULE_NAME$22 = "no-misused-capture-owner-stack";
2941
2970
  var no_misused_capture_owner_stack_default = createRule({
2942
2971
  meta: {
2943
2972
  type: "problem",
@@ -2948,11 +2977,11 @@ var no_misused_capture_owner_stack_default = createRule({
2948
2977
  },
2949
2978
  schema: []
2950
2979
  },
2951
- name: RULE_NAME$21,
2952
- create: create$21,
2980
+ name: RULE_NAME$22,
2981
+ create: create$22,
2953
2982
  defaultOptions: []
2954
2983
  });
2955
- function create$21(context) {
2984
+ function create$22(context) {
2956
2985
  if (!context.sourceCode.text.includes("captureOwnerStack")) return {};
2957
2986
  const { importSource } = getSettingsFromContext(context);
2958
2987
  return merge({
@@ -3012,7 +3041,7 @@ function isInsideCreateElementProps(context, node) {
3012
3041
 
3013
3042
  //#endregion
3014
3043
  //#region src/rules/no-nested-component-definitions/no-nested-component-definitions.ts
3015
- const RULE_NAME$20 = "no-nested-component-definitions";
3044
+ const RULE_NAME$21 = "no-nested-component-definitions";
3016
3045
  var no_nested_component_definitions_default = createRule({
3017
3046
  meta: {
3018
3047
  type: "problem",
@@ -3020,11 +3049,11 @@ var no_nested_component_definitions_default = createRule({
3020
3049
  messages: { default: "Do not nest component definitions inside other components or props. {{suggestion}}" },
3021
3050
  schema: []
3022
3051
  },
3023
- name: RULE_NAME$20,
3024
- create: create$20,
3052
+ name: RULE_NAME$21,
3053
+ create: create$21,
3025
3054
  defaultOptions: []
3026
3055
  });
3027
- function create$20(context) {
3056
+ function create$21(context) {
3028
3057
  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;
3029
3058
  const fc = core.getFunctionComponentCollector(context, { hint });
3030
3059
  const cc = core.getClassComponentCollector(context);
@@ -3098,7 +3127,7 @@ function create$20(context) {
3098
3127
 
3099
3128
  //#endregion
3100
3129
  //#region src/rules/no-nested-lazy-component-declarations/no-nested-lazy-component-declarations.ts
3101
- const RULE_NAME$19 = "no-nested-lazy-component-declarations";
3130
+ const RULE_NAME$20 = "no-nested-lazy-component-declarations";
3102
3131
  var no_nested_lazy_component_declarations_default = createRule({
3103
3132
  meta: {
3104
3133
  type: "problem",
@@ -3106,11 +3135,11 @@ var no_nested_lazy_component_declarations_default = createRule({
3106
3135
  messages: { default: "Do not declare lazy components inside other components or hooks. Instead, always declare them at the top level of your module." },
3107
3136
  schema: []
3108
3137
  },
3109
- name: RULE_NAME$19,
3110
- create: create$19,
3138
+ name: RULE_NAME$20,
3139
+ create: create$20,
3111
3140
  defaultOptions: []
3112
3141
  });
3113
- function create$19(context) {
3142
+ function create$20(context) {
3114
3143
  const fc = core.getFunctionComponentCollector(context);
3115
3144
  const cc = core.getClassComponentCollector(context);
3116
3145
  const hc = core.getHookCollector(context);
@@ -3136,7 +3165,7 @@ function create$19(context) {
3136
3165
 
3137
3166
  //#endregion
3138
3167
  //#region src/rules/no-set-state-in-component-did-mount/no-set-state-in-component-did-mount.ts
3139
- const RULE_NAME$18 = "no-set-state-in-component-did-mount";
3168
+ const RULE_NAME$19 = "no-set-state-in-component-did-mount";
3140
3169
  var no_set_state_in_component_did_mount_default = createRule({
3141
3170
  meta: {
3142
3171
  type: "problem",
@@ -3144,11 +3173,11 @@ var no_set_state_in_component_did_mount_default = createRule({
3144
3173
  messages: { default: "Do not call `this.setState` in `componentDidMount` outside functions such as callbacks." },
3145
3174
  schema: []
3146
3175
  },
3147
- name: RULE_NAME$18,
3148
- create: create$18,
3176
+ name: RULE_NAME$19,
3177
+ create: create$19,
3149
3178
  defaultOptions: []
3150
3179
  });
3151
- function create$18(context) {
3180
+ function create$19(context) {
3152
3181
  if (!context.sourceCode.text.includes("componentDidMount")) return {};
3153
3182
  return merge({ CallExpression(node) {
3154
3183
  if (!core.isThisSetStateCall(node)) return;
@@ -3166,7 +3195,7 @@ function create$18(context) {
3166
3195
 
3167
3196
  //#endregion
3168
3197
  //#region src/rules/no-set-state-in-component-did-update/no-set-state-in-component-did-update.ts
3169
- const RULE_NAME$17 = "no-set-state-in-component-did-update";
3198
+ const RULE_NAME$18 = "no-set-state-in-component-did-update";
3170
3199
  var no_set_state_in_component_did_update_default = createRule({
3171
3200
  meta: {
3172
3201
  type: "problem",
@@ -3174,11 +3203,11 @@ var no_set_state_in_component_did_update_default = createRule({
3174
3203
  messages: { default: "Do not call `this.setState` in `componentDidUpdate` outside functions such as callbacks." },
3175
3204
  schema: []
3176
3205
  },
3177
- name: RULE_NAME$17,
3178
- create: create$17,
3206
+ name: RULE_NAME$18,
3207
+ create: create$18,
3179
3208
  defaultOptions: []
3180
3209
  });
3181
- function create$17(context) {
3210
+ function create$18(context) {
3182
3211
  if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
3183
3212
  return merge({ CallExpression(node) {
3184
3213
  if (!core.isThisSetStateCall(node)) return;
@@ -3196,7 +3225,7 @@ function create$17(context) {
3196
3225
 
3197
3226
  //#endregion
3198
3227
  //#region src/rules/no-set-state-in-component-will-update/no-set-state-in-component-will-update.ts
3199
- const RULE_NAME$16 = "no-set-state-in-component-will-update";
3228
+ const RULE_NAME$17 = "no-set-state-in-component-will-update";
3200
3229
  var no_set_state_in_component_will_update_default = createRule({
3201
3230
  meta: {
3202
3231
  type: "problem",
@@ -3204,11 +3233,11 @@ var no_set_state_in_component_will_update_default = createRule({
3204
3233
  messages: { default: "Do not call `this.setState` in `componentWillUpdate` outside functions such as callbacks." },
3205
3234
  schema: []
3206
3235
  },
3207
- name: RULE_NAME$16,
3208
- create: create$16,
3236
+ name: RULE_NAME$17,
3237
+ create: create$17,
3209
3238
  defaultOptions: []
3210
3239
  });
3211
- function create$16(context) {
3240
+ function create$17(context) {
3212
3241
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
3213
3242
  return merge({ CallExpression(node) {
3214
3243
  if (!core.isThisSetStateCall(node)) return;
@@ -3239,7 +3268,7 @@ function isTestMockCallback(node) {
3239
3268
 
3240
3269
  //#endregion
3241
3270
  //#region src/rules/no-unnecessary-use-prefix/no-unnecessary-use-prefix.ts
3242
- const RULE_NAME$15 = "no-unnecessary-use-prefix";
3271
+ const RULE_NAME$16 = "no-unnecessary-use-prefix";
3243
3272
  var no_unnecessary_use_prefix_default = createRule({
3244
3273
  meta: {
3245
3274
  type: "problem",
@@ -3247,11 +3276,11 @@ var no_unnecessary_use_prefix_default = createRule({
3247
3276
  messages: { default: "If your function doesn't call any Hooks, avoid the 'use' prefix. Instead, write it as a regular function without the 'use' prefix." },
3248
3277
  schema: []
3249
3278
  },
3250
- name: RULE_NAME$15,
3251
- create: create$15,
3279
+ name: RULE_NAME$16,
3280
+ create: create$16,
3252
3281
  defaultOptions: []
3253
3282
  });
3254
- function create$15(context) {
3283
+ function create$16(context) {
3255
3284
  const { api, visitor } = core.getHookCollector(context);
3256
3285
  return merge(visitor, { "Program:exit"(program) {
3257
3286
  for (const { id, name, hookCalls, node } of api.getAllHooks(program)) {
@@ -3272,7 +3301,7 @@ function create$15(context) {
3272
3301
 
3273
3302
  //#endregion
3274
3303
  //#region src/rules/no-unsafe-component-will-mount/no-unsafe-component-will-mount.ts
3275
- const RULE_NAME$14 = "no-unsafe-component-will-mount";
3304
+ const RULE_NAME$15 = "no-unsafe-component-will-mount";
3276
3305
  var no_unsafe_component_will_mount_default = createRule({
3277
3306
  meta: {
3278
3307
  type: "problem",
@@ -3280,11 +3309,11 @@ var no_unsafe_component_will_mount_default = createRule({
3280
3309
  messages: { default: "Do not use 'UNSAFE_componentWillMount'." },
3281
3310
  schema: []
3282
3311
  },
3283
- name: RULE_NAME$14,
3284
- create: create$14,
3312
+ name: RULE_NAME$15,
3313
+ create: create$15,
3285
3314
  defaultOptions: []
3286
3315
  });
3287
- function create$14(context) {
3316
+ function create$15(context) {
3288
3317
  if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
3289
3318
  const { api, visitor } = core.getClassComponentCollector(context);
3290
3319
  return merge(visitor, { "Program:exit"(program) {
@@ -3300,7 +3329,7 @@ function create$14(context) {
3300
3329
 
3301
3330
  //#endregion
3302
3331
  //#region src/rules/no-unsafe-component-will-receive-props/no-unsafe-component-will-receive-props.ts
3303
- const RULE_NAME$13 = "no-unsafe-component-will-receive-props";
3332
+ const RULE_NAME$14 = "no-unsafe-component-will-receive-props";
3304
3333
  var no_unsafe_component_will_receive_props_default = createRule({
3305
3334
  meta: {
3306
3335
  type: "problem",
@@ -3308,11 +3337,11 @@ var no_unsafe_component_will_receive_props_default = createRule({
3308
3337
  messages: { default: "Do not use 'UNSAFE_componentWillReceiveProps'." },
3309
3338
  schema: []
3310
3339
  },
3311
- name: RULE_NAME$13,
3312
- create: create$13,
3340
+ name: RULE_NAME$14,
3341
+ create: create$14,
3313
3342
  defaultOptions: []
3314
3343
  });
3315
- function create$13(context) {
3344
+ function create$14(context) {
3316
3345
  if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
3317
3346
  const { api, visitor } = core.getClassComponentCollector(context);
3318
3347
  return merge(visitor, { "Program:exit"(program) {
@@ -3328,7 +3357,7 @@ function create$13(context) {
3328
3357
 
3329
3358
  //#endregion
3330
3359
  //#region src/rules/no-unsafe-component-will-update/no-unsafe-component-will-update.ts
3331
- const RULE_NAME$12 = "no-unsafe-component-will-update";
3360
+ const RULE_NAME$13 = "no-unsafe-component-will-update";
3332
3361
  var no_unsafe_component_will_update_default = createRule({
3333
3362
  meta: {
3334
3363
  type: "problem",
@@ -3336,11 +3365,11 @@ var no_unsafe_component_will_update_default = createRule({
3336
3365
  messages: { default: "Do not use 'UNSAFE_componentWillUpdate'." },
3337
3366
  schema: []
3338
3367
  },
3339
- name: RULE_NAME$12,
3340
- create: create$12,
3368
+ name: RULE_NAME$13,
3369
+ create: create$13,
3341
3370
  defaultOptions: []
3342
3371
  });
3343
- function create$12(context) {
3372
+ function create$13(context) {
3344
3373
  if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
3345
3374
  const { api, visitor } = core.getClassComponentCollector(context);
3346
3375
  return merge(visitor, { "Program:exit"(program) {
@@ -3364,7 +3393,7 @@ function isContextName(name, isReact18OrBelow) {
3364
3393
 
3365
3394
  //#endregion
3366
3395
  //#region src/rules/no-unstable-context-value/no-unstable-context-value.ts
3367
- const RULE_NAME$11 = "no-unstable-context-value";
3396
+ const RULE_NAME$12 = "no-unstable-context-value";
3368
3397
  var no_unstable_context_value_default = createRule({
3369
3398
  meta: {
3370
3399
  type: "problem",
@@ -3372,11 +3401,11 @@ var no_unstable_context_value_default = createRule({
3372
3401
  messages: { unstableContextValue: "A/an '{{kind}}' passed as the value prop to the context provider should not be constructed. It will change on every render. {{suggestion}}" },
3373
3402
  schema: []
3374
3403
  },
3375
- name: RULE_NAME$11,
3376
- create: create$11,
3404
+ name: RULE_NAME$12,
3405
+ create: create$12,
3377
3406
  defaultOptions: []
3378
3407
  });
3379
- function create$11(context) {
3408
+ function create$12(context) {
3380
3409
  const { compilationMode, version } = getSettingsFromContext(context);
3381
3410
  if (compilationMode === "infer" || compilationMode === "all") return {};
3382
3411
  if (compilationMode === "annotation" && context.sourceCode.ast.body.some(Check.isDirective("use memo"))) return {};
@@ -3431,7 +3460,7 @@ const SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR = [
3431
3460
 
3432
3461
  //#endregion
3433
3462
  //#region src/rules/no-unstable-default-props/no-unstable-default-props.ts
3434
- const RULE_NAME$10 = "no-unstable-default-props";
3463
+ const RULE_NAME$11 = "no-unstable-default-props";
3435
3464
  const defaultOptions$1 = [{ safeDefaultProps: [] }];
3436
3465
  const schema$1 = [{
3437
3466
  type: "object",
@@ -3448,8 +3477,8 @@ var no_unstable_default_props_default = createRule({
3448
3477
  messages: { default: "A/an '{{kind}}' as default prop. This could lead to potential infinite render loop in React. Use a variable instead of '{{kind}}'." },
3449
3478
  schema: schema$1
3450
3479
  },
3451
- name: RULE_NAME$10,
3452
- create: create$10,
3480
+ name: RULE_NAME$11,
3481
+ create: create$11,
3453
3482
  defaultOptions: defaultOptions$1
3454
3483
  });
3455
3484
  function extractIdentifier(node) {
@@ -3460,7 +3489,7 @@ function extractIdentifier(node) {
3460
3489
  }
3461
3490
  return null;
3462
3491
  }
3463
- function create$10(context, [options]) {
3492
+ function create$11(context, [options]) {
3464
3493
  const { compilationMode } = getSettingsFromContext(context);
3465
3494
  if (compilationMode === "infer" || compilationMode === "all") return {};
3466
3495
  if (compilationMode === "annotation" && context.sourceCode.ast.body.some(Check.isDirective("use memo"))) return {};
@@ -3532,7 +3561,7 @@ function isKeyLiteral(node, key) {
3532
3561
 
3533
3562
  //#endregion
3534
3563
  //#region src/rules/no-unused-class-component-members/no-unused-class-component-members.ts
3535
- const RULE_NAME$9 = "no-unused-class-component-members";
3564
+ const RULE_NAME$10 = "no-unused-class-component-members";
3536
3565
  var no_unused_class_component_members_default = createRule({
3537
3566
  meta: {
3538
3567
  type: "suggestion",
@@ -3540,11 +3569,11 @@ var no_unused_class_component_members_default = createRule({
3540
3569
  messages: { default: "Unused method or property '{{methodName}}'' of class '{{className}}'." },
3541
3570
  schema: []
3542
3571
  },
3543
- name: RULE_NAME$9,
3544
- create: create$9,
3572
+ name: RULE_NAME$10,
3573
+ create: create$10,
3545
3574
  defaultOptions: []
3546
3575
  });
3547
- function create$9(context) {
3576
+ function create$10(context) {
3548
3577
  const classStack = [];
3549
3578
  const methodStack = [];
3550
3579
  const propertyDefs = /* @__PURE__ */ new WeakMap();
@@ -3692,7 +3721,7 @@ function getKeyOfExpression(expr) {
3692
3721
 
3693
3722
  //#endregion
3694
3723
  //#region src/rules/no-unused-props/no-unused-props.ts
3695
- const RULE_NAME$8 = "no-unused-props";
3724
+ const RULE_NAME$9 = "no-unused-props";
3696
3725
  var no_unused_props_default = createRule({
3697
3726
  meta: {
3698
3727
  type: "suggestion",
@@ -3700,11 +3729,11 @@ var no_unused_props_default = createRule({
3700
3729
  messages: { default: "Prop `{{name}}` is declared but never used" },
3701
3730
  schema: []
3702
3731
  },
3703
- name: RULE_NAME$8,
3704
- create: create$8,
3732
+ name: RULE_NAME$9,
3733
+ create: create$9,
3705
3734
  defaultOptions: []
3706
3735
  });
3707
- function create$8(context) {
3736
+ function create$9(context) {
3708
3737
  const services = ESLintUtils.getParserServices(context, false);
3709
3738
  const checker = services.program.getTypeChecker();
3710
3739
  const { api, visitor } = core.getFunctionComponentCollector(context);
@@ -3743,7 +3772,7 @@ function reportUnusedProp(context, services, prop) {
3743
3772
 
3744
3773
  //#endregion
3745
3774
  //#region src/rules/no-use-context/no-use-context.ts
3746
- const RULE_NAME$7 = "no-use-context";
3775
+ const RULE_NAME$8 = "no-use-context";
3747
3776
  var no_use_context_default = createRule({
3748
3777
  meta: {
3749
3778
  type: "suggestion",
@@ -3756,11 +3785,11 @@ var no_use_context_default = createRule({
3756
3785
  },
3757
3786
  schema: []
3758
3787
  },
3759
- name: RULE_NAME$7,
3760
- create: create$7,
3788
+ name: RULE_NAME$8,
3789
+ create: create$8,
3761
3790
  defaultOptions: []
3762
3791
  });
3763
- function create$7(context) {
3792
+ function create$8(context) {
3764
3793
  if (!context.sourceCode.text.includes("useContext")) return {};
3765
3794
  const { version } = getSettingsFromContext(context);
3766
3795
  if (compare(version, "19.0.0", "<")) return {};
@@ -4069,7 +4098,7 @@ const IMPURE_CTORS = new Set([
4069
4098
 
4070
4099
  //#endregion
4071
4100
  //#region src/rules/purity/purity.ts
4072
- const RULE_NAME$6 = "purity";
4101
+ const RULE_NAME$7 = "purity";
4073
4102
  var purity_default = createRule({
4074
4103
  meta: {
4075
4104
  type: "problem",
@@ -4077,11 +4106,38 @@ var purity_default = createRule({
4077
4106
  messages: { default: "Do not call '{{name}}' during render. Components and hooks must be pure. Move this call into an event handler, effect, or state initializer." },
4078
4107
  schema: []
4079
4108
  },
4080
- name: RULE_NAME$6,
4081
- create: create$6,
4109
+ name: RULE_NAME$7,
4110
+ create: create$7,
4082
4111
  defaultOptions: []
4083
4112
  });
4084
- function create$6(context) {
4113
+ /**
4114
+ * Recursively resolve an identifier to the root builtin global object name.
4115
+ * Follows simple assignment chains like `const M = Math` or `const w = window`.
4116
+ * Returns `null` if the identifier is locally defined (parameter, import, function declaration, etc.)
4117
+ * or resolves to a non-builtin source.
4118
+ * @param context
4119
+ * @param node
4120
+ * @param visited
4121
+ */
4122
+ function resolveBuiltinObjectName(context, node, visited = /* @__PURE__ */ new Set()) {
4123
+ if (visited.has(node.name)) return null;
4124
+ visited.add(node.name);
4125
+ const variable = findVariable(context.sourceCode.getScope(node), node);
4126
+ if (variable == null) return node.name;
4127
+ const def = variable.defs[0];
4128
+ if (def == null) return node.name;
4129
+ if (def.type === DefinitionType.ImplicitGlobalVariable) return node.name;
4130
+ if (def.type === DefinitionType.Variable && def.node.init != null) {
4131
+ const init = Extract.unwrap(def.node.init);
4132
+ if (init.type === AST_NODE_TYPES.Identifier) return resolveBuiltinObjectName(context, init, visited);
4133
+ if (init.type === AST_NODE_TYPES.MemberExpression) {
4134
+ const rootId = Extract.getRootIdentifier(init);
4135
+ if (rootId != null) return resolveBuiltinObjectName(context, rootId, visited);
4136
+ }
4137
+ }
4138
+ return null;
4139
+ }
4140
+ function create$7(context) {
4085
4141
  const hc = core.getHookCollector(context);
4086
4142
  const fc = core.getFunctionComponentCollector(context);
4087
4143
  const cEntries = [];
@@ -4091,7 +4147,9 @@ function create$6(context) {
4091
4147
  const expr = Extract.unwrap(node.callee);
4092
4148
  switch (true) {
4093
4149
  case expr.type === AST_NODE_TYPES.Identifier: {
4094
- if (!IMPURE_FUNCS.get("globalThis")?.has(expr.name)) return;
4150
+ const builtinName = resolveBuiltinObjectName(context, expr);
4151
+ if (builtinName == null) return;
4152
+ if (!IMPURE_FUNCS.get("globalThis")?.has(builtinName)) return;
4095
4153
  const func = Traverse.findParent(node, Check.isFunction);
4096
4154
  if (func == null) return;
4097
4155
  cEntries.push({
@@ -4100,8 +4158,11 @@ function create$6(context) {
4100
4158
  });
4101
4159
  break;
4102
4160
  }
4103
- case expr.type === AST_NODE_TYPES.MemberExpression && expr.object.type === AST_NODE_TYPES.Identifier && expr.property.type === AST_NODE_TYPES.Identifier: {
4104
- const objectName = expr.object.name;
4161
+ case expr.type === AST_NODE_TYPES.MemberExpression && expr.property.type === AST_NODE_TYPES.Identifier: {
4162
+ const rootId = Extract.getRootIdentifier(expr.object);
4163
+ if (rootId == null) return;
4164
+ const objectName = resolveBuiltinObjectName(context, rootId);
4165
+ if (objectName == null) return;
4105
4166
  const propertyName = expr.property.name;
4106
4167
  if (!IMPURE_FUNCS.get(objectName)?.has(propertyName)) return;
4107
4168
  const func = Traverse.findParent(node, Check.isFunction);
@@ -4117,8 +4178,10 @@ function create$6(context) {
4117
4178
  NewExpression(node) {
4118
4179
  const expr = Extract.unwrap(node.callee);
4119
4180
  if (expr.type !== AST_NODE_TYPES.Identifier) return;
4120
- if (!IMPURE_CTORS.has(expr.name)) return;
4121
- if (expr.name === "Date" && node.arguments.length > 0) return;
4181
+ const builtinName = resolveBuiltinObjectName(context, expr);
4182
+ if (builtinName == null) return;
4183
+ if (!IMPURE_CTORS.has(builtinName)) return;
4184
+ if (builtinName === "Date" && node.arguments.length > 0) return;
4122
4185
  const func = Traverse.findParent(node, Check.isFunction);
4123
4186
  if (func == null) return;
4124
4187
  nEntries.push({
@@ -4152,32 +4215,57 @@ function create$6(context) {
4152
4215
  function isInNullCheckTest(node) {
4153
4216
  let parent = node.parent;
4154
4217
  while (Check.isTypeExpression(parent)) parent = parent.parent;
4155
- if (!isMatching({
4156
- type: AST_NODE_TYPES.BinaryExpression,
4157
- operator: P.union("===", "==", "!==", "!=")
4158
- }, parent)) return false;
4159
- const otherSide = parent.left === node || Extract.unwrap(parent.left) === node ? parent.right : parent.left;
4160
- if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
4161
- return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
4218
+ const isNullCompareBinary = (n) => {
4219
+ return n.type === AST_NODE_TYPES.BinaryExpression && /^(===|==|!==|!=)$/.test(n.operator);
4220
+ };
4221
+ const isLiteralNull = (n) => {
4222
+ return n.type === AST_NODE_TYPES.Literal && n.value == null;
4223
+ };
4224
+ const isIfTest = (testNode) => {
4225
+ return testNode.parent?.type === AST_NODE_TYPES.IfStatement && testNode.parent.test === testNode;
4226
+ };
4227
+ if (isNullCompareBinary(parent)) {
4228
+ if (!isLiteralNull(parent.left === node || Extract.unwrap(parent.left) === node ? parent.right : parent.left)) return false;
4229
+ if (isIfTest(parent)) return true;
4230
+ const grandparent = parent.parent;
4231
+ if (grandparent?.type === AST_NODE_TYPES.UnaryExpression && grandparent.operator === "!" && isIfTest(grandparent)) return true;
4232
+ return false;
4233
+ }
4234
+ if (parent.type === AST_NODE_TYPES.UnaryExpression && parent.operator === "!") return isIfTest(parent);
4235
+ return false;
4162
4236
  }
4163
- /**
4164
- * Check if a test expression is a null check on `ref.current` for a given ref name.
4165
- * Matches forms like `ref.current === null`, `null === ref.current`, and their != variants.
4166
- * @param test The test expression to check.
4167
- * @param refName The name of the ref variable.
4168
- */
4169
- function isRefCurrentNullCheck(test, refName) {
4237
+ function isBinaryNullCheck(test, refName) {
4170
4238
  if (test.type !== AST_NODE_TYPES.BinaryExpression) return false;
4171
- const op = test.operator;
4172
- if (op !== "===" && op !== "==" && op !== "!==" && op !== "!=") return false;
4239
+ if (!/^(===|==|!==|!=)$/.test(test.operator)) return false;
4173
4240
  const { left, right } = test;
4174
4241
  const checkSides = (a, b) => {
4175
4242
  a = Check.isTypeExpression(a) ? Extract.unwrap(a) : a;
4176
- const obj = a.type === AST_NODE_TYPES.MemberExpression ? Extract.unwrap(a.object) : null;
4177
- return a.type === AST_NODE_TYPES.MemberExpression && obj?.type === AST_NODE_TYPES.Identifier && obj.name === refName && b.type === AST_NODE_TYPES.Literal && b.value == null && Extract.getPropertyName(a.property) === "current";
4243
+ if (a.type !== AST_NODE_TYPES.MemberExpression) return false;
4244
+ if (Extract.getPropertyName(a.property) !== "current") return false;
4245
+ const obj = Extract.unwrap(a.object);
4246
+ return obj.type === AST_NODE_TYPES.Identifier && obj.name === refName && b.type === AST_NODE_TYPES.Literal && b.value == null;
4178
4247
  };
4179
4248
  return checkSides(left, right) || checkSides(right, left);
4180
4249
  }
4250
+ /**
4251
+ * Check if a test expression is a null check on `ref.current` for a given ref name.
4252
+ * Matches forms like `ref.current === null`, `null === ref.current`, `!ref.current`,
4253
+ * `!(ref.current === null)`, and their != variants.
4254
+ * @param test The test expression to check.
4255
+ * @param refName The name of the ref variable.
4256
+ */
4257
+ function isRefCurrentNullCheck(test, refName) {
4258
+ if (isBinaryNullCheck(test, refName)) return true;
4259
+ if (test.type === AST_NODE_TYPES.UnaryExpression && test.operator === "!") {
4260
+ const arg = Extract.unwrap(test.argument);
4261
+ if (arg.type === AST_NODE_TYPES.MemberExpression) {
4262
+ const obj = Extract.unwrap(arg.object);
4263
+ return obj.type === AST_NODE_TYPES.Identifier && obj.name === refName && Extract.getPropertyName(arg.property) === "current";
4264
+ }
4265
+ return isBinaryNullCheck(arg, refName);
4266
+ }
4267
+ return false;
4268
+ }
4181
4269
  function isInitializedFromRef$1(context, name, initialScope) {
4182
4270
  for (const { node } of findVariable(initialScope, name)?.defs ?? []) {
4183
4271
  if (node.type !== AST_NODE_TYPES.VariableDeclarator) continue;
@@ -4197,27 +4285,59 @@ function isInitializedFromRef$1(context, name, initialScope) {
4197
4285
 
4198
4286
  //#endregion
4199
4287
  //#region src/rules/refs/refs.ts
4200
- const RULE_NAME$5 = "refs";
4288
+ const RULE_NAME$6 = "refs";
4201
4289
  var refs_default = createRule({
4202
4290
  meta: {
4203
4291
  type: "problem",
4204
4292
  docs: { description: "Validates correct usage of refs by checking that 'ref.current' is not read or written during render." },
4205
4293
  messages: {
4206
4294
  readDuringRender: "Do not read 'ref.current' during render. Refs are not available during rendering and their values may be stale or inconsistent. Move this read into an effect or event handler.",
4295
+ refPassedToFunction: "Passing a ref to a function may cause its value to be read during render. Pass 'ref.current' instead if the function only needs the value, or move the call into an effect.",
4207
4296
  writeDuringRender: "Do not write to 'ref.current' during render. Refs should only be mutated in effects or event handlers. Move this write into an effect or event handler."
4208
4297
  },
4209
4298
  schema: []
4210
4299
  },
4211
- name: RULE_NAME$5,
4212
- create: create$5,
4300
+ name: RULE_NAME$6,
4301
+ create: create$6,
4213
4302
  defaultOptions: []
4214
4303
  });
4215
- function create$5(context) {
4304
+ function resolveAlias(name, aliases) {
4305
+ const visited = /* @__PURE__ */ new Set();
4306
+ while (aliases.has(name) && !visited.has(name)) {
4307
+ visited.add(name);
4308
+ name = aliases.get(name);
4309
+ }
4310
+ return name;
4311
+ }
4312
+ function create$6(context) {
4216
4313
  const hc = core.getHookCollector(context);
4217
4314
  const fc = core.getFunctionComponentCollector(context);
4218
4315
  const refAccesses = [];
4219
4316
  const jsxRefIdentifiers = /* @__PURE__ */ new Set();
4317
+ const aliases = /* @__PURE__ */ new Map();
4318
+ const refPassedToFunctions = [];
4220
4319
  return merge(hc.visitor, fc.visitor, {
4320
+ AssignmentExpression(node) {
4321
+ if (node.operator !== "=") return;
4322
+ const left = Extract.unwrap(node.left);
4323
+ const right = Extract.unwrap(node.right);
4324
+ if (left.type !== AST_NODE_TYPES.Identifier || right.type !== AST_NODE_TYPES.Identifier) return;
4325
+ aliases.set(left.name, right.name);
4326
+ },
4327
+ CallExpression(node) {
4328
+ const callee = Extract.unwrap(node.callee);
4329
+ const calleeName = callee.type === AST_NODE_TYPES.Identifier ? callee.name : callee.type === AST_NODE_TYPES.MemberExpression ? Extract.getPropertyName(callee.property) : null;
4330
+ if (calleeName != null && (calleeName.startsWith("use") || calleeName === "mergeRefs")) return;
4331
+ for (const arg of node.arguments) {
4332
+ const unwrapped = Extract.unwrap(arg);
4333
+ if (unwrapped.type !== AST_NODE_TYPES.Identifier) continue;
4334
+ const resolvedName = resolveAlias(unwrapped.name, aliases);
4335
+ if (resolvedName === "ref" || resolvedName.endsWith("Ref") || jsxRefIdentifiers.has(resolvedName) || isInitializedFromRef$1(context, resolvedName, context.sourceCode.getScope(unwrapped))) refPassedToFunctions.push({
4336
+ callNode: node,
4337
+ node: unwrapped
4338
+ });
4339
+ }
4340
+ },
4221
4341
  JSXAttribute(node) {
4222
4342
  switch (true) {
4223
4343
  case node.name.type === AST_NODE_TYPES.JSXIdentifier && node.name.name === "ref" && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer: {
@@ -4228,7 +4348,7 @@ function create$5(context) {
4228
4348
  }
4229
4349
  },
4230
4350
  MemberExpression(node) {
4231
- if (!Check.isIdentifier("current")(node.property)) return;
4351
+ if (Extract.getPropertyName(node.property) !== "current") return;
4232
4352
  refAccesses.push({
4233
4353
  isWrite: (() => {
4234
4354
  let parent = node.parent;
@@ -4246,16 +4366,17 @@ function create$5(context) {
4246
4366
  for (const { isWrite, node } of refAccesses) {
4247
4367
  const obj = Extract.unwrap(node.object);
4248
4368
  if (obj.type !== AST_NODE_TYPES.Identifier) continue;
4369
+ const resolvedName = resolveAlias(obj.name, aliases);
4249
4370
  switch (true) {
4250
- case obj.name === "ref" || obj.name.endsWith("Ref"):
4251
- case jsxRefIdentifiers.has(obj.name):
4252
- case isInitializedFromRef$1(context, obj.name, context.sourceCode.getScope(node.object)): break;
4371
+ case resolvedName === "ref" || resolvedName.endsWith("Ref"):
4372
+ case jsxRefIdentifiers.has(resolvedName):
4373
+ case isInitializedFromRef$1(context, resolvedName, context.sourceCode.getScope(node.object)): break;
4253
4374
  default: continue;
4254
4375
  }
4255
4376
  const boundary = Traverse.findParent(node, isCompOrHookFn);
4256
4377
  if (boundary == null) continue;
4257
4378
  if (Traverse.findParent(node, Check.isFunction) !== boundary) continue;
4258
- const refName = obj.name;
4379
+ const refName = resolvedName;
4259
4380
  let isLazyInit = isInNullCheckTest(node);
4260
4381
  if (!isLazyInit) {
4261
4382
  let current = node.parent;
@@ -4305,6 +4426,22 @@ function create$5(context) {
4305
4426
  node
4306
4427
  });
4307
4428
  }
4429
+ for (const { node } of refPassedToFunctions) {
4430
+ const boundary = Traverse.findParent(node, isCompOrHookFn);
4431
+ if (boundary == null) continue;
4432
+ if (Traverse.findParent(node, Check.isFunction) !== boundary) continue;
4433
+ context.report({
4434
+ messageId: "refPassedToFunction",
4435
+ node
4436
+ });
4437
+ }
4438
+ },
4439
+ VariableDeclarator(node) {
4440
+ if (node.init == null) return;
4441
+ const id = node.id;
4442
+ const init = Extract.unwrap(node.init);
4443
+ if (id.type !== AST_NODE_TYPES.Identifier || init.type !== AST_NODE_TYPES.Identifier) return;
4444
+ aliases.set(id.name, init.name);
4308
4445
  }
4309
4446
  });
4310
4447
  }
@@ -6560,7 +6697,7 @@ function isInitializedFromRef(context, name, initialScope) {
6560
6697
 
6561
6698
  //#endregion
6562
6699
  //#region src/rules/set-state-in-effect/set-state-in-effect.ts
6563
- const RULE_NAME$4 = "set-state-in-effect";
6700
+ const RULE_NAME$5 = "set-state-in-effect";
6564
6701
  var set_state_in_effect_default = createRule({
6565
6702
  meta: {
6566
6703
  type: "problem",
@@ -6568,11 +6705,11 @@ var set_state_in_effect_default = createRule({
6568
6705
  messages: { default: "Do not call the 'set' function '{{name}}' of 'useState' synchronously in an effect. This can lead to unnecessary re-renders and performance issues." },
6569
6706
  schema: []
6570
6707
  },
6571
- name: RULE_NAME$4,
6572
- create: create$4,
6708
+ name: RULE_NAME$5,
6709
+ create: create$5,
6573
6710
  defaultOptions: []
6574
6711
  });
6575
- function create$4(context) {
6712
+ function create$5(context) {
6576
6713
  if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
6577
6714
  const { additionalEffectHooks, additionalStateHooks } = getSettingsFromContext(context);
6578
6715
  const functionEntries = [];
@@ -6802,7 +6939,7 @@ function isComponentOrHookLikeFunction(node) {
6802
6939
 
6803
6940
  //#endregion
6804
6941
  //#region src/rules/set-state-in-render/set-state-in-render.ts
6805
- const RULE_NAME$3 = "set-state-in-render";
6942
+ const RULE_NAME$4 = "set-state-in-render";
6806
6943
  var set_state_in_render_default = createRule({
6807
6944
  meta: {
6808
6945
  type: "problem",
@@ -6810,11 +6947,11 @@ var set_state_in_render_default = createRule({
6810
6947
  messages: { default: "Do not call the 'set' function '{{name}}' unconditionally during render. This will trigger an infinite render loop." },
6811
6948
  schema: []
6812
6949
  },
6813
- name: RULE_NAME$3,
6814
- create: create$3,
6950
+ name: RULE_NAME$4,
6951
+ create: create$4,
6815
6952
  defaultOptions: []
6816
6953
  });
6817
- function create$3(context) {
6954
+ function create$4(context) {
6818
6955
  const { additionalStateHooks } = getSettingsFromContext(context);
6819
6956
  const functionEntries = [];
6820
6957
  const componentFnRef = { current: null };
@@ -6907,6 +7044,102 @@ function create$3(context) {
6907
7044
  });
6908
7045
  }
6909
7046
 
7047
+ //#endregion
7048
+ //#region src/rules/static-components/static-components.ts
7049
+ const RULE_NAME$3 = "static-components";
7050
+ var static_components_default = createRule({
7051
+ meta: {
7052
+ type: "problem",
7053
+ docs: { description: "Validates that components are static, not recreated every render." },
7054
+ messages: { default: "Component '{{name}}' is created during render. Components created during render will reset their state each time they are created. Declare components outside of render." },
7055
+ schema: []
7056
+ },
7057
+ name: RULE_NAME$3,
7058
+ create: create$3,
7059
+ defaultOptions: []
7060
+ });
7061
+ function findVariableForJSXIdentifier(context, jsxId) {
7062
+ let scope = context.sourceCode.getScope(jsxId);
7063
+ while (scope != null) {
7064
+ const variable = scope.variables.find((v) => v.name === jsxId.name);
7065
+ if (variable != null) return variable;
7066
+ scope = scope.upper;
7067
+ }
7068
+ return null;
7069
+ }
7070
+ function isDynamicallyCreatedValue(node) {
7071
+ const expr = Extract.unwrap(node);
7072
+ switch (expr.type) {
7073
+ case AST_NODE_TYPES.FunctionExpression:
7074
+ case AST_NODE_TYPES.ArrowFunctionExpression:
7075
+ case AST_NODE_TYPES.NewExpression:
7076
+ case AST_NODE_TYPES.CallExpression:
7077
+ case AST_NODE_TYPES.ClassExpression: return true;
7078
+ case AST_NODE_TYPES.ConditionalExpression: return isDynamicallyCreatedValue(expr.consequent) || isDynamicallyCreatedValue(expr.alternate);
7079
+ default: return false;
7080
+ }
7081
+ }
7082
+ function hasDynamicAssignment(variable) {
7083
+ for (const ref of variable.references) {
7084
+ if (!ref.isWrite()) continue;
7085
+ const id = ref.identifier;
7086
+ if (id.parent?.type === AST_NODE_TYPES.AssignmentExpression && id.parent.left === id) {
7087
+ if (isDynamicallyCreatedValue(id.parent.right)) return true;
7088
+ }
7089
+ }
7090
+ return false;
7091
+ }
7092
+ function isDynamicallyCreated(node, variable) {
7093
+ if (node.type === AST_NODE_TYPES.FunctionDeclaration) return true;
7094
+ if (node.type === AST_NODE_TYPES.ClassDeclaration) return true;
7095
+ if (node.type === AST_NODE_TYPES.VariableDeclarator && node.init != null) return isDynamicallyCreatedValue(node.init);
7096
+ if (node.type === AST_NODE_TYPES.VariableDeclarator && node.init == null && variable != null) return hasDynamicAssignment(variable);
7097
+ return false;
7098
+ }
7099
+ function create$3(context) {
7100
+ 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;
7101
+ const fc = core.getFunctionComponentCollector(context, { hint });
7102
+ const cc = core.getClassComponentCollector(context);
7103
+ const jsxCandidates = [];
7104
+ return merge(fc.visitor, cc.visitor, {
7105
+ JSXOpeningElement(node) {
7106
+ if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) return;
7107
+ const name = node.name.name;
7108
+ if (!core.isFunctionComponentName(name)) return;
7109
+ jsxCandidates.push({
7110
+ name,
7111
+ node
7112
+ });
7113
+ },
7114
+ "Program:exit"(program) {
7115
+ const fComponents = [...fc.api.getAllComponents(program)];
7116
+ const cComponents = [...cc.api.getAllComponents(program)];
7117
+ function getEnclosingComponent(node) {
7118
+ return Traverse.findParent(node, (n) => {
7119
+ if (Check.isFunction(n)) return fComponents.some((c) => c.node === n);
7120
+ if (Check.isClass(n)) return cComponents.some((c) => c.node === n);
7121
+ return false;
7122
+ });
7123
+ }
7124
+ for (const { name, node: jsxNode } of jsxCandidates) {
7125
+ const jsxName = jsxNode.name;
7126
+ const variable = findVariableForJSXIdentifier(context, jsxName);
7127
+ if (variable == null || variable.defs.length === 0) continue;
7128
+ const def = variable.defs.at(0);
7129
+ if (def == null) continue;
7130
+ const defNode = def.node;
7131
+ if (getEnclosingComponent(defNode) == null) continue;
7132
+ if (!isDynamicallyCreated(defNode, variable)) continue;
7133
+ context.report({
7134
+ data: { name },
7135
+ messageId: "default",
7136
+ node: jsxNode.name
7137
+ });
7138
+ }
7139
+ }
7140
+ });
7141
+ }
7142
+
6910
7143
  //#endregion
6911
7144
  //#region src/rules/unsupported-syntax/lib.ts
6912
7145
  function isEvalCall(node) {
@@ -7002,6 +7235,8 @@ var use_memo_default = createRule({
7002
7235
  type: "problem",
7003
7236
  docs: { description: "Validates that 'useMemo' is called with a callback that returns a value." },
7004
7237
  messages: {
7238
+ asyncOrGeneratorCallback: "The callback passed to 'useMemo' must be a regular function. 'useMemo' callbacks are called synchronously by React and must immediately return a value. Async and generator functions are not supported.",
7239
+ callbackWithParameters: "The callback passed to 'useMemo' may not accept parameters. 'useMemo' callbacks are called by React without arguments. Instead, directly reference the props, state, or local variables needed for the computation.",
7005
7240
  missingReturnValue: "The callback passed to 'useMemo' must return a value. Without a return value, 'useMemo' always returns 'undefined', which defeats its purpose.",
7006
7241
  notAssignedToVariable: "The return value of 'useMemo' must be assigned to a variable. Calling 'useMemo' without capturing its return value is likely a mistake — use 'useEffect' for side effects instead."
7007
7242
  },
@@ -7028,6 +7263,18 @@ function create$1(context) {
7028
7263
  if (callbackArg == null) return;
7029
7264
  const callback = Extract.unwrap(callbackArg);
7030
7265
  if (!Check.isFunction(callback)) return;
7266
+ if (callback.params.length > 0) {
7267
+ const firstParam = callback.params[0];
7268
+ if (firstParam == null) return;
7269
+ context.report({
7270
+ messageId: "callbackWithParameters",
7271
+ node: firstParam.type === AST_NODE_TYPES.Identifier ? firstParam : callback
7272
+ });
7273
+ }
7274
+ if (callback.async || callback.generator) context.report({
7275
+ messageId: "asyncOrGeneratorCallback",
7276
+ node: callback
7277
+ });
7031
7278
  if (callback.type === AST_NODE_TYPES.ArrowFunctionExpression && callback.body.type !== AST_NODE_TYPES.BlockStatement) return;
7032
7279
  if (callback.body.type !== AST_NODE_TYPES.BlockStatement) return;
7033
7280
  const returnStatements = getNestedReturnStatements(callbackArg);
@@ -7322,6 +7569,7 @@ const plugin = {
7322
7569
  "rules-of-hooks": rule,
7323
7570
  "set-state-in-effect": set_state_in_effect_default,
7324
7571
  "set-state-in-render": set_state_in_render_default,
7572
+ "static-components": static_components_default,
7325
7573
  "unsupported-syntax": unsupported_syntax_default,
7326
7574
  "use-memo": use_memo_default,
7327
7575
  "use-state": use_state_default
@@ -7372,6 +7620,7 @@ const rules$6 = {
7372
7620
  "react-x/rules-of-hooks": "error",
7373
7621
  "react-x/set-state-in-effect": "warn",
7374
7622
  "react-x/set-state-in-render": "error",
7623
+ "react-x/static-components": "error",
7375
7624
  "react-x/unsupported-syntax": "error",
7376
7625
  "react-x/use-memo": "error",
7377
7626
  "react-x/use-state": "warn"