@sentry/browser 6.6.0 → 6.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/build/bundle.es6.js +280 -80
  2. package/build/bundle.es6.js.map +1 -1
  3. package/build/bundle.es6.min.js +2 -2
  4. package/build/bundle.es6.min.js.map +1 -1
  5. package/build/bundle.js +318 -113
  6. package/build/bundle.js.map +1 -1
  7. package/build/bundle.min.js +2 -2
  8. package/build/bundle.min.js.map +1 -1
  9. package/dist/backend.d.ts.map +1 -1
  10. package/dist/backend.js +1 -1
  11. package/dist/backend.js.map +1 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/integrations/breadcrumbs.d.ts +1 -1
  15. package/dist/integrations/breadcrumbs.d.ts.map +1 -1
  16. package/dist/integrations/breadcrumbs.js +6 -3
  17. package/dist/integrations/breadcrumbs.js.map +1 -1
  18. package/dist/integrations/dedupe.d.ts +35 -0
  19. package/dist/integrations/dedupe.d.ts.map +1 -0
  20. package/dist/integrations/dedupe.js +166 -0
  21. package/dist/integrations/dedupe.js.map +1 -0
  22. package/dist/integrations/globalhandlers.d.ts.map +1 -1
  23. package/dist/integrations/globalhandlers.js +6 -8
  24. package/dist/integrations/globalhandlers.js.map +1 -1
  25. package/dist/integrations/index.d.ts +1 -0
  26. package/dist/integrations/index.d.ts.map +1 -1
  27. package/dist/integrations/index.js +2 -0
  28. package/dist/integrations/index.js.map +1 -1
  29. package/dist/sdk.d.ts +2 -2
  30. package/dist/sdk.d.ts.map +1 -1
  31. package/dist/sdk.js +1 -0
  32. package/dist/sdk.js.map +1 -1
  33. package/dist/transports/base.d.ts.map +1 -1
  34. package/dist/transports/base.js +2 -2
  35. package/dist/transports/base.js.map +1 -1
  36. package/dist/transports/fetch.d.ts.map +1 -1
  37. package/dist/transports/fetch.js +20 -18
  38. package/dist/transports/fetch.js.map +1 -1
  39. package/dist/transports/xhr.d.ts.map +1 -1
  40. package/dist/transports/xhr.js +21 -19
  41. package/dist/transports/xhr.js.map +1 -1
  42. package/esm/backend.d.ts.map +1 -1
  43. package/esm/backend.js +1 -1
  44. package/esm/backend.js.map +1 -1
  45. package/esm/index.d.ts +1 -0
  46. package/esm/index.d.ts.map +1 -1
  47. package/esm/integrations/breadcrumbs.d.ts +1 -1
  48. package/esm/integrations/breadcrumbs.d.ts.map +1 -1
  49. package/esm/integrations/breadcrumbs.js +6 -3
  50. package/esm/integrations/breadcrumbs.js.map +1 -1
  51. package/esm/integrations/dedupe.d.ts +35 -0
  52. package/esm/integrations/dedupe.d.ts.map +1 -0
  53. package/esm/integrations/dedupe.js +165 -0
  54. package/esm/integrations/dedupe.js.map +1 -0
  55. package/esm/integrations/globalhandlers.d.ts.map +1 -1
  56. package/esm/integrations/globalhandlers.js +6 -8
  57. package/esm/integrations/globalhandlers.js.map +1 -1
  58. package/esm/integrations/index.d.ts +1 -0
  59. package/esm/integrations/index.d.ts.map +1 -1
  60. package/esm/integrations/index.js +1 -0
  61. package/esm/integrations/index.js.map +1 -1
  62. package/esm/sdk.d.ts +2 -2
  63. package/esm/sdk.d.ts.map +1 -1
  64. package/esm/sdk.js +2 -1
  65. package/esm/sdk.js.map +1 -1
  66. package/esm/transports/base.d.ts.map +1 -1
  67. package/esm/transports/base.js +2 -2
  68. package/esm/transports/base.js.map +1 -1
  69. package/esm/transports/fetch.d.ts.map +1 -1
  70. package/esm/transports/fetch.js +20 -18
  71. package/esm/transports/fetch.js.map +1 -1
  72. package/esm/transports/xhr.d.ts.map +1 -1
  73. package/esm/transports/xhr.js +21 -19
  74. package/esm/transports/xhr.js.map +1 -1
  75. package/package.json +5 -5
package/build/bundle.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @sentry/browser 6.6.0 (9a13c8b) | https://github.com/getsentry/sentry-javascript */
1
+ /*! @sentry/browser 6.8.0 (e93d96f) | https://github.com/getsentry/sentry-javascript */
2
2
  var Sentry = (function (exports) {
3
3
  /*! *****************************************************************************
4
4
  Copyright (c) Microsoft Corporation. All rights reserved.
@@ -370,7 +370,7 @@ var Sentry = (function (exports) {
370
370
  * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
371
371
  * @returns generated DOM path
372
372
  */
373
- function htmlTreeAsString(elem, keyAttr) {
373
+ function htmlTreeAsString(elem, keyAttrs) {
374
374
  // try/catch both:
375
375
  // - accessing event.target (see getsentry/raven-js#838, #768)
376
376
  // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
@@ -387,7 +387,7 @@ var Sentry = (function (exports) {
387
387
  var nextStr = void 0;
388
388
  // eslint-disable-next-line no-plusplus
389
389
  while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {
390
- nextStr = _htmlElementAsString(currentElem, keyAttr);
390
+ nextStr = _htmlElementAsString(currentElem, keyAttrs);
391
391
  // bail out if
392
392
  // - nextStr is the 'html' element
393
393
  // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
@@ -410,7 +410,8 @@ var Sentry = (function (exports) {
410
410
  * e.g. [HTMLElement] => input#foo.btn[name=baz]
411
411
  * @returns generated DOM path
412
412
  */
413
- function _htmlElementAsString(el, keyAttr) {
413
+ function _htmlElementAsString(el, keyAttrs) {
414
+ var _a, _b;
414
415
  var elem = el;
415
416
  var out = [];
416
417
  var className;
@@ -422,9 +423,13 @@ var Sentry = (function (exports) {
422
423
  return '';
423
424
  }
424
425
  out.push(elem.tagName.toLowerCase());
425
- var keyAttrValue = keyAttr ? elem.getAttribute(keyAttr) : null;
426
- if (keyAttrValue) {
427
- out.push("[" + keyAttr + "=\"" + keyAttrValue + "\"]");
426
+ // Pairs of attribute keys defined in `serializeAttribute` and their values on element.
427
+ var keyAttrPairs = ((_a = keyAttrs) === null || _a === void 0 ? void 0 : _a.length) ? keyAttrs.filter(function (keyAttr) { return elem.getAttribute(keyAttr); }).map(function (keyAttr) { return [keyAttr, elem.getAttribute(keyAttr)]; })
428
+ : null;
429
+ if ((_b = keyAttrPairs) === null || _b === void 0 ? void 0 : _b.length) {
430
+ keyAttrPairs.forEach(function (keyAttrPair) {
431
+ out.push("[" + keyAttrPair[0] + "=\"" + keyAttrPair[1] + "\"]");
432
+ });
428
433
  }
429
434
  else {
430
435
  if (elem.id) {
@@ -2156,14 +2161,16 @@ var Sentry = (function (exports) {
2156
2161
  /**
2157
2162
  * Add a promise to the queue.
2158
2163
  *
2159
- * @param task Can be any PromiseLike<T>
2164
+ * @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task: PromiseLike<T>`,
2165
+ * however, Promises were instantly created on the call-site, making them fall through the buffer limit.
2160
2166
  * @returns The original promise.
2161
2167
  */
2162
- PromiseBuffer.prototype.add = function (task) {
2168
+ PromiseBuffer.prototype.add = function (taskProducer) {
2163
2169
  var _this = this;
2164
2170
  if (!this.isReady()) {
2165
2171
  return SyncPromise.reject(new SentryError('Not adding Promise due to buffer limit reached.'));
2166
2172
  }
2173
+ var task = taskProducer();
2167
2174
  if (this._buffer.indexOf(task) === -1) {
2168
2175
  this._buffer.push(task);
2169
2176
  }
@@ -2349,6 +2356,11 @@ var Sentry = (function (exports) {
2349
2356
  return dateNow;
2350
2357
  })();
2351
2358
 
2359
+ /**
2360
+ * Absolute maximum number of breadcrumbs added to an event.
2361
+ * The `maxBreadcrumbs` option cannot be higher than this value.
2362
+ */
2363
+ var MAX_BREADCRUMBS = 100;
2352
2364
  /**
2353
2365
  * Holds additional event information. {@link Scope.applyToEvent} will be
2354
2366
  * called by the client before an event will be sent.
@@ -2640,11 +2652,13 @@ var Sentry = (function (exports) {
2640
2652
  * @inheritDoc
2641
2653
  */
2642
2654
  Scope.prototype.addBreadcrumb = function (breadcrumb, maxBreadcrumbs) {
2655
+ var maxCrumbs = typeof maxBreadcrumbs === 'number' ? Math.min(maxBreadcrumbs, MAX_BREADCRUMBS) : MAX_BREADCRUMBS;
2656
+ // No data has been changed, so don't notify scope listeners
2657
+ if (maxCrumbs <= 0) {
2658
+ return this;
2659
+ }
2643
2660
  var mergedBreadcrumb = __assign({ timestamp: dateTimestampInSeconds() }, breadcrumb);
2644
- this._breadcrumbs =
2645
- maxBreadcrumbs !== undefined && maxBreadcrumbs >= 0
2646
- ? __spread(this._breadcrumbs, [mergedBreadcrumb]).slice(-maxBreadcrumbs)
2647
- : __spread(this._breadcrumbs, [mergedBreadcrumb]);
2661
+ this._breadcrumbs = __spread(this._breadcrumbs, [mergedBreadcrumb]).slice(-maxCrumbs);
2648
2662
  this._notifyScopeListeners();
2649
2663
  return this;
2650
2664
  };
@@ -2806,10 +2820,10 @@ var Sentry = (function (exports) {
2806
2820
  Session.prototype.update = function (context) {
2807
2821
  if (context === void 0) { context = {}; }
2808
2822
  if (context.user) {
2809
- if (context.user.ip_address) {
2823
+ if (!this.ipAddress && context.user.ip_address) {
2810
2824
  this.ipAddress = context.user.ip_address;
2811
2825
  }
2812
- if (!context.did) {
2826
+ if (!this.did && !context.did) {
2813
2827
  this.did = context.user.id || context.user.email || context.user.username;
2814
2828
  }
2815
2829
  }
@@ -2824,7 +2838,7 @@ var Sentry = (function (exports) {
2824
2838
  if (context.init !== undefined) {
2825
2839
  this.init = context.init;
2826
2840
  }
2827
- if (context.did) {
2841
+ if (!this.did && context.did) {
2828
2842
  this.did = "" + context.did;
2829
2843
  }
2830
2844
  if (typeof context.started === 'number') {
@@ -2846,10 +2860,10 @@ var Sentry = (function (exports) {
2846
2860
  if (context.environment) {
2847
2861
  this.environment = context.environment;
2848
2862
  }
2849
- if (context.ipAddress) {
2863
+ if (!this.ipAddress && context.ipAddress) {
2850
2864
  this.ipAddress = context.ipAddress;
2851
2865
  }
2852
- if (context.userAgent) {
2866
+ if (!this.userAgent && context.userAgent) {
2853
2867
  this.userAgent = context.userAgent;
2854
2868
  }
2855
2869
  if (typeof context.errors === 'number') {
@@ -2908,11 +2922,6 @@ var Sentry = (function (exports) {
2908
2922
  * with {@link Options.maxBreadcrumbs}.
2909
2923
  */
2910
2924
  var DEFAULT_BREADCRUMBS = 100;
2911
- /**
2912
- * Absolute maximum number of breadcrumbs added to an event. The
2913
- * `maxBreadcrumbs` option cannot be higher than this value.
2914
- */
2915
- var MAX_BREADCRUMBS = 100;
2916
2925
  /**
2917
2926
  * @inheritDoc
2918
2927
  */
@@ -3085,7 +3094,7 @@ var Sentry = (function (exports) {
3085
3094
  : mergedBreadcrumb;
3086
3095
  if (finalBreadcrumb === null)
3087
3096
  return;
3088
- scope.addBreadcrumb(finalBreadcrumb, Math.min(maxBreadcrumbs, MAX_BREADCRUMBS));
3097
+ scope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
3089
3098
  };
3090
3099
  /**
3091
3100
  * @inheritDoc
@@ -3218,8 +3227,11 @@ var Sentry = (function (exports) {
3218
3227
  Hub.prototype.startSession = function (context) {
3219
3228
  var _a = this.getStackTop(), scope = _a.scope, client = _a.client;
3220
3229
  var _b = (client && client.getOptions()) || {}, release = _b.release, environment = _b.environment;
3221
- var session = new Session(__assign(__assign({ release: release,
3222
- environment: environment }, (scope && { user: scope.getUser() })), context));
3230
+ // Will fetch userAgent if called from browser sdk
3231
+ var global = getGlobalObject();
3232
+ var userAgent = (global.navigator || {}).userAgent;
3233
+ var session = new Session(__assign(__assign(__assign({ release: release,
3234
+ environment: environment }, (scope && { user: scope.getUser() })), (userAgent && { userAgent: userAgent })), context));
3223
3235
  if (scope) {
3224
3236
  // End existing session if there's one
3225
3237
  var currentSession = scope.getSession && scope.getSession();
@@ -3572,19 +3584,24 @@ var Sentry = (function (exports) {
3572
3584
  **/
3573
3585
  var API = /** @class */ (function () {
3574
3586
  /** Create a new instance of API */
3575
- function API(dsn, metadata) {
3587
+ function API(dsn, metadata, tunnel) {
3576
3588
  if (metadata === void 0) { metadata = {}; }
3577
3589
  this.dsn = dsn;
3578
3590
  this._dsnObject = new Dsn(dsn);
3579
3591
  this.metadata = metadata;
3592
+ this._tunnel = tunnel;
3580
3593
  }
3581
3594
  /** Returns the Dsn object. */
3582
3595
  API.prototype.getDsn = function () {
3583
3596
  return this._dsnObject;
3584
3597
  };
3598
+ /** Does this transport force envelopes? */
3599
+ API.prototype.forceEnvelope = function () {
3600
+ return !!this._tunnel;
3601
+ };
3585
3602
  /** Returns the prefix to construct Sentry ingestion API endpoints. */
3586
3603
  API.prototype.getBaseApiEndpoint = function () {
3587
- var dsn = this._dsnObject;
3604
+ var dsn = this.getDsn();
3588
3605
  var protocol = dsn.protocol ? dsn.protocol + ":" : '';
3589
3606
  var port = dsn.port ? ":" + dsn.port : '';
3590
3607
  return protocol + "//" + dsn.host + port + (dsn.path ? "/" + dsn.path : '') + "/api/";
@@ -3607,11 +3624,14 @@ var Sentry = (function (exports) {
3607
3624
  * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3608
3625
  */
3609
3626
  API.prototype.getEnvelopeEndpointWithUrlEncodedAuth = function () {
3627
+ if (this.forceEnvelope()) {
3628
+ return this._tunnel;
3629
+ }
3610
3630
  return this._getEnvelopeEndpoint() + "?" + this._encodedAuth();
3611
3631
  };
3612
3632
  /** Returns only the path component for the store endpoint. */
3613
3633
  API.prototype.getStoreEndpointPath = function () {
3614
- var dsn = this._dsnObject;
3634
+ var dsn = this.getDsn();
3615
3635
  return (dsn.path ? "/" + dsn.path : '') + "/api/" + dsn.projectId + "/store/";
3616
3636
  };
3617
3637
  /**
@@ -3620,7 +3640,7 @@ var Sentry = (function (exports) {
3620
3640
  */
3621
3641
  API.prototype.getRequestHeaders = function (clientName, clientVersion) {
3622
3642
  // CHANGE THIS to use metadata but keep clientName and clientVersion compatible
3623
- var dsn = this._dsnObject;
3643
+ var dsn = this.getDsn();
3624
3644
  var header = ["Sentry sentry_version=" + SENTRY_API_VERSION];
3625
3645
  header.push("sentry_client=" + clientName + "/" + clientVersion);
3626
3646
  header.push("sentry_key=" + dsn.publicKey);
@@ -3635,7 +3655,7 @@ var Sentry = (function (exports) {
3635
3655
  /** Returns the url to the report dialog endpoint. */
3636
3656
  API.prototype.getReportDialogEndpoint = function (dialogOptions) {
3637
3657
  if (dialogOptions === void 0) { dialogOptions = {}; }
3638
- var dsn = this._dsnObject;
3658
+ var dsn = this.getDsn();
3639
3659
  var endpoint = this.getBaseApiEndpoint() + "embed/error-page/";
3640
3660
  var encodedOptions = [];
3641
3661
  encodedOptions.push("dsn=" + dsn.toString());
@@ -3669,13 +3689,16 @@ var Sentry = (function (exports) {
3669
3689
  };
3670
3690
  /** Returns the ingest API endpoint for target. */
3671
3691
  API.prototype._getIngestEndpoint = function (target) {
3692
+ if (this._tunnel) {
3693
+ return this._tunnel;
3694
+ }
3672
3695
  var base = this.getBaseApiEndpoint();
3673
- var dsn = this._dsnObject;
3696
+ var dsn = this.getDsn();
3674
3697
  return "" + base + dsn.projectId + "/" + target + "/";
3675
3698
  };
3676
3699
  /** Returns a URL-encoded string with auth config suitable for a query string. */
3677
3700
  API.prototype._encodedAuth = function () {
3678
- var dsn = this._dsnObject;
3701
+ var dsn = this.getDsn();
3679
3702
  var auth = {
3680
3703
  // We send only the minimum set of required information. See
3681
3704
  // https://github.com/getsentry/sentry-javascript/issues/2572.
@@ -3841,6 +3864,10 @@ var Sentry = (function (exports) {
3841
3864
  * @inheritDoc
3842
3865
  */
3843
3866
  BaseClient.prototype.captureSession = function (session) {
3867
+ if (!this._isEnabled()) {
3868
+ logger.warn('SDK not enabled, will not capture session.');
3869
+ return;
3870
+ }
3844
3871
  if (!(typeof session.release === 'string')) {
3845
3872
  logger.warn('Discarded session because of missing or non-string release');
3846
3873
  }
@@ -3909,7 +3936,6 @@ var Sentry = (function (exports) {
3909
3936
  var e_1, _a;
3910
3937
  var crashed = false;
3911
3938
  var errored = false;
3912
- var userAgent;
3913
3939
  var exceptions = event.exception && event.exception.values;
3914
3940
  if (exceptions) {
3915
3941
  errored = true;
@@ -3931,19 +3957,15 @@ var Sentry = (function (exports) {
3931
3957
  finally { if (e_1) throw e_1.error; }
3932
3958
  }
3933
3959
  }
3934
- var user = event.user;
3935
- if (!session.userAgent) {
3936
- var headers = event.request ? event.request.headers : {};
3937
- for (var key in headers) {
3938
- if (key.toLowerCase() === 'user-agent') {
3939
- userAgent = headers[key];
3940
- break;
3941
- }
3942
- }
3960
+ // A session is updated and that session update is sent in only one of the two following scenarios:
3961
+ // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update
3962
+ // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update
3963
+ var sessionNonTerminal = session.status === SessionStatus.Ok;
3964
+ var shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);
3965
+ if (shouldUpdateAndSend) {
3966
+ session.update(__assign(__assign({}, (crashed && { status: SessionStatus.Crashed })), { errors: session.errors || Number(errored || crashed) }));
3967
+ this.captureSession(session);
3943
3968
  }
3944
- session.update(__assign(__assign({}, (crashed && { status: SessionStatus.Crashed })), { user: user,
3945
- userAgent: userAgent, errors: session.errors + Number(errored || crashed) }));
3946
- this.captureSession(session);
3947
3969
  };
3948
3970
  /** Deliver captured session to Sentry */
3949
3971
  BaseClient.prototype._sendSession = function (session) {
@@ -4137,7 +4159,7 @@ var Sentry = (function (exports) {
4137
4159
  // eslint-disable-next-line @typescript-eslint/unbound-method
4138
4160
  var _a = this.getOptions(), beforeSend = _a.beforeSend, sampleRate = _a.sampleRate;
4139
4161
  if (!this._isEnabled()) {
4140
- return SyncPromise.reject(new SentryError('SDK not enabled, will not send event.'));
4162
+ return SyncPromise.reject(new SentryError('SDK not enabled, will not capture event.'));
4141
4163
  }
4142
4164
  var isTransaction = event.type === 'transaction';
4143
4165
  // 1.0 === 100% events are sent
@@ -4156,15 +4178,7 @@ var Sentry = (function (exports) {
4156
4178
  return prepared;
4157
4179
  }
4158
4180
  var beforeSendResult = beforeSend(prepared, hint);
4159
- if (typeof beforeSendResult === 'undefined') {
4160
- throw new SentryError('`beforeSend` method has to return `null` or a valid event.');
4161
- }
4162
- else if (isThenable(beforeSendResult)) {
4163
- return beforeSendResult.then(function (event) { return event; }, function (e) {
4164
- throw new SentryError("beforeSend rejected with " + e);
4165
- });
4166
- }
4167
- return beforeSendResult;
4181
+ return _this._ensureBeforeSendRv(beforeSendResult);
4168
4182
  })
4169
4183
  .then(function (processedEvent) {
4170
4184
  if (processedEvent === null) {
@@ -4204,6 +4218,26 @@ var Sentry = (function (exports) {
4204
4218
  return reason;
4205
4219
  });
4206
4220
  };
4221
+ /**
4222
+ * Verifies that return value of configured `beforeSend` is of expected type.
4223
+ */
4224
+ BaseClient.prototype._ensureBeforeSendRv = function (rv) {
4225
+ var nullErr = '`beforeSend` method has to return `null` or a valid event.';
4226
+ if (isThenable(rv)) {
4227
+ return rv.then(function (event) {
4228
+ if (!(isPlainObject(event) || event === null)) {
4229
+ throw new SentryError(nullErr);
4230
+ }
4231
+ return event;
4232
+ }, function (e) {
4233
+ throw new SentryError("beforeSend rejected with " + e);
4234
+ });
4235
+ }
4236
+ else if (!(isPlainObject(rv) || rv === null)) {
4237
+ throw new SentryError(nullErr);
4238
+ }
4239
+ return rv;
4240
+ };
4207
4241
  return BaseClient;
4208
4242
  }());
4209
4243
 
@@ -4316,7 +4350,7 @@ var Sentry = (function (exports) {
4316
4350
  /** Creates a SentryRequest from a Session. */
4317
4351
  function sessionToSentryRequest(session, api) {
4318
4352
  var sdkInfo = getSdkMetadataForEnvelopeHeader(api);
4319
- var envelopeHeaders = JSON.stringify(__assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })));
4353
+ var envelopeHeaders = JSON.stringify(__assign(__assign({ sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.forceEnvelope() && { dsn: api.getDsn().toString() })));
4320
4354
  // I know this is hacky but we don't want to add `session` to request type since it's never rate limited
4321
4355
  var type = 'aggregates' in session ? 'sessions' : 'session';
4322
4356
  var itemHeaders = JSON.stringify({
@@ -4332,7 +4366,7 @@ var Sentry = (function (exports) {
4332
4366
  function eventToSentryRequest(event, api) {
4333
4367
  var sdkInfo = getSdkMetadataForEnvelopeHeader(api);
4334
4368
  var eventType = event.type || 'event';
4335
- var useEnvelope = eventType === 'transaction';
4369
+ var useEnvelope = eventType === 'transaction' || api.forceEnvelope();
4336
4370
  var _a = event.debug_meta || {}, transactionSampling = _a.transactionSampling, metadata = __rest(_a, ["transactionSampling"]);
4337
4371
  var _b = transactionSampling || {}, samplingMethod = _b.method, sampleRate = _b.rate;
4338
4372
  if (Object.keys(metadata).length === 0) {
@@ -4352,9 +4386,9 @@ var Sentry = (function (exports) {
4352
4386
  // deserialization. Instead, we only implement a minimal subset of the spec to
4353
4387
  // serialize events inline here.
4354
4388
  if (useEnvelope) {
4355
- var envelopeHeaders = JSON.stringify(__assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })));
4389
+ var envelopeHeaders = JSON.stringify(__assign(__assign({ event_id: event.event_id, sent_at: new Date().toISOString() }, (sdkInfo && { sdk: sdkInfo })), (api.forceEnvelope() && { dsn: api.getDsn().toString() })));
4356
4390
  var itemHeaders = JSON.stringify({
4357
- type: event.type,
4391
+ type: eventType,
4358
4392
  // TODO: Right now, sampleRate may or may not be defined (it won't be in the cases of inheritance and
4359
4393
  // explicitly-set sampling decisions). Are we good with that?
4360
4394
  sample_rates: [{ id: samplingMethod, rate: sampleRate }],
@@ -4387,7 +4421,7 @@ var Sentry = (function (exports) {
4387
4421
  hub.bindClient(client);
4388
4422
  }
4389
4423
 
4390
- var SDK_VERSION = '6.6.0';
4424
+ var SDK_VERSION = '6.8.0';
4391
4425
 
4392
4426
  var originalFunctionToString;
4393
4427
  /** Patch toString calls to return proper name for wrapped functions */
@@ -5029,7 +5063,7 @@ var Sentry = (function (exports) {
5029
5063
  this._buffer = new PromiseBuffer(30);
5030
5064
  /** Locks transport after receiving rate limits in a response */
5031
5065
  this._rateLimits = {};
5032
- this._api = new API(options.dsn, options._metadata);
5066
+ this._api = new API(options.dsn, options._metadata, options.tunnel);
5033
5067
  // eslint-disable-next-line deprecation/deprecation
5034
5068
  this.url = this._api.getStoreEndpointWithUrlEncodedAuth();
5035
5069
  }
@@ -5057,7 +5091,7 @@ var Sentry = (function (exports) {
5057
5091
  */
5058
5092
  var limited = this._handleRateLimit(headers);
5059
5093
  if (limited)
5060
- logger.warn("Too many requests, backing off until: " + this._disabledUntil(requestType));
5094
+ logger.warn("Too many " + requestType + " requests, backing off until: " + this._disabledUntil(requestType));
5061
5095
  if (status === exports.Status.Success) {
5062
5096
  resolve({ status: status });
5063
5097
  return;
@@ -5232,7 +5266,7 @@ var Sentry = (function (exports) {
5232
5266
  return Promise.reject({
5233
5267
  event: originalPayload,
5234
5268
  type: sentryRequest.type,
5235
- reason: "Transport locked till " + this._disabledUntil(sentryRequest.type) + " due to too many requests.",
5269
+ reason: "Transport for " + sentryRequest.type + " requests locked till " + this._disabledUntil(sentryRequest.type) + " due to too many requests.",
5236
5270
  status: 429,
5237
5271
  });
5238
5272
  }
@@ -5251,23 +5285,25 @@ var Sentry = (function (exports) {
5251
5285
  if (this.options.headers !== undefined) {
5252
5286
  options.headers = this.options.headers;
5253
5287
  }
5254
- return this._buffer.add(new SyncPromise(function (resolve, reject) {
5255
- void _this._fetch(sentryRequest.url, options)
5256
- .then(function (response) {
5257
- var headers = {
5258
- 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
5259
- 'retry-after': response.headers.get('Retry-After'),
5260
- };
5261
- _this._handleResponse({
5262
- requestType: sentryRequest.type,
5263
- response: response,
5264
- headers: headers,
5265
- resolve: resolve,
5266
- reject: reject,
5267
- });
5268
- })
5269
- .catch(reject);
5270
- }));
5288
+ return this._buffer.add(function () {
5289
+ return new SyncPromise(function (resolve, reject) {
5290
+ void _this._fetch(sentryRequest.url, options)
5291
+ .then(function (response) {
5292
+ var headers = {
5293
+ 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
5294
+ 'retry-after': response.headers.get('Retry-After'),
5295
+ };
5296
+ _this._handleResponse({
5297
+ requestType: sentryRequest.type,
5298
+ response: response,
5299
+ headers: headers,
5300
+ resolve: resolve,
5301
+ reject: reject,
5302
+ });
5303
+ })
5304
+ .catch(reject);
5305
+ });
5306
+ });
5271
5307
  };
5272
5308
  return FetchTransport;
5273
5309
  }(BaseTransport));
@@ -5300,29 +5336,31 @@ var Sentry = (function (exports) {
5300
5336
  return Promise.reject({
5301
5337
  event: originalPayload,
5302
5338
  type: sentryRequest.type,
5303
- reason: "Transport locked till " + this._disabledUntil(sentryRequest.type) + " due to too many requests.",
5339
+ reason: "Transport for " + sentryRequest.type + " requests locked till " + this._disabledUntil(sentryRequest.type) + " due to too many requests.",
5304
5340
  status: 429,
5305
5341
  });
5306
5342
  }
5307
- return this._buffer.add(new SyncPromise(function (resolve, reject) {
5308
- var request = new XMLHttpRequest();
5309
- request.onreadystatechange = function () {
5310
- if (request.readyState === 4) {
5311
- var headers = {
5312
- 'x-sentry-rate-limits': request.getResponseHeader('X-Sentry-Rate-Limits'),
5313
- 'retry-after': request.getResponseHeader('Retry-After'),
5314
- };
5315
- _this._handleResponse({ requestType: sentryRequest.type, response: request, headers: headers, resolve: resolve, reject: reject });
5316
- }
5317
- };
5318
- request.open('POST', sentryRequest.url);
5319
- for (var header in _this.options.headers) {
5320
- if (_this.options.headers.hasOwnProperty(header)) {
5321
- request.setRequestHeader(header, _this.options.headers[header]);
5343
+ return this._buffer.add(function () {
5344
+ return new SyncPromise(function (resolve, reject) {
5345
+ var request = new XMLHttpRequest();
5346
+ request.onreadystatechange = function () {
5347
+ if (request.readyState === 4) {
5348
+ var headers = {
5349
+ 'x-sentry-rate-limits': request.getResponseHeader('X-Sentry-Rate-Limits'),
5350
+ 'retry-after': request.getResponseHeader('Retry-After'),
5351
+ };
5352
+ _this._handleResponse({ requestType: sentryRequest.type, response: request, headers: headers, resolve: resolve, reject: reject });
5353
+ }
5354
+ };
5355
+ request.open('POST', sentryRequest.url);
5356
+ for (var header in _this.options.headers) {
5357
+ if (_this.options.headers.hasOwnProperty(header)) {
5358
+ request.setRequestHeader(header, _this.options.headers[header]);
5359
+ }
5322
5360
  }
5323
- }
5324
- request.send(sentryRequest.body);
5325
- }));
5361
+ request.send(sentryRequest.body);
5362
+ });
5363
+ });
5326
5364
  };
5327
5365
  return XHRTransport;
5328
5366
  }(BaseTransport));
@@ -5366,7 +5404,7 @@ var Sentry = (function (exports) {
5366
5404
  // We return the noop transport here in case there is no Dsn.
5367
5405
  return _super.prototype._setupTransport.call(this);
5368
5406
  }
5369
- var transportOptions = __assign(__assign({}, this._options.transportOptions), { dsn: this._options.dsn, _metadata: this._options._metadata });
5407
+ var transportOptions = __assign(__assign({}, this._options.transportOptions), { dsn: this._options.dsn, tunnel: this._options.tunnel, _metadata: this._options._metadata });
5370
5408
  if (this._options.transport) {
5371
5409
  return new this._options.transport(transportOptions);
5372
5410
  }
@@ -5578,9 +5616,9 @@ var Sentry = (function (exports) {
5578
5616
  return;
5579
5617
  }
5580
5618
  var client = currentHub.getClient();
5581
- var event = isPrimitive(error)
5619
+ var event = error === undefined && isString(data.msg)
5582
5620
  ? _this._eventFromIncompleteOnError(data.msg, data.url, data.line, data.column)
5583
- : _this._enhanceEventWithInitialFrame(eventFromUnknownInput(error, undefined, {
5621
+ : _this._enhanceEventWithInitialFrame(eventFromUnknownInput(error || data.msg, undefined, {
5584
5622
  attachStacktrace: client && client.getOptions().attachStacktrace,
5585
5623
  rejection: false,
5586
5624
  }), data.url, data.line, data.column);
@@ -5661,12 +5699,10 @@ var Sentry = (function (exports) {
5661
5699
  // If 'message' is ErrorEvent, get real message from inside
5662
5700
  var message = isErrorEvent(msg) ? msg.message : msg;
5663
5701
  var name;
5664
- if (isString(message)) {
5665
- var groups = message.match(ERROR_TYPES_RE);
5666
- if (groups) {
5667
- name = groups[1];
5668
- message = groups[2];
5669
- }
5702
+ var groups = message.match(ERROR_TYPES_RE);
5703
+ if (groups) {
5704
+ name = groups[1];
5705
+ message = groups[2];
5670
5706
  }
5671
5707
  var event = {
5672
5708
  exception: {
@@ -6091,12 +6127,15 @@ var Sentry = (function (exports) {
6091
6127
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6092
6128
  Breadcrumbs.prototype._domBreadcrumb = function (handlerData) {
6093
6129
  var target;
6094
- var keyAttr = typeof this._options.dom === 'object' ? this._options.dom.serializeAttribute : undefined;
6130
+ var keyAttrs = typeof this._options.dom === 'object' ? this._options.dom.serializeAttribute : undefined;
6131
+ if (typeof keyAttrs === 'string') {
6132
+ keyAttrs = [keyAttrs];
6133
+ }
6095
6134
  // Accessing event.target can throw (see getsentry/raven-js#838, #768)
6096
6135
  try {
6097
6136
  target = handlerData.event.target
6098
- ? htmlTreeAsString(handlerData.event.target, keyAttr)
6099
- : htmlTreeAsString(handlerData.event, keyAttr);
6137
+ ? htmlTreeAsString(handlerData.event.target, keyAttrs)
6138
+ : htmlTreeAsString(handlerData.event, keyAttrs);
6100
6139
  }
6101
6140
  catch (e) {
6102
6141
  target = '<unknown>';
@@ -6308,6 +6347,170 @@ var Sentry = (function (exports) {
6308
6347
  return UserAgent;
6309
6348
  }());
6310
6349
 
6350
+ /** Deduplication filter */
6351
+ var Dedupe = /** @class */ (function () {
6352
+ function Dedupe() {
6353
+ /**
6354
+ * @inheritDoc
6355
+ */
6356
+ this.name = Dedupe.id;
6357
+ }
6358
+ /**
6359
+ * @inheritDoc
6360
+ */
6361
+ Dedupe.prototype.setupOnce = function (addGlobalEventProcessor, getCurrentHub) {
6362
+ addGlobalEventProcessor(function (currentEvent) {
6363
+ var self = getCurrentHub().getIntegration(Dedupe);
6364
+ if (self) {
6365
+ // Juuust in case something goes wrong
6366
+ try {
6367
+ if (self._shouldDropEvent(currentEvent, self._previousEvent)) {
6368
+ return null;
6369
+ }
6370
+ }
6371
+ catch (_oO) {
6372
+ return (self._previousEvent = currentEvent);
6373
+ }
6374
+ return (self._previousEvent = currentEvent);
6375
+ }
6376
+ return currentEvent;
6377
+ });
6378
+ };
6379
+ /** JSDoc */
6380
+ Dedupe.prototype._shouldDropEvent = function (currentEvent, previousEvent) {
6381
+ if (!previousEvent) {
6382
+ return false;
6383
+ }
6384
+ if (this._isSameMessageEvent(currentEvent, previousEvent)) {
6385
+ return true;
6386
+ }
6387
+ if (this._isSameExceptionEvent(currentEvent, previousEvent)) {
6388
+ return true;
6389
+ }
6390
+ return false;
6391
+ };
6392
+ /** JSDoc */
6393
+ Dedupe.prototype._isSameMessageEvent = function (currentEvent, previousEvent) {
6394
+ var currentMessage = currentEvent.message;
6395
+ var previousMessage = previousEvent.message;
6396
+ // If neither event has a message property, they were both exceptions, so bail out
6397
+ if (!currentMessage && !previousMessage) {
6398
+ return false;
6399
+ }
6400
+ // If only one event has a stacktrace, but not the other one, they are not the same
6401
+ if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {
6402
+ return false;
6403
+ }
6404
+ if (currentMessage !== previousMessage) {
6405
+ return false;
6406
+ }
6407
+ if (!this._isSameFingerprint(currentEvent, previousEvent)) {
6408
+ return false;
6409
+ }
6410
+ if (!this._isSameStacktrace(currentEvent, previousEvent)) {
6411
+ return false;
6412
+ }
6413
+ return true;
6414
+ };
6415
+ /** JSDoc */
6416
+ Dedupe.prototype._getFramesFromEvent = function (event) {
6417
+ var exception = event.exception;
6418
+ if (exception) {
6419
+ try {
6420
+ // @ts-ignore Object could be undefined
6421
+ return exception.values[0].stacktrace.frames;
6422
+ }
6423
+ catch (_oO) {
6424
+ return undefined;
6425
+ }
6426
+ }
6427
+ else if (event.stacktrace) {
6428
+ return event.stacktrace.frames;
6429
+ }
6430
+ return undefined;
6431
+ };
6432
+ /** JSDoc */
6433
+ Dedupe.prototype._isSameStacktrace = function (currentEvent, previousEvent) {
6434
+ var currentFrames = this._getFramesFromEvent(currentEvent);
6435
+ var previousFrames = this._getFramesFromEvent(previousEvent);
6436
+ // If neither event has a stacktrace, they are assumed to be the same
6437
+ if (!currentFrames && !previousFrames) {
6438
+ return true;
6439
+ }
6440
+ // If only one event has a stacktrace, but not the other one, they are not the same
6441
+ if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {
6442
+ return false;
6443
+ }
6444
+ currentFrames = currentFrames;
6445
+ previousFrames = previousFrames;
6446
+ // If number of frames differ, they are not the same
6447
+ if (previousFrames.length !== currentFrames.length) {
6448
+ return false;
6449
+ }
6450
+ // Otherwise, compare the two
6451
+ for (var i = 0; i < previousFrames.length; i++) {
6452
+ var frameA = previousFrames[i];
6453
+ var frameB = currentFrames[i];
6454
+ if (frameA.filename !== frameB.filename ||
6455
+ frameA.lineno !== frameB.lineno ||
6456
+ frameA.colno !== frameB.colno ||
6457
+ frameA.function !== frameB.function) {
6458
+ return false;
6459
+ }
6460
+ }
6461
+ return true;
6462
+ };
6463
+ /** JSDoc */
6464
+ Dedupe.prototype._getExceptionFromEvent = function (event) {
6465
+ return event.exception && event.exception.values && event.exception.values[0];
6466
+ };
6467
+ /** JSDoc */
6468
+ Dedupe.prototype._isSameExceptionEvent = function (currentEvent, previousEvent) {
6469
+ var previousException = this._getExceptionFromEvent(previousEvent);
6470
+ var currentException = this._getExceptionFromEvent(currentEvent);
6471
+ if (!previousException || !currentException) {
6472
+ return false;
6473
+ }
6474
+ if (previousException.type !== currentException.type || previousException.value !== currentException.value) {
6475
+ return false;
6476
+ }
6477
+ if (!this._isSameFingerprint(currentEvent, previousEvent)) {
6478
+ return false;
6479
+ }
6480
+ if (!this._isSameStacktrace(currentEvent, previousEvent)) {
6481
+ return false;
6482
+ }
6483
+ return true;
6484
+ };
6485
+ /** JSDoc */
6486
+ Dedupe.prototype._isSameFingerprint = function (currentEvent, previousEvent) {
6487
+ var currentFingerprint = currentEvent.fingerprint;
6488
+ var previousFingerprint = previousEvent.fingerprint;
6489
+ // If neither event has a fingerprint, they are assumed to be the same
6490
+ if (!currentFingerprint && !previousFingerprint) {
6491
+ return true;
6492
+ }
6493
+ // If only one event has a fingerprint, but not the other one, they are not the same
6494
+ if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {
6495
+ return false;
6496
+ }
6497
+ currentFingerprint = currentFingerprint;
6498
+ previousFingerprint = previousFingerprint;
6499
+ // Otherwise, compare the two
6500
+ try {
6501
+ return !!(currentFingerprint.join('') === previousFingerprint.join(''));
6502
+ }
6503
+ catch (_oO) {
6504
+ return false;
6505
+ }
6506
+ };
6507
+ /**
6508
+ * @inheritDoc
6509
+ */
6510
+ Dedupe.id = 'Dedupe';
6511
+ return Dedupe;
6512
+ }());
6513
+
6311
6514
 
6312
6515
 
6313
6516
  var BrowserIntegrations = /*#__PURE__*/Object.freeze({
@@ -6316,7 +6519,8 @@ var Sentry = (function (exports) {
6316
6519
  TryCatch: TryCatch,
6317
6520
  Breadcrumbs: Breadcrumbs,
6318
6521
  LinkedErrors: LinkedErrors,
6319
- UserAgent: UserAgent
6522
+ UserAgent: UserAgent,
6523
+ Dedupe: Dedupe
6320
6524
  });
6321
6525
 
6322
6526
  /**
@@ -6394,6 +6598,7 @@ var Sentry = (function (exports) {
6394
6598
  new Breadcrumbs(),
6395
6599
  new GlobalHandlers(),
6396
6600
  new LinkedErrors(),
6601
+ new Dedupe(),
6397
6602
  new UserAgent(),
6398
6603
  ];
6399
6604
  /**