@honeybadger-io/js 6.16.5 → 6.17.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.
@@ -200,6 +200,17 @@ var stackTraceParser_esm = /*#__PURE__*/Object.freeze({
200
200
  var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm);
201
201
 
202
202
  (function (exports) {
203
+ var __assign = (commonjsGlobal && commonjsGlobal.__assign) || function () {
204
+ __assign = Object.assign || function(t) {
205
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
206
+ s = arguments[i];
207
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
208
+ t[p] = s[p];
209
+ }
210
+ return t;
211
+ };
212
+ return __assign.apply(this, arguments);
213
+ };
203
214
  var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
204
215
  if (k2 === undefined) k2 = k;
205
216
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -260,7 +271,7 @@ var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm);
260
271
  }
261
272
  };
262
273
  Object.defineProperty(exports, "__esModule", { value: true });
263
- exports.logDeprecatedMethod = exports.globalThisOrWindow = exports.isBrowserConfig = exports.clone = exports.formatCGIData = exports.filterUrl = exports.filter = exports.generateStackTrace = exports.endpoint = exports.instrumentConsole = exports.instrument = exports.isErrorObject = exports.makeNotice = exports.logger = exports.sanitize = exports.shallowClone = exports.runAfterNotifyHandlers = exports.shouldSampleEvent = exports.resolveInsights = exports.runBeforeEventHandlers = exports.runBeforeNotifyHandlers = exports.getSourceForBacktrace = exports.getCauses = exports.calculateBacktraceShift = exports.DEFAULT_BACKTRACE_SHIFT = exports.makeBacktrace = exports.objectIsExtensible = exports.objectIsEmpty = exports.mergeNotice = exports.merge = void 0;
274
+ exports.logDeprecatedMethod = exports.globalThisOrWindow = exports.isBrowserConfig = exports.clone = exports.formatCGIData = exports.filterBreadcrumbs = exports.filterUrl = exports.filter = exports.generateStackTrace = exports.endpoint = exports.instrumentConsole = exports.instrument = exports.isErrorObject = exports.makeNotice = exports.logger = exports.sanitize = exports.shallowClone = exports.runAfterNotifyHandlers = exports.shouldSampleEvent = exports.resolveInsights = exports.runBeforeBreadcrumbHandlers = exports.runBeforeEventHandlers = exports.runBeforeNotifyHandlers = exports.getSourceForBacktrace = exports.getCauses = exports.calculateBacktraceShift = exports.DEFAULT_BACKTRACE_SHIFT = exports.makeBacktrace = exports.objectIsExtensible = exports.objectIsEmpty = exports.mergeNotice = exports.merge = void 0;
264
275
  /* eslint-disable prefer-rest-params */
265
276
  var stackTraceParser = __importStar(require$$0$1);
266
277
  function merge(obj1, obj2) {
@@ -473,6 +484,25 @@ var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm);
473
484
  });
474
485
  }
475
486
  exports.runBeforeEventHandlers = runBeforeEventHandlers;
487
+ function runBeforeBreadcrumbHandlers(breadcrumb, handlers, logger) {
488
+ for (var i = 0, len = handlers.length; i < len; i++) {
489
+ var result = void 0;
490
+ try {
491
+ result = handlers[i](breadcrumb);
492
+ }
493
+ catch (err) {
494
+ // Breadcrumbs are recorded inside instrumented fetch/XHR/DOM callbacks,
495
+ // so a buggy handler must not throw into the host app. Log and treat as no-op.
496
+ logger === null || logger === void 0 ? void 0 : logger.error('beforeBreadcrumb handler threw; continuing', err);
497
+ continue;
498
+ }
499
+ if (result === false) {
500
+ return false;
501
+ }
502
+ }
503
+ return true;
504
+ }
505
+ exports.runBeforeBreadcrumbHandlers = runBeforeBreadcrumbHandlers;
476
506
  function resolveInsights(config) {
477
507
  var _a, _b;
478
508
  var insights = config.insights;
@@ -846,6 +876,76 @@ var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm);
846
876
  return result;
847
877
  }
848
878
  exports.filterUrl = filterUrl;
879
+ /**
880
+ * Breadcrumb metadata keys whose value is a URL, and so may carry a query string.
881
+ *
882
+ * Checked by name rather than by running `filterUrl` over every string value: a `?` is
883
+ * ordinary punctuation in a breadcrumb message or a console argument, and rewriting around
884
+ * it would mangle text that is not a URL at all.
885
+ */
886
+ var URL_METADATA_KEYS = ['url', 'from', 'to', 'href'];
887
+ /**
888
+ * Recursively rewrites the query string of every URL-bearing value.
889
+ *
890
+ * Nested as well as top-level: a breadcrumb may well carry
891
+ * `metadata: { request: { url: '/checkout?token=secret' } }`, and `filter` leaves that URL
892
+ * alone because the key `request` matches no filter.
893
+ *
894
+ * Safe to recurse without a seen-list because `filter` has already run: it replaces a
895
+ * circular reference with a string, so what arrives here is acyclic.
896
+ */
897
+ function filterUrlValues(value, filters) {
898
+ if (is('Array', value)) {
899
+ return value.map(function (entry) { return filterUrlValues(entry, filters); });
900
+ }
901
+ if (!is('Object', value)) {
902
+ return value;
903
+ }
904
+ var result = {};
905
+ var source = value;
906
+ // Own enumerable keys only, assigned with `defineProperty`: a plain `result[key] =` would
907
+ // reassign the prototype rather than create a property for a key named `__proto__`, and
908
+ // breadcrumb metadata is host-supplied.
909
+ Object.keys(source).forEach(function (key) {
910
+ var entry = source[key];
911
+ var filtered = URL_METADATA_KEYS.includes(key.toLowerCase()) && typeof entry === 'string'
912
+ ? filterUrl(entry, filters)
913
+ : filterUrlValues(entry, filters);
914
+ Object.defineProperty(result, key, {
915
+ value: filtered,
916
+ enumerable: true,
917
+ writable: true,
918
+ configurable: true
919
+ });
920
+ });
921
+ return result;
922
+ }
923
+ /**
924
+ * Applies `filters` to a breadcrumb trail.
925
+ *
926
+ * Metadata is filtered by key, exactly as `params` and `session` are, and any value under a
927
+ * URL-bearing key additionally has its query string filtered. Breadcrumb metadata is mostly
928
+ * generated by this library -- the XHR, fetch and navigation integrations all record a full
929
+ * URL -- so a query string lands there without the user ever choosing to put it there.
930
+ */
931
+ function filterBreadcrumbs(trail, filters) {
932
+ if (!is('Array', trail)) {
933
+ return [];
934
+ }
935
+ return trail.map(function (breadcrumb) {
936
+ // Leave a crumb that never carried metadata exactly as it is, so the payload shape does
937
+ // not change for it.
938
+ if (!is('Object', breadcrumb === null || breadcrumb === void 0 ? void 0 : breadcrumb.metadata)) {
939
+ return breadcrumb;
940
+ }
941
+ // `filter` runs first, so a key-matched value is already '[FILTERED]' by the time the
942
+ // URL pass sees it. Passing that through `filterUrl` is harmless: it holds no '?', so
943
+ // it is returned untouched.
944
+ var metadata = filterUrlValues(filter(breadcrumb.metadata, filters), filters);
945
+ return __assign(__assign({}, breadcrumb), { metadata: metadata });
946
+ });
947
+ }
948
+ exports.filterBreadcrumbs = filterBreadcrumbs;
849
949
  function formatCGIData(vars, prefix) {
850
950
  if (prefix === void 0) { prefix = ''; }
851
951
  var formattedVars = {};
@@ -1468,12 +1568,14 @@ var Client = /** @class */ (function () {
1468
1568
  this.__store = null;
1469
1569
  this.__beforeNotifyHandlers = [];
1470
1570
  this.__beforeEventHandlers = [];
1571
+ this.__beforeBreadcrumbHandlers = [];
1572
+ this.__runningBeforeBreadcrumbHandlers = false;
1471
1573
  this.__afterNotifyHandlers = [];
1472
1574
  this.__pendingEvents = new Set();
1473
1575
  this.__notifier = {
1474
1576
  name: '@honeybadger-io/core',
1475
1577
  url: 'https://github.com/honeybadger-io/honeybadger-js/tree/master/packages/core',
1476
- version: '6.16.5'
1578
+ version: '6.17.0'
1477
1579
  };
1478
1580
  this.config = __assign$1(__assign$1({}, defaults_1.CONFIG), opts);
1479
1581
  this.__initStore();
@@ -1540,6 +1642,10 @@ var Client = /** @class */ (function () {
1540
1642
  this.__beforeEventHandlers.push(handler);
1541
1643
  return this;
1542
1644
  };
1645
+ Client.prototype.beforeBreadcrumb = function (handler) {
1646
+ this.__beforeBreadcrumbHandlers.push(handler);
1647
+ return this;
1648
+ };
1543
1649
  Client.prototype.afterNotify = function (handler) {
1544
1650
  this.__afterNotifyHandlers.push(handler);
1545
1651
  return this;
@@ -1745,12 +1851,29 @@ var Client = /** @class */ (function () {
1745
1851
  var metadata = (0, util_1$5.shallowClone)(opts.metadata);
1746
1852
  var category = opts.category || 'custom';
1747
1853
  var timestamp = new Date().toISOString();
1748
- this.__store.addBreadcrumb({
1854
+ var breadcrumb = {
1749
1855
  category: category,
1750
1856
  message: message,
1751
1857
  metadata: metadata,
1752
1858
  timestamp: timestamp
1753
- });
1859
+ };
1860
+ // A handler that logs, or the error we log when a handler throws, goes
1861
+ // through instrumented console methods and lands back here. Skipping the
1862
+ // handlers for those breadcrumbs keeps that from recursing.
1863
+ if (!this.__runningBeforeBreadcrumbHandlers) {
1864
+ this.__runningBeforeBreadcrumbHandlers = true;
1865
+ var keep = void 0;
1866
+ try {
1867
+ keep = (0, util_1$5.runBeforeBreadcrumbHandlers)(breadcrumb, this.__beforeBreadcrumbHandlers, this.logger);
1868
+ }
1869
+ finally {
1870
+ this.__runningBeforeBreadcrumbHandlers = false;
1871
+ }
1872
+ if (!keep) {
1873
+ return this;
1874
+ }
1875
+ }
1876
+ this.__store.addBreadcrumb(breadcrumb);
1754
1877
  return this;
1755
1878
  };
1756
1879
  /**
@@ -1834,7 +1957,7 @@ var Client = /** @class */ (function () {
1834
1957
  notifier: this.__notifier,
1835
1958
  breadcrumbs: {
1836
1959
  enabled: !!this.config.breadcrumbsEnabled,
1837
- trail: notice.__breadcrumbs || []
1960
+ trail: (0, util_1$5.filterBreadcrumbs)(notice.__breadcrumbs || [], this.config.filters)
1838
1961
  },
1839
1962
  error: {
1840
1963
  class: notice.name,
@@ -4089,7 +4212,7 @@ var globalSingleton = {};
4089
4212
  var NOTIFIER = {
4090
4213
  name: '@honeybadger-io/js',
4091
4214
  url: 'https://github.com/honeybadger-io/honeybadger-js/tree/master/packages/js',
4092
- version: '6.16.5'
4215
+ version: '6.17.0'
4093
4216
  };
4094
4217
  var userAgent = function () {
4095
4218
  return "Honeybadger JS Server Client ".concat(NOTIFIER.version, ", ").concat(os_1.default.version(), "; ").concat(os_1.default.platform());