@honeybadger-io/js
Version:
Universal (Browser & Node) JavaScript error notifier for Honeybadger.io
1,326 lines (1,269 loc) • 142 kB
JavaScript
'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 =