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