Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var utils_1 = require("@sentry/utils"); var scope_1 = require("./scope"); var session_1 = require("./session"); /** * API compatibility version of this hub. * * WARNING: This number should only be increased when the global interface * changes and new methods are introduced. * * @hidden */ exports.API_VERSION = 3; /** * Default maximum number of breadcrumbs added to an event. Can be overwritten * with {@link Options.maxBreadcrumbs}. */ var DEFAULT_BREADCRUMBS = 100; /** * Absolute maximum number of breadcrumbs added to an event. The * `maxBreadcrumbs` option cannot be higher than this value. */ var MAX_BREADCRUMBS = 100; /** * @inheritDoc */ var Hub = /** @class */ (function () { /** * Creates a new instance of the hub, will push one {@link Layer} into the * internal stack on creation. * * @param client bound to the hub. * @param scope bound to the hub. * @param version number, higher number means higher priority. */ function Hub(client, scope, _version) { if (scope === void 0) { scope = new scope_1.Scope(); } if (_version === void 0) { _version = exports.API_VERSION; } this._version = _version; /** Is a {@link Layer}[] containing the client and scope */ this._stack = [{}]; this.getStackTop().scope = scope; this.bindClient(client); } /** * @inheritDoc */ Hub.prototype.isOlderThan = function (version) { return this._version < version; }; /** * @inheritDoc */ Hub.prototype.bindClient = function (client) { var top = this.getStackTop(); top.client = client; if (client && client.setupIntegrations) { client.setupIntegrations(); } }; /** * @inheritDoc */ Hub.prototype.pushScope = function () { // We want to clone the content of prev scope var scope = scope_1.Scope.clone(this.getScope()); this.getStack().push({ client: this.getClient(), scope: scope, }); return scope; }; /** * @inheritDoc */ Hub.prototype.popScope = function () { if (this.getStack().length <= 1) return false; return !!this.getStack().pop(); }; /** * @inheritDoc */ Hub.prototype.withScope = function (callback) { var scope = this.pushScope(); try { callback(scope); } finally { this.popScope(); } }; /** * @inheritDoc */ Hub.prototype.getClient = function () { return this.getStackTop().client; }; /** Returns the scope of the top stack. */ Hub.prototype.getScope = function () { return this.getStackTop().scope; }; /** Returns the scope stack for domains or the process. */ Hub.prototype.getStack = function () { return this._stack; }; /** Returns the topmost scope layer in the order domain > local > process. */ Hub.prototype.getStackTop = function () { return this._stack[this._stack.length - 1]; }; /** * @inheritDoc */ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types Hub.prototype.captureException = function (exception, hint) { var eventId = (this._lastEventId = utils_1.uuid4()); var finalHint = hint; // If there's no explicit hint provided, mimick the same thing that would happen // in the minimal itself to create a consistent behavior. // We don't do this in the client, as it's the lowest level API, and doing this, // would prevent user from having full control over direct calls. if (!hint) { var syntheticException = void 0; try { throw new Error('Sentry syntheticException'); } catch (exception) { syntheticException = exception; } finalHint = { originalException: exception, syntheticException: syntheticException, }; } this._invokeClient('captureException', exception, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId })); return eventId; }; /** * @inheritDoc */ Hub.prototype.captureMessage = function (message, level, hint) { var eventId = (this._lastEventId = utils_1.uuid4()); var finalHint = hint; // If there's no explicit hint provided, mimick the same thing that would happen // in the minimal itself to create a consistent behavior. // We don't do this in the client, as it's the lowest level API, and doing this, // would prevent user from having full control over direct calls. if (!hint) { var syntheticException = void 0; try { throw new Error(message); } catch (exception) { syntheticException = exception; } finalHint = { originalException: message, syntheticException: syntheticException, }; } this._invokeClient('captureMessage', message, level, tslib_1.__assign(tslib_1.__assign({}, finalHint), { event_id: eventId })); return eventId; }; /** * @inheritDoc */ Hub.prototype.captureEvent = function (event, hint) { var eventId = (this._lastEventId = utils_1.uuid4()); this._invokeClient('captureEvent', event, tslib_1.__assign(tslib_1.__assign({}, hint), { event_id: eventId })); return eventId; }; /** * @inheritDoc */ Hub.prototype.lastEventId = function () { return this._lastEventId; }; /** * @inheritDoc */ Hub.prototype.addBreadcrumb = function (breadcrumb, hint) { var _a = this.getStackTop(), scope = _a.scope, client = _a.client; if (!scope || !client) return; // eslint-disable-next-line @typescript-eslint/unbound-method var _b = (client.getOptions && client.getOptions()) || {}, _c = _b.beforeBreadcrumb, beforeBreadcrumb = _c === void 0 ? null : _c, _d = _b.maxBreadcrumbs, maxBreadcrumbs = _d === void 0 ? DEFAULT_BREADCRUMBS : _d; if (maxBreadcrumbs <= 0) return; var timestamp = utils_1.dateTimestampInSeconds(); var mergedBreadcrumb = tslib_1.__assign({ timestamp: timestamp }, breadcrumb); var finalBreadcrumb = beforeBreadcrumb ? utils_1.consoleSandbox(function () { return beforeBreadcrumb(mergedBreadcrumb, hint); }) : mergedBreadcrumb; if (finalBreadcrumb === null) return; scope.addBreadcrumb(finalBreadcrumb, Math.min(maxBreadcrumbs, MAX_BREADCRUMBS)); }; /** * @inheritDoc */ Hub.prototype.setUser = function (user) { var scope = this.getScope(); if (scope) scope.setUser(user); }; /** * @inheritDoc */ Hub.prototype.setTags = function (tags) { var scope = this.getScope(); if (scope) scope.setTags(tags); }; /** * @inheritDoc */ Hub.prototype.setExtras = function (extras) { var scope = this.getScope(); if (scope) scope.setExtras(extras); }; /** * @inheritDoc */ Hub.prototype.setTag = function (key, value) { var scope = this.getScope(); if (scope) scope.setTag(key, value); }; /** * @inheritDoc */ Hub.prototype.setExtra = function (key, extra) { var scope = this.getScope(); if (scope) scope.setExtra(key, extra); }; /** * @inheritDoc */ // eslint-disable-next-line @typescript-eslint/no-explicit-any Hub.prototype.setContext = function (name, context) { var scope = this.getScope(); if (scope) scope.setContext(name, context); }; /** * @inheritDoc */ Hub.prototype.configureScope = function (callback) { var _a = this.getStackTop(), scope = _a.scope, client = _a.client; if (scope && client) { callback(scope); } }; /** * @inheritDoc */ Hub.prototype.run = function (callback) { var oldHub = makeMain(this); try { callback(this); } finally { makeMain(oldHub); } }; /** * @inheritDoc */ Hub.prototype.getIntegration = function (integration) { var client = this.getClient(); if (!client) return null; try { return client.getIntegration(integration); } catch (_oO) { utils_1.logger.warn("Cannot retrieve integration " + integration.id + " from the current Hub"); return null; } }; /** * @inheritDoc */ Hub.prototype.startSpan = function (context) { return this._callExtensionMethod('startSpan', context); }; /** * @inheritDoc */ Hub.prototype.startTransaction = function (context, customSamplingContext) { return this._callExtensionMethod('startTransaction', context, customSamplingContext); }; /** * @inheritDoc */ Hub.prototype.traceHeaders = function () { return this._callExtensionMethod('traceHeaders'); }; /** * @inheritDoc */ Hub.prototype.startSession = function (context) { // End existing session if there's one this.endSession(); var _a = this.getStackTop(), scope = _a.scope, client = _a.client; var _b = (client && client.getOptions()) || {}, release = _b.release, environment = _b.environment; var session = new session_1.Session(tslib_1.__assign(tslib_1.__assign({ release: release, environment: environment }, (scope && { user: scope.getUser() })), context)); if (scope) { scope.setSession(session); } return session; }; /** * @inheritDoc */ Hub.prototype.endSession = function () { var _a = this.getStackTop(), scope = _a.scope, client = _a.client; if (!scope) return; var session = scope.getSession(); if (session) { session.close(); if (client && client.captureSession) { client.captureSession(session); } scope.setSession(); } }; /** * Internal helper function to call a method on the top client if it exists. * * @param method The method to call on the client. * @param args Arguments to pass to the client function. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any Hub.prototype._invokeClient = function (method) { var _a; var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var _b = this.getStackTop(), scope = _b.scope, client = _b.client; if (client && client[method]) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any (_a = client)[method].apply(_a, tslib_1.__spread(args, [scope])); } }; /** * Calls global extension method and binding current instance to the function call */ // @ts-ignore Function lacks ending return statement and return type does not include 'undefined'. ts(2366) // eslint-disable-next-line @typescript-eslint/no-explicit-any Hub.prototype._callExtensionMethod = function (method) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var carrier = getMainCarrier(); var sentry = carrier.__SENTRY__; if (sentry && sentry.extensions && typeof sentry.extensions[method] === 'function') { return sentry.extensions[method].apply(this, args); } utils_1.logger.warn("Extension method " + method + " couldn't be found, doing nothing."); }; return Hub; }()); exports.Hub = Hub; /** Returns the global shim registry. */ function getMainCarrier() { var carrier = utils_1.getGlobalObject(); carrier.__SENTRY__ = carrier.__SENTRY__ || { extensions: {}, hub: undefined, }; return carrier; } exports.getMainCarrier = getMainCarrier; /** * Replaces the current main hub with the passed one on the global object * * @returns The old replaced hub */ function makeMain(hub) { var registry = getMainCarrier(); var oldHub = getHubFromCarrier(registry); setHubOnCarrier(registry, hub); return oldHub; } exports.makeMain = makeMain; /** * Returns the default hub instance. * * If a hub is already registered in the global carrier but this module * contains a more recent version, it replaces the registered version. * Otherwise, the currently registered hub will be returned. */ function getCurrentHub() { // Get main carrier (global for every environment) var registry = getMainCarrier(); // If there's no hub, or its an old API, assign a new one if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(exports.API_VERSION)) { setHubOnCarrier(registry, new Hub()); } // Prefer domains over global if they are there (applicable only to Node environment) if (utils_1.isNodeEnv()) { return getHubFromActiveDomain(registry); } // Return hub that lives on a global object return getHubFromCarrier(registry); } exports.getCurrentHub = getCurrentHub; /** * Returns the active domain, if one exists * * @returns The domain, or undefined if there is no active domain */ function getActiveDomain() { var sentry = getMainCarrier().__SENTRY__; return sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active; } exports.getActiveDomain = getActiveDomain; /** * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist * @returns discovered hub */ function getHubFromActiveDomain(registry) { try { var activeDomain = getActiveDomain(); // If there's no active domain, just return global hub if (!activeDomain) { return getHubFromCarrier(registry); } // If there's no hub on current domain, or it's an old API, assign a new one if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(exports.API_VERSION)) { var registryHubTopStack = getHubFromCarrier(registry).getStackTop(); setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, scope_1.Scope.clone(registryHubTopStack.scope))); } // Return hub that lives on a domain return getHubFromCarrier(activeDomain); } catch (_Oo) { // Return hub that lives on a global object return getHubFromCarrier(registry); } } /** * This will tell whether a carrier has a hub on it or not * @param carrier object */ function hasHubOnCarrier(carrier) { return !!(carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub); } /** * This will create a new {@link Hub} and add to the passed object on * __SENTRY__.hub. * @param carrier object * @hidden */ function getHubFromCarrier(carrier) { if (carrier && carrier.__SENTRY__ && carrier.__SENTRY__.hub) return carrier.__SENTRY__.hub; carrier.__SENTRY__ = carrier.__SENTRY__ || {}; carrier.__SENTRY__.hub = new Hub(); return carrier.__SENTRY__.hub; } exports.getHubFromCarrier = getHubFromCarrier; /** * This will set passed {@link Hub} on the passed object's __SENTRY__.hub attribute * @param carrier object * @param hub Hub */ function setHubOnCarrier(carrier, hub) { if (!carrier) return false; carrier.__SENTRY__ = carrier.__SENTRY__ || {}; carrier.__SENTRY__.hub = hub; return true; } exports.setHubOnCarrier = setHubOnCarrier; //# sourceMappingURL=hub.js.map