mirror of
https://github.com/millionco/react-doctor.git
synced 2026-09-14 20:00:24 +08:00
8c2f03aea9
* feat: make React cleanup first-class * refactor: remove editor integrations * fix: harden React cleanup analysis * fix: detect default export duplication roots * fix: unwrap typed duplication roots * feat: add opt-in project analysis rules * fix: canonicalize project analysis paths * fix: harden project analysis precision * fix: recognize cross-platform project entries * fix: eliminate project analysis false positives * fix: harden project analysis reachability * fix: canonicalize project analysis inputs * fix: resolve project analysis review findings * fix: eliminate residual project analysis false positives * fix: ignore commented registry previews * fix: eliminate project analysis false positives * fix: normalize project analysis paths across platforms * fix: normalize Nextra theme path identity * test: canonicalize convention fixture paths * fix: preserve project analysis provenance * fix: harden project analysis precision * fix: honor project analysis boundaries * fix: recognize conditional config plugins * fix: recognize executable project references * fix: recognize Stencil tool contracts * fix: recognize nested tool references * fix: recognize project setup contracts * fix: recognize generated and local package consumers * fix: recognize static template package references * fix: recognize nested package runtime contracts * fix: close project analysis parser gaps * fix: parse project conventions structurally * refactor: replace structural scanners with parsers * fix: recognize functional Next CSS config * fix: close remaining project analysis gaps * fix: apply tag filters to project analysis * fix: preserve embedded source positions * fix: validate static config helper bindings * fix: bound runtime directory discovery * fix: close final dependency analysis gaps * fix: preserve declaration dependency references * chore: refresh generated rule metadata * fix: make project analysis portable and bounded * test: stabilize cleanup scaling guard * refactor: parse project syntax with oxc * fix: normalize native filesystem paths * fix: separate path identity from report paths * fix: match project files by filesystem identity * fix: match build glob files by package identity * fix: use native path keys for file identity * fix: canonicalize Windows file identities * fix: canonicalize package ownership paths * test: inspect Windows path identities * test: trace Windows package ownership * fix: keep Windows path identities consistent * fix: classify test contracts by normalized path * fix: scope test contracts by canonical package path * fix: keep test package graphs conservative * test: keep React complexity advisory
79 lines
3.6 KiB
TypeScript
79 lines
3.6 KiB
TypeScript
import * as Sentry from "@sentry/node";
|
|
import { buildSentryScope } from "./cli/utils/build-sentry-scope.js";
|
|
import { SENTRY_DSN, SENTRY_FLUSH_TIMEOUT_MS } from "./cli/utils/constants.js";
|
|
import { isEnvFlagEnabled } from "./cli/utils/is-env-flag-enabled.js";
|
|
import { isExpectedUserError } from "./cli/utils/is-expected-user-error.js";
|
|
import { isTelemetryEnabled } from "./cli/utils/is-telemetry-enabled.js";
|
|
import { scrubSentryEvent } from "./cli/utils/scrub-sentry-event.js";
|
|
import { resolveSentryEnvironment, resolveSentryRelease } from "./cli/utils/sentry-config.js";
|
|
|
|
// Re-exported for back-compat after these resolvers moved to `sentry-config.ts`.
|
|
export { resolveSentryEnvironment, resolveSentryRelease };
|
|
|
|
let isInitialized = false;
|
|
|
|
/**
|
|
* Flushes queued Sentry events (errors + transactions) before the CLI exits, so
|
|
* the success-path transaction is delivered. A no-op when Sentry was never
|
|
* initialized, and it swallows transport failures so telemetry can never mask
|
|
* the user's result.
|
|
*/
|
|
export const flushSentry = async (): Promise<void> => {
|
|
if (!Sentry.isInitialized()) return;
|
|
try {
|
|
await Sentry.flush(SENTRY_FLUSH_TIMEOUT_MS);
|
|
} catch {}
|
|
};
|
|
|
|
/**
|
|
* Initializes the Sentry Node SDK for CLI crash reporting and performance
|
|
* crash reporting. Invoked as the first statement of the CLI entry
|
|
* (`cli/index.ts`) so the SDK's global `uncaughtException` /
|
|
* `unhandledRejection` handlers are armed before any command runs.
|
|
*
|
|
* Performance tracing is off: spans are exported to Axiom instead (see
|
|
* `telemetry-runtime.ts`), and Effect has a single `Tracer` reference, so the
|
|
* two backends are mutually exclusive. Sentry keeps what it is good at —
|
|
* symbolicated stack traces, issue grouping, and a quotable event id — while
|
|
* crashes carry the Axiom trace id as a tag so an issue pivots into its trace.
|
|
*
|
|
* Exported as a function rather than a bare side-effecting import because the
|
|
* package declares `"sideEffects": false`, which lets the bundler tree-shake
|
|
* side-effect-only modules. An explicit call keeps the initialization in the
|
|
* published `dist/cli.js`.
|
|
*
|
|
* Scoped to the CLI application only — the programmatic `@react-doctor/api`
|
|
* library never initializes Sentry, so importing `diagnose()` into a consumer
|
|
* app can't hijack their telemetry.
|
|
*
|
|
* Configuration is environment-overridable for self-hosting and tuning:
|
|
* `SENTRY_DSN`, `SENTRY_ENVIRONMENT`, `SENTRY_RELEASE`, and `SENTRY_DEBUG`.
|
|
*/
|
|
export const initializeSentry = (): void => {
|
|
if (isInitialized || !isTelemetryEnabled()) return;
|
|
isInitialized = true;
|
|
const { tags, contexts } = buildSentryScope();
|
|
try {
|
|
Sentry.init({
|
|
dsn: process.env.SENTRY_DSN || SENTRY_DSN,
|
|
release: resolveSentryRelease(),
|
|
environment: resolveSentryEnvironment(),
|
|
// Anonymized telemetry: never attach the user's IP address.
|
|
sendDefaultPii: false,
|
|
// Spans go to Axiom; Sentry captures exceptions only.
|
|
tracesSampleRate: 0,
|
|
debug: isEnvFlagEnabled(process.env.SENTRY_DEBUG),
|
|
// Seed the scope so the run snapshot rides along with every event.
|
|
// (Only `run` exists at init; the scanned `project` context is added later
|
|
// once a scan discovers it.)
|
|
initialScope: { tags, contexts },
|
|
// Anonymize every outgoing event: strip hostname/IP/device identity, drop
|
|
// captured local variables, and scrub home-directory paths and known
|
|
// secrets from all remaining strings. Returns `null` to drop the event if
|
|
// scrubbing fails, so un-anonymized data is never sent.
|
|
beforeSend: (event, hint) =>
|
|
isExpectedUserError(hint.originalException) ? null : scrubSentryEvent(event),
|
|
});
|
|
} catch {}
|
|
};
|