react-doctor 0.9.13-dev.1239043 → 0.9.13-dev.45c0df3
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/_react-doctor_require-typescript-DnwIzXJn.js +7 -0
- package/dist/{active-scan-abort-registry-DwG6tSPy.js → active-scan-abort-registry-B72ASBUh.js} +3 -3
- package/dist/build-section-divider-DUxdYc-w.js +80 -0
- package/dist/{ci-CUgNjCr-.js → ci-BwvrFxxP.js} +12 -12
- package/dist/cli.js +25 -26
- package/dist/constants-CKOk_Fa9.js +23 -0
- package/dist/{design-CX2j8ubS.js → design-kKNMVr1y.js} +4 -4
- package/dist/{devtools-CC2PAZ85.js → devtools-DOdrAPkZ.js} +3 -3
- package/dist/duplicate-jsx-worker.d.ts +1 -0
- package/dist/duplicate-jsx-worker.js +636 -0
- package/dist/{exit-gracefully-cGJM2g3O.js → exit-gracefully-rrcHzkUN.js} +7 -7
- package/dist/{get-east-asian-width-Bv2TD3Xj.js → get-east-asian-width-CM5BOEC-.js} +3 -3
- package/dist/{handle-error-BCI-Nv3P.js → handle-error-CkUL31OJ.js} +5 -5
- package/dist/index.js +2289 -1604
- package/dist/{inspect-Dq5krKWG.js → inspect-DA6s8FhA.js} +22 -20
- package/dist/{install-C0aiZKgf.js → install-6tMGZzFd.js} +9 -9
- package/dist/{install-doctor-script-CaTIms0r.js → install-doctor-script-CjJaGxqK.js} +5 -5
- package/dist/{install-github-workflow-DjPgXVqg.js → install-github-workflow-0aMzq1Ju.js} +5 -5
- package/dist/{install-react-doctor-C-PVDWXv.js → install-react-doctor-Dvq7uaam.js} +8 -8
- package/dist/{jsx-runtime-D_A4d39v.js → jsx-runtime-DmLigwoS.js} +7 -7
- package/dist/oxlint-worker.d.ts +1 -0
- package/dist/oxlint-worker.js +135 -0
- package/dist/{print-branded-header-Dz0SwyHQ.js → print-branded-header-2XLtwL_O.js} +4 -4
- package/dist/project-analysis-worker.js +452 -469
- package/dist/{prompt-runtime-scan-url-BXdY2Opw.js → prompt-runtime-scan-url-BqFheEqh.js} +5 -5
- package/dist/{read-object-file-CmMGK1uu.js → read-object-file-BC9KgyfB.js} +4 -4
- package/dist/{record-metric-B6T_Ej33.js → record-metric-DadXt-YJ.js} +1782 -1047
- package/dist/{report-error-DwL3b99q.js → report-error-RqZ4TcFp.js} +7 -7
- package/dist/{report-workflow-result-5PueDIAr.js → report-workflow-result-C-6ou3Yf.js} +5 -5
- package/dist/{resolve-scope-CTlLl7e6.js → resolve-scope-IralKJo7.js} +6 -6
- package/dist/{rules-DEbHKRag.js → rules-PiRhyXht.js} +6 -6
- package/dist/{run-scan-app-D3huvmXJ.js → run-scan-app-Bx3RR66H.js} +12 -12
- package/dist/{runtime-scan-CHFAEYg3.js → runtime-scan-CzLZG2SG.js} +11 -11
- package/dist/{sanitize-runtime-url-Bbq40iIp.js → sanitize-runtime-url-ChOwIs6Q.js} +4 -4
- package/dist/{scan-C7sCm7wi.js → scan-BsKjedB4.js} +9 -9
- package/dist/{semver-DFtnEmN-.js → semver-DlmXks31.js} +3 -3
- package/dist/{should-fail-scan-gate-CfG_ppAV.js → should-fail-scan-gate-DKuuz_Be.js} +86 -67
- package/dist/{should-skip-prompts-BuNtAVEs.js → should-skip-prompts-D49q53Ep.js} +4 -4
- package/dist/{should-use-tui-B-lCjXVG.js → should-use-tui-BSXNboYB.js} +4 -4
- package/dist/{telemetry-runtime-BF83aBFL.js → telemetry-runtime-DprfIwPW.js} +153 -5
- package/dist/unwrap-typescript-expression-CbO_6kmC.js +14 -0
- package/dist/{version-C27gr4Qj.js → version-DihZTmZU.js} +4 -4
- package/dist/{why-CYRkZ2VY.js → why-B8uIFoLE.js} +4 -4
- package/dist/{with-run-span-CdsXSJgE.js → with-run-span-JTZIIQT_.js} +5 -5
- package/package.json +4 -4
- package/dist/build-section-divider-C09RcJrc.js +0 -216
|
@@ -1,25 +1,25 @@
|
|
|
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]="
|
|
3
|
-
import { $ as
|
|
4
|
-
import { t as getTelemetryContext } from "./telemetry-runtime-
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
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]="f92e971c-99d2-5796-b6db-309ec4863494")}catch(e){}}();
|
|
3
|
+
import { $ as LintPartialFailures, $n as ParentSpan, A as SCAN_RESULT_CACHE_FILENAME, An as decodeUnknownSync, At as createOxlintSpawnSlots, B as isNonInteractiveEnvironment, Bn as runPromise, Cn as warmOxlintWorkerPool, Cr as OXLINT_NODE_REQUIREMENT, Dn as log, Dt as countOptInProjectRuleSelections, Et as computeDiagnosticDelta, Fn as orElseSucceed, Ft as filterSourceFiles, G as isCiEnvironment, Gt as hasPublishedFixRecipe, Hn as sync, In as promise, J as Config, Jn as succeed, Jt as highlighter, K as isCiOrCodingAgentEnvironment, Kn as mergeAll, Ln as provide, Mn as gen, Mt as discoverSupportedSubprojects, Nt as filterDiagnosticsForSurface, On as warn, Ot as createInvocationCaches, Pn as map, Pt as filterPathsOutsideDirectories, Qt as isReactDoctorError, Rn as provideContext, S as BASELINE_FILES_TEMP_DIR_PREFIX, Sr as MILLISECONDS_PER_SECOND, St as classifyFileContext, T as METRIC, Tn as error, Tt as computeConfigFingerprint, U as ACTION_INPUT_ENVIRONMENT_VARIABLES, Un as try_, Vn as runSync, Vt as getDiagnosticRuleIdentity, W as detectRunnerOs, Wt as groupBy, X as Git, Xt as isPathInsideDirectory, Y as Files, Yt as isMonorepoRoot, Z as InvocationCaches, _ as VERSION, _t as buildRuleDocsUrl, at as PerFileLintCacheEnabled, bn as summarizeDiagnostics, br as JSX_FILE_PATTERN, bt as calculateScore, cn as mergeReactDoctorConfigs, ct as Reporter, d as isJsonModeActive, dn as resolveLintBatchOrdering, en as isScanComplete, er as yieldToEventLoop, et as Linter, fn as resolveReactDoctorCacheDir, ft as SupplyChain, gn as runInspect, gr as ENTERPRISE_CONTACT_URL, hn as restoreLegacyThrow, ht as atomicWriteJson, in as listWorkspacePackages, it as OxlintSpawnSlots, kn as Diagnostic, kt as createNodeReadFileLinesSync, l as getRunId, ln as remainingDeadlineBudgetMs, lt as Score, mn as resolveScanTarget, mr as DIAGNOSTIC_CATEGORY_BUCKETS, n as recordDistribution, nn as listSourceFiles, nt as NodeResolver, on as mapWithConcurrency, ot as Progress, pn as resolveScanConcurrency, qt as hashFileContents, r as toSpanAttributes, rn as listSourceFilesCooperative, rr as isFile, rt as OxlintConcurrency, sn as materializeSourceTree, st as Project, t as recordCount, tr as isDirectory, tt as Maintainability, un as resolveGithubActionsScoreMetadata, ur as CI_URL, ut as SidecarLintCacheEnabled, v as makeNoopConsole, vr as GIT_SHOW_MAX_BUFFER_BYTES, vt as buildRuleSeverityControls, wn as Console, wr as SHARE_BASE_URL, wt as collectSourceFilesByDirectory, xr as MAINTAINABILITY_SOURCE_FILE_PATTERN, xt as canonicalizeUserRuleKey, yn as shouldUseMaintainabilityLayer, yr as HTML_FILE_PATTERN, yt as buildSkippedChecks, z as CliInputError, zn as provideService } from "./record-metric-DadXt-YJ.js";
|
|
4
|
+
import { t as getTelemetryContext } from "./telemetry-runtime-DprfIwPW.js";
|
|
5
|
+
import { t as activeScanAbortRegistry } from "./active-scan-abort-registry-B72ASBUh.js";
|
|
6
|
+
import { n as buildFooterLinkLines, t as buildSectionDivider } from "./build-section-divider-DUxdYc-w.js";
|
|
7
7
|
import { t as toForwardSlashes } from "./path-format-DnHpmJwG.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { t as _react_doctor_require_typescript_default } from "./_react-doctor_require-typescript-DnwIzXJn.js";
|
|
9
|
+
import { C as isRecord, M as cliLogger, S as getPackageJsonPath, a as installReactDoctorScriptStep, c as spinner, k as runGit, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-CjJaGxqK.js";
|
|
10
|
+
import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-0aMzq1Ju.js";
|
|
11
|
+
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel } from "./resolve-scope-IralKJo7.js";
|
|
12
|
+
import { n as resetSentryRunState, r as withRunSpan, t as recordSentryProjectContext } from "./with-run-span-JTZIIQT_.js";
|
|
13
|
+
import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-C-6ou3Yf.js";
|
|
13
14
|
import { createRequire } from "node:module";
|
|
14
15
|
import { spawn } from "node:child_process";
|
|
15
16
|
import * as path$1 from "node:path";
|
|
16
17
|
import path from "node:path";
|
|
17
18
|
import * as fs$2 from "node:fs";
|
|
18
19
|
import fs, { mkdtempSync, rmSync } from "node:fs";
|
|
19
|
-
import ts from "typescript";
|
|
20
20
|
import crypto, { randomUUID } from "node:crypto";
|
|
21
|
-
import { tmpdir } from "node:os";
|
|
22
21
|
import * as fs$1 from "node:fs/promises";
|
|
22
|
+
import { tmpdir } from "node:os";
|
|
23
23
|
import { performance } from "node:perf_hooks";
|
|
24
24
|
//#region src/cli/utils/apply-observability.ts
|
|
25
25
|
/**
|
|
@@ -102,7 +102,8 @@ const buildRuntimeLayers = (input) => {
|
|
|
102
102
|
configSourceDirectory: input.configSourceDirectory
|
|
103
103
|
}) : Config.layerNode, Files.layerNode, Git.layerNode, linterLayer, LintPartialFailures.layerLive, maintainabilityLayer, progressLayer, reporterLayer, scoreLayer, supplyChainLayer);
|
|
104
104
|
const layersWithConcurrency = input.oxlintConcurrency === void 0 ? baseLayers : mergeAll(baseLayers, succeed(OxlintConcurrency, input.oxlintConcurrency));
|
|
105
|
-
|
|
105
|
+
const layersWithSpawnSlots = input.oxlintSpawnSlots === void 0 ? layersWithConcurrency : mergeAll(layersWithConcurrency, succeed(OxlintSpawnSlots, input.oxlintSpawnSlots));
|
|
106
|
+
return input.invocationCaches === void 0 ? layersWithSpawnSlots : mergeAll(layersWithSpawnSlots, succeed(InvocationCaches, input.invocationCaches));
|
|
106
107
|
};
|
|
107
108
|
//#endregion
|
|
108
109
|
//#region src/cli/utils/diagnostic-grouping.ts
|
|
@@ -1025,6 +1026,15 @@ const filterDiagnosticsByChangedLines = (input) => {
|
|
|
1025
1026
|
});
|
|
1026
1027
|
};
|
|
1027
1028
|
//#endregion
|
|
1029
|
+
//#region src/cli/utils/resolve-invocation-oxlint-concurrency.ts
|
|
1030
|
+
/**
|
|
1031
|
+
* The invocation-wide oxlint worker count: an explicit `--concurrency` pin
|
|
1032
|
+
* when given, else the env-seeded / auto-budgeted `OxlintConcurrency`, clamped
|
|
1033
|
+
* to the spawn ceiling. Every project of a workspace scan shares this one
|
|
1034
|
+
* pool, so it also sizes how many projects may be in flight at once.
|
|
1035
|
+
*/
|
|
1036
|
+
const resolveInvocationOxlintConcurrency = (requestedConcurrency) => resolveScanConcurrency(requestedConcurrency ?? runSync(OxlintConcurrency));
|
|
1037
|
+
//#endregion
|
|
1028
1038
|
//#region src/cli/utils/resolve-oxlint-node.ts
|
|
1029
1039
|
const consoleWarn = (message) => warn(highlighter.warn(message));
|
|
1030
1040
|
const consoleBreak = log("");
|
|
@@ -1138,7 +1148,8 @@ const resolveInspectOptions = (inputOptions, userConfig) => {
|
|
|
1138
1148
|
supplyChainManifestChanged: inputOptions.supplyChainManifestChanged ?? false,
|
|
1139
1149
|
excludedProjectDirectories: inputOptions.excludedProjectDirectories ?? [],
|
|
1140
1150
|
retainExcludedProjectDeadCodeDiagnostics: inputOptions.retainExcludedProjectDeadCodeDiagnostics ?? false,
|
|
1141
|
-
precomputedSourceFileCount: inputOptions.precomputedSourceFileCount
|
|
1151
|
+
precomputedSourceFileCount: inputOptions.precomputedSourceFileCount,
|
|
1152
|
+
precomputedSourceFiles: inputOptions.precomputedSourceFiles
|
|
1142
1153
|
};
|
|
1143
1154
|
};
|
|
1144
1155
|
//#endregion
|
|
@@ -1619,10 +1630,10 @@ const SOURCE_EXTENSIONS = [
|
|
|
1619
1630
|
const COMPONENT_WRAPPER_NAMES = new Set(["memo", "forwardRef"]);
|
|
1620
1631
|
const getScriptKind = (filePath) => {
|
|
1621
1632
|
const extension = path.extname(filePath).toLowerCase();
|
|
1622
|
-
if (extension === ".tsx") return
|
|
1623
|
-
if (extension === ".jsx") return
|
|
1624
|
-
if (extension === ".js" || extension === ".mjs" || extension === ".cjs") return
|
|
1625
|
-
return
|
|
1633
|
+
if (extension === ".tsx") return _react_doctor_require_typescript_default.ScriptKind.TSX;
|
|
1634
|
+
if (extension === ".jsx") return _react_doctor_require_typescript_default.ScriptKind.JSX;
|
|
1635
|
+
if (extension === ".js" || extension === ".mjs" || extension === ".cjs") return _react_doctor_require_typescript_default.ScriptKind.JS;
|
|
1636
|
+
return _react_doctor_require_typescript_default.ScriptKind.TS;
|
|
1626
1637
|
};
|
|
1627
1638
|
const resolveSafeSourcePath = (rootDirectory, filePath) => {
|
|
1628
1639
|
try {
|
|
@@ -1652,7 +1663,7 @@ const readSourceRecord = (rootDirectory, filePath, state) => {
|
|
|
1652
1663
|
const record = {
|
|
1653
1664
|
absolutePath,
|
|
1654
1665
|
filePath: normalizedFilePath,
|
|
1655
|
-
sourceFile:
|
|
1666
|
+
sourceFile: _react_doctor_require_typescript_default.createSourceFile(absolutePath, sourceText, _react_doctor_require_typescript_default.ScriptTarget.Latest, true, getScriptKind(absolutePath)),
|
|
1656
1667
|
sourceText
|
|
1657
1668
|
};
|
|
1658
1669
|
state.recordByFilePath.set(normalizedFilePath, record);
|
|
@@ -1672,13 +1683,13 @@ const listSourceRecords = (rootDirectory, state) => {
|
|
|
1672
1683
|
};
|
|
1673
1684
|
const unwrapExpression = (expression) => {
|
|
1674
1685
|
let currentExpression = expression;
|
|
1675
|
-
while (
|
|
1686
|
+
while (_react_doctor_require_typescript_default.isParenthesizedExpression(currentExpression) || _react_doctor_require_typescript_default.isAsExpression(currentExpression) || _react_doctor_require_typescript_default.isTypeAssertionExpression(currentExpression) || _react_doctor_require_typescript_default.isNonNullExpression(currentExpression) || _react_doctor_require_typescript_default.isSatisfiesExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
1676
1687
|
return currentExpression;
|
|
1677
1688
|
};
|
|
1678
1689
|
const getCalleeName = (expression) => {
|
|
1679
1690
|
const unwrappedExpression = unwrapExpression(expression);
|
|
1680
|
-
if (
|
|
1681
|
-
if (
|
|
1691
|
+
if (_react_doctor_require_typescript_default.isIdentifier(unwrappedExpression)) return unwrappedExpression.text;
|
|
1692
|
+
if (_react_doctor_require_typescript_default.isPropertyAccessExpression(unwrappedExpression)) return unwrappedExpression.name.text;
|
|
1682
1693
|
return null;
|
|
1683
1694
|
};
|
|
1684
1695
|
const isComponentWrapperCall = (node) => {
|
|
@@ -1686,29 +1697,29 @@ const isComponentWrapperCall = (node) => {
|
|
|
1686
1697
|
return wrapperName !== null && COMPONENT_WRAPPER_NAMES.has(wrapperName);
|
|
1687
1698
|
};
|
|
1688
1699
|
const getFunctionName = (node) => {
|
|
1689
|
-
if (
|
|
1690
|
-
if (
|
|
1700
|
+
if (_react_doctor_require_typescript_default.isFunctionDeclaration(node) && node.name !== void 0) return node.name.text;
|
|
1701
|
+
if (_react_doctor_require_typescript_default.isArrowFunction(node) || _react_doctor_require_typescript_default.isFunctionExpression(node)) {
|
|
1691
1702
|
let componentExpression = node;
|
|
1692
1703
|
while (true) {
|
|
1693
1704
|
const parent = componentExpression.parent;
|
|
1694
|
-
if (
|
|
1705
|
+
if (_react_doctor_require_typescript_default.isParenthesizedExpression(parent) || _react_doctor_require_typescript_default.isAsExpression(parent) || _react_doctor_require_typescript_default.isTypeAssertionExpression(parent) || _react_doctor_require_typescript_default.isNonNullExpression(parent) || _react_doctor_require_typescript_default.isSatisfiesExpression(parent)) {
|
|
1695
1706
|
componentExpression = parent;
|
|
1696
1707
|
continue;
|
|
1697
1708
|
}
|
|
1698
|
-
if (
|
|
1709
|
+
if (_react_doctor_require_typescript_default.isCallExpression(parent) && parent.arguments[0] === componentExpression && isComponentWrapperCall(parent)) {
|
|
1699
1710
|
componentExpression = parent;
|
|
1700
1711
|
continue;
|
|
1701
1712
|
}
|
|
1702
|
-
if (
|
|
1713
|
+
if (_react_doctor_require_typescript_default.isVariableDeclaration(parent) && _react_doctor_require_typescript_default.isIdentifier(parent.name)) return parent.name.text;
|
|
1703
1714
|
return node.name?.text ?? null;
|
|
1704
1715
|
}
|
|
1705
1716
|
}
|
|
1706
1717
|
return null;
|
|
1707
1718
|
};
|
|
1708
|
-
const isComponentFunction = (node) =>
|
|
1719
|
+
const isComponentFunction = (node) => _react_doctor_require_typescript_default.isFunctionDeclaration(node) || _react_doctor_require_typescript_default.isFunctionExpression(node) || _react_doctor_require_typescript_default.isArrowFunction(node);
|
|
1709
1720
|
const isDefaultExportedComponent = (record, node, componentName) => {
|
|
1710
|
-
if (
|
|
1711
|
-
return record.sourceFile.statements.some((statement) =>
|
|
1721
|
+
if (_react_doctor_require_typescript_default.canHaveModifiers(node) && _react_doctor_require_typescript_default.getModifiers(node)?.some((modifier) => modifier.kind === _react_doctor_require_typescript_default.SyntaxKind.DefaultKeyword)) return true;
|
|
1722
|
+
return record.sourceFile.statements.some((statement) => _react_doctor_require_typescript_default.isExportAssignment(statement) && _react_doctor_require_typescript_default.isIdentifier(statement.expression) && statement.expression.text === componentName);
|
|
1712
1723
|
};
|
|
1713
1724
|
const findEnclosingComponent = (record, diagnostic) => {
|
|
1714
1725
|
if (!Number.isInteger(diagnostic.line) || diagnostic.line < 1) return null;
|
|
@@ -1737,7 +1748,7 @@ const findEnclosingComponent = (record, diagnostic) => {
|
|
|
1737
1748
|
componentWidth = width;
|
|
1738
1749
|
}
|
|
1739
1750
|
}
|
|
1740
|
-
|
|
1751
|
+
_react_doctor_require_typescript_default.forEachChild(node, visit);
|
|
1741
1752
|
};
|
|
1742
1753
|
visit(record.sourceFile);
|
|
1743
1754
|
return component;
|
|
@@ -1757,11 +1768,11 @@ const getComponentTagNames = (record, component) => {
|
|
|
1757
1768
|
if (record.absolutePath === component.record.absolutePath) return new Set([component.name]);
|
|
1758
1769
|
const tagNames = /* @__PURE__ */ new Set();
|
|
1759
1770
|
for (const statement of record.sourceFile.statements) {
|
|
1760
|
-
if (!
|
|
1771
|
+
if (!_react_doctor_require_typescript_default.isImportDeclaration(statement) || !_react_doctor_require_typescript_default.isStringLiteral(statement.moduleSpecifier) || !moduleSpecifierTargetsComponent(record, statement.moduleSpecifier.text, component.record)) continue;
|
|
1761
1772
|
const importClause = statement.importClause;
|
|
1762
1773
|
if (component.isDefaultExport && importClause?.name !== void 0) tagNames.add(importClause.name.text);
|
|
1763
1774
|
const namedBindings = importClause?.namedBindings;
|
|
1764
|
-
if (namedBindings !== void 0 &&
|
|
1775
|
+
if (namedBindings !== void 0 && _react_doctor_require_typescript_default.isNamedImports(namedBindings)) {
|
|
1765
1776
|
for (const element of namedBindings.elements) if ((element.propertyName?.text ?? element.name.text) === component.name) tagNames.add(element.name.text);
|
|
1766
1777
|
}
|
|
1767
1778
|
}
|
|
@@ -1769,52 +1780,52 @@ const getComponentTagNames = (record, component) => {
|
|
|
1769
1780
|
};
|
|
1770
1781
|
const getTransparentCall = (functionNode) => {
|
|
1771
1782
|
if (functionNode.body === void 0) return null;
|
|
1772
|
-
if (!
|
|
1783
|
+
if (!_react_doctor_require_typescript_default.isBlock(functionNode.body)) {
|
|
1773
1784
|
const expression = unwrapExpression(functionNode.body);
|
|
1774
|
-
return
|
|
1785
|
+
return _react_doctor_require_typescript_default.isCallExpression(expression) ? expression : null;
|
|
1775
1786
|
}
|
|
1776
1787
|
if (functionNode.body.statements.length !== 1) return null;
|
|
1777
1788
|
const statement = functionNode.body.statements[0];
|
|
1778
1789
|
if (statement === void 0) return null;
|
|
1779
|
-
const expression =
|
|
1790
|
+
const expression = _react_doctor_require_typescript_default.isExpressionStatement(statement) || _react_doctor_require_typescript_default.isReturnStatement(statement) ? statement.expression : void 0;
|
|
1780
1791
|
if (expression === void 0) return null;
|
|
1781
1792
|
const unwrappedExpression = unwrapExpression(expression);
|
|
1782
|
-
return
|
|
1793
|
+
return _react_doctor_require_typescript_default.isCallExpression(unwrappedExpression) ? unwrappedExpression : null;
|
|
1783
1794
|
};
|
|
1784
1795
|
const resolveTransparentTarget = (functionNode) => {
|
|
1785
1796
|
const call = getTransparentCall(functionNode);
|
|
1786
1797
|
if (call === null) return null;
|
|
1787
1798
|
const target = unwrapExpression(call.expression);
|
|
1788
|
-
if (!
|
|
1799
|
+
if (!_react_doctor_require_typescript_default.isIdentifier(target) || call.arguments.length !== functionNode.parameters.length) return null;
|
|
1789
1800
|
for (const [parameterIndex, parameter] of functionNode.parameters.entries()) {
|
|
1790
1801
|
const argument = call.arguments[parameterIndex];
|
|
1791
1802
|
const unwrappedArgument = argument === void 0 ? null : unwrapExpression(argument);
|
|
1792
|
-
if (!
|
|
1803
|
+
if (!_react_doctor_require_typescript_default.isIdentifier(parameter.name) || unwrappedArgument === null || !_react_doctor_require_typescript_default.isIdentifier(unwrappedArgument) || unwrappedArgument.text !== parameter.name.text) return null;
|
|
1793
1804
|
}
|
|
1794
1805
|
return target.text;
|
|
1795
1806
|
};
|
|
1796
1807
|
const getForwardingFunction = (declaration) => {
|
|
1797
|
-
if (
|
|
1798
|
-
if (!
|
|
1808
|
+
if (_react_doctor_require_typescript_default.isFunctionDeclaration(declaration)) return declaration;
|
|
1809
|
+
if (!_react_doctor_require_typescript_default.isVariableDeclaration(declaration) || declaration.initializer === void 0) return null;
|
|
1799
1810
|
const initializer = unwrapExpression(declaration.initializer);
|
|
1800
|
-
if (
|
|
1801
|
-
if (
|
|
1811
|
+
if (_react_doctor_require_typescript_default.isArrowFunction(initializer) || _react_doctor_require_typescript_default.isFunctionExpression(initializer)) return initializer;
|
|
1812
|
+
if (_react_doctor_require_typescript_default.isCallExpression(initializer) && getCalleeName(initializer.expression) === "useCallback") {
|
|
1802
1813
|
const callback = initializer.arguments[0];
|
|
1803
|
-
if (callback !== void 0 && (
|
|
1814
|
+
if (callback !== void 0 && (_react_doctor_require_typescript_default.isArrowFunction(callback) || _react_doctor_require_typescript_default.isFunctionExpression(callback))) return callback;
|
|
1804
1815
|
}
|
|
1805
1816
|
return null;
|
|
1806
1817
|
};
|
|
1807
1818
|
const getDeclaredBindingName = (node) => {
|
|
1808
|
-
if ((
|
|
1809
|
-
if (
|
|
1810
|
-
if (
|
|
1819
|
+
if ((_react_doctor_require_typescript_default.isVariableDeclaration(node) || _react_doctor_require_typescript_default.isParameter(node) || _react_doctor_require_typescript_default.isBindingElement(node) || _react_doctor_require_typescript_default.isFunctionDeclaration(node)) && node.name !== void 0 && _react_doctor_require_typescript_default.isIdentifier(node.name)) return node.name.text;
|
|
1820
|
+
if (_react_doctor_require_typescript_default.isImportClause(node)) return node.name?.text ?? null;
|
|
1821
|
+
if (_react_doctor_require_typescript_default.isImportSpecifier(node) || _react_doctor_require_typescript_default.isNamespaceImport(node)) return node.name.text;
|
|
1811
1822
|
return null;
|
|
1812
1823
|
};
|
|
1813
1824
|
const findBindingScope = (node) => {
|
|
1814
1825
|
let currentNode = node;
|
|
1815
1826
|
while (currentNode !== void 0) {
|
|
1816
|
-
if (
|
|
1817
|
-
if (
|
|
1827
|
+
if (_react_doctor_require_typescript_default.isParameter(currentNode) && _react_doctor_require_typescript_default.isFunctionLike(currentNode.parent)) return currentNode.parent;
|
|
1828
|
+
if (_react_doctor_require_typescript_default.isBlock(currentNode) || _react_doctor_require_typescript_default.isModuleBlock(currentNode) || _react_doctor_require_typescript_default.isSourceFile(currentNode)) return currentNode;
|
|
1818
1829
|
currentNode = currentNode.parent;
|
|
1819
1830
|
}
|
|
1820
1831
|
return node.getSourceFile();
|
|
@@ -1826,13 +1837,13 @@ const findBindingDeclaration = (record, binding) => {
|
|
|
1826
1837
|
if (getDeclaredBindingName(node) === binding.text) {
|
|
1827
1838
|
const scope = findBindingScope(node);
|
|
1828
1839
|
const isVisibleScope = usagePosition >= scope.getStart(record.sourceFile) && usagePosition <= scope.end;
|
|
1829
|
-
const isVisibleDeclaration =
|
|
1840
|
+
const isVisibleDeclaration = _react_doctor_require_typescript_default.isFunctionDeclaration(node) || _react_doctor_require_typescript_default.isParameter(node) || _react_doctor_require_typescript_default.isBindingElement(node) || _react_doctor_require_typescript_default.isImportClause(node) || _react_doctor_require_typescript_default.isImportSpecifier(node) || _react_doctor_require_typescript_default.isNamespaceImport(node) || node.getStart(record.sourceFile) < usagePosition;
|
|
1830
1841
|
if (isVisibleScope && isVisibleDeclaration) candidates.push({
|
|
1831
1842
|
declaration: node,
|
|
1832
1843
|
scope
|
|
1833
1844
|
});
|
|
1834
1845
|
}
|
|
1835
|
-
|
|
1846
|
+
_react_doctor_require_typescript_default.forEachChild(node, visit);
|
|
1836
1847
|
};
|
|
1837
1848
|
visit(record.sourceFile);
|
|
1838
1849
|
let nearestCandidate = null;
|
|
@@ -1848,7 +1859,7 @@ const findBindingDeclaration = (record, binding) => {
|
|
|
1848
1859
|
}
|
|
1849
1860
|
if (isNearestScopeAmbiguous) return null;
|
|
1850
1861
|
const declaration = nearestCandidate?.declaration;
|
|
1851
|
-
return declaration !== void 0 && (
|
|
1862
|
+
return declaration !== void 0 && (_react_doctor_require_typescript_default.isVariableDeclaration(declaration) || _react_doctor_require_typescript_default.isFunctionDeclaration(declaration)) ? declaration : null;
|
|
1852
1863
|
};
|
|
1853
1864
|
const resolveHandlerBinding = (record, binding) => {
|
|
1854
1865
|
const declaration = findBindingDeclaration(record, binding);
|
|
@@ -1857,15 +1868,15 @@ const resolveHandlerBinding = (record, binding) => {
|
|
|
1857
1868
|
const target = forwardingFunction === null ? null : resolveTransparentTarget(forwardingFunction);
|
|
1858
1869
|
return target === null || target === binding.text ? binding.text : target;
|
|
1859
1870
|
};
|
|
1860
|
-
const getJsxTagName = (node) =>
|
|
1871
|
+
const getJsxTagName = (node) => _react_doctor_require_typescript_default.isIdentifier(node.tagName) ? node.tagName.text : null;
|
|
1861
1872
|
const getHandlerBinding = (node, propName) => {
|
|
1862
1873
|
for (const property of node.attributes.properties) {
|
|
1863
|
-
if (!
|
|
1874
|
+
if (!_react_doctor_require_typescript_default.isJsxAttribute(property) || property.name.getText() !== propName) continue;
|
|
1864
1875
|
const initializer = property.initializer;
|
|
1865
|
-
if (initializer === void 0 || !
|
|
1876
|
+
if (initializer === void 0 || !_react_doctor_require_typescript_default.isJsxExpression(initializer)) return null;
|
|
1866
1877
|
if (initializer.expression === void 0) return null;
|
|
1867
1878
|
const expression = unwrapExpression(initializer.expression);
|
|
1868
|
-
return
|
|
1879
|
+
return _react_doctor_require_typescript_default.isIdentifier(expression) ? expression : null;
|
|
1869
1880
|
}
|
|
1870
1881
|
return null;
|
|
1871
1882
|
};
|
|
@@ -1881,7 +1892,7 @@ const getForwardedHandlerAliases = (rootDirectory, component, propNames, state)
|
|
|
1881
1892
|
if (tagNames.size === 0) continue;
|
|
1882
1893
|
const visit = (node) => {
|
|
1883
1894
|
if (record === component.record && node === component.node) return;
|
|
1884
|
-
if (
|
|
1895
|
+
if (_react_doctor_require_typescript_default.isJsxOpeningElement(node) || _react_doctor_require_typescript_default.isJsxSelfClosingElement(node)) {
|
|
1885
1896
|
const tagName = getJsxTagName(node);
|
|
1886
1897
|
if (tagName !== null && tagNames.has(tagName)) {
|
|
1887
1898
|
callsiteCount += 1;
|
|
@@ -1897,7 +1908,7 @@ const getForwardedHandlerAliases = (rootDirectory, component, propNames, state)
|
|
|
1897
1908
|
}
|
|
1898
1909
|
}
|
|
1899
1910
|
}
|
|
1900
|
-
|
|
1911
|
+
_react_doctor_require_typescript_default.forEachChild(node, visit);
|
|
1901
1912
|
};
|
|
1902
1913
|
visit(record.sourceFile);
|
|
1903
1914
|
}
|
|
@@ -2254,7 +2265,10 @@ const inspectWithOxlintRuntime = async (directory, inputOptions, oxlintRuntime)
|
|
|
2254
2265
|
userConfig = scanTarget.userConfig;
|
|
2255
2266
|
configSourceDirectory = scanTarget.configSourceDirectory;
|
|
2256
2267
|
}
|
|
2257
|
-
const options = resolveInspectOptions(inputOptions
|
|
2268
|
+
const options = resolveInspectOptions(path$1.resolve(directory) === path$1.resolve(scanDirectory) ? inputOptions : {
|
|
2269
|
+
...inputOptions,
|
|
2270
|
+
precomputedSourceFiles: void 0
|
|
2271
|
+
}, userConfig);
|
|
2258
2272
|
const ownsSpinnerSilence = options.silent && !isConcurrentScan;
|
|
2259
2273
|
const wasSpinnerSilent = isSpinnerSilent();
|
|
2260
2274
|
if (ownsSpinnerSilence) setSpinnerSilent(true);
|
|
@@ -2278,9 +2292,10 @@ const inspectWithOxlintRuntime = async (directory, inputOptions, oxlintRuntime)
|
|
|
2278
2292
|
}
|
|
2279
2293
|
};
|
|
2280
2294
|
const createInvocationInspect = (requestedOxlintConcurrency) => {
|
|
2281
|
-
const concurrency =
|
|
2295
|
+
const concurrency = resolveInvocationOxlintConcurrency(requestedOxlintConcurrency);
|
|
2282
2296
|
const spawnSlots = createOxlintSpawnSlots(concurrency);
|
|
2283
2297
|
const scanResultCacheInvocationState = createScanResultCacheInvocationState();
|
|
2298
|
+
const invocationCaches = createInvocationCaches();
|
|
2284
2299
|
return async (directory, inputOptions = {}) => {
|
|
2285
2300
|
const abortController = new AbortController();
|
|
2286
2301
|
const unregisterAbortController = activeScanAbortRegistry.register(abortController);
|
|
@@ -2289,7 +2304,8 @@ const createInvocationInspect = (requestedOxlintConcurrency) => {
|
|
|
2289
2304
|
concurrency,
|
|
2290
2305
|
spawnSlots,
|
|
2291
2306
|
abortSignal: abortController.signal,
|
|
2292
|
-
scanResultCacheInvocationState
|
|
2307
|
+
scanResultCacheInvocationState,
|
|
2308
|
+
invocationCaches
|
|
2293
2309
|
});
|
|
2294
2310
|
} finally {
|
|
2295
2311
|
unregisterAbortController();
|
|
@@ -2315,6 +2331,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
2315
2331
|
});
|
|
2316
2332
|
const cachedResult = scanResultCacheLifecycle.replay();
|
|
2317
2333
|
if (cachedResult !== null) return cachedResult;
|
|
2334
|
+
if (options.lint && resolvedNodeBinaryPath) warmOxlintWorkerPool(resolvedNodeBinaryPath, oxlintRuntime.concurrency);
|
|
2318
2335
|
const shouldShowProgressSpinners = !options.isCiOrCodingAgentEnvironment && !options.silent && !options.scoreOnly && !options.suppressRendering && options.lint && Boolean(resolvedNodeBinaryPath);
|
|
2319
2336
|
const layers = buildRuntimeLayers({
|
|
2320
2337
|
directory,
|
|
@@ -2328,12 +2345,14 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
2328
2345
|
shouldShowProgressSpinners,
|
|
2329
2346
|
oxlintConcurrency: oxlintRuntime.concurrency,
|
|
2330
2347
|
oxlintSpawnSlots: oxlintRuntime.spawnSlots,
|
|
2348
|
+
invocationCaches: oxlintRuntime.invocationCaches,
|
|
2331
2349
|
reporterLayer: options.uiLayers?.reporter,
|
|
2332
2350
|
progressLayer: options.uiLayers?.progress
|
|
2333
2351
|
});
|
|
2334
2352
|
const program = runInspect({
|
|
2335
2353
|
directory,
|
|
2336
2354
|
precomputedSourceFileCount: options.precomputedSourceFileCount,
|
|
2355
|
+
precomputedSourceFiles: options.precomputedSourceFiles,
|
|
2337
2356
|
includePaths: options.includePaths,
|
|
2338
2357
|
changedLineRanges: options.changedLineRanges ?? void 0,
|
|
2339
2358
|
customRulesOnly: options.customRulesOnly,
|
|
@@ -2445,12 +2464,12 @@ const deduplicateProjectScans = (projectScans) => {
|
|
|
2445
2464
|
return uniqueProjectScans;
|
|
2446
2465
|
};
|
|
2447
2466
|
//#endregion
|
|
2448
|
-
//#region src/cli/utils/collect-project-source-
|
|
2449
|
-
const
|
|
2467
|
+
//#region src/cli/utils/collect-project-source-files.ts
|
|
2468
|
+
const collectProjectSourceFiles = async (rootDirectory, projectDirectories) => {
|
|
2450
2469
|
const abortController = new AbortController();
|
|
2451
2470
|
const unregisterAbortController = activeScanAbortRegistry.register(abortController);
|
|
2452
2471
|
try {
|
|
2453
|
-
return await
|
|
2472
|
+
return await collectSourceFilesByDirectory(rootDirectory, projectDirectories, abortController.signal);
|
|
2454
2473
|
} finally {
|
|
2455
2474
|
unregisterAbortController();
|
|
2456
2475
|
}
|
|
@@ -3027,7 +3046,7 @@ const shouldFailScanGate = (input) => {
|
|
|
3027
3046
|
return shouldBlockCi(filterScansForSurface(input.scans, "ciFailure"), input.blockingLevel);
|
|
3028
3047
|
};
|
|
3029
3048
|
//#endregion
|
|
3030
|
-
export { createInvocationInspect as A, hasIncompleteScoreAnalysis as B, detectLaunchableAgents as C, buildHandoffPayload as D, launchCliAgent as E, formatSkippedCheckLabel as F,
|
|
3049
|
+
export { createInvocationInspect as A, hasIncompleteScoreAnalysis as B, detectLaunchableAgents as C, buildHandoffPayload as D, launchCliAgent as E, formatSkippedCheckLabel as F, hasLintHardFailure as G, buildNoScoreMessage as H, formatElapsedTime as I, formatFixRecipeLine as J, buildRulePriorityMap as K, printFooter as L, resolveMergeBaseRef as M, printHeadlessReport as N, collectProjectSourceFiles as O, pluralize as P, printDiagnosticsDump as R, setUpGitHubActions as S, copyToClipboard as T, buildEmptyReportMessage as U, filterDiagnosticsByCategories as V, resolveInvocationOxlintConcurrency as W, formatLearnMoreLine as Y, retryMissingProjectScores as _, validateModeFlags as a, filterScansForSurface as b, partitionProjectScanOutcomes as c, buildCodeFrame as d, resolveProjectScan as f, resolveProjectRelativeDirectory as g, resolveProjectSourceFilePaths as h, validateIncludeUntrackedScope as i, inspect as j, deduplicateProjectScans as k, discoverWorkspacePackages as l, resolveProjectDiffIncludePaths as m, formatSkippedProjectsMessage as n, resolveExcludedProjectDirectories as o, resolveProjectChangedLineRanges as p, buildSortedRuleGroups as q, validateFilePathSelectionFlags as r, projectManifestChanged as s, shouldFailScanGate as t, selectProjects as u, resolveWorkspaceDeadCodeOwner as v, CLI_AGENT_BINARIES as w, countUniqueScannedFiles as x, resolveCliInspectOptions as y, formatDiagnosticSite as z };
|
|
3031
3050
|
|
|
3032
|
-
//# sourceMappingURL=should-fail-scan-gate-
|
|
3033
|
-
//# debugId=
|
|
3051
|
+
//# sourceMappingURL=should-fail-scan-gate-DKuuz_Be.js.map
|
|
3052
|
+
//# debugId=f92e971c-99d2-5796-b6db-309ec4863494
|
|
@@ -1,10 +1,10 @@
|
|
|
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]="
|
|
3
|
-
import { B as isNonInteractiveEnvironment } from "./record-metric-
|
|
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]="07bf89da-af77-5442-b222-be5a7ab7265c")}catch(e){}}();
|
|
3
|
+
import { B as isNonInteractiveEnvironment } from "./record-metric-DadXt-YJ.js";
|
|
4
4
|
//#region src/cli/utils/should-skip-prompts.ts
|
|
5
5
|
const shouldSkipPrompts = (input = {}) => Boolean(input.yes) || Boolean(input.json) || isNonInteractiveEnvironment() || !process.stdin.isTTY;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { shouldSkipPrompts as t };
|
|
8
8
|
|
|
9
|
-
//# sourceMappingURL=should-skip-prompts-
|
|
10
|
-
//# debugId=
|
|
9
|
+
//# sourceMappingURL=should-skip-prompts-D49q53Ep.js.map
|
|
10
|
+
//# debugId=07bf89da-af77-5442-b222-be5a7ab7265c
|
|
@@ -1,6 +1,6 @@
|
|
|
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]="
|
|
3
|
-
import { B as isNonInteractiveEnvironment } from "./record-metric-
|
|
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]="6d1c6afe-fa2a-5c3c-af98-f0e47c4a363a")}catch(e){}}();
|
|
3
|
+
import { B as isNonInteractiveEnvironment } from "./record-metric-DadXt-YJ.js";
|
|
4
4
|
//#region src/cli/utils/resolve-tui-environment.ts
|
|
5
5
|
const resolveTuiEnvironment = (outputIsTty = process.stdout.isTTY === true) => ({
|
|
6
6
|
isNonInteractiveEnvironment: isNonInteractiveEnvironment(),
|
|
@@ -21,5 +21,5 @@ const shouldUseTui = (input) => {
|
|
|
21
21
|
//#endregion
|
|
22
22
|
export { shouldUseTui as n, resolveTuiEnvironment as r, isTuiEnvironmentSupported as t };
|
|
23
23
|
|
|
24
|
-
//# sourceMappingURL=should-use-tui-
|
|
25
|
-
//# debugId=
|
|
24
|
+
//# sourceMappingURL=should-use-tui-BSXNboYB.js.map
|
|
25
|
+
//# debugId=6d1c6afe-fa2a-5c3c-af98-f0e47c4a363a
|
|
@@ -1,6 +1,6 @@
|
|
|
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]="
|
|
3
|
-
import {
|
|
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]="10f28f35-5b56-5f7e-bb3a-2e61ed9a79a3")}catch(e){}}();
|
|
3
|
+
import { Bn as runPromise, Gn as buildWithScope, N as SENTRY_FLUSH_TIMEOUT_MS, Qn as void_, Qt as isReactDoctorError, Vn as runSync, Xn as makeUnsafe, Yn as close, Zt as isProjectDiscoveryError, _ as VERSION, _n as scrubSensitivePaths, a as isEnvFlagEnabled, ar as messageFromUnknown, i as isTelemetryEnabled, jn as make, mt as anonymizeText, nr as isErrnoException, o as buildSentryScope, pt as anonymizeInPlace, tn as layerObservability, z as CliInputError } from "./record-metric-DadXt-YJ.js";
|
|
4
4
|
//#region src/cli/utils/is-environment-error.ts
|
|
5
5
|
const ENVIRONMENT_ERROR_CODES = new Set([
|
|
6
6
|
"EACCES",
|
|
@@ -144,6 +144,154 @@ const formatNpmCacheCorruptionError = (error) => {
|
|
|
144
144
|
*/
|
|
145
145
|
const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isNpmCacheCorruptionError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
|
|
146
146
|
//#endregion
|
|
147
|
+
//#region src/cli/utils/scrub-sentry-event.ts
|
|
148
|
+
/**
|
|
149
|
+
* Anonymizes a Sentry event (error or transaction) before it leaves the
|
|
150
|
+
* machine. Strips identity the SDK attaches automatically — the IP-bearing
|
|
151
|
+
* `user`, the `server_name`, and the device `name` (all hostnames) — drops
|
|
152
|
+
* captured local variables (unbounded, un-anonymizable user data), and scrubs
|
|
153
|
+
* home-directory paths + known secrets/emails from every remaining string:
|
|
154
|
+
* messages, stack frames, breadcrumbs, contexts/extra/tags, and span
|
|
155
|
+
* attributes (e.g. the `inspect.directory` path on the bridged `runInspect`
|
|
156
|
+
* span).
|
|
157
|
+
*
|
|
158
|
+
* Wired into both `beforeSend` and `beforeSendTransaction`. If scrubbing ever
|
|
159
|
+
* throws, the event is dropped (`null`) rather than risk sending un-anonymized
|
|
160
|
+
* data — telemetry is best-effort, privacy is not.
|
|
161
|
+
*/
|
|
162
|
+
const scrubSentryEvent = (event) => {
|
|
163
|
+
try {
|
|
164
|
+
delete event.server_name;
|
|
165
|
+
delete event.user;
|
|
166
|
+
const device = event.contexts?.device;
|
|
167
|
+
if (device) delete device.name;
|
|
168
|
+
if (event.contexts) anonymizeInPlace(event.contexts);
|
|
169
|
+
if (event.extra) anonymizeInPlace(event.extra);
|
|
170
|
+
if (event.tags) anonymizeInPlace(event.tags);
|
|
171
|
+
if (typeof event.message === "string") event.message = anonymizeText(event.message);
|
|
172
|
+
for (const breadcrumb of event.breadcrumbs ?? []) {
|
|
173
|
+
if (typeof breadcrumb.message === "string") breadcrumb.message = anonymizeText(breadcrumb.message);
|
|
174
|
+
if (breadcrumb.data) anonymizeInPlace(breadcrumb.data);
|
|
175
|
+
}
|
|
176
|
+
for (const exception of event.exception?.values ?? []) {
|
|
177
|
+
if (typeof exception.value === "string") exception.value = anonymizeText(exception.value);
|
|
178
|
+
for (const frame of exception.stacktrace?.frames ?? []) {
|
|
179
|
+
delete frame.vars;
|
|
180
|
+
if (typeof frame.filename === "string") frame.filename = scrubSensitivePaths(frame.filename);
|
|
181
|
+
if (typeof frame.abs_path === "string") frame.abs_path = scrubSensitivePaths(frame.abs_path);
|
|
182
|
+
if (typeof frame.module === "string") frame.module = scrubSensitivePaths(frame.module);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
for (const span of event.spans ?? []) {
|
|
186
|
+
if (typeof span.description === "string") span.description = anonymizeText(span.description);
|
|
187
|
+
if (span.data) anonymizeInPlace(span.data);
|
|
188
|
+
}
|
|
189
|
+
return event;
|
|
190
|
+
} catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/cli/utils/sentry-config.ts
|
|
196
|
+
/**
|
|
197
|
+
* Shared Sentry configuration resolution — release, environment, and tracing
|
|
198
|
+
* sample rate — derived from `VERSION` and the standard `SENTRY_*` env
|
|
199
|
+
* overrides. Lives apart from `instrument.ts` so this resolution remains
|
|
200
|
+
* independently testable.
|
|
201
|
+
*/
|
|
202
|
+
/**
|
|
203
|
+
* A version is a "dev" build when it's the unbuilt placeholder (`0.0.0`) or
|
|
204
|
+
* carries a prerelease suffix (e.g. the `-dev.<sha>` snapshots published from
|
|
205
|
+
* CI). Everything else is a real, tagged release.
|
|
206
|
+
*/
|
|
207
|
+
const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
208
|
+
/**
|
|
209
|
+
* Sentry release identifier. `react-doctor@<version>` keeps it unique within
|
|
210
|
+
* the org and — crucially — matches the value `scripts/sentry-sourcemaps.mjs`
|
|
211
|
+
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
212
|
+
* standard `SENTRY_RELEASE` override.
|
|
213
|
+
*/
|
|
214
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.13-dev.45c0df3`;
|
|
215
|
+
/**
|
|
216
|
+
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
217
|
+
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
218
|
+
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
219
|
+
*/
|
|
220
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.13-dev.45c0df3") ? "development" : "production");
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/instrument.ts
|
|
223
|
+
let sentryPromise = null;
|
|
224
|
+
/**
|
|
225
|
+
* Resolves the initialized Sentry SDK, or `null` when Sentry was never
|
|
226
|
+
* initialized (`--no-score`, tests, a missing DSN) or failed to load. Every
|
|
227
|
+
* Sentry consumer goes through here so the SDK's module graph (hundreds of
|
|
228
|
+
* `@sentry/*` + `@opentelemetry/*` files) is loaded off the CLI's critical
|
|
229
|
+
* startup path.
|
|
230
|
+
*/
|
|
231
|
+
const getSentry = () => sentryPromise ?? Promise.resolve(null);
|
|
232
|
+
/**
|
|
233
|
+
* Flushes queued Sentry events (errors + transactions) before the CLI exits, so
|
|
234
|
+
* the success-path transaction is delivered. A no-op when Sentry was never
|
|
235
|
+
* initialized, and it swallows transport failures so telemetry can never mask
|
|
236
|
+
* the user's result.
|
|
237
|
+
*/
|
|
238
|
+
const flushSentry = async () => {
|
|
239
|
+
const Sentry = await getSentry();
|
|
240
|
+
if (!Sentry?.isInitialized()) return;
|
|
241
|
+
try {
|
|
242
|
+
await Sentry.flush(SENTRY_FLUSH_TIMEOUT_MS);
|
|
243
|
+
} catch {}
|
|
244
|
+
};
|
|
245
|
+
const initializeSentryModule = (Sentry) => {
|
|
246
|
+
const { tags, contexts } = buildSentryScope();
|
|
247
|
+
try {
|
|
248
|
+
Sentry.init({
|
|
249
|
+
dsn: process.env.SENTRY_DSN || "https://f253d570240a59b8dbd77b7a548ef133@o4510226365743104.ingest.us.sentry.io/4511487817809920",
|
|
250
|
+
release: resolveSentryRelease(),
|
|
251
|
+
environment: resolveSentryEnvironment(),
|
|
252
|
+
sendDefaultPii: false,
|
|
253
|
+
tracesSampleRate: 0,
|
|
254
|
+
registerEsmLoaderHooks: false,
|
|
255
|
+
debug: isEnvFlagEnabled(process.env.SENTRY_DEBUG),
|
|
256
|
+
initialScope: {
|
|
257
|
+
tags,
|
|
258
|
+
contexts
|
|
259
|
+
},
|
|
260
|
+
beforeSend: (event, hint) => isExpectedUserError(hint.originalException) ? null : scrubSentryEvent(event)
|
|
261
|
+
});
|
|
262
|
+
} catch {}
|
|
263
|
+
return Sentry;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Initializes the Sentry Node SDK for CLI crash reporting. Invoked as the first
|
|
267
|
+
* statement of the CLI entry (`cli/index.ts`); the SDK is imported dynamically
|
|
268
|
+
* so its module graph loads in the background while the command starts, and the
|
|
269
|
+
* SDK's global `uncaughtException` / `unhandledRejection` handlers arm as soon
|
|
270
|
+
* as it lands. Consumers await `getSentry()` and so observe the initialized SDK.
|
|
271
|
+
*
|
|
272
|
+
* Performance tracing is off: spans are exported to Axiom instead (see
|
|
273
|
+
* `telemetry-runtime.ts`), and Effect has a single `Tracer` reference, so the
|
|
274
|
+
* two backends are mutually exclusive. Sentry keeps what it is good at —
|
|
275
|
+
* symbolicated stack traces, issue grouping, and a quotable event id — while
|
|
276
|
+
* crashes carry the Axiom trace id as a tag so an issue pivots into its trace.
|
|
277
|
+
*
|
|
278
|
+
* Exported as a function rather than a bare side-effecting import because the
|
|
279
|
+
* package declares `"sideEffects": false`, which lets the bundler tree-shake
|
|
280
|
+
* side-effect-only modules. An explicit call keeps the initialization in the
|
|
281
|
+
* published `dist/cli.js`.
|
|
282
|
+
*
|
|
283
|
+
* Scoped to the CLI application only — the programmatic `@react-doctor/api`
|
|
284
|
+
* library never initializes Sentry, so importing `diagnose()` into a consumer
|
|
285
|
+
* app can't hijack their telemetry.
|
|
286
|
+
*
|
|
287
|
+
* Configuration is environment-overridable for self-hosting and tuning:
|
|
288
|
+
* `SENTRY_DSN`, `SENTRY_ENVIRONMENT`, `SENTRY_RELEASE`, and `SENTRY_DEBUG`.
|
|
289
|
+
*/
|
|
290
|
+
const initializeSentry = () => {
|
|
291
|
+
if (sentryPromise !== null || !isTelemetryEnabled()) return;
|
|
292
|
+
sentryPromise = import("@sentry/node").then(initializeSentryModule, () => null);
|
|
293
|
+
};
|
|
294
|
+
//#endregion
|
|
147
295
|
//#region src/cli/utils/resolve-axiom-telemetry-options.ts
|
|
148
296
|
/**
|
|
149
297
|
* Resolves the credentials for first-party Axiom export, or `null` when this
|
|
@@ -245,7 +393,7 @@ const shutdownTelemetry = async () => {
|
|
|
245
393
|
return pendingShutdown;
|
|
246
394
|
};
|
|
247
395
|
//#endregion
|
|
248
|
-
export {
|
|
396
|
+
export { initializeSentry as a, isNpmCacheCorruptionError as c, getSentry as i, formatEnvironmentError as l, shutdownTelemetry as n, isExpectedUserError as o, flushSentry as r, formatNpmCacheCorruptionError as s, getTelemetryContext as t, isEnvironmentError as u };
|
|
249
397
|
|
|
250
|
-
//# sourceMappingURL=telemetry-runtime-
|
|
251
|
-
//# debugId=
|
|
398
|
+
//# sourceMappingURL=telemetry-runtime-DprfIwPW.js.map
|
|
399
|
+
//# debugId=10f28f35-5b56-5f7e-bb3a-2e61ed9a79a3
|