oxlint-plugin-react-doctor 0.7.0 → 0.7.1-dev.1880b15

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
@@ -549,6 +549,12 @@ const INDEX_PARAMETER_NAMES = new Set([
549
549
  "idx",
550
550
  "i"
551
551
  ]);
552
+ const REACT_RUNTIME_MODULE_SOURCES = new Set([
553
+ "react",
554
+ "react-dom",
555
+ "preact/compat",
556
+ "preact/hooks"
557
+ ]);
552
558
  const LOADING_STATE_PATTERN = /^(?:isLoading|isPending)$/;
553
559
  const STABLE_HOOK_WRAPPERS = new Set([
554
560
  "useState",
@@ -9219,6 +9225,7 @@ const iframeMissingSandbox = defineRule({
9219
9225
  severity: "warn",
9220
9226
  recommendation: "Add `sandbox=\"\"` or a curated value so embedded pages cannot get full access to your site by default.",
9221
9227
  category: "Security",
9228
+ matchByOccurrence: true,
9222
9229
  create: skipNonProductionFiles((context) => ({
9223
9230
  JSXOpeningElement(node) {
9224
9231
  if (!isNodeOfType(node.name, "JSXIdentifier") || node.name.name !== "iframe") return;
@@ -21605,6 +21612,13 @@ const noEffectEventHandler = defineRule({
21605
21612
  }
21606
21613
  });
21607
21614
  //#endregion
21615
+ //#region src/plugin/utils/is-imported-from-non-react-module.ts
21616
+ const isImportedFromNonReactModule = (contextNode, localIdentifierName) => {
21617
+ const importSource = getImportSourceForName(contextNode, localIdentifierName);
21618
+ if (importSource === null) return false;
21619
+ return !REACT_RUNTIME_MODULE_SOURCES.has(importSource);
21620
+ };
21621
+ //#endregion
21608
21622
  //#region src/plugin/rules/state-and-effects/no-effect-event-in-deps.ts
21609
21623
  const createComponentBindingStackTracker = (callbacks) => {
21610
21624
  const componentBindingStack = [];
@@ -21658,6 +21672,7 @@ const noEffectEventInDeps = defineRule({
21658
21672
  const initializer = declaratorNode.init;
21659
21673
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return;
21660
21674
  if (!isHookCall$1(initializer, "useEffectEvent")) return;
21675
+ if (isNodeOfType(initializer.callee, "Identifier") && isImportedFromNonReactModule(declaratorNode, initializer.callee.name)) return;
21661
21676
  componentBindings.addBindingToCurrentFrame(declaratorNode.id.name);
21662
21677
  } });
21663
21678
  return {
@@ -39394,6 +39409,12 @@ const isUseEffectEventSymbol = (symbol) => {
39394
39409
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return false;
39395
39410
  return getHookNameFromCallee(initializer.callee) === "useEffectEvent";
39396
39411
  };
39412
+ const isNonReactEffectEventCallee = (callee, contextNode) => isNodeOfType(callee, "Identifier") && isImportedFromNonReactModule(contextNode, callee.name);
39413
+ const isNonReactEffectEventSymbol = (symbol, contextNode) => {
39414
+ const initializer = symbol.initializer;
39415
+ if (!initializer || !isNodeOfType(initializer, "CallExpression")) return false;
39416
+ return isNonReactEffectEventCallee(initializer.callee, contextNode);
39417
+ };
39397
39418
  const findEnclosingComponentOrHookFunction = (node) => {
39398
39419
  let current = node.parent;
39399
39420
  while (current) {
@@ -39447,7 +39468,7 @@ const rulesOfHooks = defineRule({
39447
39468
  const hookContext = isHookCall(node, context.scopes, settings);
39448
39469
  if (!hookContext) return;
39449
39470
  const { hookName } = hookContext;
39450
- if (hookName === "useEffectEvent" && !isUseEffectEventInitializer(node)) {
39471
+ if (hookName === "useEffectEvent" && !isUseEffectEventInitializer(node) && !isNonReactEffectEventCallee(node.callee, node)) {
39451
39472
  context.report({
39452
39473
  node: node.callee,
39453
39474
  message: buildEffectEventPassedDownMessage()
@@ -39557,6 +39578,7 @@ const rulesOfHooks = defineRule({
39557
39578
  Identifier(node) {
39558
39579
  const symbol = context.scopes.referenceFor(node)?.resolvedSymbol;
39559
39580
  if (!symbol || !isUseEffectEventSymbol(symbol)) return;
39581
+ if (isNonReactEffectEventSymbol(symbol, node)) return;
39560
39582
  if (!isSameComponentOrHookScope(symbol, node)) return;
39561
39583
  if (isInsideAllowedEffectEventCallback(node, additionalEffectHooksRegex)) return;
39562
39584
  context.report({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.7.0",
3
+ "version": "0.7.1-dev.1880b15",
4
4
  "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",