UNPKG

@honeybadger-io/js

Version:

Universal (Browser & Node) JavaScript error notifier for Honeybadger.io

1,326 lines (1,269 loc) 142 kB
'use strict'; var require$$0$2 = require('os'); var require$$1$1 = require('domain'); var require$$1 = require('fs'); var require$$2 = require('path'); var require$$3 = require('util'); var require$$0$3 = require('url'); var require$$3$1 = require('http'); var require$$4 = require('https'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$2); var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1); var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1); var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2); var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3); var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$3); var require$$3__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$3$1); var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4); var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getAugmentedNamespace(n) { var f = n.default; if (typeof f == "function") { var a = function () { return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var server$1 = {}; var src = {}; var events = {}; var util$1 = {}; var UNKNOWN_FUNCTION = '<unknown>'; /** * This parses the different stack traces and puts them into one format * This borrows heavily from TraceKit (https://github.com/csnover/TraceKit) */ function parse(stackString) { var lines = stackString.split('\n'); return lines.reduce(function (stack, line) { var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line); if (parseResult) { stack.push(parseResult); } return stack; }, []); } var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i; var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/; function parseChrome(line) { var parts = chromeRe.exec(line); if (!parts) { return null; } var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line var submatch = chromeEvalRe.exec(parts[2]); if (isEval && submatch != null) { // throw out eval line/column and use top-most line/column number parts[2] = submatch[1]; // url parts[3] = submatch[2]; // line parts[4] = submatch[3]; // column } return { file: !isNative ? parts[2] : null, methodName: parts[1] || UNKNOWN_FUNCTION, arguments: isNative ? [parts[2]] : [], lineNumber: parts[3] ? +parts[3] : null, column: parts[4] ? +parts[4] : null }; } var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i; function parseWinjs(line) { var parts = winjsRe.exec(line); if (!parts) { return null; } return { file: parts[2], methodName: parts[1] || UNKNOWN_FUNCTION, arguments: [], lineNumber: +parts[3], column: parts[4] ? +parts[4] : null }; } var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i; var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i; function parseGecko(line) { var parts = geckoRe.exec(line); if (!parts) { return null; } var isEval = parts[3] && parts[3].indexOf(' > eval') > -1; var submatch = geckoEvalRe.exec(parts[3]); if (isEval && submatch != null) { // throw out eval line/column and use top-most line number parts[3] = submatch[1]; parts[4] = submatch[2]; parts[5] = null; // no column when eval } return { file: parts[3], methodName: parts[1] || UNKNOWN_FUNCTION, arguments: parts[2] ? parts[2].split(',') : [], lineNumber: parts[4] ? +parts[4] : null, column: parts[5] ? +parts[5] : null }; } var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i; function parseJSC(line) { var parts = javaScriptCoreRe.exec(line); if (!parts) { return null; } return { file: parts[3], methodName: parts[1] || UNKNOWN_FUNCTION, arguments: [], lineNumber: +parts[4], column: parts[5] ? +parts[5] : null }; } var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i; function parseNode(line) { var parts = nodeRe.exec(line); if (!parts) { return null; } return { file: parts[2], methodName: parts[1] || UNKNOWN_FUNCTION, arguments: [], lineNumber: +parts[3], column: parts[4] ? +parts[4] : null }; } var stackTraceParser_esm = /*#__PURE__*/Object.freeze({ __proto__: null, parse: parse }); var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm); (function (exports) { var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); 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.runBeforeNotifyHandlers = exports.getSourceForBacktrace = exports.getCauses = exports.calculateBacktraceShift = exports.DEFAULT_BACKTRACE_SHIFT = exports.makeBacktrace = exports.objectIsExtensible = exports.objectIsEmpty = exports.mergeNotice = exports.merge = void 0; /* eslint-disable prefer-rest-params */ var stackTraceParser = __importStar(require$$0$1); function merge(obj1, obj2) { var result = {}; for (var k in obj1) { result[k] = obj1[k]; } for (var k in obj2) { result[k] = obj2[k]; } return result; } exports.merge = merge; function mergeNotice(notice1, notice2) { var result = merge(notice1, notice2); if (notice1.context && notice2.context) { result.context = merge(notice1.context, notice2.context); } return result; } exports.mergeNotice = mergeNotice; function objectIsEmpty(obj) { for (var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) { return false; } } return true; } exports.objectIsEmpty = objectIsEmpty; function objectIsExtensible(obj) { if (typeof Object.isExtensible !== 'function') { return true; } return Object.isExtensible(obj); } exports.objectIsExtensible = objectIsExtensible; function makeBacktrace(stack, filterHbSourceCode, logger) { if (filterHbSourceCode === void 0) { filterHbSourceCode = false; } if (logger === void 0) { logger = console; } if (!stack) { return []; } try { var backtrace = stackTraceParser .parse(stack) .map(function (line) { return { file: line.file, method: line.methodName, number: line.lineNumber, column: line.column }; }); if (filterHbSourceCode) { backtrace.splice(0, calculateBacktraceShift(backtrace)); } return backtrace; } catch (err) { logger.debug(err); return []; } } exports.makeBacktrace = makeBacktrace; function isFrameFromHbSourceCode(frame) { var hasHbFile = false; var hasHbMethod = false; if (frame.file) { hasHbFile = frame.file.toLowerCase().indexOf('@honeybadger-io') > -1; } if (frame.method) { hasHbMethod = frame.method.toLowerCase().indexOf('@honeybadger-io') > -1; } return hasHbFile || hasHbMethod; } exports.DEFAULT_BACKTRACE_SHIFT = 3; /** * If {@link generateStackTrace} is used, we want to exclude frames that come from * Honeybadger's source code. * * Logic: * - For each frame, increment the shift if source code is from Honeybadger * - If a frame from an <anonymous> file is encountered increment the shift ONLY if between Honeybadger source code * (i.e. previous and next frames are from Honeybadger) * - Exit when frame encountered is not from Honeybadger source code * * Note: this will not always work, especially in browser versions where code * is minified, uglified and bundled. * For those cases we default to 3: * - generateStackTrace * - makeNotice * - notify */ function calculateBacktraceShift(backtrace) { var shift = 0; for (var i = 0; i < backtrace.length; i++) { var frame = backtrace[i]; if (isFrameFromHbSourceCode(frame)) { shift++; continue; } if (!frame.file || frame.file === '<anonymous>') { var nextFrame = backtrace[i + 1]; if (nextFrame && isFrameFromHbSourceCode(nextFrame)) { shift++; continue; } } break; } return shift || exports.DEFAULT_BACKTRACE_SHIFT; } exports.calculateBacktraceShift = calculateBacktraceShift; function getCauses(notice, logger) { if (notice.cause) { var causes = []; var cause = notice; // @ts-ignore this throws an error if tsconfig.json has strict: true while (causes.length < 3 && (cause = cause.cause)) { causes.push({ class: cause.name, message: cause.message, backtrace: typeof cause.stack == 'string' ? makeBacktrace(cause.stack, false, logger) : null }); } return causes; } return []; } exports.getCauses = getCauses; function getSourceForBacktrace(backtrace, getSourceFileHandler) { return __awaiter(this, void 0, void 0, function () { var result, index, trace, fileContent; return __generator(this, function (_a) { switch (_a.label) { case 0: result = []; if (!getSourceFileHandler || !backtrace || !backtrace.length) { return [2 /*return*/, result]; } index = 0; _a.label = 1; case 1: if (!backtrace.length) return [3 /*break*/, 3]; trace = backtrace.splice(0)[index]; return [4 /*yield*/, getSourceFileHandler(trace.file)]; case 2: fileContent = _a.sent(); result[index] = getSourceCodeSnippet(fileContent, trace.number, trace.column, 2); index++; return [3 /*break*/, 1]; case 3: return [2 /*return*/, result]; } }); }); } exports.getSourceForBacktrace = getSourceForBacktrace; function runBeforeNotifyHandlers(notice, handlers) { var results = []; var result = true; for (var i = 0, len = handlers.length; i < len; i++) { var handler = handlers[i]; var handlerResult = handler(notice); if (handlerResult === false) { result = false; } results.push(handlerResult); } return { results: results, result: result }; } exports.runBeforeNotifyHandlers = runBeforeNotifyHandlers; function runAfterNotifyHandlers(notice, handlers, error) { if (notice && notice.afterNotify) { notice.afterNotify(error, notice); } for (var i = 0, len = handlers.length; i < len; i++) { handlers[i](error, notice); } return true; } exports.runAfterNotifyHandlers = runAfterNotifyHandlers; // Returns a new object with properties from other object. function shallowClone(obj) { if (typeof (obj) !== 'object' || obj === null) { return {}; } var result = {}; for (var k in obj) { result[k] = obj[k]; } return result; } exports.shallowClone = shallowClone; function sanitize(obj, maxDepth) { if (maxDepth === void 0) { maxDepth = 8; } var seenObjects = []; function seen(obj) { if (!obj || typeof (obj) !== 'object') { return false; } for (var i = 0; i < seenObjects.length; i++) { var value = seenObjects[i]; if (value === obj) { return true; } } seenObjects.push(obj); return false; } function canSerialize(obj) { var typeOfObj = typeof obj; // Functions are TMI if (/function/.test(typeOfObj)) { // Let special toJSON method pass as it's used by JSON.stringify (#722) return obj.name === 'toJSON'; } // Symbols can't convert to strings. if (/symbol/.test(typeOfObj)) { return false; } if (obj === null) { return false; } // No prototype, likely created with `Object.create(null)`. if (typeof obj === 'object' && typeof obj.hasOwnProperty === 'undefined') { return false; } return true; } function serialize(obj, depth) { if (depth === void 0) { depth = 0; } if (depth >= maxDepth) { return '[DEPTH]'; } // Inspect invalid types if (!canSerialize(obj)) { return Object.prototype.toString.call(obj); } // Halt circular references if (seen(obj)) { return '[RECURSION]'; } // Serialize inside arrays if (Array.isArray(obj)) { return obj.map(function (o) { return safeSerialize(o, depth + 1); }); } // Serialize inside objects if (typeof (obj) === 'object') { var ret = {}; for (var k in obj) { var v = obj[k]; if (Object.prototype.hasOwnProperty.call(obj, k) && (k != null) && (v != null)) { ret[k] = safeSerialize(v, depth + 1); } } return ret; } // Return everything else untouched return obj; } function safeSerialize(obj, depth) { if (depth === void 0) { depth = 0; } try { return serialize(obj, depth); } catch (e) { return "[ERROR] ".concat(e); } } return safeSerialize(obj); } exports.sanitize = sanitize; function logger(client) { var log = function (method) { return function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (method === 'debug') { if (!client.config.debug) { return; } // Log at default level so that you don't need to also enable verbose // logging in Chrome. method = 'log'; } args.unshift('[Honeybadger]'); (_a = client.config.logger)[method].apply(_a, args); }; }; return { log: log('log'), info: log('info'), debug: log('debug'), warn: log('warn'), error: log('error') }; } exports.logger = logger; /** * Converts any object into a notice object (which at minimum has the same * properties as Error, but supports additional Honeybadger properties.) */ function makeNotice(thing) { var notice; if (!thing) { notice = {}; } else if (isErrorObject(thing)) { var e = thing; notice = merge(thing, { name: e.name, message: e.message, stack: e.stack, cause: e.cause }); } else if (typeof thing === 'object') { notice = shallowClone(thing); } else { var m = String(thing); notice = { message: m }; } return notice; } exports.makeNotice = makeNotice; function isErrorObject(thing) { return thing instanceof Error || Object.prototype.toString.call(thing) === '[object Error]'; // Important for cross-realm objects } exports.isErrorObject = isErrorObject; /** * Instrument an existing function inside an object (usually global). * @param {!Object} object * @param {!String} name * @param {!Function} replacement */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function instrument(object, name, replacement) { if (!object || !name || !replacement || !(name in object)) { return; } try { var original = object[name]; while (original && original.__hb_original) { original = original.__hb_original; } object[name] = replacement(original); object[name].__hb_original = original; } catch (_e) { // Ignores errors where "original" is a restricted object (see #1001) // Uncaught Error: Permission denied to access property "__hb_original" // Also ignores: // Error: TypeError: Cannot set property onunhandledrejection of [object Object] which has only a getter // User-Agent: Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.1 Chrome/79.0.3945.136 Mobile Safari/537.36 } } exports.instrument = instrument; var _consoleAlreadyInstrumented = false; var listeners = []; // eslint-disable-next-line @typescript-eslint/no-explicit-any function instrumentConsole(_window, handler) { if (!_window || !_window.console || !handler) { return; } listeners.push(handler); if (_consoleAlreadyInstrumented) { return; } _consoleAlreadyInstrumented = true; ['debug', 'info', 'warn', 'error', 'log'].forEach(function (level) { instrument(_window.console, level, function hbLogger(original) { return function () { var args = Array.prototype.slice.call(arguments); listeners.forEach(function (listener) { try { listener(level, args); } catch (_e) { // ignore // should never reach here because instrument method already wraps with try/catch block } }); if (typeof original === 'function') { Function.prototype.apply.call(original, _window.console, arguments); } }; }); }); } exports.instrumentConsole = instrumentConsole; function endpoint(base, path) { var endpoint = base.trim().replace(/\/$/, ''); path = path.trim().replace(/(^\/|\/$)/g, ''); return "".concat(endpoint, "/").concat(path); } exports.endpoint = endpoint; function generateStackTrace() { try { throw new Error(''); } catch (e) { if (e.stack) { return e.stack; } } var maxStackSize = 10; var stack = []; var curr = arguments.callee; while (curr && stack.length < maxStackSize) { if (/function(?:\s+([\w$]+))+\s*\(/.test(curr.toString())) { stack.push(RegExp.$1 || '<anonymous>'); } else { stack.push('<anonymous>'); } try { curr = curr.caller; } catch (e) { break; } } return stack.join('\n'); } exports.generateStackTrace = generateStackTrace; function filter(obj, filters) { if (!is('Object', obj)) { return; } if (!is('Array', filters)) { filters = []; } var seen = []; function filter(obj) { var k, newObj; if (is('Object', obj) || is('Array', obj)) { if (seen.indexOf(obj) !== -1) { return '[CIRCULAR DATA STRUCTURE]'; } seen.push(obj); } if (is('Object', obj)) { newObj = {}; for (k in obj) { if (filterMatch(k, filters)) { newObj[k] = '[FILTERED]'; } else { newObj[k] = filter(obj[k]); } } return newObj; } if (is('Array', obj)) { return obj.map(function (v) { return filter(v); }); } if (is('Function', obj)) { return '[FUNC]'; } return obj; } return filter(obj); } exports.filter = filter; function filterMatch(key, filters) { for (var i = 0; i < filters.length; i++) { if (key.toLowerCase().indexOf(filters[i].toLowerCase()) !== -1) { return true; } } return false; } function is(type, obj) { var klass = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && klass === type; } function filterUrl(url, filters) { if (!filters) { return url; } if (typeof url !== 'string') { return url; } var query = url.split(/\?/, 2)[1]; if (!query) { return url; } var result = url; query.split(/[&]\s?/).forEach(function (pair) { var _a = pair.split('=', 2), key = _a[0], value = _a[1]; if (filterMatch(key, filters)) { result = result.replace("".concat(key, "=").concat(value), "".concat(key, "=[FILTERED]")); } }); return result; } exports.filterUrl = filterUrl; function formatCGIData(vars, prefix) { if (prefix === void 0) { prefix = ''; } var formattedVars = {}; Object.keys(vars).forEach(function (key) { var formattedKey = prefix + key.replace(/\W/g, '_').toUpperCase(); formattedVars[formattedKey] = vars[key]; }); return formattedVars; } exports.formatCGIData = formatCGIData; function clone(obj) { return JSON.parse(JSON.stringify(obj)); } exports.clone = clone; var THRESHOLD_COLUMN_NUMBER = 10000; var THRESHOLD_LINE_LENGTH = 10000; var THRESHOLD_FILE_SIZE = 200000; // 200KB threshold function getThresholdExceededSnippet(lineNumber) { var _a; return _a = {}, _a[lineNumber] = 'SOURCE_SIZE_TOO_LARGE', _a; } function getSourceCodeSnippet(fileData, lineNumber, columnNumber, sourceRadius) { if (sourceRadius === void 0) { sourceRadius = 2; } if (!fileData) { return null; } // If column number is provided and very high, it's likely a bundled/minified file if (columnNumber && columnNumber > THRESHOLD_COLUMN_NUMBER) { return getThresholdExceededSnippet(lineNumber); } // If file is very large, it's likely bundled if (fileData.length > THRESHOLD_FILE_SIZE) { return getThresholdExceededSnippet(lineNumber); } var lines = fileData.split('\n'); // add one empty line because array index starts from 0, but error line number is counted from 1 lines.unshift(''); // Check if the target line is extremely long var targetLine = lines[lineNumber]; if (targetLine && targetLine.length > THRESHOLD_LINE_LENGTH) { return getThresholdExceededSnippet(lineNumber); } var start = lineNumber - sourceRadius; var end = lineNumber + sourceRadius; var result = {}; for (var i = start; i <= end; i++) { var line = lines[i]; if (typeof line === 'string') { result[i] = line; } } return result; } function isBrowserConfig(config) { return config.async !== undefined; } exports.isBrowserConfig = isBrowserConfig; /** globalThis has fairly good support. But just in case, lets check its defined. * @see {https://caniuse.com/?search=globalThis} */ function globalThisOrWindow() { if (typeof globalThis !== 'undefined') { return globalThis; } if (typeof self !== 'undefined') { return self; } return window; } exports.globalThisOrWindow = globalThisOrWindow; var _deprecatedMethodCalls = {}; /** * Logs a deprecation warning, every X calls to the method. */ function logDeprecatedMethod(logger, oldMethod, newMethod, callCountThreshold) { if (callCountThreshold === void 0) { callCountThreshold = 100; } var key = "".concat(oldMethod, "-").concat(newMethod); if (typeof _deprecatedMethodCalls[key] === 'undefined') { _deprecatedMethodCalls[key] = 0; } if (_deprecatedMethodCalls[key] % callCountThreshold !== 0) { _deprecatedMethodCalls[key]++; return; } var msg = "Deprecation warning: ".concat(oldMethod, " has been deprecated; please use ").concat(newMethod, " instead."); logger.warn(msg); _deprecatedMethodCalls[key]++; } exports.logDeprecatedMethod = logDeprecatedMethod; } (util$1)); Object.defineProperty(events, "__esModule", { value: true }); var util_1$8 = util$1; function default_1$3(_window) { if (_window === void 0) { _window = (0, util_1$8.globalThisOrWindow)(); } return { shouldReloadOnConfigure: false, load: function (client) { function sendEventsToInsights() { return client.config.eventsEnabled; } if (!sendEventsToInsights()) { return; } (0, util_1$8.instrumentConsole)(_window, function (level, args) { if (!sendEventsToInsights()) { return; } if (args.length === 0) { return; } var data = { severity: level, }; if (typeof args[0] === 'string') { data.message = args[0]; data.args = args.slice(1); } else { data.args = args; } client.event('log', data); }); } }; } events.default = default_1$3; var client$1 = {}; var store = {}; Object.defineProperty(store, "__esModule", { value: true }); store.GlobalStore = void 0; var util_1$7 = util$1; var GlobalStore = /** @class */ (function () { function GlobalStore(contents, breadcrumbsLimit) { this.contents = contents; this.breadcrumbsLimit = breadcrumbsLimit; } GlobalStore.create = function (contents, breadcrumbsLimit) { return new GlobalStore(contents, breadcrumbsLimit); }; GlobalStore.prototype.available = function () { return true; }; GlobalStore.prototype.getContents = function (key) { var value = key ? this.contents[key] : this.contents; return JSON.parse(JSON.stringify(value)); }; GlobalStore.prototype.setContext = function (context) { this.contents.context = (0, util_1$7.merge)(this.contents.context, context || {}); }; GlobalStore.prototype.addBreadcrumb = function (breadcrumb) { if (this.contents.breadcrumbs.length == this.breadcrumbsLimit) { this.contents.breadcrumbs.shift(); } this.contents.breadcrumbs.push(breadcrumb); }; GlobalStore.prototype.clear = function () { this.contents.context = {}; this.contents.breadcrumbs = []; }; GlobalStore.prototype.run = function (callback) { return callback(); }; return GlobalStore; }()); store.GlobalStore = GlobalStore; var throttled_events_logger = {}; class NdJson { static parse(data) { const lines = data.trim().split('\n'); return lines.map(line => JSON.parse(line)); } static stringify(data) { return data.map(item => JSON.stringify(item)).join('\n'); } } var module$1 = /*#__PURE__*/Object.freeze({ __proto__: null, NdJson: NdJson }); var require$$0 = /*@__PURE__*/getAugmentedNamespace(module$1); var defaults = {}; Object.defineProperty(defaults, "__esModule", { value: true }); defaults.CONFIG = void 0; defaults.CONFIG = { apiKey: null, endpoint: 'https://api.honeybadger.io', appEndpoint: 'https://app.honeybadger.io', environment: null, hostname: null, projectRoot: null, component: null, action: null, revision: null, reportData: null, breadcrumbsEnabled: true, // we could decide the value of eventsEnabled based on `env` and `developmentEnvironments` eventsEnabled: false, maxBreadcrumbs: 40, maxObjectDepth: 8, logger: console, developmentEnvironments: ['dev', 'development', 'test'], debug: false, tags: null, enableUncaught: true, enableUnhandledRejection: true, afterUncaught: function () { return true; }, filters: ['creditcard', 'password'], __plugins: [], }; var __assign$2 = (commonjsGlobal && commonjsGlobal.__assign) || function () { __assign$2 = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$2.apply(this, arguments); }; var __awaiter$4 = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator$4 = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(throttled_events_logger, "__esModule", { value: true }); throttled_events_logger.ThrottledEventsLogger = void 0; var json_nd_1 = require$$0; var util_1$6 = util$1; var defaults_1$1 = defaults; var ThrottledEventsLogger = /** @class */ (function () { function ThrottledEventsLogger(config, transport) { this.config = config; this.transport = transport; this.queue = []; this.isProcessing = false; this.config = __assign$2(__assign$2({}, defaults_1$1.CONFIG), config); this.logger = this.originalLogger(); } ThrottledEventsLogger.prototype.configure = function (opts) { for (var k in opts) { this.config[k] = opts[k]; } }; ThrottledEventsLogger.prototype.log = function (payload) { this.queue.push(payload); if (!this.isProcessing) { this.processQueue(); } }; ThrottledEventsLogger.prototype.flushAsync = function () { this.logger.debug('[Honeybadger] Flushing events'); return this.send(); }; ThrottledEventsLogger.prototype.processQueue = function () { var _this = this; if (this.queue.length === 0 || this.isProcessing) { return; } this.isProcessing = true; this.send() .then(function () { setTimeout(function () { _this.isProcessing = false; _this.processQueue(); }, 50); }) .catch(function (error) { _this.logger.error('[Honeybadger] Error making HTTP request:', error); // Continue processing the queue even if there's an error setTimeout(function () { _this.isProcessing = false; _this.processQueue(); }, 50); }); }; ThrottledEventsLogger.prototype.send = function () { return __awaiter$4(this, void 0, void 0, function () { var eventsData, data; return __generator$4(this, function (_a) { if (this.queue.length === 0) { return [2 /*return*/]; } eventsData = this.queue.slice(); this.queue = []; data = json_nd_1.NdJson.stringify(eventsData); return [2 /*return*/, this.makeHttpRequest(data)]; }); }); }; ThrottledEventsLogger.prototype.makeHttpRequest = function (data) { return __awaiter$4(this, void 0, void 0, function () { var _this = this; return __generator$4(this, function (_a) { return [2 /*return*/, this.transport .send({ headers: { 'X-API-Key': this.config.apiKey, 'Content-Type': 'application/json', }, method: 'POST', endpoint: (0, util_1$6.endpoint)(this.config.endpoint, '/v1/events'), maxObjectDepth: this.config.maxObjectDepth, logger: this.logger, }, data) .then(function () { if (_this.config.debug) { _this.logger.debug('[Honeybadger] Events sent successfully'); } }) .catch(function (err) { _this.logger.error("[Honeybadger] Error sending events: ".concat(err.message)); })]; }); }); }; /** * todo: improve this * * The EventsLogger overrides the console methods to enable automatic instrumentation * of console logs to the Honeybadger API. * So if we want to log something in here we need to use the original methods. */ ThrottledEventsLogger.prototype.originalLogger = function () { var _a, _b, _c, _d, _e; return { // eslint-disable-next-line @typescript-eslint/no-explicit-any log: (_a = console.log.__hb_original) !== null && _a !== void 0 ? _a : console.log, // eslint-disable-next-line @typescript-eslint/no-explicit-any info: (_b = console.info.__hb_original) !== null && _b !== void 0 ? _b : console.info, // eslint-disable-next-line @typescript-eslint/no-explicit-any debug: (_c = console.debug.__hb_original) !== null && _c !== void 0 ? _c : console.debug, // eslint-disable-next-line @typescript-eslint/no-explicit-any warn: (_d = console.warn.__hb_original) !== null && _d !== void 0 ? _d : console.warn, // eslint-disable-next-line @typescript-eslint/no-explicit-any error: (_e = console.error.__hb_original) !== null && _e !== void 0 ? _e : console.error, }; }; return ThrottledEventsLogger; }()); throttled_events_logger.ThrottledEventsLogger = ThrottledEventsLogger; var __assign$1 = (commonjsGlobal && commonjsGlobal.__assign) || function () { __assign$1 = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign$1.apply(this, arguments); }; var __awaiter$3 = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator$3 = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(client$1, "__esModule", { value: true }); client$1.Client = void 0; var util_1$5 = util$1; var store_1 = store; var throttled_events_logger_1 = throttled_events_logger; var defaults_1 = defaults; // Split at commas and spaces var TAG_SEPARATOR = /,|\s+/; // Checks for non-blank characters var NOT_BLANK = /\S/; var Client = /** @class */ (function () { function Client(opts, transport) { if (opts === void 0) { opts = {}; } this.__pluginsLoaded = false; this.__store = null; this.__beforeNotifyHandlers = []; this.__afterNotifyHandlers = []; this.__notifier = { name: '@honeybadger-io/core', url: 'https://github.com/honeybadger-io/honeybadger-js/tree/master/packages/core', version: '6.12.2' }; this.config = __assign$1(__assign$1({}, defaults_1.CONFIG), opts); this.__initStore(); this.__transport = transport; this.__eventsLogger = new throttled_events_logger_1.ThrottledEventsLogger(this.config, this.__transport); this.logger = (0, util_1$5.logger)(this); } Client.prototype.getVersion = function () { return this.__notifier.version; }; Client.prototype.getNotifier = function () { return this.__notifier; }; /** * CAREFUL: When adding a new notifier or updating the name of an existing notifier, * the Honeybadger rails project may need its mappings updated. * See https://github.com/honeybadger-io/honeybadger/blob/master/app/presenters/breadcrumbs_presenter.rb * https://github.com/honeybadger-io/honeybadger/blob/master/app/models/parser/java_script.rb * https://github.com/honeybadger-io/honeybadger/blob/master/app/models/language.rb **/ Client.prototype.setNotifier = function (notifier) { this.__notifier = notifier; }; Client.prototype.configure = function (opts) { if (opts === void 0) { opts = {}; } for (var k in opts) { this.config[k] = opts[k]; } this.__eventsLogger.configure(this.config); this.loadPlugins(); return this; }; Client.prototype.loadPlugins = function () { var _this = this; var pluginsToLoad = this.__pluginsLoaded ? this.config.__plugins.filter(function (plugin) { return plugin.shouldReloadOnConfigure; }) : this.config.__plugins; pluginsToLoad.forEach(function (plugin) { return plugin.load(_this); }); this.__pluginsLoaded = true; }; Client.prototype.__initStore = function () { this.__store = new store_1.GlobalStore({ context: {}, breadcrumbs: [] }, this.config.maxBreadcrumbs); }; Client.prototype.beforeNotify = function (handler) { this.__beforeNotifyHandlers.push(handler); return this; }; Client.prototype.afterNotify = function (handler) { this.__afterNotifyHandlers.push(handler); return this; }; Client.prototype.setContext = function (context) { if (typeof context === 'object' && context != null) { this.__store.setContext(context); } return this; }; Client.prototype.resetContext = function (context) { this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.'); this.__store.clear(); if (typeof context === 'object' && context !== null) { this.__store.setContext(context); } return this; }; Client.prototype.clear = function () { this.__store.clear(); return this; }; Client.prototype.notify = function (noticeable, name, extra) { var _this = this; if (name === void 0) { name = undefined; } if (extra === void 0) { extra = undefined; } var notice = this.makeNotice(noticeable, name, extra); // we need to have the source file data before the beforeNotifyHandlers, // in case they modify them var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return (0, util_1$5.shallowClone)(trace); }) : null; var preConditionsResult = this.__runPreconditions(notice); if (preConditionsResult instanceof Error) { (0, util_1$5.runAfterNotifyHandlers)(notice, this.__afterNotifyHandlers, preConditionsResult); return false; } if (preConditionsResult instanceof Promise) { preConditionsResult.then(function (result) { if (result instanceof Error) { (0, util_1$5.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, result); return false; } return _this.__send(notice, sourceCodeData); }); return true; } this.__send(notice, sourceCodeData).catch(function (_err) { }); return true; }; /** * An async version of {@link notify} that resolves only after the notice has been reported to Honeybadger. * Implemented using the {@link afterNotify} hook. * Rejects if for any reason the report failed to be reported. * Useful in serverless environments (AWS Lambda). */ Client.prototype.notifyAsync = function (noticeable, name, extra) { var _this = this; if (name === void 0) { name = undefined; } if (extra === void 0) { extra = undefined; } return new Promise(function (resolve, reject) { var applyAfterNotify = function (partialNotice) { var originalAfterNotify = partialNotice.afterNotify; partialNotice.afterNotify =