diff --git a/packages/integrations/src/captureconsole.ts b/packages/integrations/src/captureconsole.ts index 7243520c0661..ea9f2df40837 100644 --- a/packages/integrations/src/captureconsole.ts +++ b/packages/integrations/src/captureconsole.ts @@ -1,7 +1,5 @@ import { EventProcessor, Hub, Integration } from '@sentry/types'; -import { CONSOLE_LEVELS, fill, getGlobalObject, safeJoin, severityLevelFromString } from '@sentry/utils'; - -const global = getGlobalObject(); +import { CONSOLE_LEVELS, fill, GLOBAL_OBJ, safeJoin, severityLevelFromString } from '@sentry/utils'; /** Send Console API calls as Sentry Events */ export class CaptureConsole implements Integration { @@ -33,17 +31,18 @@ export class CaptureConsole implements Integration { * @inheritDoc */ public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - if (!('console' in global)) { + if (!('console' in GLOBAL_OBJ)) { return; } this._levels.forEach((level: string) => { - if (!(level in global.console)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + if (!(level in (GLOBAL_OBJ as any).console)) { return; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - fill(global.console, level, (originalConsoleMethod: () => any) => (...args: any[]): void => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access + fill((GLOBAL_OBJ as any).console, level, (originalConsoleMethod: () => any) => (...args: any[]): void => { const hub = getCurrentHub(); if (hub.getIntegration(CaptureConsole)) { @@ -72,7 +71,7 @@ export class CaptureConsole implements Integration { // this fails for some browsers. :( if (originalConsoleMethod) { - originalConsoleMethod.apply(global.console, args); + originalConsoleMethod.apply(GLOBAL_OBJ.console, args); } }); }); diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index 1da4f77b3a3a..84d4c2531ee7 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { Event, EventProcessor, Hub, Integration } from '@sentry/types'; -import { getGlobalObject, logger, normalize, uuid4 } from '@sentry/utils'; +import { logger, normalize, uuid4, WINDOW } from '@sentry/utils'; import localForage from 'localforage'; type LocalForage = { @@ -30,12 +30,6 @@ export class Offline implements Integration { */ public readonly name: string = Offline.id; - /** - * the global instance - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public global: any; - /** * the current hub instance */ @@ -55,8 +49,6 @@ export class Offline implements Integration { * @inheritDoc */ public constructor(options: { maxStoredEvents?: number } = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.global = getGlobalObject(); this.maxStoredEvents = options.maxStoredEvents || 30; // set a reasonable default // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access this.offlineEventStore = localForage.createInstance({ @@ -70,8 +62,8 @@ export class Offline implements Integration { public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { this.hub = getCurrentHub(); - if ('addEventListener' in this.global) { - this.global.addEventListener('online', () => { + if ('addEventListener' in WINDOW) { + WINDOW.addEventListener('online', () => { void this._sendEvents().catch(() => { __DEBUG_BUILD__ && logger.warn('could not send cached events'); }); @@ -81,7 +73,7 @@ export class Offline implements Integration { const eventProcessor: EventProcessor = event => { if (this.hub && this.hub.getIntegration(Offline)) { // cache if we are positively offline - if ('navigator' in this.global && 'onLine' in this.global.navigator && !this.global.navigator.onLine) { + if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && !WINDOW.navigator.onLine) { __DEBUG_BUILD__ && logger.log('Event dropped due to being a offline - caching instead'); void this._cacheEvent(event) @@ -102,7 +94,7 @@ export class Offline implements Integration { addGlobalEventProcessor(eventProcessor); // if online now, send any events stored in a previous offline session - if ('navigator' in this.global && 'onLine' in this.global.navigator && this.global.navigator.onLine) { + if ('navigator' in WINDOW && 'onLine' in WINDOW.navigator && WINDOW.navigator.onLine) { void this._sendEvents().catch(() => { __DEBUG_BUILD__ && logger.warn('could not send cached events'); }); diff --git a/packages/integrations/src/reportingobserver.ts b/packages/integrations/src/reportingobserver.ts index 41e5247c2376..567e5627c2a6 100644 --- a/packages/integrations/src/reportingobserver.ts +++ b/packages/integrations/src/reportingobserver.ts @@ -1,5 +1,5 @@ import { EventProcessor, Hub, Integration } from '@sentry/types'; -import { getGlobalObject, supportsReportingObserver } from '@sentry/utils'; +import { supportsReportingObserver, WINDOW } from '@sentry/utils'; interface Report { [key: string]: unknown; @@ -76,7 +76,7 @@ export class ReportingObserver implements Integration { this._getCurrentHub = getCurrentHub; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - const observer = new (getGlobalObject().ReportingObserver)(this.handler.bind(this), { + const observer = new (WINDOW as any).ReportingObserver(this.handler.bind(this), { buffered: true, types: this._options.types, }); diff --git a/packages/integrations/test/offline.test.ts b/packages/integrations/test/offline.test.ts index 7bd77c047182..7cf5ca00825d 100644 --- a/packages/integrations/test/offline.test.ts +++ b/packages/integrations/test/offline.test.ts @@ -1,5 +1,5 @@ import { Event, EventProcessor, Hub, Integration, IntegrationClass } from '@sentry/types'; -import * as utils from '@sentry/utils'; +import { WINDOW } from '@sentry/utils'; import { Item, Offline } from '../src/offline'; @@ -34,12 +34,30 @@ jest.mock('localforage', () => ({ })); let integration: Offline; -let online: boolean; + +// We need to mock the WINDOW object so we can modify 'navigator.online' which is readonly +jest.mock('@sentry/utils', () => { + const originalModule = jest.requireActual('@sentry/utils'); + + return { + ...originalModule, + get WINDOW() { + return { + addEventListener: (_windowEvent: any, callback: any) => { + eventListeners.push(callback); + }, + navigator: { + onLine: false, + }, + }; + }, + }; +}); describe('Offline', () => { describe('when app is online', () => { beforeEach(() => { - online = true; + (WINDOW.navigator as any).onLine = true; initIntegration(); }); @@ -71,7 +89,7 @@ describe('Offline', () => { describe('when app is offline', () => { beforeEach(() => { - online = false; + (WINDOW.navigator as any).onLine = false; }); it('stores events in offline store', async () => { @@ -166,18 +184,6 @@ function initIntegration(options: { maxStoredEvents?: number } = {}): void { eventProcessors = []; events = []; - jest.spyOn(utils, 'getGlobalObject').mockImplementation( - () => - ({ - addEventListener: (_windowEvent: any, callback: any) => { - eventListeners.push(callback); - }, - navigator: { - onLine: online, - }, - } as any), - ); - integration = new Offline(options); } diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts index 118fe200d46c..d31fd5e45233 100644 --- a/packages/node/src/sdk.ts +++ b/packages/node/src/sdk.ts @@ -10,7 +10,7 @@ import { import { SessionStatus, StackParser } from '@sentry/types'; import { createStackParser, - getGlobalObject, + GLOBAL_OBJ, logger, nodeStackLineParser, stackParserFromStackParserOptions, @@ -233,9 +233,8 @@ export function getSentryRelease(fallback?: string): string | undefined { } // This supports the variable that sentry-webpack-plugin injects - const global = getGlobalObject(); - if (global.SENTRY_RELEASE && global.SENTRY_RELEASE.id) { - return global.SENTRY_RELEASE.id; + if (GLOBAL_OBJ.SENTRY_RELEASE && GLOBAL_OBJ.SENTRY_RELEASE.id) { + return GLOBAL_OBJ.SENTRY_RELEASE.id; } return (