oxlint-plugin-react-doctor 0.8.1-dev.90e794f → 0.8.1-dev.a4eaedd

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.
package/dist/index.js CHANGED
@@ -3173,7 +3173,7 @@ const getJsxPropStaticStringValues = (attribute, scopes) => getJsxPropStaticStri
3173
3173
  const getJsxPropExhaustiveStaticStringValues = (attribute, scopes) => getJsxPropStaticStringValuesWithMode(attribute, scopes, null, true);
3174
3174
  //#endregion
3175
3175
  //#region src/plugin/rules/a11y/anchor-has-content.ts
3176
- const MESSAGE$62 = "Blind users can't follow this link because screen readers announce nothing, so add visible text, `aria-label`, or `aria-labelledby`.";
3176
+ const MESSAGE$63 = "Blind users can't follow this link because screen readers announce nothing, so add visible text, `aria-label`, or `aria-labelledby`.";
3177
3177
  const hasLinkRole = (roleValue) => roleValue.trim().split(/\s+/).find((roleToken) => VALID_ARIA_ROLES.has(roleToken)) === "link";
3178
3178
  const isTransComponentsTemplate = (node) => {
3179
3179
  let current = node.parent;
@@ -3215,7 +3215,7 @@ const anchorHasContent = defineRule({
3215
3215
  if (isTransComponentsTemplate(node)) return;
3216
3216
  context.report({
3217
3217
  node: opening.name,
3218
- message: MESSAGE$62
3218
+ message: MESSAGE$63
3219
3219
  });
3220
3220
  } };
3221
3221
  }
@@ -3703,7 +3703,7 @@ const parseJsxValue = (value) => {
3703
3703
  };
3704
3704
  //#endregion
3705
3705
  //#region src/plugin/rules/a11y/aria-activedescendant-has-tabindex.ts
3706
- const MESSAGE$61 = "Keyboard users can't focus this element with `aria-activedescendant` because it isn't tabbable, so add `tabIndex={0}`.";
3706
+ const MESSAGE$62 = "Keyboard users can't focus this element with `aria-activedescendant` because it isn't tabbable, so add `tabIndex={0}`.";
3707
3707
  const ariaActivedescendantHasTabindex = defineRule({
3708
3708
  id: "aria-activedescendant-has-tabindex",
3709
3709
  title: "aria-activedescendant missing tabindex",
@@ -3721,7 +3721,7 @@ const ariaActivedescendantHasTabindex = defineRule({
3721
3721
  if (tabIndexValue === null || tabIndexValue >= -1) return;
3722
3722
  context.report({
3723
3723
  node: node.name,
3724
- message: MESSAGE$61
3724
+ message: MESSAGE$62
3725
3725
  });
3726
3726
  return;
3727
3727
  }
@@ -3729,7 +3729,7 @@ const ariaActivedescendantHasTabindex = defineRule({
3729
3729
  if (canContentEditableBeTabbable(node, context.scopes, context.settings)) return;
3730
3730
  context.report({
3731
3731
  node: node.name,
3732
- message: MESSAGE$61
3732
+ message: MESSAGE$62
3733
3733
  });
3734
3734
  } })
3735
3735
  });
@@ -6827,7 +6827,7 @@ const stripThisParameter = (parameters) => {
6827
6827
  };
6828
6828
  //#endregion
6829
6829
  //#region src/plugin/rules/security/auth-token-in-web-storage.ts
6830
- const MESSAGE$60 = "Storing an auth token in `localStorage`/`sessionStorage` exposes it to any XSS on the page: JavaScript can read web storage and exfiltrate the token. Keep tokens in an `HttpOnly`, `Secure`, `SameSite` cookie instead.";
6830
+ const MESSAGE$61 = "Storing an auth token in `localStorage`/`sessionStorage` exposes it to any XSS on the page: JavaScript can read web storage and exfiltrate the token. Keep tokens in an `HttpOnly`, `Secure`, `SameSite` cookie instead.";
6831
6831
  const STORAGE_NAMES = new Set(["localStorage", "sessionStorage"]);
6832
6832
  const STORAGE_GLOBALS = new Set([
6833
6833
  "window",
@@ -6999,7 +6999,7 @@ const authTokenInWebStorage = defineRule({
6999
6999
  })) return;
7000
7000
  context.report({
7001
7001
  node,
7002
- message: MESSAGE$60
7002
+ message: MESSAGE$61
7003
7003
  });
7004
7004
  },
7005
7005
  AssignmentExpression(node) {
@@ -7010,7 +7010,7 @@ const authTokenInWebStorage = defineRule({
7010
7010
  if (!propertyName || !isAuthCredentialKey(propertyName)) return;
7011
7011
  context.report({
7012
7012
  node: target,
7013
- message: MESSAGE$60
7013
+ message: MESSAGE$61
7014
7014
  });
7015
7015
  }
7016
7016
  }))
@@ -7149,7 +7149,7 @@ const CI_INSTALL_NEAR_SECRET_PATTERN = /(?:npm|pnpm|yarn|bun)\s+(?:install|ci)\b
7149
7149
  const INSTALL_COMMAND_PATTERN = /(?:npm|pnpm|yarn|bun)\s+(?:install|ci)\b/i;
7150
7150
  const SECRET_REFERENCE_PATTERN = /\bsecrets\.[A-Z0-9_]+/;
7151
7151
  const IGNORE_SCRIPTS_FLAG_PATTERN = /--ignore-scripts\b/;
7152
- const MESSAGE$59 = "The build or install pipeline can execute package lifecycle code while CI secrets may be present.";
7152
+ const MESSAGE$60 = "The build or install pipeline can execute package lifecycle code while CI secrets may be present.";
7153
7153
  const isWorkflowPath = (relativePath) => /(?:^|\/)\.github\/workflows\/[^/]+\.ya?ml$/i.test(relativePath);
7154
7154
  const scanWorkflowContent = (content) => {
7155
7155
  const lines = content.split("\n");
@@ -7194,7 +7194,7 @@ const scanWorkflowContent = (content) => {
7194
7194
  const installLineOffset = Math.max(step.lines.findIndex((stepLine) => INSTALL_COMMAND_PATTERN.test(stepLine)), 0);
7195
7195
  const installColumnIndex = step.lines[installLineOffset].search(INSTALL_COMMAND_PATTERN);
7196
7196
  return [{
7197
- message: MESSAGE$59,
7197
+ message: MESSAGE$60,
7198
7198
  line: step.startLineIndex + installLineOffset + 1,
7199
7199
  column: (installColumnIndex === -1 ? 0 : installColumnIndex) + 1
7200
7200
  }];
@@ -7204,7 +7204,7 @@ const scanWorkflowContent = (content) => {
7204
7204
  const scanNonWorkflowConfig = scanByPattern({
7205
7205
  shouldScan: (file) => isConfigOrCiPath(file.relativePath) && !file.relativePath.endsWith("package.json") && !isWorkflowPath(file.relativePath),
7206
7206
  pattern: CI_INSTALL_NEAR_SECRET_PATTERN,
7207
- message: MESSAGE$59
7207
+ message: MESSAGE$60
7208
7208
  });
7209
7209
  const scan = (file) => {
7210
7210
  if (isWorkflowPath(file.relativePath)) return scanWorkflowContent(file.content);
@@ -7954,7 +7954,7 @@ const isPureEventBlockerHandler = (attribute) => {
7954
7954
  };
7955
7955
  //#endregion
7956
7956
  //#region src/plugin/rules/a11y/click-events-have-key-events.ts
7957
- const MESSAGE$58 = "Keyboard users can't trigger this click handler because there's no keyboard one, so add `onKeyUp`, `onKeyDown`, or `onKeyPress`.";
7957
+ const MESSAGE$59 = "Keyboard users can't trigger this click handler because there's no keyboard one, so add `onKeyUp`, `onKeyDown`, or `onKeyPress`.";
7958
7958
  const KEY_HANDLERS = [
7959
7959
  "onKeyUp",
7960
7960
  "onKeyDown",
@@ -8165,7 +8165,7 @@ const clickEventsHaveKeyEvents = defineRule({
8165
8165
  if (KEY_HANDLERS.some((handler) => hasJsxPropIgnoreCase(node.attributes, handler) || spreadEventValues.has(handler.toLowerCase()))) return;
8166
8166
  context.report({
8167
8167
  node: node.name,
8168
- message: MESSAGE$58
8168
+ message: MESSAGE$59
8169
8169
  });
8170
8170
  } };
8171
8171
  }
@@ -10257,7 +10257,7 @@ const getClassNameLiteral = (classAttribute) => {
10257
10257
  };
10258
10258
  //#endregion
10259
10259
  //#region src/plugin/rules/a11y/control-has-associated-label.ts
10260
- const MESSAGE$57 = "Blind users can't tell what this control does because screen readers find no label, so add visible text, `aria-label`, or `aria-labelledby`.";
10260
+ const MESSAGE$58 = "Blind users can't tell what this control does because screen readers find no label, so add visible text, `aria-label`, or `aria-labelledby`.";
10261
10261
  const NON_OPERABLE_ELEMENTS = new Set([
10262
10262
  "td",
10263
10263
  "th",
@@ -10787,7 +10787,7 @@ const controlHasAssociatedLabel = defineRule({
10787
10787
  if (candidate.enclosingBindingName !== null && labelEmbeddedNames.has(candidate.enclosingBindingName)) continue;
10788
10788
  context.report({
10789
10789
  node: candidate.opening,
10790
- message: MESSAGE$57
10790
+ message: MESSAGE$58
10791
10791
  });
10792
10792
  }
10793
10793
  }
@@ -12594,7 +12594,7 @@ const noVagueButtonLabel = defineRule({
12594
12594
  });
12595
12595
  //#endregion
12596
12596
  //#region src/plugin/rules/a11y/dialog-has-accessible-name.ts
12597
- const MESSAGE$56 = "This dialog has no accessible name, so screen readers announce it as just “dialog.” Add `aria-label` or point `aria-labelledby` at its heading.";
12597
+ const MESSAGE$57 = "This dialog has no accessible name, so screen readers announce it as just “dialog.” Add `aria-label` or point `aria-labelledby` at its heading.";
12598
12598
  const DIALOG_ROLES = new Set(["dialog", "alertdialog"]);
12599
12599
  const NAME_PROVIDING_ATTRIBUTES = [
12600
12600
  "aria-label",
@@ -12619,7 +12619,7 @@ const dialogHasAccessibleName = defineRule({
12619
12619
  if (NAME_PROVIDING_ATTRIBUTES.some((attribute) => hasJsxPropIgnoreCase(node.attributes, attribute))) return;
12620
12620
  context.report({
12621
12621
  node: node.name,
12622
- message: MESSAGE$56
12622
+ message: MESSAGE$57
12623
12623
  });
12624
12624
  } };
12625
12625
  }
@@ -12659,7 +12659,7 @@ const isEs6Component = (node) => {
12659
12659
  };
12660
12660
  //#endregion
12661
12661
  //#region src/plugin/rules/react-builtins/display-name.ts
12662
- const MESSAGE$55 = "This component shows up as Anonymous in React DevTools because it has no `displayName`.";
12662
+ const MESSAGE$56 = "This component shows up as Anonymous in React DevTools because it has no `displayName`.";
12663
12663
  const DEFAULT_ADDITIONAL_HOCS = [
12664
12664
  "observer",
12665
12665
  "lazy",
@@ -12852,7 +12852,7 @@ const displayName = defineRule({
12852
12852
  const reportAt = (node) => {
12853
12853
  context.report({
12854
12854
  node,
12855
- message: MESSAGE$55
12855
+ message: MESSAGE$56
12856
12856
  });
12857
12857
  };
12858
12858
  return {
@@ -19264,7 +19264,7 @@ const forbidElements = defineRule({
19264
19264
  });
19265
19265
  //#endregion
19266
19266
  //#region src/plugin/rules/react-builtins/forward-ref-uses-ref.ts
19267
- const MESSAGE$54 = "The parent can't reach this component's node because the `forwardRef` wrapper ignores `ref`.";
19267
+ const MESSAGE$55 = "The parent can't reach this component's node because the `forwardRef` wrapper ignores `ref`.";
19268
19268
  const forwardRefUsesRef = defineRule({
19269
19269
  id: "forward-ref-uses-ref",
19270
19270
  title: "forwardRef without ref parameter",
@@ -19287,7 +19287,7 @@ const forwardRefUsesRef = defineRule({
19287
19287
  if (isNodeOfType(onlyParam, "RestElement")) return;
19288
19288
  context.report({
19289
19289
  node: inner,
19290
- message: MESSAGE$54
19290
+ message: MESSAGE$55
19291
19291
  });
19292
19292
  } })
19293
19293
  });
@@ -19328,7 +19328,7 @@ const gitProviderUrlInjectionRisk = defineRule({
19328
19328
  });
19329
19329
  //#endregion
19330
19330
  //#region src/plugin/rules/a11y/heading-has-content.ts
19331
- const MESSAGE$53 = "Blind users can't use this heading to navigate because screen readers skip it empty, so add text, `aria-label`, or `aria-labelledby`.";
19331
+ const MESSAGE$54 = "Blind users can't use this heading to navigate because screen readers skip it empty, so add text, `aria-label`, or `aria-labelledby`.";
19332
19332
  const DEFAULT_HEADING_TAGS = [
19333
19333
  "h1",
19334
19334
  "h2",
@@ -19362,7 +19362,7 @@ const headingHasContent = defineRule({
19362
19362
  for (const attribute of ["aria-label", "aria-labelledby"]) if (hasJsxPropIgnoreCase(node.attributes, attribute)) return;
19363
19363
  context.report({
19364
19364
  node,
19365
- message: MESSAGE$53
19365
+ message: MESSAGE$54
19366
19366
  });
19367
19367
  } };
19368
19368
  }
@@ -19530,7 +19530,7 @@ const hooksNoNanInDeps = defineRule({
19530
19530
  });
19531
19531
  //#endregion
19532
19532
  //#region src/plugin/rules/a11y/html-has-lang.ts
19533
- const MESSAGE$52 = "Screen readers may mispronounce this page because it doesn't declare a language, so add a `lang` attribute like `en`.";
19533
+ const MESSAGE$53 = "Screen readers may mispronounce this page because it doesn't declare a language, so add a `lang` attribute like `en`.";
19534
19534
  const resolveSettings$38 = (settings) => {
19535
19535
  const reactDoctor = settings?.["react-doctor"];
19536
19536
  return { htmlTags: (typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.htmlHasLang ?? {} : {}).htmlTags ?? ["html"] };
@@ -19577,13 +19577,13 @@ const htmlHasLang = defineRule({
19577
19577
  if (!lang) {
19578
19578
  context.report({
19579
19579
  node: node.name,
19580
- message: MESSAGE$52
19580
+ message: MESSAGE$53
19581
19581
  });
19582
19582
  return;
19583
19583
  }
19584
19584
  if (evaluateLang(lang.value) === "empty") context.report({
19585
19585
  node: lang,
19586
- message: MESSAGE$52
19586
+ message: MESSAGE$53
19587
19587
  });
19588
19588
  } };
19589
19589
  }
@@ -19856,7 +19856,7 @@ const isJsxFragmentElement = (node, scopes) => {
19856
19856
  };
19857
19857
  //#endregion
19858
19858
  //#region src/plugin/rules/a11y/iframe-has-title.ts
19859
- const MESSAGE$51 = "Screen reader users cannot identify this `<iframe>` because it has no title. Add a `title` that describes its content.";
19859
+ const MESSAGE$52 = "Screen reader users cannot identify this `<iframe>` because it has no title. Add a `title` that describes its content.";
19860
19860
  const isStaticallyAriaHidden = (openingElement) => {
19861
19861
  const ariaHiddenAttribute = getAuthoritativeJsxAttribute(openingElement.attributes, "aria-hidden", false);
19862
19862
  if (!ariaHiddenAttribute) return false;
@@ -19945,14 +19945,14 @@ const iframeHasTitle = defineRule({
19945
19945
  if (!titleAttr) {
19946
19946
  if (hasSpread || tag === "iframe") context.report({
19947
19947
  node: node.name,
19948
- message: MESSAGE$51
19948
+ message: MESSAGE$52
19949
19949
  });
19950
19950
  return;
19951
19951
  }
19952
19952
  const verdict = evaluateTitleValue(titleAttr.value);
19953
19953
  if (verdict === "missing" || verdict === "empty") context.report({
19954
19954
  node: titleAttr,
19955
- message: MESSAGE$51
19955
+ message: MESSAGE$52
19956
19956
  });
19957
19957
  } })
19958
19958
  });
@@ -20077,7 +20077,7 @@ const iframeMissingSandbox = defineRule({
20077
20077
  });
20078
20078
  //#endregion
20079
20079
  //#region src/plugin/rules/a11y/img-redundant-alt.ts
20080
- const MESSAGE$50 = "Screen reader users hear \"image\" or \"photo\" twice because they already announce it, so describe what the image shows instead.";
20080
+ const MESSAGE$51 = "Screen reader users hear \"image\" or \"photo\" twice because they already announce it, so describe what the image shows instead.";
20081
20081
  const DEFAULT_COMPONENTS = ["img"];
20082
20082
  const DEFAULT_REDUNDANT_WORDS = [
20083
20083
  "image",
@@ -20142,7 +20142,7 @@ const imgRedundantAlt = defineRule({
20142
20142
  if (!altAttribute) return;
20143
20143
  if (altValueRedundant(altAttribute, settings.words)) context.report({
20144
20144
  node: altAttribute,
20145
- message: MESSAGE$50
20145
+ message: MESSAGE$51
20146
20146
  });
20147
20147
  } };
20148
20148
  }
@@ -22106,7 +22106,7 @@ const getHoistableRegExpConstructionKind = (node, context) => {
22106
22106
  if (!STATEFUL_REGEXP_FLAGS_PATTERN.test(effectiveFlags)) return "stateless";
22107
22107
  return isSafeStatefulReplaceAllSearch(node, effectiveFlags, context) ? "statefulReplaceAll" : null;
22108
22108
  };
22109
- const MESSAGE$49 = "`new RegExp()` rebuilds the pattern on every loop pass. Move it to a constant outside the loop.";
22109
+ const MESSAGE$50 = "`new RegExp()` rebuilds the pattern on every loop pass. Move it to a constant outside the loop.";
22110
22110
  const jsHoistRegexp = defineRule({
22111
22111
  id: "js-hoist-regexp",
22112
22112
  title: "RegExp built inside a loop",
@@ -22123,7 +22123,7 @@ const jsHoistRegexp = defineRule({
22123
22123
  if (constructionKind === "statefulReplaceAll" && cachedEnvironmentHazard === "replaceAllIntegrityLost") return;
22124
22124
  context.report({
22125
22125
  node,
22126
- message: MESSAGE$49
22126
+ message: MESSAGE$50
22127
22127
  });
22128
22128
  };
22129
22129
  return createLoopAwareVisitors({
@@ -24890,7 +24890,7 @@ const jsxMaxDepth = defineRule({
24890
24890
  });
24891
24891
  //#endregion
24892
24892
  //#region src/plugin/rules/react-builtins/jsx-no-comment-textnodes.ts
24893
- const MESSAGE$48 = "Your users see this comment as text on the page because `//` & `/*` aren't hidden in JSX.";
24893
+ const MESSAGE$49 = "Your users see this comment as text on the page because `//` & `/*` aren't hidden in JSX.";
24894
24894
  const LITERAL_TEXT_TAGS = new Set([
24895
24895
  "code",
24896
24896
  "pre",
@@ -24960,7 +24960,7 @@ const jsxNoCommentTextnodes = defineRule({
24960
24960
  if (isDeliberateStyledCommentToken(node)) return;
24961
24961
  context.report({
24962
24962
  node,
24963
- message: MESSAGE$48
24963
+ message: MESSAGE$49
24964
24964
  });
24965
24965
  } })
24966
24966
  });
@@ -24991,7 +24991,7 @@ const isInsideFunctionScope = (node) => {
24991
24991
  };
24992
24992
  //#endregion
24993
24993
  //#region src/plugin/rules/react-builtins/jsx-no-constructed-context-values.ts
24994
- const MESSAGE$47 = "Every reader of this context redraws on each render because you build its `value` inline.";
24994
+ const MESSAGE$48 = "Every reader of this context redraws on each render because you build its `value` inline.";
24995
24995
  const CONTEXT_MODULES$1 = [
24996
24996
  "react",
24997
24997
  "use-context-selector",
@@ -25094,7 +25094,7 @@ const jsxNoConstructedContextValues = defineRule({
25094
25094
  if (!isConstructedValue(innerExpression)) continue;
25095
25095
  context.report({
25096
25096
  node: attribute,
25097
- message: MESSAGE$47
25097
+ message: MESSAGE$48
25098
25098
  });
25099
25099
  }
25100
25100
  }
@@ -25960,7 +25960,7 @@ const DATA_ARRAY_PROP_SUFFIXES = [
25960
25960
  ];
25961
25961
  //#endregion
25962
25962
  //#region src/plugin/rules/react-builtins/jsx-no-new-array-as-prop.ts
25963
- const MESSAGE$46 = "This child redraws every render because the prop gets a brand new array each time.";
25963
+ const MESSAGE$47 = "This child redraws every render because the prop gets a brand new array each time.";
25964
25964
  const isDataArrayPropName = (propName) => {
25965
25965
  if (DATA_ARRAY_PROP_NAMES.has(propName)) return true;
25966
25966
  for (const suffix of DATA_ARRAY_PROP_SUFFIXES) if (propName.length > suffix.length && propName.endsWith(suffix)) return true;
@@ -26047,7 +26047,7 @@ const jsxNoNewArrayAsProp = defineRule({
26047
26047
  if (!isArrayProducingExpression(expressionNode) && !followsRenderLocalArrayBinding(expressionNode, node)) return;
26048
26048
  context.report({
26049
26049
  node,
26050
- message: MESSAGE$46
26050
+ message: MESSAGE$47
26051
26051
  });
26052
26052
  }
26053
26053
  };
@@ -26305,7 +26305,7 @@ const SAFE_RECEIVER_NAMES = new Set([
26305
26305
  ]);
26306
26306
  //#endregion
26307
26307
  //#region src/plugin/rules/react-builtins/jsx-no-new-function-as-prop.ts
26308
- const MESSAGE$45 = "This child redraws every render because the prop gets a brand new function each time.";
26308
+ const MESSAGE$46 = "This child redraws every render because the prop gets a brand new function each time.";
26309
26309
  const isAccessorPredicateName = (propName) => {
26310
26310
  for (const prefix of ACCESSOR_PREDICATE_PREFIXES) {
26311
26311
  if (propName.length <= prefix.length) continue;
@@ -26512,7 +26512,7 @@ const jsxNoNewFunctionAsProp = defineRule({
26512
26512
  if (!isFunctionProducingExpression(expressionNode) && !followsRenderLocalFunctionBinding(expressionNode, node)) return;
26513
26513
  context.report({
26514
26514
  node,
26515
- message: MESSAGE$45
26515
+ message: MESSAGE$46
26516
26516
  });
26517
26517
  }
26518
26518
  };
@@ -26732,7 +26732,7 @@ const CONFIG_OBJECT_PROP_SUFFIXES = [
26732
26732
  ];
26733
26733
  //#endregion
26734
26734
  //#region src/plugin/rules/react-builtins/jsx-no-new-object-as-prop.ts
26735
- const MESSAGE$44 = "This child redraws every render because the prop gets a brand new object each time.";
26735
+ const MESSAGE$45 = "This child redraws every render because the prop gets a brand new object each time.";
26736
26736
  const isConfigObjectPropName = (propName) => {
26737
26737
  if (CONFIG_OBJECT_PROP_NAMES.has(propName)) return true;
26738
26738
  for (const suffix of CONFIG_OBJECT_PROP_SUFFIXES) if (propName.length > suffix.length && propName.endsWith(suffix)) return true;
@@ -26821,7 +26821,7 @@ const jsxNoNewObjectAsProp = defineRule({
26821
26821
  if (!isObjectProducingExpression(expressionNode) && !followsRenderLocalObjectBinding(expressionNode, node)) return;
26822
26822
  context.report({
26823
26823
  node,
26824
- message: MESSAGE$44
26824
+ message: MESSAGE$45
26825
26825
  });
26826
26826
  }
26827
26827
  };
@@ -26829,7 +26829,7 @@ const jsxNoNewObjectAsProp = defineRule({
26829
26829
  });
26830
26830
  //#endregion
26831
26831
  //#region src/plugin/rules/react-builtins/jsx-no-script-url.ts
26832
- const MESSAGE$43 = "A `javascript:` URL is an XSS hole that runs injected input as code.";
26832
+ const MESSAGE$44 = "A `javascript:` URL is an XSS hole that runs injected input as code.";
26833
26833
  const JAVASCRIPT_URL_PATTERN = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;
26834
26834
  const resolveSettings$28 = (settings) => {
26835
26835
  const reactDoctor = settings?.["react-doctor"];
@@ -26867,7 +26867,7 @@ const jsxNoScriptUrl = defineRule({
26867
26867
  if (!value || !isNodeOfType(value, "Literal") || typeof value.value !== "string") continue;
26868
26868
  if (JAVASCRIPT_URL_PATTERN.test(value.value)) context.report({
26869
26869
  node: attribute,
26870
- message: MESSAGE$43
26870
+ message: MESSAGE$44
26871
26871
  });
26872
26872
  }
26873
26873
  } };
@@ -27210,7 +27210,7 @@ const jsxPropsNoSpreadMulti = defineRule({
27210
27210
  });
27211
27211
  //#endregion
27212
27212
  //#region src/plugin/rules/react-builtins/jsx-props-no-spreading.ts
27213
- const MESSAGE$42 = "You can't tell what props reach this element when you spread them.";
27213
+ const MESSAGE$43 = "You can't tell what props reach this element when you spread them.";
27214
27214
  const resolveSettings$25 = (settings) => {
27215
27215
  const reactDoctor = settings?.["react-doctor"];
27216
27216
  const ruleSettings = typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.jsxPropsNoSpreading ?? {} : {};
@@ -27253,7 +27253,7 @@ const jsxPropsNoSpreading = defineRule({
27253
27253
  }
27254
27254
  context.report({
27255
27255
  node: attribute,
27256
- message: MESSAGE$42
27256
+ message: MESSAGE$43
27257
27257
  });
27258
27258
  didReportInFile = true;
27259
27259
  return;
@@ -27529,7 +27529,7 @@ const labelHasAssociatedControl = defineRule({
27529
27529
  });
27530
27530
  //#endregion
27531
27531
  //#region src/plugin/rules/a11y/lang.ts
27532
- const MESSAGE$41 = "Screen readers can't pick the right voice because this `lang` isn't a real language code, so use a valid one like `en` or `en-US`.";
27532
+ const MESSAGE$42 = "Screen readers can't pick the right voice because this `lang` isn't a real language code, so use a valid one like `en` or `en-US`.";
27533
27533
  const COMMON_LANGUAGE_PRIMARY_TAGS = new Set([
27534
27534
  "aa",
27535
27535
  "ab",
@@ -28009,7 +28009,7 @@ const lang = defineRule({
28009
28009
  if (expression.type === "Identifier" && expression.name === "undefined" || expression.type === "Literal" && expression.value === null) {
28010
28010
  context.report({
28011
28011
  node: langAttr,
28012
- message: MESSAGE$41
28012
+ message: MESSAGE$42
28013
28013
  });
28014
28014
  return;
28015
28015
  }
@@ -28018,7 +28018,7 @@ const lang = defineRule({
28018
28018
  if (value === null) return;
28019
28019
  if (!isValidLangTag(value)) context.report({
28020
28020
  node: langAttr,
28021
- message: MESSAGE$41
28021
+ message: MESSAGE$42
28022
28022
  });
28023
28023
  } })
28024
28024
  });
@@ -28069,7 +28069,7 @@ const mdxSsrExecutionRisk = defineRule({
28069
28069
  });
28070
28070
  //#endregion
28071
28071
  //#region src/plugin/rules/a11y/media-has-caption.ts
28072
- const MESSAGE$40 = "Deaf and hard-of-hearing users need captions for this media. Add a `<track kind=\"captions\">` inside the `<audio>` or `<video>`.";
28072
+ const MESSAGE$41 = "Deaf and hard-of-hearing users need captions for this media. Add a `<track kind=\"captions\">` inside the `<audio>` or `<video>`.";
28073
28073
  const DEFAULT_AUDIO = ["audio"];
28074
28074
  const DEFAULT_VIDEO = ["video"];
28075
28075
  const DEFAULT_TRACK = ["track"];
@@ -28159,7 +28159,7 @@ const mediaHasCaption = defineRule({
28159
28159
  if (!parent || !isNodeOfType(parent, "JSXElement")) {
28160
28160
  context.report({
28161
28161
  node: node.name,
28162
- message: MESSAGE$40
28162
+ message: MESSAGE$41
28163
28163
  });
28164
28164
  return;
28165
28165
  }
@@ -28178,7 +28178,7 @@ const mediaHasCaption = defineRule({
28178
28178
  return kindValue.value.toLowerCase() === "captions";
28179
28179
  })) context.report({
28180
28180
  node: node.name,
28181
- message: MESSAGE$40
28181
+ message: MESSAGE$41
28182
28182
  });
28183
28183
  } };
28184
28184
  }
@@ -30231,7 +30231,7 @@ const nextjsNoVercelOgImport = defineRule({
30231
30231
  });
30232
30232
  //#endregion
30233
30233
  //#region src/plugin/rules/a11y/no-access-key.ts
30234
- const MESSAGE$39 = "Screen reader users can lose their shortcuts because `accessKey` clashes with them, so remove it.";
30234
+ const MESSAGE$40 = "Screen reader users can lose their shortcuts because `accessKey` clashes with them, so remove it.";
30235
30235
  const isUndefinedIdentifier$1 = (expression) => isNodeOfType(expression, "Identifier") && expression.name === "undefined";
30236
30236
  const noAccessKey = defineRule({
30237
30237
  id: "no-access-key",
@@ -30250,7 +30250,7 @@ const noAccessKey = defineRule({
30250
30250
  if (isNodeOfType(attributeValue, "Literal") && typeof attributeValue.value === "string") {
30251
30251
  context.report({
30252
30252
  node: accessKey,
30253
- message: MESSAGE$39
30253
+ message: MESSAGE$40
30254
30254
  });
30255
30255
  return;
30256
30256
  }
@@ -30260,7 +30260,7 @@ const noAccessKey = defineRule({
30260
30260
  if (isUndefinedIdentifier$1(expression)) return;
30261
30261
  context.report({
30262
30262
  node: accessKey,
30263
- message: MESSAGE$39
30263
+ message: MESSAGE$40
30264
30264
  });
30265
30265
  }
30266
30266
  } };
@@ -32603,7 +32603,7 @@ const noAdjustStateOnPropChange = defineRule({
32603
32603
  });
32604
32604
  //#endregion
32605
32605
  //#region src/plugin/rules/a11y/no-aria-hidden-on-focusable.ts
32606
- const MESSAGE$38 = "Screen reader users tab to this focusable element but hear nothing because `aria-hidden` skips it, so remove `aria-hidden` or stop it being focusable.";
32606
+ const MESSAGE$39 = "Screen reader users tab to this focusable element but hear nothing because `aria-hidden` skips it, so remove `aria-hidden` or stop it being focusable.";
32607
32607
  const ALWAYS_FOCUSABLE_TAGS = new Set([
32608
32608
  "button",
32609
32609
  "embed",
@@ -32715,7 +32715,7 @@ const noAriaHiddenOnFocusable = defineRule({
32715
32715
  const isImplicitlyFocusable = isNativelyFocusable(tag, node);
32716
32716
  if (isExplicitlyFocusable || isImplicitlyFocusable) context.report({
32717
32717
  node: ariaHidden,
32718
- message: MESSAGE$38
32718
+ message: MESSAGE$39
32719
32719
  });
32720
32720
  } })
32721
32721
  });
@@ -33762,7 +33762,7 @@ const isAllLiteralArrayExpression = (node) => {
33762
33762
  };
33763
33763
  //#endregion
33764
33764
  //#region src/plugin/rules/react-builtins/no-array-index-key.ts
33765
- const MESSAGE$37 = "Your users can see & submit the wrong data when this list reorders.";
33765
+ const MESSAGE$38 = "Your users can see & submit the wrong data when this list reorders.";
33766
33766
  const SECOND_INDEX_METHODS = new Set([
33767
33767
  "every",
33768
33768
  "filter",
@@ -33881,14 +33881,14 @@ const noArrayIndexKey = defineRule({
33881
33881
  if (propName !== "key") continue;
33882
33882
  if (expressionUsesIndex(property.value, indexBinding.name)) context.report({
33883
33883
  node: property,
33884
- message: MESSAGE$37
33884
+ message: MESSAGE$38
33885
33885
  });
33886
33886
  }
33887
33887
  } })
33888
33888
  });
33889
33889
  //#endregion
33890
33890
  //#region src/plugin/rules/state-and-effects/no-async-effect-callback.ts
33891
- const MESSAGE$36 = "The `useEffect` callback is `async`, so it returns a Promise instead of a cleanup function. React calls that Promise as cleanup (a no-op) and the effect can race on unmount. Put the async work in an inner function and call it.";
33891
+ const MESSAGE$37 = "The `useEffect` callback is `async`, so it returns a Promise instead of a cleanup function. React calls that Promise as cleanup (a no-op) and the effect can race on unmount. Put the async work in an inner function and call it.";
33892
33892
  const noAsyncEffectCallback = defineRule({
33893
33893
  id: "no-async-effect-callback",
33894
33894
  title: "Async effect callback",
@@ -33906,13 +33906,13 @@ const noAsyncEffectCallback = defineRule({
33906
33906
  if (!callback.async) return;
33907
33907
  context.report({
33908
33908
  node: callback,
33909
- message: MESSAGE$36
33909
+ message: MESSAGE$37
33910
33910
  });
33911
33911
  } })
33912
33912
  });
33913
33913
  //#endregion
33914
33914
  //#region src/plugin/rules/a11y/no-autofocus.ts
33915
- const MESSAGE$35 = "`autoFocus` moves focus on load, which can disrupt screen reader and keyboard users. Remove it and let users choose where to focus.";
33915
+ const MESSAGE$36 = "`autoFocus` moves focus on load, which can disrupt screen reader and keyboard users. Remove it and let users choose where to focus.";
33916
33916
  const resolveSettings$21 = (settings) => {
33917
33917
  const reactDoctor = settings?.["react-doctor"];
33918
33918
  return { ignoreNonDOM: (typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.noAutofocus ?? {} : {}).ignoreNonDOM ?? true };
@@ -34009,7 +34009,7 @@ const noAutofocus = defineRule({
34009
34009
  if (isConditionallyRendered(node)) return;
34010
34010
  context.report({
34011
34011
  node: autoFocusAttribute,
34012
- message: MESSAGE$35
34012
+ message: MESSAGE$36
34013
34013
  });
34014
34014
  } };
34015
34015
  }
@@ -35338,7 +35338,7 @@ const noChainStateUpdates = defineRule({
35338
35338
  });
35339
35339
  //#endregion
35340
35340
  //#region src/plugin/rules/react-builtins/no-children-prop.ts
35341
- const MESSAGE$34 = "A `children` prop can override or hide nested children, so the component may render different content than the JSX shows.";
35341
+ const MESSAGE$35 = "A `children` prop can override or hide nested children, so the component may render different content than the JSX shows.";
35342
35342
  const noChildrenProp = defineRule({
35343
35343
  id: "no-children-prop",
35344
35344
  title: "Children passed as a prop",
@@ -35350,7 +35350,7 @@ const noChildrenProp = defineRule({
35350
35350
  if (node.name.name !== "children") return;
35351
35351
  context.report({
35352
35352
  node: node.name,
35353
- message: MESSAGE$34
35353
+ message: MESSAGE$35
35354
35354
  });
35355
35355
  },
35356
35356
  CallExpression(node) {
@@ -35363,7 +35363,7 @@ const noChildrenProp = defineRule({
35363
35363
  const propertyKey = property.key;
35364
35364
  if (isNodeOfType(propertyKey, "Identifier") && propertyKey.name === "children" || isNodeOfType(propertyKey, "Literal") && propertyKey.value === "children") context.report({
35365
35365
  node: propertyKey,
35366
- message: MESSAGE$34
35366
+ message: MESSAGE$35
35367
35367
  });
35368
35368
  }
35369
35369
  }
@@ -35371,7 +35371,7 @@ const noChildrenProp = defineRule({
35371
35371
  });
35372
35372
  //#endregion
35373
35373
  //#region src/plugin/rules/react-builtins/no-clone-element.ts
35374
- const MESSAGE$33 = "`React.cloneElement` couples the parent to the child's prop shape, so child prop changes can silently break injected behavior.";
35374
+ const MESSAGE$34 = "`React.cloneElement` couples the parent to the child's prop shape, so child prop changes can silently break injected behavior.";
35375
35375
  const noCloneElement = defineRule({
35376
35376
  id: "no-clone-element",
35377
35377
  title: "cloneElement makes child props fragile",
@@ -35384,7 +35384,7 @@ const noCloneElement = defineRule({
35384
35384
  if (isNodeOfType(callee, "Identifier") && callee.name === "cloneElement") {
35385
35385
  if (isImportedFromModule(node, "cloneElement", "react")) context.report({
35386
35386
  node: callee,
35387
- message: MESSAGE$33
35387
+ message: MESSAGE$34
35388
35388
  });
35389
35389
  return;
35390
35390
  }
@@ -35397,7 +35397,7 @@ const noCloneElement = defineRule({
35397
35397
  if (!isImportedFromModule(node, callee.object.name, "react")) return;
35398
35398
  context.report({
35399
35399
  node: callee,
35400
- message: MESSAGE$33
35400
+ message: MESSAGE$34
35401
35401
  });
35402
35402
  }
35403
35403
  } })
@@ -35417,7 +35417,7 @@ const getCallMethodName = (callee) => {
35417
35417
  };
35418
35418
  //#endregion
35419
35419
  //#region src/plugin/rules/state-and-effects/no-create-context-in-render.ts
35420
- const MESSAGE$32 = "createContext() builds a new context every render, so every consumer gets cut off & resets.";
35420
+ const MESSAGE$33 = "createContext() builds a new context every render, so every consumer gets cut off & resets.";
35421
35421
  const CONTEXT_MODULES = [
35422
35422
  "react",
35423
35423
  "use-context-selector",
@@ -35465,7 +35465,7 @@ const noCreateContextInRender = defineRule({
35465
35465
  if (!componentOrHookName) return;
35466
35466
  context.report({
35467
35467
  node,
35468
- message: `${MESSAGE$32} (called inside "${componentOrHookName}")`
35468
+ message: `${MESSAGE$33} (called inside "${componentOrHookName}")`
35469
35469
  });
35470
35470
  } })
35471
35471
  });
@@ -36212,7 +36212,7 @@ const isProvenOneShotTestingLibraryComponent = (functionNode, filename, scopes)
36212
36212
  };
36213
36213
  //#endregion
36214
36214
  //#region src/plugin/rules/react-builtins/no-create-ref-in-function-component.ts
36215
- const MESSAGE$31 = "`createRef()` may escape or be observed beyond the render that created it, so a later render can replace the ref object and detach the observed one. Hoist a `useRef()` call to the component's unconditional top level instead.";
36215
+ const MESSAGE$32 = "`createRef()` may escape or be observed beyond the render that created it, so a later render can replace the ref object and detach the observed one. Hoist a `useRef()` call to the component's unconditional top level instead.";
36216
36216
  const isUseMemoCallbackArgument = (functionNode, scopes) => {
36217
36217
  const parent = functionNode.parent;
36218
36218
  if (!parent || !isNodeOfType(parent, "CallExpression")) return false;
@@ -36266,7 +36266,7 @@ const noCreateRefInFunctionComponent = defineRule({
36266
36266
  if (isCreateRefResultWriteOnly(node, context.filename, context.scopes)) return;
36267
36267
  context.report({
36268
36268
  node,
36269
- message: MESSAGE$31
36269
+ message: MESSAGE$32
36270
36270
  });
36271
36271
  } })
36272
36272
  });
@@ -36406,7 +36406,7 @@ const noCreateStoreInRender = defineRule({
36406
36406
  });
36407
36407
  //#endregion
36408
36408
  //#region src/plugin/rules/react-builtins/no-danger.ts
36409
- const MESSAGE$30 = "`dangerouslySetInnerHTML` is an XSS hole that runs attacker-controlled HTML in your users' browsers.";
36409
+ const MESSAGE$31 = "`dangerouslySetInnerHTML` is an XSS hole that runs attacker-controlled HTML in your users' browsers.";
36410
36410
  const noDanger = defineRule({
36411
36411
  id: "no-danger",
36412
36412
  title: "Raw HTML injection can run unsafe markup",
@@ -36420,7 +36420,7 @@ const noDanger = defineRule({
36420
36420
  if (!propAttribute) return;
36421
36421
  context.report({
36422
36422
  node: propAttribute.name,
36423
- message: MESSAGE$30
36423
+ message: MESSAGE$31
36424
36424
  });
36425
36425
  },
36426
36426
  CallExpression(node) {
@@ -36432,7 +36432,7 @@ const noDanger = defineRule({
36432
36432
  const propertyKey = property.key;
36433
36433
  if (isNodeOfType(propertyKey, "Identifier") && propertyKey.name === "dangerouslySetInnerHTML" || isNodeOfType(propertyKey, "Literal") && propertyKey.value === "dangerouslySetInnerHTML") context.report({
36434
36434
  node: propertyKey,
36435
- message: MESSAGE$30
36435
+ message: MESSAGE$31
36436
36436
  });
36437
36437
  }
36438
36438
  }
@@ -36455,7 +36455,7 @@ const isMeaningfulJsxChild = (child) => {
36455
36455
  };
36456
36456
  //#endregion
36457
36457
  //#region src/plugin/rules/react-builtins/no-danger-with-children.ts
36458
- const MESSAGE$29 = "React throws an error when you set both children & `dangerouslySetInnerHTML`.";
36458
+ const MESSAGE$30 = "React throws an error when you set both children & `dangerouslySetInnerHTML`.";
36459
36459
  const mergePropsShape = (target, source) => {
36460
36460
  target.hasDangerously ||= source.hasDangerously;
36461
36461
  target.hasChildren ||= source.hasChildren;
@@ -36530,7 +36530,7 @@ const noDangerWithChildren = defineRule({
36530
36530
  if (!hasChildrenProp && !hasNestedChildren) return;
36531
36531
  if (hasJsxPropIgnoreCase(opening.attributes, "dangerouslySetInnerHTML") || spreadPropsShape.hasDangerously) context.report({
36532
36532
  node: opening,
36533
- message: MESSAGE$29
36533
+ message: MESSAGE$30
36534
36534
  });
36535
36535
  },
36536
36536
  CallExpression(node) {
@@ -36543,7 +36543,7 @@ const noDangerWithChildren = defineRule({
36543
36543
  const positionalChildren = node.arguments.slice(2);
36544
36544
  if (positionalChildren.length > 1 || positionalChildren.some((argument) => !isNullishExpression(argument)) || propsShape.hasChildren) context.report({
36545
36545
  node,
36546
- message: MESSAGE$29
36546
+ message: MESSAGE$30
36547
36547
  });
36548
36548
  }
36549
36549
  })
@@ -37518,7 +37518,7 @@ const isSetStateCallInLifecycle = (setStateCall, lifecycleNames, options = {}) =
37518
37518
  //#endregion
37519
37519
  //#region src/plugin/rules/react-builtins/no-did-mount-set-state.ts
37520
37520
  const LIFECYCLE_NAMES$2 = new Set(["componentDidMount"]);
37521
- const MESSAGE$28 = "Your users see an extra render right after mount when you call `setState` in `componentDidMount`.";
37521
+ const MESSAGE$29 = "Your users see an extra render right after mount when you call `setState` in `componentDidMount`.";
37522
37522
  const getEnclosingLifecycleFunction = (setStateCall) => {
37523
37523
  let ancestor = setStateCall.parent;
37524
37524
  while (ancestor) {
@@ -37645,7 +37645,7 @@ const noDidMountSetState = defineRule({
37645
37645
  }
37646
37646
  context.report({
37647
37647
  node: node.callee,
37648
- message: MESSAGE$28
37648
+ message: MESSAGE$29
37649
37649
  });
37650
37650
  } };
37651
37651
  }
@@ -37663,7 +37663,7 @@ const findEnclosingClass = (node) => {
37663
37663
  //#endregion
37664
37664
  //#region src/plugin/rules/react-builtins/no-did-update-set-state.ts
37665
37665
  const LIFECYCLE_NAMES$1 = new Set(["componentDidUpdate"]);
37666
- const MESSAGE$27 = "Calling setState in componentDidUpdate can trigger another update immediately, loop forever, and freeze the component.";
37666
+ const MESSAGE$28 = "Calling setState in componentDidUpdate can trigger another update immediately, loop forever, and freeze the component.";
37667
37667
  const DIFFERENCE_OPERATORS = new Set(["!=", "!=="]);
37668
37668
  const EQUALITY_OPERATORS = new Set([
37669
37669
  "==",
@@ -38057,7 +38057,7 @@ const noDidUpdateSetState = defineRule({
38057
38057
  if (isInsideDiffGuard(node, context.scopes)) return;
38058
38058
  context.report({
38059
38059
  node: node.callee,
38060
- message: MESSAGE$27
38060
+ message: MESSAGE$28
38061
38061
  });
38062
38062
  } };
38063
38063
  }
@@ -38080,7 +38080,7 @@ const isStateMemberExpression = (node) => {
38080
38080
  };
38081
38081
  //#endregion
38082
38082
  //#region src/plugin/rules/react-builtins/no-direct-mutation-state.ts
38083
- const MESSAGE$26 = "Mutating `this.state` by hand never triggers a redraw on its own & a later setState can overwrite it, so use `this.setState` instead.";
38083
+ const MESSAGE$27 = "Mutating `this.state` by hand never triggers a redraw on its own & a later setState can overwrite it, so use `this.setState` instead.";
38084
38084
  const shouldIgnoreMutation = (node) => {
38085
38085
  let isConstructor = false;
38086
38086
  let isInsideCallExpression = false;
@@ -38102,7 +38102,7 @@ const reportIfStateMutation = (context, reportNode, target) => {
38102
38102
  if (shouldIgnoreMutation(reportNode)) return;
38103
38103
  context.report({
38104
38104
  node: reportNode,
38105
- message: MESSAGE$26
38105
+ message: MESSAGE$27
38106
38106
  });
38107
38107
  };
38108
38108
  const noDirectMutationState = defineRule({
@@ -38453,7 +38453,7 @@ const noDocumentStartViewTransition = defineRule({
38453
38453
  });
38454
38454
  //#endregion
38455
38455
  //#region src/plugin/rules/js-performance/no-document-write.ts
38456
- const MESSAGE$25 = "`document.write()` blocks parsing, is ignored (or wipes the page) after load, and is flagged by browsers as a performance anti-pattern. Build DOM nodes or set `innerHTML`/`textContent` on a target element instead.";
38456
+ const MESSAGE$26 = "`document.write()` blocks parsing, is ignored (or wipes the page) after load, and is flagged by browsers as a performance anti-pattern. Build DOM nodes or set `innerHTML`/`textContent` on a target element instead.";
38457
38457
  const WRITE_METHODS = new Set(["write", "writeln"]);
38458
38458
  const isGlobalDocumentReference = (node, context) => node.name === "document" && context.scopes.isGlobalReference(node);
38459
38459
  const noDocumentWrite = defineRule({
@@ -38470,7 +38470,7 @@ const noDocumentWrite = defineRule({
38470
38470
  if (methodName === null || !WRITE_METHODS.has(methodName)) return;
38471
38471
  context.report({
38472
38472
  node,
38473
- message: MESSAGE$25
38473
+ message: MESSAGE$26
38474
38474
  });
38475
38475
  } })
38476
38476
  });
@@ -41810,7 +41810,7 @@ const ALLOWED_NAMESPACES = new Set([
41810
41810
  "ReactDOM",
41811
41811
  "ReactDom"
41812
41812
  ]);
41813
- const MESSAGE$24 = "`findDOMNode` crashes your app in React 19 because it was removed.";
41813
+ const MESSAGE$25 = "`findDOMNode` crashes your app in React 19 because it was removed.";
41814
41814
  const noFindDomNode = defineRule({
41815
41815
  id: "no-find-dom-node",
41816
41816
  title: "findDOMNode breaks component encapsulation",
@@ -41821,7 +41821,7 @@ const noFindDomNode = defineRule({
41821
41821
  if (isNodeOfType(callee, "Identifier") && callee.name === "findDOMNode") {
41822
41822
  if (isImportedFromModule(node, callee.name, "react-dom")) context.report({
41823
41823
  node: callee,
41824
- message: MESSAGE$24
41824
+ message: MESSAGE$25
41825
41825
  });
41826
41826
  return;
41827
41827
  }
@@ -41832,7 +41832,7 @@ const noFindDomNode = defineRule({
41832
41832
  if (callee.property.name !== "findDOMNode") return;
41833
41833
  context.report({
41834
41834
  node: callee.property,
41835
- message: MESSAGE$24
41835
+ message: MESSAGE$25
41836
41836
  });
41837
41837
  }
41838
41838
  } })
@@ -42970,7 +42970,7 @@ const noHydrationBranchOnBrowserGlobal = defineRule({
42970
42970
  });
42971
42971
  //#endregion
42972
42972
  //#region src/plugin/rules/performance/no-img-lazy-with-high-fetchpriority.ts
42973
- const MESSAGE$23 = "`<img loading=\"lazy\">` defers the request while `fetchPriority=\"high\"` asks the browser to rush it, so the two directives contradict each other. Drop one: keep `fetchPriority=\"high\"` (and eager loading) for an LCP image, or `loading=\"lazy\"` for a below-the-fold one.";
42973
+ const MESSAGE$24 = "`<img loading=\"lazy\">` defers the request while `fetchPriority=\"high\"` asks the browser to rush it, so the two directives contradict each other. Drop one: keep `fetchPriority=\"high\"` (and eager loading) for an LCP image, or `loading=\"lazy\"` for a below-the-fold one.";
42974
42974
  const noImgLazyWithHighFetchpriority = defineRule({
42975
42975
  id: "no-img-lazy-with-high-fetchpriority",
42976
42976
  title: "Lazy image with high fetchPriority",
@@ -42984,7 +42984,7 @@ const noImgLazyWithHighFetchpriority = defineRule({
42984
42984
  if (!fetchPriorityAttribute || getJsxPropStringValue(fetchPriorityAttribute)?.toLowerCase() !== "high") return;
42985
42985
  context.report({
42986
42986
  node: node.name,
42987
- message: MESSAGE$23
42987
+ message: MESSAGE$24
42988
42988
  });
42989
42989
  } })
42990
42990
  });
@@ -43173,7 +43173,7 @@ const noImpureStateUpdater = defineRule({
43173
43173
  });
43174
43174
  //#endregion
43175
43175
  //#region src/plugin/rules/correctness/no-indeterminate-attribute.ts
43176
- const MESSAGE$22 = "The `indeterminate` HTML attribute does not set a checkbox's visual state. Assign the `HTMLInputElement.indeterminate` DOM property instead.";
43176
+ const MESSAGE$23 = "The `indeterminate` HTML attribute does not set a checkbox's visual state. Assign the `HTMLInputElement.indeterminate` DOM property instead.";
43177
43177
  const REACT_USE_REF_OPTIONS = {
43178
43178
  allowGlobalReactNamespace: false,
43179
43179
  allowUnboundBareCalls: false
@@ -43274,7 +43274,7 @@ const noIndeterminateAttribute = defineRule({
43274
43274
  if (!inputTypeValues || !inputTypeValues.every((inputTypeValue) => inputTypeValue.toLowerCase() === "checkbox")) return;
43275
43275
  context.report({
43276
43276
  node: indeterminateAttribute,
43277
- message: MESSAGE$22
43277
+ message: MESSAGE$23
43278
43278
  });
43279
43279
  },
43280
43280
  CallExpression(node) {
@@ -43283,7 +43283,7 @@ const noIndeterminateAttribute = defineRule({
43283
43283
  if (!isProvenHtmlInputElement(receiver, context.scopes)) return;
43284
43284
  context.report({
43285
43285
  node,
43286
- message: MESSAGE$22
43286
+ message: MESSAGE$23
43287
43287
  });
43288
43288
  }
43289
43289
  };
@@ -43571,7 +43571,7 @@ const noIsMounted = defineRule({
43571
43571
  });
43572
43572
  //#endregion
43573
43573
  //#region src/plugin/rules/js-performance/no-json-parse-stringify-clone.ts
43574
- const MESSAGE$21 = "`JSON.parse(JSON.stringify(x))` deep-clones by re-serializing: it is slow on large objects and silently drops `undefined`, functions, `Date`/`Map`/`Set`, and cyclic references. Use `structuredClone(x)`.";
43574
+ const MESSAGE$22 = "`JSON.parse(JSON.stringify(x))` deep-clones by re-serializing: it is slow on large objects and silently drops `undefined`, functions, `Date`/`Map`/`Set`, and cyclic references. Use `structuredClone(x)`.";
43575
43575
  const isJsonMethodCall = (node, method) => {
43576
43576
  if (!isNodeOfType(node, "CallExpression")) return false;
43577
43577
  const callee = node.callee;
@@ -43635,13 +43635,13 @@ const noJsonParseStringifyClone = defineRule({
43635
43635
  if (isCatchParameterRoundTrip(firstArgument)) return;
43636
43636
  context.report({
43637
43637
  node,
43638
- message: MESSAGE$21
43638
+ message: MESSAGE$22
43639
43639
  });
43640
43640
  } })
43641
43641
  });
43642
43642
  //#endregion
43643
43643
  //#region src/plugin/rules/correctness/no-jsx-element-type.ts
43644
- const MESSAGE$20 = "`JSX.Element` is too narrow: it excludes `null`, strings, numbers, and fragments that components commonly return. Use `React.ReactNode` instead.";
43644
+ const MESSAGE$21 = "`JSX.Element` is too narrow: it excludes `null`, strings, numbers, and fragments that components commonly return. Use `React.ReactNode` instead.";
43645
43645
  const isJsxElementTypeReference = (node) => {
43646
43646
  if (!isNodeOfType(node, "TSTypeReference")) return false;
43647
43647
  const typeName = node.typeName;
@@ -43693,7 +43693,7 @@ const noJsxElementType = defineRule({
43693
43693
  if (isJsxImported) return;
43694
43694
  for (const typeAnnotation of flaggedAnnotations) context.report({
43695
43695
  node: typeAnnotation,
43696
- message: MESSAGE$20
43696
+ message: MESSAGE$21
43697
43697
  });
43698
43698
  }
43699
43699
  };
@@ -44974,7 +44974,7 @@ const noMoment = defineRule({
44974
44974
  });
44975
44975
  //#endregion
44976
44976
  //#region src/plugin/rules/react-builtins/no-multi-comp.ts
44977
- const MESSAGE$19 = "This file declares several components, so each component is harder to find, test, and change.";
44977
+ const MESSAGE$20 = "This file declares several components, so each component is harder to find, test, and change.";
44978
44978
  const resolveSettings$16 = (settings) => {
44979
44979
  const reactDoctor = settings?.["react-doctor"];
44980
44980
  return { ignoreStateless: (typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.noMultiComp ?? {} : {}).ignoreStateless ?? false };
@@ -45326,7 +45326,7 @@ const noMultiComp = defineRule({
45326
45326
  if (isSmallFeatureModule || isLargeFeatureModule || isVeryLargeFeatureModule) return;
45327
45327
  for (const component of flagged.slice(1)) context.report({
45328
45328
  node: component.reportNode,
45329
- message: MESSAGE$19
45329
+ message: MESSAGE$20
45330
45330
  });
45331
45331
  } };
45332
45332
  }
@@ -45539,7 +45539,7 @@ const resolveReducerFunction = (node, currentFilename) => {
45539
45539
  };
45540
45540
  //#endregion
45541
45541
  //#region src/plugin/rules/state-and-effects/no-mutating-reducer-state.ts
45542
- const MESSAGE$18 = "This reducer changes state in place, so your update is silently skipped.";
45542
+ const MESSAGE$19 = "This reducer changes state in place, so your update is silently skipped.";
45543
45543
  const SAME_REFERENCE_ARRAY_RETURN_METHODS = new Set([
45544
45544
  "copyWithin",
45545
45545
  "fill",
@@ -45743,7 +45743,7 @@ const analyzeReactUseReducerFunctionForStateMutation = (context, functionNode, r
45743
45743
  reportedNodes.add(options.crossFileConsumerCallSite);
45744
45744
  context.report({
45745
45745
  node: options.crossFileConsumerCallSite,
45746
- message: `${MESSAGE$18} (mutation in imported reducer at \`${options.crossFileSourceDisplay}\`)`
45746
+ message: `${MESSAGE$19} (mutation in imported reducer at \`${options.crossFileSourceDisplay}\`)`
45747
45747
  });
45748
45748
  return;
45749
45749
  }
@@ -45752,7 +45752,7 @@ const analyzeReactUseReducerFunctionForStateMutation = (context, functionNode, r
45752
45752
  reportedNodes.add(mutation.node);
45753
45753
  context.report({
45754
45754
  node: mutation.node,
45755
- message: MESSAGE$18
45755
+ message: MESSAGE$19
45756
45756
  });
45757
45757
  }
45758
45758
  };
@@ -46159,7 +46159,7 @@ const noNoninteractiveElementToInteractiveRole = defineRule({
46159
46159
  });
46160
46160
  //#endregion
46161
46161
  //#region src/plugin/rules/a11y/no-noninteractive-tabindex.ts
46162
- const MESSAGE$17 = "Keyboard users get stuck focusing this element they can't act on because `tabIndex` makes it tabbable, so remove it.";
46162
+ const MESSAGE$18 = "Keyboard users get stuck focusing this element they can't act on because `tabIndex` makes it tabbable, so remove it.";
46163
46163
  const KEYBOARD_HANDLER_PROP_NAMES = [
46164
46164
  "onKeyDown",
46165
46165
  "onKeyUp",
@@ -46278,7 +46278,7 @@ const noNoninteractiveTabindex = defineRule({
46278
46278
  if (numeric === null) {
46279
46279
  if (isNodeOfType(tabIndexValue, "JSXExpressionContainer") && !settings.allowExpressionValues && !isKeyboardOperable(node) && !isFocusOperable(node) && !hasJsxSpreadAttribute$1(node.attributes)) context.report({
46280
46280
  node: tabIndex,
46281
- message: MESSAGE$17
46281
+ message: MESSAGE$18
46282
46282
  });
46283
46283
  return;
46284
46284
  }
@@ -46300,7 +46300,7 @@ const noNoninteractiveTabindex = defineRule({
46300
46300
  if (!roleAttribute) {
46301
46301
  context.report({
46302
46302
  node: tabIndex,
46303
- message: MESSAGE$17
46303
+ message: MESSAGE$18
46304
46304
  });
46305
46305
  return;
46306
46306
  }
@@ -46314,7 +46314,7 @@ const noNoninteractiveTabindex = defineRule({
46314
46314
  }
46315
46315
  context.report({
46316
46316
  node: tabIndex,
46317
- message: MESSAGE$17
46317
+ message: MESSAGE$18
46318
46318
  });
46319
46319
  } };
46320
46320
  }
@@ -48520,7 +48520,7 @@ const noRandomKey = defineRule({
48520
48520
  });
48521
48521
  //#endregion
48522
48522
  //#region src/plugin/rules/react-builtins/no-react-children.ts
48523
- const MESSAGE$16 = "`React.Children` traversal depends on the runtime child shape, so wrapping or unwrapping a child can silently change what gets visited.";
48523
+ const MESSAGE$17 = "`React.Children` traversal depends on the runtime child shape, so wrapping or unwrapping a child can silently change what gets visited.";
48524
48524
  const isChildrenIdentifier = (node, contextNode) => {
48525
48525
  if (!isNodeOfType(node, "Identifier") || node.name !== "Children") return false;
48526
48526
  return isImportedFromModule(contextNode, "Children", "react");
@@ -48546,13 +48546,13 @@ const noReactChildren = defineRule({
48546
48546
  if (isChildrenIdentifier(memberObject, node)) {
48547
48547
  context.report({
48548
48548
  node: calleeOuter,
48549
- message: MESSAGE$16
48549
+ message: MESSAGE$17
48550
48550
  });
48551
48551
  return;
48552
48552
  }
48553
48553
  if (isReactNamespaceMember(memberObject, node)) context.report({
48554
48554
  node: calleeOuter,
48555
- message: MESSAGE$16
48555
+ message: MESSAGE$17
48556
48556
  });
48557
48557
  } })
48558
48558
  });
@@ -49434,7 +49434,7 @@ const noRenderPropChildren = defineRule({
49434
49434
  });
49435
49435
  //#endregion
49436
49436
  //#region src/plugin/rules/react-builtins/no-render-return-value.ts
49437
- const MESSAGE$15 = "Your app breaks in React 19 because `ReactDOM.render` returns nothing there.";
49437
+ const MESSAGE$16 = "Your app breaks in React 19 because `ReactDOM.render` returns nothing there.";
49438
49438
  const isReactDomRenderCall = (node) => isGlobalMethodCall(node, "ReactDOM", "render");
49439
49439
  const isUsedAsReturnValue = (parent) => {
49440
49440
  if (!parent) return false;
@@ -49452,7 +49452,7 @@ const noRenderReturnValue = defineRule({
49452
49452
  if (!isUsedAsReturnValue(node.parent)) return;
49453
49453
  context.report({
49454
49454
  node: node.callee,
49455
- message: MESSAGE$15
49455
+ message: MESSAGE$16
49456
49456
  });
49457
49457
  } })
49458
49458
  });
@@ -50879,7 +50879,7 @@ const noSelfUpdatingEffect = defineRule({
50879
50879
  });
50880
50880
  //#endregion
50881
50881
  //#region src/plugin/rules/react-builtins/no-set-state.ts
50882
- const MESSAGE$14 = "`this.setState` keeps local class state in a project that forbids it, so state ownership becomes harder to reason about.";
50882
+ const MESSAGE$15 = "`this.setState` keeps local class state in a project that forbids it, so state ownership becomes harder to reason about.";
50883
50883
  const noSetState = defineRule({
50884
50884
  id: "no-set-state",
50885
50885
  title: "Local class state forbidden",
@@ -50894,7 +50894,7 @@ const noSetState = defineRule({
50894
50894
  if (!getParentComponent(node)) return;
50895
50895
  context.report({
50896
50896
  node: node.callee,
50897
- message: MESSAGE$14
50897
+ message: MESSAGE$15
50898
50898
  });
50899
50899
  } })
50900
50900
  });
@@ -51264,7 +51264,7 @@ const isAbstractRole = (openingElement, settings) => {
51264
51264
  };
51265
51265
  //#endregion
51266
51266
  //#region src/plugin/rules/a11y/no-static-element-interactions.ts
51267
- const MESSAGE$13 = "Screen reader users can't tell this click handler is interactive because it has no `role`, so add a `role` or use a button or link.";
51267
+ const MESSAGE$14 = "Screen reader users can't tell this click handler is interactive because it has no `role`, so add a `role` or use a button or link.";
51268
51268
  const DEFAULT_HANDLERS = [
51269
51269
  "onClick",
51270
51270
  "onMouseDown",
@@ -51379,7 +51379,7 @@ const noStaticElementInteractions = defineRule({
51379
51379
  if (!roleAttribute || !roleAttribute.value) {
51380
51380
  context.report({
51381
51381
  node: node.name,
51382
- message: MESSAGE$13
51382
+ message: MESSAGE$14
51383
51383
  });
51384
51384
  return;
51385
51385
  }
@@ -51389,7 +51389,7 @@ const noStaticElementInteractions = defineRule({
51389
51389
  if (isRecognizedRoleString(attributeValue.value)) return;
51390
51390
  context.report({
51391
51391
  node: node.name,
51392
- message: MESSAGE$13
51392
+ message: MESSAGE$14
51393
51393
  });
51394
51394
  return;
51395
51395
  }
@@ -51397,7 +51397,7 @@ const noStaticElementInteractions = defineRule({
51397
51397
  if (!settings.allowExpressionValues) {
51398
51398
  context.report({
51399
51399
  node: node.name,
51400
- message: MESSAGE$13
51400
+ message: MESSAGE$14
51401
51401
  });
51402
51402
  return;
51403
51403
  }
@@ -51405,7 +51405,7 @@ const noStaticElementInteractions = defineRule({
51405
51405
  if (isStaticNullishExpression(expression)) {
51406
51406
  context.report({
51407
51407
  node: node.name,
51408
- message: MESSAGE$13
51408
+ message: MESSAGE$14
51409
51409
  });
51410
51410
  return;
51411
51411
  }
@@ -51415,7 +51415,7 @@ const noStaticElementInteractions = defineRule({
51415
51415
  if (branches.some((branch) => branch.role !== null && isRecognizedRoleString(branch.role))) return;
51416
51416
  context.report({
51417
51417
  node: node.name,
51418
- message: MESSAGE$13
51418
+ message: MESSAGE$14
51419
51419
  });
51420
51420
  return;
51421
51421
  }
@@ -51423,7 +51423,7 @@ const noStaticElementInteractions = defineRule({
51423
51423
  }
51424
51424
  context.report({
51425
51425
  node: node.name,
51426
- message: MESSAGE$13
51426
+ message: MESSAGE$14
51427
51427
  });
51428
51428
  } };
51429
51429
  }
@@ -51529,7 +51529,7 @@ const noStringRefs = defineRule({
51529
51529
  });
51530
51530
  //#endregion
51531
51531
  //#region src/plugin/rules/js-performance/no-sync-xhr.ts
51532
- const MESSAGE$12 = "A synchronous `XMLHttpRequest` (`.open(method, url, false)`) freezes the main thread until the request finishes, blocking all rendering and input. Use `fetch()` or an async XHR (`open(method, url, true)`).";
51532
+ const MESSAGE$13 = "A synchronous `XMLHttpRequest` (`.open(method, url, false)`) freezes the main thread until the request finishes, blocking all rendering and input. Use `fetch()` or an async XHR (`open(method, url, true)`).";
51533
51533
  const isFalseLiteral = (node) => isNodeOfType(node, "Literal") && node.value === false;
51534
51534
  const PUBLIC_ASSET_PATH_PATTERN = /(?:^|\/)public\//i;
51535
51535
  const noSyncXhr = defineRule({
@@ -51550,7 +51550,7 @@ const noSyncXhr = defineRule({
51550
51550
  if (!asyncArgument || !isFalseLiteral(stripParenExpression(asyncArgument))) return;
51551
51551
  context.report({
51552
51552
  node,
51553
- message: MESSAGE$12
51553
+ message: MESSAGE$13
51554
51554
  });
51555
51555
  };
51556
51556
  return {
@@ -51575,7 +51575,7 @@ const noSyncXhr = defineRule({
51575
51575
  });
51576
51576
  //#endregion
51577
51577
  //#region src/plugin/rules/react-builtins/no-this-in-sfc.ts
51578
- const MESSAGE$11 = "This value is `undefined` because function components have no `this`.";
51578
+ const MESSAGE$12 = "This value is `undefined` because function components have no `this`.";
51579
51579
  const isInsideClassMethod = (node, customClassFactoryNames) => {
51580
51580
  let ancestor = node.parent;
51581
51581
  while (ancestor) {
@@ -51663,7 +51663,7 @@ const noThisInSfc = defineRule({
51663
51663
  if (functionHasOwnThisMemberWrite(enclosingFunction)) return;
51664
51664
  context.report({
51665
51665
  node,
51666
- message: MESSAGE$11
51666
+ message: MESSAGE$12
51667
51667
  });
51668
51668
  } };
51669
51669
  }
@@ -54033,7 +54033,7 @@ const noWideLetterSpacing = defineRule({
54033
54033
  //#endregion
54034
54034
  //#region src/plugin/rules/react-builtins/no-will-update-set-state.ts
54035
54035
  const LIFECYCLE_NAMES = new Set(["componentWillUpdate", "UNSAFE_componentWillUpdate"]);
54036
- const MESSAGE$10 = "Calling setState in componentWillUpdate can trigger another update immediately, loop forever, and freeze the component.";
54036
+ const MESSAGE$11 = "Calling setState in componentWillUpdate can trigger another update immediately, loop forever, and freeze the component.";
54037
54037
  const resolveSettings$7 = (settings) => {
54038
54038
  const reactDoctor = settings?.["react-doctor"];
54039
54039
  return { mode: (typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.noWillUpdateSetState ?? {} : {}).mode ?? "allowed" };
@@ -54067,7 +54067,7 @@ const noWillUpdateSetState = defineRule({
54067
54067
  if (!isSetStateCallInLifecycle(node, activeLifecycleNames, { disallowInNestedFunctions: mode === "disallow-in-func" })) return;
54068
54068
  context.report({
54069
54069
  node: node.callee,
54070
- message: MESSAGE$10
54070
+ message: MESSAGE$11
54071
54071
  });
54072
54072
  } };
54073
54073
  }
@@ -55867,7 +55867,7 @@ const preactNoRenderArguments = defineRule({
55867
55867
  });
55868
55868
  //#endregion
55869
55869
  //#region src/plugin/rules/preact/preact-prefer-ondblclick.ts
55870
- const MESSAGE$9 = "Your users get no response from `onDoubleClick` in Preact core, where it never fires, so use `onDblClick` instead, which matches the DOM event name.";
55870
+ const MESSAGE$10 = "Your users get no response from `onDoubleClick` in Preact core, where it never fires, so use `onDblClick` instead, which matches the DOM event name.";
55871
55871
  const preactPreferOndblclick = defineRule({
55872
55872
  id: "preact-prefer-ondblclick",
55873
55873
  title: "onDoubleClick instead of onDblClick",
@@ -55882,7 +55882,7 @@ const preactPreferOndblclick = defineRule({
55882
55882
  if (!onDoubleClickAttribute) return;
55883
55883
  context.report({
55884
55884
  node: onDoubleClickAttribute,
55885
- message: MESSAGE$9
55885
+ message: MESSAGE$10
55886
55886
  });
55887
55887
  } })
55888
55888
  });
@@ -56122,7 +56122,7 @@ const preferExplicitVariants = defineRule({
56122
56122
  });
56123
56123
  //#endregion
56124
56124
  //#region src/plugin/rules/react-builtins/prefer-function-component.ts
56125
- const MESSAGE$8 = "This class component keeps behavior in lifecycle methods, so state and effects are harder to follow than in a hook-based function component.";
56125
+ const MESSAGE$9 = "This class component keeps behavior in lifecycle methods, so state and effects are harder to follow than in a hook-based function component.";
56126
56126
  const resolveSettings$4 = (settings) => {
56127
56127
  const reactDoctor = settings?.["react-doctor"];
56128
56128
  const ruleSettings = typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.preferFunctionComponent ?? {} : {};
@@ -56161,7 +56161,7 @@ const preferFunctionComponent = defineRule({
56161
56161
  const reportNode = node.id ?? node;
56162
56162
  context.report({
56163
56163
  node: reportNode,
56164
- message: MESSAGE$8
56164
+ message: MESSAGE$9
56165
56165
  });
56166
56166
  };
56167
56167
  return {
@@ -58362,7 +58362,7 @@ const reactCompilerNoManualMemoization = defineRule({
58362
58362
  });
58363
58363
  //#endregion
58364
58364
  //#region src/plugin/rules/react-builtins/react-in-jsx-scope.ts
58365
- const MESSAGE$7 = "This JSX crashes because `React` isn't in scope.";
58365
+ const MESSAGE$8 = "This JSX crashes because `React` isn't in scope.";
58366
58366
  const reactInJsxScope = defineRule({
58367
58367
  id: "react-in-jsx-scope",
58368
58368
  title: "React not in scope for JSX",
@@ -58374,21 +58374,21 @@ const reactInJsxScope = defineRule({
58374
58374
  if (findVariableInitializer(node, "React")) return;
58375
58375
  context.report({
58376
58376
  node: node.name,
58377
- message: MESSAGE$7
58377
+ message: MESSAGE$8
58378
58378
  });
58379
58379
  },
58380
58380
  JSXFragment(node) {
58381
58381
  if (findVariableInitializer(node, "React")) return;
58382
58382
  context.report({
58383
58383
  node: node.openingFragment,
58384
- message: MESSAGE$7
58384
+ message: MESSAGE$8
58385
58385
  });
58386
58386
  }
58387
58387
  })
58388
58388
  });
58389
58389
  //#endregion
58390
58390
  //#region src/plugin/rules/security/react-markdown-unsanitized-raw-html.ts
58391
- const MESSAGE$6 = "React Markdown parses dynamic raw HTML when `rehype-raw` is enabled. Add `rehype-sanitize` to `rehypePlugins` or sanitize the markdown before rendering it.";
58391
+ const MESSAGE$7 = "React Markdown parses dynamic raw HTML when `rehype-raw` is enabled. Add `rehype-sanitize` to `rehypePlugins` or sanitize the markdown before rendering it.";
58392
58392
  const REACT_MARKDOWN_MODULE = "react-markdown";
58393
58393
  const REHYPE_RAW_MODULE = "rehype-raw";
58394
58394
  const REHYPE_SANITIZE_MODULE = "rehype-sanitize";
@@ -58540,7 +58540,7 @@ const reactMarkdownUnsanitizedRawHtml = defineRule({
58540
58540
  if (pluginEntries.some((entry) => isPluginFromModule(entry, REHYPE_SANITIZE_MODULE, context.scopes, /* @__PURE__ */ new Set())) || !hasDynamicUnsanitizedChildren(node, context.scopes)) return;
58541
58541
  context.report({
58542
58542
  node,
58543
- message: MESSAGE$6
58543
+ message: MESSAGE$7
58544
58544
  });
58545
58545
  } }))
58546
58546
  });
@@ -58695,7 +58695,7 @@ const reduxUseselectorInlineDerivation = defineRule({
58695
58695
  });
58696
58696
  //#endregion
58697
58697
  //#region src/plugin/rules/state-and-effects/redux-useselector-returns-new-collection.ts
58698
- const MESSAGE$5 = "Your component re-renders on every dispatched action when useSelector returns a new object or array.";
58698
+ const MESSAGE$6 = "Your component re-renders on every dispatched action when useSelector returns a new object or array.";
58699
58699
  const isConciseBodyReturningCollection = (functionNode) => {
58700
58700
  if (!isNodeOfType(functionNode, "ArrowFunctionExpression") && !isNodeOfType(functionNode, "FunctionExpression")) return false;
58701
58701
  const rawBody = functionNode.body;
@@ -58730,7 +58730,7 @@ const reduxUseselectorReturnsNewCollection = defineRule({
58730
58730
  if (!isConciseBodyReturningCollection(selectorArgument)) return;
58731
58731
  context.report({
58732
58732
  node,
58733
- message: MESSAGE$5
58733
+ message: MESSAGE$6
58734
58734
  });
58735
58735
  }
58736
58736
  };
@@ -59857,7 +59857,7 @@ const functionBodyHasReturnWithValue = (functionNode) => {
59857
59857
  //#endregion
59858
59858
  //#region src/plugin/rules/react-builtins/require-render-return.ts
59859
59859
  const RENDER_METHOD_NAME = "render";
59860
- const MESSAGE$4 = "Your users see nothing because this `render` method returns nothing.";
59860
+ const MESSAGE$5 = "Your users see nothing because this `render` method returns nothing.";
59861
59861
  const isStaticRenderKey = (key) => {
59862
59862
  if (isNodeOfType(key, "Identifier")) return key.name === RENDER_METHOD_NAME;
59863
59863
  if (isNodeOfType(key, "Literal")) return key.value === RENDER_METHOD_NAME;
@@ -59917,7 +59917,7 @@ const requireRenderReturn = defineRule({
59917
59917
  if (functionBodyHasReturnWithValue(functionNode)) return;
59918
59918
  context.report({
59919
59919
  node: host.reportNode,
59920
- message: MESSAGE$4
59920
+ message: MESSAGE$5
59921
59921
  });
59922
59922
  };
59923
59923
  return {
@@ -68759,7 +68759,7 @@ const rulesOfHooks = defineRule({
68759
68759
  });
68760
68760
  //#endregion
68761
68761
  //#region src/plugin/rules/a11y/scope.ts
68762
- const MESSAGE$3 = "The `scope` attribute only works on `<th>` cells, so screen readers get no table-header help from it here.";
68762
+ const MESSAGE$4 = "The `scope` attribute only works on `<th>` cells, so screen readers get no table-header help from it here.";
68763
68763
  const scope = defineRule({
68764
68764
  id: "scope",
68765
68765
  title: "scope attribute on non-th element",
@@ -68774,7 +68774,7 @@ const scope = defineRule({
68774
68774
  if (!HTML_TAGS.has(tag)) return;
68775
68775
  if (tag !== "th") context.report({
68776
68776
  node: scopeAttribute,
68777
- message: MESSAGE$3
68777
+ message: MESSAGE$4
68778
68778
  });
68779
68779
  } })
68780
68780
  });
@@ -68791,7 +68791,7 @@ const secretInFallback = defineRule({
68791
68791
  });
68792
68792
  //#endregion
68793
68793
  //#region src/plugin/rules/react-builtins/self-closing-comp.ts
68794
- const MESSAGE$2 = "This tag has no children, so the closing tag adds noise without changing output.";
68794
+ const MESSAGE$3 = "This tag has no children, so the closing tag adds noise without changing output.";
68795
68795
  const resolveSettings$2 = (settings) => {
68796
68796
  const reactDoctor = settings?.["react-doctor"];
68797
68797
  const ruleSettings = typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.selfClosingComp ?? {} : {};
@@ -68830,7 +68830,7 @@ const selfClosingComp = defineRule({
68830
68830
  if (isHtmlTag && !settings.html) return;
68831
68831
  context.report({
68832
68832
  node: node.openingElement,
68833
- message: MESSAGE$2
68833
+ message: MESSAGE$3
68834
68834
  });
68835
68835
  } };
68836
68836
  }
@@ -70214,7 +70214,7 @@ const collectJsxRuntimeImports = (program) => {
70214
70214
  };
70215
70215
  //#endregion
70216
70216
  //#region src/plugin/rules/react-builtins/style-prop-object.ts
70217
- const MESSAGE$1 = "Your styles don't render because you passed the `style` prop a string instead of an object.";
70217
+ const MESSAGE$2 = "Your styles don't render because you passed the `style` prop a string instead of an object.";
70218
70218
  const resolveSettings = (settings) => {
70219
70219
  const reactDoctor = settings?.["react-doctor"];
70220
70220
  return { allow: (typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.stylePropObject ?? {} : {}).allow ?? [] };
@@ -70321,7 +70321,7 @@ const stylePropObject = defineRule({
70321
70321
  if (isNodeOfType(value, "Literal") && typeof value.value === "string") {
70322
70322
  context.report({
70323
70323
  node: attribute,
70324
- message: MESSAGE$1
70324
+ message: MESSAGE$2
70325
70325
  });
70326
70326
  return;
70327
70327
  }
@@ -70329,7 +70329,7 @@ const stylePropObject = defineRule({
70329
70329
  const innerExpression = value.expression;
70330
70330
  if (innerExpression && innerExpression.type !== "JSXEmptyExpression" && isInvalidStyleExpression(innerExpression)) context.report({
70331
70331
  node: attribute,
70332
- message: MESSAGE$1
70332
+ message: MESSAGE$2
70333
70333
  });
70334
70334
  }
70335
70335
  }
@@ -70352,7 +70352,7 @@ const stylePropObject = defineRule({
70352
70352
  if (!(isNodeOfType(key, "Identifier") && key.name === "style" || isNodeOfType(key, "Literal") && key.value === "style")) continue;
70353
70353
  if (isInvalidStyleExpression(property.value)) context.report({
70354
70354
  node: property,
70355
- message: MESSAGE$1
70355
+ message: MESSAGE$2
70356
70356
  });
70357
70357
  }
70358
70358
  }
@@ -70688,7 +70688,7 @@ const svgFilterClickjackingRisk = defineRule({
70688
70688
  });
70689
70689
  //#endregion
70690
70690
  //#region src/plugin/rules/a11y/tabindex-no-positive.ts
70691
- const MESSAGE = "Keyboard users get jumped out of the normal order by a positive `tabIndex`, so use `0` or `-1`.";
70691
+ const MESSAGE$1 = "Keyboard users get jumped out of the normal order by a positive `tabIndex`, so use `0` or `-1`.";
70692
70692
  const tabindexNoPositive = defineRule({
70693
70693
  id: "tabindex-no-positive",
70694
70694
  title: "Positive tabindex value",
@@ -70708,7 +70708,7 @@ const tabindexNoPositive = defineRule({
70708
70708
  } else if (tabIndex.value && isNodeOfType(tabIndex.value, "JSXExpressionContainer")) numericValue = parseJsxValue(tabIndex.value);
70709
70709
  if (numericValue !== null && numericValue > 0) context.report({
70710
70710
  node: tabIndex,
70711
- message: MESSAGE
70711
+ message: MESSAGE$1
70712
70712
  });
70713
70713
  } })
70714
70714
  });
@@ -71614,6 +71614,248 @@ const useLazyMotion = defineRule({
71614
71614
  } })
71615
71615
  });
71616
71616
  //#endregion
71617
+ //#region src/plugin/rules/valtio/valtio-no-proxy-read-in-render.ts
71618
+ const VALTIO_REACT_MODULE_SOURCES = new Set(["valtio", "valtio/react"]);
71619
+ const REACT_DEPENDENCY_ARRAY_HOOK_NAMES = new Set([
71620
+ "useCallback",
71621
+ "useEffect",
71622
+ "useInsertionEffect",
71623
+ "useLayoutEffect",
71624
+ "useMemo"
71625
+ ]);
71626
+ const MESSAGE = "Read this Valtio value from the useSnapshot result during render. Keep proxy reads for callbacks so render uses the tracked, consistent snapshot.";
71627
+ const isValtioImportSymbol = (symbol) => {
71628
+ if (symbol.kind !== "import") return false;
71629
+ const importDeclaration = symbol.declarationNode.parent;
71630
+ return Boolean(importDeclaration && isNodeOfType(importDeclaration, "ImportDeclaration") && typeof importDeclaration.source.value === "string" && VALTIO_REACT_MODULE_SOURCES.has(importDeclaration.source.value));
71631
+ };
71632
+ const isValtioUseSnapshotCall = (node, scopes) => {
71633
+ if (!isNodeOfType(node, "CallExpression")) return false;
71634
+ const callee = stripParenExpression(node.callee);
71635
+ if (isNodeOfType(callee, "Identifier")) {
71636
+ const symbol = resolveConstIdentifierAlias(callee, scopes);
71637
+ return Boolean(symbol && isValtioImportSymbol(symbol) && getImportedName(symbol.declarationNode) === "useSnapshot");
71638
+ }
71639
+ if (!isNodeOfType(callee, "MemberExpression") || getStaticPropertyName(callee) !== "useSnapshot") return false;
71640
+ const receiver = stripParenExpression(callee.object);
71641
+ if (!isNodeOfType(receiver, "Identifier")) return false;
71642
+ const namespaceSymbol = resolveConstIdentifierAlias(receiver, scopes);
71643
+ return Boolean(namespaceSymbol && isValtioImportSymbol(namespaceSymbol) && isNodeOfType(namespaceSymbol.declarationNode, "ImportNamespaceSpecifier"));
71644
+ };
71645
+ const collectPatternBindingIdentifiers = (pattern) => {
71646
+ if (isNodeOfType(pattern, "Identifier")) return [pattern];
71647
+ if (isNodeOfType(pattern, "AssignmentPattern")) return collectPatternBindingIdentifiers(pattern.left);
71648
+ if (isNodeOfType(pattern, "RestElement")) return collectPatternBindingIdentifiers(pattern.argument);
71649
+ if (isNodeOfType(pattern, "ArrayPattern")) return pattern.elements.flatMap((element) => element ? collectPatternBindingIdentifiers(element) : []);
71650
+ if (isNodeOfType(pattern, "ObjectPattern")) return pattern.properties.flatMap((property) => {
71651
+ if (isNodeOfType(property, "Property")) return collectPatternBindingIdentifiers(property.value);
71652
+ return isNodeOfType(property, "RestElement") ? collectPatternBindingIdentifiers(property.argument) : [];
71653
+ });
71654
+ return [];
71655
+ };
71656
+ const collectAssignmentWriteTargets = (target) => {
71657
+ const candidate = stripParenExpression(target);
71658
+ if (isNodeOfType(candidate, "AssignmentPattern")) return collectAssignmentWriteTargets(candidate.left);
71659
+ if (isNodeOfType(candidate, "RestElement")) return collectAssignmentWriteTargets(candidate.argument);
71660
+ if (isNodeOfType(candidate, "ArrayPattern")) return candidate.elements.flatMap((element) => element ? collectAssignmentWriteTargets(element) : []);
71661
+ if (isNodeOfType(candidate, "ObjectPattern")) return candidate.properties.flatMap((property) => isNodeOfType(property, "Property") ? collectAssignmentWriteTargets(property.value) : collectAssignmentWriteTargets(property.argument));
71662
+ return [candidate];
71663
+ };
71664
+ const findPatternPathToBinding = (pattern, bindingIdentifier) => {
71665
+ if (pattern === bindingIdentifier) return [];
71666
+ if (isNodeOfType(pattern, "AssignmentPattern")) return findPatternPathToBinding(pattern.left, bindingIdentifier);
71667
+ if (isNodeOfType(pattern, "RestElement")) return null;
71668
+ if (isNodeOfType(pattern, "ArrayPattern")) {
71669
+ for (const [elementIndex, element] of pattern.elements.entries()) {
71670
+ if (!element) continue;
71671
+ const nestedPath = findPatternPathToBinding(element, bindingIdentifier);
71672
+ if (nestedPath) return [String(elementIndex), ...nestedPath];
71673
+ }
71674
+ return null;
71675
+ }
71676
+ if (!isNodeOfType(pattern, "ObjectPattern")) return null;
71677
+ for (const property of pattern.properties) {
71678
+ if (!isNodeOfType(property, "Property")) continue;
71679
+ const nestedPath = findPatternPathToBinding(property.value, bindingIdentifier);
71680
+ if (!nestedPath) continue;
71681
+ const propertyName = getStaticPropertyKeyName(property);
71682
+ return propertyName === null ? null : [propertyName, ...nestedPath];
71683
+ }
71684
+ return null;
71685
+ };
71686
+ const resolveProxyPath = (expression, scopes, visitedSymbolIds = /* @__PURE__ */ new Set(), allowedAliasSymbolIds = null, collectedAliasCaptures = null) => {
71687
+ const candidate = stripParenExpression(expression);
71688
+ if (isNodeOfType(candidate, "MemberExpression")) {
71689
+ const receiverPath = resolveProxyPath(candidate.object, scopes, visitedSymbolIds, allowedAliasSymbolIds, collectedAliasCaptures);
71690
+ if (!receiverPath) return null;
71691
+ return {
71692
+ ...receiverPath,
71693
+ properties: [...receiverPath.properties, getStaticPropertyName(candidate)]
71694
+ };
71695
+ }
71696
+ if (!isNodeOfType(candidate, "Identifier")) return null;
71697
+ const symbol = scopes.symbolFor(candidate);
71698
+ if (!symbol) return scopes.isGlobalReference(candidate) ? {
71699
+ rootKey: `global:${candidate.name}`,
71700
+ properties: []
71701
+ } : null;
71702
+ if (visitedSymbolIds.has(symbol.id)) return null;
71703
+ if (symbol.kind === "const" && symbol.initializer && isNodeOfType(symbol.declarationNode, "VariableDeclarator")) {
71704
+ const directAlias = symbol.declarationNode.id === symbol.bindingIdentifier;
71705
+ const initializerNode = directAlias ? symbol.initializer : symbol.declarationNode.init;
71706
+ if (!initializerNode) return {
71707
+ rootKey: `symbol:${symbol.id}`,
71708
+ properties: []
71709
+ };
71710
+ const initializer = stripParenExpression(initializerNode);
71711
+ const canResolveDirectAlias = directAlias && (isNodeOfType(initializer, "Identifier") || isNodeOfType(initializer, "MemberExpression"));
71712
+ const patternPath = directAlias ? null : findPatternPathToBinding(symbol.declarationNode.id, symbol.bindingIdentifier);
71713
+ if ((canResolveDirectAlias || patternPath) && (allowedAliasSymbolIds === null || allowedAliasSymbolIds.has(symbol.id))) {
71714
+ const nextVisitedSymbolIds = new Set(visitedSymbolIds);
71715
+ nextVisitedSymbolIds.add(symbol.id);
71716
+ const initializerPath = resolveProxyPath(initializer, scopes, nextVisitedSymbolIds, allowedAliasSymbolIds, collectedAliasCaptures);
71717
+ if (initializerPath) {
71718
+ const aliasPath = {
71719
+ ...initializerPath,
71720
+ properties: [...initializerPath.properties, ...patternPath ?? []]
71721
+ };
71722
+ const declarationEnd = symbol.declarationNode.range?.[1];
71723
+ if (typeof declarationEnd === "number") collectedAliasCaptures?.set(symbol.id, {
71724
+ declarationEnd,
71725
+ path: aliasPath
71726
+ });
71727
+ return aliasPath;
71728
+ }
71729
+ }
71730
+ }
71731
+ return {
71732
+ rootKey: `symbol:${symbol.id}`,
71733
+ properties: []
71734
+ };
71735
+ };
71736
+ const isScopeWithin = (candidateScope, ancestorScope) => {
71737
+ let currentScope = candidateScope;
71738
+ while (currentScope) {
71739
+ if (currentScope === ancestorScope) return true;
71740
+ currentScope = currentScope.parent;
71741
+ }
71742
+ return false;
71743
+ };
71744
+ const isPathPrefix = (prefix, candidate) => {
71745
+ if (prefix.rootKey !== candidate.rootKey || prefix.properties.length > candidate.properties.length) return false;
71746
+ return prefix.properties.every((propertyName, propertyIndex) => propertyName !== null && propertyName === candidate.properties[propertyIndex]);
71747
+ };
71748
+ const findOutermostMemberRead = (identifier) => {
71749
+ let currentExpression = findTransparentExpressionRoot(identifier);
71750
+ for (;;) {
71751
+ const parent = currentExpression.parent;
71752
+ if (!isNodeOfType(parent, "MemberExpression") || stripParenExpression(parent.object) !== stripParenExpression(currentExpression)) return currentExpression;
71753
+ currentExpression = findTransparentExpressionRoot(parent);
71754
+ }
71755
+ };
71756
+ const isReadPositionWithinAssignmentTarget = (expression) => {
71757
+ let currentNode = expression;
71758
+ let parentNode = currentNode.parent;
71759
+ while (parentNode) {
71760
+ if (isNodeOfType(parentNode, "MemberExpression") && parentNode.computed && parentNode.property === currentNode || isNodeOfType(parentNode, "Property") && parentNode.computed && parentNode.key === currentNode || isNodeOfType(parentNode, "AssignmentPattern") && parentNode.right === currentNode) return true;
71761
+ if (isNodeOfType(parentNode, "AssignmentExpression") || isNodeOfType(parentNode, "UpdateExpression") || isNodeOfType(parentNode, "UnaryExpression") && parentNode.operator === "delete" || isNodeOfType(parentNode, "ForInStatement") || isNodeOfType(parentNode, "ForOfStatement")) return false;
71762
+ currentNode = parentNode;
71763
+ parentNode = currentNode.parent;
71764
+ }
71765
+ return false;
71766
+ };
71767
+ const isSnapshotArgument = (expression, scopes) => {
71768
+ const expressionRoot = findTransparentExpressionRoot(expression);
71769
+ const parent = expressionRoot.parent;
71770
+ return Boolean(parent && isNodeOfType(parent, "CallExpression") && isValtioUseSnapshotCall(parent, scopes) && parent.arguments[0] === expressionRoot);
71771
+ };
71772
+ const isStableProxyDependency = (expression, readPath, matchingTarget, scopes) => {
71773
+ if (readPath.properties.length !== matchingTarget.path.properties.length || !isPathPrefix(matchingTarget.path, readPath)) return false;
71774
+ const dependencyArray = findTransparentExpressionRoot(expression).parent;
71775
+ if (!isNodeOfType(dependencyArray, "ArrayExpression")) return false;
71776
+ const hookCall = dependencyArray.parent;
71777
+ return Boolean(isNodeOfType(hookCall, "CallExpression") && hookCall.arguments[1] === dependencyArray && isReactApiCall(hookCall, REACT_DEPENDENCY_ARRAY_HOOK_NAMES, scopes, { allowGlobalReactNamespace: true }));
71778
+ };
71779
+ const getSnapshotTarget = (callExpression, context) => {
71780
+ if (!isValtioUseSnapshotCall(callExpression, context.scopes)) return null;
71781
+ const proxyArgument = callExpression.arguments[0];
71782
+ if (!proxyArgument || isNodeOfType(proxyArgument, "SpreadElement")) return null;
71783
+ const path = resolveProxyPath(proxyArgument, context.scopes);
71784
+ if (!path || path.properties.some((propertyName) => propertyName === null)) return null;
71785
+ const callExpressionRoot = findTransparentExpressionRoot(callExpression);
71786
+ const declarator = callExpressionRoot.parent;
71787
+ if (!isNodeOfType(declarator, "VariableDeclarator") || declarator.init !== callExpressionRoot || !isNodeOfType(declarator.parent, "VariableDeclaration")) return null;
71788
+ const ownerFunction = findRenderPhaseComponentOrHook(callExpression, context.scopes);
71789
+ if (!ownerFunction) return null;
71790
+ const snapshotBindingScopes = collectPatternBindingIdentifiers(declarator.id).flatMap((bindingIdentifier) => {
71791
+ const bindingSymbol = context.scopes.symbolFor(bindingIdentifier);
71792
+ return bindingSymbol ? [bindingSymbol.scope] : [];
71793
+ });
71794
+ const declarationEnd = declarator.range?.[1];
71795
+ if (snapshotBindingScopes.length === 0 || typeof declarationEnd !== "number") return null;
71796
+ return {
71797
+ declarationEnd,
71798
+ ownerFunction,
71799
+ path,
71800
+ snapshotBindingScopes
71801
+ };
71802
+ };
71803
+ const wasTargetReplacedBeforeRead = (target, readPosition, writeTargets, readAliasCaptures, context) => writeTargets.some((writeTarget) => {
71804
+ const writeNode = findTransparentExpressionRoot(writeTarget).parent;
71805
+ const writePosition = writeNode?.range?.[0];
71806
+ if (!writeNode || typeof writePosition !== "number" || writePosition <= target.declarationEnd || writePosition >= readPosition || findRenderPhaseComponentOrHook(writeNode, context.scopes) !== target.ownerFunction) return false;
71807
+ const writePath = resolveProxyPath(writeTarget, context.scopes, /* @__PURE__ */ new Set(), null);
71808
+ if (!writePath || !isPathPrefix(writePath, target.path)) return false;
71809
+ return ![...readAliasCaptures.values()].some((aliasCapture) => aliasCapture.declarationEnd < writePosition && isPathPrefix(writePath, aliasCapture.path));
71810
+ });
71811
+ const valtioNoProxyReadInRender = defineRule({
71812
+ id: "valtio-no-proxy-read-in-render",
71813
+ title: "Valtio proxy read during render",
71814
+ severity: "warn",
71815
+ recommendation: "Read reactive render values from useSnapshot. Reserve the mutable proxy for event handlers, effects, and other callbacks that need the latest value.",
71816
+ requires: ["valtio:1"],
71817
+ create: (context) => {
71818
+ const snapshotTargets = [];
71819
+ const identifierCandidates = [];
71820
+ const writeTargets = [];
71821
+ return {
71822
+ CallExpression(node) {
71823
+ const snapshotTarget = getSnapshotTarget(node, context);
71824
+ if (snapshotTarget) snapshotTargets.push(snapshotTarget);
71825
+ },
71826
+ Identifier(node) {
71827
+ if (context.scopes.referenceFor(node)) identifierCandidates.push(node);
71828
+ },
71829
+ AssignmentExpression(node) {
71830
+ writeTargets.push(...collectAssignmentWriteTargets(node.left));
71831
+ },
71832
+ UpdateExpression(node) {
71833
+ writeTargets.push(node.argument);
71834
+ },
71835
+ "Program:exit"() {
71836
+ const reportedExpressions = /* @__PURE__ */ new Set();
71837
+ for (const identifier of identifierCandidates) {
71838
+ const readExpression = findOutermostMemberRead(identifier);
71839
+ if (reportedExpressions.has(readExpression) || isWithinAssignmentTarget(readExpression) && !isReadPositionWithinAssignmentTarget(readExpression) || isSnapshotArgument(readExpression, context.scopes)) continue;
71840
+ const readAliasCaptures = /* @__PURE__ */ new Map();
71841
+ const readPath = resolveProxyPath(readExpression, context.scopes, /* @__PURE__ */ new Set(), null, readAliasCaptures);
71842
+ const readPosition = readExpression.range?.[0];
71843
+ const ownerFunction = findRenderPhaseComponentOrHook(readExpression, context.scopes);
71844
+ if (!readPath || typeof readPosition !== "number" || !ownerFunction) continue;
71845
+ const readScope = context.scopes.scopeFor(readExpression);
71846
+ const matchingTarget = snapshotTargets.find((target) => target.ownerFunction === ownerFunction && target.declarationEnd < readPosition && target.snapshotBindingScopes.some((bindingScope) => isScopeWithin(readScope, bindingScope)) && isPathPrefix(target.path, readPath) && (readAliasCaptures.size === 0 || [...readAliasCaptures.values()].some((aliasCapture) => isPathPrefix(aliasCapture.path, target.path) || isPathPrefix(target.path, aliasCapture.path) && readPath.properties.length > aliasCapture.path.properties.length)) && !wasTargetReplacedBeforeRead(target, readPosition, writeTargets, readAliasCaptures, context));
71847
+ if (!matchingTarget || isStableProxyDependency(readExpression, readPath, matchingTarget, context.scopes)) continue;
71848
+ reportedExpressions.add(readExpression);
71849
+ context.report({
71850
+ node: readExpression,
71851
+ message: MESSAGE
71852
+ });
71853
+ }
71854
+ }
71855
+ };
71856
+ }
71857
+ });
71858
+ //#endregion
71617
71859
  //#region src/plugin/rules/react-builtins/void-dom-elements-no-children.ts
71618
71860
  const VOID_DOM_ELEMENTS = new Set([
71619
71861
  "area",
@@ -76766,6 +77008,18 @@ const reactDoctorRules = [
76766
77008
  category: "Performance"
76767
77009
  }
76768
77010
  },
77011
+ {
77012
+ key: "react-doctor/valtio-no-proxy-read-in-render",
77013
+ id: "valtio-no-proxy-read-in-render",
77014
+ source: "react-doctor",
77015
+ originallyExternal: false,
77016
+ rule: {
77017
+ ...valtioNoProxyReadInRender,
77018
+ framework: "global",
77019
+ category: "Bugs",
77020
+ requires: [...new Set(["react", ...valtioNoProxyReadInRender.requires ?? []])]
77021
+ }
77022
+ },
76769
77023
  {
76770
77024
  key: "react-doctor/void-dom-elements-no-children",
76771
77025
  id: "void-dom-elements-no-children",