react-doctor 0.9.1-dev.6904ff1 → 0.9.1-dev.80e89c5

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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f34e66dd-4b16-53f5-a3af-9844fbc71772")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3092d21f-ad14-532c-9877-ac1e91c6e9e0")}catch(e){}}();
3
3
  import { createRequire } from "node:module";
4
4
  import * as NodeChildProcess from "node:child_process";
5
5
  import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
@@ -65240,6 +65240,11 @@ const findMonorepoRoot = (startDirectory) => {
65240
65240
  * byte-equivalent copy.
65241
65241
  */
65242
65242
  const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
65243
+ const unwrapTypescriptExpression = (expression) => {
65244
+ let currentExpression = expression;
65245
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
65246
+ return currentExpression;
65247
+ };
65243
65248
  const TSCONFIG_FILENAME = "tsconfig.json";
65244
65249
  const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
65245
65250
  const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
@@ -65711,9 +65716,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
65711
65716
  initializer: assignedInitializer
65712
65717
  };
65713
65718
  };
65714
- const getStaticConfigValueState = (expression, analysis) => {
65715
- let unwrappedExpression = expression;
65716
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
65719
+ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
65720
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
65721
+ if (visitedExpressions.has(unwrappedExpression)) return null;
65722
+ const nextVisitedExpressions = new Set(visitedExpressions);
65723
+ nextVisitedExpressions.add(unwrappedExpression);
65717
65724
  if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
65718
65725
  isNullish: true,
65719
65726
  isTruthy: false
@@ -65729,31 +65736,31 @@ const getStaticConfigValueState = (expression, analysis) => {
65729
65736
  if (ts.isIdentifier(unwrappedExpression)) {
65730
65737
  if (analysis.localBindings.has(unwrappedExpression.text)) {
65731
65738
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
65732
- return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
65739
+ return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
65733
65740
  }
65734
65741
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
65735
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
65742
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
65736
65743
  }
65737
65744
  if (ts.isConditionalExpression(unwrappedExpression)) {
65738
- const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
65739
- if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
65740
- const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
65741
- const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
65745
+ const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
65746
+ if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
65747
+ const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
65748
+ const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
65742
65749
  return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
65743
65750
  }
65744
65751
  if (ts.isBinaryExpression(unwrappedExpression)) {
65745
- const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
65752
+ const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
65746
65753
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
65747
65754
  if (leftState === null) return null;
65748
- return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
65755
+ return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
65749
65756
  }
65750
65757
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
65751
65758
  if (leftState === null) return null;
65752
- return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
65759
+ return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
65753
65760
  }
65754
65761
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
65755
65762
  if (leftState === null) return null;
65756
- return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
65763
+ return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
65757
65764
  }
65758
65765
  }
65759
65766
  return null;
@@ -65762,25 +65769,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
65762
65769
  const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
65763
65770
  const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
65764
65771
  const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
65765
- const getReactCompilerFlagState = (expression, analysis) => {
65766
- let unwrappedExpression = expression;
65767
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
65772
+ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
65773
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
65774
+ if (visitedExpressions.has(unwrappedExpression)) return null;
65775
+ const nextVisitedExpressions = new Set(visitedExpressions);
65776
+ nextVisitedExpressions.add(unwrappedExpression);
65768
65777
  if (ts.isIdentifier(unwrappedExpression)) {
65769
65778
  const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
65770
65779
  if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
65771
65780
  if (analysis.localBindings.has(unwrappedExpression.text)) {
65772
65781
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
65773
- return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
65782
+ return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
65774
65783
  }
65775
65784
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
65776
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
65785
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
65777
65786
  }
65778
65787
  if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
65779
65788
  for (const property of [...unwrappedExpression.properties].reverse()) {
65780
65789
  if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
65781
65790
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
65782
65791
  if (ts.isSpreadAssignment(property)) {
65783
- const spreadState = getReactCompilerFlagState(property.expression, analysis);
65792
+ const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
65784
65793
  if (spreadState) return spreadState;
65785
65794
  }
65786
65795
  }
@@ -70505,11 +70514,6 @@ const getTypescriptScriptKind = (fileName) => {
70505
70514
  if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
70506
70515
  return ts.ScriptKind.JS;
70507
70516
  };
70508
- const unwrapTypescriptExpression = (expression) => {
70509
- let currentExpression = expression;
70510
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
70511
- return currentExpression;
70512
- };
70513
70517
  const BABEL_CONFIG_FILE_NAMES$1 = [
70514
70518
  "babel.config.js",
70515
70519
  "babel.config.cjs",
@@ -78414,7 +78418,7 @@ const makeNoopConsole = () => ({
78414
78418
  });
78415
78419
  //#endregion
78416
78420
  //#region src/cli/utils/version.ts
78417
- const VERSION = "0.9.1-dev.6904ff1";
78421
+ const VERSION = "0.9.1-dev.80e89c5";
78418
78422
  //#endregion
78419
78423
  //#region src/cli/utils/json-mode.ts
78420
78424
  let context = null;
@@ -78772,13 +78776,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
78772
78776
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
78773
78777
  * standard `SENTRY_RELEASE` override.
78774
78778
  */
78775
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.6904ff1`;
78779
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.80e89c5`;
78776
78780
  /**
78777
78781
  * Deployment environment shown in Sentry's environment filter. Defaults to
78778
78782
  * `production` for tagged releases and `development` for dev/unbuilt versions,
78779
78783
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
78780
78784
  */
78781
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.6904ff1") ? "development" : "production");
78785
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.80e89c5") ? "development" : "production");
78782
78786
  /**
78783
78787
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
78784
78788
  * (set to `0` to disable tracing) and falls back to
@@ -97577,4 +97581,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
97577
97581
  export { toForwardSlashes as A, highlighter as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, isCiEnvironment as F, sync as G, mergeReactDoctorConfigs as H, DIAGNOSTIC_CATEGORY_BUCKETS as I, void_ as K, Progress as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_DETAIL_WIDTH_FRACTION as P, Reporter as R, hasLintHardFailure as S, formatFixRecipeLine as T, resolveScanTarget as U, mapWithConcurrency as V, runPromise as W, canAnimateOnboarding as _, resolveCliInspectOptions as a, buildCodeFrame as b, detectLaunchableAgents as c, launchCliAgent as d, isShareOptedOut as f, doctorFace as g, easeOutCubic as h, selectProjects as i, findNearestPackageDirectory as j, recordCount as k, CLI_AGENT_BINARIES as l, printFooter as m, shouldFailScanGate as n, countUniqueScannedFiles as o, inspect as p, succeed$3 as q, discoverWorkspacePackages as r, setUpGitHubActions as s, exitGracefully as t, copyToClipboard as u, computeProjectedScore as v, buildSortedRuleGroups as w, buildNoScoreMessage as x, formatElapsedTime as y, getCategoryImpact as z };
97578
97582
 
97579
97583
  //# sourceMappingURL=cli.js.map
97580
- //# debugId=f34e66dd-4b16-53f5-a3af-9844fbc71772
97584
+ //# debugId=3092d21f-ad14-532c-9877-ac1e91c6e9e0
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="afe9afbe-4d17-5f2a-8b4f-9b49703c42be")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ac29de69-5480-5f78-bf24-603b28879241")}catch(e){}}();
3
3
  import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
@@ -62043,6 +62043,11 @@ const findMonorepoRoot = (startDirectory) => {
62043
62043
  * byte-equivalent copy.
62044
62044
  */
62045
62045
  const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
62046
+ const unwrapTypescriptExpression = (expression) => {
62047
+ let currentExpression = expression;
62048
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
62049
+ return currentExpression;
62050
+ };
62046
62051
  const TSCONFIG_FILENAME = "tsconfig.json";
62047
62052
  const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
62048
62053
  const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
@@ -62514,9 +62519,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
62514
62519
  initializer: assignedInitializer
62515
62520
  };
62516
62521
  };
62517
- const getStaticConfigValueState = (expression, analysis) => {
62518
- let unwrappedExpression = expression;
62519
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
62522
+ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
62523
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
62524
+ if (visitedExpressions.has(unwrappedExpression)) return null;
62525
+ const nextVisitedExpressions = new Set(visitedExpressions);
62526
+ nextVisitedExpressions.add(unwrappedExpression);
62520
62527
  if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
62521
62528
  isNullish: true,
62522
62529
  isTruthy: false
@@ -62532,31 +62539,31 @@ const getStaticConfigValueState = (expression, analysis) => {
62532
62539
  if (ts.isIdentifier(unwrappedExpression)) {
62533
62540
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62534
62541
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62535
- return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
62542
+ return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
62536
62543
  }
62537
62544
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62538
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
62545
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62539
62546
  }
62540
62547
  if (ts.isConditionalExpression(unwrappedExpression)) {
62541
- const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
62542
- if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
62543
- const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
62544
- const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
62548
+ const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
62549
+ if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
62550
+ const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
62551
+ const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
62545
62552
  return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
62546
62553
  }
62547
62554
  if (ts.isBinaryExpression(unwrappedExpression)) {
62548
- const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
62555
+ const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
62549
62556
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
62550
62557
  if (leftState === null) return null;
62551
- return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
62558
+ return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62552
62559
  }
62553
62560
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
62554
62561
  if (leftState === null) return null;
62555
- return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
62562
+ return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
62556
62563
  }
62557
62564
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
62558
62565
  if (leftState === null) return null;
62559
- return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
62566
+ return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62560
62567
  }
62561
62568
  }
62562
62569
  return null;
@@ -62565,25 +62572,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
62565
62572
  const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
62566
62573
  const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
62567
62574
  const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
62568
- const getReactCompilerFlagState = (expression, analysis) => {
62569
- let unwrappedExpression = expression;
62570
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
62575
+ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
62576
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
62577
+ if (visitedExpressions.has(unwrappedExpression)) return null;
62578
+ const nextVisitedExpressions = new Set(visitedExpressions);
62579
+ nextVisitedExpressions.add(unwrappedExpression);
62571
62580
  if (ts.isIdentifier(unwrappedExpression)) {
62572
62581
  const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
62573
62582
  if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
62574
62583
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62575
62584
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62576
- return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
62585
+ return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
62577
62586
  }
62578
62587
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62579
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
62588
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62580
62589
  }
62581
62590
  if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
62582
62591
  for (const property of [...unwrappedExpression.properties].reverse()) {
62583
62592
  if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
62584
62593
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
62585
62594
  if (ts.isSpreadAssignment(property)) {
62586
- const spreadState = getReactCompilerFlagState(property.expression, analysis);
62595
+ const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
62587
62596
  if (spreadState) return spreadState;
62588
62597
  }
62589
62598
  }
@@ -67280,11 +67289,6 @@ const getTypescriptScriptKind = (fileName) => {
67280
67289
  if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
67281
67290
  return ts.ScriptKind.JS;
67282
67291
  };
67283
- const unwrapTypescriptExpression = (expression) => {
67284
- let currentExpression = expression;
67285
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
67286
- return currentExpression;
67287
- };
67288
67292
  const BABEL_CONFIG_FILE_NAMES$1 = [
67289
67293
  "babel.config.js",
67290
67294
  "babel.config.cjs",
@@ -74888,4 +74892,4 @@ const toJsonReport = (result, options) => buildJsonReport({
74888
74892
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
74889
74893
 
74890
74894
  //# sourceMappingURL=index.js.map
74891
- //# debugId=afe9afbe-4d17-5f2a-8b4f-9b49703c42be
74895
+ //# debugId=ac29de69-5480-5f78-bf24-603b28879241
package/dist/lsp.js CHANGED
@@ -62096,6 +62096,11 @@ const findMonorepoRoot = (startDirectory) => {
62096
62096
  * byte-equivalent copy.
62097
62097
  */
62098
62098
  const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
62099
+ const unwrapTypescriptExpression = (expression) => {
62100
+ let currentExpression = expression;
62101
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
62102
+ return currentExpression;
62103
+ };
62099
62104
  const TSCONFIG_FILENAME = "tsconfig.json";
62100
62105
  const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
62101
62106
  const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
@@ -62567,9 +62572,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
62567
62572
  initializer: assignedInitializer
62568
62573
  };
62569
62574
  };
62570
- const getStaticConfigValueState = (expression, analysis) => {
62571
- let unwrappedExpression = expression;
62572
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
62575
+ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
62576
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
62577
+ if (visitedExpressions.has(unwrappedExpression)) return null;
62578
+ const nextVisitedExpressions = new Set(visitedExpressions);
62579
+ nextVisitedExpressions.add(unwrappedExpression);
62573
62580
  if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
62574
62581
  isNullish: true,
62575
62582
  isTruthy: false
@@ -62585,31 +62592,31 @@ const getStaticConfigValueState = (expression, analysis) => {
62585
62592
  if (ts.isIdentifier(unwrappedExpression)) {
62586
62593
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62587
62594
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62588
- return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
62595
+ return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
62589
62596
  }
62590
62597
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62591
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
62598
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62592
62599
  }
62593
62600
  if (ts.isConditionalExpression(unwrappedExpression)) {
62594
- const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
62595
- if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
62596
- const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
62597
- const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
62601
+ const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
62602
+ if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
62603
+ const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
62604
+ const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
62598
62605
  return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
62599
62606
  }
62600
62607
  if (ts.isBinaryExpression(unwrappedExpression)) {
62601
- const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
62608
+ const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
62602
62609
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
62603
62610
  if (leftState === null) return null;
62604
- return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
62611
+ return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62605
62612
  }
62606
62613
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
62607
62614
  if (leftState === null) return null;
62608
- return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
62615
+ return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
62609
62616
  }
62610
62617
  if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
62611
62618
  if (leftState === null) return null;
62612
- return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
62619
+ return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
62613
62620
  }
62614
62621
  }
62615
62622
  return null;
@@ -62618,25 +62625,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
62618
62625
  const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
62619
62626
  const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
62620
62627
  const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
62621
- const getReactCompilerFlagState = (expression, analysis) => {
62622
- let unwrappedExpression = expression;
62623
- while (ts.isParenthesizedExpression(unwrappedExpression) || ts.isAsExpression(unwrappedExpression) || ts.isTypeAssertionExpression(unwrappedExpression) || ts.isSatisfiesExpression(unwrappedExpression) || ts.isNonNullExpression(unwrappedExpression)) unwrappedExpression = unwrappedExpression.expression;
62628
+ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
62629
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
62630
+ if (visitedExpressions.has(unwrappedExpression)) return null;
62631
+ const nextVisitedExpressions = new Set(visitedExpressions);
62632
+ nextVisitedExpressions.add(unwrappedExpression);
62624
62633
  if (ts.isIdentifier(unwrappedExpression)) {
62625
62634
  const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
62626
62635
  if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
62627
62636
  if (analysis.localBindings.has(unwrappedExpression.text)) {
62628
62637
  const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
62629
- return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
62638
+ return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
62630
62639
  }
62631
62640
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
62632
- return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
62641
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
62633
62642
  }
62634
62643
  if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
62635
62644
  for (const property of [...unwrappedExpression.properties].reverse()) {
62636
62645
  if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
62637
62646
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
62638
62647
  if (ts.isSpreadAssignment(property)) {
62639
- const spreadState = getReactCompilerFlagState(property.expression, analysis);
62648
+ const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
62640
62649
  if (spreadState) return spreadState;
62641
62650
  }
62642
62651
  }
@@ -67259,11 +67268,6 @@ const getTypescriptScriptKind = (fileName) => {
67259
67268
  if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
67260
67269
  return ts.ScriptKind.JS;
67261
67270
  };
67262
- const unwrapTypescriptExpression = (expression) => {
67263
- let currentExpression = expression;
67264
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
67265
- return currentExpression;
67266
- };
67267
67271
  const BABEL_CONFIG_FILE_NAMES$1 = [
67268
67272
  "babel.config.js",
67269
67273
  "babel.config.cjs",
@@ -76510,5 +76514,5 @@ const startLanguageServer = () => {
76510
76514
  };
76511
76515
  //#endregion
76512
76516
  export { startLanguageServer };
76513
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c9dabb64-11c9-5783-a682-d985b8bc43fe")}catch(e){}}();
76514
- //# debugId=c9dabb64-11c9-5783-a682-d985b8bc43fe
76517
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="48e73e9e-1848-53fc-a033-6e6aacd3c6c2")}catch(e){}}();
76518
+ //# debugId=48e73e9e-1848-53fc-a033-6e6aacd3c6c2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.9.1-dev.6904ff1",
3
+ "version": "0.9.1-dev.80e89c5",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -71,7 +71,7 @@
71
71
  "vscode-uri": "^3.1.0",
72
72
  "yaml": "^2.9.0",
73
73
  "deslop-js": "0.9.1",
74
- "oxlint-plugin-react-doctor": "0.9.1-dev.6904ff1"
74
+ "oxlint-plugin-react-doctor": "0.9.1-dev.80e89c5"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@types/babel__code-frame": "^7.27.0",