@andre1502/react-utilities 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. package/README.md +340 -0
  2. package/dist/Config/Config.d.ts +28 -0
  3. package/dist/Config/Config.js +200 -0
  4. package/dist/Config/Config.js.map +1 -0
  5. package/dist/Config/GoogleAuth.d.ts +15 -0
  6. package/dist/Config/GoogleAuth.js +71 -0
  7. package/dist/Config/GoogleAuth.js.map +1 -0
  8. package/dist/Config/Locales.d.ts +18 -0
  9. package/dist/Config/Locales.js +62 -0
  10. package/dist/Config/Locales.js.map +1 -0
  11. package/dist/Config/Output.d.ts +10 -0
  12. package/dist/Config/Output.js +28 -0
  13. package/dist/Config/Output.js.map +1 -0
  14. package/dist/Config/Sitemap.d.ts +13 -0
  15. package/dist/Config/Sitemap.js +73 -0
  16. package/dist/Config/Sitemap.js.map +1 -0
  17. package/dist/Format/NumberFormat.d.ts +6 -0
  18. package/dist/Format/NumberFormat.js +77 -0
  19. package/dist/Format/NumberFormat.js.map +1 -0
  20. package/dist/Format/NumberParser.d.ts +9 -0
  21. package/dist/Format/NumberParser.js +51 -0
  22. package/dist/Format/NumberParser.js.map +1 -0
  23. package/dist/React-BaJ1KfGF.js +87 -0
  24. package/dist/React-BaJ1KfGF.js.map +1 -0
  25. package/dist/React-qUl0CBmE.js +109 -0
  26. package/dist/React-qUl0CBmE.js.map +1 -0
  27. package/dist/ReactNative-CqUrY2ZJ.js +3856 -0
  28. package/dist/ReactNative-CqUrY2ZJ.js.map +1 -0
  29. package/dist/ReactNative-mNnws-b5.js +3834 -0
  30. package/dist/ReactNative-mNnws-b5.js.map +1 -0
  31. package/dist/Sentry/Build.d.ts +9 -0
  32. package/dist/Sentry/Build.js +88 -0
  33. package/dist/Sentry/Build.js.map +1 -0
  34. package/dist/Sentry/React.d.ts +18 -0
  35. package/dist/Sentry/React.js +104 -0
  36. package/dist/Sentry/React.js.map +1 -0
  37. package/dist/Sentry/ReactNative.d.ts +18 -0
  38. package/dist/Sentry/ReactNative.js +114 -0
  39. package/dist/Sentry/ReactNative.js.map +1 -0
  40. package/dist/Sentry/Utils.d.ts +2 -0
  41. package/dist/Sentry/Utils.js +24 -0
  42. package/dist/Sentry/Utils.js.map +1 -0
  43. package/dist/Utils/Files.d.ts +7 -0
  44. package/dist/Utils/Files.js +52 -0
  45. package/dist/Utils/Files.js.map +1 -0
  46. package/dist/Utils-Cq948gfa.js +20 -0
  47. package/dist/Utils-Cq948gfa.js.map +1 -0
  48. package/dist/Utils-Dilye04y.js +22 -0
  49. package/dist/Utils-Dilye04y.js.map +1 -0
  50. package/dist/config-cli.cjs +471 -0
  51. package/dist/config-cli.cjs.map +1 -0
  52. package/dist/config-cli.d.ts +34 -0
  53. package/dist/config-cli.js +220 -0
  54. package/dist/config-cli.js.map +1 -0
  55. package/dist/config-cli.mjs +443 -0
  56. package/dist/config-cli.mjs.map +1 -0
  57. package/dist/enums/CurrencySymbolEnum.d.ts +5 -0
  58. package/dist/enums/CurrencySymbolEnum.js +13 -0
  59. package/dist/enums/CurrencySymbolEnum.js.map +1 -0
  60. package/dist/format.cjs +122 -0
  61. package/dist/format.cjs.map +1 -0
  62. package/dist/format.d.ts +3 -0
  63. package/dist/format.js +55 -0
  64. package/dist/format.js.map +1 -0
  65. package/dist/format.mjs +117 -0
  66. package/dist/format.mjs.map +1 -0
  67. package/dist/index-cli.cjs +24 -0
  68. package/dist/index-cli.cjs.map +1 -0
  69. package/dist/index-cli.d.ts +2 -0
  70. package/dist/index-cli.js +28 -0
  71. package/dist/index-cli.js.map +1 -0
  72. package/dist/index-cli.mjs +12 -0
  73. package/dist/index-cli.mjs.map +1 -0
  74. package/dist/index-fmt.cjs +16 -0
  75. package/dist/index-fmt.cjs.map +1 -0
  76. package/dist/index-fmt.d.ts +1 -0
  77. package/dist/index-fmt.js +17 -0
  78. package/dist/index-fmt.js.map +1 -0
  79. package/dist/index-fmt.mjs +3 -0
  80. package/dist/index-fmt.mjs.map +1 -0
  81. package/dist/index-rn.cjs +21 -0
  82. package/dist/index-rn.cjs.map +1 -0
  83. package/dist/index-rn.d.ts +2 -0
  84. package/dist/index-rn.js +28 -0
  85. package/dist/index-rn.js.map +1 -0
  86. package/dist/index-rn.mjs +6 -0
  87. package/dist/index-rn.mjs.map +1 -0
  88. package/dist/index.cjs +21 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.ts +2 -0
  91. package/dist/index.js +28 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/index.mjs +6 -0
  94. package/dist/index.mjs.map +1 -0
  95. package/dist/interfaces/Config/ConfigOptions.d.ts +8 -0
  96. package/dist/interfaces/Config/ConfigOptions.js +6 -0
  97. package/dist/interfaces/Config/ConfigOptions.js.map +1 -0
  98. package/dist/interfaces/Config/OutputMap.d.ts +3 -0
  99. package/dist/interfaces/Config/OutputMap.js +6 -0
  100. package/dist/interfaces/Config/OutputMap.js.map +1 -0
  101. package/dist/interfaces/Config/OutputOptions.d.ts +7 -0
  102. package/dist/interfaces/Config/OutputOptions.js +6 -0
  103. package/dist/interfaces/Config/OutputOptions.js.map +1 -0
  104. package/dist/interfaces/Config/SitemapMap.d.ts +5 -0
  105. package/dist/interfaces/Config/SitemapMap.js +6 -0
  106. package/dist/interfaces/Config/SitemapMap.js.map +1 -0
  107. package/dist/interfaces/Config/StringMap.d.ts +3 -0
  108. package/dist/interfaces/Config/StringMap.js +6 -0
  109. package/dist/interfaces/Config/StringMap.js.map +1 -0
  110. package/dist/interfaces/Format/FormatOptions.d.ts +14 -0
  111. package/dist/interfaces/Format/FormatOptions.js +6 -0
  112. package/dist/interfaces/Format/FormatOptions.js.map +1 -0
  113. package/dist/interfaces/Sentry/InitOptions.d.ts +20 -0
  114. package/dist/interfaces/Sentry/InitOptions.js +6 -0
  115. package/dist/interfaces/Sentry/InitOptions.js.map +1 -0
  116. package/dist/interfaces/Sentry/InitOptionsRN.d.ts +4 -0
  117. package/dist/interfaces/Sentry/InitOptionsRN.js +6 -0
  118. package/dist/interfaces/Sentry/InitOptionsRN.js.map +1 -0
  119. package/dist/interfaces/Sentry/SourceMapOptions.d.ts +7 -0
  120. package/dist/interfaces/Sentry/SourceMapOptions.js +6 -0
  121. package/dist/interfaces/Sentry/SourceMapOptions.js.map +1 -0
  122. package/dist/sentry-cli.cjs +119 -0
  123. package/dist/sentry-cli.cjs.map +1 -0
  124. package/dist/sentry-cli.d.ts +9 -0
  125. package/dist/sentry-cli.js +50 -0
  126. package/dist/sentry-cli.js.map +1 -0
  127. package/dist/sentry-cli.mjs +98 -0
  128. package/dist/sentry-cli.mjs.map +1 -0
  129. package/dist/sentry-rn.cjs +11 -0
  130. package/dist/sentry-rn.cjs.map +1 -0
  131. package/dist/sentry-rn.d.ts +2 -0
  132. package/dist/sentry-rn.js +28 -0
  133. package/dist/sentry-rn.js.map +1 -0
  134. package/dist/sentry-rn.mjs +4 -0
  135. package/dist/sentry-rn.mjs.map +1 -0
  136. package/dist/sentry.cjs +11 -0
  137. package/dist/sentry.cjs.map +1 -0
  138. package/dist/sentry.d.ts +2 -0
  139. package/dist/sentry.js +28 -0
  140. package/dist/sentry.js.map +1 -0
  141. package/dist/sentry.mjs +4 -0
  142. package/dist/sentry.mjs.map +1 -0
  143. package/dist/types/Config/OptionType.d.ts +2 -0
  144. package/dist/types/Config/OptionType.js +6 -0
  145. package/dist/types/Config/OptionType.js.map +1 -0
  146. package/dist/types/Format/OptionType.d.ts +3 -0
  147. package/dist/types/Format/OptionType.js +6 -0
  148. package/dist/types/Format/OptionType.js.map +1 -0
  149. package/dist/types/Sentry/OptionType.d.ts +1 -0
  150. package/dist/types/Sentry/OptionType.js +6 -0
  151. package/dist/types/Sentry/OptionType.js.map +1 -0
  152. package/package.json +139 -0
  153. package/src/Config/Config.ts +258 -0
  154. package/src/Config/GoogleAuth.ts +54 -0
  155. package/src/Config/Locales.ts +72 -0
  156. package/src/Config/Output.ts +29 -0
  157. package/src/Config/Sitemap.ts +67 -0
  158. package/src/Format/NumberFormat.ts +96 -0
  159. package/src/Format/NumberParser.ts +42 -0
  160. package/src/Sentry/Build.ts +67 -0
  161. package/src/Sentry/React.ts +127 -0
  162. package/src/Sentry/ReactNative.ts +133 -0
  163. package/src/Sentry/Utils.ts +26 -0
  164. package/src/Utils/Files.ts +51 -0
  165. package/src/config-cli.ts +152 -0
  166. package/src/enums/CurrencySymbolEnum.ts +5 -0
  167. package/src/format.ts +39 -0
  168. package/src/index-cli.ts +2 -0
  169. package/src/index-fmt.ts +1 -0
  170. package/src/index-rn.ts +2 -0
  171. package/src/index.ts +2 -0
  172. package/src/interfaces/Config/ConfigOptions.ts +9 -0
  173. package/src/interfaces/Config/OutputMap.ts +3 -0
  174. package/src/interfaces/Config/OutputOptions.ts +8 -0
  175. package/src/interfaces/Config/SitemapMap.ts +5 -0
  176. package/src/interfaces/Config/StringMap.ts +3 -0
  177. package/src/interfaces/Format/FormatOptions.ts +19 -0
  178. package/src/interfaces/Sentry/InitOptions.ts +23 -0
  179. package/src/interfaces/Sentry/InitOptionsRN.ts +5 -0
  180. package/src/interfaces/Sentry/SourceMapOptions.ts +7 -0
  181. package/src/sentry-cli.ts +16 -0
  182. package/src/sentry-rn.ts +2 -0
  183. package/src/sentry.ts +2 -0
  184. package/src/types/Config/OptionType.ts +2 -0
  185. package/src/types/Format/OptionType.ts +15 -0
  186. package/src/types/Sentry/OptionType.ts +1 -0
@@ -0,0 +1,3834 @@
1
+ import * as Sentry from '@sentry/react-native';
2
+ import { r as recordSentryHttp } from './Utils-Cq948gfa.js';
3
+
4
+ // eslint-disable-next-line @typescript-eslint/unbound-method
5
+ const objectToString = Object.prototype.toString;
6
+ /**
7
+ * Checks whether given value is an instance of the given built-in class.
8
+ *
9
+ * @param wat The value to be checked
10
+ * @param className
11
+ * @returns A boolean representing the result.
12
+ */
13
+ function isBuiltin(wat, className) {
14
+ return objectToString.call(wat) === `[object ${className}]`;
15
+ }
16
+
17
+ /**
18
+ * Checks whether given value's type is a string
19
+ * {@link isString}.
20
+ *
21
+ * @param wat A value to be checked.
22
+ * @returns A boolean representing the result.
23
+ */
24
+ function isString(wat) {
25
+ return isBuiltin(wat, 'String');
26
+ }
27
+
28
+ /**
29
+ * Checks whether given value's type is an object literal, or a class instance.
30
+ * {@link isPlainObject}.
31
+ *
32
+ * @param wat A value to be checked.
33
+ * @returns A boolean representing the result.
34
+ */
35
+ function isPlainObject(wat) {
36
+ return isBuiltin(wat, 'Object');
37
+ }
38
+
39
+ /**
40
+ * Checks whether given value has a then function.
41
+ * @param wat A value to be checked.
42
+ */
43
+ function isThenable(wat) {
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
45
+ return Boolean(wat && wat.then && typeof wat.then === 'function');
46
+ }
47
+
48
+ /**
49
+ * Checks whether given value's type is a Vue ViewModel.
50
+ *
51
+ * @param wat A value to be checked.
52
+ * @returns A boolean representing the result.
53
+ */
54
+ function isVueViewModel(wat) {
55
+ // Not using Object.prototype.toString because in Vue 3 it would read the instance's Symbol(Symbol.toStringTag) property.
56
+ return !!(typeof wat === 'object' && wat !== null && ((wat ).__isVue || (wat )._isVue));
57
+ }
58
+
59
+ /**
60
+ * Join values in array
61
+ * @param input array of values to be joined together
62
+ * @param delimiter string to be placed in-between values
63
+ * @returns Joined values
64
+ */
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ function safeJoin(input, delimiter) {
67
+ if (!Array.isArray(input)) {
68
+ return '';
69
+ }
70
+
71
+ const output = [];
72
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
73
+ for (let i = 0; i < input.length; i++) {
74
+ const value = input[i];
75
+ try {
76
+ // This is a hack to fix a Vue3-specific bug that causes an infinite loop of
77
+ // console warnings. This happens when a Vue template is rendered with
78
+ // an undeclared variable, which we try to stringify, ultimately causing
79
+ // Vue to issue another warning which repeats indefinitely.
80
+ // see: https://github.com/getsentry/sentry-javascript/pull/8981
81
+ if (isVueViewModel(value)) {
82
+ output.push('[VueViewModel]');
83
+ } else {
84
+ output.push(String(value));
85
+ }
86
+ } catch (e) {
87
+ output.push('[value cannot be serialized]');
88
+ }
89
+ }
90
+
91
+ return output.join(delimiter);
92
+ }
93
+
94
+ /** Internal global with common properties and Sentry extensions */
95
+
96
+ // The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification
97
+ // https://github.com/zloirock/core-js/blob/1b944df55282cdc99c90db5f49eb0b6eda2cc0a3/packages/core-js/internals/global.js
98
+ // core-js has the following licence:
99
+ //
100
+ // Copyright (c) 2014-2022 Denis Pushkarev
101
+ //
102
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
103
+ // of this software and associated documentation files (the "Software"), to deal
104
+ // in the Software without restriction, including without limitation the rights
105
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
106
+ // copies of the Software, and to permit persons to whom the Software is
107
+ // furnished to do so, subject to the following conditions:
108
+ //
109
+ // The above copyright notice and this permission notice shall be included in
110
+ // all copies or substantial portions of the Software.
111
+ //
112
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
113
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
114
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
115
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
116
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
117
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
118
+ // THE SOFTWARE.
119
+
120
+ /** Returns 'obj' if it's the global object, otherwise returns undefined */
121
+ function isGlobalObj(obj) {
122
+ return obj && obj.Math == Math ? obj : undefined;
123
+ }
124
+
125
+ /** Get's the global object for the current JavaScript runtime */
126
+ const GLOBAL_OBJ =
127
+ (typeof globalThis == 'object' && isGlobalObj(globalThis)) ||
128
+ // eslint-disable-next-line no-restricted-globals
129
+ (typeof window == 'object' && isGlobalObj(window)) ||
130
+ (typeof self == 'object' && isGlobalObj(self)) ||
131
+ (typeof global == 'object' && isGlobalObj(global)) ||
132
+ (function () {
133
+ return this;
134
+ })() ||
135
+ {};
136
+
137
+ /**
138
+ * @deprecated Use GLOBAL_OBJ instead or WINDOW from @sentry/browser. This will be removed in v8
139
+ */
140
+ function getGlobalObject() {
141
+ return GLOBAL_OBJ ;
142
+ }
143
+
144
+ /**
145
+ * Returns a global singleton contained in the global `__SENTRY__` object.
146
+ *
147
+ * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
148
+ * function and added to the `__SENTRY__` object.
149
+ *
150
+ * @param name name of the global singleton on __SENTRY__
151
+ * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
152
+ * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
153
+ * @returns the singleton
154
+ */
155
+ function getGlobalSingleton(name, creator, obj) {
156
+ const gbl = (obj || GLOBAL_OBJ) ;
157
+ const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
158
+ const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
159
+ return singleton;
160
+ }
161
+
162
+ /**
163
+ * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
164
+ *
165
+ * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
166
+ */
167
+ const DEBUG_BUILD$2 = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
168
+
169
+ /** Prefix for logging strings */
170
+ const PREFIX = 'Sentry Logger ';
171
+
172
+ const CONSOLE_LEVELS = [
173
+ 'debug',
174
+ 'info',
175
+ 'warn',
176
+ 'error',
177
+ 'log',
178
+ 'assert',
179
+ 'trace',
180
+ ] ;
181
+
182
+ /** This may be mutated by the console instrumentation. */
183
+ const originalConsoleMethods
184
+
185
+ = {};
186
+
187
+ /** JSDoc */
188
+
189
+ /**
190
+ * Temporarily disable sentry console instrumentations.
191
+ *
192
+ * @param callback The function to run against the original `console` messages
193
+ * @returns The results of the callback
194
+ */
195
+ function consoleSandbox(callback) {
196
+ if (!('console' in GLOBAL_OBJ)) {
197
+ return callback();
198
+ }
199
+
200
+ const console = GLOBAL_OBJ.console ;
201
+ const wrappedFuncs = {};
202
+
203
+ const wrappedLevels = Object.keys(originalConsoleMethods) ;
204
+
205
+ // Restore all wrapped console methods
206
+ wrappedLevels.forEach(level => {
207
+ const originalConsoleMethod = originalConsoleMethods[level] ;
208
+ wrappedFuncs[level] = console[level] ;
209
+ console[level] = originalConsoleMethod;
210
+ });
211
+
212
+ try {
213
+ return callback();
214
+ } finally {
215
+ // Revert restoration to wrapped state
216
+ wrappedLevels.forEach(level => {
217
+ console[level] = wrappedFuncs[level] ;
218
+ });
219
+ }
220
+ }
221
+
222
+ function makeLogger() {
223
+ let enabled = false;
224
+ const logger = {
225
+ enable: () => {
226
+ enabled = true;
227
+ },
228
+ disable: () => {
229
+ enabled = false;
230
+ },
231
+ isEnabled: () => enabled,
232
+ };
233
+
234
+ if (DEBUG_BUILD$2) {
235
+ CONSOLE_LEVELS.forEach(name => {
236
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
237
+ logger[name] = (...args) => {
238
+ if (enabled) {
239
+ consoleSandbox(() => {
240
+ GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);
241
+ });
242
+ }
243
+ };
244
+ });
245
+ } else {
246
+ CONSOLE_LEVELS.forEach(name => {
247
+ logger[name] = () => undefined;
248
+ });
249
+ }
250
+
251
+ return logger ;
252
+ }
253
+
254
+ const logger = makeLogger();
255
+
256
+ /**
257
+ * Replace a method in an object with a wrapped version of itself.
258
+ *
259
+ * @param source An object that contains a method to be wrapped.
260
+ * @param name The name of the method to be wrapped.
261
+ * @param replacementFactory A higher-order function that takes the original version of the given method and returns a
262
+ * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to
263
+ * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other
264
+ * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.
265
+ * @returns void
266
+ */
267
+ function fill(source, name, replacementFactory) {
268
+ if (!(name in source)) {
269
+ return;
270
+ }
271
+
272
+ const original = source[name] ;
273
+ const wrapped = replacementFactory(original) ;
274
+
275
+ // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
276
+ // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
277
+ if (typeof wrapped === 'function') {
278
+ markFunctionWrapped(wrapped, original);
279
+ }
280
+
281
+ source[name] = wrapped;
282
+ }
283
+
284
+ /**
285
+ * Defines a non-enumerable property on the given object.
286
+ *
287
+ * @param obj The object on which to set the property
288
+ * @param name The name of the property to be set
289
+ * @param value The value to which to set the property
290
+ */
291
+ function addNonEnumerableProperty(obj, name, value) {
292
+ try {
293
+ Object.defineProperty(obj, name, {
294
+ // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
295
+ value: value,
296
+ writable: true,
297
+ configurable: true,
298
+ });
299
+ } catch (o_O) {
300
+ DEBUG_BUILD$2 && logger.log(`Failed to add non-enumerable property "${name}" to object`, obj);
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Remembers the original function on the wrapped function and
306
+ * patches up the prototype.
307
+ *
308
+ * @param wrapped the wrapper function
309
+ * @param original the original function that gets wrapped
310
+ */
311
+ function markFunctionWrapped(wrapped, original) {
312
+ try {
313
+ const proto = original.prototype || {};
314
+ wrapped.prototype = original.prototype = proto;
315
+ addNonEnumerableProperty(wrapped, '__sentry_original__', original);
316
+ } catch (o_O) {} // eslint-disable-line no-empty
317
+ }
318
+
319
+ /**
320
+ * Given any object, return a new object having removed all fields whose value was `undefined`.
321
+ * Works recursively on objects and arrays.
322
+ *
323
+ * Attention: This function keeps circular references in the returned object.
324
+ */
325
+ function dropUndefinedKeys(inputValue) {
326
+ // This map keeps track of what already visited nodes map to.
327
+ // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular
328
+ // references as the input object.
329
+ const memoizationMap = new Map();
330
+
331
+ // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API
332
+ return _dropUndefinedKeys(inputValue, memoizationMap);
333
+ }
334
+
335
+ function _dropUndefinedKeys(inputValue, memoizationMap) {
336
+ if (isPojo(inputValue)) {
337
+ // If this node has already been visited due to a circular reference, return the object it was mapped to in the new object
338
+ const memoVal = memoizationMap.get(inputValue);
339
+ if (memoVal !== undefined) {
340
+ return memoVal ;
341
+ }
342
+
343
+ const returnValue = {};
344
+ // Store the mapping of this value in case we visit it again, in case of circular data
345
+ memoizationMap.set(inputValue, returnValue);
346
+
347
+ for (const key of Object.keys(inputValue)) {
348
+ if (typeof inputValue[key] !== 'undefined') {
349
+ returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);
350
+ }
351
+ }
352
+
353
+ return returnValue ;
354
+ }
355
+
356
+ if (Array.isArray(inputValue)) {
357
+ // If this node has already been visited due to a circular reference, return the array it was mapped to in the new object
358
+ const memoVal = memoizationMap.get(inputValue);
359
+ if (memoVal !== undefined) {
360
+ return memoVal ;
361
+ }
362
+
363
+ const returnValue = [];
364
+ // Store the mapping of this value in case we visit it again, in case of circular data
365
+ memoizationMap.set(inputValue, returnValue);
366
+
367
+ inputValue.forEach((item) => {
368
+ returnValue.push(_dropUndefinedKeys(item, memoizationMap));
369
+ });
370
+
371
+ return returnValue ;
372
+ }
373
+
374
+ return inputValue;
375
+ }
376
+
377
+ function isPojo(input) {
378
+ if (!isPlainObject(input)) {
379
+ return false;
380
+ }
381
+
382
+ try {
383
+ const name = (Object.getPrototypeOf(input) ).constructor.name;
384
+ return !name || name === 'Object';
385
+ } catch (e) {
386
+ return true;
387
+ }
388
+ }
389
+
390
+ const defaultFunctionName = '<anonymous>';
391
+
392
+ /**
393
+ * Safely extract function name from itself
394
+ */
395
+ function getFunctionName(fn) {
396
+ try {
397
+ if (!fn || typeof fn !== 'function') {
398
+ return defaultFunctionName;
399
+ }
400
+ return fn.name || defaultFunctionName;
401
+ } catch (e) {
402
+ // Just accessing custom props in some Selenium environments
403
+ // can cause a "Permission denied" exception (see raven-js#495).
404
+ return defaultFunctionName;
405
+ }
406
+ }
407
+
408
+ // We keep the handlers globally
409
+ const handlers = {};
410
+ const instrumented = {};
411
+
412
+ /** Add a handler function. */
413
+ function addHandler(type, handler) {
414
+ handlers[type] = handlers[type] || [];
415
+ (handlers[type] ).push(handler);
416
+ }
417
+
418
+ /** Maybe run an instrumentation function, unless it was already called. */
419
+ function maybeInstrument(type, instrumentFn) {
420
+ if (!instrumented[type]) {
421
+ instrumentFn();
422
+ instrumented[type] = true;
423
+ }
424
+ }
425
+
426
+ /** Trigger handlers for a given instrumentation type. */
427
+ function triggerHandlers(type, data) {
428
+ const typeHandlers = type && handlers[type];
429
+ if (!typeHandlers) {
430
+ return;
431
+ }
432
+
433
+ for (const handler of typeHandlers) {
434
+ try {
435
+ handler(data);
436
+ } catch (e) {
437
+ DEBUG_BUILD$2 &&
438
+ logger.error(
439
+ `Error while triggering instrumentation handler.\nType: ${type}\nName: ${getFunctionName(handler)}\nError:`,
440
+ e,
441
+ );
442
+ }
443
+ }
444
+ }
445
+
446
+ /**
447
+ * Add an instrumentation handler for when a console.xxx method is called.
448
+ *
449
+ * Use at your own risk, this might break without changelog notice, only used internally.
450
+ * @hidden
451
+ */
452
+ function addConsoleInstrumentationHandler(handler) {
453
+ const type = 'console';
454
+ addHandler(type, handler);
455
+ maybeInstrument(type, instrumentConsole);
456
+ }
457
+
458
+ function instrumentConsole() {
459
+ if (!('console' in GLOBAL_OBJ)) {
460
+ return;
461
+ }
462
+
463
+ CONSOLE_LEVELS.forEach(function (level) {
464
+ if (!(level in GLOBAL_OBJ.console)) {
465
+ return;
466
+ }
467
+
468
+ fill(GLOBAL_OBJ.console, level, function (originalConsoleMethod) {
469
+ originalConsoleMethods[level] = originalConsoleMethod;
470
+
471
+ return function (...args) {
472
+ const handlerData = { args, level };
473
+ triggerHandlers('console', handlerData);
474
+
475
+ const log = originalConsoleMethods[level];
476
+ log && log.apply(GLOBAL_OBJ.console, args);
477
+ };
478
+ });
479
+ });
480
+ }
481
+
482
+ /**
483
+ * UUID4 generator
484
+ *
485
+ * @returns string Generated UUID4.
486
+ */
487
+ function uuid4() {
488
+ const gbl = GLOBAL_OBJ ;
489
+ const crypto = gbl.crypto || gbl.msCrypto;
490
+
491
+ let getRandomByte = () => Math.random() * 16;
492
+ try {
493
+ if (crypto && crypto.randomUUID) {
494
+ return crypto.randomUUID().replace(/-/g, '');
495
+ }
496
+ if (crypto && crypto.getRandomValues) {
497
+ getRandomByte = () => {
498
+ // crypto.getRandomValues might return undefined instead of the typed array
499
+ // in old Chromium versions (e.g. 23.0.1235.0 (151422))
500
+ // However, `typedArray` is still filled in-place.
501
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#typedarray
502
+ const typedArray = new Uint8Array(1);
503
+ crypto.getRandomValues(typedArray);
504
+ return typedArray[0];
505
+ };
506
+ }
507
+ } catch (_) {
508
+ // some runtimes can crash invoking crypto
509
+ // https://github.com/getsentry/sentry-javascript/issues/8935
510
+ }
511
+
512
+ // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
513
+ // Concatenating the following numbers as strings results in '10000000100040008000100000000000'
514
+ return (([1e7] ) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>
515
+ // eslint-disable-next-line no-bitwise
516
+ ((c ) ^ ((getRandomByte() & 15) >> ((c ) / 4))).toString(16),
517
+ );
518
+ }
519
+
520
+ function getFirstException(event) {
521
+ return event.exception && event.exception.values ? event.exception.values[0] : undefined;
522
+ }
523
+
524
+ /**
525
+ * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.
526
+ *
527
+ * @param event The event to modify.
528
+ * @param newMechanism Mechanism data to add to the event.
529
+ * @hidden
530
+ */
531
+ function addExceptionMechanism(event, newMechanism) {
532
+ const firstException = getFirstException(event);
533
+ if (!firstException) {
534
+ return;
535
+ }
536
+
537
+ const defaultMechanism = { type: 'generic', handled: true };
538
+ const currentMechanism = firstException.mechanism;
539
+ firstException.mechanism = { ...defaultMechanism, ...currentMechanism, ...newMechanism };
540
+
541
+ if (newMechanism && 'data' in newMechanism) {
542
+ const mergedData = { ...(currentMechanism && currentMechanism.data), ...newMechanism.data };
543
+ firstException.mechanism.data = mergedData;
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Checks whether the given input is already an array, and if it isn't, wraps it in one.
549
+ *
550
+ * @param maybeArray Input to turn into an array, if necessary
551
+ * @returns The input, if already an array, or an array with the input as the only element, if not
552
+ */
553
+ function arrayify(maybeArray) {
554
+ return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
555
+ }
556
+
557
+ // eslint-disable-next-line deprecation/deprecation
558
+ const WINDOW$1 = getGlobalObject();
559
+
560
+ /**
561
+ * Tells whether current environment supports Fetch API
562
+ * {@link supportsFetch}.
563
+ *
564
+ * @returns Answer to the given question.
565
+ */
566
+ function supportsFetch() {
567
+ if (!('fetch' in WINDOW$1)) {
568
+ return false;
569
+ }
570
+
571
+ try {
572
+ new Headers();
573
+ new Request('http://www.example.com');
574
+ new Response();
575
+ return true;
576
+ } catch (e) {
577
+ return false;
578
+ }
579
+ }
580
+ /**
581
+ * isNativeFetch checks if the given function is a native implementation of fetch()
582
+ */
583
+ // eslint-disable-next-line @typescript-eslint/ban-types
584
+ function isNativeFetch(func) {
585
+ return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString());
586
+ }
587
+
588
+ /**
589
+ * Tells whether current environment supports Fetch API natively
590
+ * {@link supportsNativeFetch}.
591
+ *
592
+ * @returns true if `window.fetch` is natively implemented, false otherwise
593
+ */
594
+ function supportsNativeFetch() {
595
+ if (typeof EdgeRuntime === 'string') {
596
+ return true;
597
+ }
598
+
599
+ if (!supportsFetch()) {
600
+ return false;
601
+ }
602
+
603
+ // Fast path to avoid DOM I/O
604
+ // eslint-disable-next-line @typescript-eslint/unbound-method
605
+ if (isNativeFetch(WINDOW$1.fetch)) {
606
+ return true;
607
+ }
608
+
609
+ // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
610
+ // so create a "pure" iframe to see if that has native fetch
611
+ let result = false;
612
+ const doc = WINDOW$1.document;
613
+ // eslint-disable-next-line deprecation/deprecation
614
+ if (doc && typeof (doc.createElement ) === 'function') {
615
+ try {
616
+ const sandbox = doc.createElement('iframe');
617
+ sandbox.hidden = true;
618
+ doc.head.appendChild(sandbox);
619
+ if (sandbox.contentWindow && sandbox.contentWindow.fetch) {
620
+ // eslint-disable-next-line @typescript-eslint/unbound-method
621
+ result = isNativeFetch(sandbox.contentWindow.fetch);
622
+ }
623
+ doc.head.removeChild(sandbox);
624
+ } catch (err) {
625
+ DEBUG_BUILD$2 &&
626
+ logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
627
+ }
628
+ }
629
+
630
+ return result;
631
+ }
632
+
633
+ /**
634
+ * Add an instrumentation handler for when a fetch request happens.
635
+ * The handler function is called once when the request starts and once when it ends,
636
+ * which can be identified by checking if it has an `endTimestamp`.
637
+ *
638
+ * Use at your own risk, this might break without changelog notice, only used internally.
639
+ * @hidden
640
+ */
641
+ function addFetchInstrumentationHandler(handler) {
642
+ const type = 'fetch';
643
+ addHandler(type, handler);
644
+ maybeInstrument(type, instrumentFetch);
645
+ }
646
+
647
+ function instrumentFetch() {
648
+ if (!supportsNativeFetch()) {
649
+ return;
650
+ }
651
+
652
+ fill(GLOBAL_OBJ, 'fetch', function (originalFetch) {
653
+ return function (...args) {
654
+ const { method, url } = parseFetchArgs(args);
655
+
656
+ const handlerData = {
657
+ args,
658
+ fetchData: {
659
+ method,
660
+ url,
661
+ },
662
+ startTimestamp: Date.now(),
663
+ };
664
+
665
+ triggerHandlers('fetch', {
666
+ ...handlerData,
667
+ });
668
+
669
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
670
+ return originalFetch.apply(GLOBAL_OBJ, args).then(
671
+ (response) => {
672
+ const finishedHandlerData = {
673
+ ...handlerData,
674
+ endTimestamp: Date.now(),
675
+ response,
676
+ };
677
+
678
+ triggerHandlers('fetch', finishedHandlerData);
679
+ return response;
680
+ },
681
+ (error) => {
682
+ const erroredHandlerData = {
683
+ ...handlerData,
684
+ endTimestamp: Date.now(),
685
+ error,
686
+ };
687
+
688
+ triggerHandlers('fetch', erroredHandlerData);
689
+ // NOTE: If you are a Sentry user, and you are seeing this stack frame,
690
+ // it means the sentry.javascript SDK caught an error invoking your application code.
691
+ // This is expected behavior and NOT indicative of a bug with sentry.javascript.
692
+ throw error;
693
+ },
694
+ );
695
+ };
696
+ });
697
+ }
698
+
699
+ function hasProp(obj, prop) {
700
+ return !!obj && typeof obj === 'object' && !!(obj )[prop];
701
+ }
702
+
703
+ function getUrlFromResource(resource) {
704
+ if (typeof resource === 'string') {
705
+ return resource;
706
+ }
707
+
708
+ if (!resource) {
709
+ return '';
710
+ }
711
+
712
+ if (hasProp(resource, 'url')) {
713
+ return resource.url;
714
+ }
715
+
716
+ if (resource.toString) {
717
+ return resource.toString();
718
+ }
719
+
720
+ return '';
721
+ }
722
+
723
+ /**
724
+ * Parses the fetch arguments to find the used Http method and the url of the request.
725
+ * Exported for tests only.
726
+ */
727
+ function parseFetchArgs(fetchArgs) {
728
+ if (fetchArgs.length === 0) {
729
+ return { method: 'GET', url: '' };
730
+ }
731
+
732
+ if (fetchArgs.length === 2) {
733
+ const [url, options] = fetchArgs ;
734
+
735
+ return {
736
+ url: getUrlFromResource(url),
737
+ method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',
738
+ };
739
+ }
740
+
741
+ const arg = fetchArgs[0];
742
+ return {
743
+ url: getUrlFromResource(arg ),
744
+ method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',
745
+ };
746
+ }
747
+
748
+ const WINDOW = GLOBAL_OBJ ;
749
+
750
+ const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';
751
+
752
+ /**
753
+ * Add an instrumentation handler for when an XHR request happens.
754
+ * The handler function is called once when the request starts and once when it ends,
755
+ * which can be identified by checking if it has an `endTimestamp`.
756
+ *
757
+ * Use at your own risk, this might break without changelog notice, only used internally.
758
+ * @hidden
759
+ */
760
+ function addXhrInstrumentationHandler(handler) {
761
+ const type = 'xhr';
762
+ addHandler(type, handler);
763
+ maybeInstrument(type, instrumentXHR);
764
+ }
765
+
766
+ /** Exported only for tests. */
767
+ function instrumentXHR() {
768
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
769
+ if (!(WINDOW ).XMLHttpRequest) {
770
+ return;
771
+ }
772
+
773
+ const xhrproto = XMLHttpRequest.prototype;
774
+
775
+ fill(xhrproto, 'open', function (originalOpen) {
776
+ return function ( ...args) {
777
+ const startTimestamp = Date.now();
778
+
779
+ // open() should always be called with two or more arguments
780
+ // But to be on the safe side, we actually validate this and bail out if we don't have a method & url
781
+ const method = isString(args[0]) ? args[0].toUpperCase() : undefined;
782
+ const url = parseUrl(args[1]);
783
+
784
+ if (!method || !url) {
785
+ return originalOpen.apply(this, args);
786
+ }
787
+
788
+ this[SENTRY_XHR_DATA_KEY] = {
789
+ method,
790
+ url,
791
+ request_headers: {},
792
+ };
793
+
794
+ // if Sentry key appears in URL, don't capture it as a request
795
+ if (method === 'POST' && url.match(/sentry_key/)) {
796
+ this.__sentry_own_request__ = true;
797
+ }
798
+
799
+ const onreadystatechangeHandler = () => {
800
+ // For whatever reason, this is not the same instance here as from the outer method
801
+ const xhrInfo = this[SENTRY_XHR_DATA_KEY];
802
+
803
+ if (!xhrInfo) {
804
+ return;
805
+ }
806
+
807
+ if (this.readyState === 4) {
808
+ try {
809
+ // touching statusCode in some platforms throws
810
+ // an exception
811
+ xhrInfo.status_code = this.status;
812
+ } catch (e) {
813
+ /* do nothing */
814
+ }
815
+
816
+ const handlerData = {
817
+ args: [method, url],
818
+ endTimestamp: Date.now(),
819
+ startTimestamp,
820
+ xhr: this,
821
+ };
822
+ triggerHandlers('xhr', handlerData);
823
+ }
824
+ };
825
+
826
+ if ('onreadystatechange' in this && typeof this.onreadystatechange === 'function') {
827
+ fill(this, 'onreadystatechange', function (original) {
828
+ return function ( ...readyStateArgs) {
829
+ onreadystatechangeHandler();
830
+ return original.apply(this, readyStateArgs);
831
+ };
832
+ });
833
+ } else {
834
+ this.addEventListener('readystatechange', onreadystatechangeHandler);
835
+ }
836
+
837
+ // Intercepting `setRequestHeader` to access the request headers of XHR instance.
838
+ // This will only work for user/library defined headers, not for the default/browser-assigned headers.
839
+ // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.
840
+ fill(this, 'setRequestHeader', function (original) {
841
+ return function ( ...setRequestHeaderArgs) {
842
+ const [header, value] = setRequestHeaderArgs;
843
+
844
+ const xhrInfo = this[SENTRY_XHR_DATA_KEY];
845
+
846
+ if (xhrInfo && isString(header) && isString(value)) {
847
+ xhrInfo.request_headers[header.toLowerCase()] = value;
848
+ }
849
+
850
+ return original.apply(this, setRequestHeaderArgs);
851
+ };
852
+ });
853
+
854
+ return originalOpen.apply(this, args);
855
+ };
856
+ });
857
+
858
+ fill(xhrproto, 'send', function (originalSend) {
859
+ return function ( ...args) {
860
+ const sentryXhrData = this[SENTRY_XHR_DATA_KEY];
861
+
862
+ if (!sentryXhrData) {
863
+ return originalSend.apply(this, args);
864
+ }
865
+
866
+ if (args[0] !== undefined) {
867
+ sentryXhrData.body = args[0];
868
+ }
869
+
870
+ const handlerData = {
871
+ args: [sentryXhrData.method, sentryXhrData.url],
872
+ startTimestamp: Date.now(),
873
+ xhr: this,
874
+ };
875
+ triggerHandlers('xhr', handlerData);
876
+
877
+ return originalSend.apply(this, args);
878
+ };
879
+ });
880
+ }
881
+
882
+ function parseUrl(url) {
883
+ if (isString(url)) {
884
+ return url;
885
+ }
886
+
887
+ try {
888
+ // url can be a string or URL
889
+ // but since URL is not available in IE11, we do not check for it,
890
+ // but simply assume it is an URL and return `toString()` from it (which returns the full URL)
891
+ // If that fails, we just return undefined
892
+ return (url ).toString();
893
+ } catch (e2) {} // eslint-disable-line no-empty
894
+
895
+ return undefined;
896
+ }
897
+
898
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
899
+
900
+ /** SyncPromise internal states */
901
+ var States; (function (States) {
902
+ /** Pending */
903
+ const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING";
904
+ /** Resolved / OK */
905
+ const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED";
906
+ /** Rejected / Error */
907
+ const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED";
908
+ })(States || (States = {}));
909
+
910
+ /**
911
+ * Thenable class that behaves like a Promise and follows it's interface
912
+ * but is not async internally
913
+ */
914
+ class SyncPromise {
915
+
916
+ constructor(
917
+ executor,
918
+ ) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this);
919
+ this._state = States.PENDING;
920
+ this._handlers = [];
921
+
922
+ try {
923
+ executor(this._resolve, this._reject);
924
+ } catch (e) {
925
+ this._reject(e);
926
+ }
927
+ }
928
+
929
+ /** JSDoc */
930
+ then(
931
+ onfulfilled,
932
+ onrejected,
933
+ ) {
934
+ return new SyncPromise((resolve, reject) => {
935
+ this._handlers.push([
936
+ false,
937
+ result => {
938
+ if (!onfulfilled) {
939
+ // TODO: ¯\_(ツ)_/¯
940
+ // TODO: FIXME
941
+ resolve(result );
942
+ } else {
943
+ try {
944
+ resolve(onfulfilled(result));
945
+ } catch (e) {
946
+ reject(e);
947
+ }
948
+ }
949
+ },
950
+ reason => {
951
+ if (!onrejected) {
952
+ reject(reason);
953
+ } else {
954
+ try {
955
+ resolve(onrejected(reason));
956
+ } catch (e) {
957
+ reject(e);
958
+ }
959
+ }
960
+ },
961
+ ]);
962
+ this._executeHandlers();
963
+ });
964
+ }
965
+
966
+ /** JSDoc */
967
+ catch(
968
+ onrejected,
969
+ ) {
970
+ return this.then(val => val, onrejected);
971
+ }
972
+
973
+ /** JSDoc */
974
+ finally(onfinally) {
975
+ return new SyncPromise((resolve, reject) => {
976
+ let val;
977
+ let isRejected;
978
+
979
+ return this.then(
980
+ value => {
981
+ isRejected = false;
982
+ val = value;
983
+ if (onfinally) {
984
+ onfinally();
985
+ }
986
+ },
987
+ reason => {
988
+ isRejected = true;
989
+ val = reason;
990
+ if (onfinally) {
991
+ onfinally();
992
+ }
993
+ },
994
+ ).then(() => {
995
+ if (isRejected) {
996
+ reject(val);
997
+ return;
998
+ }
999
+
1000
+ resolve(val );
1001
+ });
1002
+ });
1003
+ }
1004
+
1005
+ /** JSDoc */
1006
+ __init() {this._resolve = (value) => {
1007
+ this._setResult(States.RESOLVED, value);
1008
+ };}
1009
+
1010
+ /** JSDoc */
1011
+ __init2() {this._reject = (reason) => {
1012
+ this._setResult(States.REJECTED, reason);
1013
+ };}
1014
+
1015
+ /** JSDoc */
1016
+ __init3() {this._setResult = (state, value) => {
1017
+ if (this._state !== States.PENDING) {
1018
+ return;
1019
+ }
1020
+
1021
+ if (isThenable(value)) {
1022
+ void (value ).then(this._resolve, this._reject);
1023
+ return;
1024
+ }
1025
+
1026
+ this._state = state;
1027
+ this._value = value;
1028
+
1029
+ this._executeHandlers();
1030
+ };}
1031
+
1032
+ /** JSDoc */
1033
+ __init4() {this._executeHandlers = () => {
1034
+ if (this._state === States.PENDING) {
1035
+ return;
1036
+ }
1037
+
1038
+ const cachedHandlers = this._handlers.slice();
1039
+ this._handlers = [];
1040
+
1041
+ cachedHandlers.forEach(handler => {
1042
+ if (handler[0]) {
1043
+ return;
1044
+ }
1045
+
1046
+ if (this._state === States.RESOLVED) {
1047
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1048
+ handler[1](this._value );
1049
+ }
1050
+
1051
+ if (this._state === States.REJECTED) {
1052
+ handler[2](this._value);
1053
+ }
1054
+
1055
+ handler[0] = true;
1056
+ });
1057
+ };}
1058
+ }
1059
+
1060
+ // Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either
1061
+ //
1062
+ // a) moving `validSeverityLevels` to `@sentry/types`,
1063
+ // b) moving the`SeverityLevel` type here, or
1064
+ // c) importing `validSeverityLevels` from here into `@sentry/types`.
1065
+ //
1066
+ // Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would
1067
+ // create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the
1068
+ // type, reminding anyone who changes it to change this list also, will have to do.
1069
+
1070
+ const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];
1071
+
1072
+ /**
1073
+ * Converts a string-based level into a `SeverityLevel`, normalizing it along the way.
1074
+ *
1075
+ * @param level String representation of desired `SeverityLevel`.
1076
+ * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level.
1077
+ */
1078
+ function severityLevelFromString(level) {
1079
+ return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') ;
1080
+ }
1081
+
1082
+ const ONE_SECOND_IN_MS = 1000;
1083
+
1084
+ /**
1085
+ * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
1086
+ * for accessing a high-resolution monotonic clock.
1087
+ */
1088
+
1089
+ /**
1090
+ * Returns a timestamp in seconds since the UNIX epoch using the Date API.
1091
+ *
1092
+ * TODO(v8): Return type should be rounded.
1093
+ */
1094
+ function dateTimestampInSeconds() {
1095
+ return Date.now() / ONE_SECOND_IN_MS;
1096
+ }
1097
+
1098
+ /**
1099
+ * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
1100
+ * support the API.
1101
+ *
1102
+ * Wrapping the native API works around differences in behavior from different browsers.
1103
+ */
1104
+ function createUnixTimestampInSecondsFunc() {
1105
+ const { performance } = GLOBAL_OBJ ;
1106
+ if (!performance || !performance.now) {
1107
+ return dateTimestampInSeconds;
1108
+ }
1109
+
1110
+ // Some browser and environments don't have a timeOrigin, so we fallback to
1111
+ // using Date.now() to compute the starting time.
1112
+ const approxStartingTimeOrigin = Date.now() - performance.now();
1113
+ const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin;
1114
+
1115
+ // performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current
1116
+ // wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed.
1117
+ //
1118
+ // TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the
1119
+ // wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and
1120
+ // correct for this.
1121
+ // See: https://github.com/getsentry/sentry-javascript/issues/2590
1122
+ // See: https://github.com/mdn/content/issues/4713
1123
+ // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6
1124
+ return () => {
1125
+ return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS;
1126
+ };
1127
+ }
1128
+
1129
+ /**
1130
+ * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
1131
+ * availability of the Performance API.
1132
+ *
1133
+ * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
1134
+ * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
1135
+ * skew can grow to arbitrary amounts like days, weeks or months.
1136
+ * See https://github.com/getsentry/sentry-javascript/issues/2590.
1137
+ */
1138
+ const timestampInSeconds = createUnixTimestampInSecondsFunc();
1139
+
1140
+ /**
1141
+ * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
1142
+ * performance API is available.
1143
+ */
1144
+ (() => {
1145
+ // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
1146
+ // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
1147
+ // data as reliable if they are within a reasonable threshold of the current time.
1148
+
1149
+ const { performance } = GLOBAL_OBJ ;
1150
+ if (!performance || !performance.now) {
1151
+ return undefined;
1152
+ }
1153
+
1154
+ const threshold = 3600 * 1000;
1155
+ const performanceNow = performance.now();
1156
+ const dateNow = Date.now();
1157
+
1158
+ // if timeOrigin isn't available set delta to threshold so it isn't used
1159
+ const timeOriginDelta = performance.timeOrigin
1160
+ ? Math.abs(performance.timeOrigin + performanceNow - dateNow)
1161
+ : threshold;
1162
+ const timeOriginIsReliable = timeOriginDelta < threshold;
1163
+
1164
+ // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
1165
+ // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
1166
+ // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
1167
+ // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
1168
+ // Date API.
1169
+ // eslint-disable-next-line deprecation/deprecation
1170
+ const navigationStart = performance.timing && performance.timing.navigationStart;
1171
+ const hasNavigationStart = typeof navigationStart === 'number';
1172
+ // if navigationStart isn't available set delta to threshold so it isn't used
1173
+ const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
1174
+ const navigationStartIsReliable = navigationStartDelta < threshold;
1175
+
1176
+ if (timeOriginIsReliable || navigationStartIsReliable) {
1177
+ // Use the more reliable time origin
1178
+ if (timeOriginDelta <= navigationStartDelta) {
1179
+ return performance.timeOrigin;
1180
+ } else {
1181
+ return navigationStart;
1182
+ }
1183
+ }
1184
+ return dateNow;
1185
+ })();
1186
+
1187
+ /**
1188
+ * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
1189
+ *
1190
+ * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
1191
+ */
1192
+ const DEBUG_BUILD$1 = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
1193
+
1194
+ const DEFAULT_ENVIRONMENT = 'production';
1195
+
1196
+ /**
1197
+ * Returns the global event processors.
1198
+ * @deprecated Global event processors will be removed in v8.
1199
+ */
1200
+ function getGlobalEventProcessors() {
1201
+ return getGlobalSingleton('globalEventProcessors', () => []);
1202
+ }
1203
+
1204
+ /**
1205
+ * Process an array of event processors, returning the processed event (or `null` if the event was dropped).
1206
+ */
1207
+ function notifyEventProcessors(
1208
+ processors,
1209
+ event,
1210
+ hint,
1211
+ index = 0,
1212
+ ) {
1213
+ return new SyncPromise((resolve, reject) => {
1214
+ const processor = processors[index];
1215
+ if (event === null || typeof processor !== 'function') {
1216
+ resolve(event);
1217
+ } else {
1218
+ const result = processor({ ...event }, hint) ;
1219
+
1220
+ DEBUG_BUILD$1 && processor.id && result === null && logger.log(`Event processor "${processor.id}" dropped event`);
1221
+
1222
+ if (isThenable(result)) {
1223
+ void result
1224
+ .then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve))
1225
+ .then(null, reject);
1226
+ } else {
1227
+ void notifyEventProcessors(processors, result, hint, index + 1)
1228
+ .then(resolve)
1229
+ .then(null, reject);
1230
+ }
1231
+ }
1232
+ });
1233
+ }
1234
+
1235
+ /**
1236
+ * Creates a new `Session` object by setting certain default parameters. If optional @param context
1237
+ * is passed, the passed properties are applied to the session object.
1238
+ *
1239
+ * @param context (optional) additional properties to be applied to the returned session object
1240
+ *
1241
+ * @returns a new `Session` object
1242
+ */
1243
+ function makeSession(context) {
1244
+ // Both timestamp and started are in seconds since the UNIX epoch.
1245
+ const startingTime = timestampInSeconds();
1246
+
1247
+ const session = {
1248
+ sid: uuid4(),
1249
+ init: true,
1250
+ timestamp: startingTime,
1251
+ started: startingTime,
1252
+ duration: 0,
1253
+ status: 'ok',
1254
+ errors: 0,
1255
+ ignoreDuration: false,
1256
+ toJSON: () => sessionToJSON(session),
1257
+ };
1258
+
1259
+ if (context) {
1260
+ updateSession(session, context);
1261
+ }
1262
+
1263
+ return session;
1264
+ }
1265
+
1266
+ /**
1267
+ * Updates a session object with the properties passed in the context.
1268
+ *
1269
+ * Note that this function mutates the passed object and returns void.
1270
+ * (Had to do this instead of returning a new and updated session because closing and sending a session
1271
+ * makes an update to the session after it was passed to the sending logic.
1272
+ * @see BaseClient.captureSession )
1273
+ *
1274
+ * @param session the `Session` to update
1275
+ * @param context the `SessionContext` holding the properties that should be updated in @param session
1276
+ */
1277
+ // eslint-disable-next-line complexity
1278
+ function updateSession(session, context = {}) {
1279
+ if (context.user) {
1280
+ if (!session.ipAddress && context.user.ip_address) {
1281
+ session.ipAddress = context.user.ip_address;
1282
+ }
1283
+
1284
+ if (!session.did && !context.did) {
1285
+ session.did = context.user.id || context.user.email || context.user.username;
1286
+ }
1287
+ }
1288
+
1289
+ session.timestamp = context.timestamp || timestampInSeconds();
1290
+
1291
+ if (context.abnormal_mechanism) {
1292
+ session.abnormal_mechanism = context.abnormal_mechanism;
1293
+ }
1294
+
1295
+ if (context.ignoreDuration) {
1296
+ session.ignoreDuration = context.ignoreDuration;
1297
+ }
1298
+ if (context.sid) {
1299
+ // Good enough uuid validation. — Kamil
1300
+ session.sid = context.sid.length === 32 ? context.sid : uuid4();
1301
+ }
1302
+ if (context.init !== undefined) {
1303
+ session.init = context.init;
1304
+ }
1305
+ if (!session.did && context.did) {
1306
+ session.did = `${context.did}`;
1307
+ }
1308
+ if (typeof context.started === 'number') {
1309
+ session.started = context.started;
1310
+ }
1311
+ if (session.ignoreDuration) {
1312
+ session.duration = undefined;
1313
+ } else if (typeof context.duration === 'number') {
1314
+ session.duration = context.duration;
1315
+ } else {
1316
+ const duration = session.timestamp - session.started;
1317
+ session.duration = duration >= 0 ? duration : 0;
1318
+ }
1319
+ if (context.release) {
1320
+ session.release = context.release;
1321
+ }
1322
+ if (context.environment) {
1323
+ session.environment = context.environment;
1324
+ }
1325
+ if (!session.ipAddress && context.ipAddress) {
1326
+ session.ipAddress = context.ipAddress;
1327
+ }
1328
+ if (!session.userAgent && context.userAgent) {
1329
+ session.userAgent = context.userAgent;
1330
+ }
1331
+ if (typeof context.errors === 'number') {
1332
+ session.errors = context.errors;
1333
+ }
1334
+ if (context.status) {
1335
+ session.status = context.status;
1336
+ }
1337
+ }
1338
+
1339
+ /**
1340
+ * Closes a session by setting its status and updating the session object with it.
1341
+ * Internally calls `updateSession` to update the passed session object.
1342
+ *
1343
+ * Note that this function mutates the passed session (@see updateSession for explanation).
1344
+ *
1345
+ * @param session the `Session` object to be closed
1346
+ * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,
1347
+ * this function will keep the previously set status, unless it was `'ok'` in which case
1348
+ * it is changed to `'exited'`.
1349
+ */
1350
+ function closeSession(session, status) {
1351
+ let context = {};
1352
+ if (session.status === 'ok') {
1353
+ context = { status: 'exited' };
1354
+ }
1355
+
1356
+ updateSession(session, context);
1357
+ }
1358
+
1359
+ /**
1360
+ * Serializes a passed session object to a JSON object with a slightly different structure.
1361
+ * This is necessary because the Sentry backend requires a slightly different schema of a session
1362
+ * than the one the JS SDKs use internally.
1363
+ *
1364
+ * @param session the session to be converted
1365
+ *
1366
+ * @returns a JSON object of the passed session
1367
+ */
1368
+ function sessionToJSON(session) {
1369
+ return dropUndefinedKeys({
1370
+ sid: `${session.sid}`,
1371
+ init: session.init,
1372
+ // Make sure that sec is converted to ms for date constructor
1373
+ started: new Date(session.started * 1000).toISOString(),
1374
+ timestamp: new Date(session.timestamp * 1000).toISOString(),
1375
+ status: session.status,
1376
+ errors: session.errors,
1377
+ did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,
1378
+ duration: session.duration,
1379
+ abnormal_mechanism: session.abnormal_mechanism,
1380
+ attrs: {
1381
+ release: session.release,
1382
+ environment: session.environment,
1383
+ ip_address: session.ipAddress,
1384
+ user_agent: session.userAgent,
1385
+ },
1386
+ });
1387
+ }
1388
+
1389
+ const TRACE_FLAG_SAMPLED = 0x1;
1390
+
1391
+ /**
1392
+ * Convert a span to a trace context, which can be sent as the `trace` context in an event.
1393
+ */
1394
+ function spanToTraceContext(span) {
1395
+ const { spanId: span_id, traceId: trace_id } = span.spanContext();
1396
+ const { data, op, parent_span_id, status, tags, origin } = spanToJSON(span);
1397
+
1398
+ return dropUndefinedKeys({
1399
+ data,
1400
+ op,
1401
+ parent_span_id,
1402
+ span_id,
1403
+ status,
1404
+ tags,
1405
+ trace_id,
1406
+ origin,
1407
+ });
1408
+ }
1409
+
1410
+ /**
1411
+ * Convert a span to a JSON representation.
1412
+ * Note that all fields returned here are optional and need to be guarded against.
1413
+ *
1414
+ * Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).
1415
+ * This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.
1416
+ * And `spanToJSON` needs the Span class from `span.ts` to check here.
1417
+ * TODO v8: When we remove the deprecated stuff from `span.ts`, we can remove the circular dependency again.
1418
+ */
1419
+ function spanToJSON(span) {
1420
+ if (spanIsSpanClass(span)) {
1421
+ return span.getSpanJSON();
1422
+ }
1423
+
1424
+ // Fallback: We also check for `.toJSON()` here...
1425
+ // eslint-disable-next-line deprecation/deprecation
1426
+ if (typeof span.toJSON === 'function') {
1427
+ // eslint-disable-next-line deprecation/deprecation
1428
+ return span.toJSON();
1429
+ }
1430
+
1431
+ return {};
1432
+ }
1433
+
1434
+ /**
1435
+ * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.
1436
+ * :( So instead we approximate this by checking if it has the `getSpanJSON` method.
1437
+ */
1438
+ function spanIsSpanClass(span) {
1439
+ return typeof (span ).getSpanJSON === 'function';
1440
+ }
1441
+
1442
+ /**
1443
+ * Returns true if a span is sampled.
1444
+ * In most cases, you should just use `span.isRecording()` instead.
1445
+ * However, this has a slightly different semantic, as it also returns false if the span is finished.
1446
+ * So in the case where this distinction is important, use this method.
1447
+ */
1448
+ function spanIsSampled(span) {
1449
+ // We align our trace flags with the ones OpenTelemetry use
1450
+ // So we also check for sampled the same way they do.
1451
+ const { traceFlags } = span.spanContext();
1452
+ // eslint-disable-next-line no-bitwise
1453
+ return Boolean(traceFlags & TRACE_FLAG_SAMPLED);
1454
+ }
1455
+
1456
+ /**
1457
+ * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.
1458
+ * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.
1459
+ */
1460
+ function parseEventHintOrCaptureContext(
1461
+ hint,
1462
+ ) {
1463
+ if (!hint) {
1464
+ return undefined;
1465
+ }
1466
+
1467
+ // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext
1468
+ if (hintIsScopeOrFunction(hint)) {
1469
+ return { captureContext: hint };
1470
+ }
1471
+
1472
+ if (hintIsScopeContext(hint)) {
1473
+ return {
1474
+ captureContext: hint,
1475
+ };
1476
+ }
1477
+
1478
+ return hint;
1479
+ }
1480
+
1481
+ function hintIsScopeOrFunction(
1482
+ hint,
1483
+ ) {
1484
+ return hint instanceof Scope || typeof hint === 'function';
1485
+ }
1486
+
1487
+ const captureContextKeys = [
1488
+ 'user',
1489
+ 'level',
1490
+ 'extra',
1491
+ 'contexts',
1492
+ 'tags',
1493
+ 'fingerprint',
1494
+ 'requestSession',
1495
+ 'propagationContext',
1496
+ ] ;
1497
+
1498
+ function hintIsScopeContext(hint) {
1499
+ return Object.keys(hint).some(key => captureContextKeys.includes(key ));
1500
+ }
1501
+
1502
+ /**
1503
+ * Captures an exception event and sends it to Sentry.
1504
+ *
1505
+ * @param exception The exception to capture.
1506
+ * @param hint Optional additional data to attach to the Sentry event.
1507
+ * @returns the id of the captured Sentry event.
1508
+ */
1509
+ function captureException(
1510
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1511
+ exception,
1512
+ hint,
1513
+ ) {
1514
+ // eslint-disable-next-line deprecation/deprecation
1515
+ return getCurrentHub().captureException(exception, parseEventHintOrCaptureContext(hint));
1516
+ }
1517
+
1518
+ /**
1519
+ * Captures a message event and sends it to Sentry.
1520
+ *
1521
+ * @param exception The exception to capture.
1522
+ * @param captureContext Define the level of the message or pass in additional data to attach to the message.
1523
+ * @returns the id of the captured message.
1524
+ */
1525
+ function captureMessage(
1526
+ message,
1527
+ // eslint-disable-next-line deprecation/deprecation
1528
+ captureContext,
1529
+ ) {
1530
+ // This is necessary to provide explicit scopes upgrade, without changing the original
1531
+ // arity of the `captureMessage(message, level)` method.
1532
+ const level = typeof captureContext === 'string' ? captureContext : undefined;
1533
+ const context = typeof captureContext !== 'string' ? { captureContext } : undefined;
1534
+ // eslint-disable-next-line deprecation/deprecation
1535
+ return getCurrentHub().captureMessage(message, level, context);
1536
+ }
1537
+
1538
+ /**
1539
+ * Captures a manually created event and sends it to Sentry.
1540
+ *
1541
+ * @param exception The event to send to Sentry.
1542
+ * @param hint Optional additional data to attach to the Sentry event.
1543
+ * @returns the id of the captured event.
1544
+ */
1545
+ function captureEvent(event, hint) {
1546
+ // eslint-disable-next-line deprecation/deprecation
1547
+ return getCurrentHub().captureEvent(event, hint);
1548
+ }
1549
+
1550
+ /**
1551
+ * Creates a new scope with and executes the given operation within.
1552
+ * The scope is automatically removed once the operation
1553
+ * finishes or throws.
1554
+ *
1555
+ * This is essentially a convenience function for:
1556
+ *
1557
+ * pushScope();
1558
+ * callback();
1559
+ * popScope();
1560
+ */
1561
+
1562
+ /**
1563
+ * Either creates a new active scope, or sets the given scope as active scope in the given callback.
1564
+ */
1565
+ function withScope(
1566
+ ...rest
1567
+ ) {
1568
+ // eslint-disable-next-line deprecation/deprecation
1569
+ const hub = getCurrentHub();
1570
+
1571
+ // If a scope is defined, we want to make this the active scope instead of the default one
1572
+ if (rest.length === 2) {
1573
+ const [scope, callback] = rest;
1574
+ if (!scope) {
1575
+ // eslint-disable-next-line deprecation/deprecation
1576
+ return hub.withScope(callback);
1577
+ }
1578
+
1579
+ // eslint-disable-next-line deprecation/deprecation
1580
+ return hub.withScope(() => {
1581
+ // eslint-disable-next-line deprecation/deprecation
1582
+ hub.getStackTop().scope = scope ;
1583
+ return callback(scope );
1584
+ });
1585
+ }
1586
+
1587
+ // eslint-disable-next-line deprecation/deprecation
1588
+ return hub.withScope(rest[0]);
1589
+ }
1590
+
1591
+ /**
1592
+ * Get the currently active client.
1593
+ */
1594
+ function getClient() {
1595
+ // eslint-disable-next-line deprecation/deprecation
1596
+ return getCurrentHub().getClient();
1597
+ }
1598
+
1599
+ /**
1600
+ * Get the currently active scope.
1601
+ */
1602
+ function getCurrentScope() {
1603
+ // eslint-disable-next-line deprecation/deprecation
1604
+ return getCurrentHub().getScope();
1605
+ }
1606
+
1607
+ /**
1608
+ * Returns the root span of a given span.
1609
+ *
1610
+ * As long as we use `Transaction`s internally, the returned root span
1611
+ * will be a `Transaction` but be aware that this might change in the future.
1612
+ *
1613
+ * If the given span has no root span or transaction, `undefined` is returned.
1614
+ */
1615
+ function getRootSpan(span) {
1616
+ // TODO (v8): Remove this check and just return span
1617
+ // eslint-disable-next-line deprecation/deprecation
1618
+ return span.transaction;
1619
+ }
1620
+
1621
+ /**
1622
+ * Creates a dynamic sampling context from a client.
1623
+ *
1624
+ * Dispatches the `createDsc` lifecycle hook as a side effect.
1625
+ */
1626
+ function getDynamicSamplingContextFromClient(
1627
+ trace_id,
1628
+ client,
1629
+ scope,
1630
+ ) {
1631
+ const options = client.getOptions();
1632
+
1633
+ const { publicKey: public_key } = client.getDsn() || {};
1634
+ // TODO(v8): Remove segment from User
1635
+ // eslint-disable-next-line deprecation/deprecation
1636
+ const { segment: user_segment } = (scope && scope.getUser()) || {};
1637
+
1638
+ const dsc = dropUndefinedKeys({
1639
+ environment: options.environment || DEFAULT_ENVIRONMENT,
1640
+ release: options.release,
1641
+ user_segment,
1642
+ public_key,
1643
+ trace_id,
1644
+ }) ;
1645
+
1646
+ client.emit && client.emit('createDsc', dsc);
1647
+
1648
+ return dsc;
1649
+ }
1650
+
1651
+ /**
1652
+ * A Span with a frozen dynamic sampling context.
1653
+ */
1654
+
1655
+ /**
1656
+ * Creates a dynamic sampling context from a span (and client and scope)
1657
+ *
1658
+ * @param span the span from which a few values like the root span name and sample rate are extracted.
1659
+ *
1660
+ * @returns a dynamic sampling context
1661
+ */
1662
+ function getDynamicSamplingContextFromSpan(span) {
1663
+ const client = getClient();
1664
+ if (!client) {
1665
+ return {};
1666
+ }
1667
+
1668
+ // passing emit=false here to only emit later once the DSC is actually populated
1669
+ const dsc = getDynamicSamplingContextFromClient(spanToJSON(span).trace_id || '', client, getCurrentScope());
1670
+
1671
+ // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
1672
+ const txn = getRootSpan(span) ;
1673
+ if (!txn) {
1674
+ return dsc;
1675
+ }
1676
+
1677
+ // TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
1678
+ // For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set.
1679
+ // @see Transaction class constructor
1680
+ const v7FrozenDsc = txn && txn._frozenDynamicSamplingContext;
1681
+ if (v7FrozenDsc) {
1682
+ return v7FrozenDsc;
1683
+ }
1684
+
1685
+ // TODO (v8): Replace txn.metadata with txn.attributes[]
1686
+ // We can't do this yet because attributes aren't always set yet.
1687
+ // eslint-disable-next-line deprecation/deprecation
1688
+ const { sampleRate: maybeSampleRate, source } = txn.metadata;
1689
+ if (maybeSampleRate != null) {
1690
+ dsc.sample_rate = `${maybeSampleRate}`;
1691
+ }
1692
+
1693
+ // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
1694
+ const jsonSpan = spanToJSON(txn);
1695
+
1696
+ // after JSON conversion, txn.name becomes jsonSpan.description
1697
+ if (source && source !== 'url') {
1698
+ dsc.transaction = jsonSpan.description;
1699
+ }
1700
+
1701
+ dsc.sampled = String(spanIsSampled(txn));
1702
+
1703
+ client.emit && client.emit('createDsc', dsc);
1704
+
1705
+ return dsc;
1706
+ }
1707
+
1708
+ /**
1709
+ * Applies data from the scope to the event and runs all event processors on it.
1710
+ */
1711
+ function applyScopeDataToEvent(event, data) {
1712
+ const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data;
1713
+
1714
+ // Apply general data
1715
+ applyDataToEvent(event, data);
1716
+
1717
+ // We want to set the trace context for normal events only if there isn't already
1718
+ // a trace context on the event. There is a product feature in place where we link
1719
+ // errors with transaction and it relies on that.
1720
+ if (span) {
1721
+ applySpanToEvent(event, span);
1722
+ }
1723
+
1724
+ applyFingerprintToEvent(event, fingerprint);
1725
+ applyBreadcrumbsToEvent(event, breadcrumbs);
1726
+ applySdkMetadataToEvent(event, sdkProcessingMetadata);
1727
+ }
1728
+
1729
+ function applyDataToEvent(event, data) {
1730
+ const {
1731
+ extra,
1732
+ tags,
1733
+ user,
1734
+ contexts,
1735
+ level,
1736
+ // eslint-disable-next-line deprecation/deprecation
1737
+ transactionName,
1738
+ } = data;
1739
+
1740
+ const cleanedExtra = dropUndefinedKeys(extra);
1741
+ if (cleanedExtra && Object.keys(cleanedExtra).length) {
1742
+ event.extra = { ...cleanedExtra, ...event.extra };
1743
+ }
1744
+
1745
+ const cleanedTags = dropUndefinedKeys(tags);
1746
+ if (cleanedTags && Object.keys(cleanedTags).length) {
1747
+ event.tags = { ...cleanedTags, ...event.tags };
1748
+ }
1749
+
1750
+ const cleanedUser = dropUndefinedKeys(user);
1751
+ if (cleanedUser && Object.keys(cleanedUser).length) {
1752
+ event.user = { ...cleanedUser, ...event.user };
1753
+ }
1754
+
1755
+ const cleanedContexts = dropUndefinedKeys(contexts);
1756
+ if (cleanedContexts && Object.keys(cleanedContexts).length) {
1757
+ event.contexts = { ...cleanedContexts, ...event.contexts };
1758
+ }
1759
+
1760
+ if (level) {
1761
+ event.level = level;
1762
+ }
1763
+
1764
+ if (transactionName) {
1765
+ event.transaction = transactionName;
1766
+ }
1767
+ }
1768
+
1769
+ function applyBreadcrumbsToEvent(event, breadcrumbs) {
1770
+ const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs];
1771
+ event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined;
1772
+ }
1773
+
1774
+ function applySdkMetadataToEvent(event, sdkProcessingMetadata) {
1775
+ event.sdkProcessingMetadata = {
1776
+ ...event.sdkProcessingMetadata,
1777
+ ...sdkProcessingMetadata,
1778
+ };
1779
+ }
1780
+
1781
+ function applySpanToEvent(event, span) {
1782
+ event.contexts = { trace: spanToTraceContext(span), ...event.contexts };
1783
+ const rootSpan = getRootSpan(span);
1784
+ if (rootSpan) {
1785
+ event.sdkProcessingMetadata = {
1786
+ dynamicSamplingContext: getDynamicSamplingContextFromSpan(span),
1787
+ ...event.sdkProcessingMetadata,
1788
+ };
1789
+ const transactionName = spanToJSON(rootSpan).description;
1790
+ if (transactionName) {
1791
+ event.tags = { transaction: transactionName, ...event.tags };
1792
+ }
1793
+ }
1794
+ }
1795
+
1796
+ /**
1797
+ * Applies fingerprint from the scope to the event if there's one,
1798
+ * uses message if there's one instead or get rid of empty fingerprint
1799
+ */
1800
+ function applyFingerprintToEvent(event, fingerprint) {
1801
+ // Make sure it's an array first and we actually have something in place
1802
+ event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : [];
1803
+
1804
+ // If we have something on the scope, then merge it with event
1805
+ if (fingerprint) {
1806
+ event.fingerprint = event.fingerprint.concat(fingerprint);
1807
+ }
1808
+
1809
+ // If we have no data at all, remove empty array default
1810
+ if (event.fingerprint && !event.fingerprint.length) {
1811
+ delete event.fingerprint;
1812
+ }
1813
+ }
1814
+
1815
+ /**
1816
+ * Default value for maximum number of breadcrumbs added to an event.
1817
+ */
1818
+ const DEFAULT_MAX_BREADCRUMBS = 100;
1819
+
1820
+ /**
1821
+ * Holds additional event information. {@link Scope.applyToEvent} will be
1822
+ * called by the client before an event will be sent.
1823
+ */
1824
+ class Scope {
1825
+ /** Flag if notifying is happening. */
1826
+
1827
+ /** Callback for client to receive scope changes. */
1828
+
1829
+ /** Callback list that will be called after {@link applyToEvent}. */
1830
+
1831
+ /** Array of breadcrumbs. */
1832
+
1833
+ /** User */
1834
+
1835
+ /** Tags */
1836
+
1837
+ /** Extra */
1838
+
1839
+ /** Contexts */
1840
+
1841
+ /** Attachments */
1842
+
1843
+ /** Propagation Context for distributed tracing */
1844
+
1845
+ /**
1846
+ * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
1847
+ * sent to Sentry
1848
+ */
1849
+
1850
+ /** Fingerprint */
1851
+
1852
+ /** Severity */
1853
+ // eslint-disable-next-line deprecation/deprecation
1854
+
1855
+ /**
1856
+ * Transaction Name
1857
+ */
1858
+
1859
+ /** Span */
1860
+
1861
+ /** Session */
1862
+
1863
+ /** Request Mode Session Status */
1864
+
1865
+ /** The client on this scope */
1866
+
1867
+ // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.
1868
+
1869
+ constructor() {
1870
+ this._notifyingListeners = false;
1871
+ this._scopeListeners = [];
1872
+ this._eventProcessors = [];
1873
+ this._breadcrumbs = [];
1874
+ this._attachments = [];
1875
+ this._user = {};
1876
+ this._tags = {};
1877
+ this._extra = {};
1878
+ this._contexts = {};
1879
+ this._sdkProcessingMetadata = {};
1880
+ this._propagationContext = generatePropagationContext();
1881
+ }
1882
+
1883
+ /**
1884
+ * Inherit values from the parent scope.
1885
+ * @deprecated Use `scope.clone()` and `new Scope()` instead.
1886
+ */
1887
+ static clone(scope) {
1888
+ return scope ? scope.clone() : new Scope();
1889
+ }
1890
+
1891
+ /**
1892
+ * Clone this scope instance.
1893
+ */
1894
+ clone() {
1895
+ const newScope = new Scope();
1896
+ newScope._breadcrumbs = [...this._breadcrumbs];
1897
+ newScope._tags = { ...this._tags };
1898
+ newScope._extra = { ...this._extra };
1899
+ newScope._contexts = { ...this._contexts };
1900
+ newScope._user = this._user;
1901
+ newScope._level = this._level;
1902
+ newScope._span = this._span;
1903
+ newScope._session = this._session;
1904
+ newScope._transactionName = this._transactionName;
1905
+ newScope._fingerprint = this._fingerprint;
1906
+ newScope._eventProcessors = [...this._eventProcessors];
1907
+ newScope._requestSession = this._requestSession;
1908
+ newScope._attachments = [...this._attachments];
1909
+ newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };
1910
+ newScope._propagationContext = { ...this._propagationContext };
1911
+ newScope._client = this._client;
1912
+
1913
+ return newScope;
1914
+ }
1915
+
1916
+ /** Update the client on the scope. */
1917
+ setClient(client) {
1918
+ this._client = client;
1919
+ }
1920
+
1921
+ /**
1922
+ * Get the client assigned to this scope.
1923
+ *
1924
+ * It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing.
1925
+ */
1926
+ getClient() {
1927
+ return this._client;
1928
+ }
1929
+
1930
+ /**
1931
+ * Add internal on change listener. Used for sub SDKs that need to store the scope.
1932
+ * @hidden
1933
+ */
1934
+ addScopeListener(callback) {
1935
+ this._scopeListeners.push(callback);
1936
+ }
1937
+
1938
+ /**
1939
+ * @inheritDoc
1940
+ */
1941
+ addEventProcessor(callback) {
1942
+ this._eventProcessors.push(callback);
1943
+ return this;
1944
+ }
1945
+
1946
+ /**
1947
+ * @inheritDoc
1948
+ */
1949
+ setUser(user) {
1950
+ // If null is passed we want to unset everything, but still define keys,
1951
+ // so that later down in the pipeline any existing values are cleared.
1952
+ this._user = user || {
1953
+ email: undefined,
1954
+ id: undefined,
1955
+ ip_address: undefined,
1956
+ segment: undefined,
1957
+ username: undefined,
1958
+ };
1959
+
1960
+ if (this._session) {
1961
+ updateSession(this._session, { user });
1962
+ }
1963
+
1964
+ this._notifyScopeListeners();
1965
+ return this;
1966
+ }
1967
+
1968
+ /**
1969
+ * @inheritDoc
1970
+ */
1971
+ getUser() {
1972
+ return this._user;
1973
+ }
1974
+
1975
+ /**
1976
+ * @inheritDoc
1977
+ */
1978
+ getRequestSession() {
1979
+ return this._requestSession;
1980
+ }
1981
+
1982
+ /**
1983
+ * @inheritDoc
1984
+ */
1985
+ setRequestSession(requestSession) {
1986
+ this._requestSession = requestSession;
1987
+ return this;
1988
+ }
1989
+
1990
+ /**
1991
+ * @inheritDoc
1992
+ */
1993
+ setTags(tags) {
1994
+ this._tags = {
1995
+ ...this._tags,
1996
+ ...tags,
1997
+ };
1998
+ this._notifyScopeListeners();
1999
+ return this;
2000
+ }
2001
+
2002
+ /**
2003
+ * @inheritDoc
2004
+ */
2005
+ setTag(key, value) {
2006
+ this._tags = { ...this._tags, [key]: value };
2007
+ this._notifyScopeListeners();
2008
+ return this;
2009
+ }
2010
+
2011
+ /**
2012
+ * @inheritDoc
2013
+ */
2014
+ setExtras(extras) {
2015
+ this._extra = {
2016
+ ...this._extra,
2017
+ ...extras,
2018
+ };
2019
+ this._notifyScopeListeners();
2020
+ return this;
2021
+ }
2022
+
2023
+ /**
2024
+ * @inheritDoc
2025
+ */
2026
+ setExtra(key, extra) {
2027
+ this._extra = { ...this._extra, [key]: extra };
2028
+ this._notifyScopeListeners();
2029
+ return this;
2030
+ }
2031
+
2032
+ /**
2033
+ * @inheritDoc
2034
+ */
2035
+ setFingerprint(fingerprint) {
2036
+ this._fingerprint = fingerprint;
2037
+ this._notifyScopeListeners();
2038
+ return this;
2039
+ }
2040
+
2041
+ /**
2042
+ * @inheritDoc
2043
+ */
2044
+ setLevel(
2045
+ // eslint-disable-next-line deprecation/deprecation
2046
+ level,
2047
+ ) {
2048
+ this._level = level;
2049
+ this._notifyScopeListeners();
2050
+ return this;
2051
+ }
2052
+
2053
+ /**
2054
+ * Sets the transaction name on the scope for future events.
2055
+ */
2056
+ setTransactionName(name) {
2057
+ this._transactionName = name;
2058
+ this._notifyScopeListeners();
2059
+ return this;
2060
+ }
2061
+
2062
+ /**
2063
+ * @inheritDoc
2064
+ */
2065
+ setContext(key, context) {
2066
+ if (context === null) {
2067
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
2068
+ delete this._contexts[key];
2069
+ } else {
2070
+ this._contexts[key] = context;
2071
+ }
2072
+
2073
+ this._notifyScopeListeners();
2074
+ return this;
2075
+ }
2076
+
2077
+ /**
2078
+ * Sets the Span on the scope.
2079
+ * @param span Span
2080
+ * @deprecated Instead of setting a span on a scope, use `startSpan()`/`startSpanManual()` instead.
2081
+ */
2082
+ setSpan(span) {
2083
+ this._span = span;
2084
+ this._notifyScopeListeners();
2085
+ return this;
2086
+ }
2087
+
2088
+ /**
2089
+ * Returns the `Span` if there is one.
2090
+ * @deprecated Use `getActiveSpan()` instead.
2091
+ */
2092
+ getSpan() {
2093
+ return this._span;
2094
+ }
2095
+
2096
+ /**
2097
+ * Returns the `Transaction` attached to the scope (if there is one).
2098
+ * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead.
2099
+ */
2100
+ getTransaction() {
2101
+ // Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
2102
+ // have a pointer to the currently-active transaction.
2103
+ const span = this._span;
2104
+ // Cannot replace with getRootSpan because getRootSpan returns a span, not a transaction
2105
+ // Also, this method will be removed anyway.
2106
+ // eslint-disable-next-line deprecation/deprecation
2107
+ return span && span.transaction;
2108
+ }
2109
+
2110
+ /**
2111
+ * @inheritDoc
2112
+ */
2113
+ setSession(session) {
2114
+ if (!session) {
2115
+ delete this._session;
2116
+ } else {
2117
+ this._session = session;
2118
+ }
2119
+ this._notifyScopeListeners();
2120
+ return this;
2121
+ }
2122
+
2123
+ /**
2124
+ * @inheritDoc
2125
+ */
2126
+ getSession() {
2127
+ return this._session;
2128
+ }
2129
+
2130
+ /**
2131
+ * @inheritDoc
2132
+ */
2133
+ update(captureContext) {
2134
+ if (!captureContext) {
2135
+ return this;
2136
+ }
2137
+
2138
+ const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext;
2139
+
2140
+ if (scopeToMerge instanceof Scope) {
2141
+ const scopeData = scopeToMerge.getScopeData();
2142
+
2143
+ this._tags = { ...this._tags, ...scopeData.tags };
2144
+ this._extra = { ...this._extra, ...scopeData.extra };
2145
+ this._contexts = { ...this._contexts, ...scopeData.contexts };
2146
+ if (scopeData.user && Object.keys(scopeData.user).length) {
2147
+ this._user = scopeData.user;
2148
+ }
2149
+ if (scopeData.level) {
2150
+ this._level = scopeData.level;
2151
+ }
2152
+ if (scopeData.fingerprint.length) {
2153
+ this._fingerprint = scopeData.fingerprint;
2154
+ }
2155
+ if (scopeToMerge.getRequestSession()) {
2156
+ this._requestSession = scopeToMerge.getRequestSession();
2157
+ }
2158
+ if (scopeData.propagationContext) {
2159
+ this._propagationContext = scopeData.propagationContext;
2160
+ }
2161
+ } else if (isPlainObject(scopeToMerge)) {
2162
+ const scopeContext = captureContext ;
2163
+ this._tags = { ...this._tags, ...scopeContext.tags };
2164
+ this._extra = { ...this._extra, ...scopeContext.extra };
2165
+ this._contexts = { ...this._contexts, ...scopeContext.contexts };
2166
+ if (scopeContext.user) {
2167
+ this._user = scopeContext.user;
2168
+ }
2169
+ if (scopeContext.level) {
2170
+ this._level = scopeContext.level;
2171
+ }
2172
+ if (scopeContext.fingerprint) {
2173
+ this._fingerprint = scopeContext.fingerprint;
2174
+ }
2175
+ if (scopeContext.requestSession) {
2176
+ this._requestSession = scopeContext.requestSession;
2177
+ }
2178
+ if (scopeContext.propagationContext) {
2179
+ this._propagationContext = scopeContext.propagationContext;
2180
+ }
2181
+ }
2182
+
2183
+ return this;
2184
+ }
2185
+
2186
+ /**
2187
+ * @inheritDoc
2188
+ */
2189
+ clear() {
2190
+ this._breadcrumbs = [];
2191
+ this._tags = {};
2192
+ this._extra = {};
2193
+ this._user = {};
2194
+ this._contexts = {};
2195
+ this._level = undefined;
2196
+ this._transactionName = undefined;
2197
+ this._fingerprint = undefined;
2198
+ this._requestSession = undefined;
2199
+ this._span = undefined;
2200
+ this._session = undefined;
2201
+ this._notifyScopeListeners();
2202
+ this._attachments = [];
2203
+ this._propagationContext = generatePropagationContext();
2204
+ return this;
2205
+ }
2206
+
2207
+ /**
2208
+ * @inheritDoc
2209
+ */
2210
+ addBreadcrumb(breadcrumb, maxBreadcrumbs) {
2211
+ const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;
2212
+
2213
+ // No data has been changed, so don't notify scope listeners
2214
+ if (maxCrumbs <= 0) {
2215
+ return this;
2216
+ }
2217
+
2218
+ const mergedBreadcrumb = {
2219
+ timestamp: dateTimestampInSeconds(),
2220
+ ...breadcrumb,
2221
+ };
2222
+
2223
+ const breadcrumbs = this._breadcrumbs;
2224
+ breadcrumbs.push(mergedBreadcrumb);
2225
+ this._breadcrumbs = breadcrumbs.length > maxCrumbs ? breadcrumbs.slice(-maxCrumbs) : breadcrumbs;
2226
+
2227
+ this._notifyScopeListeners();
2228
+
2229
+ return this;
2230
+ }
2231
+
2232
+ /**
2233
+ * @inheritDoc
2234
+ */
2235
+ getLastBreadcrumb() {
2236
+ return this._breadcrumbs[this._breadcrumbs.length - 1];
2237
+ }
2238
+
2239
+ /**
2240
+ * @inheritDoc
2241
+ */
2242
+ clearBreadcrumbs() {
2243
+ this._breadcrumbs = [];
2244
+ this._notifyScopeListeners();
2245
+ return this;
2246
+ }
2247
+
2248
+ /**
2249
+ * @inheritDoc
2250
+ */
2251
+ addAttachment(attachment) {
2252
+ this._attachments.push(attachment);
2253
+ return this;
2254
+ }
2255
+
2256
+ /**
2257
+ * @inheritDoc
2258
+ * @deprecated Use `getScopeData()` instead.
2259
+ */
2260
+ getAttachments() {
2261
+ const data = this.getScopeData();
2262
+
2263
+ return data.attachments;
2264
+ }
2265
+
2266
+ /**
2267
+ * @inheritDoc
2268
+ */
2269
+ clearAttachments() {
2270
+ this._attachments = [];
2271
+ return this;
2272
+ }
2273
+
2274
+ /** @inheritDoc */
2275
+ getScopeData() {
2276
+ const {
2277
+ _breadcrumbs,
2278
+ _attachments,
2279
+ _contexts,
2280
+ _tags,
2281
+ _extra,
2282
+ _user,
2283
+ _level,
2284
+ _fingerprint,
2285
+ _eventProcessors,
2286
+ _propagationContext,
2287
+ _sdkProcessingMetadata,
2288
+ _transactionName,
2289
+ _span,
2290
+ } = this;
2291
+
2292
+ return {
2293
+ breadcrumbs: _breadcrumbs,
2294
+ attachments: _attachments,
2295
+ contexts: _contexts,
2296
+ tags: _tags,
2297
+ extra: _extra,
2298
+ user: _user,
2299
+ level: _level,
2300
+ fingerprint: _fingerprint || [],
2301
+ eventProcessors: _eventProcessors,
2302
+ propagationContext: _propagationContext,
2303
+ sdkProcessingMetadata: _sdkProcessingMetadata,
2304
+ transactionName: _transactionName,
2305
+ span: _span,
2306
+ };
2307
+ }
2308
+
2309
+ /**
2310
+ * Applies data from the scope to the event and runs all event processors on it.
2311
+ *
2312
+ * @param event Event
2313
+ * @param hint Object containing additional information about the original exception, for use by the event processors.
2314
+ * @hidden
2315
+ * @deprecated Use `applyScopeDataToEvent()` directly
2316
+ */
2317
+ applyToEvent(
2318
+ event,
2319
+ hint = {},
2320
+ additionalEventProcessors = [],
2321
+ ) {
2322
+ applyScopeDataToEvent(event, this.getScopeData());
2323
+
2324
+ // TODO (v8): Update this order to be: Global > Client > Scope
2325
+ const eventProcessors = [
2326
+ ...additionalEventProcessors,
2327
+ // eslint-disable-next-line deprecation/deprecation
2328
+ ...getGlobalEventProcessors(),
2329
+ ...this._eventProcessors,
2330
+ ];
2331
+
2332
+ return notifyEventProcessors(eventProcessors, event, hint);
2333
+ }
2334
+
2335
+ /**
2336
+ * Add data which will be accessible during event processing but won't get sent to Sentry
2337
+ */
2338
+ setSDKProcessingMetadata(newData) {
2339
+ this._sdkProcessingMetadata = { ...this._sdkProcessingMetadata, ...newData };
2340
+
2341
+ return this;
2342
+ }
2343
+
2344
+ /**
2345
+ * @inheritDoc
2346
+ */
2347
+ setPropagationContext(context) {
2348
+ this._propagationContext = context;
2349
+ return this;
2350
+ }
2351
+
2352
+ /**
2353
+ * @inheritDoc
2354
+ */
2355
+ getPropagationContext() {
2356
+ return this._propagationContext;
2357
+ }
2358
+
2359
+ /**
2360
+ * Capture an exception for this scope.
2361
+ *
2362
+ * @param exception The exception to capture.
2363
+ * @param hint Optinal additional data to attach to the Sentry event.
2364
+ * @returns the id of the captured Sentry event.
2365
+ */
2366
+ captureException(exception, hint) {
2367
+ const eventId = hint && hint.event_id ? hint.event_id : uuid4();
2368
+
2369
+ if (!this._client) {
2370
+ logger.warn('No client configured on scope - will not capture exception!');
2371
+ return eventId;
2372
+ }
2373
+
2374
+ const syntheticException = new Error('Sentry syntheticException');
2375
+
2376
+ this._client.captureException(
2377
+ exception,
2378
+ {
2379
+ originalException: exception,
2380
+ syntheticException,
2381
+ ...hint,
2382
+ event_id: eventId,
2383
+ },
2384
+ this,
2385
+ );
2386
+
2387
+ return eventId;
2388
+ }
2389
+
2390
+ /**
2391
+ * Capture a message for this scope.
2392
+ *
2393
+ * @param message The message to capture.
2394
+ * @param level An optional severity level to report the message with.
2395
+ * @param hint Optional additional data to attach to the Sentry event.
2396
+ * @returns the id of the captured message.
2397
+ */
2398
+ captureMessage(message, level, hint) {
2399
+ const eventId = hint && hint.event_id ? hint.event_id : uuid4();
2400
+
2401
+ if (!this._client) {
2402
+ logger.warn('No client configured on scope - will not capture message!');
2403
+ return eventId;
2404
+ }
2405
+
2406
+ const syntheticException = new Error(message);
2407
+
2408
+ this._client.captureMessage(
2409
+ message,
2410
+ level,
2411
+ {
2412
+ originalException: message,
2413
+ syntheticException,
2414
+ ...hint,
2415
+ event_id: eventId,
2416
+ },
2417
+ this,
2418
+ );
2419
+
2420
+ return eventId;
2421
+ }
2422
+
2423
+ /**
2424
+ * Captures a manually created event for this scope and sends it to Sentry.
2425
+ *
2426
+ * @param exception The event to capture.
2427
+ * @param hint Optional additional data to attach to the Sentry event.
2428
+ * @returns the id of the captured event.
2429
+ */
2430
+ captureEvent(event, hint) {
2431
+ const eventId = hint && hint.event_id ? hint.event_id : uuid4();
2432
+
2433
+ if (!this._client) {
2434
+ logger.warn('No client configured on scope - will not capture event!');
2435
+ return eventId;
2436
+ }
2437
+
2438
+ this._client.captureEvent(event, { ...hint, event_id: eventId }, this);
2439
+
2440
+ return eventId;
2441
+ }
2442
+
2443
+ /**
2444
+ * This will be called on every set call.
2445
+ */
2446
+ _notifyScopeListeners() {
2447
+ // We need this check for this._notifyingListeners to be able to work on scope during updates
2448
+ // If this check is not here we'll produce endless recursion when something is done with the scope
2449
+ // during the callback.
2450
+ if (!this._notifyingListeners) {
2451
+ this._notifyingListeners = true;
2452
+ this._scopeListeners.forEach(callback => {
2453
+ callback(this);
2454
+ });
2455
+ this._notifyingListeners = false;
2456
+ }
2457
+ }
2458
+ }
2459
+
2460
+ function generatePropagationContext() {
2461
+ return {
2462
+ traceId: uuid4(),
2463
+ spanId: uuid4().substring(16),
2464
+ };
2465
+ }
2466
+
2467
+ const SDK_VERSION = '7.117.0';
2468
+
2469
+ /**
2470
+ * API compatibility version of this hub.
2471
+ *
2472
+ * WARNING: This number should only be increased when the global interface
2473
+ * changes and new methods are introduced.
2474
+ *
2475
+ * @hidden
2476
+ */
2477
+ const API_VERSION = parseFloat(SDK_VERSION);
2478
+
2479
+ /**
2480
+ * Default maximum number of breadcrumbs added to an event. Can be overwritten
2481
+ * with {@link Options.maxBreadcrumbs}.
2482
+ */
2483
+ const DEFAULT_BREADCRUMBS = 100;
2484
+
2485
+ /**
2486
+ * @deprecated The `Hub` class will be removed in version 8 of the SDK in favour of `Scope` and `Client` objects.
2487
+ *
2488
+ * If you previously used the `Hub` class directly, replace it with `Scope` and `Client` objects. More information:
2489
+ * - [Multiple Sentry Instances](https://docs.sentry.io/platforms/javascript/best-practices/multiple-sentry-instances/)
2490
+ * - [Browser Extensions](https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/)
2491
+ *
2492
+ * Some of our APIs are typed with the Hub class instead of the interface (e.g. `getCurrentHub`). Most of them are deprecated
2493
+ * themselves and will also be removed in version 8. More information:
2494
+ * - [Migration Guide](https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md#deprecate-hub)
2495
+ */
2496
+ // eslint-disable-next-line deprecation/deprecation
2497
+ class Hub {
2498
+ /** Is a {@link Layer}[] containing the client and scope */
2499
+
2500
+ /** Contains the last event id of a captured event. */
2501
+
2502
+ /**
2503
+ * Creates a new instance of the hub, will push one {@link Layer} into the
2504
+ * internal stack on creation.
2505
+ *
2506
+ * @param client bound to the hub.
2507
+ * @param scope bound to the hub.
2508
+ * @param version number, higher number means higher priority.
2509
+ *
2510
+ * @deprecated Instantiation of Hub objects is deprecated and the constructor will be removed in version 8 of the SDK.
2511
+ *
2512
+ * If you are currently using the Hub for multi-client use like so:
2513
+ *
2514
+ * ```
2515
+ * // OLD
2516
+ * const hub = new Hub();
2517
+ * hub.bindClient(client);
2518
+ * makeMain(hub)
2519
+ * ```
2520
+ *
2521
+ * instead initialize the client as follows:
2522
+ *
2523
+ * ```
2524
+ * // NEW
2525
+ * Sentry.withIsolationScope(() => {
2526
+ * Sentry.setCurrentClient(client);
2527
+ * client.init();
2528
+ * });
2529
+ * ```
2530
+ *
2531
+ * If you are using the Hub to capture events like so:
2532
+ *
2533
+ * ```
2534
+ * // OLD
2535
+ * const client = new Client();
2536
+ * const hub = new Hub(client);
2537
+ * hub.captureException()
2538
+ * ```
2539
+ *
2540
+ * instead capture isolated events as follows:
2541
+ *
2542
+ * ```
2543
+ * // NEW
2544
+ * const client = new Client();
2545
+ * const scope = new Scope();
2546
+ * scope.setClient(client);
2547
+ * scope.captureException();
2548
+ * ```
2549
+ */
2550
+ constructor(
2551
+ client,
2552
+ scope,
2553
+ isolationScope,
2554
+ _version = API_VERSION,
2555
+ ) {this._version = _version;
2556
+ let assignedScope;
2557
+ if (!scope) {
2558
+ assignedScope = new Scope();
2559
+ assignedScope.setClient(client);
2560
+ } else {
2561
+ assignedScope = scope;
2562
+ }
2563
+
2564
+ let assignedIsolationScope;
2565
+ if (!isolationScope) {
2566
+ assignedIsolationScope = new Scope();
2567
+ assignedIsolationScope.setClient(client);
2568
+ } else {
2569
+ assignedIsolationScope = isolationScope;
2570
+ }
2571
+
2572
+ this._stack = [{ scope: assignedScope }];
2573
+
2574
+ if (client) {
2575
+ // eslint-disable-next-line deprecation/deprecation
2576
+ this.bindClient(client);
2577
+ }
2578
+
2579
+ this._isolationScope = assignedIsolationScope;
2580
+ }
2581
+
2582
+ /**
2583
+ * Checks if this hub's version is older than the given version.
2584
+ *
2585
+ * @param version A version number to compare to.
2586
+ * @return True if the given version is newer; otherwise false.
2587
+ *
2588
+ * @deprecated This will be removed in v8.
2589
+ */
2590
+ isOlderThan(version) {
2591
+ return this._version < version;
2592
+ }
2593
+
2594
+ /**
2595
+ * This binds the given client to the current scope.
2596
+ * @param client An SDK client (client) instance.
2597
+ *
2598
+ * @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead.
2599
+ */
2600
+ bindClient(client) {
2601
+ // eslint-disable-next-line deprecation/deprecation
2602
+ const top = this.getStackTop();
2603
+ top.client = client;
2604
+ top.scope.setClient(client);
2605
+ // eslint-disable-next-line deprecation/deprecation
2606
+ if (client && client.setupIntegrations) {
2607
+ // eslint-disable-next-line deprecation/deprecation
2608
+ client.setupIntegrations();
2609
+ }
2610
+ }
2611
+
2612
+ /**
2613
+ * @inheritDoc
2614
+ *
2615
+ * @deprecated Use `withScope` instead.
2616
+ */
2617
+ pushScope() {
2618
+ // We want to clone the content of prev scope
2619
+ // eslint-disable-next-line deprecation/deprecation
2620
+ const scope = this.getScope().clone();
2621
+ // eslint-disable-next-line deprecation/deprecation
2622
+ this.getStack().push({
2623
+ // eslint-disable-next-line deprecation/deprecation
2624
+ client: this.getClient(),
2625
+ scope,
2626
+ });
2627
+ return scope;
2628
+ }
2629
+
2630
+ /**
2631
+ * @inheritDoc
2632
+ *
2633
+ * @deprecated Use `withScope` instead.
2634
+ */
2635
+ popScope() {
2636
+ // eslint-disable-next-line deprecation/deprecation
2637
+ if (this.getStack().length <= 1) return false;
2638
+ // eslint-disable-next-line deprecation/deprecation
2639
+ return !!this.getStack().pop();
2640
+ }
2641
+
2642
+ /**
2643
+ * @inheritDoc
2644
+ *
2645
+ * @deprecated Use `Sentry.withScope()` instead.
2646
+ */
2647
+ withScope(callback) {
2648
+ // eslint-disable-next-line deprecation/deprecation
2649
+ const scope = this.pushScope();
2650
+
2651
+ let maybePromiseResult;
2652
+ try {
2653
+ maybePromiseResult = callback(scope);
2654
+ } catch (e) {
2655
+ // eslint-disable-next-line deprecation/deprecation
2656
+ this.popScope();
2657
+ throw e;
2658
+ }
2659
+
2660
+ if (isThenable(maybePromiseResult)) {
2661
+ // @ts-expect-error - isThenable returns the wrong type
2662
+ return maybePromiseResult.then(
2663
+ res => {
2664
+ // eslint-disable-next-line deprecation/deprecation
2665
+ this.popScope();
2666
+ return res;
2667
+ },
2668
+ e => {
2669
+ // eslint-disable-next-line deprecation/deprecation
2670
+ this.popScope();
2671
+ throw e;
2672
+ },
2673
+ );
2674
+ }
2675
+
2676
+ // eslint-disable-next-line deprecation/deprecation
2677
+ this.popScope();
2678
+ return maybePromiseResult;
2679
+ }
2680
+
2681
+ /**
2682
+ * @inheritDoc
2683
+ *
2684
+ * @deprecated Use `Sentry.getClient()` instead.
2685
+ */
2686
+ getClient() {
2687
+ // eslint-disable-next-line deprecation/deprecation
2688
+ return this.getStackTop().client ;
2689
+ }
2690
+
2691
+ /**
2692
+ * Returns the scope of the top stack.
2693
+ *
2694
+ * @deprecated Use `Sentry.getCurrentScope()` instead.
2695
+ */
2696
+ getScope() {
2697
+ // eslint-disable-next-line deprecation/deprecation
2698
+ return this.getStackTop().scope;
2699
+ }
2700
+
2701
+ /**
2702
+ * @deprecated Use `Sentry.getIsolationScope()` instead.
2703
+ */
2704
+ getIsolationScope() {
2705
+ return this._isolationScope;
2706
+ }
2707
+
2708
+ /**
2709
+ * Returns the scope stack for domains or the process.
2710
+ * @deprecated This will be removed in v8.
2711
+ */
2712
+ getStack() {
2713
+ return this._stack;
2714
+ }
2715
+
2716
+ /**
2717
+ * Returns the topmost scope layer in the order domain > local > process.
2718
+ * @deprecated This will be removed in v8.
2719
+ */
2720
+ getStackTop() {
2721
+ return this._stack[this._stack.length - 1];
2722
+ }
2723
+
2724
+ /**
2725
+ * @inheritDoc
2726
+ *
2727
+ * @deprecated Use `Sentry.captureException()` instead.
2728
+ */
2729
+ captureException(exception, hint) {
2730
+ const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4());
2731
+ const syntheticException = new Error('Sentry syntheticException');
2732
+ // eslint-disable-next-line deprecation/deprecation
2733
+ this.getScope().captureException(exception, {
2734
+ originalException: exception,
2735
+ syntheticException,
2736
+ ...hint,
2737
+ event_id: eventId,
2738
+ });
2739
+
2740
+ return eventId;
2741
+ }
2742
+
2743
+ /**
2744
+ * @inheritDoc
2745
+ *
2746
+ * @deprecated Use `Sentry.captureMessage()` instead.
2747
+ */
2748
+ captureMessage(
2749
+ message,
2750
+ // eslint-disable-next-line deprecation/deprecation
2751
+ level,
2752
+ hint,
2753
+ ) {
2754
+ const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4());
2755
+ const syntheticException = new Error(message);
2756
+ // eslint-disable-next-line deprecation/deprecation
2757
+ this.getScope().captureMessage(message, level, {
2758
+ originalException: message,
2759
+ syntheticException,
2760
+ ...hint,
2761
+ event_id: eventId,
2762
+ });
2763
+
2764
+ return eventId;
2765
+ }
2766
+
2767
+ /**
2768
+ * @inheritDoc
2769
+ *
2770
+ * @deprecated Use `Sentry.captureEvent()` instead.
2771
+ */
2772
+ captureEvent(event, hint) {
2773
+ const eventId = hint && hint.event_id ? hint.event_id : uuid4();
2774
+ if (!event.type) {
2775
+ this._lastEventId = eventId;
2776
+ }
2777
+ // eslint-disable-next-line deprecation/deprecation
2778
+ this.getScope().captureEvent(event, { ...hint, event_id: eventId });
2779
+ return eventId;
2780
+ }
2781
+
2782
+ /**
2783
+ * @inheritDoc
2784
+ *
2785
+ * @deprecated This will be removed in v8.
2786
+ */
2787
+ lastEventId() {
2788
+ return this._lastEventId;
2789
+ }
2790
+
2791
+ /**
2792
+ * @inheritDoc
2793
+ *
2794
+ * @deprecated Use `Sentry.addBreadcrumb()` instead.
2795
+ */
2796
+ addBreadcrumb(breadcrumb, hint) {
2797
+ // eslint-disable-next-line deprecation/deprecation
2798
+ const { scope, client } = this.getStackTop();
2799
+
2800
+ if (!client) return;
2801
+
2802
+ const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } =
2803
+ (client.getOptions && client.getOptions()) || {};
2804
+
2805
+ if (maxBreadcrumbs <= 0) return;
2806
+
2807
+ const timestamp = dateTimestampInSeconds();
2808
+ const mergedBreadcrumb = { timestamp, ...breadcrumb };
2809
+ const finalBreadcrumb = beforeBreadcrumb
2810
+ ? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )
2811
+ : mergedBreadcrumb;
2812
+
2813
+ if (finalBreadcrumb === null) return;
2814
+
2815
+ if (client.emit) {
2816
+ client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
2817
+ }
2818
+
2819
+ // TODO(v8): I know this comment doesn't make much sense because the hub will be deprecated but I still wanted to
2820
+ // write it down. In theory, we would have to add the breadcrumbs to the isolation scope here, however, that would
2821
+ // duplicate all of the breadcrumbs. There was the possibility of adding breadcrumbs to both, the isolation scope
2822
+ // and the normal scope, and deduplicating it down the line in the event processing pipeline. However, that would
2823
+ // have been very fragile, because the breadcrumb objects would have needed to keep their identity all throughout
2824
+ // the event processing pipeline.
2825
+ // In the new implementation, the top level `Sentry.addBreadcrumb()` should ONLY write to the isolation scope.
2826
+
2827
+ scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
2828
+ }
2829
+
2830
+ /**
2831
+ * @inheritDoc
2832
+ * @deprecated Use `Sentry.setUser()` instead.
2833
+ */
2834
+ setUser(user) {
2835
+ // TODO(v8): The top level `Sentry.setUser()` function should write ONLY to the isolation scope.
2836
+ // eslint-disable-next-line deprecation/deprecation
2837
+ this.getScope().setUser(user);
2838
+ // eslint-disable-next-line deprecation/deprecation
2839
+ this.getIsolationScope().setUser(user);
2840
+ }
2841
+
2842
+ /**
2843
+ * @inheritDoc
2844
+ * @deprecated Use `Sentry.setTags()` instead.
2845
+ */
2846
+ setTags(tags) {
2847
+ // TODO(v8): The top level `Sentry.setTags()` function should write ONLY to the isolation scope.
2848
+ // eslint-disable-next-line deprecation/deprecation
2849
+ this.getScope().setTags(tags);
2850
+ // eslint-disable-next-line deprecation/deprecation
2851
+ this.getIsolationScope().setTags(tags);
2852
+ }
2853
+
2854
+ /**
2855
+ * @inheritDoc
2856
+ * @deprecated Use `Sentry.setExtras()` instead.
2857
+ */
2858
+ setExtras(extras) {
2859
+ // TODO(v8): The top level `Sentry.setExtras()` function should write ONLY to the isolation scope.
2860
+ // eslint-disable-next-line deprecation/deprecation
2861
+ this.getScope().setExtras(extras);
2862
+ // eslint-disable-next-line deprecation/deprecation
2863
+ this.getIsolationScope().setExtras(extras);
2864
+ }
2865
+
2866
+ /**
2867
+ * @inheritDoc
2868
+ * @deprecated Use `Sentry.setTag()` instead.
2869
+ */
2870
+ setTag(key, value) {
2871
+ // TODO(v8): The top level `Sentry.setTag()` function should write ONLY to the isolation scope.
2872
+ // eslint-disable-next-line deprecation/deprecation
2873
+ this.getScope().setTag(key, value);
2874
+ // eslint-disable-next-line deprecation/deprecation
2875
+ this.getIsolationScope().setTag(key, value);
2876
+ }
2877
+
2878
+ /**
2879
+ * @inheritDoc
2880
+ * @deprecated Use `Sentry.setExtra()` instead.
2881
+ */
2882
+ setExtra(key, extra) {
2883
+ // TODO(v8): The top level `Sentry.setExtra()` function should write ONLY to the isolation scope.
2884
+ // eslint-disable-next-line deprecation/deprecation
2885
+ this.getScope().setExtra(key, extra);
2886
+ // eslint-disable-next-line deprecation/deprecation
2887
+ this.getIsolationScope().setExtra(key, extra);
2888
+ }
2889
+
2890
+ /**
2891
+ * @inheritDoc
2892
+ * @deprecated Use `Sentry.setContext()` instead.
2893
+ */
2894
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2895
+ setContext(name, context) {
2896
+ // TODO(v8): The top level `Sentry.setContext()` function should write ONLY to the isolation scope.
2897
+ // eslint-disable-next-line deprecation/deprecation
2898
+ this.getScope().setContext(name, context);
2899
+ // eslint-disable-next-line deprecation/deprecation
2900
+ this.getIsolationScope().setContext(name, context);
2901
+ }
2902
+
2903
+ /**
2904
+ * @inheritDoc
2905
+ *
2906
+ * @deprecated Use `getScope()` directly.
2907
+ */
2908
+ configureScope(callback) {
2909
+ // eslint-disable-next-line deprecation/deprecation
2910
+ const { scope, client } = this.getStackTop();
2911
+ if (client) {
2912
+ callback(scope);
2913
+ }
2914
+ }
2915
+
2916
+ /**
2917
+ * @inheritDoc
2918
+ */
2919
+ // eslint-disable-next-line deprecation/deprecation
2920
+ run(callback) {
2921
+ // eslint-disable-next-line deprecation/deprecation
2922
+ const oldHub = makeMain(this);
2923
+ try {
2924
+ callback(this);
2925
+ } finally {
2926
+ // eslint-disable-next-line deprecation/deprecation
2927
+ makeMain(oldHub);
2928
+ }
2929
+ }
2930
+
2931
+ /**
2932
+ * @inheritDoc
2933
+ * @deprecated Use `Sentry.getClient().getIntegrationByName()` instead.
2934
+ */
2935
+ getIntegration(integration) {
2936
+ // eslint-disable-next-line deprecation/deprecation
2937
+ const client = this.getClient();
2938
+ if (!client) return null;
2939
+ try {
2940
+ // eslint-disable-next-line deprecation/deprecation
2941
+ return client.getIntegration(integration);
2942
+ } catch (_oO) {
2943
+ DEBUG_BUILD$1 && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
2944
+ return null;
2945
+ }
2946
+ }
2947
+
2948
+ /**
2949
+ * Starts a new `Transaction` and returns it. This is the entry point to manual tracing instrumentation.
2950
+ *
2951
+ * A tree structure can be built by adding child spans to the transaction, and child spans to other spans. To start a
2952
+ * new child span within the transaction or any span, call the respective `.startChild()` method.
2953
+ *
2954
+ * Every child span must be finished before the transaction is finished, otherwise the unfinished spans are discarded.
2955
+ *
2956
+ * The transaction must be finished with a call to its `.end()` method, at which point the transaction with all its
2957
+ * finished child spans will be sent to Sentry.
2958
+ *
2959
+ * @param context Properties of the new `Transaction`.
2960
+ * @param customSamplingContext Information given to the transaction sampling function (along with context-dependent
2961
+ * default values). See {@link Options.tracesSampler}.
2962
+ *
2963
+ * @returns The transaction which was just started
2964
+ *
2965
+ * @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
2966
+ */
2967
+ startTransaction(context, customSamplingContext) {
2968
+ const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
2969
+
2970
+ if (DEBUG_BUILD$1 && !result) {
2971
+ // eslint-disable-next-line deprecation/deprecation
2972
+ const client = this.getClient();
2973
+ if (!client) {
2974
+ logger.warn(
2975
+ "Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'",
2976
+ );
2977
+ } else {
2978
+ logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
2979
+ Sentry.addTracingExtensions();
2980
+ Sentry.init({...});
2981
+ `);
2982
+ }
2983
+ }
2984
+
2985
+ return result;
2986
+ }
2987
+
2988
+ /**
2989
+ * @inheritDoc
2990
+ * @deprecated Use `spanToTraceHeader()` instead.
2991
+ */
2992
+ traceHeaders() {
2993
+ return this._callExtensionMethod('traceHeaders');
2994
+ }
2995
+
2996
+ /**
2997
+ * @inheritDoc
2998
+ *
2999
+ * @deprecated Use top level `captureSession` instead.
3000
+ */
3001
+ captureSession(endSession = false) {
3002
+ // both send the update and pull the session from the scope
3003
+ if (endSession) {
3004
+ // eslint-disable-next-line deprecation/deprecation
3005
+ return this.endSession();
3006
+ }
3007
+
3008
+ // only send the update
3009
+ this._sendSessionUpdate();
3010
+ }
3011
+
3012
+ /**
3013
+ * @inheritDoc
3014
+ * @deprecated Use top level `endSession` instead.
3015
+ */
3016
+ endSession() {
3017
+ // eslint-disable-next-line deprecation/deprecation
3018
+ const layer = this.getStackTop();
3019
+ const scope = layer.scope;
3020
+ const session = scope.getSession();
3021
+ if (session) {
3022
+ closeSession(session);
3023
+ }
3024
+ this._sendSessionUpdate();
3025
+
3026
+ // the session is over; take it off of the scope
3027
+ scope.setSession();
3028
+ }
3029
+
3030
+ /**
3031
+ * @inheritDoc
3032
+ * @deprecated Use top level `startSession` instead.
3033
+ */
3034
+ startSession(context) {
3035
+ // eslint-disable-next-line deprecation/deprecation
3036
+ const { scope, client } = this.getStackTop();
3037
+ const { release, environment = DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};
3038
+
3039
+ // Will fetch userAgent if called from browser sdk
3040
+ const { userAgent } = GLOBAL_OBJ.navigator || {};
3041
+
3042
+ const session = makeSession({
3043
+ release,
3044
+ environment,
3045
+ user: scope.getUser(),
3046
+ ...(userAgent && { userAgent }),
3047
+ ...context,
3048
+ });
3049
+
3050
+ // End existing session if there's one
3051
+ const currentSession = scope.getSession && scope.getSession();
3052
+ if (currentSession && currentSession.status === 'ok') {
3053
+ updateSession(currentSession, { status: 'exited' });
3054
+ }
3055
+ // eslint-disable-next-line deprecation/deprecation
3056
+ this.endSession();
3057
+
3058
+ // Afterwards we set the new session on the scope
3059
+ scope.setSession(session);
3060
+
3061
+ return session;
3062
+ }
3063
+
3064
+ /**
3065
+ * Returns if default PII should be sent to Sentry and propagated in ourgoing requests
3066
+ * when Tracing is used.
3067
+ *
3068
+ * @deprecated Use top-level `getClient().getOptions().sendDefaultPii` instead. This function
3069
+ * only unnecessarily increased API surface but only wrapped accessing the option.
3070
+ */
3071
+ shouldSendDefaultPii() {
3072
+ // eslint-disable-next-line deprecation/deprecation
3073
+ const client = this.getClient();
3074
+ const options = client && client.getOptions();
3075
+ return Boolean(options && options.sendDefaultPii);
3076
+ }
3077
+
3078
+ /**
3079
+ * Sends the current Session on the scope
3080
+ */
3081
+ _sendSessionUpdate() {
3082
+ // eslint-disable-next-line deprecation/deprecation
3083
+ const { scope, client } = this.getStackTop();
3084
+
3085
+ const session = scope.getSession();
3086
+ if (session && client && client.captureSession) {
3087
+ client.captureSession(session);
3088
+ }
3089
+ }
3090
+
3091
+ /**
3092
+ * Calls global extension method and binding current instance to the function call
3093
+ */
3094
+ // @ts-expect-error Function lacks ending return statement and return type does not include 'undefined'. ts(2366)
3095
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3096
+ _callExtensionMethod(method, ...args) {
3097
+ const carrier = getMainCarrier();
3098
+ const sentry = carrier.__SENTRY__;
3099
+ if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') {
3100
+ return sentry.extensions[method].apply(this, args);
3101
+ }
3102
+ DEBUG_BUILD$1 && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
3103
+ }
3104
+ }
3105
+
3106
+ /**
3107
+ * Returns the global shim registry.
3108
+ *
3109
+ * FIXME: This function is problematic, because despite always returning a valid Carrier,
3110
+ * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
3111
+ * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
3112
+ **/
3113
+ function getMainCarrier() {
3114
+ GLOBAL_OBJ.__SENTRY__ = GLOBAL_OBJ.__SENTRY__ || {
3115
+ extensions: {},
3116
+ hub: undefined,
3117
+ };
3118
+ return GLOBAL_OBJ;
3119
+ }
3120
+
3121
+ /**
3122
+ * Replaces the current main hub with the passed one on the global object
3123
+ *
3124
+ * @returns The old replaced hub
3125
+ *
3126
+ * @deprecated Use `setCurrentClient()` instead.
3127
+ */
3128
+ // eslint-disable-next-line deprecation/deprecation
3129
+ function makeMain(hub) {
3130
+ const registry = getMainCarrier();
3131
+ const oldHub = getHubFromCarrier(registry);
3132
+ setHubOnCarrier(registry, hub);
3133
+ return oldHub;
3134
+ }
3135
+
3136
+ /**
3137
+ * Returns the default hub instance.
3138
+ *
3139
+ * If a hub is already registered in the global carrier but this module
3140
+ * contains a more recent version, it replaces the registered version.
3141
+ * Otherwise, the currently registered hub will be returned.
3142
+ *
3143
+ * @deprecated Use the respective replacement method directly instead.
3144
+ */
3145
+ // eslint-disable-next-line deprecation/deprecation
3146
+ function getCurrentHub() {
3147
+ // Get main carrier (global for every environment)
3148
+ const registry = getMainCarrier();
3149
+
3150
+ if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
3151
+ const hub = registry.__SENTRY__.acs.getCurrentHub();
3152
+
3153
+ if (hub) {
3154
+ return hub;
3155
+ }
3156
+ }
3157
+
3158
+ // Return hub that lives on a global object
3159
+ return getGlobalHub(registry);
3160
+ }
3161
+
3162
+ // eslint-disable-next-line deprecation/deprecation
3163
+ function getGlobalHub(registry = getMainCarrier()) {
3164
+ // If there's no hub, or its an old API, assign a new one
3165
+
3166
+ if (
3167
+ !hasHubOnCarrier(registry) ||
3168
+ // eslint-disable-next-line deprecation/deprecation
3169
+ getHubFromCarrier(registry).isOlderThan(API_VERSION)
3170
+ ) {
3171
+ // eslint-disable-next-line deprecation/deprecation
3172
+ setHubOnCarrier(registry, new Hub());
3173
+ }
3174
+
3175
+ // Return hub that lives on a global object
3176
+ return getHubFromCarrier(registry);
3177
+ }
3178
+
3179
+ /**
3180
+ * This will tell whether a carrier has a hub on it or not
3181
+ * @param carrier object
3182
+ */
3183
+ function hasHubOnCarrier(carrier) {
3184
+ return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub);
3185
+ }
3186
+
3187
+ /**
3188
+ * This will create a new {@link Hub} and add to the passed object on
3189
+ * __SENTRY__.hub.
3190
+ * @param carrier object
3191
+ * @hidden
3192
+ */
3193
+ // eslint-disable-next-line deprecation/deprecation
3194
+ function getHubFromCarrier(carrier) {
3195
+ // eslint-disable-next-line deprecation/deprecation
3196
+ return getGlobalSingleton('hub', () => new Hub(), carrier);
3197
+ }
3198
+
3199
+ /**
3200
+ * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute
3201
+ * @param carrier object
3202
+ * @param hub Hub
3203
+ * @returns A boolean indicating success or failure
3204
+ */
3205
+ // eslint-disable-next-line deprecation/deprecation
3206
+ function setHubOnCarrier(carrier, hub) {
3207
+ if (!carrier) return false;
3208
+ const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
3209
+ __SENTRY__.hub = hub;
3210
+ return true;
3211
+ }
3212
+
3213
+ /**
3214
+ * Convert a new integration function to the legacy class syntax.
3215
+ * In v8, we can remove this and instead export the integration functions directly.
3216
+ *
3217
+ * @deprecated This will be removed in v8!
3218
+ */
3219
+ function convertIntegrationFnToClass(
3220
+ name,
3221
+ fn,
3222
+ ) {
3223
+ return Object.assign(
3224
+ function ConvertedIntegration(...args) {
3225
+ return fn(...args);
3226
+ },
3227
+ { id: name },
3228
+ ) ;
3229
+ }
3230
+
3231
+ /**
3232
+ * Define an integration function that can be used to create an integration instance.
3233
+ * Note that this by design hides the implementation details of the integration, as they are considered internal.
3234
+ */
3235
+ function defineIntegration(fn) {
3236
+ return fn;
3237
+ }
3238
+
3239
+ /**
3240
+ * Checks whether given url points to Sentry server
3241
+ * @param url url to verify
3242
+ *
3243
+ * TODO(v8): Remove Hub fallback type
3244
+ */
3245
+ // eslint-disable-next-line deprecation/deprecation
3246
+ function isSentryRequestUrl(url, hubOrClient) {
3247
+ const client =
3248
+ hubOrClient && isHub(hubOrClient)
3249
+ ? // eslint-disable-next-line deprecation/deprecation
3250
+ hubOrClient.getClient()
3251
+ : hubOrClient;
3252
+ const dsn = client && client.getDsn();
3253
+ const tunnel = client && client.getOptions().tunnel;
3254
+
3255
+ return checkDsn(url, dsn) || checkTunnel(url, tunnel);
3256
+ }
3257
+
3258
+ function checkTunnel(url, tunnel) {
3259
+ if (!tunnel) {
3260
+ return false;
3261
+ }
3262
+
3263
+ return removeTrailingSlash(url) === removeTrailingSlash(tunnel);
3264
+ }
3265
+
3266
+ function checkDsn(url, dsn) {
3267
+ return dsn ? url.includes(dsn.host) : false;
3268
+ }
3269
+
3270
+ function removeTrailingSlash(str) {
3271
+ return str[str.length - 1] === '/' ? str.slice(0, -1) : str;
3272
+ }
3273
+
3274
+ // eslint-disable-next-line deprecation/deprecation
3275
+ function isHub(hubOrClient) {
3276
+ // eslint-disable-next-line deprecation/deprecation
3277
+ return (hubOrClient ).getClient !== undefined;
3278
+ }
3279
+
3280
+ const INTEGRATION_NAME$1 = 'CaptureConsole';
3281
+
3282
+ const _captureConsoleIntegration = ((options = {}) => {
3283
+ const levels = options.levels || CONSOLE_LEVELS;
3284
+
3285
+ return {
3286
+ name: INTEGRATION_NAME$1,
3287
+ // TODO v8: Remove this
3288
+ setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
3289
+ setup(client) {
3290
+ if (!('console' in GLOBAL_OBJ)) {
3291
+ return;
3292
+ }
3293
+
3294
+ addConsoleInstrumentationHandler(({ args, level }) => {
3295
+ if (getClient() !== client || !levels.includes(level)) {
3296
+ return;
3297
+ }
3298
+
3299
+ consoleHandler(args, level);
3300
+ });
3301
+ },
3302
+ };
3303
+ }) ;
3304
+
3305
+ const captureConsoleIntegration = defineIntegration(_captureConsoleIntegration);
3306
+
3307
+ /**
3308
+ * Send Console API calls as Sentry Events.
3309
+ * @deprecated Use `captureConsoleIntegration()` instead.
3310
+ */
3311
+ // eslint-disable-next-line deprecation/deprecation
3312
+ convertIntegrationFnToClass(
3313
+ INTEGRATION_NAME$1,
3314
+ captureConsoleIntegration,
3315
+ )
3316
+
3317
+ ;
3318
+
3319
+ function consoleHandler(args, level) {
3320
+ const captureContext = {
3321
+ level: severityLevelFromString(level),
3322
+ extra: {
3323
+ arguments: args,
3324
+ },
3325
+ };
3326
+
3327
+ withScope(scope => {
3328
+ scope.addEventProcessor(event => {
3329
+ event.logger = 'console';
3330
+
3331
+ addExceptionMechanism(event, {
3332
+ handled: false,
3333
+ type: 'console',
3334
+ });
3335
+
3336
+ return event;
3337
+ });
3338
+
3339
+ if (level === 'assert' && args[0] === false) {
3340
+ const message = `Assertion failed: ${safeJoin(args.slice(1), ' ') || 'console.assert'}`;
3341
+ scope.setExtra('arguments', args.slice(1));
3342
+ captureMessage(message, captureContext);
3343
+ return;
3344
+ }
3345
+
3346
+ const error = args.find(arg => arg instanceof Error);
3347
+ if (level === 'error' && error) {
3348
+ captureException(error, captureContext);
3349
+ return;
3350
+ }
3351
+
3352
+ const message = safeJoin(args, ' ');
3353
+ captureMessage(message, captureContext);
3354
+ });
3355
+ }
3356
+
3357
+ /**
3358
+ * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
3359
+ *
3360
+ * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
3361
+ */
3362
+ const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
3363
+
3364
+ const INTEGRATION_NAME = 'HttpClient';
3365
+
3366
+ const _httpClientIntegration = ((options = {}) => {
3367
+ const _options = {
3368
+ failedRequestStatusCodes: [[500, 599]],
3369
+ failedRequestTargets: [/.*/],
3370
+ ...options,
3371
+ };
3372
+
3373
+ return {
3374
+ name: INTEGRATION_NAME,
3375
+ // TODO v8: Remove this
3376
+ setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
3377
+ setup(client) {
3378
+ _wrapFetch(client, _options);
3379
+ _wrapXHR(client, _options);
3380
+ },
3381
+ };
3382
+ }) ;
3383
+
3384
+ const httpClientIntegration = defineIntegration(_httpClientIntegration);
3385
+
3386
+ /**
3387
+ * Create events for failed client side HTTP requests.
3388
+ * @deprecated Use `httpClientIntegration()` instead.
3389
+ */
3390
+ // eslint-disable-next-line deprecation/deprecation
3391
+ convertIntegrationFnToClass(INTEGRATION_NAME, httpClientIntegration)
3392
+
3393
+ ;
3394
+
3395
+ /**
3396
+ * Interceptor function for fetch requests
3397
+ *
3398
+ * @param requestInfo The Fetch API request info
3399
+ * @param response The Fetch API response
3400
+ * @param requestInit The request init object
3401
+ */
3402
+ function _fetchResponseHandler(
3403
+ options,
3404
+ requestInfo,
3405
+ response,
3406
+ requestInit,
3407
+ ) {
3408
+ if (_shouldCaptureResponse(options, response.status, response.url)) {
3409
+ const request = _getRequest(requestInfo, requestInit);
3410
+
3411
+ let requestHeaders, responseHeaders, requestCookies, responseCookies;
3412
+
3413
+ if (_shouldSendDefaultPii()) {
3414
+ [{ headers: requestHeaders, cookies: requestCookies }, { headers: responseHeaders, cookies: responseCookies }] = [
3415
+ { cookieHeader: 'Cookie', obj: request },
3416
+ { cookieHeader: 'Set-Cookie', obj: response },
3417
+ ].map(({ cookieHeader, obj }) => {
3418
+ const headers = _extractFetchHeaders(obj.headers);
3419
+ let cookies;
3420
+
3421
+ try {
3422
+ const cookieString = headers[cookieHeader] || headers[cookieHeader.toLowerCase()] || undefined;
3423
+
3424
+ if (cookieString) {
3425
+ cookies = _parseCookieString(cookieString);
3426
+ }
3427
+ } catch (e) {
3428
+ DEBUG_BUILD && logger.log(`Could not extract cookies from header ${cookieHeader}`);
3429
+ }
3430
+
3431
+ return {
3432
+ headers,
3433
+ cookies,
3434
+ };
3435
+ });
3436
+ }
3437
+
3438
+ const event = _createEvent({
3439
+ url: request.url,
3440
+ method: request.method,
3441
+ status: response.status,
3442
+ requestHeaders,
3443
+ responseHeaders,
3444
+ requestCookies,
3445
+ responseCookies,
3446
+ });
3447
+
3448
+ captureEvent(event);
3449
+ }
3450
+ }
3451
+
3452
+ /**
3453
+ * Interceptor function for XHR requests
3454
+ *
3455
+ * @param xhr The XHR request
3456
+ * @param method The HTTP method
3457
+ * @param headers The HTTP headers
3458
+ */
3459
+ function _xhrResponseHandler(
3460
+ options,
3461
+ xhr,
3462
+ method,
3463
+ headers,
3464
+ ) {
3465
+ if (_shouldCaptureResponse(options, xhr.status, xhr.responseURL)) {
3466
+ let requestHeaders, responseCookies, responseHeaders;
3467
+
3468
+ if (_shouldSendDefaultPii()) {
3469
+ try {
3470
+ const cookieString = xhr.getResponseHeader('Set-Cookie') || xhr.getResponseHeader('set-cookie') || undefined;
3471
+
3472
+ if (cookieString) {
3473
+ responseCookies = _parseCookieString(cookieString);
3474
+ }
3475
+ } catch (e) {
3476
+ DEBUG_BUILD && logger.log('Could not extract cookies from response headers');
3477
+ }
3478
+
3479
+ try {
3480
+ responseHeaders = _getXHRResponseHeaders(xhr);
3481
+ } catch (e) {
3482
+ DEBUG_BUILD && logger.log('Could not extract headers from response');
3483
+ }
3484
+
3485
+ requestHeaders = headers;
3486
+ }
3487
+
3488
+ const event = _createEvent({
3489
+ url: xhr.responseURL,
3490
+ method,
3491
+ status: xhr.status,
3492
+ requestHeaders,
3493
+ // Can't access request cookies from XHR
3494
+ responseHeaders,
3495
+ responseCookies,
3496
+ });
3497
+
3498
+ captureEvent(event);
3499
+ }
3500
+ }
3501
+
3502
+ /**
3503
+ * Extracts response size from `Content-Length` header when possible
3504
+ *
3505
+ * @param headers
3506
+ * @returns The response size in bytes or undefined
3507
+ */
3508
+ function _getResponseSizeFromHeaders(headers) {
3509
+ if (headers) {
3510
+ const contentLength = headers['Content-Length'] || headers['content-length'];
3511
+
3512
+ if (contentLength) {
3513
+ return parseInt(contentLength, 10);
3514
+ }
3515
+ }
3516
+
3517
+ return undefined;
3518
+ }
3519
+
3520
+ /**
3521
+ * Creates an object containing cookies from the given cookie string
3522
+ *
3523
+ * @param cookieString The cookie string to parse
3524
+ * @returns The parsed cookies
3525
+ */
3526
+ function _parseCookieString(cookieString) {
3527
+ return cookieString.split('; ').reduce((acc, cookie) => {
3528
+ const [key, value] = cookie.split('=');
3529
+ acc[key] = value;
3530
+ return acc;
3531
+ }, {});
3532
+ }
3533
+
3534
+ /**
3535
+ * Extracts the headers as an object from the given Fetch API request or response object
3536
+ *
3537
+ * @param headers The headers to extract
3538
+ * @returns The extracted headers as an object
3539
+ */
3540
+ function _extractFetchHeaders(headers) {
3541
+ const result = {};
3542
+
3543
+ headers.forEach((value, key) => {
3544
+ result[key] = value;
3545
+ });
3546
+
3547
+ return result;
3548
+ }
3549
+
3550
+ /**
3551
+ * Extracts the response headers as an object from the given XHR object
3552
+ *
3553
+ * @param xhr The XHR object to extract the response headers from
3554
+ * @returns The response headers as an object
3555
+ */
3556
+ function _getXHRResponseHeaders(xhr) {
3557
+ const headers = xhr.getAllResponseHeaders();
3558
+
3559
+ if (!headers) {
3560
+ return {};
3561
+ }
3562
+
3563
+ return headers.split('\r\n').reduce((acc, line) => {
3564
+ const [key, value] = line.split(': ');
3565
+ acc[key] = value;
3566
+ return acc;
3567
+ }, {});
3568
+ }
3569
+
3570
+ /**
3571
+ * Checks if the given target url is in the given list of targets
3572
+ *
3573
+ * @param target The target url to check
3574
+ * @returns true if the target url is in the given list of targets, false otherwise
3575
+ */
3576
+ function _isInGivenRequestTargets(
3577
+ failedRequestTargets,
3578
+ target,
3579
+ ) {
3580
+ return failedRequestTargets.some((givenRequestTarget) => {
3581
+ if (typeof givenRequestTarget === 'string') {
3582
+ return target.includes(givenRequestTarget);
3583
+ }
3584
+
3585
+ return givenRequestTarget.test(target);
3586
+ });
3587
+ }
3588
+
3589
+ /**
3590
+ * Checks if the given status code is in the given range
3591
+ *
3592
+ * @param status The status code to check
3593
+ * @returns true if the status code is in the given range, false otherwise
3594
+ */
3595
+ function _isInGivenStatusRanges(
3596
+ failedRequestStatusCodes,
3597
+ status,
3598
+ ) {
3599
+ return failedRequestStatusCodes.some((range) => {
3600
+ if (typeof range === 'number') {
3601
+ return range === status;
3602
+ }
3603
+
3604
+ return status >= range[0] && status <= range[1];
3605
+ });
3606
+ }
3607
+
3608
+ /**
3609
+ * Wraps `fetch` function to capture request and response data
3610
+ */
3611
+ function _wrapFetch(client, options) {
3612
+ if (!supportsNativeFetch()) {
3613
+ return;
3614
+ }
3615
+
3616
+ addFetchInstrumentationHandler(handlerData => {
3617
+ if (getClient() !== client) {
3618
+ return;
3619
+ }
3620
+
3621
+ const { response, args } = handlerData;
3622
+ const [requestInfo, requestInit] = args ;
3623
+
3624
+ if (!response) {
3625
+ return;
3626
+ }
3627
+
3628
+ _fetchResponseHandler(options, requestInfo, response , requestInit);
3629
+ });
3630
+ }
3631
+
3632
+ /**
3633
+ * Wraps XMLHttpRequest to capture request and response data
3634
+ */
3635
+ function _wrapXHR(client, options) {
3636
+ if (!('XMLHttpRequest' in GLOBAL_OBJ)) {
3637
+ return;
3638
+ }
3639
+
3640
+ addXhrInstrumentationHandler(handlerData => {
3641
+ if (getClient() !== client) {
3642
+ return;
3643
+ }
3644
+
3645
+ const xhr = handlerData.xhr ;
3646
+
3647
+ const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];
3648
+
3649
+ if (!sentryXhrData) {
3650
+ return;
3651
+ }
3652
+
3653
+ const { method, request_headers: headers } = sentryXhrData;
3654
+
3655
+ try {
3656
+ _xhrResponseHandler(options, xhr, method, headers);
3657
+ } catch (e) {
3658
+ DEBUG_BUILD && logger.warn('Error while extracting response event form XHR response', e);
3659
+ }
3660
+ });
3661
+ }
3662
+
3663
+ /**
3664
+ * Checks whether to capture given response as an event
3665
+ *
3666
+ * @param status response status code
3667
+ * @param url response url
3668
+ */
3669
+ function _shouldCaptureResponse(options, status, url) {
3670
+ return (
3671
+ _isInGivenStatusRanges(options.failedRequestStatusCodes, status) &&
3672
+ _isInGivenRequestTargets(options.failedRequestTargets, url) &&
3673
+ !isSentryRequestUrl(url, getClient())
3674
+ );
3675
+ }
3676
+
3677
+ /**
3678
+ * Creates a synthetic Sentry event from given response data
3679
+ *
3680
+ * @param data response data
3681
+ * @returns event
3682
+ */
3683
+ function _createEvent(data
3684
+
3685
+ ) {
3686
+ const message = `HTTP Client Error with status code: ${data.status}`;
3687
+
3688
+ const event = {
3689
+ message,
3690
+ exception: {
3691
+ values: [
3692
+ {
3693
+ type: 'Error',
3694
+ value: message,
3695
+ },
3696
+ ],
3697
+ },
3698
+ request: {
3699
+ url: data.url,
3700
+ method: data.method,
3701
+ headers: data.requestHeaders,
3702
+ cookies: data.requestCookies,
3703
+ },
3704
+ contexts: {
3705
+ response: {
3706
+ status_code: data.status,
3707
+ headers: data.responseHeaders,
3708
+ cookies: data.responseCookies,
3709
+ body_size: _getResponseSizeFromHeaders(data.responseHeaders),
3710
+ },
3711
+ },
3712
+ };
3713
+
3714
+ addExceptionMechanism(event, {
3715
+ type: 'http.client',
3716
+ handled: false,
3717
+ });
3718
+
3719
+ return event;
3720
+ }
3721
+
3722
+ function _getRequest(requestInfo, requestInit) {
3723
+ if (!requestInit && requestInfo instanceof Request) {
3724
+ return requestInfo;
3725
+ }
3726
+
3727
+ // If both are set, we try to construct a new Request with the given arguments
3728
+ // However, if e.g. the original request has a `body`, this will throw an error because it was already accessed
3729
+ // In this case, as a fallback, we just use the original request - using both is rather an edge case
3730
+ if (requestInfo instanceof Request && requestInfo.bodyUsed) {
3731
+ return requestInfo;
3732
+ }
3733
+
3734
+ return new Request(requestInfo, requestInit);
3735
+ }
3736
+
3737
+ function _shouldSendDefaultPii() {
3738
+ const client = getClient();
3739
+ return client ? Boolean(client.getOptions().sendDefaultPii) : false;
3740
+ }
3741
+
3742
+ /**
3743
+ * Initialize Sentry for React Native.
3744
+ *
3745
+ * @param {InitOptionsRN} options
3746
+ * @return {void}
3747
+ */
3748
+ const initSentry = options => {
3749
+ let shouldSendToSentry = options?.requiredEnvForSendToSentry?.includes(options.env);
3750
+ let ignoreErrors = [/StallTracking/];
3751
+ if (options?.ignoreErrorsOptions) {
3752
+ ignoreErrors = ignoreErrors.concat(options.ignoreErrorsOptions);
3753
+ }
3754
+ if (options?.options?.ignoreErrors) {
3755
+ ignoreErrors = ignoreErrors.concat(options.options.ignoreErrors);
3756
+ delete options.options.ignoreErrors;
3757
+ }
3758
+ let integrations = [];
3759
+ if (options?.httpClientIntegrationOptions?.failedRequestStatusCodes && options?.httpClientIntegrationOptions?.failedRequestTargets) {
3760
+ integrations.push(httpClientIntegration({
3761
+ failedRequestStatusCodes: options.httpClientIntegrationOptions.failedRequestStatusCodes,
3762
+ failedRequestTargets: options.httpClientIntegrationOptions.failedRequestTargets
3763
+ }));
3764
+ }
3765
+ if (options?.captureConsoleIntegrationOptions?.levels) {
3766
+ integrations.push(captureConsoleIntegration({
3767
+ levels: options.captureConsoleIntegrationOptions.levels
3768
+ }));
3769
+ }
3770
+ if (options?.options?.hasOwnProperty('integrations')) {
3771
+ options.options.integrations = [...options.options.integrations, ...integrations];
3772
+ } else {
3773
+ options.options = options.options || {};
3774
+ options.options.integrations = integrations;
3775
+ }
3776
+ let sentryOptions = {
3777
+ dsn: options.dsn,
3778
+ debug: options.debug,
3779
+ environment: options.env,
3780
+ ignoreErrors: ignoreErrors,
3781
+ sampleRate: 1.0,
3782
+ maxBreadcrumbs: 50,
3783
+ autoSessionTracking: true,
3784
+ attachScreenshot: true,
3785
+ enableCaptureFailedRequests: true,
3786
+ enableTracing: true,
3787
+ tracesSampleRate: 1.0,
3788
+ enableNative: true,
3789
+ autoInitializeNativeSdk: true,
3790
+ enableNativeCrashHandling: true,
3791
+ enableNativeNagger: true,
3792
+ enableAutoSessionTracking: true,
3793
+ enableNdkScopeSync: true,
3794
+ attachThreads: true,
3795
+ enableAutoPerformanceTracing: true,
3796
+ enableWatchdogTerminationTracking: true,
3797
+ enableAppHangTracking: true,
3798
+ appHangTimeoutInterval: 5,
3799
+ sendDefaultPii: true,
3800
+ beforeSend: event => {
3801
+ if (event?.message?.includes('StallTracking') || !shouldSendToSentry) {
3802
+ return null;
3803
+ }
3804
+ return event;
3805
+ }
3806
+ };
3807
+ if (options?.release) {
3808
+ sentryOptions.release = options.release;
3809
+ }
3810
+ if (options?.beforeSend) {
3811
+ sentryOptions.beforeSend = options.beforeSend;
3812
+ }
3813
+ if (options?.options) {
3814
+ sentryOptions = {
3815
+ ...sentryOptions,
3816
+ ...options.options
3817
+ };
3818
+ }
3819
+ Sentry.init(sentryOptions);
3820
+ };
3821
+ /**
3822
+ * Record additional http data for Sentry.
3823
+ *
3824
+ * @param {any | null} config
3825
+ * @param {any | null} request
3826
+ * @param {any | null} response
3827
+ * @return {void}
3828
+ */
3829
+ const recordAdditionalSentryHttp = (config, request, response) => {
3830
+ recordSentryHttp(Sentry, config, request, response);
3831
+ };
3832
+
3833
+ export { initSentry as i, recordAdditionalSentryHttp as r };
3834
+ //# sourceMappingURL=ReactNative-mNnws-b5.js.map