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

backtrace-js

Package Overview
Dependencies
Maintainers
6
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

backtrace-js - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

lib/source/backtraceApi.d.ts

3

CHANGELOG.md
# 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.

2

lib/index.js

@@ -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

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