{"version":3,"file":"getNativeImplementation.js","sources":["../../src/getNativeImplementation.ts"],"sourcesContent":["import { debug, isNativeFunction } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport { WINDOW } from './types';\n\n/**\n * We generally want to use window.fetch / window.setTimeout.\n * However, in some cases this may be wrapped (e.g. by Zone.js for Angular),\n * so we try to get an unpatched version of this from a sandboxed iframe.\n */\n\ninterface CacheableImplementations {\n setTimeout: typeof WINDOW.setTimeout;\n fetch: typeof WINDOW.fetch;\n}\n\nconst cachedImplementations: Partial = {};\n\n/**\n * Get the native implementation of a browser function.\n *\n * This can be used to ensure we get an unwrapped version of a function, in cases where a wrapped function can lead to problems.\n *\n * The following methods can be retrieved:\n * - `setTimeout`: This can be wrapped by e.g. Angular, causing change detection to be triggered.\n * - `fetch`: This can be wrapped by e.g. ad-blockers, causing an infinite loop when a request is blocked.\n */\nexport function getNativeImplementation(\n name: T,\n): CacheableImplementations[T] {\n const cached = cachedImplementations[name];\n if (cached) {\n return cached;\n }\n\n let impl = WINDOW[name] as CacheableImplementations[T];\n\n // Fast path to avoid DOM I/O\n if (isNativeFunction(impl)) {\n return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n }\n\n const document = WINDOW.document;\n // eslint-disable-next-line deprecation/deprecation\n if (document && typeof document.createElement === 'function') {\n try {\n const sandbox = document.createElement('iframe');\n sandbox.hidden = true;\n document.head.appendChild(sandbox);\n const contentWindow = sandbox.contentWindow;\n if (contentWindow?.[name]) {\n impl = contentWindow[name] as CacheableImplementations[T];\n }\n document.head.removeChild(sandbox);\n } catch (e) {\n // Could not create sandbox iframe, just use window.xxx\n DEBUG_BUILD && debug.warn(`Could not create sandbox iframe for ${name} check, bailing to window.${name}: `, e);\n }\n }\n\n // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n if (!impl) {\n return impl;\n }\n\n return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n}\n\n/** Clear a cached implementation. */\nexport function clearCachedImplementation(name: keyof CacheableImplementations): void {\n cachedImplementations[name] = undefined;\n}\n\n/**\n * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.\n * Whenever someone wraps the Fetch API and returns the wrong promise chain,\n * this chain becomes orphaned and there is no possible way to capture it's rejections\n * other than allowing it bubble up to this very handler. eg.\n *\n * const f = window.fetch;\n * window.fetch = function () {\n * const p = f.apply(this, arguments);\n *\n * p.then(function() {\n * console.log('hi.');\n * });\n *\n * return p;\n * }\n *\n * `p.then(function () { ... })` is producing a completely separate promise chain,\n * however, what's returned is `p` - the result of original `fetch` call.\n *\n * This mean, that whenever we use the Fetch API to send our own requests, _and_\n * some ad-blocker blocks it, this orphaned chain will _always_ reject,\n * effectively causing another event to be captured.\n * This makes a whole process become an infinite loop, which we need to somehow\n * deal with, and break it in one way or another.\n *\n * To deal with this issue, we are making sure that we _always_ use the real\n * browser Fetch API, instead of relying on what `window.fetch` exposes.\n * The only downside to this would be missing our own requests as breadcrumbs,\n * but because we are already not doing this, it should be just fine.\n *\n * Possible failed fetch error messages per-browser:\n *\n * Chrome: Failed to fetch\n * Edge: Failed to Fetch\n * Firefox: NetworkError when attempting to fetch resource\n * Safari: resource blocked by content blocker\n */\nexport function fetch(...rest: Parameters): ReturnType {\n return getNativeImplementation('fetch')(...rest);\n}\n\n/**\n * Get an unwrapped `setTimeout` method.\n * This ensures that even if e.g. Angular wraps `setTimeout`, we get the native implementation,\n * avoiding triggering change detection.\n */\nexport function setTimeout(...rest: Parameters): ReturnType {\n return getNativeImplementation('setTimeout')(...rest);\n}\n"],"names":[],"mappings":";;;;AAIA;AACA;AACA;AACA;AACA;;AAOA,MAAM,qBAAqB,GAAsC,EAAE;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB;AACvC,EAAE,IAAI;AACN,EAA+B;AAC/B,EAAE,MAAM,MAAA,GAAS,qBAAqB,CAAC,IAAI,CAAC;AAC5C,EAAE,IAAI,MAAM,EAAE;AACd,IAAI,OAAO,MAAM;AACjB,EAAE;;AAEF,EAAE,IAAI,IAAA,GAAO,MAAM,CAAC,IAAI,CAAA;;AAExB;AACA,EAAE,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE;AAC9B,IAAI,QAAQ,qBAAqB,CAAC,IAAI,CAAA,GAAI,IAAI,CAAC,IAAI,CAAC,MAAM;AAC1D,EAAE;;AAEF,EAAE,MAAM,QAAA,GAAW,MAAM,CAAC,QAAQ;AAClC;AACA,EAAE,IAAI,QAAA,IAAY,OAAO,QAAQ,CAAC,aAAA,KAAkB,UAAU,EAAE;AAChE,IAAI,IAAI;AACR,MAAM,MAAM,UAAU,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AACtD,MAAM,OAAO,CAAC,MAAA,GAAS,IAAI;AAC3B,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AACxC,MAAM,MAAM,aAAA,GAAgB,OAAO,CAAC,aAAa;AACjD,MAAM,IAAI,aAAa,GAAG,IAAI,CAAC,EAAE;AACjC,QAAQ,IAAA,GAAO,aAAa,CAAC,IAAI,CAAA;AACjC,MAAM;AACN,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AACxC,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB;AACA,MAAM,eAAe,KAAK,CAAC,IAAI,CAAC,CAAC,oCAAoC,EAAE,IAAI,CAAC,0BAA0B,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACpH,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,IAAI,CAAC,IAAI,EAAE;AACb,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF,EAAE,QAAQ,qBAAqB,CAAC,IAAI,CAAA,GAAI,IAAI,CAAC,IAAI,CAAC,MAAM;AACxD;;AAEA;AACO,SAAS,yBAAyB,CAAC,IAAI,EAAwC;AACtF,EAAE,qBAAqB,CAAC,IAAI,CAAA,GAAI,SAAS;AACzC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,KAAK,CAAC,GAAG,IAAI,EAAoE;AACjG,EAAE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,UAAU,CAAC,GAAG,IAAI,EAA8E;AAChH,EAAE,OAAO,uBAAuB,CAAC,YAAY,CAAC,CAAC,GAAG,IAAI,CAAC;AACvD;;;;"}