eslint-plugin-react-x 1.23.1 → 1.23.2-beta.6

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 (3) hide show
  1. package/dist/index.js +112 -75
  2. package/dist/index.mjs +114 -77
  3. package/package.json +13 -13
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ var ts__default = /*#__PURE__*/_interopDefault(ts);
42
42
 
43
43
  // package.json
44
44
  var name = "eslint-plugin-react-x";
45
- var version = "1.23.1";
45
+ var version = "1.23.2-beta.6";
46
46
  var createRule = shared.createRuleForPlugin("x");
47
47
 
48
48
  // src/rules/avoid-shorthand-boolean.ts
@@ -281,7 +281,7 @@ function isReactChildrenMethod(name2) {
281
281
  return reactChildrenMethod.some((method) => method === name2);
282
282
  }
283
283
  function isUsingReactChildren(node, context) {
284
- const settings = shared.unsafeReadSettings(context.settings);
284
+ const settings = shared.unsafeDecodeSettings(context.settings);
285
285
  const { callee } = node;
286
286
  if (!("property" in callee) || !("object" in callee) || !("name" in callee.property)) {
287
287
  return false;
@@ -290,7 +290,7 @@ function isUsingReactChildren(node, context) {
290
290
  const initialScope = context.sourceCode.getScope(node);
291
291
  if (callee.object.type === types.AST_NODE_TYPES.Identifier && callee.object.name === "Children") return true;
292
292
  if (callee.object.type === types.AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) {
293
- return core.isInitializedFromReact(callee.object.object.name, initialScope, { ...settings, strictImportCheck: true });
293
+ return core.isInitializedFromReact(callee.object.object.name, initialScope, settings.importSource);
294
294
  }
295
295
  return false;
296
296
  }
@@ -906,7 +906,7 @@ var no_context_provider_default = createRule({
906
906
  name: RULE_NAME19,
907
907
  create(context) {
908
908
  if (!context.sourceCode.text.includes(".Provider")) return {};
909
- const { version: version2 } = shared.normalizeSettings(shared.decodeSettings(context.settings));
909
+ const { version: version2 } = shared.getSettingsFromContext(context);
910
910
  if (compareVersions.compare(version2, "19.0.0", "<")) return {};
911
911
  return {
912
912
  JSXElement(node) {
@@ -952,7 +952,7 @@ var no_create_ref_default = createRule({
952
952
  return {
953
953
  CallExpression(node) {
954
954
  if (!core.isCreateRefCall(node, context)) return;
955
- if (eff.O.isSome(AST11__namespace.traverseUp(node, core.isClassComponent))) return;
955
+ if (eff.O.isSome(AST11__namespace.findParentNode(node, core.isClassComponent))) return;
956
956
  context.report({ messageId: "noCreateRef", node });
957
957
  }
958
958
  };
@@ -1044,19 +1044,24 @@ var no_direct_mutation_state_default = createRule({
1044
1044
  create(context) {
1045
1045
  function getReportDescriptor(node) {
1046
1046
  if (!isAssignmentToThisState(node)) return eff.O.none();
1047
- const maybeParentClass = AST11__namespace.traverseUpGuard(
1048
- node,
1049
- AST11__namespace.isOneOf([types.AST_NODE_TYPES.ClassDeclaration, types.AST_NODE_TYPES.ClassExpression])
1047
+ return eff.F.pipe(
1048
+ eff.O.Do,
1049
+ eff.O.bind("parentClass", () => AST11__namespace.findParentNodeGuard(
1050
+ node,
1051
+ AST11__namespace.isOneOf([
1052
+ types.AST_NODE_TYPES.ClassDeclaration,
1053
+ types.AST_NODE_TYPES.ClassExpression
1054
+ ])
1055
+ )),
1056
+ eff.O.bind("parentConstructor", () => AST11__namespace.findParentNodeGuard(node, isConstructorFunction)),
1057
+ eff.O.filter(
1058
+ ({ parentClass, parentConstructor }) => core.isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== parentConstructor
1059
+ ),
1060
+ eff.O.map(() => ({
1061
+ messageId: "noDirectMutationState",
1062
+ node
1063
+ }))
1050
1064
  );
1051
- if (eff.O.isNone(maybeParentClass)) return eff.O.none();
1052
- const parentClass = maybeParentClass.value;
1053
- if (!core.isClassComponent(parentClass)) return eff.O.none();
1054
- const maybeParentConstructor = AST11__namespace.traverseUpGuard(node, isConstructorFunction);
1055
- if (eff.O.exists(maybeParentConstructor, (n) => context.sourceCode.getScope(node).block === n)) return eff.O.none();
1056
- return eff.O.some({
1057
- messageId: "noDirectMutationState",
1058
- node
1059
- });
1060
1065
  }
1061
1066
  return {
1062
1067
  AssignmentExpression: eff.F.flow(getReportDescriptor, eff.O.map(context.report))
@@ -1146,20 +1151,20 @@ var no_duplicate_key_default = createRule({
1146
1151
  break;
1147
1152
  }
1148
1153
  default: {
1149
- const entry = eff.F.pipe(
1154
+ const mbEntry = eff.F.pipe(
1150
1155
  eff.O.Do,
1151
- eff.O.bind("call", () => AST11__namespace.traverseUpGuard(jsxElement, AST11__namespace.isMapCallLoose)),
1152
- eff.O.bind("iter", ({ call }) => AST11__namespace.traverseUpStop(jsxElement, call, AST11__namespace.isFunction)),
1153
- eff.O.bind("arg0", ({ call }) => eff.O.fromNullable(call.arguments[0]))
1156
+ eff.O.bind("call", () => AST11__namespace.findParentNodeGuard(jsxElement, AST11__namespace.isMapCallLoose)),
1157
+ eff.O.bind("iter", ({ call: call2 }) => AST11__namespace.findParentNodeStop(jsxElement, call2, AST11__namespace.isFunction)),
1158
+ eff.O.bind("arg0", ({ call: call2 }) => eff.O.fromNullable(call2.arguments[0]))
1154
1159
  );
1155
- for (const { arg0, call, iter } of eff.O.toArray(entry)) {
1156
- if (AST11__namespace.unwrapTypeExpression(arg0) !== iter) continue;
1157
- keyedEntries.set(call, {
1158
- hasDuplicate: node.value?.type === types.AST_NODE_TYPES.Literal,
1159
- keys: [node],
1160
- root: call
1161
- });
1162
- }
1160
+ if (eff.O.isNone(mbEntry)) return;
1161
+ const { arg0, call, iter } = mbEntry.value;
1162
+ if (AST11__namespace.unwrapTypeExpression(arg0) !== iter) return;
1163
+ keyedEntries.set(call, {
1164
+ hasDuplicate: node.value?.type === types.AST_NODE_TYPES.Literal,
1165
+ keys: [node],
1166
+ root: call
1167
+ });
1163
1168
  }
1164
1169
  }
1165
1170
  },
@@ -1202,7 +1207,7 @@ var no_forward_ref_default = createRule({
1202
1207
  name: RULE_NAME25,
1203
1208
  create(context) {
1204
1209
  if (!context.sourceCode.text.includes("forwardRef")) return {};
1205
- const { version: version2 } = shared.normalizeSettings(shared.decodeSettings(context.settings));
1210
+ const { version: version2 } = shared.getSettingsFromContext(context);
1206
1211
  if (compareVersions.compare(version2, "19.0.0", "<")) return {};
1207
1212
  return {
1208
1213
  CallExpression(node) {
@@ -1299,9 +1304,7 @@ var no_implicit_key_default = createRule({
1299
1304
  function getReportDescriptor(node) {
1300
1305
  const initialScope = context.sourceCode.getScope(node);
1301
1306
  const keyPropFound = JSX7__namespace.findPropInAttributes(node.attributes, initialScope)("key");
1302
- const keyPropOnElement = node.attributes.some(
1303
- (n) => AST11__namespace.is(types.AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key"
1304
- );
1307
+ const keyPropOnElement = node.attributes.some((n) => AST11__namespace.is(types.AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key");
1305
1308
  if (eff.O.isSome(keyPropFound) && !keyPropOnElement) {
1306
1309
  return eff.O.some({ messageId: "noImplicitKey", node: keyPropFound.value });
1307
1310
  }
@@ -1425,7 +1428,7 @@ var no_leaked_conditional_rendering_default = createRule({
1425
1428
  name: RULE_NAME27,
1426
1429
  create(context) {
1427
1430
  if (!context.sourceCode.text.includes("&&") && !context.sourceCode.text.includes("?")) return {};
1428
- const { version: version2 } = shared.normalizeSettings(shared.decodeSettings(context.settings));
1431
+ const { version: version2 } = shared.getSettingsFromContext(context);
1429
1432
  const allowedVariants = [
1430
1433
  "any",
1431
1434
  "boolean",
@@ -1579,10 +1582,8 @@ var no_missing_key_default = createRule({
1579
1582
  function checkBlockStatement(node) {
1580
1583
  return AST11__namespace.getNestedReturnStatements(node).reduce((acc, statement) => {
1581
1584
  if (!statement.argument) return acc;
1582
- const maybeDescriptor = checkIteratorElement(statement.argument);
1583
- if (eff.O.isNone(maybeDescriptor)) return acc;
1584
- const descriptor = maybeDescriptor.value;
1585
- return [...acc, descriptor];
1585
+ const mbDescriptor = checkIteratorElement(statement.argument);
1586
+ return eff.O.isNone(mbDescriptor) ? acc : [...acc, mbDescriptor.value];
1586
1587
  }, []);
1587
1588
  }
1588
1589
  return {
@@ -1680,7 +1681,7 @@ var no_nested_components_default = createRule({
1680
1681
  if (eff.O.isNone(componentName)) continue;
1681
1682
  const name2 = componentName.value;
1682
1683
  const isInsideProperty = component.parent.type === types.AST_NODE_TYPES.Property;
1683
- const isInsideJSXPropValue = component.parent.type === types.AST_NODE_TYPES.JSXAttribute || eff.O.isSome(JSX7__namespace.traverseUpProp(node, (n) => n.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer));
1684
+ const isInsideJSXPropValue = component.parent.type === types.AST_NODE_TYPES.JSXAttribute || eff.O.isSome(JSX7__namespace.findParentProp(node, (n) => n.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer));
1684
1685
  if (isInsideJSXPropValue) {
1685
1686
  if (!core.isDeclaredInRenderPropLoose(component)) {
1686
1687
  context.report({
@@ -1703,8 +1704,14 @@ var no_nested_components_default = createRule({
1703
1704
  });
1704
1705
  continue;
1705
1706
  }
1706
- const maybeParentComponent = AST11__namespace.traverseUpGuard(component, isFunctionComponent);
1707
- if (eff.O.isSome(maybeParentComponent) && !core.isDirectValueOfRenderPropertyLoose(maybeParentComponent.value)) {
1707
+ const isParnetComponentNotDirectValueOfRenderProperty = eff.O.exists(
1708
+ AST11__namespace.findParentNodeGuard(
1709
+ component,
1710
+ isFunctionComponent
1711
+ ),
1712
+ eff.not(core.isDirectValueOfRenderPropertyLoose)
1713
+ );
1714
+ if (isParnetComponentNotDirectValueOfRenderProperty) {
1708
1715
  context.report({
1709
1716
  messageId: isInsideProperty ? "nestedComponentInProps" : "nestedComponent",
1710
1717
  node: component,
@@ -1714,8 +1721,7 @@ var no_nested_components_default = createRule({
1714
1721
  });
1715
1722
  continue;
1716
1723
  }
1717
- const isInsideClassComponentRenderMethod = core.isInsideRenderMethod(component);
1718
- if (isInsideClassComponentRenderMethod) {
1724
+ if (core.isInsideRenderMethod(component)) {
1719
1725
  context.report({
1720
1726
  messageId: "nestedComponent",
1721
1727
  node: component,
@@ -1726,7 +1732,7 @@ var no_nested_components_default = createRule({
1726
1732
  }
1727
1733
  }
1728
1734
  for (const { name: name2, node: component } of classComponents) {
1729
- if (eff.O.isNone(AST11__namespace.traverseUp(component, eff.or(isClassComponent11, isFunctionComponent)))) {
1735
+ if (eff.O.isNone(AST11__namespace.findParentNode(component, eff.or(isClassComponent11, isFunctionComponent)))) {
1730
1736
  continue;
1731
1737
  }
1732
1738
  context.report({
@@ -1858,8 +1864,8 @@ var no_set_state_in_component_did_mount_default = createRule({
1858
1864
  if (!core.isThisSetState(node)) return eff.O.none();
1859
1865
  return eff.F.pipe(
1860
1866
  eff.O.Do,
1861
- eff.O.bind("clazz", () => AST11__namespace.traverseUpGuard(node, core.isClassComponent)),
1862
- eff.O.bind("method", ({ clazz }) => AST11__namespace.traverseUpStop(node, clazz, isComponentDidMount)),
1867
+ eff.O.bind("clazz", () => AST11__namespace.findParentNodeGuard(node, core.isClassComponent)),
1868
+ eff.O.bind("method", ({ clazz }) => AST11__namespace.findParentNodeStop(node, clazz, isComponentDidMount)),
1863
1869
  eff.O.bind("methodScope", ({ method }) => eff.O.some(context.sourceCode.getScope(method))),
1864
1870
  eff.O.bind("upperScope", () => eff.O.fromNullable(context.sourceCode.getScope(node).upper)),
1865
1871
  eff.O.filter(
@@ -1908,11 +1914,17 @@ var no_set_state_in_component_did_update_default = createRule({
1908
1914
  if (!core.isThisSetState(node)) return eff.O.none();
1909
1915
  return eff.F.pipe(
1910
1916
  eff.O.Do,
1911
- eff.O.bind("clazz", () => AST11__namespace.traverseUpGuard(node, core.isClassComponent)),
1912
- eff.O.bind("method", ({ clazz }) => AST11__namespace.traverseUpStop(node, clazz, isComponentDidUpdate)),
1917
+ eff.O.bind("clazz", () => AST11__namespace.findParentNodeGuard(node, core.isClassComponent)),
1918
+ eff.O.bind("method", ({ clazz }) => AST11__namespace.findParentNodeStop(node, clazz, isComponentDidUpdate)),
1919
+ eff.O.bind("methodScope", ({ method }) => eff.O.some(context.sourceCode.getScope(method))),
1913
1920
  eff.O.bind("upperScope", () => eff.O.fromNullable(context.sourceCode.getScope(node).upper)),
1914
1921
  eff.O.filter(
1915
- ({ clazz, method, upperScope }) => method.parent === clazz.body && upperScope === context.sourceCode.getScope(method)
1922
+ ({
1923
+ clazz,
1924
+ method,
1925
+ methodScope,
1926
+ upperScope
1927
+ }) => method.parent === clazz.body && upperScope === methodScope
1916
1928
  ),
1917
1929
  eff.O.map(() => ({
1918
1930
  messageId: "noSetStateInComponentDidUpdate",
@@ -1952,11 +1964,17 @@ var no_set_state_in_component_will_update_default = createRule({
1952
1964
  if (!core.isThisSetState(node)) return eff.O.none();
1953
1965
  return eff.F.pipe(
1954
1966
  eff.O.Do,
1955
- eff.O.bind("clazz", () => AST11__namespace.traverseUpGuard(node, core.isClassComponent)),
1956
- eff.O.bind("method", ({ clazz }) => AST11__namespace.traverseUpStop(node, clazz, isComponentWillUpdate3)),
1967
+ eff.O.bind("clazz", () => AST11__namespace.findParentNodeGuard(node, core.isClassComponent)),
1968
+ eff.O.bind("method", ({ clazz }) => AST11__namespace.findParentNodeStop(node, clazz, isComponentWillUpdate3)),
1969
+ eff.O.bind("methodScope", ({ method }) => eff.O.some(context.sourceCode.getScope(method))),
1957
1970
  eff.O.bind("upperScope", () => eff.O.fromNullable(context.sourceCode.getScope(node).upper)),
1958
1971
  eff.O.filter(
1959
- ({ clazz, method, upperScope }) => method.parent === clazz.body && upperScope === context.sourceCode.getScope(method)
1972
+ ({
1973
+ clazz,
1974
+ method,
1975
+ methodScope,
1976
+ upperScope
1977
+ }) => method.parent === clazz.body && upperScope === methodScope
1960
1978
  ),
1961
1979
  eff.O.map(() => ({
1962
1980
  messageId: "noSetStateInComponentWillUpdate",
@@ -2167,7 +2185,7 @@ var no_unstable_context_value_default = createRule({
2167
2185
  const openingElementName = node.name;
2168
2186
  if (openingElementName.type !== types.AST_NODE_TYPES.JSXMemberExpression) return;
2169
2187
  if (openingElementName.property.name !== "Provider") return;
2170
- const constructionEntry = eff.F.pipe(
2188
+ eff.F.pipe(
2171
2189
  eff.O.Do,
2172
2190
  eff.O.bind("function", ctx.getCurrentFunction),
2173
2191
  eff.O.bind("attribute", () => eff.O.fromNullable(
@@ -2180,16 +2198,14 @@ var no_unstable_context_value_default = createRule({
2180
2198
  eff.O.bind("construction", ({ valueExpression }) => {
2181
2199
  const initialScope = context.sourceCode.getScope(valueExpression);
2182
2200
  return eff.O.some(VAR__namespace.getValueConstruction(valueExpression, initialScope));
2201
+ }),
2202
+ eff.O.map((vc) => {
2203
+ if (vc.construction.kind === "None") return;
2204
+ if (core.isReactHookCall(vc.construction.node)) return;
2205
+ const prevs = constructions.get(vc.function.node) ?? [];
2206
+ constructions.set(vc.function.node, [...prevs, vc.construction]);
2183
2207
  })
2184
2208
  );
2185
- for (const { construction, function: [_, fNode] } of eff.O.toArray(constructionEntry)) {
2186
- if (construction.kind === "None") continue;
2187
- if (core.isReactHookCall(construction.node)) continue;
2188
- constructions.set(fNode, [
2189
- ...constructions.get(fNode) ?? [],
2190
- construction
2191
- ]);
2192
- }
2193
2209
  },
2194
2210
  "Program:exit"(node) {
2195
2211
  const components = ctx.getAllComponents(node).values();
@@ -2267,10 +2283,11 @@ var no_unstable_default_props_default = createRule({
2267
2283
  }
2268
2284
  },
2269
2285
  "VariableDeclarator[id.type='ObjectPattern'][init.type='Identifier']"(node) {
2270
- for (const [_, currentFn] of eff.O.toArray(ctx.getCurrentFunction())) {
2271
- const prevDeclarators = declarators.get(currentFn) ?? [];
2272
- declarators.set(currentFn, [...prevDeclarators, node]);
2273
- }
2286
+ const mbEntry = ctx.getCurrentFunction();
2287
+ if (eff.O.isNone(mbEntry)) return;
2288
+ const entry = mbEntry.value;
2289
+ const prevs = declarators.get(entry.node) ?? [];
2290
+ declarators.set(entry.node, [...prevs, node]);
2274
2291
  }
2275
2292
  };
2276
2293
  },
@@ -2398,7 +2415,9 @@ var no_unused_class_component_members_default = createRule({
2398
2415
  if (node.init && AST11__namespace.isThisExpression(node.init) && node.id.type === types.AST_NODE_TYPES.ObjectPattern) {
2399
2416
  for (const prop of node.id.properties) {
2400
2417
  if (prop.type === types.AST_NODE_TYPES.Property && AST11__namespace.isKeyLiteralLike(prop, prop.key)) {
2401
- for (const name2 of eff.O.toArray(getName3(prop.key))) {
2418
+ const mbName = getName3(prop.key);
2419
+ if (eff.O.isSome(mbName)) {
2420
+ const name2 = mbName.value;
2402
2421
  propertyUsages.get(currentClass)?.add(name2);
2403
2422
  }
2404
2423
  }
@@ -2562,7 +2581,10 @@ function checkAndReport(node, context, allowExpressions) {
2562
2581
  const initialScope = context.sourceCode.getScope(node);
2563
2582
  if (JSX7__namespace.isKeyedElement(node, initialScope)) return;
2564
2583
  if (JSX7__namespace.isBuiltInElement(node.parent)) context.report({ messageId: "noUselessFragmentInBuiltIn", node });
2565
- if (node.children.length === 0) return context.report({ messageId: "noUselessFragment", node });
2584
+ if (node.children.length === 0) {
2585
+ context.report({ messageId: "noUselessFragment", node });
2586
+ return;
2587
+ }
2566
2588
  const isChildElement = AST11__namespace.isOneOf([types.AST_NODE_TYPES.JSXElement, types.AST_NODE_TYPES.JSXFragment])(node.parent);
2567
2589
  switch (true) {
2568
2590
  // <Foo content={<>ee eeee eeee ...</>} />
@@ -2571,10 +2593,12 @@ function checkAndReport(node, context, allowExpressions) {
2571
2593
  }
2572
2594
  // <Foo><>hello, world</></Foo>
2573
2595
  case (!allowExpressions && isChildElement): {
2574
- return context.report({ messageId: "noUselessFragment", node });
2596
+ context.report({ messageId: "noUselessFragment", node });
2597
+ return;
2575
2598
  }
2576
2599
  case (!allowExpressions && !isChildElement && node.children.length === 1): {
2577
- return context.report({ messageId: "noUselessFragment", node });
2600
+ context.report({ messageId: "noUselessFragment", node });
2601
+ return;
2578
2602
  }
2579
2603
  }
2580
2604
  const nonPaddingChildren = node.children.filter((child) => !JSX7__namespace.isPaddingSpaces(child));
@@ -2582,7 +2606,8 @@ function checkAndReport(node, context, allowExpressions) {
2582
2606
  switch (true) {
2583
2607
  case nonPaddingChildren.length === 0:
2584
2608
  case (nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== types.AST_NODE_TYPES.JSXExpressionContainer): {
2585
- return context.report({ messageId: "noUselessFragment", node });
2609
+ context.report({ messageId: "noUselessFragment", node });
2610
+ return;
2586
2611
  }
2587
2612
  }
2588
2613
  return;
@@ -2659,8 +2684,10 @@ var prefer_destructuring_assignment_default = createRule({
2659
2684
  const components = Array.from(ctx.getAllComponents(node).values());
2660
2685
  function isFunctionComponent(block) {
2661
2686
  if (!AST11__namespace.isFunction(block)) return false;
2662
- const maybeId = AST11__namespace.getFunctionIdentifier(block);
2663
- return eff.O.isSome(maybeId) && core.isComponentName(maybeId.value.name) && components.some((component) => component.node === block);
2687
+ return eff.O.exists(
2688
+ AST11__namespace.getFunctionIdentifier(block),
2689
+ (id) => core.isComponentName(id.name) && components.some((component) => component.node === block)
2690
+ );
2664
2691
  }
2665
2692
  for (const [initialScope, memberExpression] of memberExpressionWithNames) {
2666
2693
  let scope = initialScope;
@@ -2718,7 +2745,7 @@ var prefer_react_namespace_import_default = createRule({
2718
2745
  },
2719
2746
  name: RULE_NAME46,
2720
2747
  create(context) {
2721
- const importSource = shared.decodeSettings(context.settings).importSource ?? "react";
2748
+ const importSource = shared.getSettingsFromContext(context).importSource ?? "react";
2722
2749
  return {
2723
2750
  [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
2724
2751
  const hasOtherSpecifiers = node.parent.specifiers.length > 1;
@@ -2839,7 +2866,8 @@ var prefer_shorthand_boolean_default = createRule({
2839
2866
  });
2840
2867
  var RULE_NAME49 = "prefer-shorthand-fragment";
2841
2868
  var RULE_FEATURES48 = [
2842
- "CHK"
2869
+ "CHK",
2870
+ "FIX"
2843
2871
  ];
2844
2872
  var prefer_shorthand_fragment_default = createRule({
2845
2873
  meta: {
@@ -2848,6 +2876,7 @@ var prefer_shorthand_fragment_default = createRule({
2848
2876
  description: "enforce using fragment syntax instead of 'Fragment' component",
2849
2877
  [Symbol.for("rule_features")]: RULE_FEATURES48
2850
2878
  },
2879
+ fixable: "code",
2851
2880
  messages: {
2852
2881
  preferShorthandFragment: "Use fragment shorthand syntax instead of 'Fragment' component."
2853
2882
  },
@@ -2861,7 +2890,15 @@ var prefer_shorthand_fragment_default = createRule({
2861
2890
  if (hasAttributes) return eff.O.none();
2862
2891
  return eff.O.some({
2863
2892
  messageId: "preferShorthandFragment",
2864
- node
2893
+ node,
2894
+ fix: (fixer) => {
2895
+ const { closingElement, openingElement } = node;
2896
+ if (!closingElement) return [];
2897
+ return [
2898
+ fixer.replaceTextRange([openingElement.range[0], openingElement.range[1]], "<>"),
2899
+ fixer.replaceTextRange([closingElement.range[0], closingElement.range[1]], "</>")
2900
+ ];
2901
+ }
2865
2902
  });
2866
2903
  }
2867
2904
  return {
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { F, O, or, isString, isNullable } from '@eslint-react/eff';
1
+ import { F, O, or, isString, not, isNullable } from '@eslint-react/eff';
2
2
  import * as JSX7 from '@eslint-react/jsx';
3
- import { createRuleForPlugin, normalizeSettings, decodeSettings, unsafeReadSettings } from '@eslint-react/shared';
3
+ import { createRuleForPlugin, getSettingsFromContext, unsafeDecodeSettings } from '@eslint-react/shared';
4
4
  import * as AST11 from '@eslint-react/ast';
5
5
  import { isForwardRefCall, isThisSetState, isClassComponent, isCreateElementCall, isCloneElementCall, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, useComponentCollectorLegacy, isCreateRefCall, isComponentName, useComponentCollector, ERFunctionComponentFlag, isChildrenToArrayCall, ERComponentHint, isDirectValueOfRenderPropertyLoose, isDeclaredInRenderPropLoose, isInsideCreateElementProps, isInsideRenderMethod, ERClassComponentFlag, isReactHookCall, isInitializedFromReact } from '@eslint-react/core';
6
6
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
@@ -15,7 +15,7 @@ import { getTypeImmutability, isUnknown, isImmutable, isReadonlyShallow, isReado
15
15
 
16
16
  // package.json
17
17
  var name = "eslint-plugin-react-x";
18
- var version = "1.23.1";
18
+ var version = "1.23.2-beta.6";
19
19
  var createRule = createRuleForPlugin("x");
20
20
 
21
21
  // src/rules/avoid-shorthand-boolean.ts
@@ -254,7 +254,7 @@ function isReactChildrenMethod(name2) {
254
254
  return reactChildrenMethod.some((method) => method === name2);
255
255
  }
256
256
  function isUsingReactChildren(node, context) {
257
- const settings = unsafeReadSettings(context.settings);
257
+ const settings = unsafeDecodeSettings(context.settings);
258
258
  const { callee } = node;
259
259
  if (!("property" in callee) || !("object" in callee) || !("name" in callee.property)) {
260
260
  return false;
@@ -263,7 +263,7 @@ function isUsingReactChildren(node, context) {
263
263
  const initialScope = context.sourceCode.getScope(node);
264
264
  if (callee.object.type === AST_NODE_TYPES.Identifier && callee.object.name === "Children") return true;
265
265
  if (callee.object.type === AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) {
266
- return isInitializedFromReact(callee.object.object.name, initialScope, { ...settings, strictImportCheck: true });
266
+ return isInitializedFromReact(callee.object.object.name, initialScope, settings.importSource);
267
267
  }
268
268
  return false;
269
269
  }
@@ -879,7 +879,7 @@ var no_context_provider_default = createRule({
879
879
  name: RULE_NAME19,
880
880
  create(context) {
881
881
  if (!context.sourceCode.text.includes(".Provider")) return {};
882
- const { version: version2 } = normalizeSettings(decodeSettings(context.settings));
882
+ const { version: version2 } = getSettingsFromContext(context);
883
883
  if (compare(version2, "19.0.0", "<")) return {};
884
884
  return {
885
885
  JSXElement(node) {
@@ -925,7 +925,7 @@ var no_create_ref_default = createRule({
925
925
  return {
926
926
  CallExpression(node) {
927
927
  if (!isCreateRefCall(node, context)) return;
928
- if (O.isSome(AST11.traverseUp(node, isClassComponent))) return;
928
+ if (O.isSome(AST11.findParentNode(node, isClassComponent))) return;
929
929
  context.report({ messageId: "noCreateRef", node });
930
930
  }
931
931
  };
@@ -1017,19 +1017,24 @@ var no_direct_mutation_state_default = createRule({
1017
1017
  create(context) {
1018
1018
  function getReportDescriptor(node) {
1019
1019
  if (!isAssignmentToThisState(node)) return O.none();
1020
- const maybeParentClass = AST11.traverseUpGuard(
1021
- node,
1022
- AST11.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression])
1020
+ return F.pipe(
1021
+ O.Do,
1022
+ O.bind("parentClass", () => AST11.findParentNodeGuard(
1023
+ node,
1024
+ AST11.isOneOf([
1025
+ AST_NODE_TYPES.ClassDeclaration,
1026
+ AST_NODE_TYPES.ClassExpression
1027
+ ])
1028
+ )),
1029
+ O.bind("parentConstructor", () => AST11.findParentNodeGuard(node, isConstructorFunction)),
1030
+ O.filter(
1031
+ ({ parentClass, parentConstructor }) => isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== parentConstructor
1032
+ ),
1033
+ O.map(() => ({
1034
+ messageId: "noDirectMutationState",
1035
+ node
1036
+ }))
1023
1037
  );
1024
- if (O.isNone(maybeParentClass)) return O.none();
1025
- const parentClass = maybeParentClass.value;
1026
- if (!isClassComponent(parentClass)) return O.none();
1027
- const maybeParentConstructor = AST11.traverseUpGuard(node, isConstructorFunction);
1028
- if (O.exists(maybeParentConstructor, (n) => context.sourceCode.getScope(node).block === n)) return O.none();
1029
- return O.some({
1030
- messageId: "noDirectMutationState",
1031
- node
1032
- });
1033
1038
  }
1034
1039
  return {
1035
1040
  AssignmentExpression: F.flow(getReportDescriptor, O.map(context.report))
@@ -1119,20 +1124,20 @@ var no_duplicate_key_default = createRule({
1119
1124
  break;
1120
1125
  }
1121
1126
  default: {
1122
- const entry = F.pipe(
1127
+ const mbEntry = F.pipe(
1123
1128
  O.Do,
1124
- O.bind("call", () => AST11.traverseUpGuard(jsxElement, AST11.isMapCallLoose)),
1125
- O.bind("iter", ({ call }) => AST11.traverseUpStop(jsxElement, call, AST11.isFunction)),
1126
- O.bind("arg0", ({ call }) => O.fromNullable(call.arguments[0]))
1129
+ O.bind("call", () => AST11.findParentNodeGuard(jsxElement, AST11.isMapCallLoose)),
1130
+ O.bind("iter", ({ call: call2 }) => AST11.findParentNodeStop(jsxElement, call2, AST11.isFunction)),
1131
+ O.bind("arg0", ({ call: call2 }) => O.fromNullable(call2.arguments[0]))
1127
1132
  );
1128
- for (const { arg0, call, iter } of O.toArray(entry)) {
1129
- if (AST11.unwrapTypeExpression(arg0) !== iter) continue;
1130
- keyedEntries.set(call, {
1131
- hasDuplicate: node.value?.type === AST_NODE_TYPES.Literal,
1132
- keys: [node],
1133
- root: call
1134
- });
1135
- }
1133
+ if (O.isNone(mbEntry)) return;
1134
+ const { arg0, call, iter } = mbEntry.value;
1135
+ if (AST11.unwrapTypeExpression(arg0) !== iter) return;
1136
+ keyedEntries.set(call, {
1137
+ hasDuplicate: node.value?.type === AST_NODE_TYPES.Literal,
1138
+ keys: [node],
1139
+ root: call
1140
+ });
1136
1141
  }
1137
1142
  }
1138
1143
  },
@@ -1175,7 +1180,7 @@ var no_forward_ref_default = createRule({
1175
1180
  name: RULE_NAME25,
1176
1181
  create(context) {
1177
1182
  if (!context.sourceCode.text.includes("forwardRef")) return {};
1178
- const { version: version2 } = normalizeSettings(decodeSettings(context.settings));
1183
+ const { version: version2 } = getSettingsFromContext(context);
1179
1184
  if (compare(version2, "19.0.0", "<")) return {};
1180
1185
  return {
1181
1186
  CallExpression(node) {
@@ -1272,9 +1277,7 @@ var no_implicit_key_default = createRule({
1272
1277
  function getReportDescriptor(node) {
1273
1278
  const initialScope = context.sourceCode.getScope(node);
1274
1279
  const keyPropFound = JSX7.findPropInAttributes(node.attributes, initialScope)("key");
1275
- const keyPropOnElement = node.attributes.some(
1276
- (n) => AST11.is(AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key"
1277
- );
1280
+ const keyPropOnElement = node.attributes.some((n) => AST11.is(AST_NODE_TYPES.JSXAttribute)(n) && n.name.name === "key");
1278
1281
  if (O.isSome(keyPropFound) && !keyPropOnElement) {
1279
1282
  return O.some({ messageId: "noImplicitKey", node: keyPropFound.value });
1280
1283
  }
@@ -1398,7 +1401,7 @@ var no_leaked_conditional_rendering_default = createRule({
1398
1401
  name: RULE_NAME27,
1399
1402
  create(context) {
1400
1403
  if (!context.sourceCode.text.includes("&&") && !context.sourceCode.text.includes("?")) return {};
1401
- const { version: version2 } = normalizeSettings(decodeSettings(context.settings));
1404
+ const { version: version2 } = getSettingsFromContext(context);
1402
1405
  const allowedVariants = [
1403
1406
  "any",
1404
1407
  "boolean",
@@ -1552,10 +1555,8 @@ var no_missing_key_default = createRule({
1552
1555
  function checkBlockStatement(node) {
1553
1556
  return AST11.getNestedReturnStatements(node).reduce((acc, statement) => {
1554
1557
  if (!statement.argument) return acc;
1555
- const maybeDescriptor = checkIteratorElement(statement.argument);
1556
- if (O.isNone(maybeDescriptor)) return acc;
1557
- const descriptor = maybeDescriptor.value;
1558
- return [...acc, descriptor];
1558
+ const mbDescriptor = checkIteratorElement(statement.argument);
1559
+ return O.isNone(mbDescriptor) ? acc : [...acc, mbDescriptor.value];
1559
1560
  }, []);
1560
1561
  }
1561
1562
  return {
@@ -1653,7 +1654,7 @@ var no_nested_components_default = createRule({
1653
1654
  if (O.isNone(componentName)) continue;
1654
1655
  const name2 = componentName.value;
1655
1656
  const isInsideProperty = component.parent.type === AST_NODE_TYPES.Property;
1656
- const isInsideJSXPropValue = component.parent.type === AST_NODE_TYPES.JSXAttribute || O.isSome(JSX7.traverseUpProp(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer));
1657
+ const isInsideJSXPropValue = component.parent.type === AST_NODE_TYPES.JSXAttribute || O.isSome(JSX7.findParentProp(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer));
1657
1658
  if (isInsideJSXPropValue) {
1658
1659
  if (!isDeclaredInRenderPropLoose(component)) {
1659
1660
  context.report({
@@ -1676,8 +1677,14 @@ var no_nested_components_default = createRule({
1676
1677
  });
1677
1678
  continue;
1678
1679
  }
1679
- const maybeParentComponent = AST11.traverseUpGuard(component, isFunctionComponent);
1680
- if (O.isSome(maybeParentComponent) && !isDirectValueOfRenderPropertyLoose(maybeParentComponent.value)) {
1680
+ const isParnetComponentNotDirectValueOfRenderProperty = O.exists(
1681
+ AST11.findParentNodeGuard(
1682
+ component,
1683
+ isFunctionComponent
1684
+ ),
1685
+ not(isDirectValueOfRenderPropertyLoose)
1686
+ );
1687
+ if (isParnetComponentNotDirectValueOfRenderProperty) {
1681
1688
  context.report({
1682
1689
  messageId: isInsideProperty ? "nestedComponentInProps" : "nestedComponent",
1683
1690
  node: component,
@@ -1687,8 +1694,7 @@ var no_nested_components_default = createRule({
1687
1694
  });
1688
1695
  continue;
1689
1696
  }
1690
- const isInsideClassComponentRenderMethod = isInsideRenderMethod(component);
1691
- if (isInsideClassComponentRenderMethod) {
1697
+ if (isInsideRenderMethod(component)) {
1692
1698
  context.report({
1693
1699
  messageId: "nestedComponent",
1694
1700
  node: component,
@@ -1699,7 +1705,7 @@ var no_nested_components_default = createRule({
1699
1705
  }
1700
1706
  }
1701
1707
  for (const { name: name2, node: component } of classComponents) {
1702
- if (O.isNone(AST11.traverseUp(component, or(isClassComponent11, isFunctionComponent)))) {
1708
+ if (O.isNone(AST11.findParentNode(component, or(isClassComponent11, isFunctionComponent)))) {
1703
1709
  continue;
1704
1710
  }
1705
1711
  context.report({
@@ -1831,8 +1837,8 @@ var no_set_state_in_component_did_mount_default = createRule({
1831
1837
  if (!isThisSetState(node)) return O.none();
1832
1838
  return F.pipe(
1833
1839
  O.Do,
1834
- O.bind("clazz", () => AST11.traverseUpGuard(node, isClassComponent)),
1835
- O.bind("method", ({ clazz }) => AST11.traverseUpStop(node, clazz, isComponentDidMount)),
1840
+ O.bind("clazz", () => AST11.findParentNodeGuard(node, isClassComponent)),
1841
+ O.bind("method", ({ clazz }) => AST11.findParentNodeStop(node, clazz, isComponentDidMount)),
1836
1842
  O.bind("methodScope", ({ method }) => O.some(context.sourceCode.getScope(method))),
1837
1843
  O.bind("upperScope", () => O.fromNullable(context.sourceCode.getScope(node).upper)),
1838
1844
  O.filter(
@@ -1881,11 +1887,17 @@ var no_set_state_in_component_did_update_default = createRule({
1881
1887
  if (!isThisSetState(node)) return O.none();
1882
1888
  return F.pipe(
1883
1889
  O.Do,
1884
- O.bind("clazz", () => AST11.traverseUpGuard(node, isClassComponent)),
1885
- O.bind("method", ({ clazz }) => AST11.traverseUpStop(node, clazz, isComponentDidUpdate)),
1890
+ O.bind("clazz", () => AST11.findParentNodeGuard(node, isClassComponent)),
1891
+ O.bind("method", ({ clazz }) => AST11.findParentNodeStop(node, clazz, isComponentDidUpdate)),
1892
+ O.bind("methodScope", ({ method }) => O.some(context.sourceCode.getScope(method))),
1886
1893
  O.bind("upperScope", () => O.fromNullable(context.sourceCode.getScope(node).upper)),
1887
1894
  O.filter(
1888
- ({ clazz, method, upperScope }) => method.parent === clazz.body && upperScope === context.sourceCode.getScope(method)
1895
+ ({
1896
+ clazz,
1897
+ method,
1898
+ methodScope,
1899
+ upperScope
1900
+ }) => method.parent === clazz.body && upperScope === methodScope
1889
1901
  ),
1890
1902
  O.map(() => ({
1891
1903
  messageId: "noSetStateInComponentDidUpdate",
@@ -1925,11 +1937,17 @@ var no_set_state_in_component_will_update_default = createRule({
1925
1937
  if (!isThisSetState(node)) return O.none();
1926
1938
  return F.pipe(
1927
1939
  O.Do,
1928
- O.bind("clazz", () => AST11.traverseUpGuard(node, isClassComponent)),
1929
- O.bind("method", ({ clazz }) => AST11.traverseUpStop(node, clazz, isComponentWillUpdate3)),
1940
+ O.bind("clazz", () => AST11.findParentNodeGuard(node, isClassComponent)),
1941
+ O.bind("method", ({ clazz }) => AST11.findParentNodeStop(node, clazz, isComponentWillUpdate3)),
1942
+ O.bind("methodScope", ({ method }) => O.some(context.sourceCode.getScope(method))),
1930
1943
  O.bind("upperScope", () => O.fromNullable(context.sourceCode.getScope(node).upper)),
1931
1944
  O.filter(
1932
- ({ clazz, method, upperScope }) => method.parent === clazz.body && upperScope === context.sourceCode.getScope(method)
1945
+ ({
1946
+ clazz,
1947
+ method,
1948
+ methodScope,
1949
+ upperScope
1950
+ }) => method.parent === clazz.body && upperScope === methodScope
1933
1951
  ),
1934
1952
  O.map(() => ({
1935
1953
  messageId: "noSetStateInComponentWillUpdate",
@@ -2140,7 +2158,7 @@ var no_unstable_context_value_default = createRule({
2140
2158
  const openingElementName = node.name;
2141
2159
  if (openingElementName.type !== AST_NODE_TYPES.JSXMemberExpression) return;
2142
2160
  if (openingElementName.property.name !== "Provider") return;
2143
- const constructionEntry = F.pipe(
2161
+ F.pipe(
2144
2162
  O.Do,
2145
2163
  O.bind("function", ctx.getCurrentFunction),
2146
2164
  O.bind("attribute", () => O.fromNullable(
@@ -2153,16 +2171,14 @@ var no_unstable_context_value_default = createRule({
2153
2171
  O.bind("construction", ({ valueExpression }) => {
2154
2172
  const initialScope = context.sourceCode.getScope(valueExpression);
2155
2173
  return O.some(VAR.getValueConstruction(valueExpression, initialScope));
2174
+ }),
2175
+ O.map((vc) => {
2176
+ if (vc.construction.kind === "None") return;
2177
+ if (isReactHookCall(vc.construction.node)) return;
2178
+ const prevs = constructions.get(vc.function.node) ?? [];
2179
+ constructions.set(vc.function.node, [...prevs, vc.construction]);
2156
2180
  })
2157
2181
  );
2158
- for (const { construction, function: [_, fNode] } of O.toArray(constructionEntry)) {
2159
- if (construction.kind === "None") continue;
2160
- if (isReactHookCall(construction.node)) continue;
2161
- constructions.set(fNode, [
2162
- ...constructions.get(fNode) ?? [],
2163
- construction
2164
- ]);
2165
- }
2166
2182
  },
2167
2183
  "Program:exit"(node) {
2168
2184
  const components = ctx.getAllComponents(node).values();
@@ -2240,10 +2256,11 @@ var no_unstable_default_props_default = createRule({
2240
2256
  }
2241
2257
  },
2242
2258
  "VariableDeclarator[id.type='ObjectPattern'][init.type='Identifier']"(node) {
2243
- for (const [_, currentFn] of O.toArray(ctx.getCurrentFunction())) {
2244
- const prevDeclarators = declarators.get(currentFn) ?? [];
2245
- declarators.set(currentFn, [...prevDeclarators, node]);
2246
- }
2259
+ const mbEntry = ctx.getCurrentFunction();
2260
+ if (O.isNone(mbEntry)) return;
2261
+ const entry = mbEntry.value;
2262
+ const prevs = declarators.get(entry.node) ?? [];
2263
+ declarators.set(entry.node, [...prevs, node]);
2247
2264
  }
2248
2265
  };
2249
2266
  },
@@ -2371,7 +2388,9 @@ var no_unused_class_component_members_default = createRule({
2371
2388
  if (node.init && AST11.isThisExpression(node.init) && node.id.type === AST_NODE_TYPES.ObjectPattern) {
2372
2389
  for (const prop of node.id.properties) {
2373
2390
  if (prop.type === AST_NODE_TYPES.Property && AST11.isKeyLiteralLike(prop, prop.key)) {
2374
- for (const name2 of O.toArray(getName3(prop.key))) {
2391
+ const mbName = getName3(prop.key);
2392
+ if (O.isSome(mbName)) {
2393
+ const name2 = mbName.value;
2375
2394
  propertyUsages.get(currentClass)?.add(name2);
2376
2395
  }
2377
2396
  }
@@ -2535,7 +2554,10 @@ function checkAndReport(node, context, allowExpressions) {
2535
2554
  const initialScope = context.sourceCode.getScope(node);
2536
2555
  if (JSX7.isKeyedElement(node, initialScope)) return;
2537
2556
  if (JSX7.isBuiltInElement(node.parent)) context.report({ messageId: "noUselessFragmentInBuiltIn", node });
2538
- if (node.children.length === 0) return context.report({ messageId: "noUselessFragment", node });
2557
+ if (node.children.length === 0) {
2558
+ context.report({ messageId: "noUselessFragment", node });
2559
+ return;
2560
+ }
2539
2561
  const isChildElement = AST11.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent);
2540
2562
  switch (true) {
2541
2563
  // <Foo content={<>ee eeee eeee ...</>} />
@@ -2544,10 +2566,12 @@ function checkAndReport(node, context, allowExpressions) {
2544
2566
  }
2545
2567
  // <Foo><>hello, world</></Foo>
2546
2568
  case (!allowExpressions && isChildElement): {
2547
- return context.report({ messageId: "noUselessFragment", node });
2569
+ context.report({ messageId: "noUselessFragment", node });
2570
+ return;
2548
2571
  }
2549
2572
  case (!allowExpressions && !isChildElement && node.children.length === 1): {
2550
- return context.report({ messageId: "noUselessFragment", node });
2573
+ context.report({ messageId: "noUselessFragment", node });
2574
+ return;
2551
2575
  }
2552
2576
  }
2553
2577
  const nonPaddingChildren = node.children.filter((child) => !JSX7.isPaddingSpaces(child));
@@ -2555,7 +2579,8 @@ function checkAndReport(node, context, allowExpressions) {
2555
2579
  switch (true) {
2556
2580
  case nonPaddingChildren.length === 0:
2557
2581
  case (nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== AST_NODE_TYPES.JSXExpressionContainer): {
2558
- return context.report({ messageId: "noUselessFragment", node });
2582
+ context.report({ messageId: "noUselessFragment", node });
2583
+ return;
2559
2584
  }
2560
2585
  }
2561
2586
  return;
@@ -2632,8 +2657,10 @@ var prefer_destructuring_assignment_default = createRule({
2632
2657
  const components = Array.from(ctx.getAllComponents(node).values());
2633
2658
  function isFunctionComponent(block) {
2634
2659
  if (!AST11.isFunction(block)) return false;
2635
- const maybeId = AST11.getFunctionIdentifier(block);
2636
- return O.isSome(maybeId) && isComponentName(maybeId.value.name) && components.some((component) => component.node === block);
2660
+ return O.exists(
2661
+ AST11.getFunctionIdentifier(block),
2662
+ (id) => isComponentName(id.name) && components.some((component) => component.node === block)
2663
+ );
2637
2664
  }
2638
2665
  for (const [initialScope, memberExpression] of memberExpressionWithNames) {
2639
2666
  let scope = initialScope;
@@ -2691,7 +2718,7 @@ var prefer_react_namespace_import_default = createRule({
2691
2718
  },
2692
2719
  name: RULE_NAME46,
2693
2720
  create(context) {
2694
- const importSource = decodeSettings(context.settings).importSource ?? "react";
2721
+ const importSource = getSettingsFromContext(context).importSource ?? "react";
2695
2722
  return {
2696
2723
  [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
2697
2724
  const hasOtherSpecifiers = node.parent.specifiers.length > 1;
@@ -2812,7 +2839,8 @@ var prefer_shorthand_boolean_default = createRule({
2812
2839
  });
2813
2840
  var RULE_NAME49 = "prefer-shorthand-fragment";
2814
2841
  var RULE_FEATURES48 = [
2815
- "CHK"
2842
+ "CHK",
2843
+ "FIX"
2816
2844
  ];
2817
2845
  var prefer_shorthand_fragment_default = createRule({
2818
2846
  meta: {
@@ -2821,6 +2849,7 @@ var prefer_shorthand_fragment_default = createRule({
2821
2849
  description: "enforce using fragment syntax instead of 'Fragment' component",
2822
2850
  [Symbol.for("rule_features")]: RULE_FEATURES48
2823
2851
  },
2852
+ fixable: "code",
2824
2853
  messages: {
2825
2854
  preferShorthandFragment: "Use fragment shorthand syntax instead of 'Fragment' component."
2826
2855
  },
@@ -2834,7 +2863,15 @@ var prefer_shorthand_fragment_default = createRule({
2834
2863
  if (hasAttributes) return O.none();
2835
2864
  return O.some({
2836
2865
  messageId: "preferShorthandFragment",
2837
- node
2866
+ node,
2867
+ fix: (fixer) => {
2868
+ const { closingElement, openingElement } = node;
2869
+ if (!closingElement) return [];
2870
+ return [
2871
+ fixer.replaceTextRange([openingElement.range[0], openingElement.range[1]], "<>"),
2872
+ fixer.replaceTextRange([closingElement.range[0], closingElement.range[1]], "</>")
2873
+ ];
2874
+ }
2838
2875
  });
2839
2876
  }
2840
2877
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "1.23.1",
3
+ "version": "1.23.2-beta.6",
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",
@@ -40,25 +40,25 @@
40
40
  "./package.json"
41
41
  ],
42
42
  "dependencies": {
43
- "@typescript-eslint/scope-manager": "^8.19.0",
44
- "@typescript-eslint/type-utils": "^8.19.0",
45
- "@typescript-eslint/types": "^8.19.0",
46
- "@typescript-eslint/utils": "^8.19.0",
43
+ "@typescript-eslint/scope-manager": "^8.19.1",
44
+ "@typescript-eslint/type-utils": "^8.19.1",
45
+ "@typescript-eslint/types": "^8.19.1",
46
+ "@typescript-eslint/utils": "^8.19.1",
47
47
  "compare-versions": "^6.1.1",
48
48
  "is-immutable-type": "^5.0.1",
49
49
  "string-ts": "^2.2.0",
50
50
  "ts-api-utils": "^2.0.0",
51
51
  "ts-pattern": "^5.6.0",
52
- "@eslint-react/ast": "1.23.1",
53
- "@eslint-react/core": "1.23.1",
54
- "@eslint-react/eff": "1.23.1",
55
- "@eslint-react/shared": "1.23.1",
56
- "@eslint-react/jsx": "1.23.1",
57
- "@eslint-react/types": "1.23.1",
58
- "@eslint-react/var": "1.23.1"
52
+ "@eslint-react/ast": "1.23.2-beta.6",
53
+ "@eslint-react/core": "1.23.2-beta.6",
54
+ "@eslint-react/eff": "1.23.2-beta.6",
55
+ "@eslint-react/jsx": "1.23.2-beta.6",
56
+ "@eslint-react/types": "1.23.2-beta.6",
57
+ "@eslint-react/var": "1.23.2-beta.6",
58
+ "@eslint-react/shared": "1.23.2-beta.6"
59
59
  },
60
60
  "devDependencies": {
61
- "@types/react": "^19.0.2",
61
+ "@types/react": "^19.0.3",
62
62
  "@types/react-dom": "^19.0.2",
63
63
  "tsup": "^8.3.5",
64
64
  "@workspace/configs": "0.0.0"