react-doctor 0.8.1-dev.c9f2c4b → 0.8.1-dev.cd9ca68
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 +289 -42
- package/dist/index.d.ts +27 -0
- package/dist/index.js +283 -38
- package/dist/lsp.js +283 -38
- package/package.json +3 -3
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]="
|
|
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]="434800fc-200b-5a59-aa25-61e682ab57d7")}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";
|
|
@@ -36571,10 +36571,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
|
|
|
36571
36571
|
const FRAMEWORK_PACKAGES = {
|
|
36572
36572
|
next: "nextjs",
|
|
36573
36573
|
"@tanstack/react-start": "tanstack-start",
|
|
36574
|
-
vite: "vite",
|
|
36575
|
-
"react-scripts": "cra",
|
|
36576
36574
|
"@remix-run/react": "remix",
|
|
36577
36575
|
gatsby: "gatsby",
|
|
36576
|
+
vite: "vite",
|
|
36577
|
+
"react-scripts": "cra",
|
|
36578
36578
|
expo: "expo",
|
|
36579
36579
|
"react-native": "react-native"
|
|
36580
36580
|
};
|
|
@@ -37101,19 +37101,6 @@ const getPreactVersion = (packageJson) => {
|
|
|
37101
37101
|
...packageJson.devDependencies
|
|
37102
37102
|
}.preact ?? null;
|
|
37103
37103
|
};
|
|
37104
|
-
const TANSTACK_QUERY_PACKAGES = new Set([
|
|
37105
|
-
"@tanstack/react-query",
|
|
37106
|
-
"@tanstack/query-core",
|
|
37107
|
-
"react-query"
|
|
37108
|
-
]);
|
|
37109
|
-
const hasTanStackQuery = (packageJson) => {
|
|
37110
|
-
const allDependencies = {
|
|
37111
|
-
...packageJson.peerDependencies,
|
|
37112
|
-
...packageJson.dependencies,
|
|
37113
|
-
...packageJson.devDependencies
|
|
37114
|
-
};
|
|
37115
|
-
return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
|
|
37116
|
-
};
|
|
37117
37104
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
37118
37105
|
if (version === null || !isCatalogReference(version)) return version;
|
|
37119
37106
|
const catalogName = extractCatalogName(version);
|
|
@@ -37316,7 +37303,60 @@ const listWorkspacePackages = (rootDirectory) => {
|
|
|
37316
37303
|
}
|
|
37317
37304
|
return packages;
|
|
37318
37305
|
};
|
|
37306
|
+
const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
|
|
37307
|
+
const allDependencies = {
|
|
37308
|
+
...packageJson.devDependencies,
|
|
37309
|
+
...packageJson.peerDependencies,
|
|
37310
|
+
...packageJson.dependencies
|
|
37311
|
+
};
|
|
37312
|
+
for (const packageName of packageNames) {
|
|
37313
|
+
const version = allDependencies[packageName];
|
|
37314
|
+
if (version !== void 0) return version;
|
|
37315
|
+
}
|
|
37316
|
+
return null;
|
|
37317
|
+
};
|
|
37318
|
+
const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
|
|
37319
|
+
const getTanStackQueryVersion = (packageJson) => {
|
|
37320
|
+
return getPreferredDependencyVersion({
|
|
37321
|
+
packageJson,
|
|
37322
|
+
packageNames: TANSTACK_REACT_QUERY_PACKAGES
|
|
37323
|
+
});
|
|
37324
|
+
};
|
|
37325
|
+
const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
|
|
37326
|
+
const getStyledComponentsVersion = (packageJson) => {
|
|
37327
|
+
return getPreferredDependencyVersion({
|
|
37328
|
+
packageJson,
|
|
37329
|
+
packageNames: STYLED_COMPONENTS_PACKAGES
|
|
37330
|
+
});
|
|
37331
|
+
};
|
|
37332
|
+
const I18N_PACKAGES = [
|
|
37333
|
+
"i18next",
|
|
37334
|
+
"react-i18next",
|
|
37335
|
+
"next-i18next",
|
|
37336
|
+
"react-intl",
|
|
37337
|
+
"next-intl",
|
|
37338
|
+
"use-intl",
|
|
37339
|
+
"@formatjs/intl",
|
|
37340
|
+
"@lingui/core",
|
|
37341
|
+
"@lingui/react",
|
|
37342
|
+
"typesafe-i18n",
|
|
37343
|
+
"@tolgee/react",
|
|
37344
|
+
"react-intl-universal"
|
|
37345
|
+
];
|
|
37346
|
+
const hasI18nDependency = (packageJson) => {
|
|
37347
|
+
const allDependencies = {
|
|
37348
|
+
...packageJson.peerDependencies,
|
|
37349
|
+
...packageJson.dependencies,
|
|
37350
|
+
...packageJson.devDependencies,
|
|
37351
|
+
...packageJson.optionalDependencies
|
|
37352
|
+
};
|
|
37353
|
+
return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
|
|
37354
|
+
};
|
|
37319
37355
|
const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
|
|
37356
|
+
const MOBX_REACT_PACKAGE_NAME = "mobx-react";
|
|
37357
|
+
const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
|
|
37358
|
+
const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
|
|
37359
|
+
const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
|
|
37320
37360
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
37321
37361
|
const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
|
|
37322
37362
|
const dependencyDeclaration = getDependencyDeclaration({
|
|
@@ -37335,7 +37375,26 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
|
|
|
37335
37375
|
if (nextMajor === null) return false;
|
|
37336
37376
|
return nextMajor < currentMajor;
|
|
37337
37377
|
};
|
|
37338
|
-
const
|
|
37378
|
+
const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
|
|
37379
|
+
if (currentFact.version === null) return true;
|
|
37380
|
+
if (nextFact.version === null) return false;
|
|
37381
|
+
const currentMajor = getLowestDependencyMajor(currentFact.version);
|
|
37382
|
+
const nextMajor = getLowestDependencyMajor(nextFact.version);
|
|
37383
|
+
if (currentMajor === null) return false;
|
|
37384
|
+
if (nextMajor === null) return true;
|
|
37385
|
+
if (currentMajor > latestSupportedMajor) return false;
|
|
37386
|
+
if (nextMajor > latestSupportedMajor) return true;
|
|
37387
|
+
return nextMajor < currentMajor;
|
|
37388
|
+
};
|
|
37389
|
+
const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
|
|
37390
|
+
if (!currentVersion) return true;
|
|
37391
|
+
const currentMajor = getLowestDependencyMajor(currentVersion);
|
|
37392
|
+
const nextMajor = getLowestDependencyMajor(nextVersion);
|
|
37393
|
+
if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
|
|
37394
|
+
if (nextMajor === null) return currentMajor >= 6;
|
|
37395
|
+
return nextMajor < currentMajor;
|
|
37396
|
+
};
|
|
37397
|
+
const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
|
|
37339
37398
|
if (facts.expo.version === null) {
|
|
37340
37399
|
const spec = getDependencySpec(packageJson, "expo");
|
|
37341
37400
|
if (spec !== null) facts.expo = {
|
|
@@ -37357,13 +37416,74 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
|
|
|
37357
37416
|
sourceDirectory: directory
|
|
37358
37417
|
};
|
|
37359
37418
|
}
|
|
37419
|
+
const mobxSpec = getDependencySpec(packageJson, "mobx");
|
|
37420
|
+
if (mobxSpec !== null) {
|
|
37421
|
+
const nextMobxFact = {
|
|
37422
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
37423
|
+
rootDirectory: directory,
|
|
37424
|
+
rootPackageJson: packageJson,
|
|
37425
|
+
packageName: "mobx",
|
|
37426
|
+
version: mobxSpec
|
|
37427
|
+
}),
|
|
37428
|
+
sourceDirectory: directory
|
|
37429
|
+
};
|
|
37430
|
+
if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
|
|
37431
|
+
}
|
|
37432
|
+
facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
|
|
37433
|
+
facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
|
|
37434
|
+
facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
|
|
37435
|
+
facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
|
|
37436
|
+
const zustandSpec = getDependencySpec(packageJson, "zustand");
|
|
37437
|
+
if (zustandSpec !== null) {
|
|
37438
|
+
const nextZustandFact = {
|
|
37439
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
37440
|
+
rootDirectory: directory,
|
|
37441
|
+
rootPackageJson: packageJson,
|
|
37442
|
+
packageName: "zustand",
|
|
37443
|
+
version: zustandSpec
|
|
37444
|
+
}),
|
|
37445
|
+
sourceDirectory: directory
|
|
37446
|
+
};
|
|
37447
|
+
if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
|
|
37448
|
+
}
|
|
37360
37449
|
if (facts.reanimatedVersion === null) {
|
|
37361
37450
|
const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
|
|
37362
37451
|
if (spec !== null) facts.reanimatedVersion = spec;
|
|
37363
37452
|
}
|
|
37453
|
+
if (facts.valtioVersion === null) {
|
|
37454
|
+
const spec = getDependencySpec(packageJson, "valtio");
|
|
37455
|
+
if (spec !== null) facts.valtioVersion = spec;
|
|
37456
|
+
}
|
|
37457
|
+
facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
|
|
37458
|
+
const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
|
|
37459
|
+
rootDirectory: directory,
|
|
37460
|
+
rootPackageJson: packageJson,
|
|
37461
|
+
packageName: "styled-components",
|
|
37462
|
+
version: getStyledComponentsVersion(packageJson)
|
|
37463
|
+
});
|
|
37464
|
+
if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
|
|
37465
|
+
facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
|
|
37364
37466
|
facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
|
|
37365
37467
|
facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
|
|
37366
37468
|
facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
|
|
37469
|
+
const remotionSpec = getDependencySpec(packageJson, "remotion");
|
|
37470
|
+
if (remotionSpec !== null) {
|
|
37471
|
+
facts.hasRemotionDependency = true;
|
|
37472
|
+
const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
|
|
37473
|
+
rootDirectory,
|
|
37474
|
+
rootPackageJson,
|
|
37475
|
+
packageName: "remotion",
|
|
37476
|
+
version: remotionSpec
|
|
37477
|
+
});
|
|
37478
|
+
const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
|
|
37479
|
+
if (remotionMajorVersion === null) {
|
|
37480
|
+
facts.hasUnknownRemotionVersion = true;
|
|
37481
|
+
facts.remotionVersion = null;
|
|
37482
|
+
} else if (!facts.hasUnknownRemotionVersion) {
|
|
37483
|
+
const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
|
|
37484
|
+
if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
|
|
37485
|
+
}
|
|
37486
|
+
}
|
|
37367
37487
|
};
|
|
37368
37488
|
const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
|
|
37369
37489
|
const facts = {
|
|
@@ -37383,12 +37503,31 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
37383
37503
|
version: null,
|
|
37384
37504
|
sourceDirectory: null
|
|
37385
37505
|
},
|
|
37506
|
+
valtioVersion: null,
|
|
37507
|
+
mobx: {
|
|
37508
|
+
version: null,
|
|
37509
|
+
sourceDirectory: null
|
|
37510
|
+
},
|
|
37511
|
+
hasMobxReact: false,
|
|
37512
|
+
hasMobxReactLite: false,
|
|
37513
|
+
hasMobxStateTree: false,
|
|
37514
|
+
hasMobxReactObserver: false,
|
|
37515
|
+
zustand: {
|
|
37516
|
+
version: null,
|
|
37517
|
+
sourceDirectory: null
|
|
37518
|
+
},
|
|
37519
|
+
tanstackQueryVersion: null,
|
|
37520
|
+
styledComponentsVersion: null,
|
|
37521
|
+
hasI18nLibrary: false,
|
|
37386
37522
|
hasReactNativeAwarePackage: false,
|
|
37387
37523
|
hasReanimatedAwarePackage: false,
|
|
37388
37524
|
hasSsrDependency: false,
|
|
37525
|
+
hasRemotionDependency: false,
|
|
37526
|
+
hasUnknownRemotionVersion: false,
|
|
37527
|
+
remotionVersion: null,
|
|
37389
37528
|
reanimatedVersion: null
|
|
37390
37529
|
};
|
|
37391
|
-
evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
|
|
37530
|
+
evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
|
|
37392
37531
|
let isReactGroupSettled = !collectReactGroup;
|
|
37393
37532
|
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
37394
37533
|
for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
|
|
@@ -37397,7 +37536,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
37397
37536
|
if (visitedDirectories.has(workspaceDirectory)) continue;
|
|
37398
37537
|
visitedDirectories.add(workspaceDirectory);
|
|
37399
37538
|
const workspacePackageJson = readPackageJson$1(Path.join(workspaceDirectory, "package.json"));
|
|
37400
|
-
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
|
|
37539
|
+
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
|
|
37401
37540
|
const info = extractDependencyInfo(workspacePackageJson);
|
|
37402
37541
|
if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
|
|
37403
37542
|
if (isReactGroupSettled) continue;
|
|
@@ -37618,11 +37757,27 @@ const discoverProjectWithoutPackageJson = (directory) => {
|
|
|
37618
37757
|
tailwindVersion: null,
|
|
37619
37758
|
zodVersion: null,
|
|
37620
37759
|
zodMajorVersion: null,
|
|
37760
|
+
mobxVersion: null,
|
|
37761
|
+
mobxMajorVersion: null,
|
|
37762
|
+
hasMobxReact: false,
|
|
37763
|
+
hasMobxReactLite: false,
|
|
37764
|
+
hasMobxStateTree: false,
|
|
37765
|
+
hasMobxReactObserver: false,
|
|
37766
|
+
zustandVersion: null,
|
|
37767
|
+
zustandMajorVersion: null,
|
|
37621
37768
|
framework: "unknown",
|
|
37622
37769
|
hasTypeScript: hasOwnTsConfig,
|
|
37623
37770
|
hasReactCompiler: false,
|
|
37624
37771
|
hasReactCompilerLintPlugin: false,
|
|
37625
37772
|
hasTanStackQuery: false,
|
|
37773
|
+
valtioVersion: null,
|
|
37774
|
+
valtioMajorVersion: null,
|
|
37775
|
+
hasRemotion: false,
|
|
37776
|
+
remotionVersion: null,
|
|
37777
|
+
remotionMajorVersion: null,
|
|
37778
|
+
hasI18nLibrary: false,
|
|
37779
|
+
tanstackQueryVersion: null,
|
|
37780
|
+
styledComponentsVersion: null,
|
|
37626
37781
|
hasSsrDependency: false,
|
|
37627
37782
|
preactVersion: null,
|
|
37628
37783
|
preactMajorVersion: null,
|
|
@@ -37721,6 +37876,12 @@ const discoverProject = (directory) => {
|
|
|
37721
37876
|
packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
|
|
37722
37877
|
version: workspaceFacts.shopifyFlashList.version
|
|
37723
37878
|
}) : null;
|
|
37879
|
+
const zustandVersion = resolveCatalogBackedDependencyVersion({
|
|
37880
|
+
rootDirectory: directory,
|
|
37881
|
+
rootPackageJson: packageJson,
|
|
37882
|
+
packageName: "zustand",
|
|
37883
|
+
version: workspaceFacts.zustand.version
|
|
37884
|
+
});
|
|
37724
37885
|
const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
|
|
37725
37886
|
const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
|
|
37726
37887
|
const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
|
|
@@ -37729,7 +37890,21 @@ const discoverProject = (directory) => {
|
|
|
37729
37890
|
packageName: "next",
|
|
37730
37891
|
version: workspaceFacts.next.version
|
|
37731
37892
|
}) : null;
|
|
37893
|
+
const valtioVersion = resolveCatalogBackedDependencyVersion({
|
|
37894
|
+
rootDirectory: directory,
|
|
37895
|
+
rootPackageJson: packageJson,
|
|
37896
|
+
packageName: "valtio",
|
|
37897
|
+
version: workspaceFacts.valtioVersion
|
|
37898
|
+
});
|
|
37899
|
+
const mobxVersion = resolveCatalogBackedDependencyVersion({
|
|
37900
|
+
rootDirectory: directory,
|
|
37901
|
+
rootPackageJson: packageJson,
|
|
37902
|
+
packageName: "mobx",
|
|
37903
|
+
version: workspaceFacts.mobx.version
|
|
37904
|
+
});
|
|
37732
37905
|
const preactVersion = getPreactVersion(packageJson);
|
|
37906
|
+
const remotionVersion = workspaceFacts.remotionVersion;
|
|
37907
|
+
const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
|
|
37733
37908
|
const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
|
|
37734
37909
|
const projectInfo = {
|
|
37735
37910
|
rootDirectory: directory,
|
|
@@ -37739,11 +37914,27 @@ const discoverProject = (directory) => {
|
|
|
37739
37914
|
tailwindVersion,
|
|
37740
37915
|
zodVersion,
|
|
37741
37916
|
zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
|
|
37917
|
+
mobxVersion,
|
|
37918
|
+
mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
|
|
37919
|
+
hasMobxReact: workspaceFacts.hasMobxReact,
|
|
37920
|
+
hasMobxReactLite: workspaceFacts.hasMobxReactLite,
|
|
37921
|
+
hasMobxStateTree: workspaceFacts.hasMobxStateTree,
|
|
37922
|
+
hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
|
|
37923
|
+
zustandVersion,
|
|
37924
|
+
zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
|
|
37742
37925
|
framework,
|
|
37743
37926
|
hasTypeScript,
|
|
37744
37927
|
hasReactCompiler: detectReactCompiler(directory, packageJson),
|
|
37745
37928
|
hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
|
|
37746
|
-
hasTanStackQuery:
|
|
37929
|
+
hasTanStackQuery: tanstackQueryVersion !== null,
|
|
37930
|
+
hasI18nLibrary: workspaceFacts.hasI18nLibrary,
|
|
37931
|
+
tanstackQueryVersion,
|
|
37932
|
+
styledComponentsVersion: workspaceFacts.styledComponentsVersion,
|
|
37933
|
+
valtioVersion,
|
|
37934
|
+
valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
|
|
37935
|
+
hasRemotion: workspaceFacts.hasRemotionDependency,
|
|
37936
|
+
remotionVersion,
|
|
37937
|
+
remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
|
|
37747
37938
|
hasSsrDependency: workspaceFacts.hasSsrDependency,
|
|
37748
37939
|
preactVersion,
|
|
37749
37940
|
preactMajorVersion: parseReactMajor(preactVersion),
|
|
@@ -37977,7 +38168,6 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
|
|
|
37977
38168
|
"react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
|
|
37978
38169
|
"react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
|
|
37979
38170
|
"react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
|
|
37980
|
-
"react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
|
|
37981
38171
|
"react/jsx-no-undef": "react-doctor/jsx-no-undef",
|
|
37982
38172
|
"react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
|
|
37983
38173
|
"react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
|
|
@@ -40299,9 +40489,25 @@ const BABEL_CONFIG_FILE_NAMES = [
|
|
|
40299
40489
|
".babelrc.json"
|
|
40300
40490
|
];
|
|
40301
40491
|
const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
|
|
40492
|
+
const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
|
|
40493
|
+
const REACT_NATIVE_PACKAGE = "react-native";
|
|
40494
|
+
const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
|
|
40495
|
+
const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
|
|
40302
40496
|
const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
|
|
40303
40497
|
const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
|
|
40498
|
+
const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
|
|
40499
|
+
const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
|
|
40500
|
+
const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson$1(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
|
|
40501
|
+
if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
|
|
40502
|
+
const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
|
|
40503
|
+
if (normalizedVersionRange === null) return false;
|
|
40504
|
+
const minimumVersion = import_semver.minVersion(normalizedVersionRange);
|
|
40505
|
+
return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
|
|
40506
|
+
};
|
|
40507
|
+
const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
|
|
40304
40508
|
const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
40509
|
+
const packageJson = readPackageJson$1(Path.join(rootDirectory, "package.json"));
|
|
40510
|
+
const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
|
|
40305
40511
|
for (const fileName of BABEL_CONFIG_FILE_NAMES) {
|
|
40306
40512
|
const filePath = Path.join(rootDirectory, fileName);
|
|
40307
40513
|
if (!isFile(filePath)) continue;
|
|
@@ -40311,7 +40517,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
40311
40517
|
} catch {
|
|
40312
40518
|
continue;
|
|
40313
40519
|
}
|
|
40314
|
-
if (
|
|
40520
|
+
if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
|
|
40315
40521
|
filePath: fileName,
|
|
40316
40522
|
rule: "rn-no-metro-babel-preset",
|
|
40317
40523
|
severity: "error",
|
|
@@ -40334,12 +40540,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
|
|
|
40334
40540
|
return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
|
|
40335
40541
|
};
|
|
40336
40542
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
40337
|
-
const DEPENDENCY_SECTIONS = [
|
|
40338
|
-
"dependencies",
|
|
40339
|
-
"devDependencies",
|
|
40340
|
-
"peerDependencies",
|
|
40341
|
-
"optionalDependencies"
|
|
40342
|
-
];
|
|
40343
40543
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
40344
40544
|
"19.0": {
|
|
40345
40545
|
rceFixedVersion: "19.0.1",
|
|
@@ -40386,20 +40586,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
|
|
|
40386
40586
|
for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
|
|
40387
40587
|
return [...directories];
|
|
40388
40588
|
};
|
|
40389
|
-
const readDeclaredSpec = (packageJson, packageName) => {
|
|
40390
|
-
for (const section of DEPENDENCY_SECTIONS) {
|
|
40391
|
-
const spec = packageJson[section]?.[packageName];
|
|
40392
|
-
if (typeof spec === "string") return spec;
|
|
40393
|
-
}
|
|
40394
|
-
return null;
|
|
40395
|
-
};
|
|
40396
40589
|
const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
|
|
40397
40590
|
const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
|
|
40398
40591
|
if (isFile(manifestPath)) {
|
|
40399
40592
|
const installedVersion = import_semver.valid(readPackageJson$1(manifestPath).version ?? null);
|
|
40400
40593
|
if (installedVersion !== null) return installedVersion;
|
|
40401
40594
|
}
|
|
40402
|
-
const candidateSpecs = [
|
|
40595
|
+
const candidateSpecs = [getDependencySpec(readPackageJson$1(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
|
|
40403
40596
|
for (const spec of candidateSpecs) {
|
|
40404
40597
|
const pinnedVersion = spec === null ? null : import_semver.valid(spec);
|
|
40405
40598
|
if (pinnedVersion !== null) return pinnedVersion;
|
|
@@ -41067,6 +41260,7 @@ const buildCapabilities = (project) => {
|
|
|
41067
41260
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
41068
41261
|
if (project.isStaticExport) capabilities.add("nextjs:static-export");
|
|
41069
41262
|
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
|
|
41263
|
+
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
|
|
41070
41264
|
addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
|
|
41071
41265
|
if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
|
|
41072
41266
|
major: 19,
|
|
@@ -41079,9 +41273,30 @@ const buildCapabilities = (project) => {
|
|
|
41079
41273
|
})) capabilities.add("tailwind:3.4");
|
|
41080
41274
|
if (project.zodVersion !== null) capabilities.add("zod");
|
|
41081
41275
|
if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
|
|
41276
|
+
if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
|
|
41277
|
+
if (project.hasMobxReact === true) capabilities.add("mobx-react");
|
|
41278
|
+
if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
|
|
41279
|
+
if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
|
|
41280
|
+
if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
|
|
41281
|
+
if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
|
|
41282
|
+
if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
|
|
41283
|
+
if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
|
|
41284
|
+
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
41082
41285
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
41083
41286
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
41084
|
-
if (project.hasTanStackQuery) capabilities.add("tanstack-query");
|
|
41287
|
+
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
41288
|
+
if (project.styledComponentsVersion) {
|
|
41289
|
+
capabilities.add("styled-components");
|
|
41290
|
+
const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
|
|
41291
|
+
if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
|
|
41292
|
+
}
|
|
41293
|
+
if (project.hasI18nLibrary) capabilities.add("i18n");
|
|
41294
|
+
if (project.valtioVersion !== null) capabilities.add("valtio");
|
|
41295
|
+
addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
|
|
41296
|
+
if (project.hasRemotion) {
|
|
41297
|
+
capabilities.add("remotion");
|
|
41298
|
+
addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
|
|
41299
|
+
}
|
|
41085
41300
|
if (project.hasTypeScript) capabilities.add("typescript");
|
|
41086
41301
|
if (project.preactVersion !== null) capabilities.add("preact");
|
|
41087
41302
|
addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
|
|
@@ -43366,6 +43581,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
43366
43581
|
}
|
|
43367
43582
|
};
|
|
43368
43583
|
};
|
|
43584
|
+
const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
|
|
43585
|
+
const fingerprintFileContents = (filePath, fingerprintLength) => {
|
|
43586
|
+
const fileStats = NFS.statSync(filePath, { bigint: true });
|
|
43587
|
+
const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
|
|
43588
|
+
if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
|
|
43589
|
+
const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
|
|
43590
|
+
fingerprintCacheByFilePath.set(filePath, {
|
|
43591
|
+
fingerprint,
|
|
43592
|
+
modifiedTimeNanoseconds: fileStats.mtimeNs,
|
|
43593
|
+
sizeBytes: fileStats.size
|
|
43594
|
+
});
|
|
43595
|
+
return fingerprint;
|
|
43596
|
+
};
|
|
43369
43597
|
const bundledRequire$3 = createRequire(import.meta.url);
|
|
43370
43598
|
const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
|
|
43371
43599
|
const resolveChildNodeVersion = (nodeBinaryPath) => {
|
|
@@ -43389,6 +43617,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS$1 = [
|
|
|
43389
43617
|
"oxlint-plugin-react-doctor/package.json",
|
|
43390
43618
|
"eslint-plugin-react-hooks/package.json"
|
|
43391
43619
|
];
|
|
43620
|
+
const resolvePluginFingerprint = () => {
|
|
43621
|
+
try {
|
|
43622
|
+
return fingerprintFileContents(bundledRequire$3.resolve("oxlint-plugin-react-doctor"), 16);
|
|
43623
|
+
} catch {
|
|
43624
|
+
return "unresolved";
|
|
43625
|
+
}
|
|
43626
|
+
};
|
|
43392
43627
|
const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
43393
43628
|
const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
|
|
43394
43629
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS$1) try {
|
|
@@ -43398,6 +43633,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
|
43398
43633
|
} catch {
|
|
43399
43634
|
versions.push(`${specifier}=missing`);
|
|
43400
43635
|
}
|
|
43636
|
+
versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
|
|
43401
43637
|
return versions;
|
|
43402
43638
|
};
|
|
43403
43639
|
const esmRequire = createRequire(import.meta.url);
|
|
@@ -44091,12 +44327,17 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
|
|
|
44091
44327
|
const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
|
|
44092
44328
|
const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
|
|
44093
44329
|
const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
|
|
44330
|
+
const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
|
|
44094
44331
|
const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
|
|
44095
44332
|
const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
|
|
44096
44333
|
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
44097
44334
|
if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
|
|
44098
44335
|
return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
|
|
44099
44336
|
};
|
|
44337
|
+
const buildSetStateInEffectMessage = (reasonSummary) => {
|
|
44338
|
+
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
44339
|
+
return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
|
|
44340
|
+
};
|
|
44100
44341
|
const PLUGIN_CATEGORY_MAP = {
|
|
44101
44342
|
react: "Bugs",
|
|
44102
44343
|
"react-hooks": "Bugs",
|
|
@@ -44154,6 +44395,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
|
|
|
44154
44395
|
message: REACT_ERROR_BOUNDARY_MESSAGE,
|
|
44155
44396
|
help: reasonDetail || help
|
|
44156
44397
|
};
|
|
44398
|
+
if (rule === "set-state-in-effect") return {
|
|
44399
|
+
message: buildSetStateInEffectMessage(reasonSummary.trim()),
|
|
44400
|
+
help: reasonDetail || help
|
|
44401
|
+
};
|
|
44157
44402
|
return {
|
|
44158
44403
|
message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
|
|
44159
44404
|
help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
|
|
@@ -47356,7 +47601,7 @@ const makeNoopConsole = () => ({
|
|
|
47356
47601
|
});
|
|
47357
47602
|
//#endregion
|
|
47358
47603
|
//#region src/cli/utils/version.ts
|
|
47359
|
-
const VERSION = "0.8.1-dev.
|
|
47604
|
+
const VERSION = "0.8.1-dev.cd9ca68";
|
|
47360
47605
|
//#endregion
|
|
47361
47606
|
//#region src/cli/utils/json-mode.ts
|
|
47362
47607
|
let context = null;
|
|
@@ -47527,7 +47772,9 @@ const buildSentryProjectContext = (projectInfo) => ({
|
|
|
47527
47772
|
reactMajorVersion: projectInfo.reactMajorVersion,
|
|
47528
47773
|
hasTypeScript: projectInfo.hasTypeScript,
|
|
47529
47774
|
hasReactCompiler: projectInfo.hasReactCompiler,
|
|
47530
|
-
|
|
47775
|
+
tanstackQueryVersion: projectInfo.tanstackQueryVersion,
|
|
47776
|
+
mobxVersion: projectInfo.mobxVersion,
|
|
47777
|
+
styledComponentsVersion: projectInfo.styledComponentsVersion,
|
|
47531
47778
|
tailwindVersion: projectInfo.tailwindVersion,
|
|
47532
47779
|
zodVersion: projectInfo.zodVersion,
|
|
47533
47780
|
preactVersion: projectInfo.preactVersion,
|
|
@@ -47708,13 +47955,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
47708
47955
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
47709
47956
|
* standard `SENTRY_RELEASE` override.
|
|
47710
47957
|
*/
|
|
47711
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.
|
|
47958
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.cd9ca68`;
|
|
47712
47959
|
/**
|
|
47713
47960
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
47714
47961
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
47715
47962
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
47716
47963
|
*/
|
|
47717
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.
|
|
47964
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.cd9ca68") ? "development" : "production");
|
|
47718
47965
|
/**
|
|
47719
47966
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
47720
47967
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -66394,4 +66641,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
66394
66641
|
export {};
|
|
66395
66642
|
|
|
66396
66643
|
//# sourceMappingURL=cli.js.map
|
|
66397
|
-
//# debugId=
|
|
66644
|
+
//# debugId=434800fc-200b-5a59-aa25-61e682ab57d7
|
package/dist/index.d.ts
CHANGED
|
@@ -9543,11 +9543,38 @@ interface ProjectInfo {
|
|
|
9543
9543
|
zodVersion: string | null;
|
|
9544
9544
|
/** Parsed major from `zodVersion`, or `null` when absent/unparseable. Mirrors `reactMajorVersion`. */
|
|
9545
9545
|
zodMajorVersion: number | null;
|
|
9546
|
+
/** Declared MobX core version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
|
|
9547
|
+
mobxVersion?: string | null;
|
|
9548
|
+
/** Parsed major from `mobxVersion`, or `null` when absent/unparseable. */
|
|
9549
|
+
mobxMajorVersion?: number | null;
|
|
9550
|
+
hasMobxReact?: boolean;
|
|
9551
|
+
hasMobxReactLite?: boolean;
|
|
9552
|
+
hasMobxStateTree?: boolean;
|
|
9553
|
+
hasMobxReactObserver?: boolean;
|
|
9554
|
+
/** Declared Zustand version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
|
|
9555
|
+
zustandVersion?: string | null;
|
|
9556
|
+
/** Parsed major from `zustandVersion`, or `null` when absent/unparseable. */
|
|
9557
|
+
zustandMajorVersion?: number | null;
|
|
9546
9558
|
framework: Framework;
|
|
9547
9559
|
hasTypeScript: boolean;
|
|
9548
9560
|
hasReactCompiler: boolean;
|
|
9549
9561
|
hasReactCompilerLintPlugin?: boolean;
|
|
9550
9562
|
hasTanStackQuery: boolean;
|
|
9563
|
+
hasRemotion?: boolean;
|
|
9564
|
+
remotionVersion?: string | null;
|
|
9565
|
+
remotionMajorVersion?: number | null;
|
|
9566
|
+
hasI18nLibrary?: boolean;
|
|
9567
|
+
tanstackQueryVersion?: string | null;
|
|
9568
|
+
styledComponentsVersion?: string | null;
|
|
9569
|
+
/**
|
|
9570
|
+
* The declared `valtio` version spec, or `null` when no package in the
|
|
9571
|
+
* analyzed project declares Valtio. `useSnapshot` has kept the same
|
|
9572
|
+
* render-read contract across Valtio 1 and 2, so presence alone drives the
|
|
9573
|
+
* `valtio` capability and its parsed major-version ladder.
|
|
9574
|
+
*/
|
|
9575
|
+
valtioVersion: string | null;
|
|
9576
|
+
/** Parsed major from `valtioVersion`, or `null` when absent/unparseable. */
|
|
9577
|
+
valtioMajorVersion: number | null;
|
|
9551
9578
|
/**
|
|
9552
9579
|
* `true` when the project or a workspace declares a Vite-based SSR runtime
|
|
9553
9580
|
* such as React Router's Node adapter, Vike, or vite-plugin-ssr.
|