backtrace-js
Advanced tools
Comparing version 1.0.2 to 1.1.0
# Backtrace JS Release Notes | ||
## Version 1.1.0 | ||
- Backtrace-Metrics support - by default metrics support is enabled. User can modify the metrics support via `BacktraceConfiguration` options. | ||
## Version 1.0.2 | ||
@@ -4,0 +7,0 @@ - Provide file name instead of full file path in the stack trace object. |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.backtraceJs=e():t.backtraceJs=e()}(window,(function(){return function(t){var e={};function r(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,i){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)r.d(i,n,function(e){return t[e]}.bind(null,n));return i},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.leaveBreadcrumb=e.errorHandlerMiddleware=e.BacktraceReport=e.createReport=e.reportSync=e.report=e.use=e.getBacktraceClient=e.initialize=e.pageStartTime=e.BtReport=e.BacktraceClientOptions=e.BacktraceClient=void 0;const i=r(1);var n=r(1);Object.defineProperty(e,"BacktraceClient",{enumerable:!0,get:function(){return n.BacktraceClient}});var s=r(3);Object.defineProperty(e,"BacktraceClientOptions",{enumerable:!0,get:function(){return s.BacktraceClientOptions}});var o=r(4);let a;function c(){if(!a)throw new Error("Must call initialize method first");const t=a.createReport("");return t.send=e=>{a.sendReport(t,e)},t.sendSync=e=>{a.sendReport(t,e)},t}Object.defineProperty(e,"BtReport",{enumerable:!0,get:function(){return o.BacktraceReport}}),e.pageStartTime=new Date,e.initialize=function(t){return a=new i.BacktraceClient(t),a},e.getBacktraceClient=function(){return a},e.use=function(t){a=t},e.report=async function(t,e={},r){if(!a)throw new Error("Must call initialize method first");let i="";(t instanceof Error||"string"==typeof t)&&(i=t),"object"==typeof t&&e==={}&&(e=t);const n=await a.reportAsync(i,e,r);return t instanceof Function&&t(),n},e.reportSync=function(t,e={},r){if(!a)throw new Error("Must call initialize method first");return a.reportSync(t,e,r)},e.createReport=function(){return c()},e.BacktraceReport=c,e.errorHandlerMiddleware=function(t,e,r,i){if(!a)throw new Error("Must call initialize method first");a.reportSync(t,Object.assign(Object.assign({},e),r)),i(t)},e.leaveBreadcrumb=function(t,e,r,i,n){if(!a)throw new Error("Must call initialize method first");if(!t)throw new Error("Breadcrumb must include message");a.breadcrumbs.add(t,e,r,i,n)}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceClient=void 0;const i=r(6),n=r(7),s=r(0),o=r(3),a=r(4),c=r(2),u=r(5),d=r(9);e.BacktraceClient=class{constructor(t){if(!t.endpoint)throw new Error("Backtrace: missing 'endpoint' option.");this.options=Object.assign(Object.assign({},new o.BacktraceClientOptions),t),this.breadcrumbs=new u.Breadcrumbs(this.options.breadcrumbLimit),this._backtraceApi=new i.BacktraceApi(this.getSubmitUrl(),this.options.timeout),this._clientRateLimit=new n.ClientRateLimit(this.options.rateLimit),this.registerHandlers(),this.attributes=Object.assign(Object.assign({},this.readAttributes()),this.options.userAttributes)}memorize(t,e){this.attributes[t]=e}setAttribute(t,e){this.attributes[t]=e}createReport(t,e={},r){const i=this.breadcrumbs.isEnabled()?this.breadcrumbs.get():void 0,n=new a.BacktraceReport(t,e,i,r);return n.send=t=>{this.sendAsync(n).then(()=>{t&&t(void 0)}).catch(e=>{t&&t(e)})},n.sendSync=t=>{this.sendReport(n,t)},n}async reportAsync(t,e={},r){const i=this.createReport(t,e,r);return new Promise((t,e)=>{this.sendReport(i,(r,i)=>{!r&&i?t(i):e(r)})})}reportSync(t,e={},r){const i=this.createReport(t,e,r);return this.sendReport(i)}sendReport(t,e){if(!t.uuid)throw new Error("Invalid backtrace report object. Please pass an instance of the Backtrace report object.");if(this.options.filter&&this.options.filter(t))return c.BacktraceResult.OnFilterHit(t);const r=this.testClientLimits(t);return r||(t.addObjectAttributes(this.attributes),this._backtraceApi.send(t).then(t=>{this.breadcrumbs.isEnabled()&&this.breadcrumbs.add("Report sent to Backtrace",{error:t.Error,message:t.Message,objectId:t.ObjectId},Date.now(),"error","log"),e&&e(t.Error,t)}).catch(t=>{e&&e(t)}),c.BacktraceResult.Processing(t))}async sendAsync(t){if(this.options.filter&&this.options.filter(t))return c.BacktraceResult.OnFilterHit(t);const e=this.testClientLimits(t);return e||await this._backtraceApi.send(t)}testClientLimits(t){if(this.samplingHit())return c.BacktraceResult.OnSamplingHit(t);return this._clientRateLimit.skipReport(t)?c.BacktraceResult.OnLimitReached(t):void 0}samplingHit(){return!!this.options.sampling&&Math.random()>this.options.sampling}getSubmitUrl(){const t=this.options.endpoint;if(t.includes("submit.backtrace.io")||t.includes("token="))return t;if(!this.options.token)throw new Error("Token is required if Backtrace-js have to build url to Backtrace");const e=t.endsWith("/")?"":"/";return`${this.options.endpoint}${e}post?format=json&token=${this.options.token}`}registerHandlers(){this.options.disableGlobalHandler||this.registerGlobalHandler(),this.options.handlePromises&&this.registerPromiseHandler()}registerPromiseHandler(){window.onunhandledrejection=t=>{const e=new Error(t.reason),r=this.createReport(e);r.addAnnotation("onunhandledrejection",t),this.sendReport(r)}}registerGlobalHandler(){window.onerror=(t,e,r,i,n)=>{n||(n="string"==typeof t?new Error(t):new Error(t.error)),this.reportSync(n,{"exception.lineNumber":r,"exception.columnNumber":i})}}readAttributes(){const t=d.getBrowserName();return{application:document.title,"process.age":Math.floor(((new Date).getTime()-s.pageStartTime.getTime())/1e3),hostname:window.location&&window.location.hostname,referer:window.location&&window.location.href,"user.agent.full":navigator.userAgent,"location.port":document.location.port,"location.protocol":document.location.protocol,"location.origin":window.location.origin,"location.href":window.location.href||document.URL,language:navigator.language,"browser.name":t,"browser.version":d.getBrowserVersion(t),"browser.platform":navigator.platform,"browser.vendor":navigator.vendor,"cookies.enable":navigator.cookieEnabled,"document.domain":document.domain,"document.baseURI":document.baseURI,"document.title":document.title,"document.referrer":document.referrer,mobile:d.isMobile(),"localstorage.enable":!!window.localStorage,"uname.sysname":d.getOs(),"window.innerHeight":window.innerHeight,"window.innerWidth":window.innerWidth,"window.outerHeight":window.outerHeight,"window.outerWidth":window.outerWidth,"window.pageXOffset":window.pageXOffset,"window.pageYOffset":window.pageYOffset,"window.screenX":window.screenX,"window.screenY":window.screenY,"window.screenLeft":window.screenLeft,"window.screenTop":window.screenTop,"backtrace.version":"1.0.2"}}}},function(t,e,r){"use strict";var i;Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceResult=e.BacktraceResultStatus=void 0,function(t){t[t.SamplingHit=0]="SamplingHit",t[t.LimitReached=1]="LimitReached",t[t.ServerError=2]="ServerError",t[t.Ok=4]="Ok",t[t.InProcessing=8]="InProcessing",t[t.FilterHit=16]="FilterHit"}(i=e.BacktraceResultStatus||(e.BacktraceResultStatus={}));class n{constructor(t,e,r,i,n){this.report=t,this.message=e,this.status=r,this.err=i,this._objectId="",this._rxId="",n&&(this._rxId=n._rxid,this._objectId=n.object,this.message=n.message?n.message:e)}static Processing(t){return new n(t,"Data were send to API and waiting for server result",i.InProcessing)}static Ok(t,e){return new n(t,"Report is available on the Backtrace server",i.Ok,void 0,e)}static OnLimitReached(t){return new n(t,"Client report limit reached",i.LimitReached)}static OnSamplingHit(t){return new n(t,"Sampling hit",i.SamplingHit)}static OnFilterHit(t){return new n(t,"Filter hit",i.FilterHit)}static OnError(t,e){return new n(t,e.message,i.ServerError,e)}get ObjectId(){return this._objectId?this._objectId:this._rxId}get Report(){return this.report}get Message(){return this.message}get Error(){return this.err}get Status(){return this.status}}e.BacktraceResult=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceClientOptions=void 0;e.BacktraceClientOptions=class{constructor(){this.timeout=15e3,this.userAttributes={},this.disableGlobalHandler=!1,this.handlePromises=!1,this.sampling=void 0,this.rateLimit=0,this.filter=void 0,this.breadcrumbLimit=-1,this.debugBacktrace=!1,this.tabWidth=8,this.contextLineCount=200}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceReport=void 0;const i=r(8),n=r(5),s=window.crypto;e.BacktraceReport=class{constructor(t="",e={},r,i){this.err=t,this.clientAttributes=e,this.breadcrumbs=r,this.attachment=i,this.uuid=this.generateUuid(),this.timestamp=Math.floor((new Date).getTime()/1e3),this.lang="js",this.langVersion=navigator.userAgent,this.agent="backtrace-js",this.agentVersion="1.0.2",this.mainThread="main",this.classifiers=[],this.attributes={},this.annotations={},e||(e={}),this.splitAttributesFromAnnotations(e),this.setError(t)}isExceptionTypeReport(){return this.detectReportType(this.err)}getPayload(){return this.err}setError(t){this.err=t,this.classifiers=this.detectReportType(t)?[t.name]:[]}log(t){console.log(t)}trace(t){console.trace(t)}addObjectAttributes(t){this.clientAttributes=Object.assign(Object.assign(Object.assign({},this.clientAttributes),this.attributes),t)}addAttribute(t,e){this.clientAttributes[t]=e}addAnnotation(t,e){this.annotations[t]=e}toJson(){this.collectReportInformation();const t={uuid:this.uuid,timestamp:this.timestamp,lang:this.lang,langVersion:this.langVersion,mainThread:this.mainThread,classifiers:this.classifiers,threads:{main:this.stackTrace.toJson()},agent:this.agent,agentVersion:this.agentVersion,annotations:this.annotations,attributes:this.attributes};return this.sourceCode&&this.sourceCode.text&&(t.sourceCode={main:this.sourceCode}),this.attributes.symbolication_id&&(t.symbolication="sourcemap"),t.attributes.guid=this.getGuid(),t}toFormData(){const t=this.toJson(),e=new FormData,r=new Blob([JSON.stringify(t)]);if(e.append("upload_file",r,"upload_file.json"),this.breadcrumbs){const t=new Blob([JSON.stringify(this.breadcrumbs)]);e.append(n.Breadcrumbs.attachmentName,t,n.Breadcrumbs.attachmentName)}if(this.attachment){const t=new Blob([JSON.stringify(this.attachment)]),r="attachment_"+Date.now();e.append(r,t,r)}return e}setSourceCodeOptions(t,e){}collectReportInformation(){this.stackTrace=new i.BacktraceStackTrace(this.err),this.attributes=Object.assign(Object.assign({},this.readErrorAttributes()),this.clientAttributes),this.annotations=this.readAnnotation()}detectReportType(t){return t instanceof Error}getGuid(){let t=window.localStorage.getItem("backtrace-guid");return t||(t=this.generateUuid(),window.localStorage.setItem("backtrace-guid",t)),t}generateUuid(){const t=new Uint8Array(16);s.getRandomValues(t);const e=t=>{const e=t.toString(16);return t<16?"0"+e:e};let r="",i=0;for(;i<4;i+=1)r+=e(t[i]);for(r+="-";i<6;i+=1)r+=e(t[i]);for(r+="-";i<8;i+=1)r+=e(t[i]);for(r+="-";i<10;i+=1)r+=e(t[i]);for(r+="-";i<16;i+=1)r+=e(t[i]);return r}readErrorAttributes(){return this.detectReportType(this.err)?(this.classifiers=[this.err.name],{"error.message":this.err.message}):{"error.message":this.err}}readAnnotation(){return Object.assign({Memory:window.performance?window.performance:performance.timing,Geolocation:navigator.geolocation,Screen:{"screen.availHeight":window.screen.availHeight,"screen.availWidth":window.screen.availWidth,"screen.height":window.screen.height,"screen.width":window.screen.width,"screen.orientation":window.screen.orientation.type,"screen.colorDepth":window.screen.colorDepth,"screen.pixelDepth":window.screen.pixelDepth},Exception:this.getSerializableError()},this.annotations)}getSerializableError(){if("string"==typeof this.err)return{message:this.err};const t={},e=this;return Object.getOwnPropertyNames(this.err).forEach(r=>{t[r]=e.err[r]}),t}splitAttributesFromAnnotations(t){for(const e in t)if(t.hasOwnProperty(e)){const t=this.clientAttributes[e];if(!t)continue;"object"==typeof t?this.annotations[e]=t:this.attributes[e]=t}}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Breadcrumbs=void 0;class i{constructor(t){this.breadcrumbLimit=-1,this._breadcrumbs=[],this.id=0,this.breadcrumbLimit=!t||t<=0?-1:t}add(t,e={},r=this.getNowTimestamp(),i="info",n="manual"){if(this.breadcrumbLimit<0)return;for(;this._breadcrumbs.length===this.breadcrumbLimit;)this._breadcrumbs.shift();const s={id:this.id++,timestamp:r,level:i,type:n,message:t,attributes:e};this._breadcrumbs.push(s)}get(){return this._breadcrumbs}isEnabled(){return this.breadcrumbLimit>0}getNowTimestamp(){return Date.now()}}e.Breadcrumbs=i,i.attachmentName="bt-breadcrumbs-0"},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceApi=void 0;const i=r(2);e.BacktraceApi=class{constructor(t,e){this._backtraceUri=t,this._timeout=e}async send(t){try{const e=t.toFormData();return new Promise((r,n)=>{const s=new XMLHttpRequest;s.timeout=this._timeout,s.open("POST",this._backtraceUri,!0),s.send(e),s.onload=e=>{s.readyState===XMLHttpRequest.DONE&&(200===s.status?r(i.BacktraceResult.Ok(t,s.responseText)):429===s.status?r(i.BacktraceResult.OnError(t,new Error("Backtrace - reached report limit."))):r(i.BacktraceResult.OnError(t,new Error("Invalid attempt to submit error to Backtrace. Result: "+s.responseText))))},s.onerror=t=>{n(t)}})}catch(e){return i.BacktraceResult.OnError(t,e)}}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ClientRateLimit=void 0;e.ClientRateLimit=class{constructor(t){if(this.reportPerMin=t,this._reportQueue=[],t<0)throw new Error("ReportPerMinute argument must be greater or equal to zero");this._watcherEnable=t>0}skipReport(t){return!!this._watcherEnable&&(this.clear(),this._reportQueue.length>=this.reportPerMin||(this._reportQueue.push(t.timestamp),!1))}clear(){const t=Math.floor((new Date).getTime()/1e3);0!==this._reportQueue.length&&t-this._reportQueue[0]>60&&(this._reportQueue.length=0)}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceStackTrace=void 0;e.BacktraceStackTrace=class{constructor(t){this.fault=!0,this.name="main",this.stack=[],this.stackLineRe=/^\s+at (?:([^\s]+) )?\(?(.+):(\d+):(\d+)\)?$/,t instanceof Error||(t=new Error),this.error=t,this.parseStackFrames()}toJson(){return{name:this.name,fault:this.fault,stack:this.stack}}parseStackFrames(){const t=this.error.stack;if(!t)return;t.split("\n").slice(1).forEach(t=>{const e=t.match(this.stackLineRe);if(!e||e.length<4)return;const r=e[2];if(-1!==r.indexOf("node_modules/backtrace-js"))return;const i={funcName:e[1]?e[1]:"unknown",library:r.substring(r.lastIndexOf("/")+1),line:parseInt(e[3],10),column:parseInt(e[4],10)};0===this.stack.length&&(i.sourceCode="main"),this.stack.push(i)})}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isMobile=e.getOs=e.getBrowserName=e.getBrowserVersion=void 0;const i=["safari","chrome","edge","opera","firefox"];e.getBrowserVersion=function(t){if("safari"===t&&(t="version"),t)return new RegExp(t+"[\\/ ]([\\d\\w\\.-]+)","i").exec(navigator.appVersion)&&RegExp.$1||void 0;{const t=navigator.appVersion.match(/version[\/ ]([\d\w\.]+)/i);return t&&t.length>1?t[1]:void 0}},e.getBrowserName=function(){const t=navigator.userAgent.toLowerCase();for(const e of i)if(-1!==t.indexOf(e))return e;return"unknown"},e.getOs=function(){const t=window.navigator.platform;return["Macintosh","MacIntel","MacPPC","Mac68K"].some(e=>e===t)||["Win32","Win64","Windows","WinCE"].some(e=>e===t)?"MacOS":["iPhone","iPad","iPod"].some(e=>e===t)?"iOS":-1!==window.navigator.userAgent.indexOf("Android")?"Android":navigator.appVersion.indexOf("Linux")||navigator.appVersion.indexOf("X11")?"Linux":"unknown"},e.isMobile=function(){return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(navigator.userAgent.toLowerCase())}}])})); | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.backtraceJs=e():t.backtraceJs=e()}(window,(function(){return function(t){var e={};function r(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,i){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)r.d(i,n,function(e){return t[e]}.bind(null,n));return i},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.post=e.getEndpointParams=e.getBacktraceGUID=e.currentTimestamp=e.uuid=void 0;const i=window.crypto;function n(){const t=new Uint8Array(16);i.getRandomValues(t);const e=t=>{const e=t.toString(16);return t<16?"0"+e:e};let r="",n=0;for(;n<4;n+=1)r+=e(t[n]);for(r+="-";n<6;n+=1)r+=e(t[n]);for(r+="-";n<8;n+=1)r+=e(t[n]);for(r+="-";n<10;n+=1)r+=e(t[n]);for(r+="-";n<16;n+=1)r+=e(t[n]);return r}e.uuid=n,e.currentTimestamp=function(t=!1){return Math.floor((new Date).getTime()/(t?1:1e3))},e.getBacktraceGUID=function(){let t=window.localStorage.getItem("backtrace-guid");return t||(t=n(),window.localStorage.setItem("backtrace-guid",t)),t},e.getEndpointParams=function(t,e){if(!t)return;if(-1!==t.indexOf("submit.backtrace.io")){const r="backtrace.io/",i=t.indexOf("backtrace.io/")+r.length;if(-1===i)return;const n=t.indexOf("/",i);if(-1===n)return;const s=t.substring(i,n);if(!e){const r=t.lastIndexOf("/");if(r===n)return;if(!(e=t.substring(n+1,r))||64!==e.length)return}return{universe:s,token:e}}const r=new URL(t).hostname,i=r.indexOf(".");return-1!==i?{token:e,universe:r.substring(0,i)}:void 0},e.post=async function(t,e,r){try{return new Promise((i,n)=>{const s=new XMLHttpRequest;s.timeout=(null==r?void 0:r.timeout)||15e3,s.open("POST",t,!0),s.setRequestHeader("Content-type","application/json"),s.send(JSON.stringify(e)),s.onload=t=>{s.readyState===XMLHttpRequest.DONE&&(200===s.status?i():429===s.status?n("Backtrace - reached metric limit."):n(`Invalid attempt to submit metric to Backtrace. HTTP Error ${s.status}. Result: ${s.responseText}`))},s.onerror=t=>{n(t)}})}catch(t){console.error(t)}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.leaveBreadcrumb=e.errorHandlerMiddleware=e.BacktraceReport=e.createReport=e.reportSync=e.report=e.use=e.getBacktraceClient=e.initialize=e.pageStartTime=e.BtReport=e.BacktraceClientOptions=e.BacktraceClient=void 0;const i=r(2);var n=r(2);Object.defineProperty(e,"BacktraceClient",{enumerable:!0,get:function(){return n.BacktraceClient}});var s=r(4);Object.defineProperty(e,"BacktraceClientOptions",{enumerable:!0,get:function(){return s.BacktraceClientOptions}});var o=r(5);let a;function c(){if(!a)throw new Error("Must call initialize method first");const t=a.createReport("");return t.send=e=>{a.sendReport(t,e)},t.sendSync=e=>{a.sendReport(t,e)},t}Object.defineProperty(e,"BtReport",{enumerable:!0,get:function(){return o.BacktraceReport}}),e.pageStartTime=new Date,e.initialize=function(t){return a=new i.BacktraceClient(t),a},e.getBacktraceClient=function(){return a},e.use=function(t){a=t},e.report=async function(t,e={},r){if(!a)throw new Error("Must call initialize method first");let i="";(t instanceof Error||"string"==typeof t)&&(i=t),"object"==typeof t&&e==={}&&(e=t);const n=await a.reportAsync(i,e,r);return t instanceof Function&&t(),n},e.reportSync=function(t,e={},r){if(!a)throw new Error("Must call initialize method first");return a.reportSync(t,e,r)},e.createReport=function(){return c()},e.BacktraceReport=c,e.errorHandlerMiddleware=function(t,e,r,i){if(!a)throw new Error("Must call initialize method first");a.reportSync(t,Object.assign(Object.assign({},e),r)),i(t)},e.leaveBreadcrumb=function(t,e,r,i,n){if(!a)throw new Error("Must call initialize method first");if(!t)throw new Error("Breadcrumb must include message");a.breadcrumbs.add(t,e,r,i,n)}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceClient=void 0;const i=r(7),n=r(8),s=r(1),o=r(4),a=r(9),c=r(5),u=r(3),d=r(6),l=r(0),h=r(13);e.BacktraceClient=class{constructor(t){if(!t.endpoint)throw new Error("Backtrace: missing 'endpoint' option.");this.options=Object.assign(Object.assign({},new o.BacktraceClientOptions),t),this.breadcrumbs=new d.Breadcrumbs(this.options.breadcrumbLimit),this._backtraceApi=new i.BacktraceApi(this.getSubmitUrl(),this.options.timeout),this._clientRateLimit=new n.ClientRateLimit(this.options.rateLimit),this.registerHandlers(),this.attributes=this.getClientAttributes(),this.options.enableMetricsSupport&&(this._backtraceMetrics=new a.BacktraceMetrics(t,()=>this.getClientAttributes()))}getClientAttributes(){return Object.assign(Object.assign({},this.readAttributes()),this.options.userAttributes)}memorize(t,e){this.attributes[t]=e}setAttribute(t,e){this.attributes[t]=e}createReport(t,e={},r){const i=this.breadcrumbs.isEnabled()?this.breadcrumbs.get():void 0,n=new c.BacktraceReport(t,e,i,r);return n.send=t=>{this.sendAsync(n).then(()=>{t&&t(void 0)}).catch(e=>{t&&t(e)})},n.sendSync=t=>{this.sendReport(n,t)},n}async reportAsync(t,e={},r){const i=this.createReport(t,e,r);return new Promise((t,e)=>{this.sendReport(i,(r,i)=>{!r&&i?t(i):e(r)})})}reportSync(t,e={},r){const i=this.createReport(t,e,r);return this.sendReport(i)}sendReport(t,e){if(!t.uuid)throw new Error("Invalid backtrace report object. Please pass an instance of the Backtrace report object.");if(this.options.filter&&this.options.filter(t))return u.BacktraceResult.OnFilterHit(t);const r=this.testClientLimits(t);return r||(t.addObjectAttributes(this.attributes),this._backtraceApi.send(t).then(t=>{this.breadcrumbs.isEnabled()&&this.breadcrumbs.add("Report sent to Backtrace",{error:t.Error,message:t.Message,objectId:t.ObjectId},Date.now(),"error","log"),e&&e(t.Error,t)}).catch(t=>{e&&e(t)}),u.BacktraceResult.Processing(t))}async sendAsync(t){if(this.options.filter&&this.options.filter(t))return u.BacktraceResult.OnFilterHit(t);const e=this.testClientLimits(t);return e||await this._backtraceApi.send(t)}testClientLimits(t){if(this.samplingHit())return u.BacktraceResult.OnSamplingHit(t);return this._clientRateLimit.skipReport(t)?u.BacktraceResult.OnLimitReached(t):void 0}samplingHit(){return!!this.options.sampling&&Math.random()>this.options.sampling}getSubmitUrl(){const t=this.options.endpoint;if(t.includes("submit.backtrace.io")||t.includes("token="))return t;if(!this.options.token)throw new Error("Token configuration option is required for this type of submission url.");const e=t.endsWith("/")?"":"/";return`${this.options.endpoint}${e}post?format=json&token=${this.options.token}`}registerHandlers(){this.options.disableGlobalHandler||this.registerGlobalHandler(),this.options.handlePromises&&this.registerPromiseHandler()}registerPromiseHandler(){window.onunhandledrejection=t=>{const e=new Error(t.reason),r=this.createReport(e);r.addAnnotation("onunhandledrejection",t),this.sendReport(r)}}registerGlobalHandler(){window.onerror=(t,e,r,i,n)=>{n||(n="string"==typeof t?new Error(t):new Error(t.error)),this.reportSync(n,{"exception.lineNumber":r,"exception.columnNumber":i})}}readAttributes(){const t=h.getBrowserName();return{application:document.title||"unknown","process.age":Math.floor(((new Date).getTime()-s.pageStartTime.getTime())/1e3),hostname:window.location&&window.location.hostname,referer:window.location&&window.location.href,"user.agent.full":navigator.userAgent,"location.port":document.location.port,"location.protocol":document.location.protocol,"location.origin":window.location.origin,"location.href":window.location.href||document.URL,language:navigator.language,"browser.name":t,"browser.version":h.getBrowserVersion(t),"browser.platform":navigator.platform,"browser.vendor":navigator.vendor,"cookies.enable":navigator.cookieEnabled,"document.domain":document.domain,"document.baseURI":document.baseURI,"document.title":document.title,"document.referrer":document.referrer,mobile:h.isMobile(),"localstorage.enable":!!window.localStorage,"uname.sysname":h.getOs(),"window.innerHeight":window.innerHeight,"window.innerWidth":window.innerWidth,"window.outerHeight":window.outerHeight,"window.outerWidth":window.outerWidth,"window.pageXOffset":window.pageXOffset,"window.pageYOffset":window.pageYOffset,"window.screenX":window.screenX,"window.screenY":window.screenY,"window.screenLeft":window.screenLeft,"window.screenTop":window.screenTop,"backtrace.version":"1.1.0",guid:l.getBacktraceGUID()}}}},function(t,e,r){"use strict";var i;Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceResult=e.BacktraceResultStatus=void 0,function(t){t[t.SamplingHit=0]="SamplingHit",t[t.LimitReached=1]="LimitReached",t[t.ServerError=2]="ServerError",t[t.Ok=4]="Ok",t[t.InProcessing=8]="InProcessing",t[t.FilterHit=16]="FilterHit"}(i=e.BacktraceResultStatus||(e.BacktraceResultStatus={}));class n{constructor(t,e,r,i,n){this.report=t,this.message=e,this.status=r,this.err=i,this._objectId="",this._rxId="",n&&(this._rxId=n._rxid,this._objectId=n.object,this.message=n.message?n.message:e)}static Processing(t){return new n(t,"Data were send to API and waiting for server result",i.InProcessing)}static Ok(t,e){return new n(t,"Report is available on the Backtrace server",i.Ok,void 0,e)}static OnLimitReached(t){return new n(t,"Client report limit reached",i.LimitReached)}static OnSamplingHit(t){return new n(t,"Sampling hit",i.SamplingHit)}static OnFilterHit(t){return new n(t,"Filter hit",i.FilterHit)}static OnError(t,e){return new n(t,e.message,i.ServerError,e)}get ObjectId(){return this._objectId?this._objectId:this._rxId}get Report(){return this.report}get Message(){return this.message}get Error(){return this.err}get Status(){return this.status}}e.BacktraceResult=n},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceClientOptions=void 0;e.BacktraceClientOptions=class{constructor(){this.timeout=15e3,this.userAttributes={},this.disableGlobalHandler=!1,this.handlePromises=!1,this.sampling=void 0,this.rateLimit=0,this.filter=void 0,this.breadcrumbLimit=-1,this.enableMetricsSupport=!0,this.debugBacktrace=!1,this.tabWidth=8,this.contextLineCount=200}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceReport=void 0;const i=r(11),n=r(6),s=r(12),o=r(0);e.BacktraceReport=class{constructor(t="",e={},r,i){this.err=t,this.clientAttributes=e,this.breadcrumbs=r,this.attachment=i,this.uuid=o.uuid(),this.timestamp=o.currentTimestamp(),this.lang=s.LANG,this.langVersion=s.USER_AGENT,this.agent=s.APP_NAME,this.agentVersion=s.VERSION,this.mainThread=s.THREAD,this.classifiers=[],this.attributes={},this.annotations={},e||(e={}),this.splitAttributesFromAnnotations(e),this.setError(t)}isExceptionTypeReport(){return this.detectReportType(this.err)}getPayload(){return this.err}setError(t){this.err=t,this.classifiers=this.detectReportType(t)?[t.name]:[]}log(t){console.log(t)}trace(t){console.trace(t)}addObjectAttributes(t){this.clientAttributes=Object.assign(Object.assign(Object.assign({},this.clientAttributes),this.attributes),t)}addAttribute(t,e){this.clientAttributes[t]=e}addAnnotation(t,e){this.annotations[t]=e}toJson(){this.collectReportInformation();const t={uuid:this.uuid,timestamp:this.timestamp,lang:this.lang,langVersion:this.langVersion,mainThread:this.mainThread,classifiers:this.classifiers,threads:{main:this.stackTrace.toJson()},agent:this.agent,agentVersion:this.agentVersion,annotations:this.annotations,attributes:this.attributes};return this.sourceCode&&this.sourceCode.text&&(t.sourceCode={main:this.sourceCode}),this.attributes.symbolication_id&&(t.symbolication="sourcemap"),t}toFormData(){const t=this.toJson(),e=new FormData,r=new Blob([JSON.stringify(t)]);if(e.append("upload_file",r,"upload_file.json"),this.breadcrumbs){const t=new Blob([JSON.stringify(this.breadcrumbs)]);e.append(n.Breadcrumbs.attachmentName,t,n.Breadcrumbs.attachmentName)}if(this.attachment){const t=new Blob([JSON.stringify(this.attachment)]),r="attachment_"+Date.now();e.append(r,t,r)}return e}setSourceCodeOptions(t,e){}collectReportInformation(){this.stackTrace=new i.BacktraceStackTrace(this.err),this.attributes=Object.assign(Object.assign({},this.readErrorAttributes()),this.clientAttributes),this.annotations=this.readAnnotation()}detectReportType(t){return t instanceof Error}readErrorAttributes(){return this.detectReportType(this.err)?(this.classifiers=[this.err.name],{"error.message":this.err.message}):{"error.message":this.err}}readAnnotation(){return Object.assign({Memory:window.performance?window.performance:performance.timing,Geolocation:navigator.geolocation,Screen:{"screen.availHeight":window.screen.availHeight,"screen.availWidth":window.screen.availWidth,"screen.height":window.screen.height,"screen.width":window.screen.width,"screen.orientation":window.screen.orientation.type,"screen.colorDepth":window.screen.colorDepth,"screen.pixelDepth":window.screen.pixelDepth},Exception:this.getSerializableError()},this.annotations)}getSerializableError(){if("string"==typeof this.err)return{message:this.err};const t={},e=this;return Object.getOwnPropertyNames(this.err).forEach(r=>{t[r]=e.err[r]}),t}splitAttributesFromAnnotations(t){for(const e in t)if(t.hasOwnProperty(e)){const t=this.clientAttributes[e];if(!t)continue;"object"==typeof t?this.annotations[e]=t:this.attributes[e]=t}}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Breadcrumbs=void 0;class i{constructor(t){this.breadcrumbLimit=-1,this._breadcrumbs=[],this.id=0,this.breadcrumbLimit=!t||t<=0?-1:t}add(t,e={},r=this.getNowTimestamp(),i="info",n="manual"){if(this.breadcrumbLimit<0)return;for(;this._breadcrumbs.length===this.breadcrumbLimit;)this._breadcrumbs.shift();const s={id:this.id++,timestamp:r,level:i,type:n,message:t,attributes:e};this._breadcrumbs.push(s)}get(){return this._breadcrumbs}isEnabled(){return this.breadcrumbLimit>0}getNowTimestamp(){return Date.now()}}e.Breadcrumbs=i,i.attachmentName="bt-breadcrumbs-0"},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceApi=void 0;const i=r(3);e.BacktraceApi=class{constructor(t,e){this._backtraceUri=t,this._timeout=e}async send(t){try{const e=t.toFormData();return new Promise((r,n)=>{const s=new XMLHttpRequest;s.timeout=this._timeout,s.open("POST",this._backtraceUri,!0),s.send(e),s.onload=e=>{s.readyState===XMLHttpRequest.DONE&&(200===s.status?r(i.BacktraceResult.Ok(t,s.responseText)):429===s.status?r(i.BacktraceResult.OnError(t,new Error("Backtrace - reached report limit."))):r(i.BacktraceResult.OnError(t,new Error("Invalid attempt to submit error to Backtrace. Result: "+s.responseText))))},s.onerror=t=>{n(t)}})}catch(e){return i.BacktraceResult.OnError(t,e)}}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ClientRateLimit=void 0;e.ClientRateLimit=class{constructor(t){if(this.reportPerMin=t,this._reportQueue=[],t<0)throw new Error("ReportPerMinute argument must be greater or equal to zero");this._watcherEnable=t>0}skipReport(t){return!!this._watcherEnable&&(this.clear(),this._reportQueue.length>=this.reportPerMin||(this._reportQueue.push(t.timestamp),!1))}clear(){const t=Math.floor((new Date).getTime()/1e3);0!==this._reportQueue.length&&t-this._reportQueue[0]>60&&(this._reportQueue.length=0)}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceMetrics=void 0;const i=r(10),n=r(0);e.BacktraceMetrics=class{constructor(t,e){var r;if(this.attributeProvider=e,this.persistenceInterval=18e5,this.heartbeatInterval=6e4,this.timestamp=n.currentTimestamp(),!t.endpoint)throw new Error("Backtrace: missing 'endpoint' option.");const i=n.getEndpointParams(t.endpoint,t.token);if(!i)throw new Error("Invalid Backtrace submission parameters. Cannot create a submission URL to metrics support");const{universe:s,token:o}=i;if(!s)throw new Error("Backtrace: 'universe' could not be parsed from the endpoint.");if(!o)throw new Error("Backtrace: missing 'token' option or it could not be parsed from the endpoint.");this.universe=s,this.token=o,this.hostname=null!==(r=t.metricsSubmissionUrl)&&void 0!==r?r:"https://events.backtrace.io",this.summedEndpoint=`${this.hostname}/api/summed-events/submit?universe=${this.universe}&token=${this.token}`,this.uniqueEndpoint=`${this.hostname}/api/unique-events/submit?universe=${this.universe}&token=${this.token}`;const a=this.getSessionId();a?this.sessionId=a:(this.sessionId=this.createNewSession(),this.sendUniqueEvent(),this.sendSummedEvent("Application Launches")),this.lastActive=this.getLastActive(),this.persistSession();setInterval(()=>this.persistIfFocused(),this.heartbeatInterval)}persistSession(){(this.lastActive||this.timestamp)<this.timestamp-this.persistenceInterval/i.SEC_TO_MILLIS&&(this.createNewSession(),this.sendUniqueEvent()),this.setLastActive(this.timestamp)}persistIfFocused(){document.hidden||this.persistSession()}async sendUniqueEvent(){const t=this.getEventAttributes(),e={application:t.application,appversion:t["application.version"],metadata:{dropped_events:0},unique_events:[{timestamp:n.currentTimestamp(),unique:["guid"],attributes:this.getEventAttributes()}]};await n.post(this.uniqueEndpoint,e)}async sendSummedEvent(t){const e=this.getEventAttributes(),r={application:e.application,appversion:e["application.version"],metadata:{dropped_events:0},summed_events:[{timestamp:n.currentTimestamp(),metric_group:t,attributes:this.getEventAttributes()}]};await n.post(this.summedEndpoint,r)}getEventAttributes(){const t=this.attributeProvider(),e={"application.session":this.sessionId,"application.version":"unknown"};for(const r in t)if(Object.prototype.hasOwnProperty.call(t,r)){const i=t[r],n=typeof i;if("string"===n||"boolean"===n||"number"===n){const t=i.toString();t&&(e[r]=t)}}return e}createNewSession(){const t=n.uuid();return this.sessionId=t,this.lastActive=this.timestamp,localStorage.setItem("sessionId",t),this.setLastActive(this.timestamp),t}getSessionId(){return localStorage.getItem("sessionId")||void 0}getLastActive(){const t=localStorage.getItem("lastActive");return t?parseInt(t,10):void 0}setLastActive(t=this.timestamp){this.lastActive=t,localStorage.setItem("lastActive",t.toString())}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SEC_TO_MILLIS=void 0,e.SEC_TO_MILLIS=1e3},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BacktraceStackTrace=void 0;e.BacktraceStackTrace=class{constructor(t){this.fault=!0,this.name="main",this.stack=[],this.stackLineRe=/^\s+at (?:([^\s]+) )?\(?(.+):(\d+):(\d+)\)?$/,t instanceof Error||(t=new Error),this.error=t,this.parseStackFrames()}toJson(){return{name:this.name,fault:this.fault,stack:this.stack}}parseStackFrames(){const t=this.error.stack;if(!t)return;t.split("\n").slice(1).forEach(t=>{const e=t.match(this.stackLineRe);if(!e||e.length<4)return;const r=e[2];if(-1!==r.indexOf("node_modules/backtrace-js"))return;const i={funcName:e[1]?e[1]:"unknown",library:r.substring(r.lastIndexOf("/")+1),line:parseInt(e[3],10),column:parseInt(e[4],10)};0===this.stack.length&&(i.sourceCode="main"),this.stack.push(i)})}}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.THREAD=e.LANG=e.USER_AGENT=e.VERSION=e.APP_NAME=void 0,e.APP_NAME="backtrace-js",e.VERSION="1.1.0",e.USER_AGENT=navigator.userAgent,e.LANG="js",e.THREAD="main"},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isMobile=e.getOs=e.getBrowserName=e.getBrowserVersion=void 0;const i=["safari","chrome","edge","opera","firefox"];e.getBrowserVersion=function(t){if("safari"===t&&(t="version"),t)return new RegExp(t+"[\\/ ]([\\d\\w\\.-]+)","i").exec(navigator.appVersion)&&RegExp.$1||void 0;{const t=navigator.appVersion.match(/version[\/ ]([\d\w\.]+)/i);return t&&t.length>1?t[1]:void 0}},e.getBrowserName=function(){const t=navigator.userAgent.toLowerCase();for(const e of i)if(-1!==t.indexOf(e))return e;return"unknown"},e.getOs=function(){const t=window.navigator.platform;return["Macintosh","MacIntel","MacPPC","Mac68K"].some(e=>e===t)||["Win32","Win64","Windows","WinCE"].some(e=>e===t)?"MacOS":["iPhone","iPad","iPod"].some(e=>e===t)?"iOS":-1!==window.navigator.userAgent.indexOf("Android")?"Android":navigator.appVersion.indexOf("Linux")||navigator.appVersion.indexOf("X11")?"Linux":"unknown"},e.isMobile=function(){return/(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(navigator.userAgent.toLowerCase())}}])})); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "backtrace-js", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "Backtrace.io error reporting tool for client-side applications", | ||
@@ -27,3 +27,3 @@ "browser": "./lib/index.js", | ||
"scripts": { | ||
"test": "mocha --require ts-node/register -r ./tsconfig.json --project tsconfig.json test/**/*.ts", | ||
"test": "NODE_ENV=test jest", | ||
"lint": "tslint -p ./tsconfig.json", | ||
@@ -37,3 +37,9 @@ "format": "prettier --write \"source/**/*.ts\" \"source/**/*.js\"", | ||
"devDependencies": { | ||
"@types/jest": "^27.0.3", | ||
"@types/jsdom": "^16.2.14", | ||
"fork-ts-checker-webpack-plugin": "^1.4.3", | ||
"jest": "^27.4.5", | ||
"jsdom": "^19.0.0", | ||
"prettier": "^2.5.1", | ||
"ts-jest": "^27.1.2", | ||
"ts-loader": "^6.0.4", | ||
@@ -40,0 +46,0 @@ "ts-node": "^8.0.3", |
@@ -9,13 +9,13 @@ # backtrace-js | ||
// Import backtrace-js with your favorite package manager. | ||
import * as bt from 'backtrace-js'; | ||
import * as backtrace from 'backtrace-js'; | ||
bt.initialize({ | ||
endpoint: `https://console.backtrace.io:${BACKTRACE_PORT}`, | ||
token: '51cc8e69c5b62fa8c72dc963e730f1e8eacbd243aeafc35d08d05ded9a024121', | ||
backtrace.initialize({ | ||
endpoint: 'https://submit.backtrace.io/<universe>/<submit_token>/json', | ||
}); | ||
// Later, when you have an error: | ||
bt.report(new Error('something broke')); | ||
backtrace.report(new Error('something broke')); | ||
``` | ||
## Documentation | ||
@@ -31,6 +31,70 @@ | ||
#### Options | ||
See [backtrace-node](https://github.com/backtrace-labs/backtrace-node#documentation)'s documentation for the complete options list. | ||
In addition to all [backtrace-node](https://github.com/backtrace-labs/backtrace-node#documentation)'s options, Backtrace-JS includes `sampling` and `filter`. | ||
##### `endpoint` | ||
Required. | ||
Example: `https://backtrace.example.com:6098`. | ||
Sets the HTTP/HTTPS endpoint that error reports will be sent to. If the user uses submit.backtrace.io - the token option is optional. By default, if the user uses a different URL (not submit.backtrace.io), then the user needs to include a token option. | ||
##### `token` | ||
Required if you're not using integration via submit.backtrace.io. | ||
Example: `51cc8e69c5b62fa8c72dc963e730f1e8eacbd243aeafc35d08d05ded9a024121`. | ||
Sets the token that will be used for authentication when sending an error | ||
report. | ||
##### `handlePromises` | ||
Optional. Set to `true` to listen to the `unhandledRejection` global event and | ||
report those errors in addition to `uncaughtException` events. | ||
Defaults to `false` because an application can technically add a promise | ||
rejection handler after an event loop iteration, which would cause the | ||
`unhandledRejection` event to fire, followed by the `rejectionHandled` event | ||
when the handler was added later. This would make the error report a false | ||
positive. However, most applications will add rejection handlers before an | ||
event loop iteration, in which case `handlePromises` should be set to `true`. | ||
##### `userAttributes` | ||
Optional. Object that contains additional attributes to be sent along with | ||
every error report. These can be overridden on an individual report with | ||
`report.addAttribute`. | ||
Example: | ||
``` | ||
{ | ||
application: "ApplicationName", | ||
serverId: "foo", | ||
} | ||
``` | ||
##### `timeout` | ||
Defaults to `15000`. Maximum amount of milliseconds to wait for child process | ||
to process error report and schedule sending the report to Backtrace. | ||
##### `allowMultipleUncaughtExceptionListeners` | ||
Defaults to `false`. Set to `true` to not crash when another `uncaughtException` | ||
listener is detected. | ||
##### `disableGlobalHandler` | ||
Defaults to `false`. If this is `false`, this module will attach an | ||
`uncaughtException` handler and report those errors automatically before | ||
re-throwing the exception. | ||
Set to `true` to disable this. Note that in this case the only way errors | ||
will be reported is if you call `bt.report(error)`. | ||
#### `rateLimit` | ||
Backtrace-js supports client rate limiting! You can define how many reports per one minute you want to send to Backtrace by adding the additional option to the BacktraceClientOptions object. Now, when you reach the defined limit, the client will skip the current report. | ||
##### `sampling` | ||
@@ -78,2 +142,8 @@ Optional. | ||
#### Metrics support | ||
Backtrace-JS allows to capture metrics data and send them to Backtrace. By default, the metrics support is enabled. To disable it, the user needs to set `enableMetricsSupport` to false. | ||
#### MetricsSubmissionUrl | ||
Optional variable that allows to override the default URL to the metrics servers. | ||
## Testing | ||
@@ -80,0 +150,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
117603
23
587
153
16
2