@vybesec/sdk 0.1.0 → 0.1.1

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.cjs CHANGED
@@ -303,37 +303,49 @@ var VybeSecSDK = class {
303
303
  if (typeof window === "undefined" || !("XMLHttpRequest" in window)) return;
304
304
  const sdk = this;
305
305
  const proto = XMLHttpRequest.prototype;
306
- if (proto.__vwPatched) return;
307
- proto.__vwPatched = true;
306
+ if (proto.__vsPatched) return;
307
+ proto.__vsPatched = true;
308
308
  const originalOpen = proto.open;
309
309
  const originalSend = proto.send;
310
310
  proto.open = function(method, url, async, user, password) {
311
311
  const xhr = this;
312
- xhr.__vwMeta = { method, url: String(url) };
313
- return originalOpen.call(xhr, method, url, async ?? true, user ?? null, password ?? null);
312
+ xhr.__vsMeta = { method, url: String(url) };
313
+ return originalOpen.call(
314
+ xhr,
315
+ method,
316
+ url,
317
+ async ?? true,
318
+ user ?? null,
319
+ password ?? null
320
+ );
314
321
  };
315
322
  proto.send = function(body) {
316
323
  const xhr = this;
317
- const meta = xhr.__vwMeta;
324
+ const meta = xhr.__vsMeta;
318
325
  const handleComplete = () => {
319
- if (!sdk.config || !meta) return;
320
- const status = xhr.status;
321
- if (status >= 400 || status === 0) {
322
- sdk.captureEvent({
323
- type: "error",
324
- message: `XHR failed with ${status || "network error"}`,
325
- errorType: "HttpError",
326
- requestUrl: meta.url,
327
- requestMethod: meta.method,
328
- responseStatus: status || void 0,
329
- url: typeof window !== "undefined" ? window.location.href : void 0,
330
- timestamp: Date.now()
331
- });
326
+ try {
327
+ if (!sdk.config || !meta) return;
328
+ const status = xhr.status;
329
+ if (status >= 400 || status === 0) {
330
+ sdk.captureEvent({
331
+ type: "error",
332
+ message: `XHR failed with ${status || "network error"}`,
333
+ errorType: "HttpError",
334
+ requestUrl: meta.url,
335
+ requestMethod: meta.method,
336
+ responseStatus: status || void 0,
337
+ url: typeof window !== "undefined" ? window.location.href : void 0,
338
+ timestamp: Date.now()
339
+ });
340
+ }
341
+ } finally {
342
+ xhr.removeEventListener("loadend", handleComplete);
343
+ xhr.removeEventListener("error", handleComplete);
332
344
  }
333
345
  };
334
346
  xhr.addEventListener("loadend", handleComplete);
335
347
  xhr.addEventListener("error", handleComplete);
336
- return originalSend.call(xhr, body ?? null);
348
+ return originalSend.call(xhr, body);
337
349
  };
338
350
  }
339
351
  trackNavigation() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nexport type RawEvent = {\n type: \"error\" | \"warning\" | \"info\" | \"performance\" | \"custom\";\n message: string;\n stackTrace?: string;\n errorType?: string;\n url?: string;\n requestUrl?: string;\n requestMethod?: string;\n responseStatus?: number;\n sessionId?: string;\n userId?: string;\n timestamp: number;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vwPatched?: boolean;\n __vwMeta?: { method: string; url: string };\n };\n\n if (proto.__vwPatched) return;\n proto.__vwPatched = true;\n\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vwMeta = { method, url: String(url) };\n return originalOpen.call(xhr, method, url, async ?? true, user ?? null, password ?? null);\n };\n\n proto.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const xhr = this as typeof proto;\n const meta = xhr.__vwMeta;\n\n const handleComplete = () => {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n return originalSend.call(xhr, body ?? null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { RawEvent } from \"@vybesec/types\";\n\nexport type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vsPatched?: boolean;\n __vsMeta?: { method: string; url: string };\n };\n\n if (proto.__vsPatched) return;\n proto.__vsPatched = true;\n\n const originalOpen = proto.open;\n // narrow the send signature to match what we'll call\n const originalSend = proto.send as (\n this: XMLHttpRequest,\n body?: Document | XMLHttpRequestBodyInit | null\n ) => void;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vsMeta = { method, url: String(url) };\n return originalOpen.call(\n xhr,\n method,\n url,\n async ?? true,\n user ?? null,\n password ?? null\n );\n };\n\n // Accept any here and cast when calling the native send to avoid\n // TypeScript diagnostics around BodyInit / ReadableStream mismatch.\n proto.send = function (body?: any) {\n const xhr = this as typeof proto;\n const meta = xhr.__vsMeta;\n\n const handleComplete = () => {\n try {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } finally {\n // clean up listeners to avoid leaks / duplicate reporting\n xhr.removeEventListener(\"loadend\", handleComplete);\n xhr.removeEventListener(\"error\", handleComplete);\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n // Cast to the native expected type to satisfy the method signature.\n return originalSend.call(xhr, body as Document | XMLHttpRequestBodyInit | null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,3 +1,50 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const rawEventSchema: z.ZodObject<{
4
+ type: z.ZodEnum<["error", "warning", "info", "performance", "custom"]>;
5
+ message: z.ZodString;
6
+ stackTrace: z.ZodOptional<z.ZodString>;
7
+ errorType: z.ZodOptional<z.ZodString>;
8
+ url: z.ZodOptional<z.ZodString>;
9
+ requestUrl: z.ZodOptional<z.ZodString>;
10
+ requestMethod: z.ZodOptional<z.ZodString>;
11
+ responseStatus: z.ZodOptional<z.ZodNumber>;
12
+ sessionId: z.ZodOptional<z.ZodString>;
13
+ userId: z.ZodOptional<z.ZodString>;
14
+ timestamp: z.ZodNumber;
15
+ tags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
16
+ extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ type: "custom" | "error" | "warning" | "info" | "performance";
19
+ message: string;
20
+ timestamp: number;
21
+ stackTrace?: string | undefined;
22
+ errorType?: string | undefined;
23
+ url?: string | undefined;
24
+ requestUrl?: string | undefined;
25
+ requestMethod?: string | undefined;
26
+ responseStatus?: number | undefined;
27
+ sessionId?: string | undefined;
28
+ userId?: string | undefined;
29
+ tags?: Record<string, string> | undefined;
30
+ extra?: Record<string, any> | undefined;
31
+ }, {
32
+ type: "custom" | "error" | "warning" | "info" | "performance";
33
+ message: string;
34
+ timestamp: number;
35
+ stackTrace?: string | undefined;
36
+ errorType?: string | undefined;
37
+ url?: string | undefined;
38
+ requestUrl?: string | undefined;
39
+ requestMethod?: string | undefined;
40
+ responseStatus?: number | undefined;
41
+ sessionId?: string | undefined;
42
+ userId?: string | undefined;
43
+ tags?: Record<string, string> | undefined;
44
+ extra?: Record<string, any> | undefined;
45
+ }>;
46
+ type RawEvent = z.infer<typeof rawEventSchema>;
47
+
1
48
  type VybeSecConfig = {
2
49
  key: string;
3
50
  environment?: "production" | "staging" | "development";
@@ -9,21 +56,6 @@ type VybeSecConfig = {
9
56
  maxEventsPerMinute?: number;
10
57
  ingestUrl?: string;
11
58
  };
12
- type RawEvent = {
13
- type: "error" | "warning" | "info" | "performance" | "custom";
14
- message: string;
15
- stackTrace?: string;
16
- errorType?: string;
17
- url?: string;
18
- requestUrl?: string;
19
- requestMethod?: string;
20
- responseStatus?: number;
21
- sessionId?: string;
22
- userId?: string;
23
- timestamp: number;
24
- tags?: Record<string, string>;
25
- extra?: Record<string, unknown>;
26
- };
27
59
  declare class VybeSecSDK {
28
60
  private config;
29
61
  private buffer;
@@ -50,4 +82,4 @@ declare const init: (config: VybeSecConfig) => void;
50
82
  declare const captureError: (error: unknown) => void;
51
83
  declare const captureEvent: (event: RawEvent) => void;
52
84
 
53
- export { type RawEvent, type VybeSecConfig, VybeSecSDK, captureError, captureEvent, init, vybesec };
85
+ export { type VybeSecConfig, VybeSecSDK, captureError, captureEvent, init, vybesec };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,50 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const rawEventSchema: z.ZodObject<{
4
+ type: z.ZodEnum<["error", "warning", "info", "performance", "custom"]>;
5
+ message: z.ZodString;
6
+ stackTrace: z.ZodOptional<z.ZodString>;
7
+ errorType: z.ZodOptional<z.ZodString>;
8
+ url: z.ZodOptional<z.ZodString>;
9
+ requestUrl: z.ZodOptional<z.ZodString>;
10
+ requestMethod: z.ZodOptional<z.ZodString>;
11
+ responseStatus: z.ZodOptional<z.ZodNumber>;
12
+ sessionId: z.ZodOptional<z.ZodString>;
13
+ userId: z.ZodOptional<z.ZodString>;
14
+ timestamp: z.ZodNumber;
15
+ tags: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
16
+ extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ type: "custom" | "error" | "warning" | "info" | "performance";
19
+ message: string;
20
+ timestamp: number;
21
+ stackTrace?: string | undefined;
22
+ errorType?: string | undefined;
23
+ url?: string | undefined;
24
+ requestUrl?: string | undefined;
25
+ requestMethod?: string | undefined;
26
+ responseStatus?: number | undefined;
27
+ sessionId?: string | undefined;
28
+ userId?: string | undefined;
29
+ tags?: Record<string, string> | undefined;
30
+ extra?: Record<string, any> | undefined;
31
+ }, {
32
+ type: "custom" | "error" | "warning" | "info" | "performance";
33
+ message: string;
34
+ timestamp: number;
35
+ stackTrace?: string | undefined;
36
+ errorType?: string | undefined;
37
+ url?: string | undefined;
38
+ requestUrl?: string | undefined;
39
+ requestMethod?: string | undefined;
40
+ responseStatus?: number | undefined;
41
+ sessionId?: string | undefined;
42
+ userId?: string | undefined;
43
+ tags?: Record<string, string> | undefined;
44
+ extra?: Record<string, any> | undefined;
45
+ }>;
46
+ type RawEvent = z.infer<typeof rawEventSchema>;
47
+
1
48
  type VybeSecConfig = {
2
49
  key: string;
3
50
  environment?: "production" | "staging" | "development";
@@ -9,21 +56,6 @@ type VybeSecConfig = {
9
56
  maxEventsPerMinute?: number;
10
57
  ingestUrl?: string;
11
58
  };
12
- type RawEvent = {
13
- type: "error" | "warning" | "info" | "performance" | "custom";
14
- message: string;
15
- stackTrace?: string;
16
- errorType?: string;
17
- url?: string;
18
- requestUrl?: string;
19
- requestMethod?: string;
20
- responseStatus?: number;
21
- sessionId?: string;
22
- userId?: string;
23
- timestamp: number;
24
- tags?: Record<string, string>;
25
- extra?: Record<string, unknown>;
26
- };
27
59
  declare class VybeSecSDK {
28
60
  private config;
29
61
  private buffer;
@@ -50,4 +82,4 @@ declare const init: (config: VybeSecConfig) => void;
50
82
  declare const captureError: (error: unknown) => void;
51
83
  declare const captureEvent: (event: RawEvent) => void;
52
84
 
53
- export { type RawEvent, type VybeSecConfig, VybeSecSDK, captureError, captureEvent, init, vybesec };
85
+ export { type VybeSecConfig, VybeSecSDK, captureError, captureEvent, init, vybesec };
package/dist/index.js CHANGED
@@ -277,37 +277,49 @@ var VybeSecSDK = class {
277
277
  if (typeof window === "undefined" || !("XMLHttpRequest" in window)) return;
278
278
  const sdk = this;
279
279
  const proto = XMLHttpRequest.prototype;
280
- if (proto.__vwPatched) return;
281
- proto.__vwPatched = true;
280
+ if (proto.__vsPatched) return;
281
+ proto.__vsPatched = true;
282
282
  const originalOpen = proto.open;
283
283
  const originalSend = proto.send;
284
284
  proto.open = function(method, url, async, user, password) {
285
285
  const xhr = this;
286
- xhr.__vwMeta = { method, url: String(url) };
287
- return originalOpen.call(xhr, method, url, async ?? true, user ?? null, password ?? null);
286
+ xhr.__vsMeta = { method, url: String(url) };
287
+ return originalOpen.call(
288
+ xhr,
289
+ method,
290
+ url,
291
+ async ?? true,
292
+ user ?? null,
293
+ password ?? null
294
+ );
288
295
  };
289
296
  proto.send = function(body) {
290
297
  const xhr = this;
291
- const meta = xhr.__vwMeta;
298
+ const meta = xhr.__vsMeta;
292
299
  const handleComplete = () => {
293
- if (!sdk.config || !meta) return;
294
- const status = xhr.status;
295
- if (status >= 400 || status === 0) {
296
- sdk.captureEvent({
297
- type: "error",
298
- message: `XHR failed with ${status || "network error"}`,
299
- errorType: "HttpError",
300
- requestUrl: meta.url,
301
- requestMethod: meta.method,
302
- responseStatus: status || void 0,
303
- url: typeof window !== "undefined" ? window.location.href : void 0,
304
- timestamp: Date.now()
305
- });
300
+ try {
301
+ if (!sdk.config || !meta) return;
302
+ const status = xhr.status;
303
+ if (status >= 400 || status === 0) {
304
+ sdk.captureEvent({
305
+ type: "error",
306
+ message: `XHR failed with ${status || "network error"}`,
307
+ errorType: "HttpError",
308
+ requestUrl: meta.url,
309
+ requestMethod: meta.method,
310
+ responseStatus: status || void 0,
311
+ url: typeof window !== "undefined" ? window.location.href : void 0,
312
+ timestamp: Date.now()
313
+ });
314
+ }
315
+ } finally {
316
+ xhr.removeEventListener("loadend", handleComplete);
317
+ xhr.removeEventListener("error", handleComplete);
306
318
  }
307
319
  };
308
320
  xhr.addEventListener("loadend", handleComplete);
309
321
  xhr.addEventListener("error", handleComplete);
310
- return originalSend.call(xhr, body ?? null);
322
+ return originalSend.call(xhr, body);
311
323
  };
312
324
  }
313
325
  trackNavigation() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nexport type RawEvent = {\n type: \"error\" | \"warning\" | \"info\" | \"performance\" | \"custom\";\n message: string;\n stackTrace?: string;\n errorType?: string;\n url?: string;\n requestUrl?: string;\n requestMethod?: string;\n responseStatus?: number;\n sessionId?: string;\n userId?: string;\n timestamp: number;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vwPatched?: boolean;\n __vwMeta?: { method: string; url: string };\n };\n\n if (proto.__vwPatched) return;\n proto.__vwPatched = true;\n\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vwMeta = { method, url: String(url) };\n return originalOpen.call(xhr, method, url, async ?? true, user ?? null, password ?? null);\n };\n\n proto.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const xhr = this as typeof proto;\n const meta = xhr.__vwMeta;\n\n const handleComplete = () => {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n return originalSend.call(xhr, body ?? null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { RawEvent } from \"@vybesec/types\";\n\nexport type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vsPatched?: boolean;\n __vsMeta?: { method: string; url: string };\n };\n\n if (proto.__vsPatched) return;\n proto.__vsPatched = true;\n\n const originalOpen = proto.open;\n // narrow the send signature to match what we'll call\n const originalSend = proto.send as (\n this: XMLHttpRequest,\n body?: Document | XMLHttpRequestBodyInit | null\n ) => void;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vsMeta = { method, url: String(url) };\n return originalOpen.call(\n xhr,\n method,\n url,\n async ?? true,\n user ?? null,\n password ?? null\n );\n };\n\n // Accept any here and cast when calling the native send to avoid\n // TypeScript diagnostics around BodyInit / ReadableStream mismatch.\n proto.send = function (body?: any) {\n const xhr = this as typeof proto;\n const meta = xhr.__vsMeta;\n\n const handleComplete = () => {\n try {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } finally {\n // clean up listeners to avoid leaks / duplicate reporting\n xhr.removeEventListener(\"loadend\", handleComplete);\n xhr.removeEventListener(\"error\", handleComplete);\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n // Cast to the native expected type to satisfy the method signature.\n return originalSend.call(xhr, body as Document | XMLHttpRequestBodyInit | null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],"mappings":"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","names":[]}
package/dist/v1/sdk.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var VybeSec=(()=>{var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var n in e)p(t,n,{get:e[n],enumerable:!0})},R=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of E(e))!T.call(t,i)&&i!==n&&p(t,i,{get:()=>e[i],enumerable:!(r=v(e,i))||r.enumerable});return t};var k=t=>R(p({},"__esModule",{value:!0}),t);var L={};b(L,{VybeSecSDK:()=>h,captureError:()=>q,captureEvent:()=>D,init:()=>U,vybesec:()=>d});var S="https://vybesec-ingest.hexeldigitalstudio.workers.dev",m="vybesec_session_id";function w(){try{let t=window.localStorage.getItem(m);if(t)return t;let e=crypto.randomUUID();return window.localStorage.setItem(m,e),e}catch{return crypto.randomUUID()}}function x(t){if(t instanceof Error)return t.message||"Unknown error";if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return"Unknown error"}}function _(t){return t instanceof Error&&t.name?t.name:"Error"}function I(t){if(t instanceof Error)return t.stack}function l(t){if(!t)return t;let e=[/sk-[a-zA-Z0-9]{20,}/g,/pk_[a-zA-Z0-9]{20,}/g,/Bearer\s+[a-zA-Z0-9\-_.]{20,}/g,/password["']?\s*[:=]\s*["'][^"']+/gi],n=t;for(let r of e)n=n.replace(r,"[REDACTED]");return n}var M=/(password|token|secret|api[_-]?key|authorization)/i,A=3;function c(t,e=0){if(e>=A)return t;if(typeof t=="string")return l(t)??t;if(Array.isArray(t))return t.map(n=>c(n,e+1));if(t&&typeof t=="object"){let n=t,r={};for(let[i,s]of Object.entries(n)){if(M.test(i)){r[i]="[REDACTED]";continue}r[i]=c(s,e+1)}return r}return t}function y(t){return{...t,message:l(t.message)??t.message,stackTrace:l(t.stackTrace),tags:t.tags?c(t.tags):t.tags,extra:t.extra?c(t.extra):t.extra}}var h=class{config=null;buffer=[];eventTimestamps=[];flushTimer;retryTimer;retryAttempt=0;isFlushing=!1;init(e){this.config={...e,sampleRate:e.sampleRate??1,maxBuffer:e.maxBuffer??100,maxEventsPerMinute:e.maxEventsPerMinute??120,ingestUrl:e.ingestUrl??S},!(typeof window>"u")&&(window.addEventListener("error",n=>{this.captureError(n.error??n.message,{url:n.filename})}),window.addEventListener("unhandledrejection",n=>{this.captureError(n.reason)}),this.patchFetch(),this.patchXHR(),this.trackNavigation(),window.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flushBeacon()}),this.flushTimer&&window.clearInterval(this.flushTimer),this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=void 0),this.retryAttempt=0,this.flushTimer=window.setInterval(()=>this.flush(),5e3))}captureError(e,n){if(!this.config||!this.shouldAcceptEvent())return;let r=y({type:"error",message:x(e),stackTrace:I(e),errorType:_(e),url:typeof window<"u"?window.location.href:void 0,sessionId:typeof window<"u"?w():void 0,userId:this.config.userId,timestamp:Date.now(),tags:{...n??{},platform:this.config.platform??"other",environment:this.config.environment??"production",release:this.config.release??""}});this.pushEvent(r)}captureEvent(e){if(!this.config||!this.shouldAcceptEvent())return;let n=y({...e,sessionId:e.sessionId??(typeof window<"u"?w():void 0),userId:e.userId??this.config.userId,timestamp:e.timestamp??Date.now(),tags:{...e.tags??{},platform:this.config.platform??"other",environment:this.config.environment??"production",release:this.config.release??""}});this.pushEvent(n)}pushEvent(e){if(!this.config)return;let n=this.config.maxBuffer??100;if(!(n<=0)){for(;this.buffer.length>=n;)this.buffer.shift();this.buffer.push(e),this.buffer.length>=10&&this.flush()}}async flush(){if(!this.config||this.isFlushing||!this.buffer.length)return;this.isFlushing=!0;let e=this.buffer.splice(0);try{await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),keepalive:!0}),this.retryAttempt=0,this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=void 0)}catch{this.buffer.unshift(...e),this.scheduleRetry()}finally{this.isFlushing=!1}}flushBeacon(){if(!this.config||!this.buffer.length)return;let e=this.buffer.splice(0),n=new Blob([JSON.stringify(e)],{type:"application/json"});if(navigator.sendBeacon){navigator.sendBeacon(`${this.config.ingestUrl}/v1/events/${this.config.key}`,n);return}fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),keepalive:!0})}scheduleRetry(){if(typeof window>"u")return;let e=Math.min(3e4,1e3*2**this.retryAttempt);this.retryAttempt=Math.min(this.retryAttempt+1,5),this.retryTimer&&window.clearTimeout(this.retryTimer),this.retryTimer=window.setTimeout(()=>this.flush(),e)}shouldAcceptEvent(){return!(!this.config||Math.random()>(this.config.sampleRate??1)||!this.consumeRateLimit())}consumeRateLimit(){if(!this.config)return!1;let e=this.config.maxEventsPerMinute??120;if(e<=0)return!1;let n=Date.now(),r=n-6e4;return this.eventTimestamps=this.eventTimestamps.filter(i=>i>r),this.eventTimestamps.length>=e?!1:(this.eventTimestamps.push(n),!0)}patchFetch(){if(typeof window>"u"||!("fetch"in window))return;let e=window.fetch.bind(window);window.fetch=async(...n)=>{let r=await e(...n);try{let i=n[0],s=(i instanceof Request?i.method:n[1]?.method)??"GET",o=i instanceof Request?i.url:String(i);r.ok||this.captureEvent({type:"error",message:`Request failed with ${r.status}`,errorType:"HttpError",requestUrl:o,requestMethod:s,responseStatus:r.status,url:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()})}catch{}return r}}patchXHR(){if(typeof window>"u"||!("XMLHttpRequest"in window))return;let e=this,n=XMLHttpRequest.prototype;if(n.__vwPatched)return;n.__vwPatched=!0;let r=n.open,i=n.send;n.open=function(s,o,u,f,a){let g=this;return g.__vwMeta={method:s,url:String(o)},r.call(g,s,o,u??!0,f??null,a??null)},n.send=function(s){let o=this,u=o.__vwMeta,f=()=>{if(!e.config||!u)return;let a=o.status;(a>=400||a===0)&&e.captureEvent({type:"error",message:`XHR failed with ${a||"network error"}`,errorType:"HttpError",requestUrl:u.url,requestMethod:u.method,responseStatus:a||void 0,url:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()})};return o.addEventListener("loadend",f),o.addEventListener("error",f),i.call(o,s??null)}}trackNavigation(){if(typeof window>"u")return;let e=history.pushState,n=history.replaceState,r=()=>{this.captureEvent({type:"info",message:`Navigation to ${window.location.href}`,url:window.location.href,timestamp:Date.now()})};history.pushState=function(...i){let s=e.apply(this,i);return r(),s},history.replaceState=function(...i){let s=n.apply(this,i);return r(),s},window.addEventListener("popstate",r)}},d=new h,U=t=>d.init(t),q=t=>d.captureError(t),D=t=>d.captureEvent(t);return k(L);})();
1
+ "use strict";var VybeSec=(()=>{var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var n in e)p(t,n,{get:e[n],enumerable:!0})},R=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of E(e))!T.call(t,i)&&i!==n&&p(t,i,{get:()=>e[i],enumerable:!(r=v(e,i))||r.enumerable});return t};var k=t=>R(p({},"__esModule",{value:!0}),t);var q={};b(q,{VybeSecSDK:()=>h,captureError:()=>U,captureEvent:()=>D,init:()=>L,vybesec:()=>d});var S="https://vybesec-ingest.hexeldigitalstudio.workers.dev",g="vybesec_session_id";function w(){try{let t=window.localStorage.getItem(g);if(t)return t;let e=crypto.randomUUID();return window.localStorage.setItem(g,e),e}catch{return crypto.randomUUID()}}function x(t){if(t instanceof Error)return t.message||"Unknown error";if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return"Unknown error"}}function _(t){return t instanceof Error&&t.name?t.name:"Error"}function I(t){if(t instanceof Error)return t.stack}function l(t){if(!t)return t;let e=[/sk-[a-zA-Z0-9]{20,}/g,/pk_[a-zA-Z0-9]{20,}/g,/Bearer\s+[a-zA-Z0-9\-_.]{20,}/g,/password["']?\s*[:=]\s*["'][^"']+/gi],n=t;for(let r of e)n=n.replace(r,"[REDACTED]");return n}var M=/(password|token|secret|api[_-]?key|authorization)/i,A=3;function c(t,e=0){if(e>=A)return t;if(typeof t=="string")return l(t)??t;if(Array.isArray(t))return t.map(n=>c(n,e+1));if(t&&typeof t=="object"){let n=t,r={};for(let[i,s]of Object.entries(n)){if(M.test(i)){r[i]="[REDACTED]";continue}r[i]=c(s,e+1)}return r}return t}function y(t){return{...t,message:l(t.message)??t.message,stackTrace:l(t.stackTrace),tags:t.tags?c(t.tags):t.tags,extra:t.extra?c(t.extra):t.extra}}var h=class{config=null;buffer=[];eventTimestamps=[];flushTimer;retryTimer;retryAttempt=0;isFlushing=!1;init(e){this.config={...e,sampleRate:e.sampleRate??1,maxBuffer:e.maxBuffer??100,maxEventsPerMinute:e.maxEventsPerMinute??120,ingestUrl:e.ingestUrl??S},!(typeof window>"u")&&(window.addEventListener("error",n=>{this.captureError(n.error??n.message,{url:n.filename})}),window.addEventListener("unhandledrejection",n=>{this.captureError(n.reason)}),this.patchFetch(),this.patchXHR(),this.trackNavigation(),window.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flushBeacon()}),this.flushTimer&&window.clearInterval(this.flushTimer),this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=void 0),this.retryAttempt=0,this.flushTimer=window.setInterval(()=>this.flush(),5e3))}captureError(e,n){if(!this.config||!this.shouldAcceptEvent())return;let r=y({type:"error",message:x(e),stackTrace:I(e),errorType:_(e),url:typeof window<"u"?window.location.href:void 0,sessionId:typeof window<"u"?w():void 0,userId:this.config.userId,timestamp:Date.now(),tags:{...n??{},platform:this.config.platform??"other",environment:this.config.environment??"production",release:this.config.release??""}});this.pushEvent(r)}captureEvent(e){if(!this.config||!this.shouldAcceptEvent())return;let n=y({...e,sessionId:e.sessionId??(typeof window<"u"?w():void 0),userId:e.userId??this.config.userId,timestamp:e.timestamp??Date.now(),tags:{...e.tags??{},platform:this.config.platform??"other",environment:this.config.environment??"production",release:this.config.release??""}});this.pushEvent(n)}pushEvent(e){if(!this.config)return;let n=this.config.maxBuffer??100;if(!(n<=0)){for(;this.buffer.length>=n;)this.buffer.shift();this.buffer.push(e),this.buffer.length>=10&&this.flush()}}async flush(){if(!this.config||this.isFlushing||!this.buffer.length)return;this.isFlushing=!0;let e=this.buffer.splice(0);try{await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),keepalive:!0}),this.retryAttempt=0,this.retryTimer&&(window.clearTimeout(this.retryTimer),this.retryTimer=void 0)}catch{this.buffer.unshift(...e),this.scheduleRetry()}finally{this.isFlushing=!1}}flushBeacon(){if(!this.config||!this.buffer.length)return;let e=this.buffer.splice(0),n=new Blob([JSON.stringify(e)],{type:"application/json"});if(navigator.sendBeacon){navigator.sendBeacon(`${this.config.ingestUrl}/v1/events/${this.config.key}`,n);return}fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),keepalive:!0})}scheduleRetry(){if(typeof window>"u")return;let e=Math.min(3e4,1e3*2**this.retryAttempt);this.retryAttempt=Math.min(this.retryAttempt+1,5),this.retryTimer&&window.clearTimeout(this.retryTimer),this.retryTimer=window.setTimeout(()=>this.flush(),e)}shouldAcceptEvent(){return!(!this.config||Math.random()>(this.config.sampleRate??1)||!this.consumeRateLimit())}consumeRateLimit(){if(!this.config)return!1;let e=this.config.maxEventsPerMinute??120;if(e<=0)return!1;let n=Date.now(),r=n-6e4;return this.eventTimestamps=this.eventTimestamps.filter(i=>i>r),this.eventTimestamps.length>=e?!1:(this.eventTimestamps.push(n),!0)}patchFetch(){if(typeof window>"u"||!("fetch"in window))return;let e=window.fetch.bind(window);window.fetch=async(...n)=>{let r=await e(...n);try{let i=n[0],s=(i instanceof Request?i.method:n[1]?.method)??"GET",o=i instanceof Request?i.url:String(i);r.ok||this.captureEvent({type:"error",message:`Request failed with ${r.status}`,errorType:"HttpError",requestUrl:o,requestMethod:s,responseStatus:r.status,url:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()})}catch{}return r}}patchXHR(){if(typeof window>"u"||!("XMLHttpRequest"in window))return;let e=this,n=XMLHttpRequest.prototype;if(n.__vsPatched)return;n.__vsPatched=!0;let r=n.open,i=n.send;n.open=function(s,o,f,a,u){let m=this;return m.__vsMeta={method:s,url:String(o)},r.call(m,s,o,f??!0,a??null,u??null)},n.send=function(s){let o=this,f=o.__vsMeta,a=()=>{try{if(!e.config||!f)return;let u=o.status;(u>=400||u===0)&&e.captureEvent({type:"error",message:`XHR failed with ${u||"network error"}`,errorType:"HttpError",requestUrl:f.url,requestMethod:f.method,responseStatus:u||void 0,url:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()})}finally{o.removeEventListener("loadend",a),o.removeEventListener("error",a)}};return o.addEventListener("loadend",a),o.addEventListener("error",a),i.call(o,s)}}trackNavigation(){if(typeof window>"u")return;let e=history.pushState,n=history.replaceState,r=()=>{this.captureEvent({type:"info",message:`Navigation to ${window.location.href}`,url:window.location.href,timestamp:Date.now()})};history.pushState=function(...i){let s=e.apply(this,i);return r(),s},history.replaceState=function(...i){let s=n.apply(this,i);return r(),s},window.addEventListener("popstate",r)}},d=new h,L=t=>d.init(t),U=t=>d.captureError(t),D=t=>d.captureEvent(t);return k(q);})();
2
2
  //# sourceMappingURL=sdk.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nexport type RawEvent = {\n type: \"error\" | \"warning\" | \"info\" | \"performance\" | \"custom\";\n message: string;\n stackTrace?: string;\n errorType?: string;\n url?: string;\n requestUrl?: string;\n requestMethod?: string;\n responseStatus?: number;\n sessionId?: string;\n userId?: string;\n timestamp: number;\n tags?: Record<string, string>;\n extra?: Record<string, unknown>;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vwPatched?: boolean;\n __vwMeta?: { method: string; url: string };\n };\n\n if (proto.__vwPatched) return;\n proto.__vwPatched = true;\n\n const originalOpen = proto.open;\n const originalSend = proto.send;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vwMeta = { method, url: String(url) };\n return originalOpen.call(xhr, method, url, async ?? true, user ?? null, password ?? null);\n };\n\n proto.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const xhr = this as typeof proto;\n const meta = xhr.__vwMeta;\n\n const handleComplete = () => {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n return originalSend.call(xhr, body ?? null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { RawEvent } from \"@vybesec/types\";\n\nexport type VybeSecConfig = {\n key: string;\n environment?: \"production\" | \"staging\" | \"development\";\n platform?:\n | \"lovable\"\n | \"cursor\"\n | \"replit\"\n | \"v0\"\n | \"bolt\"\n | \"windsurf\"\n | \"other\";\n release?: string;\n userId?: string;\n sampleRate?: number;\n maxBuffer?: number;\n maxEventsPerMinute?: number;\n ingestUrl?: string;\n};\n\nconst DEFAULT_INGEST_URL = \"https://vybesec-ingest.hexeldigitalstudio.workers.dev\";\nconst SESSION_KEY = \"vybesec_session_id\";\n\nfunction getSessionId(): string {\n try {\n const existing = window.localStorage.getItem(SESSION_KEY);\n if (existing) return existing;\n const next = crypto.randomUUID();\n window.localStorage.setItem(SESSION_KEY, next);\n return next;\n } catch {\n return crypto.randomUUID();\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message || \"Unknown error\";\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error);\n } catch {\n return \"Unknown error\";\n }\n}\n\nfunction getErrorType(error: unknown): string {\n if (error instanceof Error && error.name) return error.name;\n return \"Error\";\n}\n\nfunction getStackTrace(error: unknown): string | undefined {\n if (error instanceof Error) return error.stack;\n return undefined;\n}\n\nfunction scrubSensitiveText(value?: string): string | undefined {\n if (!value) return value;\n const patterns = [\n /sk-[a-zA-Z0-9]{20,}/g,\n /pk_[a-zA-Z0-9]{20,}/g,\n /Bearer\\s+[a-zA-Z0-9\\-_.]{20,}/g,\n /password[\"']?\\s*[:=]\\s*[\"'][^\"']+/gi\n ];\n let output = value;\n for (const pattern of patterns) {\n output = output.replace(pattern, \"[REDACTED]\");\n }\n return output;\n}\n\nconst SENSITIVE_KEY = /(password|token|secret|api[_-]?key|authorization)/i;\nconst MAX_SCRUB_DEPTH = 3;\n\nfunction scrubValue(value: unknown, depth = 0): unknown {\n if (depth >= MAX_SCRUB_DEPTH) return value;\n if (typeof value === \"string\") return scrubSensitiveText(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => scrubValue(entry, depth + 1));\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const next: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (SENSITIVE_KEY.test(key)) {\n next[key] = \"[REDACTED]\";\n continue;\n }\n next[key] = scrubValue(entry, depth + 1);\n }\n return next;\n }\n return value;\n}\n\nfunction scrubEvent(event: RawEvent): RawEvent {\n return {\n ...event,\n message: scrubSensitiveText(event.message) ?? event.message,\n stackTrace: scrubSensitiveText(event.stackTrace),\n tags: event.tags ? (scrubValue(event.tags) as Record<string, string>) : event.tags,\n extra: event.extra ? (scrubValue(event.extra) as Record<string, unknown>) : event.extra\n };\n}\n\nexport class VybeSecSDK {\n private config: VybeSecConfig | null = null;\n private buffer: RawEvent[] = [];\n private eventTimestamps: number[] = [];\n private flushTimer?: number;\n private retryTimer?: number;\n private retryAttempt = 0;\n private isFlushing = false;\n\n init(config: VybeSecConfig) {\n this.config = {\n ...config,\n sampleRate: config.sampleRate ?? 1,\n maxBuffer: config.maxBuffer ?? 100,\n maxEventsPerMinute: config.maxEventsPerMinute ?? 120,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL\n };\n\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"error\", (event) => {\n this.captureError(event.error ?? event.message, {\n url: event.filename\n });\n });\n\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.captureError(event.reason);\n });\n\n this.patchFetch();\n this.patchXHR();\n this.trackNavigation();\n\n window.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"hidden\") {\n this.flushBeacon();\n }\n });\n\n if (this.flushTimer) {\n window.clearInterval(this.flushTimer);\n }\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.retryAttempt = 0;\n this.flushTimer = window.setInterval(() => this.flush(), 5000);\n }\n\n captureError(error: unknown, context?: Record<string, string>) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n\n const event: RawEvent = scrubEvent({\n type: \"error\",\n message: getErrorMessage(error),\n stackTrace: getStackTrace(error),\n errorType: getErrorType(error),\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n sessionId: typeof window !== \"undefined\" ? getSessionId() : undefined,\n userId: this.config.userId,\n timestamp: Date.now(),\n tags: {\n ...(context ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(event);\n }\n\n captureEvent(event: RawEvent) {\n if (!this.config) return;\n if (!this.shouldAcceptEvent()) return;\n const enriched: RawEvent = scrubEvent({\n ...event,\n sessionId: event.sessionId ?? (typeof window !== \"undefined\" ? getSessionId() : undefined),\n userId: event.userId ?? this.config.userId,\n timestamp: event.timestamp ?? Date.now(),\n tags: {\n ...(event.tags ?? {}),\n platform: this.config.platform ?? \"other\",\n environment: this.config.environment ?? \"production\",\n release: this.config.release ?? \"\"\n }\n });\n\n this.pushEvent(enriched);\n }\n\n private pushEvent(event: RawEvent) {\n if (!this.config) return;\n const maxBuffer = this.config.maxBuffer ?? 100;\n if (maxBuffer <= 0) return;\n while (this.buffer.length >= maxBuffer) {\n this.buffer.shift();\n }\n this.buffer.push(event);\n if (this.buffer.length >= 10) {\n void this.flush();\n }\n }\n\n private async flush() {\n if (!this.config || this.isFlushing) return;\n if (!this.buffer.length) return;\n\n this.isFlushing = true;\n const events = this.buffer.splice(0);\n\n try {\n await fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n this.retryAttempt = 0;\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n } catch {\n this.buffer.unshift(...events);\n this.scheduleRetry();\n } finally {\n this.isFlushing = false;\n }\n }\n\n private flushBeacon() {\n if (!this.config || !this.buffer.length) return;\n\n const events = this.buffer.splice(0);\n const payload = new Blob([JSON.stringify(events)], {\n type: \"application/json\"\n });\n\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n `${this.config.ingestUrl}/v1/events/${this.config.key}`,\n payload\n );\n return;\n }\n\n void fetch(`${this.config.ingestUrl}/v1/events/${this.config.key}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(events),\n keepalive: true\n });\n }\n\n private scheduleRetry() {\n if (typeof window === \"undefined\") return;\n const backoffMs = Math.min(30_000, 1000 * 2 ** this.retryAttempt);\n this.retryAttempt = Math.min(this.retryAttempt + 1, 5);\n if (this.retryTimer) {\n window.clearTimeout(this.retryTimer);\n }\n this.retryTimer = window.setTimeout(() => this.flush(), backoffMs);\n }\n\n private shouldAcceptEvent(): boolean {\n if (!this.config) return false;\n if (Math.random() > (this.config.sampleRate ?? 1)) return false;\n if (!this.consumeRateLimit()) return false;\n return true;\n }\n\n private consumeRateLimit(): boolean {\n if (!this.config) return false;\n const maxPerMinute = this.config.maxEventsPerMinute ?? 120;\n if (maxPerMinute <= 0) return false;\n\n const now = Date.now();\n const windowStart = now - 60_000;\n this.eventTimestamps = this.eventTimestamps.filter(\n (timestamp) => timestamp > windowStart\n );\n\n if (this.eventTimestamps.length >= maxPerMinute) {\n return false;\n }\n\n this.eventTimestamps.push(now);\n return true;\n }\n\n private patchFetch() {\n if (typeof window === \"undefined\" || !(\"fetch\" in window)) return;\n\n const originalFetch = window.fetch.bind(window);\n window.fetch = async (...args) => {\n const response = await originalFetch(...args);\n\n try {\n const request = args[0];\n const method =\n (request instanceof Request\n ? request.method\n : args[1]?.method) ?? \"GET\";\n const url = request instanceof Request ? request.url : String(request);\n\n if (!response.ok) {\n this.captureEvent({\n type: \"error\",\n message: `Request failed with ${response.status}`,\n errorType: \"HttpError\",\n requestUrl: url,\n requestMethod: method,\n responseStatus: response.status,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } catch {\n // ignore fetch instrumentation failures\n }\n\n return response;\n };\n }\n\n private patchXHR() {\n if (typeof window === \"undefined\" || !(\"XMLHttpRequest\" in window)) return;\n const sdk = this;\n const proto = XMLHttpRequest.prototype as XMLHttpRequest & {\n __vsPatched?: boolean;\n __vsMeta?: { method: string; url: string };\n };\n\n if (proto.__vsPatched) return;\n proto.__vsPatched = true;\n\n const originalOpen = proto.open;\n // narrow the send signature to match what we'll call\n const originalSend = proto.send as (\n this: XMLHttpRequest,\n body?: Document | XMLHttpRequestBodyInit | null\n ) => void;\n\n proto.open = function (\n method: string,\n url: string,\n async?: boolean,\n user?: string | null,\n password?: string | null\n ) {\n const xhr = this as typeof proto;\n xhr.__vsMeta = { method, url: String(url) };\n return originalOpen.call(\n xhr,\n method,\n url,\n async ?? true,\n user ?? null,\n password ?? null\n );\n };\n\n // Accept any here and cast when calling the native send to avoid\n // TypeScript diagnostics around BodyInit / ReadableStream mismatch.\n proto.send = function (body?: any) {\n const xhr = this as typeof proto;\n const meta = xhr.__vsMeta;\n\n const handleComplete = () => {\n try {\n if (!sdk.config || !meta) return;\n const status = xhr.status;\n if (status >= 400 || status === 0) {\n sdk.captureEvent({\n type: \"error\",\n message: `XHR failed with ${status || \"network error\"}`,\n errorType: \"HttpError\",\n requestUrl: meta.url,\n requestMethod: meta.method,\n responseStatus: status || undefined,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n timestamp: Date.now()\n });\n }\n } finally {\n // clean up listeners to avoid leaks / duplicate reporting\n xhr.removeEventListener(\"loadend\", handleComplete);\n xhr.removeEventListener(\"error\", handleComplete);\n }\n };\n\n xhr.addEventListener(\"loadend\", handleComplete);\n xhr.addEventListener(\"error\", handleComplete);\n\n // Cast to the native expected type to satisfy the method signature.\n return originalSend.call(xhr, body as Document | XMLHttpRequestBodyInit | null);\n };\n }\n\n private trackNavigation() {\n if (typeof window === \"undefined\") return;\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n\n const handleNavigation = () => {\n this.captureEvent({\n type: \"info\",\n message: `Navigation to ${window.location.href}`,\n url: window.location.href,\n timestamp: Date.now()\n });\n };\n\n history.pushState = function (...args) {\n const result = pushState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n history.replaceState = function (...args) {\n const result = replaceState.apply(this, args as never);\n handleNavigation();\n return result;\n };\n\n window.addEventListener(\"popstate\", handleNavigation);\n }\n}\n\nexport const vybesec = new VybeSecSDK();\nexport const init = (config: VybeSecConfig) => vybesec.init(config);\nexport const captureError = (error: unknown) => vybesec.captureError(error);\nexport const captureEvent = (event: RawEvent) => vybesec.captureEvent(event);\n"],
5
+ "mappings": "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",
6
6
  "names": ["index_exports", "__export", "VybeSecSDK", "captureError", "captureEvent", "init", "vybesec", "DEFAULT_INGEST_URL", "SESSION_KEY", "getSessionId", "existing", "next", "getErrorMessage", "error", "getErrorType", "getStackTrace", "scrubSensitiveText", "value", "patterns", "output", "pattern", "SENSITIVE_KEY", "MAX_SCRUB_DEPTH", "scrubValue", "depth", "entry", "record", "key", "scrubEvent", "event", "config", "context", "enriched", "maxBuffer", "events", "payload", "backoffMs", "maxPerMinute", "now", "windowStart", "timestamp", "originalFetch", "args", "response", "request", "method", "url", "sdk", "proto", "originalOpen", "originalSend", "async", "user", "password", "xhr", "body", "meta", "handleComplete", "status", "pushState", "replaceState", "handleNavigation", "result"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vybesec/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",