From a68253420fed41d5195d6fed2a640ff98274817f Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 23 Jan 2024 15:06:14 +0100 Subject: [PATCH] feat(replay): Deprecate Replay, ReplayCanvas, Feedback classes (#10270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, users should use the new functional styles. Note that we'll probably actually un-deprecate `Replay` in some form in v8, as we'll be keeping the class around there for sure (as there is a lot of logic in there...). But users should not use it, so deprecating this now! While at it, I also deprecated the old `InitSentryForEmber` method in favor of `init()`. It's slightly unfortunate that I missed this, but we probably shouldn't have exposed `ReplayCanvas` as a class anymore at all 😬 maybe we wait before we document this etc. until we merged the functional style. cc @billyvg --- MIGRATION.md | 3 +++ .../suites/replay/bufferMode/test.ts | 6 ++++++ .../suites/replay/dsc/test.ts | 6 +++++- packages/browser/src/index.bundle.feedback.ts | 16 +++++++++++--- packages/browser/src/index.bundle.replay.ts | 21 ++++++++++++++++--- .../index.bundle.tracing.replay.feedback.ts | 17 ++++++++++++--- .../src/index.bundle.tracing.replay.ts | 17 ++++++++++++--- packages/browser/src/index.bundle.tracing.ts | 15 +++++++++++-- packages/browser/src/index.bundle.ts | 21 +++++++++++++++++-- packages/browser/src/index.ts | 19 ++++++++++++++--- .../test/unit/index.bundle.feedback.test.ts | 11 ++++++++-- .../test/unit/index.bundle.replay.test.ts | 11 ++++++++-- .../browser/test/unit/index.bundle.test.ts | 5 +++++ ...dex.bundle.tracing.replay.feedback.test.ts | 5 ++++- .../unit/index.bundle.tracing.replay.test.ts | 10 +++++++-- .../test/unit/index.bundle.tracing.test.ts | 10 ++++++++- packages/ember/addon/index.ts | 11 +++++++--- .../tests/acceptance/sentry-replay-test.ts | 7 ++++--- .../ember/tests/dummy/app/routes/replay.ts | 4 ++-- packages/feedback/src/index.ts | 6 +++++- packages/feedback/src/integration.ts | 11 ++++++++-- packages/feedback/test/integration.test.ts | 14 ++++++------- packages/integration-shims/src/Feedback.ts | 14 +++++++++++++ packages/integration-shims/src/Replay.ts | 14 +++++++++++++ packages/integration-shims/src/index.ts | 12 +++++++++-- packages/replay-canvas/src/canvas.ts | 17 +++++++++------ packages/replay-canvas/src/index.ts | 6 +++++- packages/replay-canvas/test/canvas.test.ts | 6 +++--- packages/replay/src/index.ts | 6 +++++- packages/replay/src/integration.ts | 9 +++++++- .../beforeAddRecordingEvent.test.ts | 1 + .../coreHandlers/handleGlobalEvent.test.ts | 4 +--- packages/replay/test/integration/stop.test.ts | 1 + packages/replay/test/mocks/mockSdk.ts | 2 ++ packages/replay/test/mocks/resetSdkMock.ts | 1 + .../test/unit/multipleInstances.test.ts | 6 +++--- 36 files changed, 279 insertions(+), 66 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 3ec81623c175..88b27b25bc16 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -36,6 +36,9 @@ The following list shows how integrations should be migrated: | `new ModuleMetadata()` | `moduleMetadataIntegration()` | `@sentry/core`, `@sentry/browser` | | `new RequestData()` | `requestDataIntegration()` | `@sentry/core`, `@sentry/node`, `@sentry/deno`, `@sentry/bun`, `@sentry/vercel-edge` | | `new Wasm() ` | `wasmIntegration()` | `@sentry/wasm` | +| `new Replay()` | `replayIntegration()` | `@sentry/browser` | +| `new ReplayCanvas()` | `replayCanvasIntegration()` | `@sentry/browser` | +| `new Feedback()` | `feedbackIntegration()` | `@sentry/browser` | ## Deprecate `hub.bindClient()` and `makeMain()` diff --git a/dev-packages/browser-integration-tests/suites/replay/bufferMode/test.ts b/dev-packages/browser-integration-tests/suites/replay/bufferMode/test.ts index c4da79faa1d9..1ff15a3d3ff2 100644 --- a/dev-packages/browser-integration-tests/suites/replay/bufferMode/test.ts +++ b/dev-packages/browser-integration-tests/suites/replay/bufferMode/test.ts @@ -67,6 +67,7 @@ sentryTest( // Start buffering and assert that it is enabled expect( await page.evaluate(() => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: InstanceType }).Replay; // @ts-expect-error private const replay = replayIntegration._replay; @@ -87,6 +88,7 @@ sentryTest( const [req0] = await Promise.all([ reqPromise0, page.evaluate(async () => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay; await replayIntegration.flush(); }), @@ -210,6 +212,7 @@ sentryTest( // Start buffering and assert that it is enabled expect( await page.evaluate(() => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: InstanceType }).Replay; // @ts-expect-error private const replay = replayIntegration._replay; @@ -230,6 +233,7 @@ sentryTest( const [req0] = await Promise.all([ reqPromise0, page.evaluate(async () => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay; await replayIntegration.flush({ continueRecording: false }); }), @@ -324,6 +328,7 @@ sentryTest( // Start buffering and assert that it is enabled expect( await page.evaluate(() => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: InstanceType }).Replay; const replay = replayIntegration['_replay']; replayIntegration.startBuffering(); @@ -342,6 +347,7 @@ sentryTest( expect(errorEvent0.tags?.replayId).toBeUndefined(); await page.evaluate(async () => { + // eslint-disable-next-line deprecation/deprecation const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay; replayIntegration['_replay'].getOptions().errorSampleRate = 1.0; }); diff --git a/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts b/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts index 63c103e51259..0588e165604e 100644 --- a/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts +++ b/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts @@ -6,7 +6,11 @@ import { sentryTest } from '../../../utils/fixtures'; import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../utils/helpers'; import { getReplaySnapshot, shouldSkipReplayTest, waitForReplayRunning } from '../../../utils/replayHelpers'; -type TestWindow = Window & { Sentry: typeof Sentry; Replay: Sentry.Replay }; +type TestWindow = Window & { + Sentry: typeof Sentry; + // eslint-disable-next-line deprecation/deprecation + Replay: Sentry.Replay; +}; sentryTest( 'should add replay_id to dsc of transactions when in session mode', diff --git a/packages/browser/src/index.bundle.feedback.ts b/packages/browser/src/index.bundle.feedback.ts index 7aab6485d254..5d3612106286 100644 --- a/packages/browser/src/index.bundle.feedback.ts +++ b/packages/browser/src/index.bundle.feedback.ts @@ -1,14 +1,24 @@ // This is exported so the loader does not fail when switching off Replay/Tracing -import { Feedback } from '@sentry-internal/feedback'; -import { BrowserTracing, Replay, addTracingExtensions } from '@sentry-internal/integration-shims'; +import { Feedback, feedbackIntegration } from '@sentry-internal/feedback'; +import { BrowserTracing, Replay, addTracingExtensions, replayIntegration } from '@sentry-internal/integration-shims'; import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; export * from './index.bundle.base'; -export { BrowserTracing, addTracingExtensions, Replay, Feedback }; +export { + BrowserTracing, + addTracingExtensions, + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, +}; // Note: We do not export a shim for `Span` here, as that is quite complex and would blow up the bundle diff --git a/packages/browser/src/index.bundle.replay.ts b/packages/browser/src/index.bundle.replay.ts index 0b556bc71b8e..2609e7d9b48c 100644 --- a/packages/browser/src/index.bundle.replay.ts +++ b/packages/browser/src/index.bundle.replay.ts @@ -1,14 +1,29 @@ // This is exported so the loader does not fail when switching off Replay/Tracing -import { BrowserTracing, Feedback, addTracingExtensions } from '@sentry-internal/integration-shims'; -import { Replay } from '@sentry/replay'; +import { + BrowserTracing, + Feedback, + addTracingExtensions, + feedbackIntegration, +} from '@sentry-internal/integration-shims'; +import { Replay, replayIntegration } from '@sentry/replay'; import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; export * from './index.bundle.base'; -export { BrowserTracing, addTracingExtensions, Replay, Feedback }; +export { + BrowserTracing, + addTracingExtensions, + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, +}; // Note: We do not export a shim for `Span` here, as that is quite complex and would blow up the bundle diff --git a/packages/browser/src/index.bundle.tracing.replay.feedback.ts b/packages/browser/src/index.bundle.tracing.replay.feedback.ts index 5558703f7703..e17c7de4159a 100644 --- a/packages/browser/src/index.bundle.tracing.replay.feedback.ts +++ b/packages/browser/src/index.bundle.tracing.replay.feedback.ts @@ -1,12 +1,13 @@ -import { Feedback } from '@sentry-internal/feedback'; +import { Feedback, feedbackIntegration } from '@sentry-internal/feedback'; import { BrowserTracing, Span, addExtensionMethods } from '@sentry-internal/tracing'; -import { Replay } from '@sentry/replay'; +import { Replay, replayIntegration } from '@sentry/replay'; import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility // We want replay to be available under Sentry.Replay, to be consistent // with the NPM package version. +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; @@ -14,5 +15,15 @@ Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods addExtensionMethods(); -export { Feedback, Replay, BrowserTracing, Span, addExtensionMethods }; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + // eslint-disable-next-line deprecation/deprecation + Replay, + feedbackIntegration, + replayIntegration, + BrowserTracing, + Span, + addExtensionMethods, +}; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.bundle.tracing.replay.ts b/packages/browser/src/index.bundle.tracing.replay.ts index 0e7aa1ec19bc..5dc0537be064 100644 --- a/packages/browser/src/index.bundle.tracing.replay.ts +++ b/packages/browser/src/index.bundle.tracing.replay.ts @@ -1,12 +1,13 @@ -import { Feedback } from '@sentry-internal/integration-shims'; +import { Feedback, feedbackIntegration } from '@sentry-internal/integration-shims'; import { BrowserTracing, Span, addExtensionMethods } from '@sentry-internal/tracing'; -import { Replay } from '@sentry/replay'; +import { Replay, replayIntegration } from '@sentry/replay'; import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility // We want replay to be available under Sentry.Replay, to be consistent // with the NPM package version. +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; @@ -14,5 +15,15 @@ Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods addExtensionMethods(); -export { Feedback, Replay, BrowserTracing, Span, addExtensionMethods }; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, + feedbackIntegration, + BrowserTracing, + Span, + addExtensionMethods, +}; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.bundle.tracing.ts b/packages/browser/src/index.bundle.tracing.ts index 22b33962e860..f810b61b92a7 100644 --- a/packages/browser/src/index.bundle.tracing.ts +++ b/packages/browser/src/index.bundle.tracing.ts @@ -1,5 +1,5 @@ // This is exported so the loader does not fail when switching off Replay -import { Feedback, Replay } from '@sentry-internal/integration-shims'; +import { Feedback, Replay, feedbackIntegration, replayIntegration } from '@sentry-internal/integration-shims'; import { BrowserTracing, Span, addExtensionMethods } from '@sentry-internal/tracing'; import * as Sentry from './index.bundle.base'; @@ -7,6 +7,7 @@ import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility // We want replay to be available under Sentry.Replay, to be consistent // with the NPM package version. +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; @@ -14,5 +15,15 @@ Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods addExtensionMethods(); -export { Feedback, Replay, BrowserTracing, Span, addExtensionMethods }; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + // eslint-disable-next-line deprecation/deprecation + Replay, + feedbackIntegration, + replayIntegration, + BrowserTracing, + Span, + addExtensionMethods, +}; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.bundle.ts b/packages/browser/src/index.bundle.ts index a2541ceadda1..a92ff6bf66ec 100644 --- a/packages/browser/src/index.bundle.ts +++ b/packages/browser/src/index.bundle.ts @@ -1,13 +1,30 @@ // This is exported so the loader does not fail when switching off Replay/Tracing -import { BrowserTracing, Feedback, Replay, addTracingExtensions } from '@sentry-internal/integration-shims'; +import { + BrowserTracing, + Feedback, + Replay, + addTracingExtensions, + feedbackIntegration, + replayIntegration, +} from '@sentry-internal/integration-shims'; import * as Sentry from './index.bundle.base'; // TODO (v8): Remove this as it was only needed for backwards compatibility +// eslint-disable-next-line deprecation/deprecation Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; export * from './index.bundle.base'; -export { BrowserTracing, addTracingExtensions, Replay, Feedback }; +export { + BrowserTracing, + addTracingExtensions, + // eslint-disable-next-line deprecation/deprecation + Replay, + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, + replayIntegration, +}; // Note: We do not export a shim for `Span` here, as that is quite complex and would blow up the bundle diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 3dbec66f1e75..6c91e141149a 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -21,7 +21,11 @@ const INTEGRATIONS = { export { INTEGRATIONS as Integrations }; -export { Replay } from '@sentry/replay'; +export { + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, +} from '@sentry/replay'; export type { ReplayEventType, ReplayEventWithTime, @@ -34,9 +38,18 @@ export type { ReplaySpanFrameEvent, } from '@sentry/replay'; -export { ReplayCanvas } from '@sentry-internal/replay-canvas'; +export { + // eslint-disable-next-line deprecation/deprecation + ReplayCanvas, + replayCanvasIntegration, +} from '@sentry-internal/replay-canvas'; -export { Feedback, sendFeedback } from '@sentry-internal/feedback'; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, + sendFeedback, +} from '@sentry-internal/feedback'; export { BrowserTracing, diff --git a/packages/browser/test/unit/index.bundle.feedback.test.ts b/packages/browser/test/unit/index.bundle.feedback.test.ts index 4c5f26e5f313..5fe2940d1881 100644 --- a/packages/browser/test/unit/index.bundle.feedback.test.ts +++ b/packages/browser/test/unit/index.bundle.feedback.test.ts @@ -1,5 +1,10 @@ -import { BrowserTracing as BrowserTracingShim, Replay as ReplayShim } from '@sentry-internal/integration-shims'; -import { Feedback } from '@sentry/browser'; +/* eslint-disable deprecation/deprecation */ +import { + BrowserTracing as BrowserTracingShim, + Replay as ReplayShim, + replayIntegration as replayIntegrationShim, +} from '@sentry-internal/integration-shims'; +import { Feedback, feedbackIntegration } from '@sentry/browser'; import * as TracingReplayBundle from '../../src/index.bundle.feedback'; @@ -16,10 +21,12 @@ describe('index.bundle.feedback', () => { expect(TracingReplayBundle.Integrations.Replay).toBe(ReplayShim); expect(TracingReplayBundle.Replay).toBe(ReplayShim); + expect(TracingReplayBundle.replayIntegration).toBe(replayIntegrationShim); expect(TracingReplayBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim); expect(TracingReplayBundle.BrowserTracing).toBe(BrowserTracingShim); expect(TracingReplayBundle.Feedback).toBe(Feedback); + expect(TracingReplayBundle.feedbackIntegration).toBe(feedbackIntegration); }); }); diff --git a/packages/browser/test/unit/index.bundle.replay.test.ts b/packages/browser/test/unit/index.bundle.replay.test.ts index b14eb70f6330..e2d5640a2183 100644 --- a/packages/browser/test/unit/index.bundle.replay.test.ts +++ b/packages/browser/test/unit/index.bundle.replay.test.ts @@ -1,5 +1,10 @@ -import { BrowserTracing as BrowserTracingShim, Feedback as FeedbackShim } from '@sentry-internal/integration-shims'; -import { Replay } from '@sentry/browser'; +/* eslint-disable deprecation/deprecation */ +import { + BrowserTracing as BrowserTracingShim, + Feedback as FeedbackShim, + feedbackIntegration as feedbackIntegrationShim, +} from '@sentry-internal/integration-shims'; +import { Replay, replayIntegration } from '@sentry/browser'; import * as TracingReplayBundle from '../../src/index.bundle.replay'; @@ -16,10 +21,12 @@ describe('index.bundle.replay', () => { expect(TracingReplayBundle.Integrations.Replay).toBe(Replay); expect(TracingReplayBundle.Replay).toBe(Replay); + expect(TracingReplayBundle.replayIntegration).toBe(replayIntegration); expect(TracingReplayBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim); expect(TracingReplayBundle.BrowserTracing).toBe(BrowserTracingShim); expect(TracingReplayBundle.Feedback).toBe(FeedbackShim); + expect(TracingReplayBundle.feedbackIntegration).toBe(feedbackIntegrationShim); }); }); diff --git a/packages/browser/test/unit/index.bundle.test.ts b/packages/browser/test/unit/index.bundle.test.ts index f61987732858..d637c8de1c3d 100644 --- a/packages/browser/test/unit/index.bundle.test.ts +++ b/packages/browser/test/unit/index.bundle.test.ts @@ -1,7 +1,10 @@ +/* eslint-disable deprecation/deprecation */ import { BrowserTracing as BrowserTracingShim, Feedback as FeedbackShim, Replay as ReplayShim, + feedbackIntegration as feedbackIntegrationShim, + replayIntegration as replayIntegrationShim, } from '@sentry-internal/integration-shims'; import * as TracingBundle from '../../src/index.bundle'; @@ -19,10 +22,12 @@ describe('index.bundle', () => { expect(TracingBundle.Integrations.Replay).toBe(ReplayShim); expect(TracingBundle.Replay).toBe(ReplayShim); + expect(TracingBundle.replayIntegration).toBe(replayIntegrationShim); expect(TracingBundle.Integrations.BrowserTracing).toBe(BrowserTracingShim); expect(TracingBundle.BrowserTracing).toBe(BrowserTracingShim); expect(TracingBundle.Feedback).toBe(FeedbackShim); + expect(TracingBundle.feedbackIntegration).toBe(feedbackIntegrationShim); }); }); diff --git a/packages/browser/test/unit/index.bundle.tracing.replay.feedback.test.ts b/packages/browser/test/unit/index.bundle.tracing.replay.feedback.test.ts index 0bd50453da43..29b700773d92 100644 --- a/packages/browser/test/unit/index.bundle.tracing.replay.feedback.test.ts +++ b/packages/browser/test/unit/index.bundle.tracing.replay.feedback.test.ts @@ -1,5 +1,6 @@ +/* eslint-disable deprecation/deprecation */ import { BrowserTracing } from '@sentry-internal/tracing'; -import { Feedback, Replay } from '@sentry/browser'; +import { Feedback, Replay, feedbackIntegration, replayIntegration } from '@sentry/browser'; import * as TracingReplayFeedbackBundle from '../../src/index.bundle.tracing.replay.feedback'; @@ -16,10 +17,12 @@ describe('index.bundle.tracing.replay.feedback', () => { expect(TracingReplayFeedbackBundle.Integrations.Replay).toBe(Replay); expect(TracingReplayFeedbackBundle.Replay).toBe(Replay); + expect(TracingReplayFeedbackBundle.replayIntegration).toBe(replayIntegration); expect(TracingReplayFeedbackBundle.Integrations.BrowserTracing).toBe(BrowserTracing); expect(TracingReplayFeedbackBundle.BrowserTracing).toBe(BrowserTracing); expect(TracingReplayFeedbackBundle.Feedback).toBe(Feedback); + expect(TracingReplayFeedbackBundle.feedbackIntegration).toBe(feedbackIntegration); }); }); diff --git a/packages/browser/test/unit/index.bundle.tracing.replay.test.ts b/packages/browser/test/unit/index.bundle.tracing.replay.test.ts index 4c8af2130a3b..4db32003607e 100644 --- a/packages/browser/test/unit/index.bundle.tracing.replay.test.ts +++ b/packages/browser/test/unit/index.bundle.tracing.replay.test.ts @@ -1,6 +1,10 @@ -import { Feedback as FeedbackShim } from '@sentry-internal/integration-shims'; +/* eslint-disable deprecation/deprecation */ +import { + Feedback as FeedbackShim, + feedbackIntegration as feedbackIntegrationShim, +} from '@sentry-internal/integration-shims'; import { BrowserTracing } from '@sentry-internal/tracing'; -import { Replay } from '@sentry/browser'; +import { Replay, replayIntegration } from '@sentry/browser'; import * as TracingReplayBundle from '../../src/index.bundle.tracing.replay'; @@ -17,10 +21,12 @@ describe('index.bundle.tracing.replay', () => { expect(TracingReplayBundle.Integrations.Replay).toBe(Replay); expect(TracingReplayBundle.Replay).toBe(Replay); + expect(TracingReplayBundle.replayIntegration).toBe(replayIntegration); expect(TracingReplayBundle.Integrations.BrowserTracing).toBe(BrowserTracing); expect(TracingReplayBundle.BrowserTracing).toBe(BrowserTracing); expect(TracingReplayBundle.Feedback).toBe(FeedbackShim); + expect(TracingReplayBundle.feedbackIntegration).toBe(feedbackIntegrationShim); }); }); diff --git a/packages/browser/test/unit/index.bundle.tracing.test.ts b/packages/browser/test/unit/index.bundle.tracing.test.ts index b439dece8c6f..cf03a26f7054 100644 --- a/packages/browser/test/unit/index.bundle.tracing.test.ts +++ b/packages/browser/test/unit/index.bundle.tracing.test.ts @@ -1,4 +1,10 @@ -import { Feedback as FeedbackShim, Replay as ReplayShim } from '@sentry-internal/integration-shims'; +/* eslint-disable deprecation/deprecation */ +import { + Feedback as FeedbackShim, + Replay as ReplayShim, + feedbackIntegration as feedbackIntegrationShim, + replayIntegration as replayIntegrationShim, +} from '@sentry-internal/integration-shims'; import { BrowserTracing } from '@sentry-internal/tracing'; import * as TracingBundle from '../../src/index.bundle.tracing'; @@ -16,10 +22,12 @@ describe('index.bundle.tracing', () => { expect(TracingBundle.Integrations.Replay).toBe(ReplayShim); expect(TracingBundle.Replay).toBe(ReplayShim); + expect(TracingBundle.replayIntegration).toBe(replayIntegrationShim); expect(TracingBundle.Integrations.BrowserTracing).toBe(BrowserTracing); expect(TracingBundle.BrowserTracing).toBe(BrowserTracing); expect(TracingBundle.Feedback).toBe(FeedbackShim); + expect(TracingBundle.feedbackIntegration).toBe(feedbackIntegrationShim); }); }); diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index 07b13697676e..4f1f399654e4 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -18,7 +18,10 @@ function _getSentryInitConfig(): EmberSentryConfig['sentry'] { return _global.__sentryEmberConfig; } -export function InitSentryForEmber(_runtimeConfig?: BrowserOptions): void { +/** + * Initialize the Sentry SDK for Ember. + */ +export function init(_runtimeConfig?: BrowserOptions): void { const environmentConfig = getOwnConfig().sentryConfig; assert('Missing configuration.', environmentConfig); @@ -125,5 +128,7 @@ export const instrumentRoutePerformance = (BaseRoute export * from '@sentry/browser'; -// init is now the preferred way to call initialization for this addon. -export const init = InitSentryForEmber; +/** + * @deprecated Use `Sentry.init()` instead. + */ +export const InitSentryForEmber = init; diff --git a/packages/ember/tests/acceptance/sentry-replay-test.ts b/packages/ember/tests/acceptance/sentry-replay-test.ts index 4e541c00a1df..c807233cea25 100644 --- a/packages/ember/tests/acceptance/sentry-replay-test.ts +++ b/packages/ember/tests/acceptance/sentry-replay-test.ts @@ -1,6 +1,6 @@ import { visit } from '@ember/test-helpers'; import * as Sentry from '@sentry/ember'; -import type { BrowserClient, Replay } from '@sentry/ember'; +import type { BrowserClient, replayIntegration } from '@sentry/ember'; import { setupApplicationTest } from 'ember-qunit'; import { module, test } from 'qunit'; @@ -13,10 +13,11 @@ module('Acceptance | Sentry Session Replay', function (hooks) { test('Test replay', async function (assert) { await visit('/replay'); - const integration = Sentry.getClient()?.getIntegrationByName('Replay'); + const integration = + Sentry.getClient()?.getIntegrationByName>('Replay'); assert.ok(integration); - const replay = (integration as Sentry.Replay)['_replay'] as Replay['_replay']; + const replay = integration!['_replay'] as ReturnType['_replay']; assert.true(replay.isEnabled()); assert.false(replay.isPaused()); diff --git a/packages/ember/tests/dummy/app/routes/replay.ts b/packages/ember/tests/dummy/app/routes/replay.ts index ce9ebe2fa813..20e5200760b3 100644 --- a/packages/ember/tests/dummy/app/routes/replay.ts +++ b/packages/ember/tests/dummy/app/routes/replay.ts @@ -4,10 +4,10 @@ import * as Sentry from '@sentry/ember'; export default class ReplayRoute extends Route { public async beforeModel(): Promise { - const { Replay } = Sentry; + const { replayIntegration } = Sentry; const client = Sentry.getClient(); if (client && !client.getIntegrationByName('Replay')) { - client.addIntegration(new Replay()); + client.addIntegration(replayIntegration()); } } } diff --git a/packages/feedback/src/index.ts b/packages/feedback/src/index.ts index 57b6075dfca5..8fcba29c5d0f 100644 --- a/packages/feedback/src/index.ts +++ b/packages/feedback/src/index.ts @@ -1,2 +1,6 @@ export { sendFeedback } from './sendFeedback'; -export { Feedback } from './integration'; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, +} from './integration'; diff --git a/packages/feedback/src/integration.ts b/packages/feedback/src/integration.ts index 639540e6eaa3..501f844abeaa 100644 --- a/packages/feedback/src/integration.ts +++ b/packages/feedback/src/integration.ts @@ -1,4 +1,4 @@ -import type { Integration } from '@sentry/types'; +import type { Integration, IntegrationFn } from '@sentry/types'; import { isBrowser, logger } from '@sentry/utils'; import { @@ -25,10 +25,17 @@ import { createWidget } from './widget/createWidget'; const doc = WINDOW.document; +export const feedbackIntegration = ((options?: OptionalFeedbackConfiguration) => { + // eslint-disable-next-line deprecation/deprecation + return new Feedback(options); +}) satisfies IntegrationFn; + /** * Feedback integration. When added as an integration to the SDK, it will * inject a button in the bottom-right corner of the window that opens a * feedback modal when clicked. + * + * @deprecated Use `feedbackIntegration()` instead. */ export class Feedback implements Integration { /** @@ -105,7 +112,7 @@ export class Feedback implements Integration { onSubmitError, onSubmitSuccess, }: OptionalFeedbackConfiguration = {}) { - // Initializations + // eslint-disable-next-line deprecation/deprecation this.name = Feedback.id; // tsc fails if these are not initialized explicitly constructor, e.g. can't call `_initialize()` diff --git a/packages/feedback/test/integration.test.ts b/packages/feedback/test/integration.test.ts index fd5ef67bed1f..4a651a8ef7be 100644 --- a/packages/feedback/test/integration.test.ts +++ b/packages/feedback/test/integration.test.ts @@ -1,7 +1,7 @@ import * as SentryUtils from '@sentry/utils'; import { ACTOR_LABEL } from '../src/constants'; -import { Feedback } from '../src/integration'; +import { feedbackIntegration } from '../src/integration'; jest.spyOn(SentryUtils, 'isBrowser').mockImplementation(() => true); @@ -14,7 +14,7 @@ jest.mock('../src/util/sendFeedbackRequest', () => { }); describe('Feedback integration', () => { - let feedback: Feedback; + let feedback: ReturnType; beforeEach(() => { jest.clearAllMocks(); @@ -27,7 +27,7 @@ describe('Feedback integration', () => { }); it('autoinjects widget with actor', () => { - feedback = new Feedback(); + feedback = feedbackIntegration(); feedback.setupOnce(); const widget = feedback.getWidget(); expect(widget?.actor?.el).toBeInstanceOf(HTMLButtonElement); @@ -40,7 +40,7 @@ describe('Feedback integration', () => { }); it('does not create a widget with `autoInject: false`', () => { - feedback = new Feedback({ autoInject: false }); + feedback = feedbackIntegration({ autoInject: false }); feedback.setupOnce(); const widget = feedback.getWidget(); expect(widget?.actor?.el).toBeUndefined(); @@ -49,7 +49,7 @@ describe('Feedback integration', () => { }); it('opens (and closes) dialog when calling `openDialog` without injecting an actor', () => { - feedback = new Feedback({ autoInject: false }); + feedback = feedbackIntegration({ autoInject: false }); feedback.setupOnce(); let widget = feedback.getWidget(); @@ -75,7 +75,7 @@ describe('Feedback integration', () => { const myActor = document.createElement('div'); myActor.textContent = 'my button'; - feedback = new Feedback({ autoInject: false }); + feedback = feedbackIntegration({ autoInject: false }); let widget = feedback.getWidget(); expect(widget).toBe(null); @@ -92,7 +92,7 @@ describe('Feedback integration', () => { }); it('creates multiple widgets and removes them', () => { - feedback = new Feedback({ autoInject: false }); + feedback = feedbackIntegration({ autoInject: false }); feedback.createWidget(); expect(feedback.getWidget()?.actor?.el).toBeInstanceOf(HTMLButtonElement); diff --git a/packages/integration-shims/src/Feedback.ts b/packages/integration-shims/src/Feedback.ts index 3a1efed9a89a..232e2be0830b 100644 --- a/packages/integration-shims/src/Feedback.ts +++ b/packages/integration-shims/src/Feedback.ts @@ -5,6 +5,8 @@ import { consoleSandbox } from '@sentry/utils'; * This is a shim for the Feedback integration. * It is needed in order for the CDN bundles to continue working when users add/remove feedback * from it, without changing their config. This is necessary for the loader mechanism. + * + * @deprecated Use `feedbackIntergation()` instead. */ class FeedbackShim implements Integration { /** @@ -19,6 +21,7 @@ class FeedbackShim implements Integration { // eslint-disable-next-line @typescript-eslint/no-explicit-any public constructor(_options: any) { + // eslint-disable-next-line deprecation/deprecation this.name = FeedbackShim.id; consoleSandbox(() => { @@ -67,4 +70,15 @@ class FeedbackShim implements Integration { } } +/** + * This is a shim for the Feedback integration. + * It is needed in order for the CDN bundles to continue working when users add/remove feedback + * from it, without changing their config. This is necessary for the loader mechanism. + */ +export function feedbackIntegration(_options: unknown): Integration { + // eslint-disable-next-line deprecation/deprecation + return new FeedbackShim({}); +} + +// eslint-disable-next-line deprecation/deprecation export { FeedbackShim as Feedback }; diff --git a/packages/integration-shims/src/Replay.ts b/packages/integration-shims/src/Replay.ts index 16c905946219..3bcc6c3e6563 100644 --- a/packages/integration-shims/src/Replay.ts +++ b/packages/integration-shims/src/Replay.ts @@ -5,6 +5,8 @@ import { consoleSandbox } from '@sentry/utils'; * This is a shim for the Replay integration. * It is needed in order for the CDN bundles to continue working when users add/remove replay * from it, without changing their config. This is necessary for the loader mechanism. + * + * @deprecated Use `replayIntegration()` instead. */ class ReplayShim implements Integration { /** @@ -19,6 +21,7 @@ class ReplayShim implements Integration { // eslint-disable-next-line @typescript-eslint/no-explicit-any public constructor(_options: any) { + // eslint-disable-next-line deprecation/deprecation this.name = ReplayShim.id; consoleSandbox(() => { @@ -48,4 +51,15 @@ class ReplayShim implements Integration { } } +/** + * This is a shim for the Replay integration. + * It is needed in order for the CDN bundles to continue working when users add/remove replay + * from it, without changing their config. This is necessary for the loader mechanism. + */ +export function replayIntegration(_options: unknown): Integration { + // eslint-disable-next-line deprecation/deprecation + return new ReplayShim({}); +} + +// eslint-disable-next-line deprecation/deprecation export { ReplayShim as Replay }; diff --git a/packages/integration-shims/src/index.ts b/packages/integration-shims/src/index.ts index 410a4a31d9c8..43243f69a194 100644 --- a/packages/integration-shims/src/index.ts +++ b/packages/integration-shims/src/index.ts @@ -1,3 +1,11 @@ -export { Feedback } from './Feedback'; -export { Replay } from './Replay'; +export { + // eslint-disable-next-line deprecation/deprecation + Feedback, + feedbackIntegration, +} from './Feedback'; +export { + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, +} from './Replay'; export { BrowserTracing, addTracingExtensions } from './BrowserTracing'; diff --git a/packages/replay-canvas/src/canvas.ts b/packages/replay-canvas/src/canvas.ts index ba3ec85ebcfb..04f91af7d578 100644 --- a/packages/replay-canvas/src/canvas.ts +++ b/packages/replay-canvas/src/canvas.ts @@ -1,5 +1,5 @@ import { CanvasManager } from '@sentry-internal/rrweb'; -import { convertIntegrationFnToClass } from '@sentry/core'; +import { convertIntegrationFnToClass, defineIntegration } from '@sentry/core'; import type { CanvasManagerInterface, CanvasManagerOptions } from '@sentry/replay'; import type { Integration, IntegrationClass, IntegrationFn } from '@sentry/types'; @@ -54,10 +54,8 @@ const CANVAS_QUALITY = { const INTEGRATION_NAME = 'ReplayCanvas'; -/** - * An integration to add canvas recording to replay. - */ -const replayCanvasIntegration = ((options: Partial = {}) => { +/** Exported only for type safe tests. */ +export const _replayCanvasIntegration = ((options: Partial = {}) => { const _canvasOptions = { quality: options.quality || 'medium', enableManualSnapshot: options.enableManualSnapshot, @@ -91,7 +89,14 @@ const replayCanvasIntegration = ((options: Partial = {}) => }; }) satisfies IntegrationFn; -// TODO(v8) +/** + * Add this in addition to `replayIntegration()` to enable canvas recording. + */ +export const replayCanvasIntegration = defineIntegration(_replayCanvasIntegration); + +/** + * @deprecated Use `replayCanvasIntegration()` instead + */ // eslint-disable-next-line deprecation/deprecation export const ReplayCanvas = convertIntegrationFnToClass(INTEGRATION_NAME, replayCanvasIntegration) as IntegrationClass< Integration & { diff --git a/packages/replay-canvas/src/index.ts b/packages/replay-canvas/src/index.ts index 97e5bab007a2..b9dc20a69f53 100644 --- a/packages/replay-canvas/src/index.ts +++ b/packages/replay-canvas/src/index.ts @@ -1,2 +1,6 @@ -export { ReplayCanvas } from './canvas'; +export { + // eslint-disable-next-line deprecation/deprecation + ReplayCanvas, + replayCanvasIntegration, +} from './canvas'; export type { ReplayCanvasIntegrationOptions } from './canvas'; diff --git a/packages/replay-canvas/test/canvas.test.ts b/packages/replay-canvas/test/canvas.test.ts index 346df7b4a89d..534c28261498 100644 --- a/packages/replay-canvas/test/canvas.test.ts +++ b/packages/replay-canvas/test/canvas.test.ts @@ -1,7 +1,7 @@ -import { ReplayCanvas } from '../src/canvas'; +import { _replayCanvasIntegration } from '../src/canvas'; it('initializes with default options', () => { - const rc = new ReplayCanvas(); + const rc = _replayCanvasIntegration(); expect(rc.getOptions()).toEqual({ recordCanvas: true, @@ -17,7 +17,7 @@ it('initializes with default options', () => { }); it('initializes with quality option and manual snapshot', () => { - const rc = new ReplayCanvas({ enableManualSnapshot: true, quality: 'low' }); + const rc = _replayCanvasIntegration({ enableManualSnapshot: true, quality: 'low' }); expect(rc.getOptions()).toEqual({ enableManualSnapshot: true, diff --git a/packages/replay/src/index.ts b/packages/replay/src/index.ts index 8e8a5d55579a..6471ff9e87ce 100644 --- a/packages/replay/src/index.ts +++ b/packages/replay/src/index.ts @@ -1,4 +1,8 @@ -export { Replay } from './integration'; +export { + // eslint-disable-next-line deprecation/deprecation + Replay, + replayIntegration, +} from './integration'; export type { ReplayConfiguration, diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts index c73da03c1b85..9f4d03e7f5fa 100644 --- a/packages/replay/src/integration.ts +++ b/packages/replay/src/integration.ts @@ -1,5 +1,5 @@ import { getClient } from '@sentry/core'; -import type { BrowserClientReplayOptions, Integration } from '@sentry/types'; +import type { BrowserClientReplayOptions, Integration, IntegrationFn } from '@sentry/types'; import { consoleSandbox, dropUndefinedKeys, isBrowser } from '@sentry/utils'; import { @@ -30,8 +30,14 @@ let _initialized = false; type InitialReplayPluginOptions = Omit & Partial>; +export const replayIntegration = ((options?: InitialReplayPluginOptions) => { + // eslint-disable-next-line deprecation/deprecation + return new Replay(options); +}) satisfies IntegrationFn; + /** * The main replay integration class, to be passed to `init({ integrations: [] })`. + * @deprecated Use `replayIntegration()` instead. */ export class Replay implements Integration { /** @@ -111,6 +117,7 @@ export class Replay implements Integration { // eslint-disable-next-line deprecation/deprecation ignoreClass, }: ReplayConfiguration = {}) { + // eslint-disable-next-line deprecation/deprecation this.name = Replay.id; const privacyOptions = getPrivacyOptions({ diff --git a/packages/replay/test/integration/beforeAddRecordingEvent.test.ts b/packages/replay/test/integration/beforeAddRecordingEvent.test.ts index 68467f7bcafc..e8076875386b 100644 --- a/packages/replay/test/integration/beforeAddRecordingEvent.test.ts +++ b/packages/replay/test/integration/beforeAddRecordingEvent.test.ts @@ -23,6 +23,7 @@ type MockTransportSend = jest.MockedFunction; describe('Integration | beforeAddRecordingEvent', () => { let replay: ReplayContainer; + // eslint-disable-next-line deprecation/deprecation let integration: Replay; let mockTransportSend: MockTransportSend; let mockSendReplayRequest: jest.SpyInstance; diff --git a/packages/replay/test/integration/coreHandlers/handleGlobalEvent.test.ts b/packages/replay/test/integration/coreHandlers/handleGlobalEvent.test.ts index 7ea8f45755a4..a1ca45a8d76a 100644 --- a/packages/replay/test/integration/coreHandlers/handleGlobalEvent.test.ts +++ b/packages/replay/test/integration/coreHandlers/handleGlobalEvent.test.ts @@ -1,6 +1,5 @@ import type { Event } from '@sentry/types'; -import type { Replay as ReplayIntegration } from '../../../src'; import { REPLAY_EVENT_NAME, SESSION_IDLE_EXPIRE_DURATION } from '../../../src/constants'; import { handleGlobalEventListener } from '../../../src/coreHandlers/handleGlobalEvent'; import type { ReplayContainer } from '../../../src/replay'; @@ -130,8 +129,7 @@ describe('Integration | coreHandlers | handleGlobalEvent', () => { }); it('tags errors and transactions with replay id for session samples', async () => { - let integration: ReplayIntegration; - ({ replay, integration } = await resetSdkMock({})); + const { replay, integration } = await resetSdkMock({}); // @ts-expect-error protected but ok to use for testing integration._initialize(); const transaction = Transaction(); diff --git a/packages/replay/test/integration/stop.test.ts b/packages/replay/test/integration/stop.test.ts index 043dd76bcddc..75faef8f0d04 100644 --- a/packages/replay/test/integration/stop.test.ts +++ b/packages/replay/test/integration/stop.test.ts @@ -17,6 +17,7 @@ type MockRunFlush = jest.MockedFunction; describe('Integration | stop', () => { let replay: ReplayContainer; + // eslint-disable-next-line deprecation/deprecation let integration: Replay; const prevLocation = WINDOW.location; diff --git a/packages/replay/test/mocks/mockSdk.ts b/packages/replay/test/mocks/mockSdk.ts index f7e268bb49ba..ccf11dabb6ad 100644 --- a/packages/replay/test/mocks/mockSdk.ts +++ b/packages/replay/test/mocks/mockSdk.ts @@ -51,8 +51,10 @@ class MockTransport implements Transport { export async function mockSdk({ replayOptions, sentryOptions, autoStart = true }: MockSdkParams = {}): Promise<{ replay: ReplayContainer; + // eslint-disable-next-line deprecation/deprecation integration: ReplayIntegration; }> { + // eslint-disable-next-line deprecation/deprecation const { Replay } = await import('../../src'); // Scope this to the test, instead of the module diff --git a/packages/replay/test/mocks/resetSdkMock.ts b/packages/replay/test/mocks/resetSdkMock.ts index 7b3fb7a169b1..8c60f6d1c742 100644 --- a/packages/replay/test/mocks/resetSdkMock.ts +++ b/packages/replay/test/mocks/resetSdkMock.ts @@ -13,6 +13,7 @@ export async function resetSdkMock({ replayOptions, sentryOptions, autoStart }: domHandler: DomHandler; mockRecord: RecordMock; replay: ReplayContainer; + // eslint-disable-next-line deprecation/deprecation integration: ReplayIntegration; }> { let domHandler: DomHandler; diff --git a/packages/replay/test/unit/multipleInstances.test.ts b/packages/replay/test/unit/multipleInstances.test.ts index a271801936ff..fc5bc13e03cf 100644 --- a/packages/replay/test/unit/multipleInstances.test.ts +++ b/packages/replay/test/unit/multipleInstances.test.ts @@ -1,10 +1,10 @@ -import { Replay } from '../../src'; +import { replayIntegration } from '../../src/integration'; describe('Unit | multipleInstances', () => { it('throws on creating multiple instances', function () { expect(() => { - new Replay(); - new Replay(); + replayIntegration(); + replayIntegration(); }).toThrow(); }); });