raygun4js
Version:
Raygun.com plugin for JavaScript
1,452 lines (1,235 loc) • 197 kB
JavaScript
/*! Raygun4js - v3.1.3 - 2024-11-28
* https://github.com/MindscapeHQ/raygun4js
* Copyright (c) 2024 MindscapeHQ; Licensed MIT */
// https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define('raygun4js', function() {
return (root.Raygun = factory());
});
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Browser globals
root.Raygun = factory();
}
}(this, function() {
var windw = this || window || global;
var originalOnError = windw.onerror;
windw.onerror = function(msg, url, line, col, err) {
if (originalOnError) {
originalOnError(msg, url, line, col, err);
}
if (!err) {
err = new Error(msg);
}
windw['rg4js'].q = windw['rg4js'].q || [];
windw['rg4js'].q.push({ e: err });
};
// Similar approach as the snippet, creates the rg4js proxy function, which is exported in umd.outro.js once the
// script is executed, and later overwritten by the loader once it's finished
(function(wind) {
wind['RaygunObject'] = 'rg4js';
wind[wind['RaygunObject']] = wind[wind['RaygunObject']] || function() {
if (wind && typeof wind['Raygun'] === 'undefined' ||
(typeof document === 'undefined' || document.readyState !== 'complete') || (!wind['RaygunInitialized'])) {
// onload hasn't been called, cache the commands just like the snippet
(wind[wind['RaygunObject']].o = wind[wind['RaygunObject']].o || []).push(arguments)
} else {
// onload has been called and provider has executed, call the executor proxy function
return wind[wind['RaygunObject']](arguments[0], arguments[1]);
}
}
})(windw);
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).webVitals={})}(this,(function(e){"use strict";var n,t,i,r,o,a=-1,c=function(e){addEventListener("pageshow",(function(n){n.persisted&&(a=n.timeStamp,e(n))}),!0)},u=function(){return window.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]},f=function(){var e=u();return e&&e.activationStart||0},s=function(e,n){var t=u(),i="navigate";a>=0?i="back-forward-cache":t&&(document.prerendering||f()>0?i="prerender":document.wasDiscarded?i="restore":t.type&&(i=t.type.replace(/_/g,"-")));return{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:i}},d=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var i=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return i.observe(Object.assign({type:e,buffered:!0},t||{})),i}}catch(e){}},l=function(e,n,t,i){var r,o;return function(a){n.value>=0&&(a||i)&&((o=n.value-(r||0))||void 0===r)&&(r=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},p=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},v=function(e){var n=function(n){"pagehide"!==n.type&&"hidden"!==document.visibilityState||e(n)};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},m=function(e){var n=!1;return function(t){n||(e(t),n=!0)}},h=-1,g=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},T=function(e){"hidden"===document.visibilityState&&h>-1&&(h="visibilitychange"===e.type?e.timeStamp:0,E())},y=function(){addEventListener("visibilitychange",T,!0),addEventListener("prerenderingchange",T,!0)},E=function(){removeEventListener("visibilitychange",T,!0),removeEventListener("prerenderingchange",T,!0)},C=function(){return h<0&&(h=g(),y(),c((function(){setTimeout((function(){h=g(),y()}),0)}))),{get firstHiddenTime(){return h}}},L=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},b=[1800,3e3],w=function(e,n){n=n||{},L((function(){var t,i=C(),r=s("FCP"),o=d("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=Math.max(e.startTime-f(),0),r.entries.push(e),t(!0)))}))}));o&&(t=l(e,r,b,n.reportAllChanges),c((function(i){r=s("FCP"),t=l(e,r,b,n.reportAllChanges),p((function(){r.value=performance.now()-i.timeStamp,t(!0)}))})))}))},S=[.1,.25],P=function(e,n){n=n||{},w(m((function(){var t,i=s("CLS",0),r=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];r&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(r+=e.value,o.push(e)):(r=e.value,o=[e])}})),r>i.value&&(i.value=r,i.entries=o,t())},u=d("layout-shift",a);u&&(t=l(e,i,S,n.reportAllChanges),v((function(){a(u.takeRecords()),t(!0)})),c((function(){r=0,i=s("CLS",0),t=l(e,i,S,n.reportAllChanges),p((function(){return t()}))})),setTimeout(t,0))})))},I={passive:!0,capture:!0},F=new Date,A=function(e,r){n||(n=r,t=e,i=new Date,k(removeEventListener),D())},D=function(){if(t>=0&&t<i-F){var e={entryType:"first-input",name:n.type,target:n.target,cancelable:n.cancelable,startTime:n.timeStamp,processingStart:n.timeStamp+t};r.forEach((function(n){n(e)})),r=[]}},M=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){A(e,n),r()},i=function(){r()},r=function(){removeEventListener("pointerup",t,I),removeEventListener("pointercancel",i,I)};addEventListener("pointerup",t,I),addEventListener("pointercancel",i,I)}(n,e):A(n,e)}},k=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,M,I)}))},x=[100,300],B=function(e,i){i=i||{},L((function(){var o,a=C(),u=s("FID"),f=function(e){e.startTime<a.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),o(!0))},p=function(e){e.forEach(f)},h=d("first-input",p);o=l(e,u,x,i.reportAllChanges),h&&v(m((function(){p(h.takeRecords()),h.disconnect()}))),h&&c((function(){var a;u=s("FID"),o=l(e,u,x,i.reportAllChanges),r=[],t=-1,n=null,k(addEventListener),a=f,r.push(a),D()}))}))},N=0,R=1/0,H=0,O=function(e){e.forEach((function(e){e.interactionId&&(R=Math.min(R,e.interactionId),H=Math.max(H,e.interactionId),N=H?(H-R)/7+1:0)}))},j=function(){return o?N:performance.interactionCount||0},q=function(){"interactionCount"in performance||o||(o=d("event",O,{type:"event",buffered:!0,durationThreshold:0}))},V=[200,500],_=0,z=function(){return j()-_},G=[],J={},K=function(e){var n=G[G.length-1],t=J[e.interactionId];if(t||G.length<10||e.duration>n.latency){if(t)t.entries.push(e),t.latency=Math.max(t.latency,e.duration);else{var i={id:e.interactionId,latency:e.duration,entries:[e]};J[i.id]=i,G.push(i)}G.sort((function(e,n){return n.latency-e.latency})),G.splice(10).forEach((function(e){delete J[e.id]}))}},Q=function(e,n){n=n||{},L((function(){var t;q();var i,r=s("INP"),o=function(e){e.forEach((function(e){(e.interactionId&&K(e),"first-input"===e.entryType)&&(!G.some((function(n){return n.entries.some((function(n){return e.duration===n.duration&&e.startTime===n.startTime}))}))&&K(e))}));var n,t=(n=Math.min(G.length-1,Math.floor(z()/50)),G[n]);t&&t.latency!==r.value&&(r.value=t.latency,r.entries=t.entries,i())},a=d("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});i=l(e,r,V,n.reportAllChanges),a&&("PerformanceEventTiming"in window&&"interactionId"in PerformanceEventTiming.prototype&&a.observe({type:"first-input",buffered:!0}),v((function(){o(a.takeRecords()),r.value<0&&z()>0&&(r.value=0,r.entries=[]),i(!0)})),c((function(){G=[],_=j(),r=s("INP"),i=l(e,r,V,n.reportAllChanges)})))}))},U=[2500,4e3],W={},X=function(e,n){n=n||{},L((function(){var t,i=C(),r=s("LCP"),o=function(e){var n=e[e.length-1];n&&n.startTime<i.firstHiddenTime&&(r.value=Math.max(n.startTime-f(),0),r.entries=[n],t())},a=d("largest-contentful-paint",o);if(a){t=l(e,r,U,n.reportAllChanges);var u=m((function(){W[r.id]||(o(a.takeRecords()),a.disconnect(),W[r.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return setTimeout(u,0)}),!0)})),v(u),c((function(i){r=s("LCP"),t=l(e,r,U,n.reportAllChanges),p((function(){r.value=performance.now()-i.timeStamp,W[r.id]=!0,t(!0)}))}))}}))},Y=[800,1800],Z=function e(n){document.prerendering?L((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},$=function(e,n){n=n||{};var t=s("TTFB"),i=l(e,t,Y,n.reportAllChanges);Z((function(){var r=u();if(r){var o=r.responseStart;if(o<=0||o>performance.now())return;t.value=Math.max(o-f(),0),t.entries=[r],i(!0),c((function(){t=s("TTFB",0),(i=l(e,t,Y,n.reportAllChanges))(!0)}))}}))};e.CLSThresholds=S,e.FCPThresholds=b,e.FIDThresholds=x,e.INPThresholds=V,e.LCPThresholds=U,e.TTFBThresholds=Y,e.getCLS=P,e.getFCP=w,e.getFID=B,e.getINP=Q,e.getLCP=X,e.getTTFB=$,e.onCLS=P,e.onFCP=w,e.onFID=B,e.onINP=Q,e.onLCP=X,e.onTTFB=$}));
},{}],2:[function(require,module,exports){
// Mozilla's toISOString() shim for IE8
if (!Date.prototype.toISOString) {
(function () {
function pad(number) {
var r = String(number);
if (r.length === 1) {
r = '0' + r;
}
return r;
}
Date.prototype.toISOString = function () {
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1) + '-' + pad(this.getUTCDate()) + 'T' + pad(this.getUTCHours()) + ':' + pad(this.getUTCMinutes()) + ':' + pad(this.getUTCSeconds()) + '.' + String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5) + 'Z';
};
}());
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return -1;
}
var n = fromIndex | 0;
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
Array.prototype.map = function(callback/*, thisArg*/) {
var T, A, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = arguments[1];
}
A = new Array(len);
k = 0;
while (k < len) {
var kValue, mappedValue;
if (k in O) {
kValue = O[k];
mappedValue = callback.call(T, kValue, k, O);
A[k] = mappedValue;
}
k++;
}
return A;
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback/*, thisArg*/) {
var T, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = arguments[1];
}
k = 0;
while (k < len) {
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k++;
}
};
}
// Mozilla's bind() shim for IE8
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
FNOP = function () {
},
fBound = function () {
return fToBind.apply(this instanceof FNOP && oThis ? this : oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
FNOP.prototype = this.prototype;
fBound.prototype = new FNOP();
return fBound;
};
}
},{}],3:[function(require,module,exports){
/**
* @prettier
*/
/*
* raygun4js
* https://github.com/MindscapeHQ/raygun4js
*
* Copyright (c) 2024 MindscapeHQ
* Licensed under the MIT license.
*/
/* globals console */
window.raygunBreadcrumbsFactory = function(window, Raygun) {
function urlMatchesIgnoredHosts(url, ignoredHosts) {
for (var i = 0; i < ignoredHosts.length; i++) {
var host = ignoredHosts[i];
if (typeof host === 'string' && url && url.indexOf(host) > -1) {
return true;
} else if (typeof host === 'object' && host.exec(url)) {
return true;
}
}
return false;
}
var Breadcrumbs = function() {
this.MAX_BREADCRUMBS = 32;
this.MAX_MESSAGE_SIZE = 1024;
this.BREADCRUMB_LEVELS = ['debug', 'info', 'warning', 'error'];
this.DEFAULT_BREADCRUMB_LEVEL = 'info';
this.DEFAULT_XHR_IGNORED_HOSTS = ['raygun'];
this.breadcrumbLevel = 'info';
this.logXhrContents = false;
this.xhrIgnoredHosts = [].concat(this.DEFAULT_XHR_IGNORED_HOSTS);
this.breadcrumbs = [];
this.wrapWithHandler = function(method) {
return function() {
try {
return method.apply(this, arguments);
} catch (ex) {
Raygun.Utilities.log(ex);
}
};
};
this.disableConsoleFunctions = [];
this.disableNavigationFunctions = [];
this.disableXHRLogging = function() {};
this.disableClicksTracking = function() {};
this.enableAutoBreadcrumbs();
this.wrapPrototypeWithHandlers();
};
Breadcrumbs.prototype.recordBreadcrumb = function(value, metadata) {
var crumb = {
level: this.DEFAULT_BREADCRUMB_LEVEL,
timestamp: new Date().getTime(),
type: 'manual',
};
switch (typeof value) {
case 'object':
crumb = Raygun.Utilities.merge(crumb, value);
break;
case 'string':
crumb = Raygun.Utilities.merge(
Raygun.Utilities.merge(crumb, {
message: value,
metadata: metadata,
})
);
break;
default:
Raygun.Utilities.log(
"expected first argument to recordBreadcrumb to be a 'string' or 'object', got " +
typeof value
);
return;
}
if (this.BREADCRUMB_LEVELS.indexOf(crumb.level) === -1) {
Raygun.Utilities.log(
'unknown breadcrumb level ' +
crumb.level +
" setting to default of '" +
this.DEFAULT_BREADCRUMB_LEVEL +
"'"
);
crumb.level = this.DEFAULT_BREADCRUMB_LEVEL;
}
if (this.shouldRecord(crumb)) {
crumb.message = Raygun.Utilities.truncate(crumb.message, this.MAX_MESSAGE_SIZE);
this.breadcrumbs.push(crumb);
this.breadcrumbs = this.breadcrumbs.slice(-this.MAX_BREADCRUMBS);
}
};
Breadcrumbs.prototype.shouldRecord = function(crumb) {
var crumbLevel = this.BREADCRUMB_LEVELS.indexOf(crumb.level);
var activeLevel = this.BREADCRUMB_LEVELS.indexOf(this.breadcrumbLevel);
return crumbLevel >= activeLevel;
};
Breadcrumbs.prototype.setBreadcrumbLevel = function(level) {
if (this.BREADCRUMB_LEVELS.indexOf(level) === -1) {
Raygun.Utilities.log(
"Breadcrumb level of '" +
level +
"' is invalid, setting to default of '" +
this.DEFAULT_BREADCRUMB_LEVEL +
"'"
);
return;
}
this.breadcrumbLevel = level;
};
Breadcrumbs.prototype.setOption = function(option, value) {
if (option === 'breadcrumbsLevel') {
this.setBreadcrumbLevel(value);
} else if (option === 'xhrIgnoredHosts') {
this.xhrIgnoredHosts = value.concat(this.DEFAULT_XHR_IGNORED_HOSTS);
var self = this;
this.removeBreadcrumbsWithPredicate(function(crumb) {
if (crumb.type !== 'request') {
return false;
}
return urlMatchesIgnoredHosts(
crumb.metadata.requestURL || crumb.metadata.responseURL,
self.xhrIgnoredHosts
);
});
} else if (option === 'logXhrContents') {
this.logXhrContents = value;
}
};
Breadcrumbs.prototype.any = function() {
return this.breadcrumbs.length > 0;
};
Breadcrumbs.prototype.all = function() {
var sanitizedBreadcrumbs = [];
for (var i = 0; i < this.breadcrumbs.length; i++) {
var crumb = this.breadcrumbs[i];
if (crumb && crumb.type === 'request' && !this.logXhrContents) {
if (crumb.metadata && crumb.metadata.body) {
crumb.metadata.body = 'Disabled because logContentsOfXhrCalls has not been enabled';
}
}
sanitizedBreadcrumbs.push(crumb);
}
return sanitizedBreadcrumbs;
};
Breadcrumbs.prototype.enableAutoBreadcrumbs = function() {
this.enableAutoBreadcrumbsXHR();
this.enableAutoBreadcrumbsClicks();
this.enableAutoBreadcrumbsConsole();
this.enableAutoBreadcrumbsNavigation();
};
Breadcrumbs.prototype.disableAutoBreadcrumbs = function() {
this.disableAutoBreadcrumbsXHR();
this.disableAutoBreadcrumbsClicks();
this.disableAutoBreadcrumbsConsole();
this.disableAutoBreadcrumbsNavigation();
};
Breadcrumbs.prototype.removeBreadcrumbsWithPredicate = function(predicate) {
var crumbs = this.breadcrumbs;
var filteredCrumbs = [];
for (var i = 0; i < crumbs.length; i++) {
var crumb = crumbs[i];
if (!predicate(crumb)) {
filteredCrumbs.push(crumb);
}
}
this.breadcrumbs = filteredCrumbs;
};
Breadcrumbs.prototype.removeCrumbsOfType = function(type) {
this.removeBreadcrumbsWithPredicate(function(crumb) {
return crumb.type === type;
});
};
Breadcrumbs.prototype.enableAutoBreadcrumbsConsole = function() {
if (typeof window.console === 'undefined') {
return;
}
var logConsoleCall = function logConsoleCall(severity, args) {
var stringifiedArgs = [];
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (arg === null || arg === undefined) {
continue;
}
stringifiedArgs.push(arg.toString());
}
this.recordBreadcrumb({
type: 'console',
level: severity,
message: Array.prototype.slice.call(stringifiedArgs).join(', '),
});
}.bind(this);
var consoleProperties = ['log', 'warn', 'error'];
var self = this;
this.disableConsoleFunctions = consoleProperties.map(function(property) {
return Raygun.Utilities.enhance(
console,
property,
self.wrapWithHandler(function() {
var severity = property === 'log' ? 'info' : property === 'warn' ? 'warning' : 'error';
logConsoleCall(severity, arguments);
})
);
});
};
Breadcrumbs.prototype.disableAutoBreadcrumbsConsole = function() {
this.disableConsoleFunctions.forEach(function(unenhance) {
unenhance();
});
this.removeCrumbsOfType('console');
};
Breadcrumbs.prototype.enableAutoBreadcrumbsNavigation = function() {
if (!window.addEventListener || !window.history || !window.history.pushState) {
return;
}
var buildStateChange = function(name, state, title, url) {
var currentPath = location.pathname + location.search + location.hash;
var prevState = null;
if (window.history.state) {
prevState = history.state;
}
return {
message: 'History ' + name,
type: 'navigation',
level: 'info',
metadata: {
from: currentPath,
to: url || currentPath,
prevState: JSON.stringify(prevState) || 'unsupported',
nextState: JSON.stringify(state),
},
};
}.bind(this);
var parseHash = function(url) {
return url.split('#')[1] || '';
};
var historyFunctionsToEnhance = ['pushState', 'replaceState'];
this.disableNavigationFunctions = this.disableNavigationFunctions.concat(
historyFunctionsToEnhance.map(
function(stateChange) {
return Raygun.Utilities.enhance(
history,
stateChange,
this.wrapWithHandler(
function(state, title, url) {
this.recordBreadcrumb(buildStateChange(stateChange, state, title, url));
}.bind(this)
)
);
}.bind(this)
)
);
var buildHashChange = function(e) {
var oldURL = e.oldURL;
var newURL = e.newURL;
var metadata;
if (oldURL && newURL) {
metadata = {
from: parseHash(oldURL),
to: parseHash(newURL),
};
} else {
metadata = {
to: location.hash,
};
}
return {
type: 'navigation',
message: 'Hash change',
metadata: metadata,
};
};
var logBreadcrumbWrapper = function(handler) {
return this.wrapWithHandler(
function() {
this.recordBreadcrumb(handler.apply(null, arguments));
}.bind(this)
);
}.bind(this);
var eventsWithHandlers = [
{ element: window, event: 'hashchange', handler: buildHashChange },
{
element: window,
event: 'load',
handler: function() {
return { type: 'navigation', message: 'Page loaded' };
},
},
{
element: window,
event: 'popstate',
handler: function() {
return { type: 'navigation', message: 'Navigated back' };
},
},
{
element: window,
event: 'pagehide',
handler: function() {
return { type: 'navigation', message: 'Page hidden' };
},
},
{
element: window,
event: 'pageshow',
handler: function() {
return { type: 'navigation', message: 'Page shown' };
},
},
{
element: document,
event: 'DOMContentLoaded',
handler: function() {
return { type: 'navigation', message: 'DOMContentLoaded' };
},
},
];
this.disableNavigationFunctions = this.disableNavigationFunctions.concat(
eventsWithHandlers.map(
function(mapping) {
return Raygun.Utilities.addEventHandler(
mapping.element,
mapping.event,
logBreadcrumbWrapper(mapping.handler)
);
}.bind(this)
)
);
};
Breadcrumbs.prototype.disableAutoBreadcrumbsNavigation = function() {
this.disableNavigationFunctions.forEach(function(unenhance) {
unenhance();
});
this.disableNavigationFunctions = [];
this.removeCrumbsOfType('navigation');
};
Breadcrumbs.prototype.enableAutoBreadcrumbsClicks = function() {
this.disableClicksTracking = Raygun.Utilities.addEventHandler(
window,
'click',
this.wrapWithHandler(
function(e) {
var text, selector;
try {
text = Raygun.Utilities.truncate(Raygun.Utilities.nodeText(e.target), 150);
selector = Raygun.Utilities.nodeSelector(e.target);
} catch (exception) {
text = '[unknown]';
selector = '[unknown]';
Raygun.Utilities.log(
'Error retrieving node text/selector. Most likely due to a cross domain error'
);
}
this.recordBreadcrumb({
type: 'click-event',
message: 'UI Click',
level: 'info',
metadata: {
text: text,
selector: selector,
},
});
}.bind(this),
true
)
);
};
Breadcrumbs.prototype.disableAutoBreadcrumbsClicks = function() {
this.disableClicksTracking();
this.removeCrumbsOfType('click-event');
};
Breadcrumbs.prototype.enableAutoBreadcrumbsXHR = function() {
var self = this;
var requestHandler = self.wrapWithHandler(function(request) {
if (urlMatchesIgnoredHosts(request.requestURL, self.xhrIgnoredHosts)) {
return;
}
if (request.body) {
request.body = Raygun.Utilities.truncate(request.body, 500);
}
self.recordBreadcrumb({
type: 'request',
message: 'Opening request to ' + request.requestURL,
level: 'info',
metadata: request,
});
});
var responseHandler = self.wrapWithHandler(function(response) {
if (
urlMatchesIgnoredHosts(response.requestURL, self.xhrIgnoredHosts) ||
urlMatchesIgnoredHosts(response.responseURL, self.xhrIgnoredHosts)
) {
return;
}
if (response.body) {
response.body = Raygun.Utilities.truncate(response.body, 500);
}
response.duration = response.duration + 'ms';
self.recordBreadcrumb({
type: 'request',
message: 'Finished request to ' + response.requestURL,
level: 'info',
metadata: response,
});
});
var errorHandler = self.wrapWithHandler(function(error) {
if (urlMatchesIgnoredHosts(error.requestURL, self.xhrIgnoredHosts)) {
return;
}
error.duration = error.duration + 'ms';
self.recordBreadcrumb({
type: 'request',
message: 'Failed request to ' + error.requestURL,
level: 'info',
metadata: error,
});
});
Raygun.NetworkTracking.on('request', requestHandler);
Raygun.NetworkTracking.on('response', responseHandler);
Raygun.NetworkTracking.on('error', errorHandler);
this.disableXHRLogging = function() {
Raygun.NetworkTracking.off('request', requestHandler);
Raygun.NetworkTracking.off('response', responseHandler);
Raygun.NetworkTracking.off('error', errorHandler);
};
};
Breadcrumbs.prototype.disableAutoBreadcrumbsXHR = function() {
this.disableXHRLogging();
this.removeCrumbsOfType('request');
};
Breadcrumbs.prototype.wrapPrototypeWithHandlers = function() {
var name, method;
for (name in Breadcrumbs.prototype) {
method = Breadcrumbs.prototype[name];
if (typeof method === 'function') {
Breadcrumbs.prototype[name] = this.wrapWithHandler(method);
}
}
};
return Breadcrumbs;
};
},{}],4:[function(require,module,exports){
/**
* @prettier
*/
/*
* raygun4js
* https://github.com/MindscapeHQ/raygun4js
*
* Copyright (c) 2013-2024 Raygun Limited
* Licensed under the MIT license.
*/
/*globals __DEV__, raygunUtilityFactory, raygunErrorUtilitiesFactory, raygunBreadcrumbsFactory, raygunNetworkTrackingFactory, raygunViewportFactory, raygunCoreWebVitalFactory */
var raygunFactory = function (window, $, undefined) {
var Raygun = {};
Raygun.Utilities = raygunUtilityFactory(window, Raygun);
Raygun.ErrorUtilities = raygunErrorUtilitiesFactory(window, Raygun);
Raygun.NetworkTracking = raygunNetworkTrackingFactory(window, Raygun);
Raygun.Breadcrumbs = raygunBreadcrumbsFactory(window, Raygun);
Raygun.CoreWebVitals = raygunCoreWebVitalFactory(window);
Raygun.Viewport = raygunViewportFactory(window, document, Raygun);
// Constants
var ProviderStates = {
LOADING: 0,
READY: 1,
};
var _userKey = 'raygun4js-userid';
// State variables
var _traceKit = TraceKit,
_raygun = window.Raygun,
_debugMode = false,
_ignoreAjaxAbort = false,
_ignoreAjaxError = false,
_enableOfflineSave = false,
_ignore3rdPartyErrors = false,
_disableAnonymousUserTracking = false,
_disableErrorTracking = false,
_disablePulse = true,
_wrapAsynchronousCallbacks = false,
_automaticPerformanceCustomTimings = false,
_trackCoreWebVitals = true,
_trackViewportDimensions = true,
_customData = {},
_tags = [],
_user,
_version,
_filteredKeys,
_whitelistedScriptDomains = [],
_beforeSendCallback,
_beforeSendRumCallback,
_groupingKeyCallback,
_beforeXHRCallback,
_afterSendCallback,
_excludedHostnames = null,
_excludedUserAgents = null,
_filterScope = 'customData',
_rum = null,
_breadcrumbs = new Raygun.Breadcrumbs(),
_pulseMaxVirtualPageDuration = null,
_pulseIgnoreUrlCasing = true,
_providerState = ProviderStates.LOADING,
_loadedFrom,
_processExceptionQueue = [],
_trackEventQueue = [],
_pulseCustomLoadTimeEnabled = null,
$document,
_captureUnhandledRejections = true,
_setCookieAsSecure = false,
_clientIp,
_captureMissingRequests = false,
detachPromiseRejectionFunction,
_customEndpointSet = false;
var rand = Math.random();
var _publicRaygunFunctions = {
Rand: rand,
Options: {},
noConflict: function () {
// Because _raygun potentially gets set before other code sets window.Raygun
// this will potentially overwrite the new Raygun object with undefined
// Not really much point in restoring undefined so just don't do that
if (_raygun) {
window.Raygun = _raygun;
}
return Raygun;
},
constructNewRaygun: function () {
var rgInstance = raygunFactory(window, window.jQuery);
return rgInstance;
},
init: function (key, options, customdata) {
_traceKit.remoteFetching = false;
Raygun.Options._raygunApiUrl = 'https://api.raygun.io';
this.Options._raygunApiKey = key;
if (customdata) {
_customData = customdata;
}
if ($) {
$document = $(document);
}
if (options) {
_ignoreAjaxAbort = options.ignoreAjaxAbort || false;
_ignoreAjaxError = options.ignoreAjaxError || false;
_disableAnonymousUserTracking = options.disableAnonymousUserTracking || false;
_disableErrorTracking = options.disableErrorTracking || false;
_disablePulse = options.disablePulse === undefined ? true : options.disablePulse;
_excludedHostnames = options.excludedHostnames || false;
_excludedUserAgents = options.excludedUserAgents || false;
_pulseMaxVirtualPageDuration = options.pulseMaxVirtualPageDuration || null;
_pulseIgnoreUrlCasing = options.pulseIgnoreUrlCasing || false;
_pulseCustomLoadTimeEnabled = options.pulseCustomLoadTimeEnabled || false;
_setCookieAsSecure = options.setCookieAsSecure || false;
_captureMissingRequests = options.captureMissingRequests || false;
_automaticPerformanceCustomTimings = options.automaticPerformanceCustomTimings || false;
_trackCoreWebVitals = options.trackCoreWebVitals === undefined ? true : options.trackCoreWebVitals;
_trackViewportDimensions = options.trackViewportDimensions === undefined ? true : options.trackViewportDimensions;
if (options.apiUrl) {
this.Options._raygunApiUrl = options.apiUrl;
this.Options._customEndpointSet = true;
}
if (typeof options.wrapAsynchronousCallbacks !== 'undefined') {
_wrapAsynchronousCallbacks = options.wrapAsynchronousCallbacks;
}
if (typeof options.captureUnhandledRejections !== 'undefined') {
_captureUnhandledRejections = options.captureUnhandledRejections;
}
if (options.debugMode) {
_debugMode = options.debugMode;
}
this.Options._debugMode = _debugMode;
if (options.ignore3rdPartyErrors) {
_ignore3rdPartyErrors = true;
}
if (options.apiEndpoint) {
this.Options._raygunApiUrl = options.apiEndpoint;
this.Options._customEndpointSet = true;
}
if (options.from) {
_loadedFrom = options.from;
}
if (options.clientIp) {
_clientIp = options.clientIp;
}
}
ensureUser();
return Raygun;
},
withCustomData: function (customdata) {
_customData = customdata;
return Raygun;
},
withTags: function (tags) {
_tags = tags;
if (_rum !== undefined && _rum !== null) {
_rum.withTags(tags);
}
return Raygun;
},
attach: function () {
if (!Raygun.Utilities.isApiKeyConfigured() || _disableErrorTracking) {
return Raygun;
}
if (window.RaygunObject && window[window.RaygunObject] && window[window.RaygunObject].q) {
window.onerror = null;
}
if (_captureUnhandledRejections) {
attachPromiseRejectionHandler();
}
// Attach React Native's handler in Release mode
if (Raygun.Utilities.isReactNative()) {
if (__DEV__ !== true && window.ErrorUtils && window.ErrorUtils.setGlobalHandler) {
window.ErrorUtils.setGlobalHandler(function (error, fatal) {
// Calling the defaultReactNativeGlobalHandler in release mode instantly closes the application
// If an exception is currently being sent it will be lost, this sets our own afterSendCallback
// to notify us when the error is done sending so we can call the default handler
var originalAfterSendCallback = _afterSendCallback;
_afterSendCallback = function () {
if (typeof originalAfterSendCallback === 'function') {
originalAfterSendCallback();
}
Raygun.Utilities.defaultReactNativeGlobalHandler(error, fatal);
_afterSendCallback = originalAfterSendCallback;
};
TraceKit.report(error);
});
}
}
_traceKit.report.subscribe(processException);
if (_wrapAsynchronousCallbacks) {
_traceKit.extendToAsynchronousCallbacks();
}
if ($document && $document.ajaxError && !_ignoreAjaxError) {
$document.ajaxError(processJQueryAjaxError);
}
return Raygun;
},
detach: function () {
_traceKit.report.unsubscribe(processException);
if ($document) {
$document.unbind('ajaxError', processJQueryAjaxError);
}
if (_captureUnhandledRejections) {
detachPromiseRejectionHandler();
}
return Raygun;
},
send: function (ex, customData, tags) {
if (_disableErrorTracking) {
Raygun.Utilities.log('Error not sent due to disabled error tracking');
return Raygun;
}
try {
processException(
_traceKit.computeStackTrace(ex),
{
customData:
typeof _customData === 'function'
? Raygun.Utilities.merge(_customData(), customData)
: Raygun.Utilities.merge(_customData, customData),
tags:
typeof _tags === 'function'
? Raygun.Utilities.mergeArray(_tags(), tags)
: Raygun.Utilities.mergeArray(_tags, tags),
},
true,
ex
);
} catch (traceKitException) {
if (ex !== traceKitException) {
throw traceKitException;
}
}
return Raygun;
},
setUser: function (user, isAnonymous, email, fullName, firstName, uuid) {
_user = {
Identifier: user,
};
if (typeof isAnonymous === 'boolean') {
_user['IsAnonymous'] = isAnonymous;
}
if (email) {
_user['Email'] = email;
}
if (fullName) {
_user['FullName'] = fullName;
}
if (firstName) {
_user['FirstName'] = firstName;
}
if (uuid) {
_user['UUID'] = uuid;
}
if (_rum !== undefined && _rum !== null) {
_rum.setUser(_user);
}
return Raygun;
},
resetAnonymousUser: function () {
clearStorage();
},
setVersion: function (version) {
_version = version;
return Raygun;
},
saveIfOffline: function (enableOffline) {
if (typeof enableOffline !== 'undefined' && typeof enableOffline === 'boolean') {
_enableOfflineSave = enableOffline;
}
return Raygun;
},
filterSensitiveData: function (filteredKeys) {
_filteredKeys = filteredKeys;
return Raygun;
},
setFilterScope: function (scope) {
if (scope === 'customData' || scope === 'all') {
_filterScope = scope;
}
return Raygun;
},
whitelistCrossOriginDomains: function (whitelist) {
_whitelistedScriptDomains = whitelist;
return Raygun;
},
onBeforeSend: function (callback) {
_beforeSendCallback = callback;
return Raygun;
},
onBeforeSendRum: function (callback) {
_beforeSendRumCallback = callback;
return Raygun;
},
groupingKey: function (callback) {
_groupingKeyCallback = callback;
return Raygun;
},
onBeforeXHR: function (callback) {
_beforeXHRCallback = callback;
return Raygun;
},
onAfterSend: function (callback) {
_afterSendCallback = callback;
return Raygun;
},
// Public Pulse functions
endSession: function () {
if (Raygun.RealUserMonitoring !== undefined && _rum) {
_rum.endSession();
}
},
trackEvent: function (type, options) {
if (_providerState !== ProviderStates.READY) {
_trackEventQueue.push({ type: type, options: options });
return;
}
if (Raygun.RealUserMonitoring !== undefined && _rum) {
var parentResource = _rum.parentResource;
if (type === 'pageView' && options.path) {
_rum.virtualPageLoaded(options.path);
} else if (type === 'customTiming') {
_rum.trackCustomTiming(options.name, options.duration, options.offset || 0, parentResource);
} else if (type === 'customTimings' && options.timings) {
_rum.sendCustomTimings(options.timings, parentResource);
}
}
},
setClientIp: function (ip) {
_clientIp = ip;
},
captureMissingRequests: function (val) {
if (Raygun.RealUserMonitoring !== undefined && _rum) {
_rum.captureMissingRequests(val);
}
},
recordBreadcrumb: function () {
_breadcrumbs.recordBreadcrumb.apply(_breadcrumbs, arguments);
},
enableAutoBreadcrumbs: function (type) {
if (type) {
_breadcrumbs['enableAutoBreadcrumbs' + type]();
} else {
_breadcrumbs.enableAutoBreadcrumbs();
}
},
disableAutoBreadcrumbs: function (type) {
if (type) {
_breadcrumbs['disableAutoBreadcrumbs' + type]();
} else {
_breadcrumbs.disableAutoBreadcrumbs();
}
},
setBreadcrumbOption: function (option, value) {
_breadcrumbs.setOption(option, value);
},
setBreadcrumbs: function (breadcrumbs) {
_breadcrumbs = breadcrumbs;
},
getBreadcrumbs: function () {
return _breadcrumbs.all();
},
};
Raygun = Raygun.Utilities.mergeMutate(Raygun, _publicRaygunFunctions);
function callAfterSend(response) {
if (typeof _afterSendCallback === 'function') {
_afterSendCallback(response);
}
}
function ensureUser() {
if (!_user && !_disableAnonymousUserTracking) {
getFromStorage(setUserComplete);
} else {
bootRaygun();
}
}
function setUserComplete(userId) {
var userIdentifier = "Unknown";
if (!userId) {
userIdentifier = Raygun.Utilities.getUuid();
saveToStorage(userIdentifier);
} else {
userIdentifier = userId;
}
Raygun.setUser(userIdentifier, true, null, null, null, userIdentifier);
bootRaygun();
}
// Callback for `unhandledrejection` event.
function promiseRejectionHandler(event) {
var error = event.reason;
if (!error && event.detail && event.detail.reason) {
error = event.detail.reason;
}
if (!(error instanceof Error) && event.reason && event.reason.error) {
error = event.reason.error;
}
if (!error) {
error = new Error('Unhandled promise rejection');
// Clear the stacktrace, as we don't want the error to appear to come from raygun4js
error.stack = null;
}
_publicRaygunFunctions.send(error, null, ['UnhandledPromiseRejection']);
}
// Install global promise rejection handler.
function attachPromiseRejectionHandler() {
detachPromiseRejectionFunction = Raygun.Utilities.addEventHandler(
window,
'unhandledrejection',
promiseRejectionHandler
);
}
// Uninstall global promise rejection handler.
function detachPromiseRejectionHandler() {
if (detachPromiseRejectionFunction) {
detachPromiseRejectionFunction();
}
}
// The final initializing logic is provided as a callback due to async storage methods for user data in React Native
// The common case executes it immediately due to that data being provided by the cookie synchronously
// The case when Customers is enabled calls this function when the code sets the user data
function bootRaygun() {
if (_providerState === ProviderStates.READY) {
return;
}
_providerState = ProviderStates.READY;
if (Raygun.RealUserMonitoring !== undefined && !_disablePulse) {
var startRum = function () {
_rum = new Raygun.RealUserMonitoring(
Raygun.Options._raygunApiKey,
Raygun.Options._raygunApiUrl,
makePostCorsRequest,
_user,
_version,
_tags,
_excludedHostnames,
_excludedUserAgents,
_debugMode,
_pulseMaxVirtualPageDuration,
_pulseIgnoreUrlCasing,
_pulseCustomLoadTimeEnabled,
_beforeSendRumCallback,
_setCookieAsSecure,
_captureMissingRequests,
_automaticPerformanceCustomTimings,
_trackCoreWebVitals,
_trackViewportDimensions
);
_rum.attach();
};
if (!Raygun.Utilities.isReactNative()) {
if (_loadedFrom === 'onLoad') {
startRum();
} else {
if (window.addEventListener) {
window.addEventListener('load', startRum);
} else {
window.attachEvent('onload', startRum);
}
}
} else {
Raygun.Utilities.log('Not enabling RUM because Raygun4JS has detected a React Native environment, see #310 on Github');
}
}
retriggerDelayedCommands();
sendSavedErrors();
}
// We need to delay handled/unhandled send() and trackEvent() calls until the user data callback has returned
function retriggerDelayedCommands() {
var i;
for (i = 0; i < _processExceptionQueue.length; i++) {
processException(
_processExceptionQueue[i].stackTrace,
_processExceptionQueue[i].options,
_processExceptionQueue[i].userTriggered,
_processExceptionQueue[i].error
);
}
_processExceptionQueue = [];
for (i = 0; i < _trackEventQueue.length; i++) {
_publicRaygunFunctions.trackEvent(_trackEventQueue[i].type, _trackEventQueue[i].options);
}
_trackEventQueue = [];
}
function offlineSave(url, data) {
var dateTime = new Date().toJSON();
try {
var key =
'raygunjs+' +
Raygun.Options._raygunApiKey +
'=' +
dateTime +
'=' +
Raygun.Utilities.getRandomInt();
if (typeof localStorage[key] === 'undefined') {
localStorage[key] = JSON.stringify({ url: url, data: data });
}
} catch (e) {
Raygun.Utilities.log('Raygun4JS: LocalStorage full, cannot save exception');
}
}
function sendSavedErrors() {
if (Raygun.Utilities.localStorageAvailable()) {
for (var key in localStorage) {
if (key.indexOf('raygunjs+' + Raygun.Options._raygunApiKey) > -1) {
try {
var payload = JSON.parse(localStorage[key]);
// If the url contains 'raygun.com', replace it with 'raygun.io', but only if not custom set already (proxy, testing, etc)
if (!_customEndpointSet && payload.url.includes('raygun.com')) {
payload.url = payload.url.replace('raygun.com', 'raygun.io');
}
makePostCorsRequest(payload.url, payload.data);
} catch (e) {
Raygun.Utilities.log('Raygun4JS: Invalid JSON object in LocalStorage');
}
try {
localStorage.removeItem(key);
} catch (e) {
Raygun.Utilities.log('Raygun4JS: Unable to remove error');
}
}
}
}
}
function filterValue(key, value) {
if (_filteredKeys) {
for (var i = 0; i < _filteredKeys.length; i++) {
if (typeof _filteredKeys[i] === 'object' && typeof _filteredKeys[i].exec === 'function') {
var executedFilter = _filteredKeys[i].exec(key);
if (executedFilter !== null && executedFilter !== undefined) {
return '[removed by filter]';
}
} else if (_filteredKeys[i] === key) {
return '[removed by filter]';
}
}
}
return value;
}
function filterObject(reference, parentKey) {
if (reference == null) {
return reference;
}
if (Object.prototype.toString.call(reference) !== '[object Object]') {
return reference;
}
var filteredObject = {};
for (var propertyName in reference) {
var propertyValue = reference[propertyName];
if (Object.prototype.toString.call(propertyValue) === '[object Object]') {
if (parentKey !== 'Details' || propertyName !== 'Client') {
filteredObject[propertyName] = filterObject(
filterValue(propertyName, propertyValue),
propertyName
);
} else {
filteredObject[propertyName] = propertyValue;
}
} else if (Object.prototype.toString.call(propertyValue) !== '[object Function]') {
if (typeof parentKey !== 'undefined') {
filteredObject[propertyName] = filterValue(propertyName, propertyValue);
} else if (propertyName === 'OccurredOn') {
filteredObject[propertyName] = propertyValue;
}
}
}
return filteredObject;
}
function processJQueryAjaxError(event, jqXHR, ajaxSettings, thrownError) {
var message =
'AJAX Error: ' +
(jqXHR.statusText || 'unknown') +
' ' +
(ajaxSettings.type || 'unknown') +
' ' +
(Raygun.Utilities.truncateURL(ajaxSettings.url) || 'unknown');
// ignore ajax abort if set in the options
if (_ignoreAjaxAbort) {
if (jqXHR.status === 0 || !jqXHR.getAllResponseHeaders()) {
return;
}
}
Raygun.send(thrownError || event.type, {
status: jqXHR.status,
statusText: jqXHR.statusText,
type: ajaxSettings.type,
url: ajaxSettings.url,
ajaxErrorMessage: message,
contentType: ajaxSettings.contentType,
requestData:
ajaxSettings.data && ajaxSettings.data.slice
? ajaxSettings.data.slice(0, 10240)
: undefined,
responseData:
jqXHR.responseText && jqXHR.responseText.slice
? jqXHR.responseText.slice(0, 10240)
: undefined,
activeTarget:
event.target &&
event.target.activeElement &&
event.target.activeElement.outerHTML &&
event.target.activeElement.outerHTML.slice
? event.target.activeElement.outerHTML.slice(0, 10240)
: undefined,
});
}
function processException(stackTrace, options, userTriggered, error) {
if (_providerState !== ProviderStates.READY) {
_processExceptionQueue.push({
stackTrace: stackTrace,
options: options,
userTriggered: userTriggered,
error: error,
});
return;
}
var scriptError = 'Script error';
var stack = [],
qs = {};
if (_ignore3rdPartyErrors && shouldDiscardThirdPartyError(stackTrace, options)) {
return;
}
if (_excludedHostnames instanceof Array) {
for (var hostIndex in _excludedHostnames) {
if (_excludedHostnames.hasOwnProperty(hostIndex)) {
if (
window.location.hostname &&
window.location.hostname.match(_excludedHostnames[hostIndex])
) {
Raygun.Utilities.log(
'Raygun4JS: cancelling send as error originates from an excluded hostname'
);