diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e60dd573..2ccf2dc231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ## Unreleased +### Upgrading from 6.x to 7.0 + +Version 7 of the Sentry React Native SDK primarily introduces API cleanup and version support changes. This update contains behavioral changes that will not be caught by type checkers, linters, or tests, so we recommend carefully reading through the entire migration guide instead of relying on automatic tooling. + +Version 7 of the SDK is compatible with Sentry self-hosted versions 24.4.2 or higher (unchanged from v6). Lower versions may continue to work, but may not support all features. + ### Dependencies - Bump Bundler Plugins from v3.2.2 to v3.2.4 ([#4693](https://github.com/getsentry/sentry-react-native/pull/4693), [#4707](https://github.com/getsentry/sentry-react-native/pull/4707)) @@ -17,6 +23,39 @@ - [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2430) - [diff](https://github.com/getsentry/sentry-cli/compare/2.42.4...2.43.0) +### Major Changes + +- `ip addresses` is only collected when `sendDefaultPii`: `true` +- Exceptions from `captureConsoleIntegration` are now marked as handled: true by default +- `shutdownTimeout` moved from `core` to `@sentry/react-native` +- `hasTracingEnabled` was renamed to `hasSpansEnabled` +- You can no longer drop spans or return null on `beforeSendSpan` hook + +### Removed types + +- TransactionNamingScheme +- Request +- Scope (prefer using the Scope class) + +### Other removed items. + +- `autoSessionTracking` from options. + To enable session tracking, ensure that `enableAutoSessionTracking` is enabled. + +- `enableTracing`. Instead, set `tracesSampleRate` to a value greater than `zero` to `enable tracing`, `0` to keep tracing integrations active without sampling, or `undefined` to disable the performance integration. + +- `getCurrentHub()`, `Hub`, and `getCurrentHubShim()` +- `spanId` from propagation `context` +- metrics API +- `transactionContext` from `samplingContext` +- `@sentry/utils` package, the exports were moved to `@sentry/core` +- Standalone `Client` interface & deprecate `BaseClient` + +## Other Changes + +- Fork `scope` if custom scope is passed to `startSpanManual` or `startSpan` + + ## 6.11.0-beta.0 ### Features @@ -186,6 +225,9 @@ Change `Cold/Warm App Start` span description to `Cold/Warm Start` ([#4636](http ### Dependencies +- Bump JavaScript SDK from v8.54.0 to v9.1.0 ([#4568](https://github.com/getsentry/sentry-react-native/pull/4568)) + - [changelog](https://github.com/getsentry/sentry-javascript/blob/9.1.0/CHANGELOG.md) + - [diff](https://github.com/getsentry/sentry-javascript/compare/8.54.0...9.1.0) - Bump Android SDK from v7.20.1 to v8.3.0 ([#4490](https://github.com/getsentry/sentry-react-native/pull/4490)) - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#830) - [diff](https://github.com/getsentry/sentry-java/compare/7.20.1...8.3.0) diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index 69ceadf907..1be91abf60 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -13,7 +13,7 @@ "devDependencies": { "@babel/preset-env": "^7.25.3", "@babel/preset-typescript": "^7.18.6", - "@sentry/core": "8.54.0", + "@sentry/core": "9.1.0", "@sentry/react-native": "6.11.0-beta.0", "@types/node": "^20.9.3", "@types/react": "^18.2.64", diff --git a/dev-packages/type-check/ts3.8-test/index.ts b/dev-packages/type-check/ts3.8-test/index.ts index 1e9fda3cd2..94e332746c 100644 --- a/dev-packages/type-check/ts3.8-test/index.ts +++ b/dev-packages/type-check/ts3.8-test/index.ts @@ -3,6 +3,8 @@ declare global { interface IDBObjectStore {} interface Window { fetch: any; + setTimeout: any; + document: any; } interface ShadowRoot {} interface BufferSource {} @@ -19,6 +21,7 @@ declare global { redirectCount: number; } interface PerformanceEntry {} + interface Performance {} } declare module 'react-native' { diff --git a/packages/core/package.json b/packages/core/package.json index 92901958ef..b95acdec6e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -65,22 +65,21 @@ "react-native": ">=0.65.0" }, "dependencies": { - "@sentry/babel-plugin-component-annotate": "3.2.4", - "@sentry/browser": "8.54.0", + "@sentry/babel-plugin-component-annotate": "3.1.2", + "@sentry/browser": "9.1.0", "@sentry/cli": "2.43.0", - "@sentry/core": "8.54.0", - "@sentry/react": "8.54.0", - "@sentry/types": "8.54.0", - "@sentry/utils": "8.54.0" + "@sentry/core": "9.1.0", + "@sentry/react": "9.1.0", + "@sentry/types": "9.1.0" }, "devDependencies": { "@babel/core": "^7.25.2", "@expo/metro-config": "0.19.5", "@mswjs/interceptors": "^0.25.15", "@react-native/babel-preset": "0.77.1", - "@sentry-internal/eslint-config-sdk": "8.54.0", - "@sentry-internal/eslint-plugin-sdk": "8.54.0", - "@sentry-internal/typescript": "8.54.0", + "@sentry-internal/eslint-config-sdk": "9.1.0", + "@sentry-internal/eslint-plugin-sdk": "9.1.0", + "@sentry-internal/typescript": "9.1.0", "@sentry/wizard": "4.6.0", "@testing-library/react-native": "^12.7.2", "@types/jest": "^29.5.13", @@ -110,7 +109,7 @@ "react-native": "0.77.1", "react-test-renderer": "^18.3.1", "rimraf": "^4.1.1", - "ts-jest": "^29.1.1", + "ts-jest": "^29.3.1", "typescript": "4.9.5", "uglify-js": "^3.17.4", "uuid": "^9.0.1", diff --git a/packages/core/plugin/src/withSentry.ts b/packages/core/plugin/src/withSentry.ts index 70d4c8932b..332957e871 100644 --- a/packages/core/plugin/src/withSentry.ts +++ b/packages/core/plugin/src/withSentry.ts @@ -18,7 +18,7 @@ interface PluginProps { const withSentryPlugin: ConfigPlugin = (config, props) => { const sentryProperties = getSentryProperties(props); - if (props && props.authToken) { + if (props?.authToken) { // If not removed, the plugin config with the authToken will be written to the application package delete props.authToken; } diff --git a/packages/core/plugin/src/withSentryAndroidGradlePlugin.ts b/packages/core/plugin/src/withSentryAndroidGradlePlugin.ts index 27a9a4d904..3154f25aad 100644 --- a/packages/core/plugin/src/withSentryAndroidGradlePlugin.ts +++ b/packages/core/plugin/src/withSentryAndroidGradlePlugin.ts @@ -35,7 +35,7 @@ export function withSentryAndroidGradlePlugin( const withSentryProjectBuildGradle = (config: any): any => { return withProjectBuildGradle(config, (projectBuildGradle: any) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (!projectBuildGradle.modResults || !projectBuildGradle.modResults.contents) { + if (!projectBuildGradle.modResults?.contents) { warnOnce('android/build.gradle content is missing or undefined.'); return config; } diff --git a/packages/core/src/js/index.ts b/packages/core/src/js/index.ts index 3aa2bdb71d..fb931312d9 100644 --- a/packages/core/src/js/index.ts +++ b/packages/core/src/js/index.ts @@ -1,6 +1,5 @@ export type { Breadcrumb, - Request, SdkInfo, Event, Exception, @@ -43,7 +42,6 @@ export { getClient, setCurrentClient, addEventProcessor, - metricsDefault as metrics, lastEventId, } from '@sentry/core'; diff --git a/packages/core/src/js/integrations/debugsymbolicator.ts b/packages/core/src/js/integrations/debugsymbolicator.ts index 8529d0eeb6..3ff5bc5169 100644 --- a/packages/core/src/js/integrations/debugsymbolicator.ts +++ b/packages/core/src/js/integrations/debugsymbolicator.ts @@ -143,7 +143,7 @@ function replaceExceptionFramesInException(exception: Exception, frames: SentryS * @param frames StackFrame[] */ function replaceThreadFramesInEvent(event: Event, frames: SentryStackFrame[]): void { - if (event.threads && event.threads.values && event.threads.values[0] && event.threads.values[0].stacktrace) { + if (event.threads?.values?.[0]?.stacktrace) { event.threads.values[0].stacktrace.frames = frames.reverse(); } } diff --git a/packages/core/src/js/integrations/default.ts b/packages/core/src/js/integrations/default.ts index 54b4065ee5..1fbfa987e9 100644 --- a/packages/core/src/js/integrations/default.ts +++ b/packages/core/src/js/integrations/default.ts @@ -93,10 +93,7 @@ export function getDefaultIntegrations(options: ReactNativeClientOptions): Integ // hasTracingEnabled from `@sentry/core` only check if tracesSampler or tracesSampleRate keys are present // that's different from prev imp here and might lead misconfiguration // `tracesSampleRate: undefined` should not enable tracing - const hasTracingEnabled = - options.enableTracing || - typeof options.tracesSampleRate === 'number' || - typeof options.tracesSampler === 'function'; + const hasTracingEnabled = typeof options.tracesSampleRate === 'number' || typeof options.tracesSampler === 'function'; if (hasTracingEnabled && options.enableAppStartTracking) { integrations.push(appStartIntegration()); } diff --git a/packages/core/src/js/integrations/nativelinkederrors.ts b/packages/core/src/js/integrations/nativelinkederrors.ts index 39d8d55879..d920cc8a55 100644 --- a/packages/core/src/js/integrations/nativelinkederrors.ts +++ b/packages/core/src/js/integrations/nativelinkederrors.ts @@ -43,7 +43,7 @@ export const nativeLinkedErrorsIntegration = (options: Partial { @@ -155,7 +156,7 @@ function setupErrorUtilsGlobalHandler(): void { return; } - void client.flush(client.getOptions().shutdownTimeout || 2000).then( + void client.flush((client.getOptions() as ReactNativeClientOptions).shutdownTimeout || 2000).then( () => { defaultHandler(error, isFatal); }, diff --git a/packages/core/src/js/integrations/screenshot.ts b/packages/core/src/js/integrations/screenshot.ts index 6f504fa76e..84bb72c2b4 100644 --- a/packages/core/src/js/integrations/screenshot.ts +++ b/packages/core/src/js/integrations/screenshot.ts @@ -18,13 +18,13 @@ export const screenshotIntegration = (): Integration => { }; async function processEvent(event: Event, hint: EventHint, client: ReactNativeClient): Promise { - const hasException = event.exception && event.exception.values && event.exception.values.length > 0; + const hasException = event.exception?.values?.length > 0; if (!hasException || client.getOptions().beforeScreenshot?.(event, hint) === false) { return event; } const screenshots: ScreenshotAttachment[] | null = await NATIVE.captureScreenshot(); - if (screenshots && screenshots.length > 0) { + if (screenshots?.length > 0) { hint.attachments = [...screenshots, ...(hint?.attachments || [])]; } diff --git a/packages/core/src/js/integrations/spotlight.ts b/packages/core/src/js/integrations/spotlight.ts index b4f62e06da..50191aa132 100644 --- a/packages/core/src/js/integrations/spotlight.ts +++ b/packages/core/src/js/integrations/spotlight.ts @@ -103,7 +103,7 @@ function getHostnameFromString(urlString: string): string | null { const regex = /^(?:\w+:)?\/\/([^/:]+)(:\d+)?(.*)$/; const matches = urlString.match(regex); - if (matches && matches[1]) { + if (matches?.[1]) { return matches[1]; } else { // Invalid URL format diff --git a/packages/core/src/js/integrations/viewhierarchy.ts b/packages/core/src/js/integrations/viewhierarchy.ts index 9b84ece273..d4d4530b15 100644 --- a/packages/core/src/js/integrations/viewhierarchy.ts +++ b/packages/core/src/js/integrations/viewhierarchy.ts @@ -21,7 +21,7 @@ export const viewHierarchyIntegration = (): Integration => { }; async function processEvent(event: Event, hint: EventHint): Promise { - const hasException = event.exception && event.exception.values && event.exception.values.length > 0; + const hasException = event.exception?.values?.length > 0; if (!hasException) { return event; } diff --git a/packages/core/src/js/options.ts b/packages/core/src/js/options.ts index a95de6df4c..14cc743fc2 100644 --- a/packages/core/src/js/options.ts +++ b/packages/core/src/js/options.ts @@ -234,6 +234,14 @@ export interface BaseReactNativeOptions { */ replaysOnErrorSampleRate?: number; + /** + * Controls how many milliseconds to wait before shutting down. The default is 2 seconds. Setting this too low can cause + * problems for sending events from command line applications. Setting it too + * high can cause the application to block for users with network connectivity + * problems. + */ + shutdownTimeout?: number; + /** * Options which are in beta, or otherwise not guaranteed to be stable. */ diff --git a/packages/core/src/js/profiling/convertHermesProfile.ts b/packages/core/src/js/profiling/convertHermesProfile.ts index 39ed9ac752..6db66dd6d5 100644 --- a/packages/core/src/js/profiling/convertHermesProfile.ts +++ b/packages/core/src/js/profiling/convertHermesProfile.ts @@ -163,7 +163,7 @@ function mapStacks( while (currentHermesFrameId !== undefined) { const sentryFrameId = hermesStackFrameIdToSentryFrameIdMap.get(currentHermesFrameId); sentryFrameId !== undefined && stack.push(sentryFrameId); - currentHermesFrameId = hermesStackFrames[currentHermesFrameId] && hermesStackFrames[currentHermesFrameId].parent; + currentHermesFrameId = hermesStackFrames[currentHermesFrameId]?.parent; } stacks.push(stack); } diff --git a/packages/core/src/js/profiling/integration.ts b/packages/core/src/js/profiling/integration.ts index e2e4134fe6..803c116073 100644 --- a/packages/core/src/js/profiling/integration.ts +++ b/packages/core/src/js/profiling/integration.ts @@ -128,7 +128,7 @@ export const hermesProfilingIntegration = (initOptions: HermesProfilingOptions = } const client = getClient(); - const options = client && client.getOptions(); + const options = client?.getOptions?.(); const profilesSampleRate = options && typeof options.profilesSampleRate === 'number' ? options.profilesSampleRate : undefined; diff --git a/packages/core/src/js/profiling/utils.ts b/packages/core/src/js/profiling/utils.ts index c83342b50b..5c6d996e83 100644 --- a/packages/core/src/js/profiling/utils.ts +++ b/packages/core/src/js/profiling/utils.ts @@ -75,12 +75,12 @@ export function enrichCombinedProfileWithEventContext( return null; } - const trace_id = (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || ''; + const trace_id = event.contexts?.trace?.trace_id || ''; // Log a warning if the profile has an invalid traceId (should be uuidv4). // All profiles and transactions are rejected if this is the case and we want to // warn users that this is happening if they enable debug flag - if (trace_id && trace_id.length !== 32) { + if (trace_id?.length !== 32) { if (__DEV__) { logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`); } @@ -97,25 +97,25 @@ export function enrichCombinedProfileWithEventContext( release: event.release || '', environment: event.environment || getDefaultEnvironment(), os: { - name: (event.contexts && event.contexts.os && event.contexts.os.name) || '', - version: (event.contexts && event.contexts.os && event.contexts.os.version) || '', - build_number: (event.contexts && event.contexts.os && event.contexts.os.build) || '', + name: event.contexts?.os?.name || '', + version: event.contexts?.os?.version || '', + build_number: event.contexts?.os?.build || '', }, device: { - locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '', - model: (event.contexts && event.contexts.device && event.contexts.device.model) || '', - manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '', - architecture: (event.contexts && event.contexts.device && event.contexts.device.arch) || '', - is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false, + locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '', + model: event.contexts?.device?.model || '', + manufacturer: event.contexts?.device?.manufacturer || '', + architecture: event.contexts?.device?.arch || '', + is_emulator: event.contexts?.device?.simulator || false, }, transaction: { name: event.transaction || '', id: event.event_id || '', trace_id, - active_thread_id: (profile.transaction && profile.transaction.active_thread_id) || '', + active_thread_id: profile.transaction?.active_thread_id || '', }, debug_meta: { - images: [...getDebugMetadata(), ...((profile.debug_meta && profile.debug_meta.images) || [])], + images: [...getDebugMetadata(), ...(profile.debug_meta?.images || [])], }, }; } @@ -136,19 +136,15 @@ export function enrichAndroidProfileWithEventContext( build_id: profile.build_id || '', device_cpu_frequencies: [], - device_is_emulator: (event.contexts && event.contexts.device && event.contexts.device.simulator) || false, - device_locale: (event.contexts && event.contexts.device && (event.contexts.device.locale as string)) || '', - device_manufacturer: (event.contexts && event.contexts.device && event.contexts.device.manufacturer) || '', - device_model: (event.contexts && event.contexts.device && event.contexts.device.model) || '', - device_os_name: (event.contexts && event.contexts.os && event.contexts.os.name) || '', - device_os_version: (event.contexts && event.contexts.os && event.contexts.os.version) || '', + device_is_emulator: event.contexts?.device?.simulator || false, + device_locale: (event.contexts?.device && (event.contexts.device.locale as string)) || '', + device_manufacturer: event.contexts?.device?.manufacturer || '', + device_model: event.contexts?.device?.model || '', + device_os_name: event.contexts?.os?.name || '', + device_os_version: event.contexts?.os?.version || '', device_physical_memory_bytes: - (event.contexts && - event.contexts.device && - event.contexts.device.memory_size && - Number(event.contexts.device.memory_size).toString(10)) || - '', + (event.contexts?.device?.memory_size && Number(event.contexts.device.memory_size).toString(10)) || '', environment: event.environment || getDefaultEnvironment(), @@ -161,7 +157,7 @@ export function enrichAndroidProfileWithEventContext( transaction_id: event.event_id || '', transaction_name: event.transaction || '', - trace_id: (event.contexts && event.contexts.trace && event.contexts.trace.trace_id) || '', + trace_id: event.contexts?.trace?.trace_id || '', version_name: event.release || '', version_code: event.dist || '', diff --git a/packages/core/src/js/replay/CustomMask.tsx b/packages/core/src/js/replay/CustomMask.tsx index 4608dfbe04..7d84ec1b8c 100644 --- a/packages/core/src/js/replay/CustomMask.tsx +++ b/packages/core/src/js/replay/CustomMask.tsx @@ -34,7 +34,7 @@ const UnmaskFallback = (viewProps: ViewProps): React.ReactElement => { return ; }; -const hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig && UIManager.hasViewManagerConfig(nativeComponentName); +const hasViewManagerConfig = (nativeComponentName: string): boolean => UIManager.hasViewManagerConfig?.(nativeComponentName); const Mask = ((): HostComponent | React.ComponentType => { if (isExpoGo() || !hasViewManagerConfig(MaskNativeComponentName)) { diff --git a/packages/core/src/js/replay/mobilereplay.ts b/packages/core/src/js/replay/mobilereplay.ts index 4bdfdd7955..d0db1810f4 100644 --- a/packages/core/src/js/replay/mobilereplay.ts +++ b/packages/core/src/js/replay/mobilereplay.ts @@ -103,7 +103,7 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau const options = { ...defaultOptions, ...initOptions }; async function processEvent(event: Event): Promise { - const hasException = event.exception && event.exception.values && event.exception.values.length > 0; + const hasException = event.exception?.values?.length > 0; if (!hasException) { // Event is not an error, will not capture replay return event; diff --git a/packages/core/src/js/sdk.tsx b/packages/core/src/js/sdk.tsx index 5edba50b48..dd6a176322 100644 --- a/packages/core/src/js/sdk.tsx +++ b/packages/core/src/js/sdk.tsx @@ -158,6 +158,7 @@ export function wrap

>( const profilerProps = { ...(options?.profilerProps ?? {}), name: RootComponent.displayName ?? 'Root', + updateProps: {} }; const RootApp: React.FC

= (appProps) => { diff --git a/packages/core/src/js/tools/metroconfig.ts b/packages/core/src/js/tools/metroconfig.ts index e3c71b684f..73c9445b40 100644 --- a/packages/core/src/js/tools/metroconfig.ts +++ b/packages/core/src/js/tools/metroconfig.ts @@ -140,7 +140,7 @@ export function withSentryBabelTransformer( config: MetroConfig, annotateReactComponents: true | { ignoredComponents?: string[] }, ): MetroConfig { - const defaultBabelTransformerPath = config.transformer && config.transformer.babelTransformerPath; + const defaultBabelTransformerPath = config.transformer?.babelTransformerPath; logger.debug('Default Babel transformer path from `config.transformer`:', defaultBabelTransformerPath); if (!defaultBabelTransformerPath) { @@ -270,10 +270,10 @@ export function withSentryFramesCollapsed(config: MetroConfig): MetroConfig { originalCustomization: MetroCustomizeFrame | undefined, ): MetroCustomizeFrame => ({ ...originalCustomization, - collapse: (originalCustomization && originalCustomization.collapse) || collapseSentryInternalFrames(frame), + collapse: originalCustomization?.collapse || collapseSentryInternalFrames(frame), }); - const maybePromiseCustomization = (originalCustomizeFrame && originalCustomizeFrame(frame)) || undefined; + const maybePromiseCustomization = originalCustomizeFrame?.(frame) || undefined; if (maybePromiseCustomization !== undefined && 'then' in maybePromiseCustomization) { return maybePromiseCustomization.then(originalCustomization => diff --git a/packages/core/src/js/tracing/integrations/appStart.ts b/packages/core/src/js/tracing/integrations/appStart.ts index 949ae1e40f..d2a9739e47 100644 --- a/packages/core/src/js/tracing/integrations/appStart.ts +++ b/packages/core/src/js/tracing/integrations/appStart.ts @@ -260,7 +260,7 @@ export const appStartIntegration = ({ return; } - if (!event.contexts || !event.contexts.trace) { + if (!event.contexts?.trace) { logger.warn('[AppStart] Transaction event is missing trace context. Can not attach app start.'); return; } diff --git a/packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts b/packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts index 52cd915634..6f48b4b877 100644 --- a/packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts +++ b/packages/core/src/js/tracing/integrations/timeToDisplayIntegration.ts @@ -54,14 +54,14 @@ export const timeToDisplayIntegration = (): Integration => { }); const ttfdSpan = await addTimeToFullDisplay({ event, rootSpanId, transactionStartTimestampSeconds, ttidSpan }); - if (ttidSpan && ttidSpan.start_timestamp && ttidSpan.timestamp) { + if (ttidSpan?.start_timestamp && ttidSpan?.timestamp) { event.measurements['time_to_initial_display'] = { value: (ttidSpan.timestamp - ttidSpan.start_timestamp) * 1000, unit: 'millisecond', }; } - if (ttfdSpan && ttfdSpan.start_timestamp && ttfdSpan.timestamp) { + if (ttfdSpan?.start_timestamp && ttfdSpan?.timestamp) { const durationMs = (ttfdSpan.timestamp - ttfdSpan.start_timestamp) * 1000; if (isDeadlineExceeded(durationMs)) { event.measurements['time_to_full_display'] = event.measurements['time_to_initial_display']; @@ -117,7 +117,7 @@ async function addTimeToInitialDisplay({ }); } - if (ttidSpan && ttidSpan.status && ttidSpan.status !== 'ok') { + if (ttidSpan?.status && ttidSpan.status !== 'ok') { ttidSpan.status = 'ok'; ttidSpan.timestamp = ttidEndTimestampSeconds; logger.debug(`[${INTEGRATION_NAME}] Updated existing ttid span.`, ttidSpan); @@ -214,7 +214,7 @@ async function addTimeToFullDisplay({ const durationMs = (ttfdAdjustedEndTimestampSeconds - transactionStartTimestampSeconds) * 1000; - if (ttfdSpan && ttfdSpan.status && ttfdSpan.status !== 'ok') { + if (ttfdSpan?.status && ttfdSpan.status !== 'ok') { ttfdSpan.status = 'ok'; ttfdSpan.timestamp = ttfdAdjustedEndTimestampSeconds; logger.debug(`[${INTEGRATION_NAME}] Updated existing ttfd span.`, ttfdSpan); diff --git a/packages/core/src/js/tracing/onSpanEndUtils.ts b/packages/core/src/js/tracing/onSpanEndUtils.ts index 40365b33fd..4ae3c027f6 100644 --- a/packages/core/src/js/tracing/onSpanEndUtils.ts +++ b/packages/core/src/js/tracing/onSpanEndUtils.ts @@ -129,7 +129,7 @@ export const cancelInBackground = (client: Client, span: Span): void => { client.on('spanEnd', (endedSpan: Span) => { if (endedSpan === span) { logger.debug(`Removing AppState listener for ${spanToJSON(span).op} transaction.`); - subscription && subscription.remove && subscription.remove(); + subscription?.remove?.(); } }); }; diff --git a/packages/core/src/js/tracing/reactnativenavigation.ts b/packages/core/src/js/tracing/reactnativenavigation.ts index 0b0f696c68..2ce7ef7f5d 100644 --- a/packages/core/src/js/tracing/reactnativenavigation.ts +++ b/packages/core/src/js/tracing/reactnativenavigation.ts @@ -129,7 +129,7 @@ export const reactNativeNavigationIntegration = ({ } latestNavigationSpan = startGenericIdleNavigationSpan( - tracing && tracing.options.beforeStartSpan + tracing?.options.beforeStartSpan ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions()) : getDefaultIdleNavigationSpanOptions(), idleSpanOptions, diff --git a/packages/core/src/js/tracing/reactnativeprofiler.tsx b/packages/core/src/js/tracing/reactnativeprofiler.tsx index 4eb6604f83..7a302345eb 100644 --- a/packages/core/src/js/tracing/reactnativeprofiler.tsx +++ b/packages/core/src/js/tracing/reactnativeprofiler.tsx @@ -47,10 +47,9 @@ export class ReactNativeProfiler extends Profiler { return; } - client.addIntegration && client.addIntegration(createIntegration(this.name)); + client.addIntegration?.(createIntegration(this.name)); getAppRegistryIntegration(client).onRunApplication(ReactNativeProfilerGlobalState.onRunApplicationHook); - // eslint-disable-next-line @typescript-eslint/no-floating-promises _captureAppStart({ isManual: false }); } diff --git a/packages/core/src/js/tracing/reactnavigation.ts b/packages/core/src/js/tracing/reactnavigation.ts index 58afcf1f4a..8528466d11 100644 --- a/packages/core/src/js/tracing/reactnavigation.ts +++ b/packages/core/src/js/tracing/reactnavigation.ts @@ -241,7 +241,7 @@ export const reactNavigationIntegration = ({ } latestNavigationSpan = startGenericIdleNavigationSpan( - tracing && tracing.options.beforeStartSpan + tracing?.options.beforeStartSpan ? tracing.options.beforeStartSpan(getDefaultIdleNavigationSpanOptions()) : getDefaultIdleNavigationSpanOptions(), idleSpanOptions, diff --git a/packages/core/src/js/tracing/span.ts b/packages/core/src/js/tracing/span.ts index d7909d8d6b..c4b89b8d74 100644 --- a/packages/core/src/js/tracing/span.ts +++ b/packages/core/src/js/tracing/span.ts @@ -1,6 +1,6 @@ import type { Client, Scope, Span, SpanJSON, StartSpanOptions } from '@sentry/core'; import { - generatePropagationContext, + generateTraceId, getActiveSpan, getClient, getCurrentScope, @@ -104,7 +104,7 @@ export const startIdleSpan = ( return new SentryNonRecordingSpan(); } - getCurrentScope().setPropagationContext(generatePropagationContext()); + getCurrentScope().setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() }); const span = coreStartIdleSpan(startSpanOption, { finalTimeout, idleTimeout }); cancelInBackground(client, span); diff --git a/packages/core/src/js/transports/encodePolyfill.ts b/packages/core/src/js/transports/encodePolyfill.ts index 6e84209ed0..3d801561b7 100644 --- a/packages/core/src/js/transports/encodePolyfill.ts +++ b/packages/core/src/js/transports/encodePolyfill.ts @@ -1,3 +1,5 @@ +import { SDK_VERSION } from '@sentry/core'; + import { RN_GLOBAL_OBJ } from '../utils/worldwide'; import { utf8ToBytes } from '../vendor'; @@ -6,7 +8,7 @@ export const useEncodePolyfill = (): void => { (RN_GLOBAL_OBJ.__SENTRY__ as Partial<(typeof RN_GLOBAL_OBJ)['__SENTRY__']>) = {}; } - RN_GLOBAL_OBJ.__SENTRY__.encodePolyfill = encodePolyfill; + RN_GLOBAL_OBJ.__SENTRY__[SDK_VERSION].encodePolyfill = encodePolyfill; }; export const encodePolyfill = (text: string): Uint8Array => { diff --git a/packages/core/src/js/utils/AsyncExpiringMap.ts b/packages/core/src/js/utils/AsyncExpiringMap.ts index 3f3906c9cd..657286ed26 100644 --- a/packages/core/src/js/utils/AsyncExpiringMap.ts +++ b/packages/core/src/js/utils/AsyncExpiringMap.ts @@ -116,7 +116,7 @@ export class AsyncExpiringMap { */ public ttl(key: K): number | undefined { const entry = this._map.get(key); - if (entry && entry.expiresAt) { + if (entry?.expiresAt) { const remainingTime = entry.expiresAt - Date.now(); return remainingTime > 0 ? remainingTime : 0; } diff --git a/packages/core/src/js/utils/envelope.ts b/packages/core/src/js/utils/envelope.ts index f115ca4bd2..ca6cb9a6d0 100644 --- a/packages/core/src/js/utils/envelope.ts +++ b/packages/core/src/js/utils/envelope.ts @@ -22,13 +22,12 @@ export function createUserFeedbackEnvelope( const headers: EventEnvelope[0] = { event_id: feedback.event_id, sent_at: new Date().toISOString(), - ...(metadata && - metadata.sdk && { - sdk: { - name: metadata.sdk.name, - version: metadata.sdk.version, - }, - }), + ...(metadata?.sdk && { + sdk: { + name: metadata.sdk.name, + version: metadata.sdk.version, + }, + }), ...(!!tunnel && !!dsn && { dsn: dsnToString(dsn) }), }; const item = createUserFeedbackEnvelopeItem(feedback); diff --git a/packages/core/src/js/utils/environment.ts b/packages/core/src/js/utils/environment.ts index 214532b031..ad19462a18 100644 --- a/packages/core/src/js/utils/environment.ts +++ b/packages/core/src/js/utils/environment.ts @@ -36,7 +36,7 @@ export function isExpo(): boolean { /** Check if JS runs in Expo Go */ export function isExpoGo(): boolean { const expoConstants = getExpoConstants(); - return (expoConstants && expoConstants.appOwnership) === 'expo'; + return expoConstants?.appOwnership === 'expo'; } /** Check Expo Go version if available */ @@ -75,11 +75,7 @@ export function notMobileOs(): boolean { /** Returns Hermes Version if hermes is present in the runtime */ export function getHermesVersion(): string | undefined { - return ( - RN_GLOBAL_OBJ.HermesInternal && - RN_GLOBAL_OBJ.HermesInternal.getRuntimeProperties && - RN_GLOBAL_OBJ.HermesInternal.getRuntimeProperties()['OSS Release Version'] - ); + return RN_GLOBAL_OBJ.HermesInternal?.getRuntimeProperties?.()['OSS Release Version']; } /** Returns default environment based on __DEV__ */ @@ -91,8 +87,7 @@ export function getDefaultEnvironment(): 'development' | 'production' { export function isRunningInMetroDevServer(): boolean { if ( typeof RN_GLOBAL_OBJ.process !== 'undefined' && - RN_GLOBAL_OBJ.process.env && - RN_GLOBAL_OBJ.process.env.___SENTRY_METRO_DEV_SERVER___ === 'true' + RN_GLOBAL_OBJ.process.env?.___SENTRY_METRO_DEV_SERVER___ === 'true' ) { return true; } diff --git a/packages/core/src/js/utils/expomodules.ts b/packages/core/src/js/utils/expomodules.ts index 349c454d9d..73d4ea7f1e 100644 --- a/packages/core/src/js/utils/expomodules.ts +++ b/packages/core/src/js/utils/expomodules.ts @@ -5,14 +5,12 @@ import { RN_GLOBAL_OBJ } from './worldwide'; * Returns the Expo Constants module if present */ export function getExpoConstants(): ExpoConstants | undefined { - return ( - (RN_GLOBAL_OBJ.expo && RN_GLOBAL_OBJ.expo.modules && RN_GLOBAL_OBJ.expo.modules.ExponentConstants) || undefined - ); + return RN_GLOBAL_OBJ.expo?.modules?.ExponentConstants || undefined; } /** * Returns the Expo Device module if present */ export function getExpoDevice(): ExpoDevice | undefined { - return (RN_GLOBAL_OBJ.expo && RN_GLOBAL_OBJ.expo.modules && RN_GLOBAL_OBJ.expo.modules.ExpoDevice) || undefined; + return RN_GLOBAL_OBJ.expo?.modules?.ExpoDevice || undefined; } diff --git a/packages/core/src/js/wrapper.ts b/packages/core/src/js/wrapper.ts index 598ea7c9db..31152c02b2 100644 --- a/packages/core/src/js/wrapper.ts +++ b/packages/core/src/js/wrapper.ts @@ -37,7 +37,7 @@ import { base64StringFromByteArray, utf8ToBytes } from './vendor'; */ export function getRNSentryModule(): Spec | undefined { return isTurboModuleEnabled() - ? ReactNativeLibraries.TurboModuleRegistry && ReactNativeLibraries.TurboModuleRegistry.get('RNSentry') + ? ReactNativeLibraries.TurboModuleRegistry?.get('RNSentry') : NativeModules.RNSentry; } diff --git a/packages/core/test/feedback.test.ts b/packages/core/test/feedback.test.ts index 6b1831934d..f25bc4eec1 100644 --- a/packages/core/test/feedback.test.ts +++ b/packages/core/test/feedback.test.ts @@ -240,17 +240,17 @@ describe('captureFeedback', () => { const mockTransport = jest.spyOn(client.getTransport()!, 'send'); const traceId = '4C79F60C11214EB38604F4AE0781BFB2'; - const spanId = 'FA90FDEAD5F74052'; + const parentSpanId = 'FA90FDEAD5F74052'; const dsc = { trace_id: traceId, - span_id: spanId, sampled: 'true', }; getCurrentScope().setPropagationContext({ traceId, - spanId, + parentSpanId, dsc, + sampleRand: 1, }); const eventId = captureFeedback({ @@ -264,7 +264,7 @@ describe('captureFeedback', () => { expect(mockTransport).toHaveBeenCalledWith([ { event_id: eventId, - sent_at: expect.any(String), + sent_at: expect.toBeDateString(), }, [ [ @@ -274,7 +274,8 @@ describe('captureFeedback', () => { contexts: { trace: { trace_id: traceId, - span_id: spanId, + parent_span_id: parentSpanId, + span_id: expect.any(String), }, feedback: { message: 'test', @@ -297,7 +298,7 @@ describe('captureFeedback', () => { getDefaultTestClientOptions({ dsn: 'https://dsn@ingest.f00.f00/1', enableSend: true, - enableTracing: true, + tracesSampleRate: 1.0, // We don't care about transactions here... beforeSendTransaction() { return null; @@ -322,12 +323,12 @@ describe('captureFeedback', () => { expect(typeof eventId).toBe('string'); expect(span).toBeDefined(); - const { spanId, traceId } = span!.spanContext(); + const traceId = span!.spanContext().traceId; expect(mockTransport).toHaveBeenCalledWith([ { event_id: eventId, - sent_at: expect.any(String), + sent_at: expect.toBeDateString(), }, [ [ @@ -337,7 +338,7 @@ describe('captureFeedback', () => { contexts: { trace: { trace_id: traceId, - span_id: spanId, + span_id: expect.any(String), }, feedback: { message: 'test', @@ -360,7 +361,7 @@ describe('captureFeedback', () => { getDefaultTestClientOptions({ dsn: 'https://dsn@ingest.f00.f00/1', enableSend: true, - enableTracing: true, + tracesSampleRate: 1.0, // We don't care about transactions here... beforeSendTransaction() { return null; diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 8a0df75ebc..8db8b51dec 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -88,7 +88,7 @@ export class TestClient extends BaseClient { super.sendEvent(event, hint); return; } - TestClient.sendEventCalled && TestClient.sendEventCalled(event); + TestClient.sendEventCalled?.(event); } public sendSession(session: Session): void { diff --git a/packages/core/test/profiling/integration.test.ts b/packages/core/test/profiling/integration.test.ts index 7462d94c6e..d845aa9f57 100644 --- a/packages/core/test/profiling/integration.test.ts +++ b/packages/core/test/profiling/integration.test.ts @@ -344,7 +344,7 @@ function initTestClient( const transportSendMock = jest.fn, Parameters>(); const options: Sentry.ReactNativeOptions = { dsn: MOCK_DSN, - enableTracing: true, + tracesSampleRate: 1.0, enableNativeFramesTracking: false, profilesSampleRate: 1, integrations: integrations => { @@ -430,5 +430,5 @@ function addIntegrationAndForceSetupOnce(integration: Integration): void { } client.addIntegration(integration); - integration.setupOnce && integration.setupOnce(); + integration.setupOnce?.(); } diff --git a/packages/core/test/tracing/addTracingExtensions.test.ts b/packages/core/test/tracing/addTracingExtensions.test.ts index 4d4c5384c3..bb074e36ee 100644 --- a/packages/core/test/tracing/addTracingExtensions.test.ts +++ b/packages/core/test/tracing/addTracingExtensions.test.ts @@ -1,3 +1,4 @@ +import type { Span } from '@sentry/core'; import { getCurrentScope, spanToJSON, startSpanManual } from '@sentry/core'; import { reactNativeTracingIntegration } from '../../src/js'; @@ -55,9 +56,12 @@ describe('Tracing extensions', () => { }); test('transaction start span passes correct values to the child', async () => { - const transaction = startSpanManual({ name: 'parent', op: 'custom', scope: getCurrentScope() }, span => span); - const span = startSpanManual({ name: 'child', scope: getCurrentScope() }, span => span); - span!.end(); + let childSpan: Span = undefined; + const transaction = startSpanManual({ name: 'parent', op: 'custom', scope: getCurrentScope() }, _span => { + childSpan = startSpanManual({ name: 'child', scope: getCurrentScope() }, __span => __span); + return _span; + }); + childSpan!.end(); transaction!.end(); await client.flush(); @@ -70,9 +74,9 @@ describe('Tracing extensions', () => { }), }), ); - expect(spanToJSON(span!)).toEqual( + expect(spanToJSON(childSpan!)).toEqual( expect.objectContaining({ - parent_span_id: transaction!.spanContext().spanId, + parent_span_id: spanToJSON(transaction!).span_id, }), ); }); diff --git a/packages/core/test/tracing/integrations/appStart.test.ts b/packages/core/test/tracing/integrations/appStart.test.ts index 8ae6a63ef0..85d87160a1 100644 --- a/packages/core/test/tracing/integrations/appStart.test.ts +++ b/packages/core/test/tracing/integrations/appStart.test.ts @@ -839,6 +839,7 @@ function getMinimalTransactionEvent({ description: 'Test', span_id: '123', trace_id: '456', + data: {}, }, ], }; @@ -893,6 +894,7 @@ function expectEventWithAttachedColdAppStart({ description: 'Test', span_id: '123', trace_id: '456', + data: {}, }, ]), }); @@ -947,6 +949,7 @@ function expectEventWithAttachedWarmAppStart({ description: 'Test', span_id: '123', trace_id: '456', + data: {}, }, ]), }); diff --git a/packages/core/test/tracing/integrations/userInteraction.test.ts b/packages/core/test/tracing/integrations/userInteraction.test.ts index a026e79c0e..1f86614c36 100644 --- a/packages/core/test/tracing/integrations/userInteraction.test.ts +++ b/packages/core/test/tracing/integrations/userInteraction.test.ts @@ -255,15 +255,20 @@ describe('User Interaction Tracing', () => { }); test('do not start UI event transaction if active transaction on scope', () => { - const activeTransaction = startSpanManual( - { name: 'activeTransactionOnScope', scope: getCurrentScope() }, - (span: Span) => span, - ); - expect(activeTransaction).toBeDefined(); - expect(activeTransaction).toBe(getActiveSpan()); + const placeholderCallback: (span: Span, finish: () => void) => void = (span, finish) => { + // @ts-expect-error no direct access to _name + expect(span._name).toBe('activeTransactionOnScope'); - startUserInteractionSpan(mockedUserInteractionId); - expect(activeTransaction).toBe(getActiveSpan()); + expect(span).toBe(getActiveSpan()); + + startUserInteractionSpan(mockedUserInteractionId); + + expect(span).toBe(getActiveSpan()); + + finish(); + }; + + startSpanManual({ name: 'activeTransactionOnScope', scope: getCurrentScope() }, placeholderCallback); }); test('UI event transaction is canceled when routing transaction starts', () => { diff --git a/packages/core/test/tracing/reactnavigation.ttid.test.tsx b/packages/core/test/tracing/reactnavigation.ttid.test.tsx index 6ab972f3d8..ba01506feb 100644 --- a/packages/core/test/tracing/reactnavigation.ttid.test.tsx +++ b/packages/core/test/tracing/reactnavigation.ttid.test.tsx @@ -678,7 +678,7 @@ function initSentry(sut: ReturnType): const transportSendMock = jest.fn, Parameters>(); const options: Sentry.ReactNativeOptions = { dsn: MOCK_DSN, - enableTracing: true, + tracesSampleRate: 1.0, enableStallTracking: false, integrations: [ sut, diff --git a/packages/core/test/tracing/timetodisplaynative.web.test.tsx b/packages/core/test/tracing/timetodisplaynative.web.test.tsx index 507c33a745..c60dad0a75 100644 --- a/packages/core/test/tracing/timetodisplaynative.web.test.tsx +++ b/packages/core/test/tracing/timetodisplaynative.web.test.tsx @@ -1,6 +1,9 @@ jest.mock('react-native', () => { const RN = jest.requireActual('react-native'); + // Fixes TypeError: Cannot set property UIManager of # which has only a getter + delete RN.UIManager; RN.UIManager = {}; + return RN; }); diff --git a/packages/core/test/utils/safe.test.ts b/packages/core/test/utils/safe.test.ts index 89e063bd35..0e781ef313 100644 --- a/packages/core/test/utils/safe.test.ts +++ b/packages/core/test/utils/safe.test.ts @@ -38,14 +38,31 @@ describe('safe', () => { test('calls given function with correct args', () => { const mockFn = jest.fn(); const actualSafeFunction = safeTracesSampler(mockFn); - actualSafeFunction?.({ name: 'foo', transactionContext: { name: 'foo' } }); + const expectedInheritOrSampleWith = function (fallbackSampleRate: number): number { + return fallbackSampleRate; + }; + actualSafeFunction?.({ + name: 'foo', + transactionContext: { name: 'foo' }, + inheritOrSampleWith: expectedInheritOrSampleWith, + }); expect(mockFn).toBeCalledTimes(1); - expect(mockFn).toBeCalledWith({ name: 'foo', transactionContext: { name: 'foo' } }); + expect(mockFn).toBeCalledWith({ + name: 'foo', + transactionContext: { name: 'foo' }, + inheritOrSampleWith: expectedInheritOrSampleWith, + }); }); test('calls given function amd return its result', () => { const mockFn = jest.fn(() => 0.5); const actualSafeFunction = safeTracesSampler(mockFn); - const actualResult = actualSafeFunction?.({ name: 'foo', transactionContext: { name: 'foo' } }); + const actualResult = actualSafeFunction?.({ + name: 'foo', + transactionContext: { name: 'foo' }, + inheritOrSampleWith: function (fallbackSampleRate: number): number { + return fallbackSampleRate; + }, + }); expect(mockFn).toBeCalledTimes(1); expect(actualResult).toBe(0.5); }); @@ -58,7 +75,13 @@ describe('safe', () => { throw 'Test error'; }); const actualSafeFunction = safeTracesSampler(mockFn); - const actualResult = actualSafeFunction?.({ name: 'foo', transactionContext: { name: 'foo' } }); + const actualResult = actualSafeFunction?.({ + name: 'foo', + transactionContext: { name: 'foo' }, + inheritOrSampleWith: function (fallbackSampleRate: number): number { + return fallbackSampleRate; + }, + }); expect(mockFn).toBeCalledTimes(1); expect(actualResult).toEqual(0); }); diff --git a/samples/react-native-macos/package.json b/samples/react-native-macos/package.json index 302c961d7a..2938c0dde6 100644 --- a/samples/react-native-macos/package.json +++ b/samples/react-native-macos/package.json @@ -16,8 +16,8 @@ "@react-navigation/bottom-tabs": "^6.5.12", "@react-navigation/native": "^6.1.9", "@react-navigation/stack": "^6.3.20", - "@sentry/core": "8.54.0", - "@sentry/react": "8.54.0", + "@sentry/core": "9.1.0", + "@sentry/react": "9.1.0", "@sentry/react-native": "6.11.0-beta.0", "delay": "^6.0.0", "react": "18.2.0", diff --git a/samples/react-native/package.json b/samples/react-native/package.json index 2d73447025..58464514df 100644 --- a/samples/react-native/package.json +++ b/samples/react-native/package.json @@ -27,7 +27,7 @@ "@react-navigation/native": "^7.0.14", "@react-navigation/native-stack": "^7.2.0", "@react-navigation/stack": "^7.1.1", - "@sentry/core": "8.54.0", + "@sentry/core": "9.1.0", "@sentry/react-native": "6.11.0-beta.0", "@shopify/flash-list": "^1.7.3", "axios": "^1.8.3", @@ -74,7 +74,7 @@ "prettier": "2.8.8", "react-test-renderer": "18.3.1", "sentry-react-native-samples-utils": "workspace:^", - "ts-jest": "^29.2.5", + "ts-jest": "^29.3.1", "typescript": "5.0.4" }, "engines": { diff --git a/yarn.lock b/yarn.lock index 9409d0faac..1b8d925c7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7855,21 +7855,21 @@ __metadata: languageName: node linkType: hard -"@sentry-internal/browser-utils@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/browser-utils@npm:8.54.0" +"@sentry-internal/browser-utils@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/browser-utils@npm:9.1.0" dependencies: - "@sentry/core": 8.54.0 - checksum: a6dc51bcf0b6029ebb49dd3478bd216da5aac118512ae247a3fa4c61b809a6caa27ee1531dc49cdab18f340f6a0cb337cc160c217e6af60060cb50aa2ab15abd + "@sentry/core": 9.1.0 + checksum: 08c6b383fe2256d367469269d15f454f9a1345f9ae49ae63682265f0052821b259728907afc3c231186953cca14d08b43a2386fe3e984338f988ae9ae8175064 languageName: node linkType: hard -"@sentry-internal/eslint-config-sdk@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/eslint-config-sdk@npm:8.54.0" +"@sentry-internal/eslint-config-sdk@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/eslint-config-sdk@npm:9.1.0" dependencies: - "@sentry-internal/eslint-plugin-sdk": 8.54.0 - "@sentry-internal/typescript": 8.54.0 + "@sentry-internal/eslint-plugin-sdk": 9.1.0 + "@sentry-internal/typescript": 9.1.0 "@typescript-eslint/eslint-plugin": ^5.48.0 "@typescript-eslint/parser": ^5.48.0 eslint-config-prettier: ^6.11.0 @@ -7880,43 +7880,43 @@ __metadata: eslint-plugin-simple-import-sort: ^5.0.3 peerDependencies: eslint: ">=5" - checksum: 4b4ed9e455517ab9ca90f0d9ab8f9a27342dd2635cd3464bda6b06430ab44028c421f4c7a214a034c20514e950380cd7f37f825a0a60d5b6c07d5e7040cbc1b3 + checksum: aef3a7b34b32202303dcc9d75f213a37d471354673bdfd97d31f8909e3e24ffe0d7dff595097c9a0055a5f9addbc91758ea667ca82206368f687a85d669295b3 languageName: node linkType: hard -"@sentry-internal/eslint-plugin-sdk@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/eslint-plugin-sdk@npm:8.54.0" - checksum: b9f3d9512df82d1e9cbef100b2f19626a1ede9b25eee6ff1f0e163f74f087a9de6dc6705c58c01cedd4b1782b2db31f8c158ee8a05552db8b49315c3917b9d92 +"@sentry-internal/eslint-plugin-sdk@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/eslint-plugin-sdk@npm:9.1.0" + checksum: 28eab0a957912dbc82c2b308af84a9105b23eb66f582134f14132dec68de114de196114b8ecdef75fd1b91ee4691735d2760585c512775d0d691b45fc09650a3 languageName: node linkType: hard -"@sentry-internal/feedback@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/feedback@npm:8.54.0" +"@sentry-internal/feedback@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/feedback@npm:9.1.0" dependencies: - "@sentry/core": 8.54.0 - checksum: e99ca3997609deba59af450b6298dc5125cc7633a59751632cf3b4a7cf12f097cc3ffa9424c483489a0d232a6c577479fe5496355e6a5c2b3ada0c7aa72e7251 + "@sentry/core": 9.1.0 + checksum: 4f0b3335e391d55ffdcac56bfbcbf9fa62ba865ab75c97daf6904cca6f5ea4cce156a78adddd81d3bd4119f9bd8c81e5bb18d330f61c77800cd911c74f776689 languageName: node linkType: hard -"@sentry-internal/replay-canvas@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/replay-canvas@npm:8.54.0" +"@sentry-internal/replay-canvas@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/replay-canvas@npm:9.1.0" dependencies: - "@sentry-internal/replay": 8.54.0 - "@sentry/core": 8.54.0 - checksum: ed11de4c3503833d1e3503e521d0945eb393e16c6e5a2da3b5eae8632540a96530e465e8b6947879440ef19aba5f0d13ce36c4400955fcb310de2882c8610887 + "@sentry-internal/replay": 9.1.0 + "@sentry/core": 9.1.0 + checksum: 413fd391dcb0bdae64ce70ea1b37f5935d9449a44172d98363eda64385775573b444ec5e56e700445c20f53ca8a7bca6157889732c5985b6450d5f0f09c3abc3 languageName: node linkType: hard -"@sentry-internal/replay@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/replay@npm:8.54.0" +"@sentry-internal/replay@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/replay@npm:9.1.0" dependencies: - "@sentry-internal/browser-utils": 8.54.0 - "@sentry/core": 8.54.0 - checksum: 2d46529612cb279ef53e8fb0f96d9da7b0526e9c3990af27620cb1f10a3f66b81966121d904da08b4ad07c0ae162230dfa39a9572127033b62ca2aae9b9008d8 + "@sentry-internal/browser-utils": 9.1.0 + "@sentry/core": 9.1.0 + checksum: 11ef5a88d3bafd2b5143a150af7b0c77af521a17bf48e1840b2fd2116c55e7acd49ddce3618a1191ccc11b8b38e70ab8c59a030a90557c21499e2e815ce184fb languageName: node linkType: hard @@ -7931,12 +7931,19 @@ __metadata: languageName: node linkType: hard -"@sentry-internal/typescript@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry-internal/typescript@npm:8.54.0" +"@sentry-internal/typescript@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry-internal/typescript@npm:9.1.0" peerDependencies: - typescript: 4.9.5 - checksum: 83cfd303f34dbc5e70fc18e0af788ae37cdc0635258c082924e022b44177bac5c9c589448b368fbeeafb282a22623b5a6ea0e5ef3140c3f54fce1ac222e1920b + typescript: ~5.0.0 + checksum: 76bc7fefc76af9000b3f78f5270349f844261f079775753c36aa46e78dea963c89dbfdeddf4bd36b6c5fc197b4415f9c1883a38287fa4d6a90ded51ae5e97f25 + languageName: node + linkType: hard + +"@sentry/babel-plugin-component-annotate@npm:3.1.2": + version: 3.1.2 + resolution: "@sentry/babel-plugin-component-annotate@npm:3.1.2" + checksum: 4e957d44dde3eacc60d6d33d28523fa16775e3c05603defc9268ad7209ce06da9dba50243e637f64cb12d7bb302b46584dd815754805210517a3b4da91af2c91 languageName: node linkType: hard @@ -7947,16 +7954,16 @@ __metadata: languageName: node linkType: hard -"@sentry/browser@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry/browser@npm:8.54.0" +"@sentry/browser@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry/browser@npm:9.1.0" dependencies: - "@sentry-internal/browser-utils": 8.54.0 - "@sentry-internal/feedback": 8.54.0 - "@sentry-internal/replay": 8.54.0 - "@sentry-internal/replay-canvas": 8.54.0 - "@sentry/core": 8.54.0 - checksum: b125b194877cbdefc76884f6b1b7995d0949f7e7e5c4283c69f01071656df0e571bd0ac1cf1bb47f89f268370dd8b69126db44e2949ee5176a043e615c5bc7e0 + "@sentry-internal/browser-utils": 9.1.0 + "@sentry-internal/feedback": 9.1.0 + "@sentry-internal/replay": 9.1.0 + "@sentry-internal/replay-canvas": 9.1.0 + "@sentry/core": 9.1.0 + checksum: 782ce1b01d3719c0047a2bc5bf3ef0463188a70224109562c6d22341d4fb647992775b2f62a2b45e0a185fb1c4cab49f07298b67c2c290e87e281405f6af8a4c languageName: node linkType: hard @@ -8066,10 +8073,10 @@ __metadata: languageName: node linkType: hard -"@sentry/core@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry/core@npm:8.54.0" - checksum: ad7165a0bc56918cf8b8e5e15c4ceed11358970d8bf4c587a0fb05d8bd2759ee1d965da2a51e705e0e0aaf3a84150ecbf3bd647bfa0dd32bc723b28b91d46a66 +"@sentry/core@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry/core@npm:9.1.0" + checksum: 81713903ab3be8940eae23f22a4efe753f4c14e10f618c0bd79128028dde0810909a93b23a87407658010d5097a620e31ccb91ca50b86ee7eb69a26d80a747f3 languageName: node linkType: hard @@ -8106,16 +8113,15 @@ __metadata: "@expo/metro-config": 0.19.5 "@mswjs/interceptors": ^0.25.15 "@react-native/babel-preset": 0.77.1 - "@sentry-internal/eslint-config-sdk": 8.54.0 - "@sentry-internal/eslint-plugin-sdk": 8.54.0 - "@sentry-internal/typescript": 8.54.0 - "@sentry/babel-plugin-component-annotate": 3.2.4 - "@sentry/browser": 8.54.0 + "@sentry-internal/eslint-config-sdk": 9.1.0 + "@sentry-internal/eslint-plugin-sdk": 9.1.0 + "@sentry-internal/typescript": 9.1.0 + "@sentry/babel-plugin-component-annotate": 3.1.2 + "@sentry/browser": 9.1.0 "@sentry/cli": 2.43.0 - "@sentry/core": 8.54.0 - "@sentry/react": 8.54.0 - "@sentry/types": 8.54.0 - "@sentry/utils": 8.54.0 + "@sentry/core": 9.1.0 + "@sentry/react": 9.1.0 + "@sentry/types": 9.1.0 "@sentry/wizard": 4.6.0 "@testing-library/react-native": ^12.7.2 "@types/jest": ^29.5.13 @@ -8145,7 +8151,7 @@ __metadata: react-native: 0.77.1 react-test-renderer: ^18.3.1 rimraf: ^4.1.1 - ts-jest: ^29.1.1 + ts-jest: ^29.3.1 typescript: 4.9.5 uglify-js: ^3.17.4 uuid: ^9.0.1 @@ -8162,16 +8168,16 @@ __metadata: languageName: unknown linkType: soft -"@sentry/react@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry/react@npm:8.54.0" +"@sentry/react@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry/react@npm:9.1.0" dependencies: - "@sentry/browser": 8.54.0 - "@sentry/core": 8.54.0 + "@sentry/browser": 9.1.0 + "@sentry/core": 9.1.0 hoist-non-react-statics: ^3.3.2 peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x - checksum: 6f6d12f4db77f137b7b4361bfe298f9eba19b865e56701f7ba336ffedada683bd4baa962747f8b96a91d3399b1317206689e8a7565fb06b930b71440cd8a00a1 + checksum: 670cfde6f966079e4224bba0a5020f059f7c2c99e2bdd9f4163b0fbb367cb29e407de671be4dac1a684f18a80ae0c65ef0c179143e1772ef3dcc258c80d01ae8 languageName: node linkType: hard @@ -8182,12 +8188,12 @@ __metadata: languageName: node linkType: hard -"@sentry/types@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry/types@npm:8.54.0" +"@sentry/types@npm:9.1.0": + version: 9.1.0 + resolution: "@sentry/types@npm:9.1.0" dependencies: - "@sentry/core": 8.54.0 - checksum: 948095843efa280ee1a1dad5ac6dc20688395c25b344860d22505de14a10b1f873bcbeaaf32ba8506955a789a9c0fb0df4e80b93dfee21b1847423e954d0e616 + "@sentry/core": 9.1.0 + checksum: 9193a6ba72efaaa2605301d0dd54651e240c02e380ce89fc402945a70b5d1da85a4a4f562d9ac99e9e8e64dc988a59ce3b9bbc88be2cd47590acb6ae019e7080 languageName: node linkType: hard @@ -8200,15 +8206,6 @@ __metadata: languageName: node linkType: hard -"@sentry/utils@npm:8.54.0": - version: 8.54.0 - resolution: "@sentry/utils@npm:8.54.0" - dependencies: - "@sentry/core": 8.54.0 - checksum: 063c31528f4d3d0f17be18050c84fad12a8a62fde97ca8e0e10c0cc01323e644d8d1cbba4b95b20de5d62eaee23ba43ae51b479057da4fd59dbccd49ac97277a - languageName: node - linkType: hard - "@sentry/wizard@npm:4.6.0": version: 4.6.0 resolution: "@sentry/wizard@npm:4.6.0" @@ -24505,7 +24502,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.3, semver@npm:7.x, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:~7.6.3": +"semver@npm:7.6.3, semver@npm:7.x, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:~7.6.3": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -24523,6 +24520,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.7.1": + version: 7.7.1 + resolution: "semver@npm:7.7.1" + bin: + semver: bin/semver.js + checksum: 586b825d36874007c9382d9e1ad8f93888d8670040add24a28e06a910aeebd673a2eb9e3bf169c6679d9245e66efb9057e0852e70d9daa6c27372aab1dda7104 + languageName: node + linkType: hard + "send@npm:0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -24592,7 +24598,7 @@ __metadata: dependencies: "@babel/preset-env": ^7.25.3 "@babel/preset-typescript": ^7.18.6 - "@sentry/core": 8.54.0 + "@sentry/core": 9.1.0 "@sentry/react-native": 6.11.0-beta.0 "@types/node": ^20.9.3 "@types/react": ^18.2.64 @@ -24658,8 +24664,8 @@ __metadata: "@react-navigation/bottom-tabs": ^6.5.12 "@react-navigation/native": ^6.1.9 "@react-navigation/stack": ^6.3.20 - "@sentry/core": 8.54.0 - "@sentry/react": 8.54.0 + "@sentry/core": 9.1.0 + "@sentry/react": 9.1.0 "@sentry/react-native": 6.11.0-beta.0 "@types/react": ^18.2.65 "@types/react-native-vector-icons": ^6.4.18 @@ -24706,7 +24712,7 @@ __metadata: "@react-navigation/native-stack": ^7.2.0 "@react-navigation/stack": ^7.1.1 "@sentry/babel-plugin-component-annotate": 3.2.4 - "@sentry/core": 8.54.0 + "@sentry/core": 9.1.0 "@sentry/react-native": 6.11.0-beta.0 "@shopify/flash-list": ^1.7.3 "@types/jest": ^29.5.14 @@ -24740,7 +24746,7 @@ __metadata: react-test-renderer: 18.3.1 redux: ^4.2.1 sentry-react-native-samples-utils: "workspace:^" - ts-jest: ^29.2.5 + ts-jest: ^29.3.1 typescript: 5.0.4 languageName: unknown linkType: soft @@ -26318,19 +26324,20 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.1.1, ts-jest@npm:^29.2.5": - version: 29.2.5 - resolution: "ts-jest@npm:29.2.5" +"ts-jest@npm:^29.3.1": + version: 29.3.1 + resolution: "ts-jest@npm:29.3.1" dependencies: - bs-logger: "npm:^0.2.6" - ejs: "npm:^3.1.10" - fast-json-stable-stringify: "npm:^2.1.0" - jest-util: "npm:^29.0.0" - json5: "npm:^2.2.3" - lodash.memoize: "npm:^4.1.2" - make-error: "npm:^1.3.6" - semver: "npm:^7.6.3" - yargs-parser: "npm:^21.1.1" + bs-logger: ^0.2.6 + ejs: ^3.1.10 + fast-json-stable-stringify: ^2.1.0 + jest-util: ^29.0.0 + json5: ^2.2.3 + lodash.memoize: ^4.1.2 + make-error: ^1.3.6 + semver: ^7.7.1 + type-fest: ^4.38.0 + yargs-parser: ^21.1.1 peerDependencies: "@babel/core": ">=7.0.0-beta.0 <8" "@jest/transform": ^29.0.0 @@ -26351,7 +26358,7 @@ __metadata: optional: true bin: ts-jest: cli.js - checksum: d60d1e1d80936f6002b1bb27f7e062408bc733141b9d666565503f023c340a3196d506c836a4316c5793af81a5f910ab49bb9c13f66e2dc66de4e0f03851dbca + checksum: 7320bbfab2e2cc7d5308fadcfe486d24ffc0018f92bf05946cd3ac75888977ec52887b2beaa99ec5ee3d67b8636b56a1688db447fd2794eeefc498862e850f77 languageName: node linkType: hard @@ -26603,6 +26610,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.38.0": + version: 4.39.1 + resolution: "type-fest@npm:4.39.1" + checksum: 71ce0e25822d5d984c8882e3243c42c741f089c003d89222dc361a133698d8ac021c18a9139ba3baf0fee2f523383422b8c5aaa390b1b3a98140f23dd0f44795 + languageName: node + linkType: hard + "type-fest@npm:^4.4.0": version: 4.26.0 resolution: "type-fest@npm:4.26.0"