Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sentry/integrations

Package Overview
Dependencies
Maintainers
13
Versions
387
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sentry/integrations - npm Package Compare versions

Comparing version 5.15.5 to 5.16.0-beta.1

329

build/vue.js

@@ -6,7 +6,2 @@ (function (__window) {

/**
* Consumes the promise and logs the error when it rejects.
* @param promise A promise to forget.
*/
/*! *****************************************************************************

@@ -41,2 +36,41 @@ Copyright (c) Microsoft Corporation. All rights reserved.

var __assign = function() {
__assign = Object.assign || function __assign(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.apply(this, arguments);
};
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/**
* Consumes the promise and logs the error when it rejects.
* @param promise A promise to forget.
*/
var setPrototypeOf = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); // tslint:disable-line:no-unbound-method

@@ -86,12 +120,2 @@ /**

*/
/**
* Checks whether given value's type is an object literal
* {@link isPlainObject}.
*
* @param wat A value to be checked.
* @returns A boolean representing the result.
*/
function isPlainObject(wat) {
return Object.prototype.toString.call(wat) === '[object Object]';
}

@@ -194,2 +218,8 @@ /**

})();
/**
* Returns a timestamp in seconds with milliseconds precision since the UNIX epoch calculated with the monotonic clock.
*/
function timestampWithMs() {
return (crossPlatformPerformance.timeOrigin + crossPlatformPerformance.now()) / 1000;
}

@@ -262,2 +292,18 @@ // TODO: Implement different loggers for different environments

// Slightly modified (no IE8 support, ES6) and transcribed to TypeScript
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
/** JSDoc */
function splitPath(filename) {
var parts = splitPathRe.exec(filename);
return parts ? parts.slice(1) : [];
}
/** JSDoc */
function basename(path, ext) {
var f = splitPath(path)[2];
if (ext && f.substr(ext.length * -1) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
}

@@ -278,2 +324,26 @@ /** SyncPromise internal states */

/**
* Used to extract Tracing integration from the current client,
* without the need to import `Tracing` itself from the @sentry/apm package.
*/
var TRACING_GETTER = {
id: 'Tracing',
};
// Mappings from lifecycle hook to corresponding operation,
// used to track already started measurements.
var OPERATIONS = {
activated: 'activate',
beforeCreate: 'create',
beforeDestroy: 'destroy',
beforeMount: 'mount',
beforeUpdate: 'update',
created: 'create',
deactivated: 'activate',
destroyed: 'destroy',
mounted: 'mount',
updated: 'update',
};
var COMPONENT_NAME_REGEXP = /(?:^|[-_/])(\w)/g;
var ROOT_COMPONENT_NAME = 'root';
var ANONYMOUS_COMPONENT_NAME = 'anonymous component';
/** JSDoc */

@@ -285,3 +355,3 @@ var Vue = /** @class */ (function () {

function Vue(options) {
if (options === void 0) { options = {}; }
var _this = this;
/**

@@ -292,54 +362,181 @@ * @inheritDoc

/**
* When set to false, Sentry will suppress reporting all props data
* from your Vue components for privacy concerns.
* Cache holding already processed component names
*/
this._attachProps = true;
/**
* When set to true, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
*/
this._logErrors = false;
// tslint:disable-next-line: no-unsafe-any
this._Vue = options.Vue || getGlobalObject().Vue;
if (options.logErrors !== undefined) {
this._logErrors = options.logErrors;
this._componentsCache = {};
/** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */
this._applyTracingHooks = function (vm, getCurrentHub) {
// Don't attach twice, just in case
if (vm.$options.$_sentryPerfHook) {
return;
}
vm.$options.$_sentryPerfHook = true;
var name = _this._getComponentName(vm);
var rootMount = name === ROOT_COMPONENT_NAME;
var spans = {};
// Render hook starts after once event is emitted,
// but it ends before the second event of the same type.
//
// Because of this, we start measuring inside the first event,
// but finish it before it triggers, to skip the event emitter timing itself.
var rootHandler = function (hook) {
var now = timestampWithMs();
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (_this._rootSpan) {
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
// Create an activity on the first event call. There'll be no second call, as rootSpan will be in place,
// thus new event handler won't be attached.
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
_this._tracingActivity = tracingIntegration.constructor.pushActivity('Vue Application Render');
}
_this._rootSpan = getCurrentHub().startSpan({
description: 'Application Render',
op: 'Vue',
});
});
}
};
var childHandler = function (hook) {
// Skip components that we don't want to track to minimize the noise and give a more granular control to the user
var shouldTrack = Array.isArray(_this._options.tracingOptions.trackComponents)
? _this._options.tracingOptions.trackComponents.includes(name)
: _this._options.tracingOptions.trackComponents;
if (!_this._rootSpan || !shouldTrack) {
return;
}
var now = timestampWithMs();
var op = OPERATIONS[hook];
var span = spans[op];
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (span) {
span.finish();
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
if (_this._rootSpan) {
spans[op] = _this._rootSpan.child({
description: "Vue <" + name + ">",
op: op,
});
}
});
}
};
// Each compomnent has it's own scope, so all activities are only related to one of them
_this._options.tracingOptions.hooks.forEach(function (hook) {
var handler = rootMount ? rootHandler.bind(_this, hook) : childHandler.bind(_this, hook);
var currentValue = vm.$options[hook];
if (Array.isArray(currentValue)) {
vm.$options[hook] = __spread([handler], currentValue);
}
else if (typeof currentValue === 'function') {
vm.$options[hook] = [handler, currentValue];
}
else {
vm.$options[hook] = [handler];
}
});
};
this._options = __assign({ Vue: getGlobalObject().Vue, attachProps: true, logErrors: false, tracing: true }, options, { tracingOptions: __assign({ hooks: ['beforeMount', 'mounted', 'beforeUpdate', 'updated'], timeout: 2000, trackComponents: false }, options.tracingOptions) });
}
/**
* Extract component name from the ViewModel
*/
Vue.prototype._getComponentName = function (vm) {
// Such level of granularity is most likely not necessary, but better safe than sorry. — Kamil
if (!vm) {
return ANONYMOUS_COMPONENT_NAME;
}
if (options.attachProps === false) {
this._attachProps = false;
}
}
/** JSDoc */
Vue.prototype._formatComponentName = function (vm) {
// tslint:disable:no-unsafe-any
if (vm.$root === vm) {
return 'root instance';
return ROOT_COMPONENT_NAME;
}
var name = vm._isVue ? vm.$options.name || vm.$options._componentTag : vm.name;
return ((name ? "component <" + name + ">" : 'anonymous component') +
(vm._isVue && vm.$options.__file ? " at " + vm.$options.__file : ''));
if (!vm.$options) {
return ANONYMOUS_COMPONENT_NAME;
}
if (vm.$options.name) {
return vm.$options.name;
}
if (vm.$options._componentTag) {
return vm.$options._componentTag;
}
// injected by vue-loader
if (vm.$options.__file) {
var unifiedFile = vm.$options.__file.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/');
var filename = basename(unifiedFile, '.vue');
return (this._componentsCache[filename] ||
(this._componentsCache[filename] = filename.replace(COMPONENT_NAME_REGEXP, function (_, c) {
return c ? c.toUpperCase() : '';
})));
}
return ANONYMOUS_COMPONENT_NAME;
};
/**
* @inheritDoc
*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
// tslint:disable:no-unsafe-any
/** Finish top-level span and activity with a debounce configured using `timeout` option */
Vue.prototype._finishRootSpan = function (timestamp, getCurrentHub) {
var _this = this;
if (!this._Vue || !this._Vue.config) {
logger.error('VueIntegration is missing a Vue instance');
if (this._rootSpanTimer) {
clearTimeout(this._rootSpanTimer);
}
this._rootSpanTimer = setTimeout(function () {
if (_this._rootSpan) {
_this._rootSpan.timestamp = timestamp;
}
if (_this._tracingActivity) {
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
tracingIntegration.constructor.popActivity(_this._tracingActivity);
}
}
}, this._options.tracingOptions.timeout);
};
/** Inject configured tracing hooks into Vue's component lifecycles */
Vue.prototype._startTracing = function (getCurrentHub) {
var applyTracingHooks = this._applyTracingHooks;
this._options.Vue.mixin({
beforeCreate: function () {
if (getCurrentHub().getIntegration(TRACING_GETTER)) {
// `this` points to currently rendered component
applyTracingHooks(this, getCurrentHub);
}
else {
logger.error('Vue integration has tracing enabled, but Tracing integration is not configured');
}
},
});
};
/** Inject Sentry's handler into owns Vue's error handler */
Vue.prototype._attachErrorHandler = function (getCurrentHub) {
var _this = this;
if (!this._options.Vue.config) {
logger.error('Vue instance is missing required `config` attribute');
return;
}
var oldOnError = this._Vue.config.errorHandler;
this._Vue.config.errorHandler = function (error, vm, info) {
var currentErrorHandler = this._options.Vue.config.errorHandler; // tslint:disable-line:no-unbound-method
this._options.Vue.config.errorHandler = function (error, vm, info) {
var metadata = {};
if (isPlainObject(vm)) {
metadata.componentName = _this._formatComponentName(vm);
if (_this._attachProps) {
metadata.propsData = vm.$options.propsData;
if (vm) {
try {
metadata.componentName = _this._getComponentName(vm);
if (_this._options.attachProps) {
metadata.propsData = vm.$options.propsData;
}
}
catch (_oO) {
logger.warn('Unable to extract metadata from Vue component.');
}
}
if (info !== void 0) {
if (info) {
metadata.lifecycleHook = info;
}
if (getCurrentHub().getIntegration(Vue)) {
// This timeout makes sure that any breadcrumbs are recorded before sending it off the sentry
// Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time.
setTimeout(function () {

@@ -352,9 +549,8 @@ getCurrentHub().withScope(function (scope) {

}
if (typeof oldOnError === 'function') {
oldOnError.call(_this._Vue, error, vm, info);
if (typeof currentErrorHandler === 'function') {
currentErrorHandler.call(_this._options.Vue, error, vm, info);
}
if (_this._logErrors) {
_this._Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
// tslint:disable-next-line:no-console
console.error(error);
if (_this._options.logErrors) {
_this._options.Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
console.error(error); // tslint:disable-line:no-console
}

@@ -366,2 +562,15 @@ };

*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
if (!this._options.Vue) {
logger.error('Vue integration is missing a Vue instance');
return;
}
this._attachErrorHandler(getCurrentHub);
if (this._options.tracing) {
this._startTracing(getCurrentHub);
}
};
/**
* @inheritDoc
*/
Vue.id = 'Vue';

@@ -368,0 +577,0 @@ return Vue;

2

build/vue.min.js

@@ -1,2 +0,2 @@

!function(o){var n={};Object.defineProperty(n,"__esModule",{value:!0});var t=function(o,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n}||function(o,n){for(var t in n)n.hasOwnProperty(t)&&(o[t]=n[t])})(o,n)};var r=Object.setPrototypeOf||({__proto__:[]}instanceof Array?function(o,n){return o.__proto__=n,o}:function(o,n){for(var t in n)o.hasOwnProperty(t)||(o[t]=n[t]);return o});!function(o){function n(n){var t=this.constructor,e=o.call(this,n)||this;return e.message=n,e.name=t.prototype.constructor.name,r(e,t.prototype),e}(function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)})(n,o)}(Error);function e(){return"[object process]"===Object.prototype.toString.call("undefined"!=typeof process?process:0)}var i={};function a(){return e()?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:i}function c(o){var n=a();if(!("console"in n))return o();var t=n.console,r={};["debug","info","warn","error","log","assert"].forEach(function(o){o in n.console&&t[o].__sentry_original__&&(r[o]=t[o],t[o]=t[o].__sentry_original__)});var e=o();return Object.keys(r).forEach(function(o){t[o]=r[o]}),e}var s=Date.now(),u=0,f={now:function(){var o=Date.now()-s;return o<u&&(o=u),u=o,o},timeOrigin:s},p=(function(){if(e())try{return(o=module,n="perf_hooks",o.require(n)).performance}catch(o){return f}var o,n;a().performance&&void 0===performance.timeOrigin&&(performance.timeOrigin=performance.timing&&performance.timing.navigationStart||s),a().performance}(),a()),_="Sentry Logger ",l=function(){function o(){this._enabled=!1}return o.prototype.disable=function(){this._enabled=!1},o.prototype.enable=function(){this._enabled=!0},o.prototype.log=function(){for(var o=[],n=0;n<arguments.length;n++)o[n]=arguments[n];this._enabled&&c(function(){p.console.log(_+"[Log]: "+o.join(" "))})},o.prototype.warn=function(){for(var o=[],n=0;n<arguments.length;n++)o[n]=arguments[n];this._enabled&&c(function(){p.console.warn(_+"[Warn]: "+o.join(" "))})},o.prototype.error=function(){for(var o=[],n=0;n<arguments.length;n++)o[n]=arguments[n];this._enabled&&c(function(){p.console.error(_+"[Error]: "+o.join(" "))})},o}();p.__SENTRY__=p.__SENTRY__||{};var g,y=p.__SENTRY__.logger||(p.__SENTRY__.logger=new l);!function(o){o.PENDING="PENDING",o.RESOLVED="RESOLVED",o.REJECTED="REJECTED"}(g||(g={}));a();var h=function(){function o(n){void 0===n&&(n={}),this.name=o.id,this._attachProps=!0,this._logErrors=!1,this._Vue=n.Vue||a().Vue,void 0!==n.logErrors&&(this._logErrors=n.logErrors),!1===n.attachProps&&(this._attachProps=!1)}return o.prototype._formatComponentName=function(o){if(o.$root===o)return"root instance";var n=o._isVue?o.$options.name||o.$options._componentTag:o.name;return(n?"component <"+n+">":"anonymous component")+(o._isVue&&o.$options.__file?" at "+o.$options.__file:"")},o.prototype.setupOnce=function(n,t){var r=this;if(this._Vue&&this._Vue.config){var e=this._Vue.config.errorHandler;this._Vue.config.errorHandler=function(n,i,a){var c,s={};c=i,"[object Object]"===Object.prototype.toString.call(c)&&(s.componentName=r._formatComponentName(i),r._attachProps&&(s.propsData=i.$options.propsData)),void 0!==a&&(s.lifecycleHook=a),t().getIntegration(o)&&setTimeout(function(){t().withScope(function(o){o.setContext("vue",s),t().captureException(n)})}),"function"==typeof e&&e.call(r._Vue,n,i,a),r._logErrors&&(r._Vue.util.warn("Error in "+a+': "'+n.toString()+'"',i),console.error(n))}}else y.error("VueIntegration is missing a Vue instance")},o.id="Vue",o}();for(var m in n.Vue=h,o.Sentry=o.Sentry||{},o.Sentry.Integrations=o.Sentry.Integrations||{},n)Object.prototype.hasOwnProperty.call(n,m)&&(o.Sentry.Integrations[m]=n[m])}(window);
!function(t){var o={};Object.defineProperty(o,"__esModule",{value:!0});var n=function(t,o){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])})(t,o)};var r=function(){return(r=Object.assign||function(t){for(var o,n=1,r=arguments.length;n<r;n++)for(var e in o=arguments[n])Object.prototype.hasOwnProperty.call(o,e)&&(t[e]=o[e]);return t}).apply(this,arguments)};function e(t,o){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,e,i=n.call(t),a=[];try{for(;(void 0===o||o-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){e={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}return a}var i=Object.setPrototypeOf||({__proto__:[]}instanceof Array?function(t,o){return t.__proto__=o,t}:function(t,o){for(var n in o)t.hasOwnProperty(n)||(t[n]=o[n]);return t});!function(t){function o(o){var n=this.constructor,r=t.call(this,o)||this;return r.message=o,r.name=n.prototype.constructor.name,i(r,n.prototype),r}(function(t,o){function r(){this.constructor=t}n(t,o),t.prototype=null===o?Object.create(o):(r.prototype=o.prototype,new r)})(o,t)}(Error);function a(){return"[object process]"===Object.prototype.toString.call("undefined"!=typeof process?process:0)}var c={};function s(){return a()?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:c}function p(t){var o=s();if(!("console"in o))return t();var n=o.console,r={};["debug","info","warn","error","log","assert"].forEach(function(t){t in o.console&&n[t].__sentry_original__&&(r[t]=n[t],n[t]=n[t].__sentry_original__)});var e=t();return Object.keys(r).forEach(function(t){n[t]=r[t]}),e}var u=Date.now(),f=0,_={now:function(){var t=Date.now()-u;return t<f&&(t=f),f=t,t},timeOrigin:u},l=function(){if(a())try{return(t=module,o="perf_hooks",t.require(o)).performance}catch(t){return _}var t,o;return s().performance&&void 0===performance.timeOrigin&&(performance.timeOrigin=performance.timing&&performance.timing.navigationStart||u),s().performance||_}();function g(){return(l.timeOrigin+l.now())/1e3}var h=s(),y="Sentry Logger ",m=function(){function t(){this._enabled=!1}return t.prototype.disable=function(){this._enabled=!1},t.prototype.enable=function(){this._enabled=!0},t.prototype.log=function(){for(var t=[],o=0;o<arguments.length;o++)t[o]=arguments[o];this._enabled&&p(function(){h.console.log(y+"[Log]: "+t.join(" "))})},t.prototype.warn=function(){for(var t=[],o=0;o<arguments.length;o++)t[o]=arguments[o];this._enabled&&p(function(){h.console.warn(y+"[Warn]: "+t.join(" "))})},t.prototype.error=function(){for(var t=[],o=0;o<arguments.length;o++)t[o]=arguments[o];this._enabled&&p(function(){h.console.error(y+"[Error]: "+t.join(" "))})},t}();h.__SENTRY__=h.__SENTRY__||{};var d,v=h.__SENTRY__.logger||(h.__SENTRY__.logger=new m),b=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;function S(t,o){var n,r,e=(n=t,r=b.exec(n),r?r.slice(1):[])[2];return o&&e.substr(-1*o.length)===o&&(e=e.substr(0,e.length-o.length)),e}!function(t){t.PENDING="PENDING",t.RESOLVED="RESOLVED",t.REJECTED="REJECTED"}(d||(d={}));s();var O={id:"Tracing"},E={activated:"activate",beforeCreate:"create",beforeDestroy:"destroy",beforeMount:"mount",beforeUpdate:"update",created:"create",deactivated:"activate",destroyed:"destroy",mounted:"mount",updated:"update"},w=/(?:^|[-_/])(\w)/g,V="root",T=function(){function t(o){var n=this;this.name=t.id,this._componentsCache={},this._applyTracingHooks=function(t,o){if(!t.$options.$_sentryPerfHook){t.$options.$_sentryPerfHook=!0;var r=n._getComponentName(t),i=r===V,a={};n._options.tracingOptions.hooks.forEach(function(c){var s=i?function(r){var e=g();n._rootSpan?n._finishRootSpan(e,o):t.$once("hook:"+r,function(){var t=o().getIntegration(O);t&&(n._tracingActivity=t.constructor.pushActivity("Vue Application Render")),n._rootSpan=o().startSpan({description:"Application Render",op:"Vue"})})}.bind(n,c):function(e){var i=Array.isArray(n._options.tracingOptions.trackComponents)?n._options.tracingOptions.trackComponents.includes(r):n._options.tracingOptions.trackComponents;if(n._rootSpan&&i){var c=g(),s=E[e],p=a[s];p?(p.finish(),n._finishRootSpan(c,o)):t.$once("hook:"+e,function(){n._rootSpan&&(a[s]=n._rootSpan.child({description:"Vue <"+r+">",op:s}))})}}.bind(n,c),p=t.$options[c];Array.isArray(p)?t.$options[c]=function(){for(var t=[],o=0;o<arguments.length;o++)t=t.concat(e(arguments[o]));return t}([s],p):t.$options[c]="function"==typeof p?[s,p]:[s]})}},this._options=r({Vue:s().Vue,attachProps:!0,logErrors:!1,tracing:!0},o,{tracingOptions:r({hooks:["beforeMount","mounted","beforeUpdate","updated"],timeout:2e3,trackComponents:!1},o.tracingOptions)})}return t.prototype._getComponentName=function(t){if(!t)return"anonymous component";if(t.$root===t)return V;if(!t.$options)return"anonymous component";if(t.$options.name)return t.$options.name;if(t.$options._componentTag)return t.$options._componentTag;if(t.$options.__file){var o=S(t.$options.__file.replace(/^[a-zA-Z]:/,"").replace(/\\/g,"/"),".vue");return this._componentsCache[o]||(this._componentsCache[o]=o.replace(w,function(t,o){return o?o.toUpperCase():""}))}return"anonymous component"},t.prototype._finishRootSpan=function(t,o){var n=this;this._rootSpanTimer&&clearTimeout(this._rootSpanTimer),this._rootSpanTimer=setTimeout(function(){if(n._rootSpan&&(n._rootSpan.timestamp=t),n._tracingActivity){var r=o().getIntegration(O);r&&r.constructor.popActivity(n._tracingActivity)}},this._options.tracingOptions.timeout)},t.prototype._startTracing=function(t){var o=this._applyTracingHooks;this._options.Vue.mixin({beforeCreate:function(){t().getIntegration(O)?o(this,t):v.error("Vue integration has tracing enabled, but Tracing integration is not configured")}})},t.prototype._attachErrorHandler=function(o){var n=this;if(this._options.Vue.config){var r=this._options.Vue.config.errorHandler;this._options.Vue.config.errorHandler=function(e,i,a){var c={};if(i)try{c.componentName=n._getComponentName(i),n._options.attachProps&&(c.propsData=i.$options.propsData)}catch(t){v.warn("Unable to extract metadata from Vue component.")}a&&(c.lifecycleHook=a),o().getIntegration(t)&&setTimeout(function(){o().withScope(function(t){t.setContext("vue",c),o().captureException(e)})}),"function"==typeof r&&r.call(n._options.Vue,e,i,a),n._options.logErrors&&(n._options.Vue.util.warn("Error in "+a+': "'+e.toString()+'"',i),console.error(e))}}else v.error("Vue instance is missing required `config` attribute")},t.prototype.setupOnce=function(t,o){this._options.Vue?(this._attachErrorHandler(o),this._options.tracing&&this._startTracing(o)):v.error("Vue integration is missing a Vue instance")},t.id="Vue",t}();for(var $ in o.Vue=T,t.Sentry=t.Sentry||{},t.Sentry.Integrations=t.Sentry.Integrations||{},o)Object.prototype.hasOwnProperty.call(o,$)&&(t.Sentry.Integrations[$]=o[$])}(window);
//# sourceMappingURL=vue.min.js.map
import { EventProcessor, Hub, Integration } from '@sentry/types';
/** Global Vue object limited to the methods/attributes we require */
interface VueInstance {
config?: {
errorHandler?(error: Error, vm?: ViewModel, info?: string): void;
};
mixin(hooks: {
[key: string]: () => void;
}): void;
util: {
warn(...input: any): void;
};
}
/** Representation of Vue component internals */
interface ViewModel {
[key: string]: any;
$root: object;
$options: {
[key: string]: any;
name?: string;
propsData?: {
[key: string]: any;
};
_componentTag?: string;
__file?: string;
$_sentryPerfHook?: boolean;
};
$once(hook: string, cb: () => void): void;
}
/** Vue Integration configuration */
interface IntegrationOptions {
/** Vue instance to be used inside the integration */
Vue: VueInstance;
/**
* When set to `false`, Sentry will suppress reporting of all props data
* from your Vue components for privacy concerns.
*/
attachProps: boolean;
/**
* When set to `true`, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
*/
logErrors: boolean;
/**
* When set to `false`, disables tracking of components lifecycle performance.
* By default, it tracks only when `Tracing` integration is also enabled.
*/
tracing: boolean;
/** {@link TracingOptions} */
tracingOptions: TracingOptions;
}
/** Vue specific configuration for Tracing Integration */
interface TracingOptions {
/**
* Decides whether to track components by hooking into its lifecycle methods.
* Can be either set to `boolean` to enable/disable tracking for all of them.
* Or to an array of specific component names (case-sensitive).
*/
trackComponents: boolean | string[];
/** How long to wait until the tracked root activity is marked as finished and sent of to Sentry */
timeout: number;
/**
* List of hooks to keep track of during component lifecycle.
* Available hooks: https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
*/
hooks: Hook[];
}
declare type Hook = 'activated' | 'beforeCreate' | 'beforeDestroy' | 'beforeMount' | 'beforeUpdate' | 'created' | 'deactivated' | 'destroyed' | 'mounted' | 'updated';
/** JSDoc */

@@ -12,30 +79,31 @@ export declare class Vue implements Integration {

static id: string;
private readonly _options;
/**
* @inheritDoc
* Cache holding already processed component names
*/
private readonly _Vue;
private readonly _componentsCache;
private _rootSpan?;
private _rootSpanTimer?;
private _tracingActivity?;
/**
* When set to false, Sentry will suppress reporting all props data
* from your Vue components for privacy concerns.
* @inheritDoc
*/
private readonly _attachProps;
constructor(options: Partial<IntegrationOptions>);
/**
* When set to true, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
* Extract component name from the ViewModel
*/
private readonly _logErrors;
private _getComponentName;
/** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */
private readonly _applyTracingHooks;
/** Finish top-level span and activity with a debounce configured using `timeout` option */
private _finishRootSpan;
/** Inject configured tracing hooks into Vue's component lifecycles */
private _startTracing;
/** Inject Sentry's handler into owns Vue's error handler */
private _attachErrorHandler;
/**
* @inheritDoc
*/
constructor(options?: {
Vue?: any;
attachProps?: boolean;
logErrors?: boolean;
});
/** JSDoc */
private _formatComponentName;
/**
* @inheritDoc
*/
setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void;
}
export {};
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var utils_1 = require("@sentry/utils");
/**
* Used to extract Tracing integration from the current client,
* without the need to import `Tracing` itself from the @sentry/apm package.
*/
var TRACING_GETTER = {
id: 'Tracing',
};
// Mappings from lifecycle hook to corresponding operation,
// used to track already started measurements.
var OPERATIONS = {
activated: 'activate',
beforeCreate: 'create',
beforeDestroy: 'destroy',
beforeMount: 'mount',
beforeUpdate: 'update',
created: 'create',
deactivated: 'activate',
destroyed: 'destroy',
mounted: 'mount',
updated: 'update',
};
var COMPONENT_NAME_REGEXP = /(?:^|[-_/])(\w)/g;
var ROOT_COMPONENT_NAME = 'root';
var ANONYMOUS_COMPONENT_NAME = 'anonymous component';
/** JSDoc */

@@ -9,3 +34,3 @@ var Vue = /** @class */ (function () {

function Vue(options) {
if (options === void 0) { options = {}; }
var _this = this;
/**

@@ -16,54 +41,181 @@ * @inheritDoc

/**
* When set to false, Sentry will suppress reporting all props data
* from your Vue components for privacy concerns.
* Cache holding already processed component names
*/
this._attachProps = true;
/**
* When set to true, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
*/
this._logErrors = false;
// tslint:disable-next-line: no-unsafe-any
this._Vue = options.Vue || utils_1.getGlobalObject().Vue;
if (options.logErrors !== undefined) {
this._logErrors = options.logErrors;
this._componentsCache = {};
/** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */
this._applyTracingHooks = function (vm, getCurrentHub) {
// Don't attach twice, just in case
if (vm.$options.$_sentryPerfHook) {
return;
}
vm.$options.$_sentryPerfHook = true;
var name = _this._getComponentName(vm);
var rootMount = name === ROOT_COMPONENT_NAME;
var spans = {};
// Render hook starts after once event is emitted,
// but it ends before the second event of the same type.
//
// Because of this, we start measuring inside the first event,
// but finish it before it triggers, to skip the event emitter timing itself.
var rootHandler = function (hook) {
var now = utils_1.timestampWithMs();
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (_this._rootSpan) {
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
// Create an activity on the first event call. There'll be no second call, as rootSpan will be in place,
// thus new event handler won't be attached.
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
_this._tracingActivity = tracingIntegration.constructor.pushActivity('Vue Application Render');
}
_this._rootSpan = getCurrentHub().startSpan({
description: 'Application Render',
op: 'Vue',
});
});
}
};
var childHandler = function (hook) {
// Skip components that we don't want to track to minimize the noise and give a more granular control to the user
var shouldTrack = Array.isArray(_this._options.tracingOptions.trackComponents)
? _this._options.tracingOptions.trackComponents.includes(name)
: _this._options.tracingOptions.trackComponents;
if (!_this._rootSpan || !shouldTrack) {
return;
}
var now = utils_1.timestampWithMs();
var op = OPERATIONS[hook];
var span = spans[op];
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (span) {
span.finish();
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
if (_this._rootSpan) {
spans[op] = _this._rootSpan.child({
description: "Vue <" + name + ">",
op: op,
});
}
});
}
};
// Each compomnent has it's own scope, so all activities are only related to one of them
_this._options.tracingOptions.hooks.forEach(function (hook) {
var handler = rootMount ? rootHandler.bind(_this, hook) : childHandler.bind(_this, hook);
var currentValue = vm.$options[hook];
if (Array.isArray(currentValue)) {
vm.$options[hook] = tslib_1.__spread([handler], currentValue);
}
else if (typeof currentValue === 'function') {
vm.$options[hook] = [handler, currentValue];
}
else {
vm.$options[hook] = [handler];
}
});
};
this._options = tslib_1.__assign({ Vue: utils_1.getGlobalObject().Vue, attachProps: true, logErrors: false, tracing: true }, options, { tracingOptions: tslib_1.__assign({ hooks: ['beforeMount', 'mounted', 'beforeUpdate', 'updated'], timeout: 2000, trackComponents: false }, options.tracingOptions) });
}
/**
* Extract component name from the ViewModel
*/
Vue.prototype._getComponentName = function (vm) {
// Such level of granularity is most likely not necessary, but better safe than sorry. — Kamil
if (!vm) {
return ANONYMOUS_COMPONENT_NAME;
}
if (options.attachProps === false) {
this._attachProps = false;
}
}
/** JSDoc */
Vue.prototype._formatComponentName = function (vm) {
// tslint:disable:no-unsafe-any
if (vm.$root === vm) {
return 'root instance';
return ROOT_COMPONENT_NAME;
}
var name = vm._isVue ? vm.$options.name || vm.$options._componentTag : vm.name;
return ((name ? "component <" + name + ">" : 'anonymous component') +
(vm._isVue && vm.$options.__file ? " at " + vm.$options.__file : ''));
if (!vm.$options) {
return ANONYMOUS_COMPONENT_NAME;
}
if (vm.$options.name) {
return vm.$options.name;
}
if (vm.$options._componentTag) {
return vm.$options._componentTag;
}
// injected by vue-loader
if (vm.$options.__file) {
var unifiedFile = vm.$options.__file.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/');
var filename = utils_1.basename(unifiedFile, '.vue');
return (this._componentsCache[filename] ||
(this._componentsCache[filename] = filename.replace(COMPONENT_NAME_REGEXP, function (_, c) {
return c ? c.toUpperCase() : '';
})));
}
return ANONYMOUS_COMPONENT_NAME;
};
/**
* @inheritDoc
*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
// tslint:disable:no-unsafe-any
/** Finish top-level span and activity with a debounce configured using `timeout` option */
Vue.prototype._finishRootSpan = function (timestamp, getCurrentHub) {
var _this = this;
if (!this._Vue || !this._Vue.config) {
utils_1.logger.error('VueIntegration is missing a Vue instance');
if (this._rootSpanTimer) {
clearTimeout(this._rootSpanTimer);
}
this._rootSpanTimer = setTimeout(function () {
if (_this._rootSpan) {
_this._rootSpan.timestamp = timestamp;
}
if (_this._tracingActivity) {
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
tracingIntegration.constructor.popActivity(_this._tracingActivity);
}
}
}, this._options.tracingOptions.timeout);
};
/** Inject configured tracing hooks into Vue's component lifecycles */
Vue.prototype._startTracing = function (getCurrentHub) {
var applyTracingHooks = this._applyTracingHooks;
this._options.Vue.mixin({
beforeCreate: function () {
if (getCurrentHub().getIntegration(TRACING_GETTER)) {
// `this` points to currently rendered component
applyTracingHooks(this, getCurrentHub);
}
else {
utils_1.logger.error('Vue integration has tracing enabled, but Tracing integration is not configured');
}
},
});
};
/** Inject Sentry's handler into owns Vue's error handler */
Vue.prototype._attachErrorHandler = function (getCurrentHub) {
var _this = this;
if (!this._options.Vue.config) {
utils_1.logger.error('Vue instance is missing required `config` attribute');
return;
}
var oldOnError = this._Vue.config.errorHandler;
this._Vue.config.errorHandler = function (error, vm, info) {
var currentErrorHandler = this._options.Vue.config.errorHandler; // tslint:disable-line:no-unbound-method
this._options.Vue.config.errorHandler = function (error, vm, info) {
var metadata = {};
if (utils_1.isPlainObject(vm)) {
metadata.componentName = _this._formatComponentName(vm);
if (_this._attachProps) {
metadata.propsData = vm.$options.propsData;
if (vm) {
try {
metadata.componentName = _this._getComponentName(vm);
if (_this._options.attachProps) {
metadata.propsData = vm.$options.propsData;
}
}
catch (_oO) {
utils_1.logger.warn('Unable to extract metadata from Vue component.');
}
}
if (info !== void 0) {
if (info) {
metadata.lifecycleHook = info;
}
if (getCurrentHub().getIntegration(Vue)) {
// This timeout makes sure that any breadcrumbs are recorded before sending it off the sentry
// Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time.
setTimeout(function () {

@@ -76,9 +228,8 @@ getCurrentHub().withScope(function (scope) {

}
if (typeof oldOnError === 'function') {
oldOnError.call(_this._Vue, error, vm, info);
if (typeof currentErrorHandler === 'function') {
currentErrorHandler.call(_this._options.Vue, error, vm, info);
}
if (_this._logErrors) {
_this._Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
// tslint:disable-next-line:no-console
console.error(error);
if (_this._options.logErrors) {
_this._options.Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
console.error(error); // tslint:disable-line:no-console
}

@@ -90,2 +241,15 @@ };

*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
if (!this._options.Vue) {
utils_1.logger.error('Vue integration is missing a Vue instance');
return;
}
this._attachErrorHandler(getCurrentHub);
if (this._options.tracing) {
this._startTracing(getCurrentHub);
}
};
/**
* @inheritDoc
*/
Vue.id = 'Vue';

@@ -92,0 +256,0 @@ return Vue;

import { EventProcessor, Hub, Integration } from '@sentry/types';
/** Global Vue object limited to the methods/attributes we require */
interface VueInstance {
config?: {
errorHandler?(error: Error, vm?: ViewModel, info?: string): void;
};
mixin(hooks: {
[key: string]: () => void;
}): void;
util: {
warn(...input: any): void;
};
}
/** Representation of Vue component internals */
interface ViewModel {
[key: string]: any;
$root: object;
$options: {
[key: string]: any;
name?: string;
propsData?: {
[key: string]: any;
};
_componentTag?: string;
__file?: string;
$_sentryPerfHook?: boolean;
};
$once(hook: string, cb: () => void): void;
}
/** Vue Integration configuration */
interface IntegrationOptions {
/** Vue instance to be used inside the integration */
Vue: VueInstance;
/**
* When set to `false`, Sentry will suppress reporting of all props data
* from your Vue components for privacy concerns.
*/
attachProps: boolean;
/**
* When set to `true`, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
*/
logErrors: boolean;
/**
* When set to `false`, disables tracking of components lifecycle performance.
* By default, it tracks only when `Tracing` integration is also enabled.
*/
tracing: boolean;
/** {@link TracingOptions} */
tracingOptions: TracingOptions;
}
/** Vue specific configuration for Tracing Integration */
interface TracingOptions {
/**
* Decides whether to track components by hooking into its lifecycle methods.
* Can be either set to `boolean` to enable/disable tracking for all of them.
* Or to an array of specific component names (case-sensitive).
*/
trackComponents: boolean | string[];
/** How long to wait until the tracked root activity is marked as finished and sent of to Sentry */
timeout: number;
/**
* List of hooks to keep track of during component lifecycle.
* Available hooks: https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
*/
hooks: Hook[];
}
declare type Hook = 'activated' | 'beforeCreate' | 'beforeDestroy' | 'beforeMount' | 'beforeUpdate' | 'created' | 'deactivated' | 'destroyed' | 'mounted' | 'updated';
/** JSDoc */

@@ -12,30 +79,31 @@ export declare class Vue implements Integration {

static id: string;
private readonly _options;
/**
* @inheritDoc
* Cache holding already processed component names
*/
private readonly _Vue;
private readonly _componentsCache;
private _rootSpan?;
private _rootSpanTimer?;
private _tracingActivity?;
/**
* When set to false, Sentry will suppress reporting all props data
* from your Vue components for privacy concerns.
* @inheritDoc
*/
private readonly _attachProps;
constructor(options: Partial<IntegrationOptions>);
/**
* When set to true, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
* Extract component name from the ViewModel
*/
private readonly _logErrors;
private _getComponentName;
/** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */
private readonly _applyTracingHooks;
/** Finish top-level span and activity with a debounce configured using `timeout` option */
private _finishRootSpan;
/** Inject configured tracing hooks into Vue's component lifecycles */
private _startTracing;
/** Inject Sentry's handler into owns Vue's error handler */
private _attachErrorHandler;
/**
* @inheritDoc
*/
constructor(options?: {
Vue?: any;
attachProps?: boolean;
logErrors?: boolean;
});
/** JSDoc */
private _formatComponentName;
/**
* @inheritDoc
*/
setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void;
}
export {};

@@ -1,2 +0,27 @@

import { getGlobalObject, isPlainObject, logger } from '@sentry/utils';
import * as tslib_1 from "tslib";
import { basename, getGlobalObject, logger, timestampWithMs } from '@sentry/utils';
/**
* Used to extract Tracing integration from the current client,
* without the need to import `Tracing` itself from the @sentry/apm package.
*/
var TRACING_GETTER = {
id: 'Tracing',
};
// Mappings from lifecycle hook to corresponding operation,
// used to track already started measurements.
var OPERATIONS = {
activated: 'activate',
beforeCreate: 'create',
beforeDestroy: 'destroy',
beforeMount: 'mount',
beforeUpdate: 'update',
created: 'create',
deactivated: 'activate',
destroyed: 'destroy',
mounted: 'mount',
updated: 'update',
};
var COMPONENT_NAME_REGEXP = /(?:^|[-_/])(\w)/g;
var ROOT_COMPONENT_NAME = 'root';
var ANONYMOUS_COMPONENT_NAME = 'anonymous component';
/** JSDoc */

@@ -8,3 +33,3 @@ var Vue = /** @class */ (function () {

function Vue(options) {
if (options === void 0) { options = {}; }
var _this = this;
/**

@@ -15,54 +40,181 @@ * @inheritDoc

/**
* When set to false, Sentry will suppress reporting all props data
* from your Vue components for privacy concerns.
* Cache holding already processed component names
*/
this._attachProps = true;
/**
* When set to true, original Vue's `logError` will be called as well.
* https://github.com/vuejs/vue/blob/c2b1cfe9ccd08835f2d99f6ce60f67b4de55187f/src/core/util/error.js#L38-L48
*/
this._logErrors = false;
// tslint:disable-next-line: no-unsafe-any
this._Vue = options.Vue || getGlobalObject().Vue;
if (options.logErrors !== undefined) {
this._logErrors = options.logErrors;
this._componentsCache = {};
/** Keep it as attribute function, to keep correct `this` binding inside the hooks callbacks */
this._applyTracingHooks = function (vm, getCurrentHub) {
// Don't attach twice, just in case
if (vm.$options.$_sentryPerfHook) {
return;
}
vm.$options.$_sentryPerfHook = true;
var name = _this._getComponentName(vm);
var rootMount = name === ROOT_COMPONENT_NAME;
var spans = {};
// Render hook starts after once event is emitted,
// but it ends before the second event of the same type.
//
// Because of this, we start measuring inside the first event,
// but finish it before it triggers, to skip the event emitter timing itself.
var rootHandler = function (hook) {
var now = timestampWithMs();
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (_this._rootSpan) {
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
// Create an activity on the first event call. There'll be no second call, as rootSpan will be in place,
// thus new event handler won't be attached.
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
_this._tracingActivity = tracingIntegration.constructor.pushActivity('Vue Application Render');
}
_this._rootSpan = getCurrentHub().startSpan({
description: 'Application Render',
op: 'Vue',
});
});
}
};
var childHandler = function (hook) {
// Skip components that we don't want to track to minimize the noise and give a more granular control to the user
var shouldTrack = Array.isArray(_this._options.tracingOptions.trackComponents)
? _this._options.tracingOptions.trackComponents.includes(name)
: _this._options.tracingOptions.trackComponents;
if (!_this._rootSpan || !shouldTrack) {
return;
}
var now = timestampWithMs();
var op = OPERATIONS[hook];
var span = spans[op];
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
// However, on the second call (after), it'll be already in place.
if (span) {
span.finish();
_this._finishRootSpan(now, getCurrentHub);
}
else {
vm.$once("hook:" + hook, function () {
if (_this._rootSpan) {
spans[op] = _this._rootSpan.child({
description: "Vue <" + name + ">",
op: op,
});
}
});
}
};
// Each compomnent has it's own scope, so all activities are only related to one of them
_this._options.tracingOptions.hooks.forEach(function (hook) {
var handler = rootMount ? rootHandler.bind(_this, hook) : childHandler.bind(_this, hook);
var currentValue = vm.$options[hook];
if (Array.isArray(currentValue)) {
vm.$options[hook] = tslib_1.__spread([handler], currentValue);
}
else if (typeof currentValue === 'function') {
vm.$options[hook] = [handler, currentValue];
}
else {
vm.$options[hook] = [handler];
}
});
};
this._options = tslib_1.__assign({ Vue: getGlobalObject().Vue, attachProps: true, logErrors: false, tracing: true }, options, { tracingOptions: tslib_1.__assign({ hooks: ['beforeMount', 'mounted', 'beforeUpdate', 'updated'], timeout: 2000, trackComponents: false }, options.tracingOptions) });
}
/**
* Extract component name from the ViewModel
*/
Vue.prototype._getComponentName = function (vm) {
// Such level of granularity is most likely not necessary, but better safe than sorry. — Kamil
if (!vm) {
return ANONYMOUS_COMPONENT_NAME;
}
if (options.attachProps === false) {
this._attachProps = false;
}
}
/** JSDoc */
Vue.prototype._formatComponentName = function (vm) {
// tslint:disable:no-unsafe-any
if (vm.$root === vm) {
return 'root instance';
return ROOT_COMPONENT_NAME;
}
var name = vm._isVue ? vm.$options.name || vm.$options._componentTag : vm.name;
return ((name ? "component <" + name + ">" : 'anonymous component') +
(vm._isVue && vm.$options.__file ? " at " + vm.$options.__file : ''));
if (!vm.$options) {
return ANONYMOUS_COMPONENT_NAME;
}
if (vm.$options.name) {
return vm.$options.name;
}
if (vm.$options._componentTag) {
return vm.$options._componentTag;
}
// injected by vue-loader
if (vm.$options.__file) {
var unifiedFile = vm.$options.__file.replace(/^[a-zA-Z]:/, '').replace(/\\/g, '/');
var filename = basename(unifiedFile, '.vue');
return (this._componentsCache[filename] ||
(this._componentsCache[filename] = filename.replace(COMPONENT_NAME_REGEXP, function (_, c) {
return c ? c.toUpperCase() : '';
})));
}
return ANONYMOUS_COMPONENT_NAME;
};
/**
* @inheritDoc
*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
// tslint:disable:no-unsafe-any
/** Finish top-level span and activity with a debounce configured using `timeout` option */
Vue.prototype._finishRootSpan = function (timestamp, getCurrentHub) {
var _this = this;
if (!this._Vue || !this._Vue.config) {
logger.error('VueIntegration is missing a Vue instance');
if (this._rootSpanTimer) {
clearTimeout(this._rootSpanTimer);
}
this._rootSpanTimer = setTimeout(function () {
if (_this._rootSpan) {
_this._rootSpan.timestamp = timestamp;
}
if (_this._tracingActivity) {
// We do this whole dance with `TRACING_GETTER` to prevent `@sentry/apm` from becoming a peerDependency.
// We also need to ask for the `.constructor`, as `pushActivity` and `popActivity` are static, not instance methods.
var tracingIntegration = getCurrentHub().getIntegration(TRACING_GETTER);
if (tracingIntegration) {
tracingIntegration.constructor.popActivity(_this._tracingActivity);
}
}
}, this._options.tracingOptions.timeout);
};
/** Inject configured tracing hooks into Vue's component lifecycles */
Vue.prototype._startTracing = function (getCurrentHub) {
var applyTracingHooks = this._applyTracingHooks;
this._options.Vue.mixin({
beforeCreate: function () {
if (getCurrentHub().getIntegration(TRACING_GETTER)) {
// `this` points to currently rendered component
applyTracingHooks(this, getCurrentHub);
}
else {
logger.error('Vue integration has tracing enabled, but Tracing integration is not configured');
}
},
});
};
/** Inject Sentry's handler into owns Vue's error handler */
Vue.prototype._attachErrorHandler = function (getCurrentHub) {
var _this = this;
if (!this._options.Vue.config) {
logger.error('Vue instance is missing required `config` attribute');
return;
}
var oldOnError = this._Vue.config.errorHandler;
this._Vue.config.errorHandler = function (error, vm, info) {
var currentErrorHandler = this._options.Vue.config.errorHandler; // tslint:disable-line:no-unbound-method
this._options.Vue.config.errorHandler = function (error, vm, info) {
var metadata = {};
if (isPlainObject(vm)) {
metadata.componentName = _this._formatComponentName(vm);
if (_this._attachProps) {
metadata.propsData = vm.$options.propsData;
if (vm) {
try {
metadata.componentName = _this._getComponentName(vm);
if (_this._options.attachProps) {
metadata.propsData = vm.$options.propsData;
}
}
catch (_oO) {
logger.warn('Unable to extract metadata from Vue component.');
}
}
if (info !== void 0) {
if (info) {
metadata.lifecycleHook = info;
}
if (getCurrentHub().getIntegration(Vue)) {
// This timeout makes sure that any breadcrumbs are recorded before sending it off the sentry
// Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time.
setTimeout(function () {

@@ -75,9 +227,8 @@ getCurrentHub().withScope(function (scope) {

}
if (typeof oldOnError === 'function') {
oldOnError.call(_this._Vue, error, vm, info);
if (typeof currentErrorHandler === 'function') {
currentErrorHandler.call(_this._options.Vue, error, vm, info);
}
if (_this._logErrors) {
_this._Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
// tslint:disable-next-line:no-console
console.error(error);
if (_this._options.logErrors) {
_this._options.Vue.util.warn("Error in " + info + ": \"" + error.toString() + "\"", vm);
console.error(error); // tslint:disable-line:no-console
}

@@ -89,2 +240,15 @@ };

*/
Vue.prototype.setupOnce = function (_, getCurrentHub) {
if (!this._options.Vue) {
logger.error('Vue integration is missing a Vue instance');
return;
}
this._attachErrorHandler(getCurrentHub);
if (this._options.tracing) {
this._startTracing(getCurrentHub);
}
};
/**
* @inheritDoc
*/
Vue.id = 'Vue';

@@ -91,0 +255,0 @@ return Vue;

{
"name": "@sentry/integrations",
"version": "5.15.5",
"version": "5.16.0-beta.1",
"description": "Pluggable integrations that can be used to enchance JS SDKs",

@@ -19,4 +19,4 @@ "repository": "git://github.com/getsentry/sentry-javascript.git",

"dependencies": {
"@sentry/types": "5.15.5",
"@sentry/utils": "5.15.5",
"@sentry/types": "5.16.0-beta.1",
"@sentry/utils": "5.16.0-beta.1",
"tslib": "^1.9.3"

@@ -23,0 +23,0 @@ },

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc