diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e63591f4bc99..877240d8716f 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,6 +2,7 @@ export type { ClientClass } from './sdk'; export type { Carrier, Layer } from './hub'; export type { OfflineStore, OfflineTransportOptions } from './transports/offline'; +export * from './tracing'; export { addBreadcrumb, captureException, diff --git a/packages/tracing/src/hubextensions.ts b/packages/core/src/tracing/hubextensions.ts similarity index 77% rename from packages/tracing/src/hubextensions.ts rename to packages/core/src/tracing/hubextensions.ts index 9514cb00b321..6770a2aa9c5c 100644 --- a/packages/tracing/src/hubextensions.ts +++ b/packages/core/src/tracing/hubextensions.ts @@ -1,17 +1,8 @@ -import type { Hub } from '@sentry/core'; -import { getMainCarrier } from '@sentry/core'; -import type { - ClientOptions, - CustomSamplingContext, - Integration, - IntegrationClass, - Options, - SamplingContext, - TransactionContext, -} from '@sentry/types'; -import { dynamicRequire, isNaN, isNodeEnv, loadModule, logger } from '@sentry/utils'; +import type { ClientOptions, CustomSamplingContext, Options, SamplingContext, TransactionContext } from '@sentry/types'; +import { isNaN, logger } from '@sentry/utils'; -import { registerErrorInstrumentation } from './errors'; +import type { Hub } from '../'; +import { getMainCarrier } from '../'; import { IdleTransaction } from './idletransaction'; import { Transaction } from './transaction'; import { hasTracingEnabled } from './utils'; @@ -220,9 +211,9 @@ export function startIdleTransaction( } /** - * @private + * Adds tracing extensions to the global hub. */ -export function _addTracingExtensions(): void { +export function addTracingExtensions(): void { const carrier = getMainCarrier(); if (!carrier.__SENTRY__) { return; @@ -235,70 +226,3 @@ export function _addTracingExtensions(): void { carrier.__SENTRY__.extensions.traceHeaders = traceHeaders; } } - -/** - * @private - */ -function _autoloadDatabaseIntegrations(): void { - const carrier = getMainCarrier(); - if (!carrier.__SENTRY__) { - return; - } - - const packageToIntegrationMapping: Record Integration> = { - mongodb() { - const integration = dynamicRequire(module, './integrations/node/mongo') as { - Mongo: IntegrationClass; - }; - return new integration.Mongo(); - }, - mongoose() { - const integration = dynamicRequire(module, './integrations/node/mongo') as { - Mongo: IntegrationClass; - }; - return new integration.Mongo({ mongoose: true }); - }, - mysql() { - const integration = dynamicRequire(module, './integrations/node/mysql') as { - Mysql: IntegrationClass; - }; - return new integration.Mysql(); - }, - pg() { - const integration = dynamicRequire(module, './integrations/node/postgres') as { - Postgres: IntegrationClass; - }; - return new integration.Postgres(); - }, - }; - - const mappedPackages = Object.keys(packageToIntegrationMapping) - .filter(moduleName => !!loadModule(moduleName)) - .map(pkg => { - try { - return packageToIntegrationMapping[pkg](); - } catch (e) { - return undefined; - } - }) - .filter(p => p) as Integration[]; - - if (mappedPackages.length > 0) { - carrier.__SENTRY__.integrations = [...(carrier.__SENTRY__.integrations || []), ...mappedPackages]; - } -} - -/** - * This patches the global object and injects the Tracing extensions methods - */ -export function addExtensionMethods(): void { - _addTracingExtensions(); - - // Detect and automatically load specified integrations. - if (isNodeEnv()) { - _autoloadDatabaseIntegrations(); - } - - // If an error happens globally, we should make sure transaction status is set to error. - registerErrorInstrumentation(); -} diff --git a/packages/tracing/src/idletransaction.ts b/packages/core/src/tracing/idletransaction.ts similarity index 96% rename from packages/tracing/src/idletransaction.ts rename to packages/core/src/tracing/idletransaction.ts index 395b116481b1..f1274c709cc8 100644 --- a/packages/tracing/src/idletransaction.ts +++ b/packages/core/src/tracing/idletransaction.ts @@ -1,15 +1,17 @@ /* eslint-disable max-lines */ -import type { Hub } from '@sentry/core'; import type { TransactionContext } from '@sentry/types'; import { logger, timestampWithMs } from '@sentry/utils'; +import type { Hub } from '..'; import type { Span } from './span'; import { SpanRecorder } from './span'; import { Transaction } from './transaction'; -export const DEFAULT_IDLE_TIMEOUT = 1000; -export const DEFAULT_FINAL_TIMEOUT = 30000; -export const DEFAULT_HEARTBEAT_INTERVAL = 5000; +export const TRACING_DEFAULTS = { + idleTimeout: 1000, + finalTimeout: 30000, + heartbeatInterval: 5000, +}; /** * @inheritDoc @@ -81,12 +83,12 @@ export class IdleTransaction extends Transaction { * The time to wait in ms until the idle transaction will be finished. This timer is started each time * there are no active spans on this transaction. */ - private readonly _idleTimeout: number = DEFAULT_IDLE_TIMEOUT, + private readonly _idleTimeout: number = TRACING_DEFAULTS.idleTimeout, /** * The final value in ms that a transaction cannot exceed */ - private readonly _finalTimeout: number = DEFAULT_FINAL_TIMEOUT, - private readonly _heartbeatInterval: number = DEFAULT_HEARTBEAT_INTERVAL, + private readonly _finalTimeout: number = TRACING_DEFAULTS.finalTimeout, + private readonly _heartbeatInterval: number = TRACING_DEFAULTS.heartbeatInterval, // Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends private readonly _onScope: boolean = false, ) { diff --git a/packages/core/src/tracing/index.ts b/packages/core/src/tracing/index.ts new file mode 100644 index 000000000000..a1213e62add6 --- /dev/null +++ b/packages/core/src/tracing/index.ts @@ -0,0 +1,14 @@ +export { startIdleTransaction, addTracingExtensions } from './hubextensions'; +export { IdleTransaction, TRACING_DEFAULTS } from './idletransaction'; +export { Span, spanStatusfromHttpCode } from './span'; +export { Transaction } from './transaction'; +export { + extractTraceparentData, + getActiveTransaction, + hasTracingEnabled, + stripUrlQueryAndFragment, + TRACEPARENT_REGEXP, +} from './utils'; +// eslint-disable-next-line deprecation/deprecation +export { SpanStatus } from './spanstatus'; +export type { SpanStatusType } from './span'; diff --git a/packages/tracing/src/span.ts b/packages/core/src/tracing/span.ts similarity index 100% rename from packages/tracing/src/span.ts rename to packages/core/src/tracing/span.ts diff --git a/packages/tracing/src/spanstatus.ts b/packages/core/src/tracing/spanstatus.ts similarity index 100% rename from packages/tracing/src/spanstatus.ts rename to packages/core/src/tracing/spanstatus.ts diff --git a/packages/tracing/src/transaction.ts b/packages/core/src/tracing/transaction.ts similarity index 98% rename from packages/tracing/src/transaction.ts rename to packages/core/src/tracing/transaction.ts index 627478da744e..1ccd4a57f335 100644 --- a/packages/tracing/src/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -1,5 +1,3 @@ -import type { Hub } from '@sentry/core'; -import { getCurrentHub } from '@sentry/core'; import type { Context, Contexts, @@ -13,6 +11,8 @@ import type { } from '@sentry/types'; import { dropUndefinedKeys, logger } from '@sentry/utils'; +import type { Hub } from '..'; +import { getCurrentHub } from '..'; import { Span as SpanClass, SpanRecorder } from './span'; /** JSDoc */ diff --git a/packages/tracing/src/utils.ts b/packages/core/src/tracing/utils.ts similarity index 80% rename from packages/tracing/src/utils.ts rename to packages/core/src/tracing/utils.ts index 66cba77843b7..d47503d2c8fa 100644 --- a/packages/tracing/src/utils.ts +++ b/packages/core/src/tracing/utils.ts @@ -1,7 +1,8 @@ -import type { Hub } from '@sentry/core'; -import { getCurrentHub } from '@sentry/core'; import type { Options, Transaction } from '@sentry/types'; +import type { Hub } from '..'; +import { getCurrentHub } from '..'; + /** * The `extractTraceparentData` function and `TRACEPARENT_REGEXP` constant used * to be declared in this file. It was later moved into `@sentry/utils` as part of a @@ -36,21 +37,5 @@ export function getActiveTransaction(maybeHub?: Hub): T | return scope && (scope.getTransaction() as T | undefined); } -/** - * Converts from milliseconds to seconds - * @param time time in ms - */ -export function msToSec(time: number): number { - return time / 1000; -} - -/** - * Converts from seconds to milliseconds - * @param time time in seconds - */ -export function secToMs(time: number): number { - return time * 1000; -} - // so it can be used in manual instrumentation without necessitating a hard dependency on @sentry/utils export { stripUrlQueryAndFragment } from '@sentry/utils'; diff --git a/packages/nextjs/src/index.types.ts b/packages/nextjs/src/index.types.ts index 0b115d213d5d..da88c22d4f99 100644 --- a/packages/nextjs/src/index.types.ts +++ b/packages/nextjs/src/index.types.ts @@ -35,6 +35,8 @@ export declare const ErrorBoundary: typeof clientSdk.ErrorBoundary; export declare const showReportDialog: typeof clientSdk.showReportDialog; export declare const withErrorBoundary: typeof clientSdk.withErrorBoundary; +export declare const Span: typeof edgeSdk.Span; + /** * @deprecated Use `wrapApiHandlerWithSentry` instead */ diff --git a/packages/tracing/src/browser/backgroundtab.ts b/packages/tracing/src/browser/backgroundtab.ts index 8c55e9853901..e061f39925a1 100644 --- a/packages/tracing/src/browser/backgroundtab.ts +++ b/packages/tracing/src/browser/backgroundtab.ts @@ -1,8 +1,7 @@ +import type { IdleTransaction, SpanStatusType } from '@sentry/core'; +import { getActiveTransaction } from '@sentry/core'; import { logger } from '@sentry/utils'; -import type { IdleTransaction } from '../idletransaction'; -import type { SpanStatusType } from '../span'; -import { getActiveTransaction } from '../utils'; import { WINDOW } from './types'; /** diff --git a/packages/tracing/src/browser/browsertracing.ts b/packages/tracing/src/browser/browsertracing.ts index 9030e8a11400..4eab4662b5f3 100644 --- a/packages/tracing/src/browser/browsertracing.ts +++ b/packages/tracing/src/browser/browsertracing.ts @@ -1,12 +1,9 @@ /* eslint-disable max-lines */ -import type { Hub } from '@sentry/core'; +import type { Hub, IdleTransaction } from '@sentry/core'; +import { extractTraceparentData, startIdleTransaction, TRACING_DEFAULTS } from '@sentry/core'; import type { EventProcessor, Integration, Transaction, TransactionContext, TransactionSource } from '@sentry/types'; import { baggageHeaderToDynamicSamplingContext, getDomElement, logger } from '@sentry/utils'; -import { startIdleTransaction } from '../hubextensions'; -import type { IdleTransaction } from '../idletransaction'; -import { DEFAULT_FINAL_TIMEOUT, DEFAULT_HEARTBEAT_INTERVAL, DEFAULT_IDLE_TIMEOUT } from '../idletransaction'; -import { extractTraceparentData } from '../utils'; import { registerBackgroundTabDetection } from './backgroundtab'; import { addPerformanceEntries, startTrackingLongTasks, startTrackingWebVitals } from './metrics'; import type { RequestInstrumentationOptions } from './request'; @@ -127,9 +124,7 @@ export interface BrowserTracingOptions extends RequestInstrumentationOptions { } const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = { - idleTimeout: DEFAULT_IDLE_TIMEOUT, - finalTimeout: DEFAULT_FINAL_TIMEOUT, - heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL, + ...TRACING_DEFAULTS, markBackgroundTransactions: true, routingInstrumentation: instrumentRoutingWithDefaults, startTransactionOnLocationChange: true, diff --git a/packages/tracing/src/browser/metrics/index.ts b/packages/tracing/src/browser/metrics/index.ts index b59f344899d2..2d37ef8c1919 100644 --- a/packages/tracing/src/browser/metrics/index.ts +++ b/packages/tracing/src/browser/metrics/index.ts @@ -1,10 +1,9 @@ /* eslint-disable max-lines */ +import type { IdleTransaction, Transaction } from '@sentry/core'; +import { getActiveTransaction } from '@sentry/core'; import type { Measurements } from '@sentry/types'; import { browserPerformanceTimeOrigin, htmlTreeAsString, logger } from '@sentry/utils'; -import type { IdleTransaction } from '../../idletransaction'; -import type { Transaction } from '../../transaction'; -import { getActiveTransaction, msToSec } from '../../utils'; import { WINDOW } from '../types'; import { onCLS } from '../web-vitals/getCLS'; import { onFID } from '../web-vitals/getFID'; @@ -14,6 +13,14 @@ import { observe } from '../web-vitals/lib/observe'; import type { NavigatorDeviceMemory, NavigatorNetworkInformation } from '../web-vitals/types'; import { _startChild, isMeasurementValue } from './utils'; +/** + * Converts from milliseconds to seconds + * @param time time in ms + */ +function msToSec(time: number): number { + return time / 1000; +} + function getBrowserPerformanceAPI(): Performance | undefined { return WINDOW && WINDOW.addEventListener && WINDOW.performance; } diff --git a/packages/tracing/src/browser/metrics/utils.ts b/packages/tracing/src/browser/metrics/utils.ts index 7c30a9090245..80bf01b9c333 100644 --- a/packages/tracing/src/browser/metrics/utils.ts +++ b/packages/tracing/src/browser/metrics/utils.ts @@ -1,7 +1,6 @@ +import type { Transaction } from '@sentry/core'; import type { Span, SpanContext } from '@sentry/types'; -import type { Transaction } from '../../transaction'; - /** * Checks if a given value is a valid measurement value. */ diff --git a/packages/tracing/src/browser/request.ts b/packages/tracing/src/browser/request.ts index 57d0178509ef..e1e1c9aaf7fb 100644 --- a/packages/tracing/src/browser/request.ts +++ b/packages/tracing/src/browser/request.ts @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -import { getCurrentHub } from '@sentry/core'; +import { getCurrentHub, hasTracingEnabled } from '@sentry/core'; import type { DynamicSamplingContext, Span } from '@sentry/types'; import { addInstrumentationHandler, @@ -9,8 +9,6 @@ import { stringMatchesSomePattern, } from '@sentry/utils'; -import { hasTracingEnabled } from '../utils'; - export const DEFAULT_TRACE_PROPAGATION_TARGETS = ['localhost', /^\//]; /** Options for Request Instrumentation */ diff --git a/packages/tracing/src/errors.ts b/packages/tracing/src/errors.ts index 1952fb75a915..3d41e43830f0 100644 --- a/packages/tracing/src/errors.ts +++ b/packages/tracing/src/errors.ts @@ -1,8 +1,7 @@ +import type { SpanStatusType } from '@sentry/core'; +import { getActiveTransaction } from '@sentry/core'; import { addInstrumentationHandler, logger } from '@sentry/utils'; -import type { SpanStatusType } from './span'; -import { getActiveTransaction } from './utils'; - /** * Configures global error listeners */ diff --git a/packages/tracing/src/extensions.ts b/packages/tracing/src/extensions.ts new file mode 100644 index 000000000000..d6c0298dbbd7 --- /dev/null +++ b/packages/tracing/src/extensions.ts @@ -0,0 +1,72 @@ +import { addTracingExtensions, getMainCarrier } from '@sentry/core'; +import type { Integration, IntegrationClass } from '@sentry/types'; +import { dynamicRequire, isNodeEnv, loadModule } from '@sentry/utils'; + +import { registerErrorInstrumentation } from './errors'; + +/** + * @private + */ +function _autoloadDatabaseIntegrations(): void { + const carrier = getMainCarrier(); + if (!carrier.__SENTRY__) { + return; + } + + const packageToIntegrationMapping: Record Integration> = { + mongodb() { + const integration = dynamicRequire(module, './integrations/node/mongo') as { + Mongo: IntegrationClass; + }; + return new integration.Mongo(); + }, + mongoose() { + const integration = dynamicRequire(module, './integrations/node/mongo') as { + Mongo: IntegrationClass; + }; + return new integration.Mongo({ mongoose: true }); + }, + mysql() { + const integration = dynamicRequire(module, './integrations/node/mysql') as { + Mysql: IntegrationClass; + }; + return new integration.Mysql(); + }, + pg() { + const integration = dynamicRequire(module, './integrations/node/postgres') as { + Postgres: IntegrationClass; + }; + return new integration.Postgres(); + }, + }; + + const mappedPackages = Object.keys(packageToIntegrationMapping) + .filter(moduleName => !!loadModule(moduleName)) + .map(pkg => { + try { + return packageToIntegrationMapping[pkg](); + } catch (e) { + return undefined; + } + }) + .filter(p => p) as Integration[]; + + if (mappedPackages.length > 0) { + carrier.__SENTRY__.integrations = [...(carrier.__SENTRY__.integrations || []), ...mappedPackages]; + } +} + +/** + * This patches the global object and injects the Tracing extensions methods + */ +export function addExtensionMethods(): void { + addTracingExtensions(); + + // Detect and automatically load specified integrations. + if (isNodeEnv()) { + _autoloadDatabaseIntegrations(); + } + + // If an error happens globally, we should make sure transaction status is set to error. + registerErrorInstrumentation(); +} diff --git a/packages/tracing/src/index.bundle.ts b/packages/tracing/src/index.bundle.ts index fce29d33758e..a753bab932d4 100644 --- a/packages/tracing/src/index.bundle.ts +++ b/packages/tracing/src/index.bundle.ts @@ -58,9 +58,9 @@ import type { Integration } from '@sentry/types'; import { GLOBAL_OBJ } from '@sentry/utils'; import { BrowserTracing } from './browser'; -import { addExtensionMethods } from './hubextensions'; +import { addExtensionMethods } from './extensions'; -export { Span } from './span'; +export { Span } from '@sentry/core'; let windowIntegrations = {}; diff --git a/packages/tracing/src/index.ts b/packages/tracing/src/index.ts index 14d80fb7b4cc..b8cb377ffdfe 100644 --- a/packages/tracing/src/index.ts +++ b/packages/tracing/src/index.ts @@ -1,8 +1,23 @@ -import { addExtensionMethods } from './hubextensions'; +export { + extractTraceparentData, + getActiveTransaction, + hasTracingEnabled, + IdleTransaction, + Span, + // eslint-disable-next-line deprecation/deprecation + SpanStatus, + spanStatusfromHttpCode, + startIdleTransaction, + stripUrlQueryAndFragment, + TRACEPARENT_REGEXP, + Transaction, +} from '@sentry/core'; +export type { SpanStatusType } from '@sentry/core'; + +import { addExtensionMethods } from './extensions'; import * as Integrations from './integrations'; export type { RequestInstrumentationOptions } from './browser'; -export type { SpanStatusType } from './span'; export { Integrations }; @@ -24,13 +39,7 @@ export { Integrations }; // For an example of of the new usage of BrowserTracing, see @sentry/nextjs index.client.ts export { BrowserTracing, BROWSER_TRACING_INTEGRATION_ID } from './browser'; -export { Span, spanStatusfromHttpCode } from './span'; -// eslint-disable-next-line deprecation/deprecation -export { SpanStatus } from './spanstatus'; -export { Transaction } from './transaction'; export { instrumentOutgoingRequests, defaultRequestInstrumentationOptions } from './browser'; -export { IdleTransaction } from './idletransaction'; -export { startIdleTransaction } from './hubextensions'; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; @@ -42,11 +51,3 @@ if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) { } export { addExtensionMethods }; - -export { - extractTraceparentData, - getActiveTransaction, - hasTracingEnabled, - stripUrlQueryAndFragment, - TRACEPARENT_REGEXP, -} from './utils'; diff --git a/packages/tracing/test/browser/backgroundtab.test.ts b/packages/tracing/test/browser/backgroundtab.test.ts index 47b7f14d8a7d..ddbf76baa6c6 100644 --- a/packages/tracing/test/browser/backgroundtab.test.ts +++ b/packages/tracing/test/browser/backgroundtab.test.ts @@ -2,8 +2,8 @@ import { BrowserClient } from '@sentry/browser'; import { Hub, makeMain } from '@sentry/core'; import { JSDOM } from 'jsdom'; +import { addExtensionMethods } from '../../src'; import { registerBackgroundTabDetection } from '../../src/browser/backgroundtab'; -import { addExtensionMethods } from '../../src/hubextensions'; import { getDefaultBrowserClientOptions } from '../testutils'; describe('registerBackgroundTabDetection', () => { diff --git a/packages/tracing/test/browser/browsertracing.test.ts b/packages/tracing/test/browser/browsertracing.test.ts index 1bb0c631e6ec..e0b520bf174d 100644 --- a/packages/tracing/test/browser/browsertracing.test.ts +++ b/packages/tracing/test/browser/browsertracing.test.ts @@ -1,17 +1,16 @@ import { BrowserClient, WINDOW } from '@sentry/browser'; -import { Hub, makeMain } from '@sentry/core'; +import { Hub, makeMain, TRACING_DEFAULTS } from '@sentry/core'; +import * as hubExtensions from '@sentry/core'; import type { BaseTransportOptions, ClientOptions, DsnComponents } from '@sentry/types'; import type { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { JSDOM } from 'jsdom'; +import type { IdleTransaction } from '../../src'; +import { getActiveTransaction } from '../../src'; import type { BrowserTracingOptions } from '../../src/browser/browsertracing'; import { BrowserTracing, getMetaContent } from '../../src/browser/browsertracing'; import { defaultRequestInstrumentationOptions } from '../../src/browser/request'; import { instrumentRoutingWithDefaults } from '../../src/browser/router'; -import * as hubExtensions from '../../src/hubextensions'; -import type { IdleTransaction } from '../../src/idletransaction'; -import { DEFAULT_FINAL_TIMEOUT, DEFAULT_HEARTBEAT_INTERVAL, DEFAULT_IDLE_TIMEOUT } from '../../src/idletransaction'; -import { getActiveTransaction } from '../../src/utils'; import { getDefaultBrowserClientOptions } from '../testutils'; let mockChangeHistory: ({ to, from }: { to: string; from?: string }) => void = () => undefined; @@ -86,9 +85,7 @@ describe('BrowserTracing', () => { expect(browserTracing.options).toEqual({ _experiments: {}, enableLongTask: true, - idleTimeout: DEFAULT_IDLE_TIMEOUT, - finalTimeout: DEFAULT_FINAL_TIMEOUT, - heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL, + ...TRACING_DEFAULTS, markBackgroundTransactions: true, routingInstrumentation: instrumentRoutingWithDefaults, startTransactionOnLocationChange: true, @@ -109,9 +106,7 @@ describe('BrowserTracing', () => { enableLongTask: false, }, enableLongTask: false, - idleTimeout: DEFAULT_IDLE_TIMEOUT, - finalTimeout: DEFAULT_FINAL_TIMEOUT, - heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL, + ...TRACING_DEFAULTS, markBackgroundTransactions: true, routingInstrumentation: instrumentRoutingWithDefaults, startTransactionOnLocationChange: true, @@ -128,9 +123,7 @@ describe('BrowserTracing', () => { expect(browserTracing.options).toEqual({ _experiments: {}, enableLongTask: false, - idleTimeout: DEFAULT_IDLE_TIMEOUT, - finalTimeout: DEFAULT_FINAL_TIMEOUT, - heartbeatInterval: DEFAULT_HEARTBEAT_INTERVAL, + ...TRACING_DEFAULTS, markBackgroundTransactions: true, routingInstrumentation: instrumentRoutingWithDefaults, startTransactionOnLocationChange: true, @@ -350,7 +343,7 @@ describe('BrowserTracing', () => { span.finish(); // activities = 0 expect(mockFinish).toHaveBeenCalledTimes(0); - jest.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT); + jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout); expect(mockFinish).toHaveBeenCalledTimes(1); }); diff --git a/packages/tracing/test/browser/request.test.ts b/packages/tracing/test/browser/request.test.ts index 3dd107d708dc..abbe44b5a4ea 100644 --- a/packages/tracing/test/browser/request.test.ts +++ b/packages/tracing/test/browser/request.test.ts @@ -1,13 +1,12 @@ import { BrowserClient } from '@sentry/browser'; import { Hub, makeMain } from '@sentry/core'; +import * as tracingUtils from '@sentry/core'; import * as utils from '@sentry/utils'; import type { Transaction } from '../../src'; -import { Span, spanStatusfromHttpCode } from '../../src'; +import { addExtensionMethods, Span, spanStatusfromHttpCode } from '../../src'; import type { FetchData, XHRData } from '../../src/browser/request'; import { fetchCallback, instrumentOutgoingRequests, shouldAttachHeaders, xhrCallback } from '../../src/browser/request'; -import { addExtensionMethods } from '../../src/hubextensions'; -import * as tracingUtils from '../../src/utils'; import { getDefaultBrowserClientOptions } from '../testutils'; beforeAll(() => { diff --git a/packages/tracing/test/errors.test.ts b/packages/tracing/test/errors.test.ts index 554ee3b3d8c7..70a2e4561671 100644 --- a/packages/tracing/test/errors.test.ts +++ b/packages/tracing/test/errors.test.ts @@ -1,9 +1,8 @@ import { BrowserClient } from '@sentry/browser'; -import { Hub, makeMain } from '@sentry/core'; +import { addTracingExtensions, Hub, makeMain } from '@sentry/core'; import type { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils'; import { registerErrorInstrumentation } from '../src/errors'; -import { _addTracingExtensions } from '../src/hubextensions'; import { getDefaultBrowserClientOptions } from './testutils'; const mockAddInstrumentationHandler = jest.fn(); @@ -28,7 +27,7 @@ jest.mock('@sentry/utils', () => { }); beforeAll(() => { - _addTracingExtensions(); + addTracingExtensions(); }); describe('registerErrorHandlers()', () => { diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 18c357066ff5..365ae4b41664 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -4,10 +4,8 @@ import { Hub, makeMain } from '@sentry/core'; import * as utilsModule from '@sentry/utils'; // for mocking import { logger } from '@sentry/utils'; +import { addExtensionMethods, extractTraceparentData, TRACEPARENT_REGEXP, Transaction } from '../src'; import { BrowserTracing } from '../src/browser/browsertracing'; -import { addExtensionMethods } from '../src/hubextensions'; -import { Transaction } from '../src/transaction'; -import { extractTraceparentData, TRACEPARENT_REGEXP } from '../src/utils'; import { addDOMPropertiesToGlobal, getDefaultBrowserClientOptions, diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/tracing/test/idletransaction.test.ts index 79cd3f546bf9..5ac210c19a08 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/tracing/test/idletransaction.test.ts @@ -1,14 +1,8 @@ import { BrowserClient } from '@sentry/browser'; -import { Hub } from '@sentry/core'; - -import { - DEFAULT_FINAL_TIMEOUT, - DEFAULT_HEARTBEAT_INTERVAL, - DEFAULT_IDLE_TIMEOUT, - IdleTransaction, - IdleTransactionSpanRecorder, -} from '../src/idletransaction'; -import { Span } from '../src/span'; +import { TRACING_DEFAULTS } from '@sentry/core'; + +import { Hub, IdleTransaction, Span } from '../../core/src'; +import { IdleTransactionSpanRecorder } from '../../core/src/tracing/idletransaction'; import { getDefaultBrowserClientOptions } from './testutils'; const dsn = 'https://123@sentry.io/42'; @@ -24,9 +18,9 @@ describe('IdleTransaction', () => { const transaction = new IdleTransaction( { name: 'foo' }, hub, - DEFAULT_IDLE_TIMEOUT, - DEFAULT_FINAL_TIMEOUT, - DEFAULT_HEARTBEAT_INTERVAL, + TRACING_DEFAULTS.idleTimeout, + TRACING_DEFAULTS.finalTimeout, + TRACING_DEFAULTS.heartbeatInterval, true, ); transaction.initSpanRecorder(10); @@ -49,9 +43,9 @@ describe('IdleTransaction', () => { const transaction = new IdleTransaction( { name: 'foo' }, hub, - DEFAULT_IDLE_TIMEOUT, - DEFAULT_FINAL_TIMEOUT, - DEFAULT_HEARTBEAT_INTERVAL, + TRACING_DEFAULTS.idleTimeout, + TRACING_DEFAULTS.finalTimeout, + TRACING_DEFAULTS.heartbeatInterval, true, ); transaction.initSpanRecorder(10); @@ -68,9 +62,9 @@ describe('IdleTransaction', () => { const transaction = new IdleTransaction( { name: 'foo', sampled: false }, hub, - DEFAULT_IDLE_TIMEOUT, - DEFAULT_FINAL_TIMEOUT, - DEFAULT_HEARTBEAT_INTERVAL, + TRACING_DEFAULTS.idleTimeout, + TRACING_DEFAULTS.finalTimeout, + TRACING_DEFAULTS.heartbeatInterval, true, ); @@ -125,7 +119,7 @@ describe('IdleTransaction', () => { expect(transaction.activities).toMatchObject({ [span.spanId]: true, [childSpan.spanId]: true }); span.finish(); - jest.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT + 1); + jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout + 1); expect(mockFinish).toHaveBeenCalledTimes(0); expect(transaction.activities).toMatchObject({ [childSpan.spanId]: true }); @@ -203,7 +197,7 @@ describe('IdleTransaction', () => { const transaction = new IdleTransaction({ name: 'foo', startTimestamp: 1234 }, hub); transaction.initSpanRecorder(10); - jest.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT); + jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout); expect(transaction.endTimestamp).toBeDefined(); }); @@ -212,7 +206,7 @@ describe('IdleTransaction', () => { transaction.initSpanRecorder(10); transaction.startChild({}); - jest.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT); + jest.advanceTimersByTime(TRACING_DEFAULTS.idleTimeout); expect(transaction.endTimestamp).toBeUndefined(); }); @@ -263,23 +257,23 @@ describe('IdleTransaction', () => { expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(transaction.status).not.toEqual('deadline_exceeded'); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 2 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(transaction.status).not.toEqual('deadline_exceeded'); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 3 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(transaction.status).not.toEqual('deadline_exceeded'); expect(mockFinish).toHaveBeenCalledTimes(0); }); it('finishes a transaction after 3 beats', () => { - const transaction = new IdleTransaction({ name: 'foo' }, hub, DEFAULT_IDLE_TIMEOUT); + const transaction = new IdleTransaction({ name: 'foo' }, hub, TRACING_DEFAULTS.idleTimeout); const mockFinish = jest.spyOn(transaction, 'finish'); transaction.initSpanRecorder(10); @@ -287,20 +281,20 @@ describe('IdleTransaction', () => { transaction.startChild({}); // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 2 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 3 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(1); }); it('resets after new activities are added', () => { - const transaction = new IdleTransaction({ name: 'foo' }, hub, DEFAULT_IDLE_TIMEOUT, 50000); + const transaction = new IdleTransaction({ name: 'foo' }, hub, TRACING_DEFAULTS.idleTimeout, 50000); const mockFinish = jest.spyOn(transaction, 'finish'); transaction.initSpanRecorder(10); @@ -308,42 +302,42 @@ describe('IdleTransaction', () => { transaction.startChild({}); // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); const span = transaction.startChild(); // push activity // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 2 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); transaction.startChild(); // push activity transaction.startChild(); // push activity // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 2 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); span.finish(); // pop activity // Beat 1 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 2 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(0); // Beat 3 - jest.advanceTimersByTime(DEFAULT_HEARTBEAT_INTERVAL); + jest.advanceTimersByTime(TRACING_DEFAULTS.heartbeatInterval); expect(mockFinish).toHaveBeenCalledTimes(1); // Heartbeat does not keep going after finish has been called diff --git a/packages/tracing/test/integrations/apollo-nestjs.test.ts b/packages/tracing/test/integrations/apollo-nestjs.test.ts index 117cfd6ab704..4eb173b9958a 100644 --- a/packages/tracing/test/integrations/apollo-nestjs.test.ts +++ b/packages/tracing/test/integrations/apollo-nestjs.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../src'; import { Apollo } from '../../src/integrations/node/apollo'; -import { Span } from '../../src/span'; import { getTestClient } from '../testutils'; type ApolloResolverGroup = { @@ -43,6 +43,10 @@ class GraphQLFactory { } } +// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. +/* eslint-disable no-var */ +var mockFactory = GraphQLFactory; + // mock for @nestjs/graphql package jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); @@ -50,7 +54,7 @@ jest.mock('@sentry/utils', () => { ...actual, loadModule() { return { - GraphQLFactory, + GraphQLFactory: mockFactory, }; }, }; diff --git a/packages/tracing/test/integrations/apollo.test.ts b/packages/tracing/test/integrations/apollo.test.ts index 8b9946ba4a70..4a79fe227c9d 100644 --- a/packages/tracing/test/integrations/apollo.test.ts +++ b/packages/tracing/test/integrations/apollo.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../src'; import { Apollo } from '../../src/integrations/node/apollo'; -import { Span } from '../../src/span'; import { getTestClient } from '../testutils'; type ApolloResolverGroup = { @@ -45,6 +45,10 @@ class ApolloServerBase { } } +// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. +/* eslint-disable no-var */ +var mockClient = ApolloServerBase; + // mock for ApolloServer package jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); @@ -52,7 +56,7 @@ jest.mock('@sentry/utils', () => { ...actual, loadModule() { return { - ApolloServerBase, + ApolloServerBase: mockClient, }; }, }; diff --git a/packages/tracing/test/integrations/graphql.test.ts b/packages/tracing/test/integrations/graphql.test.ts index 265bbe0fb0d8..db59187a6c7b 100644 --- a/packages/tracing/test/integrations/graphql.test.ts +++ b/packages/tracing/test/integrations/graphql.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../src'; import { GraphQL } from '../../src/integrations/node/graphql'; -import { Span } from '../../src/span'; import { getTestClient } from '../testutils'; const GQLExecute = { @@ -12,13 +12,17 @@ const GQLExecute = { }, }; +// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. +/* eslint-disable no-var */ +var mockClient = GQLExecute; + // mock for 'graphql/execution/execution.js' package jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, loadModule() { - return GQLExecute; + return mockClient; }, }; }); diff --git a/packages/tracing/test/integrations/node/mongo.test.ts b/packages/tracing/test/integrations/node/mongo.test.ts index e362db6f0c47..84b1071c2f3c 100644 --- a/packages/tracing/test/integrations/node/mongo.test.ts +++ b/packages/tracing/test/integrations/node/mongo.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../../src'; import { Mongo } from '../../../src/integrations/node/mongo'; -import { Span } from '../../../src/span'; import { getTestClient } from '../../testutils'; class Collection { @@ -25,13 +25,17 @@ class Collection { } } +// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. +/* eslint-disable no-var */ +var mockCollection = Collection; + jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); return { ...actual, loadModule() { return { - Collection, + Collection: mockCollection, }; }, }; diff --git a/packages/tracing/test/integrations/node/postgres.test.ts b/packages/tracing/test/integrations/node/postgres.test.ts index 2ef3754b28ef..57e655bd1a99 100644 --- a/packages/tracing/test/integrations/node/postgres.test.ts +++ b/packages/tracing/test/integrations/node/postgres.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../../src'; import { Postgres } from '../../../src/integrations/node/postgres'; -import { Span } from '../../../src/span'; import { getTestClient } from '../../testutils'; class PgClient { @@ -23,6 +23,10 @@ class PgClient { } } +// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. +/* eslint-disable no-var */ +var mockClient = PgClient; + // mock for 'pg' / 'pg-native' package jest.mock('@sentry/utils', () => { const actual = jest.requireActual('@sentry/utils'); @@ -30,9 +34,9 @@ jest.mock('@sentry/utils', () => { ...actual, loadModule() { return { - Client: PgClient, + Client: mockClient, native: { - Client: PgClient, + Client: mockClient, }, }; }, diff --git a/packages/tracing/test/integrations/node/prisma.test.ts b/packages/tracing/test/integrations/node/prisma.test.ts index d2adb685fc9d..b4866c31f15f 100644 --- a/packages/tracing/test/integrations/node/prisma.test.ts +++ b/packages/tracing/test/integrations/node/prisma.test.ts @@ -2,8 +2,8 @@ import { Hub, Scope } from '@sentry/core'; import { logger } from '@sentry/utils'; +import { Span } from '../../../src'; import { Prisma } from '../../../src/integrations/node/prisma'; -import { Span } from '../../../src/span'; import { getTestClient } from '../../testutils'; type PrismaMiddleware = (params: unknown, next: (params?: unknown) => Promise) => Promise; diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index 96a71811eec9..38231b40e2ca 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -2,8 +2,7 @@ import { BrowserClient } from '@sentry/browser'; import { Hub, makeMain, Scope } from '@sentry/core'; import type { BaseTransportOptions, ClientOptions, TransactionSource } from '@sentry/types'; -import { Span, Transaction } from '../src'; -import { TRACEPARENT_REGEXP } from '../src/utils'; +import { Span, TRACEPARENT_REGEXP, Transaction } from '../src'; import { getDefaultBrowserClientOptions } from './testutils'; describe('Span', () => { diff --git a/packages/tracing/test/transaction.test.ts b/packages/tracing/test/transaction.test.ts index fb49dcc4d909..dae87c3a2f20 100644 --- a/packages/tracing/test/transaction.test.ts +++ b/packages/tracing/test/transaction.test.ts @@ -1,7 +1,6 @@ import { BrowserClient, Hub } from '@sentry/browser'; -import { addExtensionMethods } from '../src'; -import { Transaction } from '../src/transaction'; +import { addExtensionMethods, Transaction } from '../src'; import { getDefaultBrowserClientOptions } from './testutils'; describe('`Transaction` class', () => { diff --git a/packages/tracing/test/tsconfig.json b/packages/tracing/test/tsconfig.json index 074ceb45a9db..6c6ff4423fde 100644 --- a/packages/tracing/test/tsconfig.json +++ b/packages/tracing/test/tsconfig.json @@ -1,6 +1,5 @@ // TODO Once https://github.com/microsoft/TypeScript/issues/33094 is done (if it ever is), this file can disappear, as // it's purely a placeholder to satisfy VSCode. - { "extends": "../tsconfig.test.json", diff --git a/packages/tracing/test/utils.test.ts b/packages/tracing/test/utils.test.ts index 3bd3e9f5f35f..f20f4aeffe27 100644 --- a/packages/tracing/test/utils.test.ts +++ b/packages/tracing/test/utils.test.ts @@ -1,4 +1,4 @@ -import { extractTraceparentData, hasTracingEnabled } from '../src/utils'; +import { extractTraceparentData, hasTracingEnabled } from '../src'; describe('hasTracingEnabled', () => { const tracesSampler = () => 1;