autotel-web 1.11.1 → 1.11.2
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.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { createTraceparent, parseTraceparent } from './chunk-L3S7LTIH.js';
|
|
1
|
+
import { createTraceparent, __publicField, parseTraceparent } from './chunk-L3S7LTIH.js';
|
|
2
2
|
export { createTraceparent, extractContext, generateSpanId, generateTraceId, getActiveContext, getTraceparent, parseTraceparent, trace } from './chunk-L3S7LTIH.js';
|
|
3
3
|
|
|
4
4
|
// src/privacy.ts
|
|
5
5
|
var PrivacyManager = class {
|
|
6
6
|
constructor(config2) {
|
|
7
|
-
this
|
|
7
|
+
__publicField(this, "config", config2);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Check if traceparent header should be injected for a given URL
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/privacy.ts","../src/span-exporter.ts","../src/init.ts"],"names":["config","privacyManager","init"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Privacy controls for autotel-web\n *\n * Provides origin filtering and privacy signal respecting (DNT, GPC)\n * to ensure compliance with GDPR, CCPA, and user privacy preferences.\n */\n\nexport interface PrivacyConfig {\n /**\n * Only inject traceparent headers on requests to these origins (whitelist)\n *\n * If specified, traceparent will ONLY be injected on matching origins.\n * Origins are matched using substring matching (e.g., \"example.com\" matches \"https://api.example.com\").\n *\n * @example\n * ```typescript\n * {\n * allowedOrigins: ['api.myapp.com', 'myapp.com']\n * }\n * ```\n */\n allowedOrigins?: string[];\n\n /**\n * Never inject traceparent headers on requests to these origins (blacklist)\n *\n * Takes precedence over allowedOrigins.\n * Origins are matched using substring matching.\n *\n * @example\n * ```typescript\n * {\n * blockedOrigins: ['analytics.google.com', 'facebook.com']\n * }\n * ```\n */\n blockedOrigins?: string[];\n\n /**\n * Respect the Do Not Track (DNT) browser setting\n *\n * If true and user has DNT enabled, no traceparent headers will be injected.\n *\n * @default false\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack\n */\n respectDoNotTrack?: boolean;\n\n /**\n * Respect the Global Privacy Control (GPC) browser signal\n *\n * If true and user has GPC enabled, no traceparent headers will be injected.\n *\n * @default false\n * @see https://globalprivacycontrol.org/\n */\n respectGPC?: boolean;\n}\n\n/**\n * Manages privacy controls for traceparent header injection\n *\n * Checks user privacy preferences (DNT, GPC) and origin filtering rules\n * to determine if traceparent headers should be injected on a given request.\n */\nexport class PrivacyManager {\n constructor(private readonly config: PrivacyConfig) {}\n\n /**\n * Check if traceparent header should be injected for a given URL\n *\n * Decision order:\n * 1. Check Do Not Track (if enabled)\n * 2. Check Global Privacy Control (if enabled)\n * 3. Check blockedOrigins (explicit deny)\n * 4. Check allowedOrigins (explicit allow, if configured)\n * 5. Default: allow\n *\n * @param url - Full URL or relative path of the request\n * @returns true if traceparent should be injected, false otherwise\n */\n shouldInjectTraceparent(url: string): boolean {\n // Check Do Not Track\n if (this.config.respectDoNotTrack && this.isDoNotTrackEnabled()) {\n return false;\n }\n\n // Check Global Privacy Control\n if (this.config.respectGPC && this.isGPCEnabled()) {\n return false;\n }\n\n // Get the origin of the target URL\n const targetOrigin = this.extractOrigin(url);\n\n // Check blocklist first (explicit deny takes precedence)\n if (\n this.config.blockedOrigins &&\n this.matchesAnyOrigin(targetOrigin, this.config.blockedOrigins)\n ) {\n return false;\n }\n\n // If allowlist exists, only allow those origins\n if (this.config.allowedOrigins && this.config.allowedOrigins.length > 0) {\n return this.matchesAnyOrigin(targetOrigin, this.config.allowedOrigins);\n }\n\n // Default: allow (backward compatible behavior)\n return true;\n }\n\n /**\n * Check if Do Not Track is enabled in the browser\n */\n private isDoNotTrackEnabled(): boolean {\n if (typeof navigator === 'undefined') return false;\n\n // DNT header can be \"1\" (enabled), \"0\" (disabled), or null (not set)\n return navigator.doNotTrack === '1';\n }\n\n /**\n * Check if Global Privacy Control is enabled in the browser\n */\n private isGPCEnabled(): boolean {\n if (typeof navigator === 'undefined') return false;\n\n // GPC is a newer spec, not all browsers support it yet\n // TypeScript doesn't have types for this yet, so we cast\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n return nav.globalPrivacyControl === true;\n }\n\n /**\n * Extract origin from a URL (handles both absolute and relative URLs)\n *\n * @param url - Full URL or relative path\n * @returns Origin string (e.g., \"https://api.example.com\")\n */\n private extractOrigin(url: string): string {\n try {\n // Handle absolute URLs\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return new URL(url).origin;\n }\n\n // Handle relative URLs - use current window location\n if (typeof window !== 'undefined') {\n return new URL(url, window.location.href).origin;\n }\n\n // Fallback for SSR or unknown cases\n return '';\n } catch {\n // Invalid URL - return empty string\n return '';\n }\n }\n\n /**\n * Check if a target origin matches any of the configured origins\n *\n * Uses substring matching for flexibility (e.g., \"example.com\" matches \"https://api.example.com\")\n *\n * @param targetOrigin - Origin to check\n * @param configuredOrigins - List of allowed or blocked origins\n * @returns true if any origin matches\n */\n private matchesAnyOrigin(\n targetOrigin: string,\n configuredOrigins: string[]\n ): boolean {\n return configuredOrigins.some((configuredOrigin) => {\n // Normalize both strings to lowercase for case-insensitive matching\n const normalizedTarget = targetOrigin.toLowerCase();\n const normalizedConfigured = configuredOrigin.toLowerCase();\n\n // Check if target origin contains the configured origin\n // This allows \"example.com\" to match \"https://api.example.com\"\n return normalizedTarget.includes(normalizedConfigured);\n });\n }\n}\n\n/**\n * Get reason why traceparent injection was denied (for debugging)\n *\n * Returns a human-readable reason if injection would be blocked,\n * or null if injection would be allowed.\n *\n * @param privacyManager - Configured PrivacyManager instance\n * @param url - URL to check\n * @returns Denial reason or null if allowed\n *\n * @example\n * ```typescript\n * const manager = new PrivacyManager({ respectDoNotTrack: true })\n * const reason = getDenialReason(manager, 'https://api.example.com')\n * if (reason) {\n * console.log('Traceparent blocked:', reason)\n * }\n * ```\n */\nexport function getDenialReason(\n privacyManager: PrivacyManager,\n url: string\n): string | null {\n // This is a helper for debugging - it re-checks the conditions\n // to provide a user-friendly reason string\n const config = (privacyManager as any).config as PrivacyConfig;\n\n // Check DNT\n if (config.respectDoNotTrack && typeof navigator !== 'undefined') {\n if (navigator.doNotTrack === '1') {\n return 'Do Not Track is enabled';\n }\n }\n\n // Check GPC\n if (config.respectGPC && typeof navigator !== 'undefined') {\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n if (nav.globalPrivacyControl === true) {\n return 'Global Privacy Control is enabled';\n }\n }\n\n // Extract origin\n let targetOrigin = '';\n try {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n targetOrigin = new URL(url).origin;\n } else if (typeof window !== 'undefined') {\n targetOrigin = new URL(url, window.location.href).origin;\n }\n } catch {\n return 'Invalid URL';\n }\n\n // Check blocklist\n if (config.blockedOrigins) {\n const blocked = config.blockedOrigins.some((origin) =>\n targetOrigin.toLowerCase().includes(origin.toLowerCase())\n );\n if (blocked) {\n return `Origin ${targetOrigin} is in blockedOrigins list`;\n }\n }\n\n // Check allowlist\n if (config.allowedOrigins && config.allowedOrigins.length > 0) {\n const allowed = config.allowedOrigins.some((origin) =>\n targetOrigin.toLowerCase().includes(origin.toLowerCase())\n );\n if (!allowed) {\n return `Origin ${targetOrigin} is not in allowedOrigins list`;\n }\n }\n\n return null;\n}\n","/**\n * Lightweight browser span exporter via sendBeacon/fetch.\n * Sends OTLP/JSON spans so the browser's traceparent spanId\n * exists as a real span in the collector.\n */\n\nlet debug = false;\nlet serviceName = 'browser';\nlet exportEndpoint: string | undefined;\nlet pendingSpans: unknown[] = [];\nlet flushTimer: ReturnType<typeof setTimeout> | undefined;\nlet rawFetch: typeof globalThis.fetch | undefined;\n\n/**\n * Provide the unpatched fetch so the exporter bypasses instrumentation.\n * Must be called before init() patches window.fetch.\n */\nexport function setRawFetch(fn: typeof globalThis.fetch): void {\n rawFetch = fn;\n}\n\nexport function configureExporter(service: string, endpoint: string, enableDebug = false): void {\n debug = enableDebug;\n serviceName = service;\n exportEndpoint = endpoint.replace(/\\/$/, '');\n if (!exportEndpoint.endsWith('/v1/traces')) {\n exportEndpoint += '/v1/traces';\n }\n if (!flushTimer) {\n flushTimer = setInterval(flushSpans, 2000);\n }\n}\n\nexport function recordSpan(\n traceId: string,\n spanId: string,\n name: string,\n startMs: number,\n endMs: number,\n attrs?: Record<string, string | number>,\n): void {\n if (!exportEndpoint) return;\n if (debug) console.log(`[autotel-web] recordSpan: ${name} (${traceId.slice(0, 8)}…)`);\n const attributes = attrs\n ? Object.entries(attrs).map(([key, value]) => ({\n key,\n value: typeof value === 'number' ? { intValue: String(value) } : { stringValue: value },\n }))\n : undefined;\n pendingSpans.push({\n traceId,\n spanId,\n name,\n kind: 3, // CLIENT\n startTimeUnixNano: String(Math.round(startMs * 1_000_000)),\n endTimeUnixNano: String(Math.round(endMs * 1_000_000)),\n attributes,\n });\n // Flush immediately — browser spans are infrequent\n flushSpans();\n}\n\nexport function flushSpans(): void {\n if (!exportEndpoint || pendingSpans.length === 0) return;\n if (debug) console.log(`[autotel-web] flushSpans: sending ${pendingSpans.length} span(s) to ${exportEndpoint}`);\n const spans = pendingSpans;\n pendingSpans = [];\n const payload = JSON.stringify({\n resourceSpans: [{\n resource: { attributes: [{ key: 'service.name', value: { stringValue: serviceName } }] },\n scopeSpans: [{ scope: { name: 'autotel-web' }, spans }],\n }],\n });\n const blob = new Blob([payload], { type: 'application/json' });\n const sent = typeof navigator?.sendBeacon === 'function' && navigator.sendBeacon(exportEndpoint, blob);\n if (!sent && rawFetch) {\n rawFetch(exportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: payload,\n keepalive: true,\n }).catch(() => {});\n }\n}\n\nexport function isConfigured(): boolean {\n return exportEndpoint !== undefined;\n}\n\nexport function resetForTesting(): void {\n exportEndpoint = undefined;\n pendingSpans = [];\n if (flushTimer) { clearInterval(flushTimer); flushTimer = undefined; }\n}\n","/**\n * Minimal browser SDK initialization\n *\n * Patches fetch() and XMLHttpRequest to automatically inject W3C traceparent headers.\n * NO OpenTelemetry dependencies - just native browser APIs.\n *\n * Bundle size: ~2-5KB gzipped\n */\n\nimport { createTraceparent, parseTraceparent } from './traceparent';\nimport { PrivacyManager, PrivacyConfig, getDenialReason } from './privacy';\nimport { configureExporter, setRawFetch, recordSpan, flushSpans, isConfigured, resetForTesting as resetExporter } from './span-exporter';\n\nexport interface AutotelWebConfig {\n /**\n * Service name for the browser application\n * Used only for logging/debugging - not sent in headers\n */\n service: string;\n\n /**\n * Enable debug logging to console\n * @default false\n */\n debug?: boolean;\n\n /**\n * Enable automatic traceparent injection on fetch calls\n * @default true\n */\n instrumentFetch?: boolean;\n\n /**\n * Enable automatic traceparent injection on XMLHttpRequest\n * @default true\n */\n instrumentXHR?: boolean;\n\n /**\n * OTLP endpoint for exporting browser spans.\n * When set, browser spans are sent via sendBeacon so the traceparent\n * spanId exists as a real span in the collector.\n * Use '' (empty string) for same-origin (requires /v1/traces proxy).\n */\n endpoint?: string;\n\n /**\n * Privacy controls for traceparent header injection\n *\n * Configure origin filtering and privacy signal respecting (DNT, GPC)\n * to ensure compliance with GDPR, CCPA, and user privacy preferences.\n *\n * @example Basic origin filtering\n * ```typescript\n * {\n * privacy: {\n * allowedOrigins: ['api.myapp.com'], // Only inject on API calls\n * respectDoNotTrack: true // Respect user's DNT setting\n * }\n * }\n * ```\n *\n * @example Block third-party analytics\n * ```typescript\n * {\n * privacy: {\n * blockedOrigins: ['analytics.google.com', 'facebook.com']\n * }\n * }\n * ```\n */\n privacy?: PrivacyConfig;\n}\n\nlet isInitialized = false;\nlet config: AutotelWebConfig | undefined;\nlet privacyManager: PrivacyManager | undefined;\nlet originalFetch: typeof window.fetch | undefined;\nlet originalXHROpen: typeof XMLHttpRequest.prototype.open | undefined;\nlet originalXHRSetRequestHeader: typeof XMLHttpRequest.prototype.setRequestHeader | undefined;\n\n/**\n * Initialize autotel-web\n *\n * Patches fetch() and XMLHttpRequest to auto-inject traceparent headers.\n *\n * **SSR-safe:** Safe to call in SSR environments (checks for window).\n * **Call once:** Subsequent calls are ignored.\n *\n * @example\n * ```typescript\n * import { init } from 'autotel-web'\n *\n * init({ service: 'my-frontend-app' })\n *\n * // Now all fetch/XHR calls include traceparent headers!\n * fetch('/api/users') // <-- traceparent header automatically injected\n * ```\n *\n * @example With React (client-only)\n * ```typescript\n * import { useEffect } from 'react'\n * import { init } from 'autotel-web'\n *\n * function App() {\n * useEffect(() => {\n * init({ service: 'my-spa' })\n * }, [])\n *\n * return <div>...</div>\n * }\n * ```\n */\nexport function init(userConfig: AutotelWebConfig): void {\n // SSR-safe: do nothing on the server\n if (typeof window === 'undefined') {\n return;\n }\n\n if (isInitialized) {\n if (userConfig.debug) {\n console.warn('[autotel-web] Already initialized. Skipping.');\n }\n return;\n }\n\n // Validate configuration\n validateConfig(userConfig);\n\n config = userConfig;\n\n // Initialize privacy manager if privacy config provided\n if (config.privacy) {\n privacyManager = new PrivacyManager(config.privacy);\n }\n\n // Capture unpatched fetch for the exporter before we patch it\n if (config.endpoint !== undefined) {\n setRawFetch(window.fetch.bind(window));\n configureExporter(config.service, config.endpoint, config.debug);\n }\n\n // Patch fetch\n if (config.instrumentFetch !== false) {\n patchFetch();\n }\n\n // Patch XHR\n if (config.instrumentXHR !== false) {\n patchXMLHttpRequest();\n }\n\n if (config.endpoint !== undefined) {\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') flushSpans();\n });\n }\n\n isInitialized = true;\n\n if (config.debug) {\n console.log('[autotel-web] Initialized successfully', {\n service: config.service,\n instrumentFetch: config.instrumentFetch !== false,\n instrumentXHR: config.instrumentXHR !== false,\n privacyEnabled: !!config.privacy,\n privacyConfig: config.privacy\n ? {\n allowedOrigins: config.privacy.allowedOrigins?.length ?? 0,\n blockedOrigins: config.privacy.blockedOrigins?.length ?? 0,\n respectDoNotTrack: config.privacy.respectDoNotTrack ?? false,\n respectGPC: config.privacy.respectGPC ?? false,\n }\n : null,\n });\n }\n}\n\n/**\n * Patch fetch() to auto-inject traceparent headers\n */\nfunction patchFetch(): void {\n // Always get the current window.fetch as the original\n // This allows tests to set up mocks before calling init()\n originalFetch = window.fetch.bind(window);\n\n window.fetch = function (\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n // Get URL string for logging and privacy checks\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n // Create headers object\n const headers = new Headers(init?.headers);\n\n // Only inject if traceparent doesn't already exist\n let injectedTraceparent: string | undefined;\n if (!headers.has('traceparent')) {\n // Check privacy controls\n if (privacyManager && !privacyManager.shouldInjectTraceparent(url)) {\n if (config?.debug) {\n const reason = getDenialReason(privacyManager, url);\n console.log(\n '[autotel-web] Skipped traceparent on fetch (privacy):',\n url,\n reason\n );\n }\n } else {\n injectedTraceparent = createTraceparent();\n headers.set('traceparent', injectedTraceparent);\n\n if (config?.debug) {\n console.log(\n '[autotel-web] Injected traceparent on fetch:',\n url,\n injectedTraceparent\n );\n }\n }\n }\n\n // Resolve HTTP method: prefer init override, then Request.method, then default GET\n const method = init?.method\n ?? (input instanceof Request ? input.method : undefined)\n ?? 'GET';\n\n // Call original fetch with updated headers\n const startTime = performance.timeOrigin + performance.now();\n const fetchPromise = originalFetch!(input, { ...init, headers });\n\n // Export browser span if exporter is configured\n if (injectedTraceparent && isConfigured()) {\n fetchPromise.then(\n (response) => {\n const endTime = performance.timeOrigin + performance.now();\n const parsed = parseTraceparent(injectedTraceparent!);\n if (parsed) {\n let pathname: string;\n try { pathname = new URL(url, window.location.origin).pathname; } catch { pathname = url; }\n recordSpan(parsed.traceId, parsed.spanId, `browser ${pathname}`, startTime, endTime, {\n 'http.method': method,\n 'http.url': url,\n 'http.status_code': response.status,\n });\n }\n },\n () => {\n const endTime = performance.timeOrigin + performance.now();\n const parsed = parseTraceparent(injectedTraceparent!);\n if (parsed) {\n let pathname: string;\n try { pathname = new URL(url, window.location.origin).pathname; } catch { pathname = url; }\n recordSpan(parsed.traceId, parsed.spanId, `browser ${pathname}`, startTime, endTime, {\n 'http.method': method,\n 'http.url': url,\n });\n }\n },\n );\n }\n\n return fetchPromise;\n };\n}\n\n/**\n * Patch XMLHttpRequest to auto-inject traceparent headers\n */\nfunction patchXMLHttpRequest(): void {\n // Always get the current prototypes as the originals\n // This allows tests to set up mocks before calling init()\n originalXHROpen = XMLHttpRequest.prototype.open;\n originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;\n\n // Track which XHR instances have traceparent set\n const xhrHasTraceparent = new WeakSet<XMLHttpRequest>();\n\n // Patch setRequestHeader to track manual traceparent headers\n XMLHttpRequest.prototype.setRequestHeader = function (\n name: string,\n value: string\n ): void {\n if (name.toLowerCase() === 'traceparent') {\n xhrHasTraceparent.add(this);\n }\n // originalXHRSetRequestHeader is always defined here because patchXMLHttpRequest() sets it before patching\n return originalXHRSetRequestHeader!.call(this, name, value);\n };\n\n // Patch open to inject traceparent after headers are ready\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async: boolean = true,\n username?: string | null,\n password?: string | null\n ): void {\n // Call original open\n // originalXHROpen is always defined here because patchXMLHttpRequest() sets it before patching\n const result = originalXHROpen!.call(this, method, url, async, username, password);\n\n // Convert URL to string for logging and privacy checks\n const urlStr = typeof url === 'string' ? url : url.toString();\n\n // Listen for readyState change to inject header at the right time\n const xhr = this;\n const originalOnReadyStateChange = xhr.onreadystatechange;\n\n xhr.onreadystatechange = function (event: Event) {\n // OPENED state (1) - headers can now be set\n if (xhr.readyState === XMLHttpRequest.OPENED) {\n // Only inject if not already set\n if (!xhrHasTraceparent.has(xhr)) {\n // Check privacy controls\n if (privacyManager && !privacyManager.shouldInjectTraceparent(urlStr)) {\n if (config?.debug) {\n const reason = getDenialReason(privacyManager, urlStr);\n console.log(\n '[autotel-web] Skipped traceparent on XHR (privacy):',\n urlStr,\n reason\n );\n }\n } else {\n // Inject traceparent header\n try {\n const traceparent = createTraceparent();\n // originalXHRSetRequestHeader is always defined here because patchXMLHttpRequest() sets it before patching\n originalXHRSetRequestHeader!.call(xhr, 'traceparent', traceparent);\n\n if (config?.debug) {\n console.log(\n '[autotel-web] Injected traceparent on XHR:',\n urlStr,\n traceparent\n );\n }\n } catch (error) {\n // Silently ignore if setRequestHeader fails\n if (config?.debug) {\n console.warn(\n '[autotel-web] Failed to inject traceparent on XHR:',\n error\n );\n }\n }\n }\n }\n }\n\n // Call original handler if it exists\n if (originalOnReadyStateChange) {\n return originalOnReadyStateChange.call(xhr, event);\n }\n };\n\n return result;\n };\n}\n\n/**\n * Validate configuration at initialization time\n * Catches common misconfigurations early\n */\nfunction validateConfig(userConfig: AutotelWebConfig): void {\n // Validate service name\n if (!userConfig.service || typeof userConfig.service !== 'string') {\n throw new Error('[autotel-web] service name is required and must be a string');\n }\n\n if (userConfig.service.length === 0) {\n throw new Error('[autotel-web] service name cannot be empty');\n }\n\n if (userConfig.service.length > 255) {\n console.warn(\n '[autotel-web] service name is very long (> 255 chars). Consider using a shorter name.'\n );\n }\n\n // Validate privacy config if provided\n if (userConfig.privacy) {\n const { allowedOrigins, blockedOrigins } = userConfig.privacy;\n\n // Warn if both allowlist and blocklist are empty\n if (\n (!allowedOrigins || allowedOrigins.length === 0) &&\n (!blockedOrigins || blockedOrigins.length === 0) &&\n !userConfig.privacy.respectDoNotTrack &&\n !userConfig.privacy.respectGPC\n ) {\n console.warn(\n '[autotel-web] privacy config provided but all options are empty/disabled. This has no effect.'\n );\n }\n\n // Warn about overlapping origins\n if (allowedOrigins && blockedOrigins) {\n const overlap = allowedOrigins.filter((allowed) =>\n blockedOrigins.some((blocked) =>\n allowed.toLowerCase().includes(blocked.toLowerCase())\n )\n );\n if (overlap.length > 0) {\n console.warn(\n '[autotel-web] Some allowedOrigins match blockedOrigins. Blocklist takes precedence:',\n overlap\n );\n }\n }\n\n // Validate origin format (warn if looks invalid)\n const allOrigins = [\n ...(allowedOrigins ?? []),\n ...(blockedOrigins ?? []),\n ];\n allOrigins.forEach((origin) => {\n if (origin.includes('://')) {\n console.warn(\n `[autotel-web] Origin \"${origin}\" includes protocol (://) - this is usually not needed. Just use the domain name.`\n );\n }\n });\n }\n}\n\n/**\n * Reset initialization state (for testing)\n * @internal\n */\nexport function resetForTesting(): void {\n isInitialized = false;\n config = undefined;\n privacyManager = undefined;\n resetExporter();\n\n // Restore original fetch/XHR if they were patched\n // Then clear the stored originals so next test can set up fresh mocks\n if (typeof window !== 'undefined') {\n if (originalFetch) {\n window.fetch = originalFetch;\n originalFetch = undefined;\n }\n if (originalXHROpen) {\n XMLHttpRequest.prototype.open = originalXHROpen;\n originalXHROpen = undefined;\n }\n if (originalXHRSetRequestHeader) {\n XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;\n originalXHRSetRequestHeader = undefined;\n }\n }\n}\n\n/**\n * Get current configuration\n * @internal\n */\nexport function getConfig(): AutotelWebConfig | undefined {\n return config;\n}\n\n/**\n * Get current privacy manager\n * @internal\n */\nexport function getPrivacyManager(): PrivacyManager | undefined {\n return privacyManager;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/privacy.ts","../src/span-exporter.ts","../src/init.ts"],"names":["config","privacyManager","init"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Privacy controls for autotel-web\n *\n * Provides origin filtering and privacy signal respecting (DNT, GPC)\n * to ensure compliance with GDPR, CCPA, and user privacy preferences.\n */\n\nexport interface PrivacyConfig {\n /**\n * Only inject traceparent headers on requests to these origins (whitelist)\n *\n * If specified, traceparent will ONLY be injected on matching origins.\n * Origins are matched using substring matching (e.g., \"example.com\" matches \"https://api.example.com\").\n *\n * @example\n * ```typescript\n * {\n * allowedOrigins: ['api.myapp.com', 'myapp.com']\n * }\n * ```\n */\n allowedOrigins?: string[];\n\n /**\n * Never inject traceparent headers on requests to these origins (blacklist)\n *\n * Takes precedence over allowedOrigins.\n * Origins are matched using substring matching.\n *\n * @example\n * ```typescript\n * {\n * blockedOrigins: ['analytics.google.com', 'facebook.com']\n * }\n * ```\n */\n blockedOrigins?: string[];\n\n /**\n * Respect the Do Not Track (DNT) browser setting\n *\n * If true and user has DNT enabled, no traceparent headers will be injected.\n *\n * @default false\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/doNotTrack\n */\n respectDoNotTrack?: boolean;\n\n /**\n * Respect the Global Privacy Control (GPC) browser signal\n *\n * If true and user has GPC enabled, no traceparent headers will be injected.\n *\n * @default false\n * @see https://globalprivacycontrol.org/\n */\n respectGPC?: boolean;\n}\n\n/**\n * Manages privacy controls for traceparent header injection\n *\n * Checks user privacy preferences (DNT, GPC) and origin filtering rules\n * to determine if traceparent headers should be injected on a given request.\n */\nexport class PrivacyManager {\n constructor(private readonly config: PrivacyConfig) {}\n\n /**\n * Check if traceparent header should be injected for a given URL\n *\n * Decision order:\n * 1. Check Do Not Track (if enabled)\n * 2. Check Global Privacy Control (if enabled)\n * 3. Check blockedOrigins (explicit deny)\n * 4. Check allowedOrigins (explicit allow, if configured)\n * 5. Default: allow\n *\n * @param url - Full URL or relative path of the request\n * @returns true if traceparent should be injected, false otherwise\n */\n shouldInjectTraceparent(url: string): boolean {\n // Check Do Not Track\n if (this.config.respectDoNotTrack && this.isDoNotTrackEnabled()) {\n return false;\n }\n\n // Check Global Privacy Control\n if (this.config.respectGPC && this.isGPCEnabled()) {\n return false;\n }\n\n // Get the origin of the target URL\n const targetOrigin = this.extractOrigin(url);\n\n // Check blocklist first (explicit deny takes precedence)\n if (\n this.config.blockedOrigins &&\n this.matchesAnyOrigin(targetOrigin, this.config.blockedOrigins)\n ) {\n return false;\n }\n\n // If allowlist exists, only allow those origins\n if (this.config.allowedOrigins && this.config.allowedOrigins.length > 0) {\n return this.matchesAnyOrigin(targetOrigin, this.config.allowedOrigins);\n }\n\n // Default: allow (backward compatible behavior)\n return true;\n }\n\n /**\n * Check if Do Not Track is enabled in the browser\n */\n private isDoNotTrackEnabled(): boolean {\n if (typeof navigator === 'undefined') return false;\n\n // DNT header can be \"1\" (enabled), \"0\" (disabled), or null (not set)\n return navigator.doNotTrack === '1';\n }\n\n /**\n * Check if Global Privacy Control is enabled in the browser\n */\n private isGPCEnabled(): boolean {\n if (typeof navigator === 'undefined') return false;\n\n // GPC is a newer spec, not all browsers support it yet\n // TypeScript doesn't have types for this yet, so we cast\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n return nav.globalPrivacyControl === true;\n }\n\n /**\n * Extract origin from a URL (handles both absolute and relative URLs)\n *\n * @param url - Full URL or relative path\n * @returns Origin string (e.g., \"https://api.example.com\")\n */\n private extractOrigin(url: string): string {\n try {\n // Handle absolute URLs\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return new URL(url).origin;\n }\n\n // Handle relative URLs - use current window location\n if (typeof window !== 'undefined') {\n return new URL(url, window.location.href).origin;\n }\n\n // Fallback for SSR or unknown cases\n return '';\n } catch {\n // Invalid URL - return empty string\n return '';\n }\n }\n\n /**\n * Check if a target origin matches any of the configured origins\n *\n * Uses substring matching for flexibility (e.g., \"example.com\" matches \"https://api.example.com\")\n *\n * @param targetOrigin - Origin to check\n * @param configuredOrigins - List of allowed or blocked origins\n * @returns true if any origin matches\n */\n private matchesAnyOrigin(\n targetOrigin: string,\n configuredOrigins: string[]\n ): boolean {\n return configuredOrigins.some((configuredOrigin) => {\n // Normalize both strings to lowercase for case-insensitive matching\n const normalizedTarget = targetOrigin.toLowerCase();\n const normalizedConfigured = configuredOrigin.toLowerCase();\n\n // Check if target origin contains the configured origin\n // This allows \"example.com\" to match \"https://api.example.com\"\n return normalizedTarget.includes(normalizedConfigured);\n });\n }\n}\n\n/**\n * Get reason why traceparent injection was denied (for debugging)\n *\n * Returns a human-readable reason if injection would be blocked,\n * or null if injection would be allowed.\n *\n * @param privacyManager - Configured PrivacyManager instance\n * @param url - URL to check\n * @returns Denial reason or null if allowed\n *\n * @example\n * ```typescript\n * const manager = new PrivacyManager({ respectDoNotTrack: true })\n * const reason = getDenialReason(manager, 'https://api.example.com')\n * if (reason) {\n * console.log('Traceparent blocked:', reason)\n * }\n * ```\n */\nexport function getDenialReason(\n privacyManager: PrivacyManager,\n url: string\n): string | null {\n // This is a helper for debugging - it re-checks the conditions\n // to provide a user-friendly reason string\n const config = (privacyManager as any).config as PrivacyConfig;\n\n // Check DNT\n if (config.respectDoNotTrack && typeof navigator !== 'undefined') {\n if (navigator.doNotTrack === '1') {\n return 'Do Not Track is enabled';\n }\n }\n\n // Check GPC\n if (config.respectGPC && typeof navigator !== 'undefined') {\n const nav = navigator as Navigator & { globalPrivacyControl?: boolean };\n if (nav.globalPrivacyControl === true) {\n return 'Global Privacy Control is enabled';\n }\n }\n\n // Extract origin\n let targetOrigin = '';\n try {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n targetOrigin = new URL(url).origin;\n } else if (typeof window !== 'undefined') {\n targetOrigin = new URL(url, window.location.href).origin;\n }\n } catch {\n return 'Invalid URL';\n }\n\n // Check blocklist\n if (config.blockedOrigins) {\n const blocked = config.blockedOrigins.some((origin) =>\n targetOrigin.toLowerCase().includes(origin.toLowerCase())\n );\n if (blocked) {\n return `Origin ${targetOrigin} is in blockedOrigins list`;\n }\n }\n\n // Check allowlist\n if (config.allowedOrigins && config.allowedOrigins.length > 0) {\n const allowed = config.allowedOrigins.some((origin) =>\n targetOrigin.toLowerCase().includes(origin.toLowerCase())\n );\n if (!allowed) {\n return `Origin ${targetOrigin} is not in allowedOrigins list`;\n }\n }\n\n return null;\n}\n","/**\n * Lightweight browser span exporter via sendBeacon/fetch.\n * Sends OTLP/JSON spans so the browser's traceparent spanId\n * exists as a real span in the collector.\n */\n\nlet debug = false;\nlet serviceName = 'browser';\nlet exportEndpoint: string | undefined;\nlet pendingSpans: unknown[] = [];\nlet flushTimer: ReturnType<typeof setTimeout> | undefined;\nlet rawFetch: typeof globalThis.fetch | undefined;\n\n/**\n * Provide the unpatched fetch so the exporter bypasses instrumentation.\n * Must be called before init() patches window.fetch.\n */\nexport function setRawFetch(fn: typeof globalThis.fetch): void {\n rawFetch = fn;\n}\n\nexport function configureExporter(service: string, endpoint: string, enableDebug = false): void {\n debug = enableDebug;\n serviceName = service;\n exportEndpoint = endpoint.replace(/\\/$/, '');\n if (!exportEndpoint.endsWith('/v1/traces')) {\n exportEndpoint += '/v1/traces';\n }\n if (!flushTimer) {\n flushTimer = setInterval(flushSpans, 2000);\n }\n}\n\nexport function recordSpan(\n traceId: string,\n spanId: string,\n name: string,\n startMs: number,\n endMs: number,\n attrs?: Record<string, string | number>,\n): void {\n if (!exportEndpoint) return;\n if (debug) console.log(`[autotel-web] recordSpan: ${name} (${traceId.slice(0, 8)}…)`);\n const attributes = attrs\n ? Object.entries(attrs).map(([key, value]) => ({\n key,\n value: typeof value === 'number' ? { intValue: String(value) } : { stringValue: value },\n }))\n : undefined;\n pendingSpans.push({\n traceId,\n spanId,\n name,\n kind: 3, // CLIENT\n startTimeUnixNano: String(Math.round(startMs * 1_000_000)),\n endTimeUnixNano: String(Math.round(endMs * 1_000_000)),\n attributes,\n });\n // Flush immediately — browser spans are infrequent\n flushSpans();\n}\n\nexport function flushSpans(): void {\n if (!exportEndpoint || pendingSpans.length === 0) return;\n if (debug) console.log(`[autotel-web] flushSpans: sending ${pendingSpans.length} span(s) to ${exportEndpoint}`);\n const spans = pendingSpans;\n pendingSpans = [];\n const payload = JSON.stringify({\n resourceSpans: [{\n resource: { attributes: [{ key: 'service.name', value: { stringValue: serviceName } }] },\n scopeSpans: [{ scope: { name: 'autotel-web' }, spans }],\n }],\n });\n const blob = new Blob([payload], { type: 'application/json' });\n const sent = typeof navigator?.sendBeacon === 'function' && navigator.sendBeacon(exportEndpoint, blob);\n if (!sent && rawFetch) {\n rawFetch(exportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: payload,\n keepalive: true,\n }).catch(() => {});\n }\n}\n\nexport function isConfigured(): boolean {\n return exportEndpoint !== undefined;\n}\n\nexport function resetForTesting(): void {\n exportEndpoint = undefined;\n pendingSpans = [];\n if (flushTimer) { clearInterval(flushTimer); flushTimer = undefined; }\n}\n","/**\n * Minimal browser SDK initialization\n *\n * Patches fetch() and XMLHttpRequest to automatically inject W3C traceparent headers.\n * NO OpenTelemetry dependencies - just native browser APIs.\n *\n * Bundle size: ~2-5KB gzipped\n */\n\nimport { createTraceparent, parseTraceparent } from './traceparent';\nimport { PrivacyManager, PrivacyConfig, getDenialReason } from './privacy';\nimport { configureExporter, setRawFetch, recordSpan, flushSpans, isConfigured, resetForTesting as resetExporter } from './span-exporter';\n\nexport interface AutotelWebConfig {\n /**\n * Service name for the browser application\n * Used only for logging/debugging - not sent in headers\n */\n service: string;\n\n /**\n * Enable debug logging to console\n * @default false\n */\n debug?: boolean;\n\n /**\n * Enable automatic traceparent injection on fetch calls\n * @default true\n */\n instrumentFetch?: boolean;\n\n /**\n * Enable automatic traceparent injection on XMLHttpRequest\n * @default true\n */\n instrumentXHR?: boolean;\n\n /**\n * OTLP endpoint for exporting browser spans.\n * When set, browser spans are sent via sendBeacon so the traceparent\n * spanId exists as a real span in the collector.\n * Use '' (empty string) for same-origin (requires /v1/traces proxy).\n */\n endpoint?: string;\n\n /**\n * Privacy controls for traceparent header injection\n *\n * Configure origin filtering and privacy signal respecting (DNT, GPC)\n * to ensure compliance with GDPR, CCPA, and user privacy preferences.\n *\n * @example Basic origin filtering\n * ```typescript\n * {\n * privacy: {\n * allowedOrigins: ['api.myapp.com'], // Only inject on API calls\n * respectDoNotTrack: true // Respect user's DNT setting\n * }\n * }\n * ```\n *\n * @example Block third-party analytics\n * ```typescript\n * {\n * privacy: {\n * blockedOrigins: ['analytics.google.com', 'facebook.com']\n * }\n * }\n * ```\n */\n privacy?: PrivacyConfig;\n}\n\nlet isInitialized = false;\nlet config: AutotelWebConfig | undefined;\nlet privacyManager: PrivacyManager | undefined;\nlet originalFetch: typeof window.fetch | undefined;\nlet originalXHROpen: typeof XMLHttpRequest.prototype.open | undefined;\nlet originalXHRSetRequestHeader: typeof XMLHttpRequest.prototype.setRequestHeader | undefined;\n\n/**\n * Initialize autotel-web\n *\n * Patches fetch() and XMLHttpRequest to auto-inject traceparent headers.\n *\n * **SSR-safe:** Safe to call in SSR environments (checks for window).\n * **Call once:** Subsequent calls are ignored.\n *\n * @example\n * ```typescript\n * import { init } from 'autotel-web'\n *\n * init({ service: 'my-frontend-app' })\n *\n * // Now all fetch/XHR calls include traceparent headers!\n * fetch('/api/users') // <-- traceparent header automatically injected\n * ```\n *\n * @example With React (client-only)\n * ```typescript\n * import { useEffect } from 'react'\n * import { init } from 'autotel-web'\n *\n * function App() {\n * useEffect(() => {\n * init({ service: 'my-spa' })\n * }, [])\n *\n * return <div>...</div>\n * }\n * ```\n */\nexport function init(userConfig: AutotelWebConfig): void {\n // SSR-safe: do nothing on the server\n if (typeof window === 'undefined') {\n return;\n }\n\n if (isInitialized) {\n if (userConfig.debug) {\n console.warn('[autotel-web] Already initialized. Skipping.');\n }\n return;\n }\n\n // Validate configuration\n validateConfig(userConfig);\n\n config = userConfig;\n\n // Initialize privacy manager if privacy config provided\n if (config.privacy) {\n privacyManager = new PrivacyManager(config.privacy);\n }\n\n // Capture unpatched fetch for the exporter before we patch it\n if (config.endpoint !== undefined) {\n setRawFetch(window.fetch.bind(window));\n configureExporter(config.service, config.endpoint, config.debug);\n }\n\n // Patch fetch\n if (config.instrumentFetch !== false) {\n patchFetch();\n }\n\n // Patch XHR\n if (config.instrumentXHR !== false) {\n patchXMLHttpRequest();\n }\n\n if (config.endpoint !== undefined) {\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') flushSpans();\n });\n }\n\n isInitialized = true;\n\n if (config.debug) {\n console.log('[autotel-web] Initialized successfully', {\n service: config.service,\n instrumentFetch: config.instrumentFetch !== false,\n instrumentXHR: config.instrumentXHR !== false,\n privacyEnabled: !!config.privacy,\n privacyConfig: config.privacy\n ? {\n allowedOrigins: config.privacy.allowedOrigins?.length ?? 0,\n blockedOrigins: config.privacy.blockedOrigins?.length ?? 0,\n respectDoNotTrack: config.privacy.respectDoNotTrack ?? false,\n respectGPC: config.privacy.respectGPC ?? false,\n }\n : null,\n });\n }\n}\n\n/**\n * Patch fetch() to auto-inject traceparent headers\n */\nfunction patchFetch(): void {\n // Always get the current window.fetch as the original\n // This allows tests to set up mocks before calling init()\n originalFetch = window.fetch.bind(window);\n\n window.fetch = function (\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n // Get URL string for logging and privacy checks\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n // Create headers object\n const headers = new Headers(init?.headers);\n\n // Only inject if traceparent doesn't already exist\n let injectedTraceparent: string | undefined;\n if (!headers.has('traceparent')) {\n // Check privacy controls\n if (privacyManager && !privacyManager.shouldInjectTraceparent(url)) {\n if (config?.debug) {\n const reason = getDenialReason(privacyManager, url);\n console.log(\n '[autotel-web] Skipped traceparent on fetch (privacy):',\n url,\n reason\n );\n }\n } else {\n injectedTraceparent = createTraceparent();\n headers.set('traceparent', injectedTraceparent);\n\n if (config?.debug) {\n console.log(\n '[autotel-web] Injected traceparent on fetch:',\n url,\n injectedTraceparent\n );\n }\n }\n }\n\n // Resolve HTTP method: prefer init override, then Request.method, then default GET\n const method = init?.method\n ?? (input instanceof Request ? input.method : undefined)\n ?? 'GET';\n\n // Call original fetch with updated headers\n const startTime = performance.timeOrigin + performance.now();\n const fetchPromise = originalFetch!(input, { ...init, headers });\n\n // Export browser span if exporter is configured\n if (injectedTraceparent && isConfigured()) {\n fetchPromise.then(\n (response) => {\n const endTime = performance.timeOrigin + performance.now();\n const parsed = parseTraceparent(injectedTraceparent!);\n if (parsed) {\n let pathname: string;\n try { pathname = new URL(url, window.location.origin).pathname; } catch { pathname = url; }\n recordSpan(parsed.traceId, parsed.spanId, `browser ${pathname}`, startTime, endTime, {\n 'http.method': method,\n 'http.url': url,\n 'http.status_code': response.status,\n });\n }\n },\n () => {\n const endTime = performance.timeOrigin + performance.now();\n const parsed = parseTraceparent(injectedTraceparent!);\n if (parsed) {\n let pathname: string;\n try { pathname = new URL(url, window.location.origin).pathname; } catch { pathname = url; }\n recordSpan(parsed.traceId, parsed.spanId, `browser ${pathname}`, startTime, endTime, {\n 'http.method': method,\n 'http.url': url,\n });\n }\n },\n );\n }\n\n return fetchPromise;\n };\n}\n\n/**\n * Patch XMLHttpRequest to auto-inject traceparent headers\n */\nfunction patchXMLHttpRequest(): void {\n // Always get the current prototypes as the originals\n // This allows tests to set up mocks before calling init()\n originalXHROpen = XMLHttpRequest.prototype.open;\n originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;\n\n // Track which XHR instances have traceparent set\n const xhrHasTraceparent = new WeakSet<XMLHttpRequest>();\n\n // Patch setRequestHeader to track manual traceparent headers\n XMLHttpRequest.prototype.setRequestHeader = function (\n name: string,\n value: string\n ): void {\n if (name.toLowerCase() === 'traceparent') {\n xhrHasTraceparent.add(this);\n }\n // originalXHRSetRequestHeader is always defined here because patchXMLHttpRequest() sets it before patching\n return originalXHRSetRequestHeader!.call(this, name, value);\n };\n\n // Patch open to inject traceparent after headers are ready\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async: boolean = true,\n username?: string | null,\n password?: string | null\n ): void {\n // Call original open\n // originalXHROpen is always defined here because patchXMLHttpRequest() sets it before patching\n const result = originalXHROpen!.call(this, method, url, async, username, password);\n\n // Convert URL to string for logging and privacy checks\n const urlStr = typeof url === 'string' ? url : url.toString();\n\n // Listen for readyState change to inject header at the right time\n const xhr = this;\n const originalOnReadyStateChange = xhr.onreadystatechange;\n\n xhr.onreadystatechange = function (event: Event) {\n // OPENED state (1) - headers can now be set\n if (xhr.readyState === XMLHttpRequest.OPENED) {\n // Only inject if not already set\n if (!xhrHasTraceparent.has(xhr)) {\n // Check privacy controls\n if (privacyManager && !privacyManager.shouldInjectTraceparent(urlStr)) {\n if (config?.debug) {\n const reason = getDenialReason(privacyManager, urlStr);\n console.log(\n '[autotel-web] Skipped traceparent on XHR (privacy):',\n urlStr,\n reason\n );\n }\n } else {\n // Inject traceparent header\n try {\n const traceparent = createTraceparent();\n // originalXHRSetRequestHeader is always defined here because patchXMLHttpRequest() sets it before patching\n originalXHRSetRequestHeader!.call(xhr, 'traceparent', traceparent);\n\n if (config?.debug) {\n console.log(\n '[autotel-web] Injected traceparent on XHR:',\n urlStr,\n traceparent\n );\n }\n } catch (error) {\n // Silently ignore if setRequestHeader fails\n if (config?.debug) {\n console.warn(\n '[autotel-web] Failed to inject traceparent on XHR:',\n error\n );\n }\n }\n }\n }\n }\n\n // Call original handler if it exists\n if (originalOnReadyStateChange) {\n return originalOnReadyStateChange.call(xhr, event);\n }\n };\n\n return result;\n };\n}\n\n/**\n * Validate configuration at initialization time\n * Catches common misconfigurations early\n */\nfunction validateConfig(userConfig: AutotelWebConfig): void {\n // Validate service name\n if (!userConfig.service || typeof userConfig.service !== 'string') {\n throw new Error('[autotel-web] service name is required and must be a string');\n }\n\n if (userConfig.service.length === 0) {\n throw new Error('[autotel-web] service name cannot be empty');\n }\n\n if (userConfig.service.length > 255) {\n console.warn(\n '[autotel-web] service name is very long (> 255 chars). Consider using a shorter name.'\n );\n }\n\n // Validate privacy config if provided\n if (userConfig.privacy) {\n const { allowedOrigins, blockedOrigins } = userConfig.privacy;\n\n // Warn if both allowlist and blocklist are empty\n if (\n (!allowedOrigins || allowedOrigins.length === 0) &&\n (!blockedOrigins || blockedOrigins.length === 0) &&\n !userConfig.privacy.respectDoNotTrack &&\n !userConfig.privacy.respectGPC\n ) {\n console.warn(\n '[autotel-web] privacy config provided but all options are empty/disabled. This has no effect.'\n );\n }\n\n // Warn about overlapping origins\n if (allowedOrigins && blockedOrigins) {\n const overlap = allowedOrigins.filter((allowed) =>\n blockedOrigins.some((blocked) =>\n allowed.toLowerCase().includes(blocked.toLowerCase())\n )\n );\n if (overlap.length > 0) {\n console.warn(\n '[autotel-web] Some allowedOrigins match blockedOrigins. Blocklist takes precedence:',\n overlap\n );\n }\n }\n\n // Validate origin format (warn if looks invalid)\n const allOrigins = [\n ...(allowedOrigins ?? []),\n ...(blockedOrigins ?? []),\n ];\n allOrigins.forEach((origin) => {\n if (origin.includes('://')) {\n console.warn(\n `[autotel-web] Origin \"${origin}\" includes protocol (://) - this is usually not needed. Just use the domain name.`\n );\n }\n });\n }\n}\n\n/**\n * Reset initialization state (for testing)\n * @internal\n */\nexport function resetForTesting(): void {\n isInitialized = false;\n config = undefined;\n privacyManager = undefined;\n resetExporter();\n\n // Restore original fetch/XHR if they were patched\n // Then clear the stored originals so next test can set up fresh mocks\n if (typeof window !== 'undefined') {\n if (originalFetch) {\n window.fetch = originalFetch;\n originalFetch = undefined;\n }\n if (originalXHROpen) {\n XMLHttpRequest.prototype.open = originalXHROpen;\n originalXHROpen = undefined;\n }\n if (originalXHRSetRequestHeader) {\n XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;\n originalXHRSetRequestHeader = undefined;\n }\n }\n}\n\n/**\n * Get current configuration\n * @internal\n */\nexport function getConfig(): AutotelWebConfig | undefined {\n return config;\n}\n\n/**\n * Get current privacy manager\n * @internal\n */\nexport function getPrivacyManager(): PrivacyManager | undefined {\n return privacyManager;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-web",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2",
|
|
4
4
|
"description": "Ultra-lightweight browser SDK for distributed tracing - propagates W3C traceparent headers to backends using Autotel (~2-5KB gzipped)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,23 +44,23 @@
|
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@opentelemetry/api": "^1.9.1",
|
|
47
|
-
"@opentelemetry/core": "^2.
|
|
48
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
49
|
-
"@opentelemetry/instrumentation": "^0.
|
|
50
|
-
"@opentelemetry/instrumentation-document-load": "^0.
|
|
51
|
-
"@opentelemetry/instrumentation-fetch": "^0.
|
|
52
|
-
"@opentelemetry/instrumentation-xml-http-request": "^0.
|
|
53
|
-
"@opentelemetry/resources": "^2.
|
|
54
|
-
"@opentelemetry/sdk-trace-base": "^2.
|
|
55
|
-
"@opentelemetry/sdk-trace-web": "^2.
|
|
47
|
+
"@opentelemetry/core": "^2.7.0",
|
|
48
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.215.0",
|
|
49
|
+
"@opentelemetry/instrumentation": "^0.215.0",
|
|
50
|
+
"@opentelemetry/instrumentation-document-load": "^0.60.0",
|
|
51
|
+
"@opentelemetry/instrumentation-fetch": "^0.215.0",
|
|
52
|
+
"@opentelemetry/instrumentation-xml-http-request": "^0.215.0",
|
|
53
|
+
"@opentelemetry/resources": "^2.7.0",
|
|
54
|
+
"@opentelemetry/sdk-trace-base": "^2.7.0",
|
|
55
|
+
"@opentelemetry/sdk-trace-web": "^2.7.0",
|
|
56
56
|
"web-vitals": "^5.2.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@types/node": "^25.
|
|
59
|
+
"@types/node": "^25.6.0",
|
|
60
60
|
"rimraf": "^6.1.3",
|
|
61
61
|
"tsup": "^8.5.1",
|
|
62
|
-
"typescript": "^6.0.
|
|
63
|
-
"vitest": "^4.1.
|
|
62
|
+
"typescript": "^6.0.3",
|
|
63
|
+
"vitest": "^4.1.5",
|
|
64
64
|
"vitest-mock-extended": "^4.0.0"
|
|
65
65
|
},
|
|
66
66
|
"repository": {
|