@sentry/browser 9.22.0 → 9.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/npm/cjs/client.js +34 -24
- package/build/npm/cjs/client.js.map +1 -1
- package/build/npm/cjs/index.js +1 -0
- package/build/npm/cjs/index.js.map +1 -1
- package/build/npm/cjs/integrations/browserapierrors.js +18 -2
- package/build/npm/cjs/integrations/browserapierrors.js.map +1 -1
- package/build/npm/cjs/sdk.js +10 -89
- package/build/npm/cjs/sdk.js.map +1 -1
- package/build/npm/cjs/tracing/browserTracingIntegration.js +37 -41
- package/build/npm/cjs/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/cjs/utils/detectBrowserExtension.js +59 -0
- package/build/npm/cjs/utils/detectBrowserExtension.js.map +1 -0
- package/build/npm/esm/client.js +34 -25
- package/build/npm/esm/client.js.map +1 -1
- package/build/npm/esm/index.js +1 -1
- package/build/npm/esm/integrations/browserapierrors.js +18 -2
- package/build/npm/esm/integrations/browserapierrors.js.map +1 -1
- package/build/npm/esm/package.json +1 -1
- package/build/npm/esm/sdk.js +12 -90
- package/build/npm/esm/sdk.js.map +1 -1
- package/build/npm/esm/tracing/browserTracingIntegration.js +39 -43
- package/build/npm/esm/tracing/browserTracingIntegration.js.map +1 -1
- package/build/npm/esm/utils/detectBrowserExtension.js +57 -0
- package/build/npm/esm/utils/detectBrowserExtension.js.map +1 -0
- package/build/npm/types/client.d.ts +9 -5
- package/build/npm/types/client.d.ts.map +1 -1
- package/build/npm/types/exports.d.ts +1 -1
- package/build/npm/types/exports.d.ts.map +1 -1
- package/build/npm/types/integrations/browserapierrors.d.ts +8 -0
- package/build/npm/types/integrations/browserapierrors.d.ts.map +1 -1
- package/build/npm/types/sdk.d.ts +1 -3
- package/build/npm/types/sdk.d.ts.map +1 -1
- package/build/npm/types/tracing/browserTracingIntegration.d.ts +7 -0
- package/build/npm/types/tracing/browserTracingIntegration.d.ts.map +1 -1
- package/build/npm/types/utils/detectBrowserExtension.d.ts +6 -0
- package/build/npm/types/utils/detectBrowserExtension.d.ts.map +1 -0
- package/build/npm/types-ts3.8/client.d.ts +9 -5
- package/build/npm/types-ts3.8/exports.d.ts +1 -1
- package/build/npm/types-ts3.8/integrations/browserapierrors.d.ts +8 -0
- package/build/npm/types-ts3.8/sdk.d.ts +1 -3
- package/build/npm/types-ts3.8/tracing/browserTracingIntegration.d.ts +7 -0
- package/build/npm/types-ts3.8/utils/detectBrowserExtension.d.ts +6 -0
- package/package.json +7 -7
package/build/npm/cjs/client.js
CHANGED
|
@@ -4,13 +4,12 @@ const core = require('@sentry/core');
|
|
|
4
4
|
const eventbuilder = require('./eventbuilder.js');
|
|
5
5
|
const helpers = require('./helpers.js');
|
|
6
6
|
|
|
7
|
-
const DEFAULT_FLUSH_INTERVAL = 5000;
|
|
8
|
-
|
|
9
7
|
/**
|
|
10
|
-
*
|
|
11
|
-
* @see @sentry/core Options for more information.
|
|
8
|
+
* A magic string that build tooling can leverage in order to inject a release value into the SDK.
|
|
12
9
|
*/
|
|
13
10
|
|
|
11
|
+
const DEFAULT_FLUSH_INTERVAL = 5000;
|
|
12
|
+
|
|
14
13
|
/**
|
|
15
14
|
* The Sentry Browser SDK Client.
|
|
16
15
|
*
|
|
@@ -25,51 +24,47 @@ class BrowserClient extends core.Client {
|
|
|
25
24
|
* @param options Configuration options for this SDK.
|
|
26
25
|
*/
|
|
27
26
|
constructor(options) {
|
|
28
|
-
const opts =
|
|
29
|
-
// We default this to true, as it is the safer scenario
|
|
30
|
-
parentSpanIsAlwaysRootSpan: true,
|
|
31
|
-
...options,
|
|
32
|
-
};
|
|
27
|
+
const opts = applyDefaultOptions(options);
|
|
33
28
|
const sdkSource = helpers.WINDOW.SENTRY_SDK_SOURCE || core.getSDKSource();
|
|
34
29
|
core.applySdkMetadata(opts, 'browser', ['browser'], sdkSource);
|
|
35
30
|
|
|
36
31
|
super(opts);
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
const client = this;
|
|
40
|
-
const { sendDefaultPii, _experiments } = client._options;
|
|
33
|
+
const { sendDefaultPii, sendClientReports, _experiments } = this._options;
|
|
41
34
|
const enableLogs = _experiments?.enableLogs;
|
|
42
35
|
|
|
43
|
-
if (
|
|
36
|
+
if (helpers.WINDOW.document && (sendClientReports || enableLogs)) {
|
|
44
37
|
helpers.WINDOW.document.addEventListener('visibilitychange', () => {
|
|
45
38
|
if (helpers.WINDOW.document.visibilityState === 'hidden') {
|
|
46
|
-
|
|
39
|
+
if (sendClientReports) {
|
|
40
|
+
this._flushOutcomes();
|
|
41
|
+
}
|
|
47
42
|
if (enableLogs) {
|
|
48
|
-
core._INTERNAL_flushLogsBuffer(
|
|
43
|
+
core._INTERNAL_flushLogsBuffer(this);
|
|
49
44
|
}
|
|
50
45
|
}
|
|
51
46
|
});
|
|
52
47
|
}
|
|
53
48
|
|
|
54
49
|
if (enableLogs) {
|
|
55
|
-
|
|
56
|
-
core._INTERNAL_flushLogsBuffer(
|
|
50
|
+
this.on('flush', () => {
|
|
51
|
+
core._INTERNAL_flushLogsBuffer(this);
|
|
57
52
|
});
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
clearTimeout(
|
|
54
|
+
this.on('afterCaptureLog', () => {
|
|
55
|
+
if (this._logFlushIdleTimeout) {
|
|
56
|
+
clearTimeout(this._logFlushIdleTimeout);
|
|
62
57
|
}
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
core._INTERNAL_flushLogsBuffer(
|
|
59
|
+
this._logFlushIdleTimeout = setTimeout(() => {
|
|
60
|
+
core._INTERNAL_flushLogsBuffer(this);
|
|
66
61
|
}, DEFAULT_FLUSH_INTERVAL);
|
|
67
62
|
});
|
|
68
63
|
}
|
|
69
64
|
|
|
70
65
|
if (sendDefaultPii) {
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
this.on('postprocessEvent', core.addAutoIpAddressToUser);
|
|
67
|
+
this.on('beforeSendSession', core.addAutoIpAddressToSession);
|
|
73
68
|
}
|
|
74
69
|
}
|
|
75
70
|
|
|
@@ -106,5 +101,20 @@ class BrowserClient extends core.Client {
|
|
|
106
101
|
}
|
|
107
102
|
}
|
|
108
103
|
|
|
104
|
+
/** Exported only for tests. */
|
|
105
|
+
function applyDefaultOptions(optionsArg) {
|
|
106
|
+
return {
|
|
107
|
+
release:
|
|
108
|
+
typeof __SENTRY_RELEASE__ === 'string' // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value
|
|
109
|
+
? __SENTRY_RELEASE__
|
|
110
|
+
: helpers.WINDOW.SENTRY_RELEASE?.id, // This supports the variable that sentry-webpack-plugin injects
|
|
111
|
+
sendClientReports: true,
|
|
112
|
+
// We default this to true, as it is the safer scenario
|
|
113
|
+
parentSpanIsAlwaysRootSpan: true,
|
|
114
|
+
...optionsArg,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
exports.BrowserClient = BrowserClient;
|
|
119
|
+
exports.applyDefaultOptions = applyDefaultOptions;
|
|
110
120
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n _INTERNAL_flushLogsBuffer,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n Client,\n getSDKSource,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\nconst DEFAULT_FLUSH_INTERVAL = 5000;\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n _INTERNAL_flushLogsBuffer,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n Client,\n getSDKSource,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\n/**\n * A magic string that build tooling can leverage in order to inject a release value into the SDK.\n */\ndeclare const __SENTRY_RELEASE__: string | undefined;\n\nconst DEFAULT_FLUSH_INTERVAL = 5000;\n\ntype BrowserSpecificOptions = BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /** If configured, this URL will be used as base URL for lazy loading integration. */\n cdnBaseUrl?: string;\n };\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n BrowserSpecificOptions & {\n /**\n * Important: Only set this option if you know what you are doing!\n *\n * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n * In case it is, it will stop initialization and log a warning\n * because browser extensions require a different Sentry initialization process:\n * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n *\n * Setting up the SDK in a browser extension with global error monitoring is not recommended\n * and will likely flood you with errors from other web sites or extensions. This can heavily\n * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n *\n * If this check wrongfully flags your setup as a browser extension, you can set this\n * option to `true` to skip the check.\n *\n * @default false\n */\n skipBrowserExtensionCheck?: boolean;\n };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> & BrowserSpecificOptions;\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends Client<BrowserClientOptions> {\n private _logFlushIdleTimeout: ReturnType<typeof setTimeout> | undefined;\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n public constructor(options: BrowserClientOptions) {\n const opts = applyDefaultOptions(options);\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n const { sendDefaultPii, sendClientReports, _experiments } = this._options;\n const enableLogs = _experiments?.enableLogs;\n\n if (WINDOW.document && (sendClientReports || enableLogs)) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n if (sendClientReports) {\n this._flushOutcomes();\n }\n if (enableLogs) {\n _INTERNAL_flushLogsBuffer(this);\n }\n }\n });\n }\n\n if (enableLogs) {\n this.on('flush', () => {\n _INTERNAL_flushLogsBuffer(this);\n });\n\n this.on('afterCaptureLog', () => {\n if (this._logFlushIdleTimeout) {\n clearTimeout(this._logFlushIdleTimeout);\n }\n\n this._logFlushIdleTimeout = setTimeout(() => {\n _INTERNAL_flushLogsBuffer(this);\n }, DEFAULT_FLUSH_INTERVAL);\n });\n }\n\n if (sendDefaultPii) {\n this.on('postprocessEvent', addAutoIpAddressToUser);\n this.on('beforeSendSession', addAutoIpAddressToSession);\n }\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n event.platform = event.platform || 'javascript';\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n}\n\n/** Exported only for tests. */\nexport function applyDefaultOptions<T extends Partial<BrowserClientOptions>>(optionsArg: T): T {\n return {\n release:\n typeof __SENTRY_RELEASE__ === 'string' // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value\n ? __SENTRY_RELEASE__\n : WINDOW.SENTRY_RELEASE?.id, // This supports the variable that sentry-webpack-plugin injects\n sendClientReports: true,\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...optionsArg,\n };\n}\n"],"names":["Client","WINDOW","getSDKSource","applySdkMetadata","_INTERNAL_flushLogsBuffer","addAutoIpAddressToUser","addAutoIpAddressToSession","eventFromException","eventFromMessage"],"mappings":"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"}
|
package/build/npm/cjs/index.js
CHANGED
|
@@ -79,6 +79,7 @@ exports.getSpanDescendants = core.getSpanDescendants;
|
|
|
79
79
|
exports.getSpanStatusFromHttpCode = core.getSpanStatusFromHttpCode;
|
|
80
80
|
exports.inboundFiltersIntegration = core.inboundFiltersIntegration;
|
|
81
81
|
exports.instrumentSupabaseClient = core.instrumentSupabaseClient;
|
|
82
|
+
exports.isEnabled = core.isEnabled;
|
|
82
83
|
exports.isInitialized = core.isInitialized;
|
|
83
84
|
exports.lastEventId = core.lastEventId;
|
|
84
85
|
exports.makeMultiplexedTransport = core.makeMultiplexedTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -46,6 +46,7 @@ const _browserApiErrorsIntegration = ((options = {}) => {
|
|
|
46
46
|
requestAnimationFrame: true,
|
|
47
47
|
setInterval: true,
|
|
48
48
|
setTimeout: true,
|
|
49
|
+
unregisterOriginalCallbacks: false,
|
|
49
50
|
...options,
|
|
50
51
|
};
|
|
51
52
|
|
|
@@ -73,7 +74,7 @@ const _browserApiErrorsIntegration = ((options = {}) => {
|
|
|
73
74
|
const eventTargetOption = _options.eventTarget;
|
|
74
75
|
if (eventTargetOption) {
|
|
75
76
|
const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;
|
|
76
|
-
eventTarget.forEach(_wrapEventTarget);
|
|
77
|
+
eventTarget.forEach(target => _wrapEventTarget(target, _options));
|
|
77
78
|
}
|
|
78
79
|
},
|
|
79
80
|
};
|
|
@@ -151,7 +152,7 @@ function _wrapXHR(originalSend) {
|
|
|
151
152
|
};
|
|
152
153
|
}
|
|
153
154
|
|
|
154
|
-
function _wrapEventTarget(target) {
|
|
155
|
+
function _wrapEventTarget(target, integrationOptions) {
|
|
155
156
|
const globalObject = helpers.WINDOW ;
|
|
156
157
|
const proto = globalObject[target]?.prototype;
|
|
157
158
|
|
|
@@ -188,6 +189,10 @@ function _wrapEventTarget(target) {
|
|
|
188
189
|
// can sometimes get 'Permission denied to access property "handle Event'
|
|
189
190
|
}
|
|
190
191
|
|
|
192
|
+
if (integrationOptions.unregisterOriginalCallbacks) {
|
|
193
|
+
unregisterOriginalCallback(this, eventName, fn);
|
|
194
|
+
}
|
|
195
|
+
|
|
191
196
|
return original.apply(this, [
|
|
192
197
|
eventName,
|
|
193
198
|
helpers.wrap(fn, {
|
|
@@ -244,5 +249,16 @@ function isEventListenerObject(obj) {
|
|
|
244
249
|
return typeof (obj ).handleEvent === 'function';
|
|
245
250
|
}
|
|
246
251
|
|
|
252
|
+
function unregisterOriginalCallback(target, eventName, fn) {
|
|
253
|
+
if (
|
|
254
|
+
target &&
|
|
255
|
+
typeof target === 'object' &&
|
|
256
|
+
'removeEventListener' in target &&
|
|
257
|
+
typeof target.removeEventListener === 'function'
|
|
258
|
+
) {
|
|
259
|
+
target.removeEventListener(eventName, fn);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
247
263
|
exports.browserApiErrorsIntegration = browserApiErrorsIntegration;
|
|
248
264
|
//# sourceMappingURL=browserapierrors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserapierrors.js","sources":["../../../../src/integrations/browserapierrors.ts"],"sourcesContent":["import type { IntegrationFn, WrappedFunction } from '@sentry/core';\nimport { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core';\nimport { WINDOW, wrap } from '../helpers';\n\nconst DEFAULT_EVENT_TARGET = [\n 'EventTarget',\n 'Window',\n 'Node',\n 'ApplicationCache',\n 'AudioTrackList',\n 'BroadcastChannel',\n 'ChannelMergerNode',\n 'CryptoOperation',\n 'EventSource',\n 'FileReader',\n 'HTMLUnknownElement',\n 'IDBDatabase',\n 'IDBRequest',\n 'IDBTransaction',\n 'KeyOperation',\n 'MediaController',\n 'MessagePort',\n 'ModalWindow',\n 'Notification',\n 'SVGElementInstance',\n 'Screen',\n 'SharedWorker',\n 'TextTrack',\n 'TextTrackCue',\n 'TextTrackList',\n 'WebSocket',\n 'WebSocketWorker',\n 'Worker',\n 'XMLHttpRequest',\n 'XMLHttpRequestEventTarget',\n 'XMLHttpRequestUpload',\n];\n\nconst INTEGRATION_NAME = 'BrowserApiErrors';\n\ntype XMLHttpRequestProp = 'onload' | 'onerror' | 'onprogress' | 'onreadystatechange';\n\ninterface BrowserApiErrorsOptions {\n setTimeout: boolean;\n setInterval: boolean;\n requestAnimationFrame: boolean;\n XMLHttpRequest: boolean;\n eventTarget: boolean | string[];\n}\n\nconst _browserApiErrorsIntegration = ((options: Partial<BrowserApiErrorsOptions> = {}) => {\n const _options = {\n XMLHttpRequest: true,\n eventTarget: true,\n requestAnimationFrame: true,\n setInterval: true,\n setTimeout: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n // TODO: This currently only works for the first client this is setup\n // We may want to adjust this to check for client etc.\n setupOnce() {\n if (_options.setTimeout) {\n fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n }\n\n if (_options.setInterval) {\n fill(WINDOW, 'setInterval', _wrapTimeFunction);\n }\n\n if (_options.requestAnimationFrame) {\n fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n }\n\n if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n }\n\n const eventTargetOption = _options.eventTarget;\n if (eventTargetOption) {\n const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n eventTarget.forEach(_wrapEventTarget);\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nexport const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original: () => void): () => number {\n return function (this: unknown, ...args: unknown[]): number {\n const originalCallback = args[0];\n args[0] = wrap(originalCallback, {\n mechanism: {\n data: { function: getFunctionName(original) },\n handled: false,\n type: 'instrument',\n },\n });\n return original.apply(this, args);\n };\n}\n\nfunction _wrapRAF(original: () => void): (callback: () => void) => unknown {\n return function (this: unknown, callback: () => void): () => void {\n return original.apply(this, [\n wrap(callback, {\n mechanism: {\n data: {\n function: 'requestAnimationFrame',\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n }),\n ]);\n };\n}\n\nfunction _wrapXHR(originalSend: () => void): () => void {\n return function (this: XMLHttpRequest, ...args: unknown[]): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const xhr = this;\n const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n xmlHttpRequestProps.forEach(prop => {\n if (prop in xhr && typeof xhr[prop] === 'function') {\n fill(xhr, prop, function (original) {\n const wrapOptions = {\n mechanism: {\n data: {\n function: prop,\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n };\n\n // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n const originalFunction = getOriginalFunction(original);\n if (originalFunction) {\n wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n }\n\n // Otherwise wrap directly\n return wrap(original, wrapOptions);\n });\n }\n });\n\n return originalSend.apply(this, args);\n };\n}\n\nfunction _wrapEventTarget(target: string): void {\n const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n const proto = globalObject[target]?.prototype;\n\n // eslint-disable-next-line no-prototype-builtins\n if (!proto?.hasOwnProperty?.('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (original: VoidFunction): (\n ...args: Parameters<typeof WINDOW.addEventListener>\n ) => ReturnType<typeof WINDOW.addEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n try {\n if (isEventListenerObject(fn)) {\n // ESlint disable explanation:\n // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n // introduce a bug here, because bind returns a new function that doesn't have our\n // flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n // Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n fn.handleEvent = wrap(fn.handleEvent, {\n mechanism: {\n data: {\n function: 'handleEvent',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n });\n }\n } catch {\n // can sometimes get 'Permission denied to access property \"handle Event'\n }\n\n return original.apply(this, [\n eventName,\n wrap(fn, {\n mechanism: {\n data: {\n function: 'addEventListener',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n }),\n options,\n ]);\n };\n });\n\n fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction): (\n this: unknown,\n ...args: Parameters<typeof WINDOW.removeEventListener>\n ) => ReturnType<typeof WINDOW.removeEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n /**\n * There are 2 possible scenarios here:\n *\n * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n * as a pass-through, and call original `removeEventListener` with it.\n *\n * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n *\n * When someone adds a handler prior to initialization, and then do it again, but after,\n * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n * to get rid of the initial handler and it'd stick there forever.\n */\n try {\n const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__;\n if (originalEventHandler) {\n originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n }\n } catch (e) {\n // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n }\n return originalRemoveEventListener.call(this, eventName, fn, options);\n };\n });\n}\n\nfunction isEventListenerObject(obj: unknown): obj is EventListenerObject {\n return typeof (obj as EventListenerObject).handleEvent === 'function';\n}\n"],"names":["fill","WINDOW","defineIntegration","wrap","getFunctionName","getOriginalFunction"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browserapierrors.js","sources":["../../../../src/integrations/browserapierrors.ts"],"sourcesContent":["import type { IntegrationFn, WrappedFunction } from '@sentry/core';\nimport { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core';\nimport { WINDOW, wrap } from '../helpers';\n\nconst DEFAULT_EVENT_TARGET = [\n 'EventTarget',\n 'Window',\n 'Node',\n 'ApplicationCache',\n 'AudioTrackList',\n 'BroadcastChannel',\n 'ChannelMergerNode',\n 'CryptoOperation',\n 'EventSource',\n 'FileReader',\n 'HTMLUnknownElement',\n 'IDBDatabase',\n 'IDBRequest',\n 'IDBTransaction',\n 'KeyOperation',\n 'MediaController',\n 'MessagePort',\n 'ModalWindow',\n 'Notification',\n 'SVGElementInstance',\n 'Screen',\n 'SharedWorker',\n 'TextTrack',\n 'TextTrackCue',\n 'TextTrackList',\n 'WebSocket',\n 'WebSocketWorker',\n 'Worker',\n 'XMLHttpRequest',\n 'XMLHttpRequestEventTarget',\n 'XMLHttpRequestUpload',\n];\n\nconst INTEGRATION_NAME = 'BrowserApiErrors';\n\ntype XMLHttpRequestProp = 'onload' | 'onerror' | 'onprogress' | 'onreadystatechange';\n\ninterface BrowserApiErrorsOptions {\n setTimeout: boolean;\n setInterval: boolean;\n requestAnimationFrame: boolean;\n XMLHttpRequest: boolean;\n eventTarget: boolean | string[];\n\n /**\n * If you experience issues with this integration causing double-invocations of event listeners,\n * try setting this option to `true`. It will unregister the original callbacks from the event targets\n * before adding the instrumented callback.\n *\n * @default false\n */\n unregisterOriginalCallbacks: boolean;\n}\n\nconst _browserApiErrorsIntegration = ((options: Partial<BrowserApiErrorsOptions> = {}) => {\n const _options = {\n XMLHttpRequest: true,\n eventTarget: true,\n requestAnimationFrame: true,\n setInterval: true,\n setTimeout: true,\n unregisterOriginalCallbacks: false,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n // TODO: This currently only works for the first client this is setup\n // We may want to adjust this to check for client etc.\n setupOnce() {\n if (_options.setTimeout) {\n fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n }\n\n if (_options.setInterval) {\n fill(WINDOW, 'setInterval', _wrapTimeFunction);\n }\n\n if (_options.requestAnimationFrame) {\n fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n }\n\n if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n }\n\n const eventTargetOption = _options.eventTarget;\n if (eventTargetOption) {\n const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n eventTarget.forEach(target => _wrapEventTarget(target, _options));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nexport const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original: () => void): () => number {\n return function (this: unknown, ...args: unknown[]): number {\n const originalCallback = args[0];\n args[0] = wrap(originalCallback, {\n mechanism: {\n data: { function: getFunctionName(original) },\n handled: false,\n type: 'instrument',\n },\n });\n return original.apply(this, args);\n };\n}\n\nfunction _wrapRAF(original: () => void): (callback: () => void) => unknown {\n return function (this: unknown, callback: () => void): () => void {\n return original.apply(this, [\n wrap(callback, {\n mechanism: {\n data: {\n function: 'requestAnimationFrame',\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n }),\n ]);\n };\n}\n\nfunction _wrapXHR(originalSend: () => void): () => void {\n return function (this: XMLHttpRequest, ...args: unknown[]): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const xhr = this;\n const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n xmlHttpRequestProps.forEach(prop => {\n if (prop in xhr && typeof xhr[prop] === 'function') {\n fill(xhr, prop, function (original) {\n const wrapOptions = {\n mechanism: {\n data: {\n function: prop,\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n };\n\n // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n const originalFunction = getOriginalFunction(original);\n if (originalFunction) {\n wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n }\n\n // Otherwise wrap directly\n return wrap(original, wrapOptions);\n });\n }\n });\n\n return originalSend.apply(this, args);\n };\n}\n\nfunction _wrapEventTarget(target: string, integrationOptions: BrowserApiErrorsOptions): void {\n const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n const proto = globalObject[target]?.prototype;\n\n // eslint-disable-next-line no-prototype-builtins\n if (!proto?.hasOwnProperty?.('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (original: VoidFunction): (\n ...args: Parameters<typeof WINDOW.addEventListener>\n ) => ReturnType<typeof WINDOW.addEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n try {\n if (isEventListenerObject(fn)) {\n // ESlint disable explanation:\n // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n // introduce a bug here, because bind returns a new function that doesn't have our\n // flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n // Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n fn.handleEvent = wrap(fn.handleEvent, {\n mechanism: {\n data: {\n function: 'handleEvent',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n });\n }\n } catch {\n // can sometimes get 'Permission denied to access property \"handle Event'\n }\n\n if (integrationOptions.unregisterOriginalCallbacks) {\n unregisterOriginalCallback(this, eventName, fn);\n }\n\n return original.apply(this, [\n eventName,\n wrap(fn, {\n mechanism: {\n data: {\n function: 'addEventListener',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n }),\n options,\n ]);\n };\n });\n\n fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction): (\n this: unknown,\n ...args: Parameters<typeof WINDOW.removeEventListener>\n ) => ReturnType<typeof WINDOW.removeEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n /**\n * There are 2 possible scenarios here:\n *\n * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n * as a pass-through, and call original `removeEventListener` with it.\n *\n * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n *\n * When someone adds a handler prior to initialization, and then do it again, but after,\n * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n * to get rid of the initial handler and it'd stick there forever.\n */\n try {\n const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__;\n if (originalEventHandler) {\n originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n }\n } catch (e) {\n // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n }\n return originalRemoveEventListener.call(this, eventName, fn, options);\n };\n });\n}\n\nfunction isEventListenerObject(obj: unknown): obj is EventListenerObject {\n return typeof (obj as EventListenerObject).handleEvent === 'function';\n}\n\nfunction unregisterOriginalCallback(target: unknown, eventName: string, fn: EventListenerOrEventListenerObject): void {\n if (\n target &&\n typeof target === 'object' &&\n 'removeEventListener' in target &&\n typeof target.removeEventListener === 'function'\n ) {\n target.removeEventListener(eventName, fn);\n }\n}\n"],"names":["fill","WINDOW","defineIntegration","wrap","getFunctionName","getOriginalFunction"],"mappings":"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"}
|
package/build/npm/cjs/sdk.js
CHANGED
|
@@ -2,8 +2,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const core = require('@sentry/core');
|
|
4
4
|
const client = require('./client.js');
|
|
5
|
-
const debugBuild = require('./debug-build.js');
|
|
6
|
-
const helpers = require('./helpers.js');
|
|
7
5
|
const breadcrumbs = require('./integrations/breadcrumbs.js');
|
|
8
6
|
const browserapierrors = require('./integrations/browserapierrors.js');
|
|
9
7
|
const browsersession = require('./integrations/browsersession.js');
|
|
@@ -12,6 +10,7 @@ const httpcontext = require('./integrations/httpcontext.js');
|
|
|
12
10
|
const linkederrors = require('./integrations/linkederrors.js');
|
|
13
11
|
const stackParsers = require('./stack-parsers.js');
|
|
14
12
|
const fetch = require('./transports/fetch.js');
|
|
13
|
+
const detectBrowserExtension = require('./utils/detectBrowserExtension.js');
|
|
15
14
|
|
|
16
15
|
/** Get the default integrations for the browser SDK. */
|
|
17
16
|
function getDefaultIntegrations(_options) {
|
|
@@ -34,40 +33,6 @@ function getDefaultIntegrations(_options) {
|
|
|
34
33
|
];
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
/** Exported only for tests. */
|
|
38
|
-
function applyDefaultOptions(optionsArg = {}) {
|
|
39
|
-
const defaultOptions = {
|
|
40
|
-
defaultIntegrations: getDefaultIntegrations(),
|
|
41
|
-
release:
|
|
42
|
-
typeof __SENTRY_RELEASE__ === 'string' // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value
|
|
43
|
-
? __SENTRY_RELEASE__
|
|
44
|
-
: helpers.WINDOW.SENTRY_RELEASE?.id, // This supports the variable that sentry-webpack-plugin injects
|
|
45
|
-
sendClientReports: true,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
...defaultOptions,
|
|
50
|
-
...dropTopLevelUndefinedKeys(optionsArg),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* In contrast to the regular `dropUndefinedKeys` method,
|
|
56
|
-
* this one does not deep-drop keys, but only on the top level.
|
|
57
|
-
*/
|
|
58
|
-
function dropTopLevelUndefinedKeys(obj) {
|
|
59
|
-
const mutatetedObj = {};
|
|
60
|
-
|
|
61
|
-
for (const k of Object.getOwnPropertyNames(obj)) {
|
|
62
|
-
const key = k ;
|
|
63
|
-
if (obj[key] !== undefined) {
|
|
64
|
-
mutatetedObj[key] = obj[key];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return mutatetedObj;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
36
|
/**
|
|
72
37
|
* The Sentry Browser SDK Client.
|
|
73
38
|
*
|
|
@@ -114,19 +79,21 @@ function dropTopLevelUndefinedKeys(obj) {
|
|
|
114
79
|
*
|
|
115
80
|
* @see {@link BrowserOptions} for documentation on configuration options.
|
|
116
81
|
*/
|
|
117
|
-
function init(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
82
|
+
function init(options = {}) {
|
|
83
|
+
const shouldDisableBecauseIsBrowserExtenstion =
|
|
84
|
+
!options.skipBrowserExtensionCheck && detectBrowserExtension.checkAndWarnIfIsEmbeddedBrowserExtension();
|
|
121
85
|
|
|
122
|
-
const options = applyDefaultOptions(browserOptions);
|
|
123
86
|
const clientOptions = {
|
|
124
87
|
...options,
|
|
88
|
+
enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled,
|
|
125
89
|
stackParser: core.stackParserFromStackParserOptions(options.stackParser || stackParsers.defaultStackParser),
|
|
126
|
-
integrations: core.getIntegrationsToSetup(
|
|
90
|
+
integrations: core.getIntegrationsToSetup({
|
|
91
|
+
integrations: options.integrations,
|
|
92
|
+
defaultIntegrations:
|
|
93
|
+
options.defaultIntegrations == null ? getDefaultIntegrations() : options.defaultIntegrations,
|
|
94
|
+
}),
|
|
127
95
|
transport: options.transport || fetch.makeFetchTransport,
|
|
128
96
|
};
|
|
129
|
-
|
|
130
97
|
return core.initAndBind(client.BrowserClient, clientOptions);
|
|
131
98
|
}
|
|
132
99
|
|
|
@@ -146,52 +113,6 @@ function onLoad(callback) {
|
|
|
146
113
|
callback();
|
|
147
114
|
}
|
|
148
115
|
|
|
149
|
-
function _isEmbeddedBrowserExtension() {
|
|
150
|
-
if (typeof helpers.WINDOW.window === 'undefined') {
|
|
151
|
-
// No need to show the error if we're not in a browser window environment (e.g. service workers)
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const _window = helpers.WINDOW ;
|
|
156
|
-
|
|
157
|
-
// Running the SDK in NW.js, which appears like a browser extension but isn't, is also fine
|
|
158
|
-
// see: https://github.com/getsentry/sentry-javascript/issues/12668
|
|
159
|
-
if (_window.nw) {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const extensionObject = _window['chrome'] || _window['browser'];
|
|
164
|
-
|
|
165
|
-
if (!extensionObject?.runtime?.id) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const href = core.getLocationHref();
|
|
170
|
-
const extensionProtocols = ['chrome-extension', 'moz-extension', 'ms-browser-extension', 'safari-web-extension'];
|
|
171
|
-
|
|
172
|
-
// Running the SDK in a dedicated extension page and calling Sentry.init is fine; no risk of data leakage
|
|
173
|
-
const isDedicatedExtensionPage =
|
|
174
|
-
helpers.WINDOW === helpers.WINDOW.top && extensionProtocols.some(protocol => href.startsWith(`${protocol}://`));
|
|
175
|
-
|
|
176
|
-
return !isDedicatedExtensionPage;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function _checkForBrowserExtension() {
|
|
180
|
-
if (_isEmbeddedBrowserExtension()) {
|
|
181
|
-
if (debugBuild.DEBUG_BUILD) {
|
|
182
|
-
core.consoleSandbox(() => {
|
|
183
|
-
// eslint-disable-next-line no-console
|
|
184
|
-
console.error(
|
|
185
|
-
'[Sentry] You cannot use Sentry.init() in a browser extension, see: https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/',
|
|
186
|
-
);
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
exports.applyDefaultOptions = applyDefaultOptions;
|
|
195
116
|
exports.forceLoad = forceLoad;
|
|
196
117
|
exports.getDefaultIntegrations = getDefaultIntegrations;
|
|
197
118
|
exports.init = init;
|
package/build/npm/cjs/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/sdk.ts"],"sourcesContent":["import type { Client, Integration, Options } from '@sentry/core';\nimport {\n
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/sdk.ts"],"sourcesContent":["import type { Client, Integration, Options } from '@sentry/core';\nimport {\n dedupeIntegration,\n functionToStringIntegration,\n getIntegrationsToSetup,\n inboundFiltersIntegration,\n initAndBind,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport type { BrowserClientOptions, BrowserOptions } from './client';\nimport { BrowserClient } from './client';\nimport { breadcrumbsIntegration } from './integrations/breadcrumbs';\nimport { browserApiErrorsIntegration } from './integrations/browserapierrors';\nimport { browserSessionIntegration } from './integrations/browsersession';\nimport { globalHandlersIntegration } from './integrations/globalhandlers';\nimport { httpContextIntegration } from './integrations/httpcontext';\nimport { linkedErrorsIntegration } from './integrations/linkederrors';\nimport { defaultStackParser } from './stack-parsers';\nimport { makeFetchTransport } from './transports/fetch';\nimport { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension';\n\n/** Get the default integrations for the browser SDK. */\nexport function getDefaultIntegrations(_options: Options): Integration[] {\n /**\n * Note: Please make sure this stays in sync with Angular SDK, which re-exports\n * `getDefaultIntegrations` but with an adjusted set of integrations.\n */\n return [\n // TODO(v10): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n browserApiErrorsIntegration(),\n breadcrumbsIntegration(),\n globalHandlersIntegration(),\n linkedErrorsIntegration(),\n dedupeIntegration(),\n httpContextIntegration(),\n browserSessionIntegration(),\n ];\n}\n\n/**\n * The Sentry Browser SDK Client.\n *\n * To use this SDK, call the {@link init} function as early as possible when\n * loading the web page. To set context information or send manual events, use\n * the provided methods.\n *\n * @example\n *\n * ```\n *\n * import { init } from '@sentry/browser';\n *\n * init({\n * dsn: '__DSN__',\n * // ...\n * });\n * ```\n *\n * @example\n * ```\n *\n * import { addBreadcrumb } from '@sentry/browser';\n * addBreadcrumb({\n * message: 'My Breadcrumb',\n * // ...\n * });\n * ```\n *\n * @example\n *\n * ```\n *\n * import * as Sentry from '@sentry/browser';\n * Sentry.captureMessage('Hello, world!');\n * Sentry.captureException(new Error('Good bye'));\n * Sentry.captureEvent({\n * message: 'Manual',\n * stacktrace: [\n * // ...\n * ],\n * });\n * ```\n *\n * @see {@link BrowserOptions} for documentation on configuration options.\n */\nexport function init(options: BrowserOptions = {}): Client | undefined {\n const shouldDisableBecauseIsBrowserExtenstion =\n !options.skipBrowserExtensionCheck && checkAndWarnIfIsEmbeddedBrowserExtension();\n\n const clientOptions: BrowserClientOptions = {\n ...options,\n enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup({\n integrations: options.integrations,\n defaultIntegrations:\n options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations,\n }),\n transport: options.transport || makeFetchTransport,\n };\n return initAndBind(BrowserClient, clientOptions);\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function forceLoad(): void {\n // Noop\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function onLoad(callback: () => void): void {\n callback();\n}\n"],"names":["inboundFiltersIntegration","functionToStringIntegration","browserApiErrorsIntegration","breadcrumbsIntegration","globalHandlersIntegration","linkedErrorsIntegration","dedupeIntegration","httpContextIntegration","browserSessionIntegration","checkAndWarnIfIsEmbeddedBrowserExtension","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","makeFetchTransport","initAndBind","BrowserClient"],"mappings":";;;;;;;;;;;;;;AAqBA;AACO,SAAS,sBAAsB,CAAC,QAAQ,EAA0B;AACzE;AACA;AACA;AACA;AACA,EAAE,OAAO;AACT;AACA;AACA,IAAIA,8BAAyB,EAAE;AAC/B,IAAIC,gCAA2B,EAAE;AACjC,IAAIC,4CAA2B,EAAE;AACjC,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,IAAIC,oCAAuB,EAAE;AAC7B,IAAIC,sBAAiB,EAAE;AACvB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,GAAG;AACH;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,GAAmB,EAAE,EAAsB;AACvE,EAAE,MAAM,uCAAwC;AAChD,IAAI,CAAC,OAAO,CAAC,6BAA6BC,+DAAwC,EAAE;;AAEpF,EAAE,MAAM,aAAa,GAAyB;AAC9C,IAAI,GAAG,OAAO;AACd,IAAI,OAAO,EAAE,uCAAwC,GAAE,QAAQ,OAAO,CAAC,OAAO;AAC9E,IAAI,WAAW,EAAEC,sCAAiC,CAAC,OAAO,CAAC,WAAA,IAAeC,+BAAkB,CAAC;AAC7F,IAAI,YAAY,EAAEC,2BAAsB,CAAC;AACzC,MAAM,YAAY,EAAE,OAAO,CAAC,YAAY;AACxC,MAAM,mBAAmB;AACzB,QAAQ,OAAO,CAAC,mBAAoB,IAAG,IAAK,GAAE,sBAAsB,CAAQ,CAAA,GAAI,OAAO,CAAC,mBAAmB;AAC3G,KAAK,CAAC;AACN,IAAI,SAAS,EAAE,OAAO,CAAC,SAAA,IAAaC,wBAAkB;AACtD,GAAG;AACH,EAAE,OAAOC,gBAAW,CAACC,oBAAa,EAAE,aAAa,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACO,SAAS,SAAS,GAAS;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACO,SAAS,MAAM,CAAC,QAAQ,EAAoB;AACnD,EAAE,QAAQ,EAAE;AACZ;;;;;;;"}
|
|
@@ -18,14 +18,13 @@ const DEFAULT_BROWSER_TRACING_OPTIONS = {
|
|
|
18
18
|
enableLongTask: true,
|
|
19
19
|
enableLongAnimationFrame: true,
|
|
20
20
|
enableInp: true,
|
|
21
|
+
ignoreResourceSpans: [],
|
|
21
22
|
linkPreviousTrace: 'in-memory',
|
|
22
23
|
consistentTraceSampling: false,
|
|
23
24
|
_experiments: {},
|
|
24
25
|
...request.defaultRequestInstrumentationOptions,
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
let _hasBeenInitialized = false;
|
|
28
|
-
|
|
29
28
|
/**
|
|
30
29
|
* The Browser Tracing integration automatically instruments browser pageload/navigation
|
|
31
30
|
* actions as transactions, and captures requests, metrics and errors as spans.
|
|
@@ -36,14 +35,10 @@ let _hasBeenInitialized = false;
|
|
|
36
35
|
* We explicitly export the proper type here, as this has to be extended in some cases.
|
|
37
36
|
*/
|
|
38
37
|
const browserTracingIntegration = ((_options = {}) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
_hasBeenInitialized = true;
|
|
38
|
+
const latestRoute = {
|
|
39
|
+
name: undefined,
|
|
40
|
+
source: undefined,
|
|
41
|
+
};
|
|
47
42
|
|
|
48
43
|
/**
|
|
49
44
|
* This is just a small wrapper that makes `document` optional.
|
|
@@ -51,8 +46,6 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
51
46
|
*/
|
|
52
47
|
const optionalWindowDocument = helpers.WINDOW.document ;
|
|
53
48
|
|
|
54
|
-
core.registerSpanErrorInstrumentation();
|
|
55
|
-
|
|
56
49
|
const {
|
|
57
50
|
enableInp,
|
|
58
51
|
enableLongTask,
|
|
@@ -68,6 +61,7 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
68
61
|
trackFetchStreamPerformance,
|
|
69
62
|
shouldCreateSpanForRequest,
|
|
70
63
|
enableHTTPTimings,
|
|
64
|
+
ignoreResourceSpans,
|
|
71
65
|
instrumentPageLoad,
|
|
72
66
|
instrumentNavigation,
|
|
73
67
|
linkPreviousTrace,
|
|
@@ -78,31 +72,7 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
78
72
|
..._options,
|
|
79
73
|
};
|
|
80
74
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (enableInp) {
|
|
84
|
-
browserUtils.startTrackingINP();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
enableLongAnimationFrame &&
|
|
89
|
-
core.GLOBAL_OBJ.PerformanceObserver &&
|
|
90
|
-
PerformanceObserver.supportedEntryTypes &&
|
|
91
|
-
PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')
|
|
92
|
-
) {
|
|
93
|
-
browserUtils.startTrackingLongAnimationFrames();
|
|
94
|
-
} else if (enableLongTask) {
|
|
95
|
-
browserUtils.startTrackingLongTasks();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (enableInteractions) {
|
|
99
|
-
browserUtils.startTrackingInteractions();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const latestRoute = {
|
|
103
|
-
name: undefined,
|
|
104
|
-
source: undefined,
|
|
105
|
-
};
|
|
75
|
+
let _collectWebVitals;
|
|
106
76
|
|
|
107
77
|
/** Create routing idle transaction. */
|
|
108
78
|
function _createRouteSpan(client, startSpanOptions) {
|
|
@@ -131,8 +101,10 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
131
101
|
// should wait for finish signal if it's a pageload transaction
|
|
132
102
|
disableAutoFinish: isPageloadTransaction,
|
|
133
103
|
beforeSpanEnd: span => {
|
|
134
|
-
|
|
135
|
-
|
|
104
|
+
// This will generally always be defined here, because it is set in `setup()` of the integration
|
|
105
|
+
// but technically, it is optional, so we guard here to be extra safe
|
|
106
|
+
_collectWebVitals?.();
|
|
107
|
+
browserUtils.addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans, ignoreResourceSpans });
|
|
136
108
|
setActiveIdleSpan(client, undefined);
|
|
137
109
|
|
|
138
110
|
// A trace should stay consistent over the entire timespan of one route - even after the pageload/navigation ended.
|
|
@@ -169,8 +141,29 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
169
141
|
|
|
170
142
|
return {
|
|
171
143
|
name: BROWSER_TRACING_INTEGRATION_ID,
|
|
172
|
-
|
|
173
|
-
|
|
144
|
+
setup(client) {
|
|
145
|
+
core.registerSpanErrorInstrumentation();
|
|
146
|
+
|
|
147
|
+
_collectWebVitals = browserUtils.startTrackingWebVitals({ recordClsStandaloneSpans: enableStandaloneClsSpans || false });
|
|
148
|
+
|
|
149
|
+
if (enableInp) {
|
|
150
|
+
browserUtils.startTrackingINP();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
enableLongAnimationFrame &&
|
|
155
|
+
core.GLOBAL_OBJ.PerformanceObserver &&
|
|
156
|
+
PerformanceObserver.supportedEntryTypes &&
|
|
157
|
+
PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')
|
|
158
|
+
) {
|
|
159
|
+
browserUtils.startTrackingLongAnimationFrames();
|
|
160
|
+
} else if (enableLongTask) {
|
|
161
|
+
browserUtils.startTrackingLongTasks();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (enableInteractions) {
|
|
165
|
+
browserUtils.startTrackingInteractions();
|
|
166
|
+
}
|
|
174
167
|
|
|
175
168
|
function maybeEndActiveSpan() {
|
|
176
169
|
const activeSpan = getActiveIdleSpan(client);
|
|
@@ -231,6 +224,9 @@ const browserTracingIntegration = ((_options = {}) => {
|
|
|
231
224
|
...startSpanOptions,
|
|
232
225
|
});
|
|
233
226
|
});
|
|
227
|
+
},
|
|
228
|
+
afterAllSetup(client) {
|
|
229
|
+
let startingUrl = core.getLocationHref();
|
|
234
230
|
|
|
235
231
|
if (linkPreviousTrace !== 'off') {
|
|
236
232
|
linkedTraces.linkTraces(client, { linkPreviousTrace, consistentTraceSampling });
|