From 20c6293213faaa68c34b50e49d60165edf89fc56 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 28 Mar 2024 10:09:57 +0100 Subject: [PATCH] feat(feedback): Add `getFeedback` utility to get typed feedback instance Also ensure the `feedbackIntegration` returns a properly typed response. --- packages/browser/src/index.bundle.feedback.ts | 3 +- .../index.bundle.tracing.replay.feedback.ts | 3 +- packages/browser/src/index.ts | 1 + .../feedback/src/core/getFeedback.test.ts | 40 +++++++++++++++++++ packages/feedback/src/core/getFeedback.ts | 10 +++++ packages/feedback/src/core/integration.ts | 9 +++-- packages/feedback/src/index.ts | 1 + 7 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 packages/feedback/src/core/getFeedback.test.ts create mode 100644 packages/feedback/src/core/getFeedback.ts diff --git a/packages/browser/src/index.bundle.feedback.ts b/packages/browser/src/index.bundle.feedback.ts index 887cc2e864ac..de24e36e2a60 100644 --- a/packages/browser/src/index.bundle.feedback.ts +++ b/packages/browser/src/index.bundle.feedback.ts @@ -1,5 +1,5 @@ // This is exported so the loader does not fail when switching off Replay/Tracing -import { feedbackIntegration } from '@sentry-internal/feedback'; +import { feedbackIntegration, getFeedback } from '@sentry-internal/feedback'; import { addTracingExtensionsShim, browserTracingIntegrationShim, @@ -12,5 +12,6 @@ export { addTracingExtensionsShim as addTracingExtensions, replayIntegrationShim as replayIntegration, feedbackIntegration, + getFeedback, }; // 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 41db6a7cb5f7..861074cf8d1a 100644 --- a/packages/browser/src/index.bundle.tracing.replay.feedback.ts +++ b/packages/browser/src/index.bundle.tracing.replay.feedback.ts @@ -1,4 +1,4 @@ -import { feedbackIntegration } from '@sentry-internal/feedback'; +import { feedbackIntegration, getFeedback } from '@sentry-internal/feedback'; import { replayIntegration } from '@sentry-internal/replay'; import { browserTracingIntegration, @@ -27,6 +27,7 @@ export { addTracingExtensions, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan, + getFeedback, }; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 3108dc603d42..8608944e3155 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -49,6 +49,7 @@ export { replayCanvasIntegration } from '@sentry-internal/replay-canvas'; export { feedbackIntegration, + getFeedback, sendFeedback, } from '@sentry-internal/feedback'; diff --git a/packages/feedback/src/core/getFeedback.test.ts b/packages/feedback/src/core/getFeedback.test.ts new file mode 100644 index 000000000000..f0cc7b70d0bc --- /dev/null +++ b/packages/feedback/src/core/getFeedback.test.ts @@ -0,0 +1,40 @@ +import { getCurrentScope } from '@sentry/core'; +import { getFeedback } from './getFeedback'; +import { feedbackIntegration } from './integration'; +import { mockSdk } from './mockSdk'; + +describe('getFeedback', () => { + beforeEach(() => { + getCurrentScope().setClient(undefined); + }); + + it('works without a client', () => { + const actual = getFeedback(); + expect(actual).toBeUndefined(); + }); + + it('works with a client without Feedback', () => { + mockSdk({ + sentryOptions: { + integrations: [], + }, + }); + + const actual = getFeedback(); + expect(actual).toBeUndefined(); + }); + + it('works with a client with Feedback', () => { + const feedback = feedbackIntegration(); + + mockSdk({ + sentryOptions: { + integrations: [feedback], + }, + }); + + const actual = getFeedback(); + expect(actual).toBeDefined(); + expect(actual === feedback).toBe(true); + }); +}); diff --git a/packages/feedback/src/core/getFeedback.ts b/packages/feedback/src/core/getFeedback.ts new file mode 100644 index 000000000000..f729d308971c --- /dev/null +++ b/packages/feedback/src/core/getFeedback.ts @@ -0,0 +1,10 @@ +import { getClient } from '@sentry/core'; +import type { feedbackIntegration } from './integration'; + +/** + * This is a small utility to get a type-safe instance of the Feedback integration. + */ +export function getFeedback(): ReturnType | undefined { + const client = getClient(); + return client && client.getIntegrationByName>('Feedback'); +} diff --git a/packages/feedback/src/core/integration.ts b/packages/feedback/src/core/integration.ts index a37aec267730..e0a0e273e6f0 100644 --- a/packages/feedback/src/core/integration.ts +++ b/packages/feedback/src/core/integration.ts @@ -1,4 +1,4 @@ -import { defineIntegration, getClient } from '@sentry/core'; +import { getClient } from '@sentry/core'; import type { Integration, IntegrationFn } from '@sentry/types'; import { isBrowser, logger } from '@sentry/utils'; import { @@ -45,7 +45,10 @@ interface PublicFeedbackIntegration { } export type IFeedbackIntegration = Integration & PublicFeedbackIntegration; -export const _feedbackIntegration = (({ +/** + * Allow users to capture user feedback and send it to Sentry. + */ +export const feedbackIntegration = (({ // FeedbackGeneralConfiguration id = 'sentry-feedback', showBranding = true, @@ -279,5 +282,3 @@ export const _feedbackIntegration = (({ }, }; }) satisfies IntegrationFn; - -export const feedbackIntegration = defineIntegration(_feedbackIntegration); diff --git a/packages/feedback/src/index.ts b/packages/feedback/src/index.ts index e8233ec2455e..c182c98669c3 100644 --- a/packages/feedback/src/index.ts +++ b/packages/feedback/src/index.ts @@ -1,6 +1,7 @@ export { sendFeedback } from './core/sendFeedback'; export { feedbackIntegration } from './core/integration'; export { feedbackModalIntegration } from './modal/integration'; +export { getFeedback } from './core/getFeedback'; export { feedbackScreenshotIntegration } from './screenshot/integration'; export type { OptionalFeedbackConfiguration } from './types';