scout-error 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # scout-error
2
+
3
+ Lightweight error tracking for JavaScript applications. Works with any framework or vanilla JS, plus Node.js backends.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install scout-error
9
+ ```
10
+
11
+ ## Browser (Vanilla)
12
+
13
+ ```js
14
+ import { init } from 'scout-error'
15
+
16
+ init({
17
+ app: 'My App',
18
+ project: 'my-project',
19
+ version: '1.0.0',
20
+ }, {
21
+ endpoint: 'https://your-scout-instance.com/errors',
22
+ })
23
+ ```
24
+
25
+ ## Vue.js
26
+
27
+ ```js
28
+ import { init } from 'scout-error'
29
+ import { ScoutVue } from 'scout-error/vue'
30
+
31
+ init({
32
+ app: 'My App',
33
+ project: 'my-project',
34
+ version: '1.0.0',
35
+ }, {
36
+ endpoint: 'https://your-scout-instance.com/errors',
37
+ })
38
+
39
+ const app = createApp(App)
40
+ app.use(ScoutVue) // Captures Vue component errors and warnings
41
+ app.mount('#app')
42
+ ```
43
+
44
+ ## React
45
+
46
+ ```jsx
47
+ import { init } from 'scout-error'
48
+ import { ScoutErrorBoundary } from 'scout-error/react'
49
+
50
+ init({
51
+ app: 'My App',
52
+ project: 'my-project',
53
+ version: '1.0.0',
54
+ }, {
55
+ endpoint: 'https://your-scout-instance.com/errors',
56
+ })
57
+
58
+ <ScoutErrorBoundary fallback={<p>Something went wrong</p>}>
59
+ <App />
60
+ </ScoutErrorBoundary>
61
+ ```
62
+
63
+ ## Node.js + Express
64
+
65
+ ```js
66
+ import { initTracker, errorHandlingMiddleware } from 'scout-error/node'
67
+
68
+ initTracker({
69
+ environment: 'production',
70
+ project: 'my-backend',
71
+ release: '1.0.0',
72
+ }, {
73
+ endpoint: 'https://your-scout-instance.com/errors',
74
+ })
75
+
76
+ // Add as last middleware
77
+ app.use(errorHandlingMiddleware)
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ Options passed as the second argument to `init()` / `initTracker()`:
83
+
84
+ | Option | Default | Description |
85
+ |---|---|---|
86
+ | `endpoint` | `''` | URL to send errors to |
87
+ | `sampleRate` | `1.0` | Fraction of errors to capture (0.0 - 1.0) |
88
+ | `debug` | `false` | Log captured errors to console |
89
+ | `ignoreErrors` | `null` | Array of string/regex patterns to ignore |
90
+ | `sendErrors` | `true` | Enable/disable sending |
91
+
92
+ ## Manual Capture
93
+
94
+ ```js
95
+ import { captureError } from 'scout-error'
96
+
97
+ try {
98
+ riskyOperation()
99
+ } catch (err) {
100
+ captureError({
101
+ message: err.message,
102
+ stack: err.stack,
103
+ type: 'manual',
104
+ })
105
+ }
106
+ ```
107
+
108
+ ## License
109
+
110
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ var f=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var k=(e,r)=>{for(var o in r)f(e,o,{get:r[o],enumerable:!0})},T=(e,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of b(r))!_.call(e,s)&&s!==o&&f(e,s,{get:()=>r[s],enumerable:!(t=I(r,s))||t.enumerable});return e};var R=e=>T(f({},"__esModule",{value:!0}),e);var O={};k(O,{captureError:()=>v,init:()=>D});module.exports=R(O);var C={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},n={...C},i={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},u={clicks:0,scrolls:0},g=null,m=!1;var c=console.warn;var h=console.log;function p(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function P(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",p("user")),localStorage.getItem("__scoutUserId")),r=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",p("session")),sessionStorage.getItem("__scoutSessionId"));return g=g||p("pageload"),{pageloadId:g,userId:e,sessionId:r}}function M(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(o=>e.match(o.p))?.n||"Unknown"}function L(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(o=>e.match(o.p))?.n||"Unknown"}function U(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:M(),browserVersion:window._uaParserResult?.browser?.version||null,os:L(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:u.clicks,userScrolls:u.scrolls}}function l(e){return!n.ignoreErrors||!Array.isArray(n.ignoreErrors)?!1:n.ignoreErrors.some(r=>typeof r=="string"?e.includes(r):r instanceof RegExp?r.test(e):!1)}function A(e,r){let o=new AbortController,t=setTimeout(()=>o.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:o.signal}).then(s=>(clearTimeout(t),s)).catch(()=>{clearTimeout(t)})}function d(e){let r=(e[0]||"")+"",o=[...e];return r.replace(/%[sdj]/g,t=>{let s=o.shift();return t==="%s"?String(s):t==="%d"?Number(s):t==="%j"?JSON.stringify(s):t})}async function a(e){let r=n.browserDetails?U():{},o=Object.assign(e,r,i,P());if(n.sampleRate&&Math.random()<1-parseFloat(n.sampleRate)){n.debug&&h("[Scout] Suppressed by sampling");return}if(n.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let t=e.errorTrace||e.stack,s=t?t.split(`
2
+ `):[],E=s.length>1?s[1].trim():"",[,w,S,y]=E.match(/(http.*?):(\d+):(\d+)/)||[];w&&(e.source=w,e.lineno=parseInt(S,10),e.colno=parseInt(y,10))}catch{}n.debug&&h("[Scout] Sending:",o),n.endpoint&&A(n.endpoint,o)}function v(e){n.enabled&&a(e)}function x(){if(n.trackUserInteractions){document.addEventListener("click",()=>{u.clicks++});let e=0;window.addEventListener("scroll",()=>{let r=Date.now();r-e>100&&(u.scrolls++,e=r)})}if(n.addErrorEventListener&&window.addEventListener("error",async e=>{if(n.enabled){try{let r=e.error?e.error.stack:"No stack trace available";if(l(e.message))return;n.sendErrors&&a({type:"window.onerror",message:e.message,source:e.filename,lineno:e.lineno,colno:e.colno,errorTrace:r})}catch(r){c("[Scout] Error handler failure:",r)}n.selfHealingErrors&&e.preventDefault()}}),n.addUnhandledRejectionEventListener&&window.addEventListener("unhandledrejection",e=>{if(n.enabled){try{let r=e.reason,o=r?.stack||"No stack trace available";if(l(r?.message||""))return;n.sendErrors&&a({type:"Unhandled Promise Rejection",message:r?.message||"Unhandled Promise Rejection",reason:e.reason,errorTrace:o})}catch(r){c("[Scout] Rejection handler failure:",r)}n.selfHealingErrors&&e.preventDefault()}}),n.overrideConsoleError&&(console.error=function(...e){if(n.enabled)try{let r=new Error().stack;if(l(d(e)))return;n.sendErrors&&a({type:"console.error",errorTrace:r,args:d(e)})}catch(r){c("[Scout] console.error override failure:",r)}}),n.overrideConsoleWarn&&(console.warn=function(...e){if(n.enabled)try{let r=new Error().stack;if(l(d(e)))return;n.sendErrors&&a({type:"console.warn",errorTrace:r,args:d(e)})}catch(r){c("[Scout] console.warn override failure:",r)}}),n.loadUAParser&&n.browserDetails){let e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js",e.async=!0,e.onload=()=>{typeof UAParser<"u"&&(window._uaParserResult=new UAParser().getResult())},document.head.appendChild(e)}}function D(e={},r={}){if(m){i={...i,...e},n={...n,...r};return}i={...i,...e},n={...n,...r},m=!0,typeof window<"u"&&(x(),window.Scout={init:(o,t)=>{i={...i,...o},t&&(n={...n,...t})},setScope:o=>{i={...i,...o}},setConfig:o=>{n={...n,...o}},error:v})}
3
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["index_exports", "__export", "captureError", "init", "__toCommonJS", "defaultConfig", "config", "scope", "userInteractions", "pageloadId", "initialized", "_consoleWarn", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "captureBrowserDetails", "conn", "userInteractions", "shouldIgnoreError", "msg", "config", "pattern", "postData", "url", "data", "controller", "timeout", "r", "argsToString", "args", "fmt", "rest", "m", "v", "pushErrorEvent", "obj", "details", "event", "scope", "stack", "lines", "loc", "source", "lineno", "colno", "captureError", "setupListeners", "lastScroll", "now", "errorTrace", "e", "_consoleWarn", "error", "s", "init", "scopeOptions", "configOptions", "initialized", "c"]
7
+ }
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ var S={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},n={...S},s={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},u={clicks:0,scrolls:0},f=null,w=!1;var c=console.warn;var m=console.log;function g(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function y(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",g("user")),localStorage.getItem("__scoutUserId")),r=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",g("session")),sessionStorage.getItem("__scoutSessionId"));return f=f||g("pageload"),{pageloadId:f,userId:e,sessionId:r}}function I(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(o=>e.match(o.p))?.n||"Unknown"}function b(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(o=>e.match(o.p))?.n||"Unknown"}function _(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:I(),browserVersion:window._uaParserResult?.browser?.version||null,os:b(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:u.clicks,userScrolls:u.scrolls}}function l(e){return!n.ignoreErrors||!Array.isArray(n.ignoreErrors)?!1:n.ignoreErrors.some(r=>typeof r=="string"?e.includes(r):r instanceof RegExp?r.test(e):!1)}function k(e,r){let o=new AbortController,t=setTimeout(()=>o.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:o.signal}).then(i=>(clearTimeout(t),i)).catch(()=>{clearTimeout(t)})}function d(e){let r=(e[0]||"")+"",o=[...e];return r.replace(/%[sdj]/g,t=>{let i=o.shift();return t==="%s"?String(i):t==="%d"?Number(i):t==="%j"?JSON.stringify(i):t})}async function a(e){let r=n.browserDetails?_():{},o=Object.assign(e,r,s,y());if(n.sampleRate&&Math.random()<1-parseFloat(n.sampleRate)){n.debug&&m("[Scout] Suppressed by sampling");return}if(n.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let t=e.errorTrace||e.stack,i=t?t.split(`
2
+ `):[],h=i.length>1?i[1].trim():"",[,p,v,E]=h.match(/(http.*?):(\d+):(\d+)/)||[];p&&(e.source=p,e.lineno=parseInt(v,10),e.colno=parseInt(E,10))}catch{}n.debug&&m("[Scout] Sending:",o),n.endpoint&&k(n.endpoint,o)}function T(e){n.enabled&&a(e)}function R(){if(n.trackUserInteractions){document.addEventListener("click",()=>{u.clicks++});let e=0;window.addEventListener("scroll",()=>{let r=Date.now();r-e>100&&(u.scrolls++,e=r)})}if(n.addErrorEventListener&&window.addEventListener("error",async e=>{if(n.enabled){try{let r=e.error?e.error.stack:"No stack trace available";if(l(e.message))return;n.sendErrors&&a({type:"window.onerror",message:e.message,source:e.filename,lineno:e.lineno,colno:e.colno,errorTrace:r})}catch(r){c("[Scout] Error handler failure:",r)}n.selfHealingErrors&&e.preventDefault()}}),n.addUnhandledRejectionEventListener&&window.addEventListener("unhandledrejection",e=>{if(n.enabled){try{let r=e.reason,o=r?.stack||"No stack trace available";if(l(r?.message||""))return;n.sendErrors&&a({type:"Unhandled Promise Rejection",message:r?.message||"Unhandled Promise Rejection",reason:e.reason,errorTrace:o})}catch(r){c("[Scout] Rejection handler failure:",r)}n.selfHealingErrors&&e.preventDefault()}}),n.overrideConsoleError&&(console.error=function(...e){if(n.enabled)try{let r=new Error().stack;if(l(d(e)))return;n.sendErrors&&a({type:"console.error",errorTrace:r,args:d(e)})}catch(r){c("[Scout] console.error override failure:",r)}}),n.overrideConsoleWarn&&(console.warn=function(...e){if(n.enabled)try{let r=new Error().stack;if(l(d(e)))return;n.sendErrors&&a({type:"console.warn",errorTrace:r,args:d(e)})}catch(r){c("[Scout] console.warn override failure:",r)}}),n.loadUAParser&&n.browserDetails){let e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js",e.async=!0,e.onload=()=>{typeof UAParser<"u"&&(window._uaParserResult=new UAParser().getResult())},document.head.appendChild(e)}}function C(e={},r={}){if(w){s={...s,...e},n={...n,...r};return}s={...s,...e},n={...n,...r},w=!0,typeof window<"u"&&(R(),window.Scout={init:(o,t)=>{s={...s,...o},t&&(n={...n,...t})},setScope:o=>{s={...s,...o}},setConfig:o=>{n={...n,...o}},error:T})}export{T as captureError,C as init};
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["defaultConfig", "config", "scope", "userInteractions", "pageloadId", "initialized", "_consoleWarn", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "captureBrowserDetails", "conn", "userInteractions", "shouldIgnoreError", "msg", "config", "pattern", "postData", "url", "data", "controller", "timeout", "r", "argsToString", "args", "fmt", "rest", "m", "v", "pushErrorEvent", "obj", "details", "event", "scope", "stack", "lines", "loc", "source", "lineno", "colno", "captureError", "setupListeners", "lastScroll", "now", "errorTrace", "e", "_consoleWarn", "error", "s", "init", "scopeOptions", "configOptions", "initialized", "c"]
7
+ }
package/dist/node.cjs ADDED
@@ -0,0 +1,2 @@
1
+ var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var a in e)i(t,a,{get:e[a],enumerable:!0})},m=(t,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of p(e))!d.call(t,s)&&s!==a&&i(t,s,{get:()=>e[s],enumerable:!(o=u(e,s))||o.enumerable});return t};var g=t=>m(i({},"__esModule",{value:!0}),t);var h={};l(h,{captureError:()=>f,errorHandlingMiddleware:()=>S,initTracker:()=>k});module.exports=g(h);var r={debug:!1,endpoint:"",sendErrors:!0,captureUserDetails:!1,captureRequestDetails:!0,captureStackTrace:!0},n={environment:"production",project:null,release:null,version:null,sdk:"node",user:null};function c(t){r.debug&&console.error("[Scout]:",t),r.endpoint&&r.sendErrors&&fetch(r.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).catch(e=>{console.error("[Scout] Failed to send error:",e.message)})}function k(t={},e={}){n={...n,...t},r={...r,...e},process.on("uncaughtException",a=>{c({type:"uncaughtException",message:a.message,stack:a.stack,errorTrace:a.stack,timestamp:new Date().toISOString(),...n})}),process.on("unhandledRejection",a=>{c({type:"unhandledRejection",message:a?.message||"Unhandled Promise Rejection",stack:a?.stack||"No stack trace",errorTrace:a?.stack||"No stack trace",timestamp:new Date().toISOString(),...n})})}function S(t,e,a,o){c({type:"expressError",message:t.message,stack:r.captureStackTrace?t.stack:void 0,errorTrace:r.captureStackTrace?t.stack:void 0,path:e.originalUrl,method:e.method,params:e.params,query:e.query,headers:r.captureRequestDetails?e.headers:void 0,user:r.captureUserDetails?e.user:void 0,timestamp:new Date().toISOString(),...n}),a.status(500).json({error:"Internal Server Error"})}function f(t,e={}){c({type:"manual",message:t?.message||String(t),stack:t?.stack,errorTrace:t?.stack,timestamp:new Date().toISOString(),...e,...n})}0&&(module.exports={captureError,errorHandlingMiddleware,initTracker});
2
+ //# sourceMappingURL=node.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/node.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Node.js SDK\n *\n * Captures uncaught exceptions, unhandled rejections, and Express errors.\n *\n * Usage:\n * const { initTracker, errorHandlingMiddleware } = require('scoutjs/node')\n *\n * initTracker(\n * { environment: 'production', project: 'my-backend', release: '1.0.0' },\n * { endpoint: 'https://your-scout-instance.com/errors' }\n * )\n *\n * app.use(errorHandlingMiddleware)\n */\n\nlet config = {\n debug: false,\n endpoint: '',\n sendErrors: true,\n captureUserDetails: false,\n captureRequestDetails: true,\n captureStackTrace: true,\n}\n\nlet scope = {\n environment: 'production',\n project: null,\n release: null,\n version: null,\n sdk: 'node',\n user: null,\n}\n\nfunction logError(details) {\n if (config.debug) {\n console.error('[Scout]:', details)\n }\n\n if (config.endpoint && config.sendErrors) {\n fetch(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(details),\n }).catch(err => {\n console.error('[Scout] Failed to send error:', err.message)\n })\n }\n}\n\n/**\n * Initialize the Node.js error tracker.\n *\n * @param {Object} customScope - { environment, project, release, version }\n * @param {Object} customConfig - { endpoint, debug, sendErrors, ... }\n */\nexport function initTracker(customScope = {}, customConfig = {}) {\n scope = { ...scope, ...customScope }\n config = { ...config, ...customConfig }\n\n process.on('uncaughtException', (error) => {\n logError({\n type: 'uncaughtException',\n message: error.message,\n stack: error.stack,\n errorTrace: error.stack,\n timestamp: new Date().toISOString(),\n ...scope,\n })\n })\n\n process.on('unhandledRejection', (reason) => {\n logError({\n type: 'unhandledRejection',\n message: reason?.message || 'Unhandled Promise Rejection',\n stack: reason?.stack || 'No stack trace',\n errorTrace: reason?.stack || 'No stack trace',\n timestamp: new Date().toISOString(),\n ...scope,\n })\n })\n}\n\n/**\n * Express error handling middleware.\n * Add as the last middleware: app.use(errorHandlingMiddleware)\n */\nexport function errorHandlingMiddleware(err, req, res, next) {\n logError({\n type: 'expressError',\n message: err.message,\n stack: config.captureStackTrace ? err.stack : undefined,\n errorTrace: config.captureStackTrace ? err.stack : undefined,\n path: req.originalUrl,\n method: req.method,\n params: req.params,\n query: req.query,\n headers: config.captureRequestDetails ? req.headers : undefined,\n user: config.captureUserDetails ? req.user : undefined,\n timestamp: new Date().toISOString(),\n ...scope,\n })\n\n res.status(500).json({ error: 'Internal Server Error' })\n}\n\n/**\n * Manually capture an error in Node.js.\n */\nexport function captureError(error, extra = {}) {\n logError({\n type: 'manual',\n message: error?.message || String(error),\n stack: error?.stack,\n errorTrace: error?.stack,\n timestamp: new Date().toISOString(),\n ...extra,\n ...scope,\n })\n}\n"],
5
+ "mappings": "4ZAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,4BAAAC,EAAA,gBAAAC,IAAA,eAAAC,EAAAL,GAgBA,IAAIM,EAAS,CACX,MAAO,GACP,SAAU,GACV,WAAY,GACZ,mBAAoB,GACpB,sBAAuB,GACvB,kBAAmB,EACrB,EAEIC,EAAQ,CACV,YAAa,aACb,QAAS,KACT,QAAS,KACT,QAAS,KACT,IAAK,OACL,KAAM,IACR,EAEA,SAASC,EAASC,EAAS,CACrBH,EAAO,OACT,QAAQ,MAAM,WAAYG,CAAO,EAG/BH,EAAO,UAAYA,EAAO,YAC5B,MAAMA,EAAO,SAAU,CACrB,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAUG,CAAO,CAC9B,CAAC,EAAE,MAAMC,GAAO,CACd,QAAQ,MAAM,gCAAiCA,EAAI,OAAO,CAC5D,CAAC,CAEL,CAQO,SAASN,EAAYO,EAAc,CAAC,EAAGC,EAAe,CAAC,EAAG,CAC/DL,EAAQ,CAAE,GAAGA,EAAO,GAAGI,CAAY,EACnCL,EAAS,CAAE,GAAGA,EAAQ,GAAGM,CAAa,EAEtC,QAAQ,GAAG,oBAAsBC,GAAU,CACzCL,EAAS,CACP,KAAM,oBACN,QAASK,EAAM,QACf,MAAOA,EAAM,MACb,WAAYA,EAAM,MAClB,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGN,CACL,CAAC,CACH,CAAC,EAED,QAAQ,GAAG,qBAAuBO,GAAW,CAC3CN,EAAS,CACP,KAAM,qBACN,QAASM,GAAQ,SAAW,8BAC5B,MAAOA,GAAQ,OAAS,iBACxB,WAAYA,GAAQ,OAAS,iBAC7B,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGP,CACL,CAAC,CACH,CAAC,CACH,CAMO,SAASJ,EAAwBO,EAAKK,EAAKC,EAAKC,EAAM,CAC3DT,EAAS,CACP,KAAM,eACN,QAASE,EAAI,QACb,MAAOJ,EAAO,kBAAoBI,EAAI,MAAQ,OAC9C,WAAYJ,EAAO,kBAAoBI,EAAI,MAAQ,OACnD,KAAMK,EAAI,YACV,OAAQA,EAAI,OACZ,OAAQA,EAAI,OACZ,MAAOA,EAAI,MACX,QAAST,EAAO,sBAAwBS,EAAI,QAAU,OACtD,KAAMT,EAAO,mBAAqBS,EAAI,KAAO,OAC7C,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGR,CACL,CAAC,EAEDS,EAAI,OAAO,GAAG,EAAE,KAAK,CAAE,MAAO,uBAAwB,CAAC,CACzD,CAKO,SAASd,EAAaW,EAAOK,EAAQ,CAAC,EAAG,CAC9CV,EAAS,CACP,KAAM,SACN,QAASK,GAAO,SAAW,OAAOA,CAAK,EACvC,MAAOA,GAAO,MACd,WAAYA,GAAO,MACnB,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGK,EACH,GAAGX,CACL,CAAC,CACH",
6
+ "names": ["node_exports", "__export", "captureError", "errorHandlingMiddleware", "initTracker", "__toCommonJS", "config", "scope", "logError", "details", "err", "customScope", "customConfig", "error", "reason", "req", "res", "next", "extra"]
7
+ }
package/dist/node.js ADDED
@@ -0,0 +1,2 @@
1
+ var a={debug:!1,endpoint:"",sendErrors:!0,captureUserDetails:!1,captureRequestDetails:!0,captureStackTrace:!0},n={environment:"production",project:null,release:null,version:null,sdk:"node",user:null};function s(e){a.debug&&console.error("[Scout]:",e),a.endpoint&&a.sendErrors&&fetch(a.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).catch(t=>{console.error("[Scout] Failed to send error:",t.message)})}function o(e={},t={}){n={...n,...e},a={...a,...t},process.on("uncaughtException",r=>{s({type:"uncaughtException",message:r.message,stack:r.stack,errorTrace:r.stack,timestamp:new Date().toISOString(),...n})}),process.on("unhandledRejection",r=>{s({type:"unhandledRejection",message:r?.message||"Unhandled Promise Rejection",stack:r?.stack||"No stack trace",errorTrace:r?.stack||"No stack trace",timestamp:new Date().toISOString(),...n})})}function i(e,t,r,c){s({type:"expressError",message:e.message,stack:a.captureStackTrace?e.stack:void 0,errorTrace:a.captureStackTrace?e.stack:void 0,path:t.originalUrl,method:t.method,params:t.params,query:t.query,headers:a.captureRequestDetails?t.headers:void 0,user:a.captureUserDetails?t.user:void 0,timestamp:new Date().toISOString(),...n}),r.status(500).json({error:"Internal Server Error"})}function u(e,t={}){s({type:"manual",message:e?.message||String(e),stack:e?.stack,errorTrace:e?.stack,timestamp:new Date().toISOString(),...t,...n})}export{u as captureError,i as errorHandlingMiddleware,o as initTracker};
2
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/node.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Node.js SDK\n *\n * Captures uncaught exceptions, unhandled rejections, and Express errors.\n *\n * Usage:\n * const { initTracker, errorHandlingMiddleware } = require('scoutjs/node')\n *\n * initTracker(\n * { environment: 'production', project: 'my-backend', release: '1.0.0' },\n * { endpoint: 'https://your-scout-instance.com/errors' }\n * )\n *\n * app.use(errorHandlingMiddleware)\n */\n\nlet config = {\n debug: false,\n endpoint: '',\n sendErrors: true,\n captureUserDetails: false,\n captureRequestDetails: true,\n captureStackTrace: true,\n}\n\nlet scope = {\n environment: 'production',\n project: null,\n release: null,\n version: null,\n sdk: 'node',\n user: null,\n}\n\nfunction logError(details) {\n if (config.debug) {\n console.error('[Scout]:', details)\n }\n\n if (config.endpoint && config.sendErrors) {\n fetch(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(details),\n }).catch(err => {\n console.error('[Scout] Failed to send error:', err.message)\n })\n }\n}\n\n/**\n * Initialize the Node.js error tracker.\n *\n * @param {Object} customScope - { environment, project, release, version }\n * @param {Object} customConfig - { endpoint, debug, sendErrors, ... }\n */\nexport function initTracker(customScope = {}, customConfig = {}) {\n scope = { ...scope, ...customScope }\n config = { ...config, ...customConfig }\n\n process.on('uncaughtException', (error) => {\n logError({\n type: 'uncaughtException',\n message: error.message,\n stack: error.stack,\n errorTrace: error.stack,\n timestamp: new Date().toISOString(),\n ...scope,\n })\n })\n\n process.on('unhandledRejection', (reason) => {\n logError({\n type: 'unhandledRejection',\n message: reason?.message || 'Unhandled Promise Rejection',\n stack: reason?.stack || 'No stack trace',\n errorTrace: reason?.stack || 'No stack trace',\n timestamp: new Date().toISOString(),\n ...scope,\n })\n })\n}\n\n/**\n * Express error handling middleware.\n * Add as the last middleware: app.use(errorHandlingMiddleware)\n */\nexport function errorHandlingMiddleware(err, req, res, next) {\n logError({\n type: 'expressError',\n message: err.message,\n stack: config.captureStackTrace ? err.stack : undefined,\n errorTrace: config.captureStackTrace ? err.stack : undefined,\n path: req.originalUrl,\n method: req.method,\n params: req.params,\n query: req.query,\n headers: config.captureRequestDetails ? req.headers : undefined,\n user: config.captureUserDetails ? req.user : undefined,\n timestamp: new Date().toISOString(),\n ...scope,\n })\n\n res.status(500).json({ error: 'Internal Server Error' })\n}\n\n/**\n * Manually capture an error in Node.js.\n */\nexport function captureError(error, extra = {}) {\n logError({\n type: 'manual',\n message: error?.message || String(error),\n stack: error?.stack,\n errorTrace: error?.stack,\n timestamp: new Date().toISOString(),\n ...extra,\n ...scope,\n })\n}\n"],
5
+ "mappings": "AAgBA,IAAIA,EAAS,CACX,MAAO,GACP,SAAU,GACV,WAAY,GACZ,mBAAoB,GACpB,sBAAuB,GACvB,kBAAmB,EACrB,EAEIC,EAAQ,CACV,YAAa,aACb,QAAS,KACT,QAAS,KACT,QAAS,KACT,IAAK,OACL,KAAM,IACR,EAEA,SAASC,EAASC,EAAS,CACrBH,EAAO,OACT,QAAQ,MAAM,WAAYG,CAAO,EAG/BH,EAAO,UAAYA,EAAO,YAC5B,MAAMA,EAAO,SAAU,CACrB,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAUG,CAAO,CAC9B,CAAC,EAAE,MAAMC,GAAO,CACd,QAAQ,MAAM,gCAAiCA,EAAI,OAAO,CAC5D,CAAC,CAEL,CAQO,SAASC,EAAYC,EAAc,CAAC,EAAGC,EAAe,CAAC,EAAG,CAC/DN,EAAQ,CAAE,GAAGA,EAAO,GAAGK,CAAY,EACnCN,EAAS,CAAE,GAAGA,EAAQ,GAAGO,CAAa,EAEtC,QAAQ,GAAG,oBAAsBC,GAAU,CACzCN,EAAS,CACP,KAAM,oBACN,QAASM,EAAM,QACf,MAAOA,EAAM,MACb,WAAYA,EAAM,MAClB,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGP,CACL,CAAC,CACH,CAAC,EAED,QAAQ,GAAG,qBAAuBQ,GAAW,CAC3CP,EAAS,CACP,KAAM,qBACN,QAASO,GAAQ,SAAW,8BAC5B,MAAOA,GAAQ,OAAS,iBACxB,WAAYA,GAAQ,OAAS,iBAC7B,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGR,CACL,CAAC,CACH,CAAC,CACH,CAMO,SAASS,EAAwBN,EAAKO,EAAKC,EAAKC,EAAM,CAC3DX,EAAS,CACP,KAAM,eACN,QAASE,EAAI,QACb,MAAOJ,EAAO,kBAAoBI,EAAI,MAAQ,OAC9C,WAAYJ,EAAO,kBAAoBI,EAAI,MAAQ,OACnD,KAAMO,EAAI,YACV,OAAQA,EAAI,OACZ,OAAQA,EAAI,OACZ,MAAOA,EAAI,MACX,QAASX,EAAO,sBAAwBW,EAAI,QAAU,OACtD,KAAMX,EAAO,mBAAqBW,EAAI,KAAO,OAC7C,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGV,CACL,CAAC,EAEDW,EAAI,OAAO,GAAG,EAAE,KAAK,CAAE,MAAO,uBAAwB,CAAC,CACzD,CAKO,SAASE,EAAaN,EAAOO,EAAQ,CAAC,EAAG,CAC9Cb,EAAS,CACP,KAAM,SACN,QAASM,GAAO,SAAW,OAAOA,CAAK,EACvC,MAAOA,GAAO,MACd,WAAYA,GAAO,MACnB,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,GAAGO,EACH,GAAGd,CACL,CAAC,CACH",
6
+ "names": ["config", "scope", "logError", "details", "err", "initTracker", "customScope", "customConfig", "error", "reason", "errorHandlingMiddleware", "req", "res", "next", "captureError", "extra"]
7
+ }
package/dist/react.cjs ADDED
@@ -0,0 +1,3 @@
1
+ var E=Object.create;var a=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,b=Object.prototype.hasOwnProperty;var I=(e,r)=>{for(var n in r)a(e,n,{get:r[n],enumerable:!0})},u=(e,r,n,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of k(r))!b.call(e,o)&&o!==n&&a(e,o,{get:()=>r[o],enumerable:!(t=S(r,o))||t.enumerable});return e};var _=(e,r,n)=>(n=e!=null?E(y(e)):{},u(r||!e||!e.__esModule?a(n,"default",{value:e,enumerable:!0}):n,e)),T=e=>u(a({},"__esModule",{value:!0}),e);var D={};I(D,{ScoutErrorBoundary:()=>l});module.exports=T(D);var m=_(require("react"),1);var R={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},s={...R},C={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},f={clicks:0,scrolls:0},i=null;var p=console.log;function c(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function P(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",c("user")),localStorage.getItem("__scoutUserId")),r=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",c("session")),sessionStorage.getItem("__scoutSessionId"));return i=i||c("pageload"),{pageloadId:i,userId:e,sessionId:r}}function M(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(n=>e.match(n.p))?.n||"Unknown"}function L(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(n=>e.match(n.p))?.n||"Unknown"}function U(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:M(),browserVersion:window._uaParserResult?.browser?.version||null,os:L(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:f.clicks,userScrolls:f.scrolls}}function x(e,r){let n=new AbortController,t=setTimeout(()=>n.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal}).then(o=>(clearTimeout(t),o)).catch(()=>{clearTimeout(t)})}async function A(e){let r=s.browserDetails?U():{},n=Object.assign(e,r,C,P());if(s.sampleRate&&Math.random()<1-parseFloat(s.sampleRate)){s.debug&&p("[Scout] Suppressed by sampling");return}if(s.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let t=e.errorTrace||e.stack,o=t?t.split(`
2
+ `):[],w=o.length>1?o[1].trim():"",[,d,h,v]=w.match(/(http.*?):(\d+):(\d+)/)||[];d&&(e.source=d,e.lineno=parseInt(h,10),e.colno=parseInt(v,10))}catch{}s.debug&&p("[Scout] Sending:",n),s.endpoint&&x(s.endpoint,n)}function g(e){s.enabled&&A(e)}var l=class extends m.default.Component{constructor(r){super(r),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(r,n){g({message:r.message,stack:r.stack,errorTrace:r.stack,component:n?.componentStack||"",type:"react-error-boundary"})}render(){return this.state.hasError?this.props.fallback||null:this.props.children}};
3
+ //# sourceMappingURL=react.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/react.js", "../src/index.js"],
4
+ "sourcesContent": ["/**\n * Scout.js React Error Boundary\n *\n * Usage:\n * import { init } from 'scoutjs'\n * import { ScoutErrorBoundary } from 'scoutjs/react'\n *\n * init({ app: 'My App', project: 'my-project' }, { endpoint: '...' })\n *\n * <ScoutErrorBoundary>\n * <App />\n * </ScoutErrorBoundary>\n */\n\nimport React from 'react'\nimport { captureError } from './index.js'\n\nexport class ScoutErrorBoundary extends React.Component {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n componentDidCatch(error, errorInfo) {\n captureError({\n message: error.message,\n stack: error.stack,\n errorTrace: error.stack,\n component: errorInfo?.componentStack || '',\n type: 'react-error-boundary',\n })\n }\n\n render() {\n if (this.state.hasError) {\n return this.props.fallback || null\n }\n return this.props.children\n }\n}\n", "/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["react_exports", "__export", "ScoutErrorBoundary", "__toCommonJS", "import_react", "defaultConfig", "config", "scope", "userInteractions", "pageloadId", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "o", "captureBrowserDetails", "conn", "userInteractions", "postData", "url", "data", "controller", "timeout", "r", "pushErrorEvent", "obj", "details", "config", "captureBrowserDetails", "event", "scope", "getIds", "_consoleLog", "stack", "lines", "loc", "source", "lineno", "colno", "postData", "captureError", "ScoutErrorBoundary", "React", "props", "error", "errorInfo", "captureError"]
7
+ }
package/dist/react.js ADDED
@@ -0,0 +1,3 @@
1
+ import I from"react";var w={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},o={...w},h={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},l={clicks:0,scrolls:0},a=null;var d=console.log;function i(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function v(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",i("user")),localStorage.getItem("__scoutUserId")),r=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",i("session")),sessionStorage.getItem("__scoutSessionId"));return a=a||i("pageload"),{pageloadId:a,userId:e,sessionId:r}}function E(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(n=>e.match(n.p))?.n||"Unknown"}function S(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(n=>e.match(n.p))?.n||"Unknown"}function k(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:E(),browserVersion:window._uaParserResult?.browser?.version||null,os:S(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:l.clicks,userScrolls:l.scrolls}}function y(e,r){let n=new AbortController,t=setTimeout(()=>n.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal}).then(s=>(clearTimeout(t),s)).catch(()=>{clearTimeout(t)})}async function b(e){let r=o.browserDetails?k():{},n=Object.assign(e,r,h,v());if(o.sampleRate&&Math.random()<1-parseFloat(o.sampleRate)){o.debug&&d("[Scout] Suppressed by sampling");return}if(o.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let t=e.errorTrace||e.stack,s=t?t.split(`
2
+ `):[],p=s.length>1?s[1].trim():"",[,c,g,m]=p.match(/(http.*?):(\d+):(\d+)/)||[];c&&(e.source=c,e.lineno=parseInt(g,10),e.colno=parseInt(m,10))}catch{}o.debug&&d("[Scout] Sending:",n),o.endpoint&&y(o.endpoint,n)}function u(e){o.enabled&&b(e)}var f=class extends I.Component{constructor(r){super(r),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(r,n){u({message:r.message,stack:r.stack,errorTrace:r.stack,component:n?.componentStack||"",type:"react-error-boundary"})}render(){return this.state.hasError?this.props.fallback||null:this.props.children}};export{f as ScoutErrorBoundary};
3
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/react.js", "../src/index.js"],
4
+ "sourcesContent": ["/**\n * Scout.js React Error Boundary\n *\n * Usage:\n * import { init } from 'scoutjs'\n * import { ScoutErrorBoundary } from 'scoutjs/react'\n *\n * init({ app: 'My App', project: 'my-project' }, { endpoint: '...' })\n *\n * <ScoutErrorBoundary>\n * <App />\n * </ScoutErrorBoundary>\n */\n\nimport React from 'react'\nimport { captureError } from './index.js'\n\nexport class ScoutErrorBoundary extends React.Component {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n componentDidCatch(error, errorInfo) {\n captureError({\n message: error.message,\n stack: error.stack,\n errorTrace: error.stack,\n component: errorInfo?.componentStack || '',\n type: 'react-error-boundary',\n })\n }\n\n render() {\n if (this.state.hasError) {\n return this.props.fallback || null\n }\n return this.props.children\n }\n}\n", "/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "defaultConfig", "config", "scope", "userInteractions", "pageloadId", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "o", "captureBrowserDetails", "conn", "userInteractions", "postData", "url", "data", "controller", "timeout", "r", "pushErrorEvent", "obj", "details", "config", "captureBrowserDetails", "event", "scope", "getIds", "_consoleLog", "stack", "lines", "loc", "source", "lineno", "colno", "postData", "captureError", "ScoutErrorBoundary", "React", "props", "error", "errorInfo", "captureError"]
7
+ }
package/dist/vue.cjs ADDED
@@ -0,0 +1,3 @@
1
+ var a=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var E=(e,r)=>{for(var n in r)a(e,n,{get:r[n],enumerable:!0})},S=(e,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of h(r))!v.call(e,t)&&t!==n&&a(e,t,{get:()=>r[t],enumerable:!(o=w(r,t))||o.enumerable});return e};var y=e=>S(a({},"__esModule",{value:!0}),e);var L={};E(L,{ScoutVue:()=>M});module.exports=y(L);var _={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},s={..._},k={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},d={clicks:0,scrolls:0},i=null;var f=console.log;function c(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function I(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",c("user")),localStorage.getItem("__scoutUserId")),r=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",c("session")),sessionStorage.getItem("__scoutSessionId"));return i=i||c("pageload"),{pageloadId:i,userId:e,sessionId:r}}function b(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(n=>e.match(n.p))?.n||"Unknown"}function T(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(n=>e.match(n.p))?.n||"Unknown"}function R(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:b(),browserVersion:window._uaParserResult?.browser?.version||null,os:T(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:d.clicks,userScrolls:d.scrolls}}function C(e,r){let n=new AbortController,o=setTimeout(()=>n.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal}).then(t=>(clearTimeout(o),t)).catch(()=>{clearTimeout(o)})}async function P(e){let r=s.browserDetails?R():{},n=Object.assign(e,r,k,I());if(s.sampleRate&&Math.random()<1-parseFloat(s.sampleRate)){s.debug&&f("[Scout] Suppressed by sampling");return}if(s.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let o=e.errorTrace||e.stack,t=o?o.split(`
2
+ `):[],p=t.length>1?t[1].trim():"",[,u,g,m]=p.match(/(http.*?):(\d+):(\d+)/)||[];u&&(e.source=u,e.lineno=parseInt(g,10),e.colno=parseInt(m,10))}catch{}s.debug&&f("[Scout] Sending:",n),s.endpoint&&C(s.endpoint,n)}function l(e){s.enabled&&P(e)}var M={install(e){e.config.errorHandler=(r,n,o)=>{l({message:r.message,stack:r.stack,errorTrace:r.stack,component:n?.$options?.name||n?.$options?.__name||"Anonymous",type:"vue-error-handler",info:o})},e.config.warnHandler=(r,n,o)=>{l({message:r,component:n?.$options?.name||n?.$options?.__name||"Anonymous",type:"vue-warn-handler",errorTrace:o})}}};
3
+ //# sourceMappingURL=vue.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/vue.js", "../src/index.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Vue Plugin\n *\n * Usage:\n * import { init } from 'scoutjs'\n * import { ScoutVue } from 'scoutjs/vue'\n *\n * init({ app: 'My App', project: 'my-project' }, { endpoint: '...' })\n * app.use(ScoutVue)\n */\n\nimport { captureError } from './index.js'\n\n/**\n * Vue plugin that installs error and warning handlers.\n *\n * app.use(ScoutVue)\n */\nexport const ScoutVue = {\n install(app) {\n app.config.errorHandler = (err, vm, info) => {\n captureError({\n message: err.message,\n stack: err.stack,\n errorTrace: err.stack,\n component: vm?.$options?.name || vm?.$options?.__name || 'Anonymous',\n type: 'vue-error-handler',\n info,\n })\n }\n\n app.config.warnHandler = (msg, vm, trace) => {\n captureError({\n message: msg,\n component: vm?.$options?.name || vm?.$options?.__name || 'Anonymous',\n type: 'vue-warn-handler',\n errorTrace: trace,\n })\n }\n },\n}\n", "/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["vue_exports", "__export", "ScoutVue", "__toCommonJS", "defaultConfig", "config", "scope", "userInteractions", "pageloadId", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "o", "captureBrowserDetails", "conn", "userInteractions", "postData", "url", "data", "controller", "timeout", "r", "pushErrorEvent", "obj", "details", "config", "captureBrowserDetails", "event", "scope", "getIds", "_consoleLog", "stack", "lines", "loc", "source", "lineno", "colno", "postData", "captureError", "ScoutVue", "app", "err", "vm", "info", "captureError", "msg", "trace"]
7
+ }
package/dist/vue.js ADDED
@@ -0,0 +1,3 @@
1
+ var m={trackUserInteractions:!0,selfHealingErrors:!1,attachStacktrace:!0,handleSourceMaps:!1,browserDetails:!0,warnOnCapture:!1,loadUAParser:!0,ignoreErrors:null,sendErrors:!0,sampleRate:1,enabled:!0,debug:!1,endpoint:"",overrideOnError:!1,overrideOnUnhandledRejection:!1,addErrorEventListener:!0,addUnhandledRejectionEventListener:!0,overrideConsoleLog:!1,overrideConsoleWarn:!1,overrideConsoleInfo:!1,overrideConsoleError:!0},t={...m},w={environment:typeof window<"u"&&window.location?.hostname==="localhost"?"development":"production",sdk:"javascript",project:null,release:null,version:null,user:null,app:null},u={clicks:0,scrolls:0},a=null;var d=console.log;function i(e){return`${e}_${Math.random().toString(36).substr(2,9)}`}function h(){let e=localStorage.getItem("__scoutUserId")||(localStorage.setItem("__scoutUserId",i("user")),localStorage.getItem("__scoutUserId")),n=sessionStorage.getItem("__scoutSessionId")||(sessionStorage.setItem("__scoutSessionId",i("session")),sessionStorage.getItem("__scoutSessionId"));return a=a||i("pageload"),{pageloadId:a,userId:e,sessionId:n}}function v(){if(window._uaParserResult?.browser?.name)return window._uaParserResult.browser.name;let e=navigator.userAgent;return[{p:/Chrome.*Mobile/,n:"Chrome Mobile"},{p:/Chrome/,n:"Chrome"},{p:/Firefox.*Mobile/,n:"Firefox Mobile"},{p:/Firefox/,n:"Firefox"},{p:/Safari.*Mobile/,n:"Safari Mobile"},{p:/Safari/,n:"Safari"},{p:/MSIE|Trident/,n:"Internet Explorer"},{p:/Edge/,n:"Edge"}].find(r=>e.match(r.p))?.n||"Unknown"}function E(){if(window._uaParserResult?.os?.name)return window._uaParserResult.os.name;let e=navigator.userAgent;return[{p:/Win/,n:"Windows"},{p:/Mac/,n:"Mac OS"},{p:/X11|Linux/,n:"Linux"},{p:/Android/,n:"Android"},{p:/iPhone|iPad/,n:"iOS"}].find(r=>e.match(r.p))?.n||"Unknown"}function S(){let e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{connectionType:e?e.effectiveType:"unknown",userAgent:navigator.userAgent,width:window.innerWidth,height:window.innerHeight,screenWidth:screen.width,screenHeight:screen.height,errorTimestamp:Date.now(),timeLocale:Intl.DateTimeFormat().resolvedOptions().timeZone,browserLocale:navigator.language||navigator.userLanguage,sessionTime:Math.round(performance.now()/1e3),deviceMemory:navigator.deviceMemory||"unknown",timezoneOffset:new Date().getTimezoneOffset(),cookiesEnabled:navigator.cookieEnabled,url:window.location.href,host:window.location.host,referrer:document.referrer,browser:v(),browserVersion:window._uaParserResult?.browser?.version||null,os:E(),osVersion:window._uaParserResult?.os?.version||null,deviceType:window._uaParserResult?.device?.type||null,deviceModel:window._uaParserResult?.device?.model||null,deviceVendor:window._uaParserResult?.device?.vendor||null,loadTime:Math.max(0,performance.timing.loadEventEnd-performance.timing.navigationStart),userClicks:u.clicks,userScrolls:u.scrolls}}function y(e,n){let r=new AbortController,o=setTimeout(()=>r.abort(),5e3);return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),signal:r.signal}).then(s=>(clearTimeout(o),s)).catch(()=>{clearTimeout(o)})}async function _(e){let n=t.browserDetails?S():{},r=Object.assign(e,n,w,h());if(t.sampleRate&&Math.random()<1-parseFloat(t.sampleRate)){t.debug&&d("[Scout] Suppressed by sampling");return}if(t.attachStacktrace||(e.errorTrace=null),(e.errorTrace||e.stack)&&!e.source)try{let o=e.errorTrace||e.stack,s=o?o.split(`
2
+ `):[],f=s.length>1?s[1].trim():"",[,l,p,g]=f.match(/(http.*?):(\d+):(\d+)/)||[];l&&(e.source=l,e.lineno=parseInt(p,10),e.colno=parseInt(g,10))}catch{}t.debug&&d("[Scout] Sending:",r),t.endpoint&&y(t.endpoint,r)}function c(e){t.enabled&&_(e)}var b={install(e){e.config.errorHandler=(n,r,o)=>{c({message:n.message,stack:n.stack,errorTrace:n.stack,component:r?.$options?.name||r?.$options?.__name||"Anonymous",type:"vue-error-handler",info:o})},e.config.warnHandler=(n,r,o)=>{c({message:n,component:r?.$options?.name||r?.$options?.__name||"Anonymous",type:"vue-warn-handler",errorTrace:o})}}};export{b as ScoutVue};
3
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.js", "../src/vue.js"],
4
+ "sourcesContent": ["/**\n * Scout.js Browser SDK\n *\n * Captures errors, unhandled rejections, and console output.\n * Collects browser telemetry, session tracking, and source maps.\n *\n * Usage:\n * import { init, captureError } from 'scoutjs'\n * init({ app: 'My App', project: 'my-project' }, { endpoint: 'https://...' })\n */\n\nconst defaultConfig = {\n trackUserInteractions: true,\n selfHealingErrors: false,\n attachStacktrace: true,\n handleSourceMaps: false,\n browserDetails: true,\n warnOnCapture: false,\n loadUAParser: true,\n ignoreErrors: null,\n sendErrors: true,\n sampleRate: 1.0,\n enabled: true,\n debug: false,\n endpoint: '',\n\n overrideOnError: false,\n overrideOnUnhandledRejection: false,\n addErrorEventListener: true,\n addUnhandledRejectionEventListener: true,\n\n overrideConsoleLog: false,\n overrideConsoleWarn: false,\n overrideConsoleInfo: false,\n overrideConsoleError: true,\n}\n\nlet config = { ...defaultConfig }\n\nlet scope = {\n environment: typeof window !== 'undefined' && window.location?.hostname === 'localhost' ? 'development' : 'production',\n sdk: 'javascript',\n project: null,\n release: null,\n version: null,\n user: null,\n app: null,\n}\n\nconst userInteractions = { clicks: 0, scrolls: 0 }\nlet pageloadId = null\nlet initialized = false\n\n// Save originals before any overrides\nconst _consoleError = console.error\nconst _consoleWarn = console.warn\nconst _consoleInfo = console.info\nconst _consoleLog = console.log\n\n// --- Utilities ---\n\nfunction generateId(prefix) {\n return `${prefix}_${Math.random().toString(36).substr(2, 9)}`\n}\n\nfunction getIds() {\n const userId = localStorage.getItem('__scoutUserId') || (localStorage.setItem('__scoutUserId', generateId('user')), localStorage.getItem('__scoutUserId'))\n const sessionId = sessionStorage.getItem('__scoutSessionId') || (sessionStorage.setItem('__scoutSessionId', generateId('session')), sessionStorage.getItem('__scoutSessionId'))\n pageloadId = pageloadId || generateId('pageload')\n return { pageloadId, userId, sessionId }\n}\n\nfunction getBrowser() {\n if (window._uaParserResult?.browser?.name) return window._uaParserResult.browser.name\n const ua = navigator.userAgent\n const map = [\n { p: /Chrome.*Mobile/, n: 'Chrome Mobile' },\n { p: /Chrome/, n: 'Chrome' },\n { p: /Firefox.*Mobile/, n: 'Firefox Mobile' },\n { p: /Firefox/, n: 'Firefox' },\n { p: /Safari.*Mobile/, n: 'Safari Mobile' },\n { p: /Safari/, n: 'Safari' },\n { p: /MSIE|Trident/, n: 'Internet Explorer' },\n { p: /Edge/, n: 'Edge' },\n ]\n return map.find(b => ua.match(b.p))?.n || 'Unknown'\n}\n\nfunction getOS() {\n if (window._uaParserResult?.os?.name) return window._uaParserResult.os.name\n const ua = navigator.userAgent\n const map = [\n { p: /Win/, n: 'Windows' },\n { p: /Mac/, n: 'Mac OS' },\n { p: /X11|Linux/, n: 'Linux' },\n { p: /Android/, n: 'Android' },\n { p: /iPhone|iPad/, n: 'iOS' },\n ]\n return map.find(o => ua.match(o.p))?.n || 'Unknown'\n}\n\nfunction captureBrowserDetails() {\n const conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection\n return {\n connectionType: conn ? conn.effectiveType : 'unknown',\n userAgent: navigator.userAgent,\n width: window.innerWidth,\n height: window.innerHeight,\n screenWidth: screen.width,\n screenHeight: screen.height,\n errorTimestamp: Date.now(),\n timeLocale: Intl.DateTimeFormat().resolvedOptions().timeZone,\n browserLocale: navigator.language || navigator.userLanguage,\n sessionTime: Math.round(performance.now() / 1000),\n deviceMemory: navigator.deviceMemory || 'unknown',\n timezoneOffset: new Date().getTimezoneOffset(),\n cookiesEnabled: navigator.cookieEnabled,\n url: window.location.href,\n host: window.location.host,\n referrer: document.referrer,\n browser: getBrowser(),\n browserVersion: window._uaParserResult?.browser?.version || null,\n os: getOS(),\n osVersion: window._uaParserResult?.os?.version || null,\n deviceType: window._uaParserResult?.device?.type || null,\n deviceModel: window._uaParserResult?.device?.model || null,\n deviceVendor: window._uaParserResult?.device?.vendor || null,\n loadTime: Math.max(0, performance.timing.loadEventEnd - performance.timing.navigationStart),\n userClicks: userInteractions.clicks,\n userScrolls: userInteractions.scrolls,\n }\n}\n\nfunction shouldIgnoreError(msg) {\n if (!config.ignoreErrors || !Array.isArray(config.ignoreErrors)) return false\n return config.ignoreErrors.some(pattern => {\n if (typeof pattern === 'string') return msg.includes(pattern)\n if (pattern instanceof RegExp) return pattern.test(msg)\n return false\n })\n}\n\nfunction postData(url, data) {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 5000)\n\n return fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n signal: controller.signal,\n })\n .then(r => { clearTimeout(timeout); return r })\n .catch(() => { clearTimeout(timeout) })\n}\n\nfunction argsToString(args) {\n const fmt = (args[0] || '') + ''\n const rest = [...args]\n return fmt.replace(/%[sdj]/g, (m) => {\n const v = rest.shift()\n if (m === '%s') return String(v)\n if (m === '%d') return Number(v)\n if (m === '%j') return JSON.stringify(v)\n return m\n })\n}\n\n// --- Core ---\n\nasync function pushErrorEvent(obj) {\n const details = config.browserDetails ? captureBrowserDetails() : {}\n const event = Object.assign(obj, details, scope, getIds())\n\n if (config.sampleRate && Math.random() < (1 - parseFloat(config.sampleRate))) {\n if (config.debug) _consoleLog('[Scout] Suppressed by sampling')\n return\n }\n\n if (!config.attachStacktrace) obj.errorTrace = null\n\n // Parse source from stack trace if not provided\n if ((obj.errorTrace || obj.stack) && !obj.source) {\n try {\n const stack = obj.errorTrace || obj.stack\n const lines = stack ? stack.split('\\n') : []\n const loc = lines.length > 1 ? lines[1].trim() : ''\n const [, source, lineno, colno] = loc.match(/(http.*?):(\\d+):(\\d+)/) || []\n if (source) {\n obj.source = source\n obj.lineno = parseInt(lineno, 10)\n obj.colno = parseInt(colno, 10)\n }\n } catch (e) { /* ignore parse failures */ }\n }\n\n if (config.debug) _consoleLog('[Scout] Sending:', event)\n if (config.endpoint) postData(config.endpoint, event)\n}\n\n/**\n * Manually capture an error object.\n */\nexport function captureError(event) {\n if (!config.enabled) return\n pushErrorEvent(event)\n}\n\n// --- Setup ---\n\nfunction setupListeners() {\n // User interactions\n if (config.trackUserInteractions) {\n document.addEventListener('click', () => { userInteractions.clicks++ })\n let lastScroll = 0\n window.addEventListener('scroll', () => {\n const now = Date.now()\n if (now - lastScroll > 100) { userInteractions.scrolls++; lastScroll = now }\n })\n }\n\n // Error event listener\n if (config.addErrorEventListener) {\n window.addEventListener('error', async (event) => {\n if (!config.enabled) return\n try {\n const errorTrace = event.error ? event.error.stack : 'No stack trace available'\n if (shouldIgnoreError(event.message)) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'window.onerror',\n message: event.message,\n source: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Error handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Unhandled rejection listener\n if (config.addUnhandledRejectionEventListener) {\n window.addEventListener('unhandledrejection', (event) => {\n if (!config.enabled) return\n try {\n const error = event.reason\n const errorTrace = error?.stack || 'No stack trace available'\n if (shouldIgnoreError(error?.message || '')) return\n if (config.sendErrors) {\n pushErrorEvent({\n type: 'Unhandled Promise Rejection',\n message: error?.message || 'Unhandled Promise Rejection',\n reason: event.reason,\n errorTrace,\n })\n }\n } catch (e) {\n _consoleWarn('[Scout] Rejection handler failure:', e)\n }\n if (config.selfHealingErrors) event.preventDefault()\n })\n }\n\n // Console overrides\n if (config.overrideConsoleError) {\n console.error = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.error', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.error override failure:', e) }\n }\n }\n\n if (config.overrideConsoleWarn) {\n console.warn = function (...args) {\n if (!config.enabled) return\n try {\n const errorTrace = new Error().stack\n if (shouldIgnoreError(argsToString(args))) return\n if (config.sendErrors) pushErrorEvent({ type: 'console.warn', errorTrace, args: argsToString(args) })\n } catch (e) { _consoleWarn('[Scout] console.warn override failure:', e) }\n }\n }\n\n // Load UA parser\n if (config.loadUAParser && config.browserDetails) {\n const s = document.createElement('script')\n s.src = 'https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js'\n s.async = true\n s.onload = () => {\n if (typeof UAParser !== 'undefined') {\n window._uaParserResult = new UAParser().getResult()\n }\n }\n document.head.appendChild(s)\n }\n}\n\n/**\n * Initialize Scout error tracking.\n *\n * @param {Object} scopeOptions - { app, project, version, environment, user }\n * @param {Object} configOptions - { endpoint, sampleRate, debug, ... }\n */\nexport function init(scopeOptions = {}, configOptions = {}) {\n if (initialized) {\n // Allow re-init to update config\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n return\n }\n\n scope = { ...scope, ...scopeOptions }\n config = { ...config, ...configOptions }\n initialized = true\n\n if (typeof window !== 'undefined') {\n setupListeners()\n\n // Also expose on window for script-tag compat\n window.Scout = {\n init: (s, c) => { scope = { ...scope, ...s }; if (c) config = { ...config, ...c } },\n setScope: (s) => { scope = { ...scope, ...s } },\n setConfig: (c) => { config = { ...config, ...c } },\n error: captureError,\n }\n }\n}\n", "/**\n * Scout.js Vue Plugin\n *\n * Usage:\n * import { init } from 'scoutjs'\n * import { ScoutVue } from 'scoutjs/vue'\n *\n * init({ app: 'My App', project: 'my-project' }, { endpoint: '...' })\n * app.use(ScoutVue)\n */\n\nimport { captureError } from './index.js'\n\n/**\n * Vue plugin that installs error and warning handlers.\n *\n * app.use(ScoutVue)\n */\nexport const ScoutVue = {\n install(app) {\n app.config.errorHandler = (err, vm, info) => {\n captureError({\n message: err.message,\n stack: err.stack,\n errorTrace: err.stack,\n component: vm?.$options?.name || vm?.$options?.__name || 'Anonymous',\n type: 'vue-error-handler',\n info,\n })\n }\n\n app.config.warnHandler = (msg, vm, trace) => {\n captureError({\n message: msg,\n component: vm?.$options?.name || vm?.$options?.__name || 'Anonymous',\n type: 'vue-warn-handler',\n errorTrace: trace,\n })\n }\n },\n}\n"],
5
+ "mappings": "AAWA,IAAMA,EAAgB,CACpB,sBAAuB,GACvB,kBAAmB,GACnB,iBAAkB,GAClB,iBAAkB,GAClB,eAAgB,GAChB,cAAe,GACf,aAAc,GACd,aAAc,KACd,WAAY,GACZ,WAAY,EACZ,QAAS,GACT,MAAO,GACP,SAAU,GAEV,gBAAiB,GACjB,6BAA8B,GAC9B,sBAAuB,GACvB,mCAAoC,GAEpC,mBAAoB,GACpB,oBAAqB,GACrB,oBAAqB,GACrB,qBAAsB,EACxB,EAEIC,EAAS,CAAE,GAAGD,CAAc,EAE5BE,EAAQ,CACV,YAAa,OAAO,OAAW,KAAe,OAAO,UAAU,WAAa,YAAc,cAAgB,aAC1G,IAAK,aACL,QAAS,KACT,QAAS,KACT,QAAS,KACT,KAAM,KACN,IAAK,IACP,EAEMC,EAAmB,CAAE,OAAQ,EAAG,QAAS,CAAE,EAC7CC,EAAa,KAOjB,IAAMC,EAAc,QAAQ,IAI5B,SAASC,EAAWC,EAAQ,CAC1B,MAAO,GAAGA,CAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,EAAG,CAAC,CAAC,EAC7D,CAEA,SAASC,GAAS,CAChB,IAAMC,EAAS,aAAa,QAAQ,eAAe,IAAM,aAAa,QAAQ,gBAAiBH,EAAW,MAAM,CAAC,EAAG,aAAa,QAAQ,eAAe,GAClJI,EAAY,eAAe,QAAQ,kBAAkB,IAAM,eAAe,QAAQ,mBAAoBJ,EAAW,SAAS,CAAC,EAAG,eAAe,QAAQ,kBAAkB,GAC7K,OAAAK,EAAaA,GAAcL,EAAW,UAAU,EACzC,CAAE,WAAAK,EAAY,OAAAF,EAAQ,UAAAC,CAAU,CACzC,CAEA,SAASE,GAAa,CACpB,GAAI,OAAO,iBAAiB,SAAS,KAAM,OAAO,OAAO,gBAAgB,QAAQ,KACjF,IAAMC,EAAK,UAAU,UAWrB,MAVY,CACV,CAAE,EAAG,iBAAkB,EAAG,eAAgB,EAC1C,CAAE,EAAG,SAAU,EAAG,QAAS,EAC3B,CAAE,EAAG,kBAAmB,EAAG,gBAAiB,EAC5C,CAAE,EAAG,UAAW,EAAG,SAAU,EAC7B,CAAE,EAAG,iBAAkB,EAAG,eAAgB,EAC1C,CAAE,EAAG,SAAU,EAAG,QAAS,EAC3B,CAAE,EAAG,eAAgB,EAAG,mBAAoB,EAC5C,CAAE,EAAG,OAAQ,EAAG,MAAO,CACzB,EACW,KAAKC,GAAKD,EAAG,MAAMC,EAAE,CAAC,CAAC,GAAG,GAAK,SAC5C,CAEA,SAASC,GAAQ,CACf,GAAI,OAAO,iBAAiB,IAAI,KAAM,OAAO,OAAO,gBAAgB,GAAG,KACvE,IAAMF,EAAK,UAAU,UAQrB,MAPY,CACV,CAAE,EAAG,MAAO,EAAG,SAAU,EACzB,CAAE,EAAG,MAAO,EAAG,QAAS,EACxB,CAAE,EAAG,YAAa,EAAG,OAAQ,EAC7B,CAAE,EAAG,UAAW,EAAG,SAAU,EAC7B,CAAE,EAAG,cAAe,EAAG,KAAM,CAC/B,EACW,KAAKG,GAAKH,EAAG,MAAMG,EAAE,CAAC,CAAC,GAAG,GAAK,SAC5C,CAEA,SAASC,GAAwB,CAC/B,IAAMC,EAAO,UAAU,YAAc,UAAU,eAAiB,UAAU,iBAC1E,MAAO,CACL,eAAgBA,EAAOA,EAAK,cAAgB,UAC5C,UAAW,UAAU,UACrB,MAAO,OAAO,WACd,OAAQ,OAAO,YACf,YAAa,OAAO,MACpB,aAAc,OAAO,OACrB,eAAgB,KAAK,IAAI,EACzB,WAAY,KAAK,eAAe,EAAE,gBAAgB,EAAE,SACpD,cAAe,UAAU,UAAY,UAAU,aAC/C,YAAa,KAAK,MAAM,YAAY,IAAI,EAAI,GAAI,EAChD,aAAc,UAAU,cAAgB,UACxC,eAAgB,IAAI,KAAK,EAAE,kBAAkB,EAC7C,eAAgB,UAAU,cAC1B,IAAK,OAAO,SAAS,KACrB,KAAM,OAAO,SAAS,KACtB,SAAU,SAAS,SACnB,QAASN,EAAW,EACpB,eAAgB,OAAO,iBAAiB,SAAS,SAAW,KAC5D,GAAIG,EAAM,EACV,UAAW,OAAO,iBAAiB,IAAI,SAAW,KAClD,WAAY,OAAO,iBAAiB,QAAQ,MAAQ,KACpD,YAAa,OAAO,iBAAiB,QAAQ,OAAS,KACtD,aAAc,OAAO,iBAAiB,QAAQ,QAAU,KACxD,SAAU,KAAK,IAAI,EAAG,YAAY,OAAO,aAAe,YAAY,OAAO,eAAe,EAC1F,WAAYI,EAAiB,OAC7B,YAAaA,EAAiB,OAChC,CACF,CAWA,SAASC,EAASC,EAAKC,EAAM,CAC3B,IAAMC,EAAa,IAAI,gBACjBC,EAAU,WAAW,IAAMD,EAAW,MAAM,EAAG,GAAI,EAEzD,OAAO,MAAMF,EAAK,CAChB,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAUC,CAAI,EACzB,OAAQC,EAAW,MACrB,CAAC,EACE,KAAKE,IAAO,aAAaD,CAAO,EAAUC,EAAG,EAC7C,MAAM,IAAM,CAAE,aAAaD,CAAO,CAAE,CAAC,CAC1C,CAgBA,eAAeE,EAAeC,EAAK,CACjC,IAAMC,EAAUC,EAAO,eAAiBC,EAAsB,EAAI,CAAC,EAC7DC,EAAQ,OAAO,OAAOJ,EAAKC,EAASI,EAAOC,EAAO,CAAC,EAEzD,GAAIJ,EAAO,YAAc,KAAK,OAAO,EAAK,EAAI,WAAWA,EAAO,UAAU,EAAI,CACxEA,EAAO,OAAOK,EAAY,gCAAgC,EAC9D,MACF,CAKA,GAHKL,EAAO,mBAAkBF,EAAI,WAAa,OAG1CA,EAAI,YAAcA,EAAI,QAAU,CAACA,EAAI,OACxC,GAAI,CACF,IAAMQ,EAAQR,EAAI,YAAcA,EAAI,MAC9BS,EAAQD,EAAQA,EAAM,MAAM;AAAA,CAAI,EAAI,CAAC,EACrCE,EAAMD,EAAM,OAAS,EAAIA,EAAM,CAAC,EAAE,KAAK,EAAI,GAC3C,CAAC,CAAEE,EAAQC,EAAQC,CAAK,EAAIH,EAAI,MAAM,uBAAuB,GAAK,CAAC,EACrEC,IACFX,EAAI,OAASW,EACbX,EAAI,OAAS,SAASY,EAAQ,EAAE,EAChCZ,EAAI,MAAQ,SAASa,EAAO,EAAE,EAElC,MAAY,CAA8B,CAGxCX,EAAO,OAAOK,EAAY,mBAAoBH,CAAK,EACnDF,EAAO,UAAUY,EAASZ,EAAO,SAAUE,CAAK,CACtD,CAKO,SAASW,EAAaX,EAAO,CAC7BF,EAAO,SACZH,EAAeK,CAAK,CACtB,CC5LO,IAAMY,EAAW,CACtB,QAAQC,EAAK,CACXA,EAAI,OAAO,aAAe,CAACC,EAAKC,EAAIC,IAAS,CAC3CC,EAAa,CACX,QAASH,EAAI,QACb,MAAOA,EAAI,MACX,WAAYA,EAAI,MAChB,UAAWC,GAAI,UAAU,MAAQA,GAAI,UAAU,QAAU,YACzD,KAAM,oBACN,KAAAC,CACF,CAAC,CACH,EAEAH,EAAI,OAAO,YAAc,CAACK,EAAKH,EAAII,IAAU,CAC3CF,EAAa,CACX,QAASC,EACT,UAAWH,GAAI,UAAU,MAAQA,GAAI,UAAU,QAAU,YACzD,KAAM,mBACN,WAAYI,CACd,CAAC,CACH,CACF,CACF",
6
+ "names": ["defaultConfig", "config", "scope", "userInteractions", "pageloadId", "_consoleLog", "generateId", "prefix", "getIds", "userId", "sessionId", "pageloadId", "getBrowser", "ua", "b", "getOS", "o", "captureBrowserDetails", "conn", "userInteractions", "postData", "url", "data", "controller", "timeout", "r", "pushErrorEvent", "obj", "details", "config", "captureBrowserDetails", "event", "scope", "getIds", "_consoleLog", "stack", "lines", "loc", "source", "lineno", "colno", "postData", "captureError", "ScoutVue", "app", "err", "vm", "info", "captureError", "msg", "trace"]
7
+ }
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "scout-error",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight error tracking for JavaScript applications",
5
+ "author": "James Futhey",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./vue": {
16
+ "import": "./dist/vue.js",
17
+ "require": "./dist/vue.cjs"
18
+ },
19
+ "./react": {
20
+ "import": "./dist/react.js",
21
+ "require": "./dist/react.cjs"
22
+ },
23
+ "./node": {
24
+ "import": "./dist/node.js",
25
+ "require": "./dist/node.cjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "scripts": {
32
+ "build": "node build.js"
33
+ },
34
+ "peerDependencies": {
35
+ "vue": ">=3.0.0",
36
+ "react": ">=16.0.0"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "vue": { "optional": true },
40
+ "react": { "optional": true }
41
+ },
42
+ "devDependencies": {
43
+ "esbuild": "^0.24.0"
44
+ },
45
+ "keywords": [
46
+ "error-tracking",
47
+ "error-monitoring",
48
+ "javascript",
49
+ "vue",
50
+ "react",
51
+ "node",
52
+ "express"
53
+ ],
54
+ "homepage": "https://scoutjs.com"
55
+ }