From a5bfa8013ab84c6e43a7d48b9a0da197d2b32443 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 26 Sep 2022 11:36:31 +0100 Subject: [PATCH] feat(utils): Modern implementation of `getGlobalObject` (#5809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaces `getGlobalObject` global object detection with a modern implementation taken from `core-js` which is then modified/simplified a little - Prioritises `globalThis` which was previously removed due to requiring a TypeScript version which was required in a no longer supported version of Angular (#2978) - This is a requirement for future support of other js runtimes (#5611) - No longer uses `isNodeEnv` 🎉 - Caches the global so it doesn't need to be evaluated for every invocation of `getGlobalObject` --- packages/utils/src/global.ts | 54 +++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/packages/utils/src/global.ts b/packages/utils/src/global.ts index a8b4b7ce0b0e..8515e2af82eb 100644 --- a/packages/utils/src/global.ts +++ b/packages/utils/src/global.ts @@ -7,8 +7,6 @@ import { Integration } from '@sentry/types'; -import { isNodeEnv } from './node'; - /** Internal */ interface SentryGlobal { Sentry?: { @@ -26,7 +24,45 @@ interface SentryGlobal { }; } -const fallbackGlobalObject = {}; +// The code below for 'isGlobalObj' and 'GLOBAL' was copied from core-js before modification +// https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js +// core-js has the following licence: +// +// Copyright (c) 2014-2022 Denis Pushkarev +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** Returns 'obj' if it's the global object, otherwise returns undefined */ +function isGlobalObj(obj: { Math?: Math }): any | undefined { + return obj && obj.Math == Math ? obj : undefined; +} + +const GLOBAL = + (typeof globalThis == 'object' && isGlobalObj(globalThis)) || + // eslint-disable-next-line no-restricted-globals + (typeof window == 'object' && isGlobalObj(window)) || + (typeof self == 'object' && isGlobalObj(self)) || + (typeof global == 'object' && isGlobalObj(global)) || + (function (this: any) { + return this; + })() || + {}; /** * Safely get global scope object @@ -34,15 +70,7 @@ const fallbackGlobalObject = {}; * @returns Global scope object */ export function getGlobalObject(): T & SentryGlobal { - return ( - isNodeEnv() - ? global - : typeof window !== 'undefined' // eslint-disable-line no-restricted-globals - ? window // eslint-disable-line no-restricted-globals - : typeof self !== 'undefined' - ? self - : fallbackGlobalObject - ) as T & SentryGlobal; + return GLOBAL as T & SentryGlobal; } /** @@ -57,7 +85,7 @@ export function getGlobalObject(): T & SentryGlobal { * @returns the singleton */ export function getGlobalSingleton(name: keyof SentryGlobal['__SENTRY__'], creator: () => T, obj?: unknown): T { - const global = (obj || getGlobalObject()) as SentryGlobal; + const global = (obj || GLOBAL) as SentryGlobal; const __SENTRY__ = (global.__SENTRY__ = global.__SENTRY__ || {}); const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator()); return singleton;