bugcatch-sdk 0.1.9 → 0.1.10
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/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +75 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +75 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -269,6 +269,7 @@ var BugCatchClient = class {
|
|
|
269
269
|
}
|
|
270
270
|
if (this.opts.autoTrackRequests) {
|
|
271
271
|
this.cleanups.push(this.installFetchInterceptor());
|
|
272
|
+
this.cleanups.push(this.installXhrInterceptor());
|
|
272
273
|
}
|
|
273
274
|
this.log("Initialized. Project:", this.dsn.projectId);
|
|
274
275
|
}
|
|
@@ -409,8 +410,14 @@ var BugCatchClient = class {
|
|
|
409
410
|
}
|
|
410
411
|
// ─── Internal: request tracking ──────────────────────────────────────────
|
|
411
412
|
installFetchInterceptor() {
|
|
413
|
+
if (typeof globalThis.fetch !== "function") {
|
|
414
|
+
console.warn("[BugCatch] autoTrackRequests is enabled but globalThis.fetch is not available. Metrics will not be tracked.");
|
|
415
|
+
return () => {
|
|
416
|
+
};
|
|
417
|
+
}
|
|
412
418
|
const original = globalThis.fetch.bind(globalThis);
|
|
413
419
|
const self = this;
|
|
420
|
+
this.log("autoTrackRequests: fetch interceptor installed");
|
|
414
421
|
globalThis.fetch = async function patchedFetch(input, init) {
|
|
415
422
|
var _a;
|
|
416
423
|
const url = input instanceof Request ? input.url : String(input);
|
|
@@ -418,11 +425,13 @@ var BugCatchClient = class {
|
|
|
418
425
|
return original(input, init);
|
|
419
426
|
}
|
|
420
427
|
if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {
|
|
428
|
+
self.log("autoTrackRequests: ignored (trackIgnoreUrls match)", url);
|
|
421
429
|
return original(input, init);
|
|
422
430
|
}
|
|
423
431
|
const method = ((_a = init == null ? void 0 : init.method) != null ? _a : input instanceof Request ? input.method : "GET").toUpperCase();
|
|
424
432
|
const route = normalizeUrl(url);
|
|
425
433
|
const start = Date.now();
|
|
434
|
+
self.log("autoTrackRequests: intercepted", method, url);
|
|
426
435
|
try {
|
|
427
436
|
const response = await original(input, init);
|
|
428
437
|
void self.sendMetric({
|
|
@@ -440,16 +449,80 @@ var BugCatchClient = class {
|
|
|
440
449
|
};
|
|
441
450
|
return () => {
|
|
442
451
|
globalThis.fetch = original;
|
|
452
|
+
this.log("autoTrackRequests: fetch interceptor removed");
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
installXhrInterceptor() {
|
|
456
|
+
if (typeof XMLHttpRequest === "undefined") {
|
|
457
|
+
return () => {
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const self = this;
|
|
461
|
+
const OriginalXHR = XMLHttpRequest;
|
|
462
|
+
const ingestBase = this.dsn.ingestUrl.split("?")[0];
|
|
463
|
+
function PatchedXHR() {
|
|
464
|
+
const xhr = new OriginalXHR();
|
|
465
|
+
let method = "GET";
|
|
466
|
+
let url = "";
|
|
467
|
+
let start = 0;
|
|
468
|
+
const originalOpen = xhr.open.bind(xhr);
|
|
469
|
+
const originalSend = xhr.send.bind(xhr);
|
|
470
|
+
this.open = function(m, u, async, user, password) {
|
|
471
|
+
method = m ? m.toUpperCase() : "GET";
|
|
472
|
+
url = u || "";
|
|
473
|
+
return originalOpen(m, u, async != null ? async : true, user, password);
|
|
474
|
+
};
|
|
475
|
+
this.send = function(body) {
|
|
476
|
+
const skip = url.includes(ingestBase) || (self.opts.trackIgnoreUrls ? matchesPattern(url, self.opts.trackIgnoreUrls) : false);
|
|
477
|
+
if (!skip) {
|
|
478
|
+
start = Date.now();
|
|
479
|
+
self.log("autoTrackRequests: XHR intercepted", method, url);
|
|
480
|
+
xhr.addEventListener("loadend", () => {
|
|
481
|
+
void self.sendMetric({
|
|
482
|
+
method,
|
|
483
|
+
route: normalizeUrl(url),
|
|
484
|
+
duration_ms: Date.now() - start,
|
|
485
|
+
status_code: xhr.status || 0,
|
|
486
|
+
user_id: self.user.id
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
return originalSend(body);
|
|
491
|
+
};
|
|
492
|
+
return new Proxy(this, {
|
|
493
|
+
get(_target, prop) {
|
|
494
|
+
if (prop === "open") return this.open;
|
|
495
|
+
if (prop === "send") return this.send;
|
|
496
|
+
const val = xhr[prop];
|
|
497
|
+
return typeof val === "function" ? val.bind(xhr) : val;
|
|
498
|
+
},
|
|
499
|
+
set(_target, prop, value) {
|
|
500
|
+
xhr[prop] = value;
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
PatchedXHR.prototype = OriginalXHR.prototype;
|
|
506
|
+
window.XMLHttpRequest = PatchedXHR;
|
|
507
|
+
this.log("autoTrackRequests: XHR interceptor installed");
|
|
508
|
+
return () => {
|
|
509
|
+
window.XMLHttpRequest = OriginalXHR;
|
|
510
|
+
this.log("autoTrackRequests: XHR interceptor removed");
|
|
443
511
|
};
|
|
444
512
|
}
|
|
445
513
|
async sendMetric(metric) {
|
|
514
|
+
this.log("autoTrackRequests: sending metric", metric.method, metric.route, metric.duration_ms + "ms", metric.status_code);
|
|
446
515
|
try {
|
|
447
|
-
await fetch(this.dsn.metricsUrl, {
|
|
516
|
+
const res = await fetch(this.dsn.metricsUrl, {
|
|
448
517
|
method: "POST",
|
|
449
518
|
headers: { "Content-Type": "application/json" },
|
|
450
519
|
body: JSON.stringify(metric)
|
|
451
520
|
});
|
|
452
|
-
|
|
521
|
+
if (!res.ok) {
|
|
522
|
+
this.log("autoTrackRequests: metric rejected by server \u2014", res.status, await res.text().catch(() => ""));
|
|
523
|
+
}
|
|
524
|
+
} catch (err) {
|
|
525
|
+
this.log("autoTrackRequests: failed to send metric \u2014", err.message);
|
|
453
526
|
}
|
|
454
527
|
}
|
|
455
528
|
// ─── Internal: transport ─────────────────────────────────────────────────
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parse-stack.ts","../src/breadcrumbs.ts","../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { StackFrame } from './types.js';\n\n// Chrome/V8: \" at functionName (filename:line:col)\"\n// \" at filename:line:col\"\nconst CHROME_RE = /^\\s*at (?:(.*?) \\()?(.+?):(\\d+):(\\d+)\\)?$/;\n\n// Firefox/Safari: \"functionName@filename:line:col\"\n// \"@filename:line:col\"\nconst FIREFOX_RE = /^(?:(.+?)@)?(.+?):(\\d+):(\\d+)$/;\n\n// Origins that are not \"in-app\" frames\nconst INTERNAL_PATTERNS = [/node_modules\\//, /bugcatch[-_]?sdk/, /^\\(native\\)$/, /^native code/];\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n return !INTERNAL_PATTERNS.some((p) => p.test(filename));\n}\n\nfunction parseChromeLine(line: string): StackFrame | null {\n const m = CHROME_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nfunction parseFirefoxLine(line: string): StackFrame | null {\n const m = FIREFOX_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nexport function parseStack(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const lines = stack.split('\\n');\n const frames: StackFrame[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('Error') || trimmed.startsWith(error.message ?? '')) {\n continue;\n }\n const frame = parseChromeLine(trimmed) ?? parseFirefoxLine(trimmed);\n if (frame) {\n frames.push(frame);\n }\n }\n\n // The API fingerprinting uses the LAST in-app frame, which maps to innermost\n // call. Return in innermost-first order (as captured).\n return frames;\n}\n","import type { BreadcrumbEntry } from './types.js';\n\nexport class BreadcrumbBuffer {\n private readonly buffer: BreadcrumbEntry[] = [];\n private readonly max: number;\n\n constructor(max = 100) {\n this.max = max;\n }\n\n add(crumb: BreadcrumbEntry): void {\n if (this.buffer.length >= this.max) {\n this.buffer.shift();\n }\n this.buffer.push(crumb);\n }\n\n getAll(): BreadcrumbEntry[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer.length = 0;\n }\n}\n\n// ─── Auto-capture helpers ─────────────────────────────────────────────────────\n\ntype AddFn = (crumb: BreadcrumbEntry) => void;\n\n/**\n * Patch History API (pushState / replaceState / popstate) to capture\n * navigation breadcrumbs.\n */\nexport function installNavigationBreadcrumbs(add: AddFn): () => void {\n if (typeof window === 'undefined') return () => undefined;\n\n const originalPush = history.pushState.bind(history);\n const originalReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated to ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalPush(...args);\n };\n\n history.replaceState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Replaced state: ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalReplace(...args);\n };\n\n const onPopState = () => {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated back/forward to ${window.location.href}`,\n data: { to: window.location.href },\n });\n };\n\n window.addEventListener('popstate', onPopState);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n window.removeEventListener('popstate', onPopState);\n };\n}\n\n/**\n * Capture click events as breadcrumbs (element tag + text).\n */\nexport function installClickBreadcrumbs(add: AddFn): () => void {\n if (typeof document === 'undefined') return () => undefined;\n\n const handler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const tag = target.tagName?.toLowerCase() ?? 'unknown';\n const text = (target.textContent ?? '').trim().slice(0, 50);\n const id = target.id ? `#${target.id}` : '';\n const cls = target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').join('.')}`\n : '';\n add({\n timestamp: new Date().toISOString(),\n type: 'user',\n category: 'ui.click',\n message: `Click on <${tag}${id}${cls}>`,\n data: { tag, text: text || undefined },\n });\n };\n\n document.addEventListener('click', handler, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', handler, { capture: true });\n };\n}\n\n/**\n * Capture console.warn and console.error calls as breadcrumbs.\n */\nexport function installConsoleBreadcrumbs(add: AddFn): () => void {\n if (typeof console === 'undefined') return () => undefined;\n\n const originalWarn = console.warn.bind(console);\n const originalError = console.error.bind(console);\n\n const formatArgs = (args: unknown[]): string =>\n args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ').slice(0, 200);\n\n console.warn = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'warning' },\n });\n originalWarn(...args);\n };\n\n console.error = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'error' },\n });\n originalError(...args);\n };\n\n return () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n}\n","import type {\n BugCatchOptions,\n UserContext,\n BreadcrumbEntry,\n EventPayload,\n MetricPayload,\n ParsedDsn,\n ExceptionValue,\n} from './types.js';\nimport { parseStack } from './parse-stack.js';\nimport {\n BreadcrumbBuffer,\n installNavigationBreadcrumbs,\n installClickBreadcrumbs,\n installConsoleBreadcrumbs,\n} from './breadcrumbs.js';\n\n// ─── UUID ─────────────────────────────────────────────────────────────────────\n\nfunction uuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// ─── DSN parser ───────────────────────────────────────────────────────────────\n\nfunction parseDsn(dsn: string): ParsedDsn & { metricsUrl: string } {\n let url: URL;\n try {\n url = new URL(dsn);\n } catch {\n throw new Error(`[BugCatch] Invalid DSN: \"${dsn}\"`);\n }\n\n const sdkKey = url.searchParams.get('key');\n if (!sdkKey) {\n throw new Error(`[BugCatch] DSN is missing the \"key\" query parameter: \"${dsn}\"`);\n }\n\n // Extract projectId from the last path segment (/ingest/{projectId})\n const segments = url.pathname.split('/').filter(Boolean);\n const projectId = segments[segments.length - 1];\n if (!projectId) {\n throw new Error(`[BugCatch] Could not extract projectId from DSN path: \"${dsn}\"`);\n }\n\n // Reconstruct the URL without extra query params\n const ingestUrl = `${url.origin}${url.pathname}?key=${sdkKey}`;\n const metricsUrl = `${url.origin}${url.pathname}/metrics?key=${sdkKey}`;\n\n return { ingestUrl, metricsUrl, projectId, sdkKey };\n}\n\n// ─── Route normalizer ─────────────────────────────────────────────────────────\n\n/**\n * Strips the origin and query string from a URL and replaces dynamic path\n * segments (UUIDs, numeric IDs) with `:id` so metrics group by route template.\n *\n * e.g. https://api.example.com/users/42/orders/abc-123?page=1 → /users/:id/orders/:id\n */\nfunction normalizeUrl(rawUrl: string): string {\n let pathname: string;\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n // rawUrl is already a path (e.g. \"/api/users/1\")\n pathname = rawUrl.split('?')[0];\n }\n return pathname\n .replace(/\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')\n .replace(/\\/\\d{1,20}(?=\\/|$)/g, '/:id');\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────────\n\nfunction matchesPattern(value: string, patterns: Array<string | RegExp>): boolean {\n return patterns.some((p) =>\n typeof p === 'string' ? value.includes(p) : p.test(value),\n );\n}\n\n// ─── Client ───────────────────────────────────────────────────────────────────\n\nexport class BugCatchClient {\n private readonly opts: Required<\n Pick<BugCatchOptions, 'debug' | 'maxBreadcrumbs' | 'autoCaptureErrors' | 'autoCaptureBreadcrumbs' | 'autoTrackRequests'>\n > & BugCatchOptions;\n\n private readonly dsn: ParsedDsn & { metricsUrl: string };\n private readonly crumbs: BreadcrumbBuffer;\n private user: UserContext = {};\n private tags: Record<string, string> = {};\n private readonly cleanups: Array<() => void> = [];\n\n constructor(options: BugCatchOptions) {\n this.opts = {\n debug: false,\n maxBreadcrumbs: 100,\n autoCaptureErrors: true,\n autoCaptureBreadcrumbs: true,\n autoTrackRequests: false,\n ...options,\n };\n\n this.dsn = parseDsn(options.dsn);\n this.crumbs = new BreadcrumbBuffer(this.opts.maxBreadcrumbs);\n\n if (this.opts.autoCaptureErrors) {\n this.installErrorHandlers();\n }\n\n if (this.opts.autoCaptureBreadcrumbs) {\n this.cleanups.push(installNavigationBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installClickBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installConsoleBreadcrumbs((c) => this.addBreadcrumb(c)));\n }\n\n if (this.opts.autoTrackRequests) {\n this.cleanups.push(this.installFetchInterceptor());\n }\n\n this.log('Initialized. Project:', this.dsn.projectId);\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────────\n\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n const event = this.buildExceptionPayload(error, extra);\n void this.send(event);\n return event.event_id;\n }\n\n captureMessage(message: string, level: string = 'info', extra?: Record<string, unknown>): string {\n const event = this.buildMessagePayload(message, level, extra);\n void this.send(event);\n return event.event_id;\n }\n\n setUser(user: UserContext): void {\n this.user = {\n ...user,\n id: user.id != null ? String(user.id) : undefined,\n };\n }\n\n clearUser(): void {\n this.user = {};\n }\n\n setTag(key: string, value: string): void {\n this.tags[key] = value;\n }\n\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n this.crumbs.add(crumb);\n }\n\n /** Tear down all global listeners. Call when unmounting in SPAs. */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups.length = 0;\n }\n\n /**\n * Manually report an API call timing. Use this when `autoTrackRequests`\n * is off or when you want to track server-side (Node.js) requests explicitly.\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n void this.sendMetric({ method: method.toUpperCase(), route, duration_ms: durationMs, status_code: statusCode });\n }\n\n // ─── Internal: build payloads ────────────────────────────────────────────\n\n private buildExceptionPayload(\n error: unknown,\n extra?: Record<string, unknown>,\n ): EventPayload {\n const err = error instanceof Error ? error : new Error(String(error));\n const frames = parseStack(err);\n\n const exceptionValue: ExceptionValue = {\n type: err.name || 'Error',\n value: err.message,\n stacktrace: frames.length > 0 ? { frames } : undefined,\n };\n\n return this.buildBase({\n level: 'error',\n exception: { values: [exceptionValue] },\n extra,\n });\n }\n\n private buildMessagePayload(\n message: string,\n level: string,\n extra?: Record<string, unknown>,\n ): EventPayload {\n return this.buildBase({ level, message, extra });\n }\n\n private buildBase(\n overrides: Partial<EventPayload> & { extra?: Record<string, unknown> },\n ): EventPayload {\n const { extra, ...rest } = overrides;\n const payload: EventPayload = {\n event_id: uuid(),\n timestamp: new Date().toISOString(),\n platform: 'javascript',\n ...rest,\n };\n\n if (this.opts.release) payload.release = this.opts.release;\n if (this.opts.environment) payload.environment = this.opts.environment;\n\n if (Object.keys(this.user).length > 0) {\n payload.user = { ...this.user };\n }\n\n if (Object.keys(this.tags).length > 0) {\n payload.tags = { ...this.tags };\n }\n\n if (extra && Object.keys(extra).length > 0) {\n payload.extra = extra;\n }\n\n const breadcrumbs = this.crumbs.getAll();\n if (breadcrumbs.length > 0) {\n payload.breadcrumbs = breadcrumbs;\n }\n\n // Capture browser request context\n if (typeof window !== 'undefined') {\n payload.request = {\n url: window.location.href,\n headers: {\n 'user-agent': navigator.userAgent,\n },\n };\n }\n\n return payload;\n }\n\n // ─── Internal: error handlers ────────────────────────────────────────────\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') {\n // Node.js environment\n const onUncaught = (err: Error) => {\n this.captureException(err, { handler: 'uncaughtException' });\n };\n const onUnhandled = (reason: unknown) => {\n this.captureException(reason, { handler: 'unhandledRejection' });\n };\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onUnhandled);\n this.cleanups.push(() => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onUnhandled);\n });\n return;\n }\n\n // Browser environment\n const onError = (event: ErrorEvent) => {\n if (!event.error) return;\n if (this.shouldIgnore(event.error, event.filename ?? '')) return;\n this.captureException(event.error, { handler: 'window.onerror' });\n };\n\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason as unknown;\n if (this.shouldIgnore(reason, '')) return;\n this.captureException(reason, { handler: 'unhandledrejection' });\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n this.cleanups.push(() => {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n });\n }\n\n private shouldIgnore(error: unknown, scriptUrl: string): boolean {\n const { ignoreUrls, ignoreErrors } = this.opts;\n\n if (ignoreUrls?.length && scriptUrl) {\n if (matchesPattern(scriptUrl, ignoreUrls)) return true;\n }\n\n if (ignoreErrors?.length) {\n const message = error instanceof Error ? error.message : String(error);\n if (matchesPattern(message, ignoreErrors)) return true;\n }\n\n return false;\n }\n\n // ─── Internal: request tracking ──────────────────────────────────────────\n\n private installFetchInterceptor(): () => void {\n const original = globalThis.fetch.bind(globalThis);\n const self = this;\n\n globalThis.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url = input instanceof Request ? input.url : String(input);\n\n // Never intercept BugCatch's own ingest/metrics requests\n if (url.includes(self.dsn.ingestUrl.split('?')[0])) {\n return original(input, init);\n }\n\n if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {\n return original(input, init);\n }\n\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const route = normalizeUrl(url);\n const start = Date.now();\n\n try {\n const response = await original(input, init);\n void self.sendMetric({\n method,\n route,\n duration_ms: Date.now() - start,\n status_code: response.status,\n user_id: self.user.id,\n });\n return response;\n } catch (err) {\n // Network error — report as status 0\n void self.sendMetric({ method, route, duration_ms: Date.now() - start, status_code: 0 });\n throw err;\n }\n };\n\n // Return cleanup function that restores original fetch\n return () => {\n globalThis.fetch = original;\n };\n }\n\n private async sendMetric(metric: MetricPayload): Promise<void> {\n try {\n await fetch(this.dsn.metricsUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(metric),\n });\n } catch {\n // Silently ignore — metric loss is acceptable\n }\n }\n\n // ─── Internal: transport ─────────────────────────────────────────────────\n\n private async send(event: EventPayload): Promise<void> {\n let finalEvent: EventPayload | false = event;\n\n if (this.opts.beforeSend) {\n finalEvent = this.opts.beforeSend(event);\n if (finalEvent === false) {\n this.log('Event dropped by beforeSend hook');\n return;\n }\n }\n\n this.log('Sending event:', finalEvent.event_id, finalEvent.level);\n\n let body: string;\n try {\n body = JSON.stringify(finalEvent);\n } catch (err) {\n console.warn('[BugCatch] Failed to serialize event:', err);\n return;\n }\n\n try {\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n\n // keepalive is browser-only; Node.js fetch (undici) enforces a 64 KB body\n // limit with keepalive: true, which silently drops large payloads.\n if (typeof window !== 'undefined') {\n fetchOptions.keepalive = true;\n }\n\n const res = await fetch(this.dsn.ingestUrl, fetchOptions);\n\n if (!res.ok) {\n console.warn(`[BugCatch] Ingest responded with ${res.status}:`, await res.text());\n }\n } catch (err) {\n console.warn('[BugCatch] Failed to send event:', err);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.opts.debug) {\n console.debug('[BugCatch]', ...args);\n }\n }\n}\n","import { BugCatchClient } from './client.js';\nimport type { BugCatchOptions, UserContext, BreadcrumbEntry } from './types.js';\n\nexport type { BugCatchOptions, UserContext, BreadcrumbEntry };\nexport type { EventPayload, StackFrame, ParsedDsn } from './types.js';\nexport { BugCatchClient };\n\n// ─── Singleton instance ───────────────────────────────────────────────────────\n\nlet _client: BugCatchClient | null = null;\n\nfunction getClient(): BugCatchClient {\n if (!_client) {\n throw new Error('[BugCatch] SDK not initialized. Call BugCatch.init(options) first.');\n }\n return _client;\n}\n\n// ─── Public singleton API ─────────────────────────────────────────────────────\n\nconst BugCatch = {\n /**\n * Initialize the SDK. Call this once, as early as possible in your app.\n *\n * @example\n * BugCatch.init({\n * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',\n * release: '1.0.0',\n * environment: 'production',\n * });\n */\n init(options: BugCatchOptions): BugCatchClient {\n if (_client) {\n console.warn('[BugCatch] init() called more than once. Ignoring.');\n return _client;\n }\n _client = new BugCatchClient(options);\n return _client;\n },\n\n /**\n * Capture an Error object or any value as an error event.\n * Returns the generated event_id.\n */\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n return getClient().captureException(error, extra);\n },\n\n /**\n * Capture a plain text message as an event.\n * Returns the generated event_id.\n */\n captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string {\n return getClient().captureMessage(message, level, extra);\n },\n\n /**\n * Set the current user context. Attached to all subsequent events.\n */\n setUser(user: UserContext): void {\n getClient().setUser(user);\n },\n\n /**\n * Clear the current user context (e.g. on logout).\n */\n clearUser(): void {\n getClient().clearUser();\n },\n\n /**\n * Set a tag that will be attached to all subsequent events.\n */\n setTag(key: string, value: string): void {\n getClient().setTag(key, value);\n },\n\n /**\n * Manually add a breadcrumb.\n */\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n getClient().addBreadcrumb(crumb);\n },\n\n /**\n * Manually report an API call timing to BugCatch.\n * Use when `autoTrackRequests` is off or for server-side tracking.\n *\n * @example\n * const start = Date.now();\n * await fetch('/api/orders');\n * BugCatch.trackRequest('GET', '/api/orders', Date.now() - start, 200);\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n getClient().trackRequest(method, route, durationMs, statusCode);\n },\n\n /**\n * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.\n */\n destroy(): void {\n _client?.destroy();\n _client = null;\n },\n};\n\n// Named export for CJS consumers: const { BugCatch } = require('bugcatch-sdk')\nexport { BugCatch };\n\n// Default export for ESM consumers: import BugCatch from 'bugcatch-sdk'\nexport default BugCatch;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/parse-stack.ts","../src/breadcrumbs.ts","../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { StackFrame } from './types.js';\n\n// Chrome/V8: \" at functionName (filename:line:col)\"\n// \" at filename:line:col\"\nconst CHROME_RE = /^\\s*at (?:(.*?) \\()?(.+?):(\\d+):(\\d+)\\)?$/;\n\n// Firefox/Safari: \"functionName@filename:line:col\"\n// \"@filename:line:col\"\nconst FIREFOX_RE = /^(?:(.+?)@)?(.+?):(\\d+):(\\d+)$/;\n\n// Origins that are not \"in-app\" frames\nconst INTERNAL_PATTERNS = [/node_modules\\//, /bugcatch[-_]?sdk/, /^\\(native\\)$/, /^native code/];\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n return !INTERNAL_PATTERNS.some((p) => p.test(filename));\n}\n\nfunction parseChromeLine(line: string): StackFrame | null {\n const m = CHROME_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nfunction parseFirefoxLine(line: string): StackFrame | null {\n const m = FIREFOX_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nexport function parseStack(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const lines = stack.split('\\n');\n const frames: StackFrame[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('Error') || trimmed.startsWith(error.message ?? '')) {\n continue;\n }\n const frame = parseChromeLine(trimmed) ?? parseFirefoxLine(trimmed);\n if (frame) {\n frames.push(frame);\n }\n }\n\n // The API fingerprinting uses the LAST in-app frame, which maps to innermost\n // call. Return in innermost-first order (as captured).\n return frames;\n}\n","import type { BreadcrumbEntry } from './types.js';\n\nexport class BreadcrumbBuffer {\n private readonly buffer: BreadcrumbEntry[] = [];\n private readonly max: number;\n\n constructor(max = 100) {\n this.max = max;\n }\n\n add(crumb: BreadcrumbEntry): void {\n if (this.buffer.length >= this.max) {\n this.buffer.shift();\n }\n this.buffer.push(crumb);\n }\n\n getAll(): BreadcrumbEntry[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer.length = 0;\n }\n}\n\n// ─── Auto-capture helpers ─────────────────────────────────────────────────────\n\ntype AddFn = (crumb: BreadcrumbEntry) => void;\n\n/**\n * Patch History API (pushState / replaceState / popstate) to capture\n * navigation breadcrumbs.\n */\nexport function installNavigationBreadcrumbs(add: AddFn): () => void {\n if (typeof window === 'undefined') return () => undefined;\n\n const originalPush = history.pushState.bind(history);\n const originalReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated to ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalPush(...args);\n };\n\n history.replaceState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Replaced state: ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalReplace(...args);\n };\n\n const onPopState = () => {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated back/forward to ${window.location.href}`,\n data: { to: window.location.href },\n });\n };\n\n window.addEventListener('popstate', onPopState);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n window.removeEventListener('popstate', onPopState);\n };\n}\n\n/**\n * Capture click events as breadcrumbs (element tag + text).\n */\nexport function installClickBreadcrumbs(add: AddFn): () => void {\n if (typeof document === 'undefined') return () => undefined;\n\n const handler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const tag = target.tagName?.toLowerCase() ?? 'unknown';\n const text = (target.textContent ?? '').trim().slice(0, 50);\n const id = target.id ? `#${target.id}` : '';\n const cls = target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').join('.')}`\n : '';\n add({\n timestamp: new Date().toISOString(),\n type: 'user',\n category: 'ui.click',\n message: `Click on <${tag}${id}${cls}>`,\n data: { tag, text: text || undefined },\n });\n };\n\n document.addEventListener('click', handler, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', handler, { capture: true });\n };\n}\n\n/**\n * Capture console.warn and console.error calls as breadcrumbs.\n */\nexport function installConsoleBreadcrumbs(add: AddFn): () => void {\n if (typeof console === 'undefined') return () => undefined;\n\n const originalWarn = console.warn.bind(console);\n const originalError = console.error.bind(console);\n\n const formatArgs = (args: unknown[]): string =>\n args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ').slice(0, 200);\n\n console.warn = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'warning' },\n });\n originalWarn(...args);\n };\n\n console.error = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'error' },\n });\n originalError(...args);\n };\n\n return () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n}\n","import type {\n BugCatchOptions,\n UserContext,\n BreadcrumbEntry,\n EventPayload,\n MetricPayload,\n ParsedDsn,\n ExceptionValue,\n} from './types.js';\nimport { parseStack } from './parse-stack.js';\nimport {\n BreadcrumbBuffer,\n installNavigationBreadcrumbs,\n installClickBreadcrumbs,\n installConsoleBreadcrumbs,\n} from './breadcrumbs.js';\n\n// ─── UUID ─────────────────────────────────────────────────────────────────────\n\nfunction uuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// ─── DSN parser ───────────────────────────────────────────────────────────────\n\nfunction parseDsn(dsn: string): ParsedDsn & { metricsUrl: string } {\n let url: URL;\n try {\n url = new URL(dsn);\n } catch {\n throw new Error(`[BugCatch] Invalid DSN: \"${dsn}\"`);\n }\n\n const sdkKey = url.searchParams.get('key');\n if (!sdkKey) {\n throw new Error(`[BugCatch] DSN is missing the \"key\" query parameter: \"${dsn}\"`);\n }\n\n // Extract projectId from the last path segment (/ingest/{projectId})\n const segments = url.pathname.split('/').filter(Boolean);\n const projectId = segments[segments.length - 1];\n if (!projectId) {\n throw new Error(`[BugCatch] Could not extract projectId from DSN path: \"${dsn}\"`);\n }\n\n // Reconstruct the URL without extra query params\n const ingestUrl = `${url.origin}${url.pathname}?key=${sdkKey}`;\n const metricsUrl = `${url.origin}${url.pathname}/metrics?key=${sdkKey}`;\n\n return { ingestUrl, metricsUrl, projectId, sdkKey };\n}\n\n// ─── Route normalizer ─────────────────────────────────────────────────────────\n\n/**\n * Strips the origin and query string from a URL and replaces dynamic path\n * segments (UUIDs, numeric IDs) with `:id` so metrics group by route template.\n *\n * e.g. https://api.example.com/users/42/orders/abc-123?page=1 → /users/:id/orders/:id\n */\nfunction normalizeUrl(rawUrl: string): string {\n let pathname: string;\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n // rawUrl is already a path (e.g. \"/api/users/1\")\n pathname = rawUrl.split('?')[0];\n }\n return pathname\n .replace(/\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')\n .replace(/\\/\\d{1,20}(?=\\/|$)/g, '/:id');\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────────\n\nfunction matchesPattern(value: string, patterns: Array<string | RegExp>): boolean {\n return patterns.some((p) =>\n typeof p === 'string' ? value.includes(p) : p.test(value),\n );\n}\n\n// ─── Client ───────────────────────────────────────────────────────────────────\n\nexport class BugCatchClient {\n private readonly opts: Required<\n Pick<BugCatchOptions, 'debug' | 'maxBreadcrumbs' | 'autoCaptureErrors' | 'autoCaptureBreadcrumbs' | 'autoTrackRequests'>\n > & BugCatchOptions;\n\n private readonly dsn: ParsedDsn & { metricsUrl: string };\n private readonly crumbs: BreadcrumbBuffer;\n private user: UserContext = {};\n private tags: Record<string, string> = {};\n private readonly cleanups: Array<() => void> = [];\n\n constructor(options: BugCatchOptions) {\n this.opts = {\n debug: false,\n maxBreadcrumbs: 100,\n autoCaptureErrors: true,\n autoCaptureBreadcrumbs: true,\n autoTrackRequests: false,\n ...options,\n };\n\n this.dsn = parseDsn(options.dsn);\n this.crumbs = new BreadcrumbBuffer(this.opts.maxBreadcrumbs);\n\n if (this.opts.autoCaptureErrors) {\n this.installErrorHandlers();\n }\n\n if (this.opts.autoCaptureBreadcrumbs) {\n this.cleanups.push(installNavigationBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installClickBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installConsoleBreadcrumbs((c) => this.addBreadcrumb(c)));\n }\n\n if (this.opts.autoTrackRequests) {\n this.cleanups.push(this.installFetchInterceptor());\n this.cleanups.push(this.installXhrInterceptor());\n }\n\n this.log('Initialized. Project:', this.dsn.projectId);\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────────\n\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n const event = this.buildExceptionPayload(error, extra);\n void this.send(event);\n return event.event_id;\n }\n\n captureMessage(message: string, level: string = 'info', extra?: Record<string, unknown>): string {\n const event = this.buildMessagePayload(message, level, extra);\n void this.send(event);\n return event.event_id;\n }\n\n setUser(user: UserContext): void {\n this.user = {\n ...user,\n id: user.id != null ? String(user.id) : undefined,\n };\n }\n\n clearUser(): void {\n this.user = {};\n }\n\n setTag(key: string, value: string): void {\n this.tags[key] = value;\n }\n\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n this.crumbs.add(crumb);\n }\n\n /** Tear down all global listeners. Call when unmounting in SPAs. */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups.length = 0;\n }\n\n /**\n * Manually report an API call timing. Use this when `autoTrackRequests`\n * is off or when you want to track server-side (Node.js) requests explicitly.\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n void this.sendMetric({ method: method.toUpperCase(), route, duration_ms: durationMs, status_code: statusCode });\n }\n\n // ─── Internal: build payloads ────────────────────────────────────────────\n\n private buildExceptionPayload(\n error: unknown,\n extra?: Record<string, unknown>,\n ): EventPayload {\n const err = error instanceof Error ? error : new Error(String(error));\n const frames = parseStack(err);\n\n const exceptionValue: ExceptionValue = {\n type: err.name || 'Error',\n value: err.message,\n stacktrace: frames.length > 0 ? { frames } : undefined,\n };\n\n return this.buildBase({\n level: 'error',\n exception: { values: [exceptionValue] },\n extra,\n });\n }\n\n private buildMessagePayload(\n message: string,\n level: string,\n extra?: Record<string, unknown>,\n ): EventPayload {\n return this.buildBase({ level, message, extra });\n }\n\n private buildBase(\n overrides: Partial<EventPayload> & { extra?: Record<string, unknown> },\n ): EventPayload {\n const { extra, ...rest } = overrides;\n const payload: EventPayload = {\n event_id: uuid(),\n timestamp: new Date().toISOString(),\n platform: 'javascript',\n ...rest,\n };\n\n if (this.opts.release) payload.release = this.opts.release;\n if (this.opts.environment) payload.environment = this.opts.environment;\n\n if (Object.keys(this.user).length > 0) {\n payload.user = { ...this.user };\n }\n\n if (Object.keys(this.tags).length > 0) {\n payload.tags = { ...this.tags };\n }\n\n if (extra && Object.keys(extra).length > 0) {\n payload.extra = extra;\n }\n\n const breadcrumbs = this.crumbs.getAll();\n if (breadcrumbs.length > 0) {\n payload.breadcrumbs = breadcrumbs;\n }\n\n // Capture browser request context\n if (typeof window !== 'undefined') {\n payload.request = {\n url: window.location.href,\n headers: {\n 'user-agent': navigator.userAgent,\n },\n };\n }\n\n return payload;\n }\n\n // ─── Internal: error handlers ────────────────────────────────────────────\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') {\n // Node.js environment\n const onUncaught = (err: Error) => {\n this.captureException(err, { handler: 'uncaughtException' });\n };\n const onUnhandled = (reason: unknown) => {\n this.captureException(reason, { handler: 'unhandledRejection' });\n };\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onUnhandled);\n this.cleanups.push(() => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onUnhandled);\n });\n return;\n }\n\n // Browser environment\n const onError = (event: ErrorEvent) => {\n if (!event.error) return;\n if (this.shouldIgnore(event.error, event.filename ?? '')) return;\n this.captureException(event.error, { handler: 'window.onerror' });\n };\n\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason as unknown;\n if (this.shouldIgnore(reason, '')) return;\n this.captureException(reason, { handler: 'unhandledrejection' });\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n this.cleanups.push(() => {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n });\n }\n\n private shouldIgnore(error: unknown, scriptUrl: string): boolean {\n const { ignoreUrls, ignoreErrors } = this.opts;\n\n if (ignoreUrls?.length && scriptUrl) {\n if (matchesPattern(scriptUrl, ignoreUrls)) return true;\n }\n\n if (ignoreErrors?.length) {\n const message = error instanceof Error ? error.message : String(error);\n if (matchesPattern(message, ignoreErrors)) return true;\n }\n\n return false;\n }\n\n // ─── Internal: request tracking ──────────────────────────────────────────\n\n private installFetchInterceptor(): () => void {\n if (typeof globalThis.fetch !== 'function') {\n console.warn('[BugCatch] autoTrackRequests is enabled but globalThis.fetch is not available. Metrics will not be tracked.');\n return () => {};\n }\n\n const original = globalThis.fetch.bind(globalThis);\n const self = this;\n\n this.log('autoTrackRequests: fetch interceptor installed');\n\n globalThis.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url = input instanceof Request ? input.url : String(input);\n\n // Never intercept BugCatch's own ingest/metrics requests\n if (url.includes(self.dsn.ingestUrl.split('?')[0])) {\n return original(input, init);\n }\n\n if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {\n self.log('autoTrackRequests: ignored (trackIgnoreUrls match)', url);\n return original(input, init);\n }\n\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const route = normalizeUrl(url);\n const start = Date.now();\n\n self.log('autoTrackRequests: intercepted', method, url);\n\n try {\n const response = await original(input, init);\n void self.sendMetric({\n method,\n route,\n duration_ms: Date.now() - start,\n status_code: response.status,\n user_id: self.user.id,\n });\n return response;\n } catch (err) {\n // Network error — report as status 0\n void self.sendMetric({ method, route, duration_ms: Date.now() - start, status_code: 0 });\n throw err;\n }\n };\n\n // Return cleanup function that restores original fetch\n return () => {\n globalThis.fetch = original;\n this.log('autoTrackRequests: fetch interceptor removed');\n };\n }\n\n private installXhrInterceptor(): () => void {\n if (typeof XMLHttpRequest === 'undefined') {\n // Node.js environment — XHR not available\n return () => {};\n }\n\n const self = this;\n const OriginalXHR = XMLHttpRequest;\n const ingestBase = this.dsn.ingestUrl.split('?')[0];\n\n function PatchedXHR(this: XMLHttpRequest) {\n const xhr = new OriginalXHR();\n\n let method = 'GET';\n let url = '';\n let start = 0;\n\n const originalOpen = xhr.open.bind(xhr);\n const originalSend = xhr.send.bind(xhr);\n\n (this as any).open = function (m: string, u: string, async?: boolean, user?: string, password?: string) {\n method = m ? m.toUpperCase() : 'GET';\n url = u || '';\n return originalOpen(m, u, async ?? true, user, password);\n };\n\n (this as any).send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n // Skip BugCatch's own requests and ignored URLs\n const skip =\n url.includes(ingestBase) ||\n (self.opts.trackIgnoreUrls ? matchesPattern(url, self.opts.trackIgnoreUrls) : false);\n\n if (!skip) {\n start = Date.now();\n self.log('autoTrackRequests: XHR intercepted', method, url);\n\n xhr.addEventListener('loadend', () => {\n void self.sendMetric({\n method,\n route: normalizeUrl(url),\n duration_ms: Date.now() - start,\n status_code: xhr.status || 0,\n user_id: self.user.id,\n });\n });\n }\n\n return originalSend(body);\n };\n\n // Proxy all other properties/methods to the real XHR instance\n return new Proxy(this, {\n get(_target, prop) {\n if (prop === 'open') return (this as any).open;\n if (prop === 'send') return (this as any).send;\n const val = (xhr as any)[prop];\n return typeof val === 'function' ? val.bind(xhr) : val;\n },\n set(_target, prop, value) {\n (xhr as any)[prop] = value;\n return true;\n },\n });\n }\n\n PatchedXHR.prototype = OriginalXHR.prototype;\n (window as any).XMLHttpRequest = PatchedXHR;\n\n this.log('autoTrackRequests: XHR interceptor installed');\n\n return () => {\n (window as any).XMLHttpRequest = OriginalXHR;\n this.log('autoTrackRequests: XHR interceptor removed');\n };\n }\n\n private async sendMetric(metric: MetricPayload): Promise<void> {\n this.log('autoTrackRequests: sending metric', metric.method, metric.route, metric.duration_ms + 'ms', metric.status_code);\n try {\n const res = await fetch(this.dsn.metricsUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(metric),\n });\n if (!res.ok) {\n this.log('autoTrackRequests: metric rejected by server —', res.status, await res.text().catch(() => ''));\n }\n } catch (err) {\n this.log('autoTrackRequests: failed to send metric —', (err as Error).message);\n }\n }\n\n // ─── Internal: transport ─────────────────────────────────────────────────\n\n private async send(event: EventPayload): Promise<void> {\n let finalEvent: EventPayload | false = event;\n\n if (this.opts.beforeSend) {\n finalEvent = this.opts.beforeSend(event);\n if (finalEvent === false) {\n this.log('Event dropped by beforeSend hook');\n return;\n }\n }\n\n this.log('Sending event:', finalEvent.event_id, finalEvent.level);\n\n let body: string;\n try {\n body = JSON.stringify(finalEvent);\n } catch (err) {\n console.warn('[BugCatch] Failed to serialize event:', err);\n return;\n }\n\n try {\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n\n // keepalive is browser-only; Node.js fetch (undici) enforces a 64 KB body\n // limit with keepalive: true, which silently drops large payloads.\n if (typeof window !== 'undefined') {\n fetchOptions.keepalive = true;\n }\n\n const res = await fetch(this.dsn.ingestUrl, fetchOptions);\n\n if (!res.ok) {\n console.warn(`[BugCatch] Ingest responded with ${res.status}:`, await res.text());\n }\n } catch (err) {\n console.warn('[BugCatch] Failed to send event:', err);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.opts.debug) {\n console.debug('[BugCatch]', ...args);\n }\n }\n}\n","import { BugCatchClient } from './client.js';\nimport type { BugCatchOptions, UserContext, BreadcrumbEntry } from './types.js';\n\nexport type { BugCatchOptions, UserContext, BreadcrumbEntry };\nexport type { EventPayload, StackFrame, ParsedDsn } from './types.js';\nexport { BugCatchClient };\n\n// ─── Singleton instance ───────────────────────────────────────────────────────\n\nlet _client: BugCatchClient | null = null;\n\nfunction getClient(): BugCatchClient {\n if (!_client) {\n throw new Error('[BugCatch] SDK not initialized. Call BugCatch.init(options) first.');\n }\n return _client;\n}\n\n// ─── Public singleton API ─────────────────────────────────────────────────────\n\nconst BugCatch = {\n /**\n * Initialize the SDK. Call this once, as early as possible in your app.\n *\n * @example\n * BugCatch.init({\n * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',\n * release: '1.0.0',\n * environment: 'production',\n * });\n */\n init(options: BugCatchOptions): BugCatchClient {\n if (_client) {\n console.warn('[BugCatch] init() called more than once. Ignoring.');\n return _client;\n }\n _client = new BugCatchClient(options);\n return _client;\n },\n\n /**\n * Capture an Error object or any value as an error event.\n * Returns the generated event_id.\n */\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n return getClient().captureException(error, extra);\n },\n\n /**\n * Capture a plain text message as an event.\n * Returns the generated event_id.\n */\n captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string {\n return getClient().captureMessage(message, level, extra);\n },\n\n /**\n * Set the current user context. Attached to all subsequent events.\n */\n setUser(user: UserContext): void {\n getClient().setUser(user);\n },\n\n /**\n * Clear the current user context (e.g. on logout).\n */\n clearUser(): void {\n getClient().clearUser();\n },\n\n /**\n * Set a tag that will be attached to all subsequent events.\n */\n setTag(key: string, value: string): void {\n getClient().setTag(key, value);\n },\n\n /**\n * Manually add a breadcrumb.\n */\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n getClient().addBreadcrumb(crumb);\n },\n\n /**\n * Manually report an API call timing to BugCatch.\n * Use when `autoTrackRequests` is off or for server-side tracking.\n *\n * @example\n * const start = Date.now();\n * await fetch('/api/orders');\n * BugCatch.trackRequest('GET', '/api/orders', Date.now() - start, 200);\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n getClient().trackRequest(method, route, durationMs, statusCode);\n },\n\n /**\n * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.\n */\n destroy(): void {\n _client?.destroy();\n _client = null;\n },\n};\n\n// Named export for CJS consumers: const { BugCatch } = require('bugcatch-sdk')\nexport { BugCatch };\n\n// Default export for ESM consumers: import BugCatch from 'bugcatch-sdk'\nexport default BugCatch;\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -265,6 +265,7 @@ var BugCatchClient = class {
|
|
|
265
265
|
}
|
|
266
266
|
if (this.opts.autoTrackRequests) {
|
|
267
267
|
this.cleanups.push(this.installFetchInterceptor());
|
|
268
|
+
this.cleanups.push(this.installXhrInterceptor());
|
|
268
269
|
}
|
|
269
270
|
this.log("Initialized. Project:", this.dsn.projectId);
|
|
270
271
|
}
|
|
@@ -405,8 +406,14 @@ var BugCatchClient = class {
|
|
|
405
406
|
}
|
|
406
407
|
// ─── Internal: request tracking ──────────────────────────────────────────
|
|
407
408
|
installFetchInterceptor() {
|
|
409
|
+
if (typeof globalThis.fetch !== "function") {
|
|
410
|
+
console.warn("[BugCatch] autoTrackRequests is enabled but globalThis.fetch is not available. Metrics will not be tracked.");
|
|
411
|
+
return () => {
|
|
412
|
+
};
|
|
413
|
+
}
|
|
408
414
|
const original = globalThis.fetch.bind(globalThis);
|
|
409
415
|
const self = this;
|
|
416
|
+
this.log("autoTrackRequests: fetch interceptor installed");
|
|
410
417
|
globalThis.fetch = async function patchedFetch(input, init) {
|
|
411
418
|
var _a;
|
|
412
419
|
const url = input instanceof Request ? input.url : String(input);
|
|
@@ -414,11 +421,13 @@ var BugCatchClient = class {
|
|
|
414
421
|
return original(input, init);
|
|
415
422
|
}
|
|
416
423
|
if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {
|
|
424
|
+
self.log("autoTrackRequests: ignored (trackIgnoreUrls match)", url);
|
|
417
425
|
return original(input, init);
|
|
418
426
|
}
|
|
419
427
|
const method = ((_a = init == null ? void 0 : init.method) != null ? _a : input instanceof Request ? input.method : "GET").toUpperCase();
|
|
420
428
|
const route = normalizeUrl(url);
|
|
421
429
|
const start = Date.now();
|
|
430
|
+
self.log("autoTrackRequests: intercepted", method, url);
|
|
422
431
|
try {
|
|
423
432
|
const response = await original(input, init);
|
|
424
433
|
void self.sendMetric({
|
|
@@ -436,16 +445,80 @@ var BugCatchClient = class {
|
|
|
436
445
|
};
|
|
437
446
|
return () => {
|
|
438
447
|
globalThis.fetch = original;
|
|
448
|
+
this.log("autoTrackRequests: fetch interceptor removed");
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
installXhrInterceptor() {
|
|
452
|
+
if (typeof XMLHttpRequest === "undefined") {
|
|
453
|
+
return () => {
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
const self = this;
|
|
457
|
+
const OriginalXHR = XMLHttpRequest;
|
|
458
|
+
const ingestBase = this.dsn.ingestUrl.split("?")[0];
|
|
459
|
+
function PatchedXHR() {
|
|
460
|
+
const xhr = new OriginalXHR();
|
|
461
|
+
let method = "GET";
|
|
462
|
+
let url = "";
|
|
463
|
+
let start = 0;
|
|
464
|
+
const originalOpen = xhr.open.bind(xhr);
|
|
465
|
+
const originalSend = xhr.send.bind(xhr);
|
|
466
|
+
this.open = function(m, u, async, user, password) {
|
|
467
|
+
method = m ? m.toUpperCase() : "GET";
|
|
468
|
+
url = u || "";
|
|
469
|
+
return originalOpen(m, u, async != null ? async : true, user, password);
|
|
470
|
+
};
|
|
471
|
+
this.send = function(body) {
|
|
472
|
+
const skip = url.includes(ingestBase) || (self.opts.trackIgnoreUrls ? matchesPattern(url, self.opts.trackIgnoreUrls) : false);
|
|
473
|
+
if (!skip) {
|
|
474
|
+
start = Date.now();
|
|
475
|
+
self.log("autoTrackRequests: XHR intercepted", method, url);
|
|
476
|
+
xhr.addEventListener("loadend", () => {
|
|
477
|
+
void self.sendMetric({
|
|
478
|
+
method,
|
|
479
|
+
route: normalizeUrl(url),
|
|
480
|
+
duration_ms: Date.now() - start,
|
|
481
|
+
status_code: xhr.status || 0,
|
|
482
|
+
user_id: self.user.id
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
return originalSend(body);
|
|
487
|
+
};
|
|
488
|
+
return new Proxy(this, {
|
|
489
|
+
get(_target, prop) {
|
|
490
|
+
if (prop === "open") return this.open;
|
|
491
|
+
if (prop === "send") return this.send;
|
|
492
|
+
const val = xhr[prop];
|
|
493
|
+
return typeof val === "function" ? val.bind(xhr) : val;
|
|
494
|
+
},
|
|
495
|
+
set(_target, prop, value) {
|
|
496
|
+
xhr[prop] = value;
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
PatchedXHR.prototype = OriginalXHR.prototype;
|
|
502
|
+
window.XMLHttpRequest = PatchedXHR;
|
|
503
|
+
this.log("autoTrackRequests: XHR interceptor installed");
|
|
504
|
+
return () => {
|
|
505
|
+
window.XMLHttpRequest = OriginalXHR;
|
|
506
|
+
this.log("autoTrackRequests: XHR interceptor removed");
|
|
439
507
|
};
|
|
440
508
|
}
|
|
441
509
|
async sendMetric(metric) {
|
|
510
|
+
this.log("autoTrackRequests: sending metric", metric.method, metric.route, metric.duration_ms + "ms", metric.status_code);
|
|
442
511
|
try {
|
|
443
|
-
await fetch(this.dsn.metricsUrl, {
|
|
512
|
+
const res = await fetch(this.dsn.metricsUrl, {
|
|
444
513
|
method: "POST",
|
|
445
514
|
headers: { "Content-Type": "application/json" },
|
|
446
515
|
body: JSON.stringify(metric)
|
|
447
516
|
});
|
|
448
|
-
|
|
517
|
+
if (!res.ok) {
|
|
518
|
+
this.log("autoTrackRequests: metric rejected by server \u2014", res.status, await res.text().catch(() => ""));
|
|
519
|
+
}
|
|
520
|
+
} catch (err) {
|
|
521
|
+
this.log("autoTrackRequests: failed to send metric \u2014", err.message);
|
|
449
522
|
}
|
|
450
523
|
}
|
|
451
524
|
// ─── Internal: transport ─────────────────────────────────────────────────
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parse-stack.ts","../src/breadcrumbs.ts","../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { StackFrame } from './types.js';\n\n// Chrome/V8: \" at functionName (filename:line:col)\"\n// \" at filename:line:col\"\nconst CHROME_RE = /^\\s*at (?:(.*?) \\()?(.+?):(\\d+):(\\d+)\\)?$/;\n\n// Firefox/Safari: \"functionName@filename:line:col\"\n// \"@filename:line:col\"\nconst FIREFOX_RE = /^(?:(.+?)@)?(.+?):(\\d+):(\\d+)$/;\n\n// Origins that are not \"in-app\" frames\nconst INTERNAL_PATTERNS = [/node_modules\\//, /bugcatch[-_]?sdk/, /^\\(native\\)$/, /^native code/];\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n return !INTERNAL_PATTERNS.some((p) => p.test(filename));\n}\n\nfunction parseChromeLine(line: string): StackFrame | null {\n const m = CHROME_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nfunction parseFirefoxLine(line: string): StackFrame | null {\n const m = FIREFOX_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nexport function parseStack(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const lines = stack.split('\\n');\n const frames: StackFrame[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('Error') || trimmed.startsWith(error.message ?? '')) {\n continue;\n }\n const frame = parseChromeLine(trimmed) ?? parseFirefoxLine(trimmed);\n if (frame) {\n frames.push(frame);\n }\n }\n\n // The API fingerprinting uses the LAST in-app frame, which maps to innermost\n // call. Return in innermost-first order (as captured).\n return frames;\n}\n","import type { BreadcrumbEntry } from './types.js';\n\nexport class BreadcrumbBuffer {\n private readonly buffer: BreadcrumbEntry[] = [];\n private readonly max: number;\n\n constructor(max = 100) {\n this.max = max;\n }\n\n add(crumb: BreadcrumbEntry): void {\n if (this.buffer.length >= this.max) {\n this.buffer.shift();\n }\n this.buffer.push(crumb);\n }\n\n getAll(): BreadcrumbEntry[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer.length = 0;\n }\n}\n\n// ─── Auto-capture helpers ─────────────────────────────────────────────────────\n\ntype AddFn = (crumb: BreadcrumbEntry) => void;\n\n/**\n * Patch History API (pushState / replaceState / popstate) to capture\n * navigation breadcrumbs.\n */\nexport function installNavigationBreadcrumbs(add: AddFn): () => void {\n if (typeof window === 'undefined') return () => undefined;\n\n const originalPush = history.pushState.bind(history);\n const originalReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated to ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalPush(...args);\n };\n\n history.replaceState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Replaced state: ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalReplace(...args);\n };\n\n const onPopState = () => {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated back/forward to ${window.location.href}`,\n data: { to: window.location.href },\n });\n };\n\n window.addEventListener('popstate', onPopState);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n window.removeEventListener('popstate', onPopState);\n };\n}\n\n/**\n * Capture click events as breadcrumbs (element tag + text).\n */\nexport function installClickBreadcrumbs(add: AddFn): () => void {\n if (typeof document === 'undefined') return () => undefined;\n\n const handler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const tag = target.tagName?.toLowerCase() ?? 'unknown';\n const text = (target.textContent ?? '').trim().slice(0, 50);\n const id = target.id ? `#${target.id}` : '';\n const cls = target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').join('.')}`\n : '';\n add({\n timestamp: new Date().toISOString(),\n type: 'user',\n category: 'ui.click',\n message: `Click on <${tag}${id}${cls}>`,\n data: { tag, text: text || undefined },\n });\n };\n\n document.addEventListener('click', handler, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', handler, { capture: true });\n };\n}\n\n/**\n * Capture console.warn and console.error calls as breadcrumbs.\n */\nexport function installConsoleBreadcrumbs(add: AddFn): () => void {\n if (typeof console === 'undefined') return () => undefined;\n\n const originalWarn = console.warn.bind(console);\n const originalError = console.error.bind(console);\n\n const formatArgs = (args: unknown[]): string =>\n args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ').slice(0, 200);\n\n console.warn = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'warning' },\n });\n originalWarn(...args);\n };\n\n console.error = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'error' },\n });\n originalError(...args);\n };\n\n return () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n}\n","import type {\n BugCatchOptions,\n UserContext,\n BreadcrumbEntry,\n EventPayload,\n MetricPayload,\n ParsedDsn,\n ExceptionValue,\n} from './types.js';\nimport { parseStack } from './parse-stack.js';\nimport {\n BreadcrumbBuffer,\n installNavigationBreadcrumbs,\n installClickBreadcrumbs,\n installConsoleBreadcrumbs,\n} from './breadcrumbs.js';\n\n// ─── UUID ─────────────────────────────────────────────────────────────────────\n\nfunction uuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// ─── DSN parser ───────────────────────────────────────────────────────────────\n\nfunction parseDsn(dsn: string): ParsedDsn & { metricsUrl: string } {\n let url: URL;\n try {\n url = new URL(dsn);\n } catch {\n throw new Error(`[BugCatch] Invalid DSN: \"${dsn}\"`);\n }\n\n const sdkKey = url.searchParams.get('key');\n if (!sdkKey) {\n throw new Error(`[BugCatch] DSN is missing the \"key\" query parameter: \"${dsn}\"`);\n }\n\n // Extract projectId from the last path segment (/ingest/{projectId})\n const segments = url.pathname.split('/').filter(Boolean);\n const projectId = segments[segments.length - 1];\n if (!projectId) {\n throw new Error(`[BugCatch] Could not extract projectId from DSN path: \"${dsn}\"`);\n }\n\n // Reconstruct the URL without extra query params\n const ingestUrl = `${url.origin}${url.pathname}?key=${sdkKey}`;\n const metricsUrl = `${url.origin}${url.pathname}/metrics?key=${sdkKey}`;\n\n return { ingestUrl, metricsUrl, projectId, sdkKey };\n}\n\n// ─── Route normalizer ─────────────────────────────────────────────────────────\n\n/**\n * Strips the origin and query string from a URL and replaces dynamic path\n * segments (UUIDs, numeric IDs) with `:id` so metrics group by route template.\n *\n * e.g. https://api.example.com/users/42/orders/abc-123?page=1 → /users/:id/orders/:id\n */\nfunction normalizeUrl(rawUrl: string): string {\n let pathname: string;\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n // rawUrl is already a path (e.g. \"/api/users/1\")\n pathname = rawUrl.split('?')[0];\n }\n return pathname\n .replace(/\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')\n .replace(/\\/\\d{1,20}(?=\\/|$)/g, '/:id');\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────────\n\nfunction matchesPattern(value: string, patterns: Array<string | RegExp>): boolean {\n return patterns.some((p) =>\n typeof p === 'string' ? value.includes(p) : p.test(value),\n );\n}\n\n// ─── Client ───────────────────────────────────────────────────────────────────\n\nexport class BugCatchClient {\n private readonly opts: Required<\n Pick<BugCatchOptions, 'debug' | 'maxBreadcrumbs' | 'autoCaptureErrors' | 'autoCaptureBreadcrumbs' | 'autoTrackRequests'>\n > & BugCatchOptions;\n\n private readonly dsn: ParsedDsn & { metricsUrl: string };\n private readonly crumbs: BreadcrumbBuffer;\n private user: UserContext = {};\n private tags: Record<string, string> = {};\n private readonly cleanups: Array<() => void> = [];\n\n constructor(options: BugCatchOptions) {\n this.opts = {\n debug: false,\n maxBreadcrumbs: 100,\n autoCaptureErrors: true,\n autoCaptureBreadcrumbs: true,\n autoTrackRequests: false,\n ...options,\n };\n\n this.dsn = parseDsn(options.dsn);\n this.crumbs = new BreadcrumbBuffer(this.opts.maxBreadcrumbs);\n\n if (this.opts.autoCaptureErrors) {\n this.installErrorHandlers();\n }\n\n if (this.opts.autoCaptureBreadcrumbs) {\n this.cleanups.push(installNavigationBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installClickBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installConsoleBreadcrumbs((c) => this.addBreadcrumb(c)));\n }\n\n if (this.opts.autoTrackRequests) {\n this.cleanups.push(this.installFetchInterceptor());\n }\n\n this.log('Initialized. Project:', this.dsn.projectId);\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────────\n\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n const event = this.buildExceptionPayload(error, extra);\n void this.send(event);\n return event.event_id;\n }\n\n captureMessage(message: string, level: string = 'info', extra?: Record<string, unknown>): string {\n const event = this.buildMessagePayload(message, level, extra);\n void this.send(event);\n return event.event_id;\n }\n\n setUser(user: UserContext): void {\n this.user = {\n ...user,\n id: user.id != null ? String(user.id) : undefined,\n };\n }\n\n clearUser(): void {\n this.user = {};\n }\n\n setTag(key: string, value: string): void {\n this.tags[key] = value;\n }\n\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n this.crumbs.add(crumb);\n }\n\n /** Tear down all global listeners. Call when unmounting in SPAs. */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups.length = 0;\n }\n\n /**\n * Manually report an API call timing. Use this when `autoTrackRequests`\n * is off or when you want to track server-side (Node.js) requests explicitly.\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n void this.sendMetric({ method: method.toUpperCase(), route, duration_ms: durationMs, status_code: statusCode });\n }\n\n // ─── Internal: build payloads ────────────────────────────────────────────\n\n private buildExceptionPayload(\n error: unknown,\n extra?: Record<string, unknown>,\n ): EventPayload {\n const err = error instanceof Error ? error : new Error(String(error));\n const frames = parseStack(err);\n\n const exceptionValue: ExceptionValue = {\n type: err.name || 'Error',\n value: err.message,\n stacktrace: frames.length > 0 ? { frames } : undefined,\n };\n\n return this.buildBase({\n level: 'error',\n exception: { values: [exceptionValue] },\n extra,\n });\n }\n\n private buildMessagePayload(\n message: string,\n level: string,\n extra?: Record<string, unknown>,\n ): EventPayload {\n return this.buildBase({ level, message, extra });\n }\n\n private buildBase(\n overrides: Partial<EventPayload> & { extra?: Record<string, unknown> },\n ): EventPayload {\n const { extra, ...rest } = overrides;\n const payload: EventPayload = {\n event_id: uuid(),\n timestamp: new Date().toISOString(),\n platform: 'javascript',\n ...rest,\n };\n\n if (this.opts.release) payload.release = this.opts.release;\n if (this.opts.environment) payload.environment = this.opts.environment;\n\n if (Object.keys(this.user).length > 0) {\n payload.user = { ...this.user };\n }\n\n if (Object.keys(this.tags).length > 0) {\n payload.tags = { ...this.tags };\n }\n\n if (extra && Object.keys(extra).length > 0) {\n payload.extra = extra;\n }\n\n const breadcrumbs = this.crumbs.getAll();\n if (breadcrumbs.length > 0) {\n payload.breadcrumbs = breadcrumbs;\n }\n\n // Capture browser request context\n if (typeof window !== 'undefined') {\n payload.request = {\n url: window.location.href,\n headers: {\n 'user-agent': navigator.userAgent,\n },\n };\n }\n\n return payload;\n }\n\n // ─── Internal: error handlers ────────────────────────────────────────────\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') {\n // Node.js environment\n const onUncaught = (err: Error) => {\n this.captureException(err, { handler: 'uncaughtException' });\n };\n const onUnhandled = (reason: unknown) => {\n this.captureException(reason, { handler: 'unhandledRejection' });\n };\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onUnhandled);\n this.cleanups.push(() => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onUnhandled);\n });\n return;\n }\n\n // Browser environment\n const onError = (event: ErrorEvent) => {\n if (!event.error) return;\n if (this.shouldIgnore(event.error, event.filename ?? '')) return;\n this.captureException(event.error, { handler: 'window.onerror' });\n };\n\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason as unknown;\n if (this.shouldIgnore(reason, '')) return;\n this.captureException(reason, { handler: 'unhandledrejection' });\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n this.cleanups.push(() => {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n });\n }\n\n private shouldIgnore(error: unknown, scriptUrl: string): boolean {\n const { ignoreUrls, ignoreErrors } = this.opts;\n\n if (ignoreUrls?.length && scriptUrl) {\n if (matchesPattern(scriptUrl, ignoreUrls)) return true;\n }\n\n if (ignoreErrors?.length) {\n const message = error instanceof Error ? error.message : String(error);\n if (matchesPattern(message, ignoreErrors)) return true;\n }\n\n return false;\n }\n\n // ─── Internal: request tracking ──────────────────────────────────────────\n\n private installFetchInterceptor(): () => void {\n const original = globalThis.fetch.bind(globalThis);\n const self = this;\n\n globalThis.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url = input instanceof Request ? input.url : String(input);\n\n // Never intercept BugCatch's own ingest/metrics requests\n if (url.includes(self.dsn.ingestUrl.split('?')[0])) {\n return original(input, init);\n }\n\n if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {\n return original(input, init);\n }\n\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const route = normalizeUrl(url);\n const start = Date.now();\n\n try {\n const response = await original(input, init);\n void self.sendMetric({\n method,\n route,\n duration_ms: Date.now() - start,\n status_code: response.status,\n user_id: self.user.id,\n });\n return response;\n } catch (err) {\n // Network error — report as status 0\n void self.sendMetric({ method, route, duration_ms: Date.now() - start, status_code: 0 });\n throw err;\n }\n };\n\n // Return cleanup function that restores original fetch\n return () => {\n globalThis.fetch = original;\n };\n }\n\n private async sendMetric(metric: MetricPayload): Promise<void> {\n try {\n await fetch(this.dsn.metricsUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(metric),\n });\n } catch {\n // Silently ignore — metric loss is acceptable\n }\n }\n\n // ─── Internal: transport ─────────────────────────────────────────────────\n\n private async send(event: EventPayload): Promise<void> {\n let finalEvent: EventPayload | false = event;\n\n if (this.opts.beforeSend) {\n finalEvent = this.opts.beforeSend(event);\n if (finalEvent === false) {\n this.log('Event dropped by beforeSend hook');\n return;\n }\n }\n\n this.log('Sending event:', finalEvent.event_id, finalEvent.level);\n\n let body: string;\n try {\n body = JSON.stringify(finalEvent);\n } catch (err) {\n console.warn('[BugCatch] Failed to serialize event:', err);\n return;\n }\n\n try {\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n\n // keepalive is browser-only; Node.js fetch (undici) enforces a 64 KB body\n // limit with keepalive: true, which silently drops large payloads.\n if (typeof window !== 'undefined') {\n fetchOptions.keepalive = true;\n }\n\n const res = await fetch(this.dsn.ingestUrl, fetchOptions);\n\n if (!res.ok) {\n console.warn(`[BugCatch] Ingest responded with ${res.status}:`, await res.text());\n }\n } catch (err) {\n console.warn('[BugCatch] Failed to send event:', err);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.opts.debug) {\n console.debug('[BugCatch]', ...args);\n }\n }\n}\n","import { BugCatchClient } from './client.js';\nimport type { BugCatchOptions, UserContext, BreadcrumbEntry } from './types.js';\n\nexport type { BugCatchOptions, UserContext, BreadcrumbEntry };\nexport type { EventPayload, StackFrame, ParsedDsn } from './types.js';\nexport { BugCatchClient };\n\n// ─── Singleton instance ───────────────────────────────────────────────────────\n\nlet _client: BugCatchClient | null = null;\n\nfunction getClient(): BugCatchClient {\n if (!_client) {\n throw new Error('[BugCatch] SDK not initialized. Call BugCatch.init(options) first.');\n }\n return _client;\n}\n\n// ─── Public singleton API ─────────────────────────────────────────────────────\n\nconst BugCatch = {\n /**\n * Initialize the SDK. Call this once, as early as possible in your app.\n *\n * @example\n * BugCatch.init({\n * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',\n * release: '1.0.0',\n * environment: 'production',\n * });\n */\n init(options: BugCatchOptions): BugCatchClient {\n if (_client) {\n console.warn('[BugCatch] init() called more than once. Ignoring.');\n return _client;\n }\n _client = new BugCatchClient(options);\n return _client;\n },\n\n /**\n * Capture an Error object or any value as an error event.\n * Returns the generated event_id.\n */\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n return getClient().captureException(error, extra);\n },\n\n /**\n * Capture a plain text message as an event.\n * Returns the generated event_id.\n */\n captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string {\n return getClient().captureMessage(message, level, extra);\n },\n\n /**\n * Set the current user context. Attached to all subsequent events.\n */\n setUser(user: UserContext): void {\n getClient().setUser(user);\n },\n\n /**\n * Clear the current user context (e.g. on logout).\n */\n clearUser(): void {\n getClient().clearUser();\n },\n\n /**\n * Set a tag that will be attached to all subsequent events.\n */\n setTag(key: string, value: string): void {\n getClient().setTag(key, value);\n },\n\n /**\n * Manually add a breadcrumb.\n */\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n getClient().addBreadcrumb(crumb);\n },\n\n /**\n * Manually report an API call timing to BugCatch.\n * Use when `autoTrackRequests` is off or for server-side tracking.\n *\n * @example\n * const start = Date.now();\n * await fetch('/api/orders');\n * BugCatch.trackRequest('GET', '/api/orders', Date.now() - start, 200);\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n getClient().trackRequest(method, route, durationMs, statusCode);\n },\n\n /**\n * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.\n */\n destroy(): void {\n _client?.destroy();\n _client = null;\n },\n};\n\n// Named export for CJS consumers: const { BugCatch } = require('bugcatch-sdk')\nexport { BugCatch };\n\n// Default export for ESM consumers: import BugCatch from 'bugcatch-sdk'\nexport default BugCatch;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/parse-stack.ts","../src/breadcrumbs.ts","../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { StackFrame } from './types.js';\n\n// Chrome/V8: \" at functionName (filename:line:col)\"\n// \" at filename:line:col\"\nconst CHROME_RE = /^\\s*at (?:(.*?) \\()?(.+?):(\\d+):(\\d+)\\)?$/;\n\n// Firefox/Safari: \"functionName@filename:line:col\"\n// \"@filename:line:col\"\nconst FIREFOX_RE = /^(?:(.+?)@)?(.+?):(\\d+):(\\d+)$/;\n\n// Origins that are not \"in-app\" frames\nconst INTERNAL_PATTERNS = [/node_modules\\//, /bugcatch[-_]?sdk/, /^\\(native\\)$/, /^native code/];\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n return !INTERNAL_PATTERNS.some((p) => p.test(filename));\n}\n\nfunction parseChromeLine(line: string): StackFrame | null {\n const m = CHROME_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nfunction parseFirefoxLine(line: string): StackFrame | null {\n const m = FIREFOX_RE.exec(line);\n if (!m) return null;\n const [, fn, filename, lineno, colno] = m;\n return {\n function: fn ?? '<anonymous>',\n filename: filename ?? undefined,\n lineno: lineno ? parseInt(lineno, 10) : undefined,\n colno: colno ? parseInt(colno, 10) : undefined,\n in_app: isInApp(filename ?? undefined),\n };\n}\n\nexport function parseStack(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const lines = stack.split('\\n');\n const frames: StackFrame[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('Error') || trimmed.startsWith(error.message ?? '')) {\n continue;\n }\n const frame = parseChromeLine(trimmed) ?? parseFirefoxLine(trimmed);\n if (frame) {\n frames.push(frame);\n }\n }\n\n // The API fingerprinting uses the LAST in-app frame, which maps to innermost\n // call. Return in innermost-first order (as captured).\n return frames;\n}\n","import type { BreadcrumbEntry } from './types.js';\n\nexport class BreadcrumbBuffer {\n private readonly buffer: BreadcrumbEntry[] = [];\n private readonly max: number;\n\n constructor(max = 100) {\n this.max = max;\n }\n\n add(crumb: BreadcrumbEntry): void {\n if (this.buffer.length >= this.max) {\n this.buffer.shift();\n }\n this.buffer.push(crumb);\n }\n\n getAll(): BreadcrumbEntry[] {\n return [...this.buffer];\n }\n\n clear(): void {\n this.buffer.length = 0;\n }\n}\n\n// ─── Auto-capture helpers ─────────────────────────────────────────────────────\n\ntype AddFn = (crumb: BreadcrumbEntry) => void;\n\n/**\n * Patch History API (pushState / replaceState / popstate) to capture\n * navigation breadcrumbs.\n */\nexport function installNavigationBreadcrumbs(add: AddFn): () => void {\n if (typeof window === 'undefined') return () => undefined;\n\n const originalPush = history.pushState.bind(history);\n const originalReplace = history.replaceState.bind(history);\n\n history.pushState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated to ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalPush(...args);\n };\n\n history.replaceState = function (...args) {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Replaced state: ${String(args[2] ?? '')}`,\n data: { to: String(args[2] ?? '') },\n });\n return originalReplace(...args);\n };\n\n const onPopState = () => {\n add({\n timestamp: new Date().toISOString(),\n type: 'navigation',\n category: 'navigation',\n message: `Navigated back/forward to ${window.location.href}`,\n data: { to: window.location.href },\n });\n };\n\n window.addEventListener('popstate', onPopState);\n\n return () => {\n history.pushState = originalPush;\n history.replaceState = originalReplace;\n window.removeEventListener('popstate', onPopState);\n };\n}\n\n/**\n * Capture click events as breadcrumbs (element tag + text).\n */\nexport function installClickBreadcrumbs(add: AddFn): () => void {\n if (typeof document === 'undefined') return () => undefined;\n\n const handler = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target) return;\n const tag = target.tagName?.toLowerCase() ?? 'unknown';\n const text = (target.textContent ?? '').trim().slice(0, 50);\n const id = target.id ? `#${target.id}` : '';\n const cls = target.className && typeof target.className === 'string'\n ? `.${target.className.split(' ').join('.')}`\n : '';\n add({\n timestamp: new Date().toISOString(),\n type: 'user',\n category: 'ui.click',\n message: `Click on <${tag}${id}${cls}>`,\n data: { tag, text: text || undefined },\n });\n };\n\n document.addEventListener('click', handler, { capture: true, passive: true });\n\n return () => {\n document.removeEventListener('click', handler, { capture: true });\n };\n}\n\n/**\n * Capture console.warn and console.error calls as breadcrumbs.\n */\nexport function installConsoleBreadcrumbs(add: AddFn): () => void {\n if (typeof console === 'undefined') return () => undefined;\n\n const originalWarn = console.warn.bind(console);\n const originalError = console.error.bind(console);\n\n const formatArgs = (args: unknown[]): string =>\n args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ').slice(0, 200);\n\n console.warn = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'warning' },\n });\n originalWarn(...args);\n };\n\n console.error = (...args: unknown[]) => {\n add({\n timestamp: new Date().toISOString(),\n type: 'console',\n category: 'console',\n message: formatArgs(args),\n data: { level: 'error' },\n });\n originalError(...args);\n };\n\n return () => {\n console.warn = originalWarn;\n console.error = originalError;\n };\n}\n","import type {\n BugCatchOptions,\n UserContext,\n BreadcrumbEntry,\n EventPayload,\n MetricPayload,\n ParsedDsn,\n ExceptionValue,\n} from './types.js';\nimport { parseStack } from './parse-stack.js';\nimport {\n BreadcrumbBuffer,\n installNavigationBreadcrumbs,\n installClickBreadcrumbs,\n installConsoleBreadcrumbs,\n} from './breadcrumbs.js';\n\n// ─── UUID ─────────────────────────────────────────────────────────────────────\n\nfunction uuid(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// ─── DSN parser ───────────────────────────────────────────────────────────────\n\nfunction parseDsn(dsn: string): ParsedDsn & { metricsUrl: string } {\n let url: URL;\n try {\n url = new URL(dsn);\n } catch {\n throw new Error(`[BugCatch] Invalid DSN: \"${dsn}\"`);\n }\n\n const sdkKey = url.searchParams.get('key');\n if (!sdkKey) {\n throw new Error(`[BugCatch] DSN is missing the \"key\" query parameter: \"${dsn}\"`);\n }\n\n // Extract projectId from the last path segment (/ingest/{projectId})\n const segments = url.pathname.split('/').filter(Boolean);\n const projectId = segments[segments.length - 1];\n if (!projectId) {\n throw new Error(`[BugCatch] Could not extract projectId from DSN path: \"${dsn}\"`);\n }\n\n // Reconstruct the URL without extra query params\n const ingestUrl = `${url.origin}${url.pathname}?key=${sdkKey}`;\n const metricsUrl = `${url.origin}${url.pathname}/metrics?key=${sdkKey}`;\n\n return { ingestUrl, metricsUrl, projectId, sdkKey };\n}\n\n// ─── Route normalizer ─────────────────────────────────────────────────────────\n\n/**\n * Strips the origin and query string from a URL and replaces dynamic path\n * segments (UUIDs, numeric IDs) with `:id` so metrics group by route template.\n *\n * e.g. https://api.example.com/users/42/orders/abc-123?page=1 → /users/:id/orders/:id\n */\nfunction normalizeUrl(rawUrl: string): string {\n let pathname: string;\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n // rawUrl is already a path (e.g. \"/api/users/1\")\n pathname = rawUrl.split('?')[0];\n }\n return pathname\n .replace(/\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')\n .replace(/\\/\\d{1,20}(?=\\/|$)/g, '/:id');\n}\n\n// ─── Pattern matching ─────────────────────────────────────────────────────────\n\nfunction matchesPattern(value: string, patterns: Array<string | RegExp>): boolean {\n return patterns.some((p) =>\n typeof p === 'string' ? value.includes(p) : p.test(value),\n );\n}\n\n// ─── Client ───────────────────────────────────────────────────────────────────\n\nexport class BugCatchClient {\n private readonly opts: Required<\n Pick<BugCatchOptions, 'debug' | 'maxBreadcrumbs' | 'autoCaptureErrors' | 'autoCaptureBreadcrumbs' | 'autoTrackRequests'>\n > & BugCatchOptions;\n\n private readonly dsn: ParsedDsn & { metricsUrl: string };\n private readonly crumbs: BreadcrumbBuffer;\n private user: UserContext = {};\n private tags: Record<string, string> = {};\n private readonly cleanups: Array<() => void> = [];\n\n constructor(options: BugCatchOptions) {\n this.opts = {\n debug: false,\n maxBreadcrumbs: 100,\n autoCaptureErrors: true,\n autoCaptureBreadcrumbs: true,\n autoTrackRequests: false,\n ...options,\n };\n\n this.dsn = parseDsn(options.dsn);\n this.crumbs = new BreadcrumbBuffer(this.opts.maxBreadcrumbs);\n\n if (this.opts.autoCaptureErrors) {\n this.installErrorHandlers();\n }\n\n if (this.opts.autoCaptureBreadcrumbs) {\n this.cleanups.push(installNavigationBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installClickBreadcrumbs((c) => this.addBreadcrumb(c)));\n this.cleanups.push(installConsoleBreadcrumbs((c) => this.addBreadcrumb(c)));\n }\n\n if (this.opts.autoTrackRequests) {\n this.cleanups.push(this.installFetchInterceptor());\n this.cleanups.push(this.installXhrInterceptor());\n }\n\n this.log('Initialized. Project:', this.dsn.projectId);\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────────\n\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n const event = this.buildExceptionPayload(error, extra);\n void this.send(event);\n return event.event_id;\n }\n\n captureMessage(message: string, level: string = 'info', extra?: Record<string, unknown>): string {\n const event = this.buildMessagePayload(message, level, extra);\n void this.send(event);\n return event.event_id;\n }\n\n setUser(user: UserContext): void {\n this.user = {\n ...user,\n id: user.id != null ? String(user.id) : undefined,\n };\n }\n\n clearUser(): void {\n this.user = {};\n }\n\n setTag(key: string, value: string): void {\n this.tags[key] = value;\n }\n\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n this.crumbs.add(crumb);\n }\n\n /** Tear down all global listeners. Call when unmounting in SPAs. */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups.length = 0;\n }\n\n /**\n * Manually report an API call timing. Use this when `autoTrackRequests`\n * is off or when you want to track server-side (Node.js) requests explicitly.\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n void this.sendMetric({ method: method.toUpperCase(), route, duration_ms: durationMs, status_code: statusCode });\n }\n\n // ─── Internal: build payloads ────────────────────────────────────────────\n\n private buildExceptionPayload(\n error: unknown,\n extra?: Record<string, unknown>,\n ): EventPayload {\n const err = error instanceof Error ? error : new Error(String(error));\n const frames = parseStack(err);\n\n const exceptionValue: ExceptionValue = {\n type: err.name || 'Error',\n value: err.message,\n stacktrace: frames.length > 0 ? { frames } : undefined,\n };\n\n return this.buildBase({\n level: 'error',\n exception: { values: [exceptionValue] },\n extra,\n });\n }\n\n private buildMessagePayload(\n message: string,\n level: string,\n extra?: Record<string, unknown>,\n ): EventPayload {\n return this.buildBase({ level, message, extra });\n }\n\n private buildBase(\n overrides: Partial<EventPayload> & { extra?: Record<string, unknown> },\n ): EventPayload {\n const { extra, ...rest } = overrides;\n const payload: EventPayload = {\n event_id: uuid(),\n timestamp: new Date().toISOString(),\n platform: 'javascript',\n ...rest,\n };\n\n if (this.opts.release) payload.release = this.opts.release;\n if (this.opts.environment) payload.environment = this.opts.environment;\n\n if (Object.keys(this.user).length > 0) {\n payload.user = { ...this.user };\n }\n\n if (Object.keys(this.tags).length > 0) {\n payload.tags = { ...this.tags };\n }\n\n if (extra && Object.keys(extra).length > 0) {\n payload.extra = extra;\n }\n\n const breadcrumbs = this.crumbs.getAll();\n if (breadcrumbs.length > 0) {\n payload.breadcrumbs = breadcrumbs;\n }\n\n // Capture browser request context\n if (typeof window !== 'undefined') {\n payload.request = {\n url: window.location.href,\n headers: {\n 'user-agent': navigator.userAgent,\n },\n };\n }\n\n return payload;\n }\n\n // ─── Internal: error handlers ────────────────────────────────────────────\n\n private installErrorHandlers(): void {\n if (typeof window === 'undefined') {\n // Node.js environment\n const onUncaught = (err: Error) => {\n this.captureException(err, { handler: 'uncaughtException' });\n };\n const onUnhandled = (reason: unknown) => {\n this.captureException(reason, { handler: 'unhandledRejection' });\n };\n process.on('uncaughtException', onUncaught);\n process.on('unhandledRejection', onUnhandled);\n this.cleanups.push(() => {\n process.off('uncaughtException', onUncaught);\n process.off('unhandledRejection', onUnhandled);\n });\n return;\n }\n\n // Browser environment\n const onError = (event: ErrorEvent) => {\n if (!event.error) return;\n if (this.shouldIgnore(event.error, event.filename ?? '')) return;\n this.captureException(event.error, { handler: 'window.onerror' });\n };\n\n const onUnhandledRejection = (event: PromiseRejectionEvent) => {\n const reason = event.reason as unknown;\n if (this.shouldIgnore(reason, '')) return;\n this.captureException(reason, { handler: 'unhandledrejection' });\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onUnhandledRejection);\n\n this.cleanups.push(() => {\n window.removeEventListener('error', onError);\n window.removeEventListener('unhandledrejection', onUnhandledRejection);\n });\n }\n\n private shouldIgnore(error: unknown, scriptUrl: string): boolean {\n const { ignoreUrls, ignoreErrors } = this.opts;\n\n if (ignoreUrls?.length && scriptUrl) {\n if (matchesPattern(scriptUrl, ignoreUrls)) return true;\n }\n\n if (ignoreErrors?.length) {\n const message = error instanceof Error ? error.message : String(error);\n if (matchesPattern(message, ignoreErrors)) return true;\n }\n\n return false;\n }\n\n // ─── Internal: request tracking ──────────────────────────────────────────\n\n private installFetchInterceptor(): () => void {\n if (typeof globalThis.fetch !== 'function') {\n console.warn('[BugCatch] autoTrackRequests is enabled but globalThis.fetch is not available. Metrics will not be tracked.');\n return () => {};\n }\n\n const original = globalThis.fetch.bind(globalThis);\n const self = this;\n\n this.log('autoTrackRequests: fetch interceptor installed');\n\n globalThis.fetch = async function patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const url = input instanceof Request ? input.url : String(input);\n\n // Never intercept BugCatch's own ingest/metrics requests\n if (url.includes(self.dsn.ingestUrl.split('?')[0])) {\n return original(input, init);\n }\n\n if (self.opts.trackIgnoreUrls && matchesPattern(url, self.opts.trackIgnoreUrls)) {\n self.log('autoTrackRequests: ignored (trackIgnoreUrls match)', url);\n return original(input, init);\n }\n\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n const route = normalizeUrl(url);\n const start = Date.now();\n\n self.log('autoTrackRequests: intercepted', method, url);\n\n try {\n const response = await original(input, init);\n void self.sendMetric({\n method,\n route,\n duration_ms: Date.now() - start,\n status_code: response.status,\n user_id: self.user.id,\n });\n return response;\n } catch (err) {\n // Network error — report as status 0\n void self.sendMetric({ method, route, duration_ms: Date.now() - start, status_code: 0 });\n throw err;\n }\n };\n\n // Return cleanup function that restores original fetch\n return () => {\n globalThis.fetch = original;\n this.log('autoTrackRequests: fetch interceptor removed');\n };\n }\n\n private installXhrInterceptor(): () => void {\n if (typeof XMLHttpRequest === 'undefined') {\n // Node.js environment — XHR not available\n return () => {};\n }\n\n const self = this;\n const OriginalXHR = XMLHttpRequest;\n const ingestBase = this.dsn.ingestUrl.split('?')[0];\n\n function PatchedXHR(this: XMLHttpRequest) {\n const xhr = new OriginalXHR();\n\n let method = 'GET';\n let url = '';\n let start = 0;\n\n const originalOpen = xhr.open.bind(xhr);\n const originalSend = xhr.send.bind(xhr);\n\n (this as any).open = function (m: string, u: string, async?: boolean, user?: string, password?: string) {\n method = m ? m.toUpperCase() : 'GET';\n url = u || '';\n return originalOpen(m, u, async ?? true, user, password);\n };\n\n (this as any).send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n // Skip BugCatch's own requests and ignored URLs\n const skip =\n url.includes(ingestBase) ||\n (self.opts.trackIgnoreUrls ? matchesPattern(url, self.opts.trackIgnoreUrls) : false);\n\n if (!skip) {\n start = Date.now();\n self.log('autoTrackRequests: XHR intercepted', method, url);\n\n xhr.addEventListener('loadend', () => {\n void self.sendMetric({\n method,\n route: normalizeUrl(url),\n duration_ms: Date.now() - start,\n status_code: xhr.status || 0,\n user_id: self.user.id,\n });\n });\n }\n\n return originalSend(body);\n };\n\n // Proxy all other properties/methods to the real XHR instance\n return new Proxy(this, {\n get(_target, prop) {\n if (prop === 'open') return (this as any).open;\n if (prop === 'send') return (this as any).send;\n const val = (xhr as any)[prop];\n return typeof val === 'function' ? val.bind(xhr) : val;\n },\n set(_target, prop, value) {\n (xhr as any)[prop] = value;\n return true;\n },\n });\n }\n\n PatchedXHR.prototype = OriginalXHR.prototype;\n (window as any).XMLHttpRequest = PatchedXHR;\n\n this.log('autoTrackRequests: XHR interceptor installed');\n\n return () => {\n (window as any).XMLHttpRequest = OriginalXHR;\n this.log('autoTrackRequests: XHR interceptor removed');\n };\n }\n\n private async sendMetric(metric: MetricPayload): Promise<void> {\n this.log('autoTrackRequests: sending metric', metric.method, metric.route, metric.duration_ms + 'ms', metric.status_code);\n try {\n const res = await fetch(this.dsn.metricsUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(metric),\n });\n if (!res.ok) {\n this.log('autoTrackRequests: metric rejected by server —', res.status, await res.text().catch(() => ''));\n }\n } catch (err) {\n this.log('autoTrackRequests: failed to send metric —', (err as Error).message);\n }\n }\n\n // ─── Internal: transport ─────────────────────────────────────────────────\n\n private async send(event: EventPayload): Promise<void> {\n let finalEvent: EventPayload | false = event;\n\n if (this.opts.beforeSend) {\n finalEvent = this.opts.beforeSend(event);\n if (finalEvent === false) {\n this.log('Event dropped by beforeSend hook');\n return;\n }\n }\n\n this.log('Sending event:', finalEvent.event_id, finalEvent.level);\n\n let body: string;\n try {\n body = JSON.stringify(finalEvent);\n } catch (err) {\n console.warn('[BugCatch] Failed to serialize event:', err);\n return;\n }\n\n try {\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n };\n\n // keepalive is browser-only; Node.js fetch (undici) enforces a 64 KB body\n // limit with keepalive: true, which silently drops large payloads.\n if (typeof window !== 'undefined') {\n fetchOptions.keepalive = true;\n }\n\n const res = await fetch(this.dsn.ingestUrl, fetchOptions);\n\n if (!res.ok) {\n console.warn(`[BugCatch] Ingest responded with ${res.status}:`, await res.text());\n }\n } catch (err) {\n console.warn('[BugCatch] Failed to send event:', err);\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.opts.debug) {\n console.debug('[BugCatch]', ...args);\n }\n }\n}\n","import { BugCatchClient } from './client.js';\nimport type { BugCatchOptions, UserContext, BreadcrumbEntry } from './types.js';\n\nexport type { BugCatchOptions, UserContext, BreadcrumbEntry };\nexport type { EventPayload, StackFrame, ParsedDsn } from './types.js';\nexport { BugCatchClient };\n\n// ─── Singleton instance ───────────────────────────────────────────────────────\n\nlet _client: BugCatchClient | null = null;\n\nfunction getClient(): BugCatchClient {\n if (!_client) {\n throw new Error('[BugCatch] SDK not initialized. Call BugCatch.init(options) first.');\n }\n return _client;\n}\n\n// ─── Public singleton API ─────────────────────────────────────────────────────\n\nconst BugCatch = {\n /**\n * Initialize the SDK. Call this once, as early as possible in your app.\n *\n * @example\n * BugCatch.init({\n * dsn: 'http://localhost:3000/ingest/project-id?key=sdk-key',\n * release: '1.0.0',\n * environment: 'production',\n * });\n */\n init(options: BugCatchOptions): BugCatchClient {\n if (_client) {\n console.warn('[BugCatch] init() called more than once. Ignoring.');\n return _client;\n }\n _client = new BugCatchClient(options);\n return _client;\n },\n\n /**\n * Capture an Error object or any value as an error event.\n * Returns the generated event_id.\n */\n captureException(error: unknown, extra?: Record<string, unknown>): string {\n return getClient().captureException(error, extra);\n },\n\n /**\n * Capture a plain text message as an event.\n * Returns the generated event_id.\n */\n captureMessage(message: string, level?: string, extra?: Record<string, unknown>): string {\n return getClient().captureMessage(message, level, extra);\n },\n\n /**\n * Set the current user context. Attached to all subsequent events.\n */\n setUser(user: UserContext): void {\n getClient().setUser(user);\n },\n\n /**\n * Clear the current user context (e.g. on logout).\n */\n clearUser(): void {\n getClient().clearUser();\n },\n\n /**\n * Set a tag that will be attached to all subsequent events.\n */\n setTag(key: string, value: string): void {\n getClient().setTag(key, value);\n },\n\n /**\n * Manually add a breadcrumb.\n */\n addBreadcrumb(crumb: BreadcrumbEntry): void {\n getClient().addBreadcrumb(crumb);\n },\n\n /**\n * Manually report an API call timing to BugCatch.\n * Use when `autoTrackRequests` is off or for server-side tracking.\n *\n * @example\n * const start = Date.now();\n * await fetch('/api/orders');\n * BugCatch.trackRequest('GET', '/api/orders', Date.now() - start, 200);\n */\n trackRequest(method: string, route: string, durationMs: number, statusCode: number): void {\n getClient().trackRequest(method, route, durationMs, statusCode);\n },\n\n /**\n * Tear down all listeners. Useful in SPA cleanup or hot-reload scenarios.\n */\n destroy(): void {\n _client?.destroy();\n _client = null;\n },\n};\n\n// Named export for CJS consumers: const { BugCatch } = require('bugcatch-sdk')\nexport { BugCatch };\n\n// Default export for ESM consumers: import BugCatch from 'bugcatch-sdk'\nexport default BugCatch;\n"]}
|