diff --git a/.env.example b/.env.example index 645a44b833e9..ff20efaace55 100644 --- a/.env.example +++ b/.env.example @@ -135,6 +135,39 @@ NODE_MAX_OLD_SPACE_SIZE=6144 # OTEL_LOG_LEVEL=INFO # OTEL_SDK_DISABLED=false +#===============================# +# Real User Monitoring (Browser) # +#===============================# + +# Enables browser Real User Monitoring. Disabled by default. +# Currently supports HyperDX via the browser SDK. +# RUM_ENABLED=false +# RUM_PROVIDER=hyperdx +# RUM_URL=http://localhost:4318 +# RUM_SERVICE_NAME=librechat-web +# RUM_ENVIRONMENT=development + +# Public browser-token mode is suitable for OSS/self-hosted deployments. +# Treat the token as public and restrict/rate-limit ingestion in your RUM backend. +# RUM_AUTH_MODE=publicToken +# RUM_PUBLIC_TOKEN= + +# Authenticated mode sends the active LibreChat user JWT only to the configured RUM URL. +# Use only with a trusted HTTPS ingest URL that will not log or expose authorization headers. +# RUM_AUTH_MODE=userJwt +# RUM_AUTH_HEADER_SCHEME=Bearer + +# Optional comma-separated first-party HTTPS origins/URLs that should receive traceparent headers. +# Wildcards and non-HTTPS targets are ignored. +# RUM_TRACE_PROPAGATION_TARGETS=https://api.example.com + +# Privacy defaults: replay, console capture, and full network body capture stay off. +# Console/network capture may collect sensitive browser logs, prompts, responses, or payloads. +# RUM_DISABLE_REPLAY=true +# RUM_CONSOLE_CAPTURE=false +# RUM_ADVANCED_NETWORK_CAPTURE=false +# RUM_SAMPLE_RATE=1 + #===================================================# # Endpoints # #===================================================# diff --git a/api/server/routes/__tests__/config.rum.spec.js b/api/server/routes/__tests__/config.rum.spec.js new file mode 100644 index 000000000000..f10685a6e705 --- /dev/null +++ b/api/server/routes/__tests__/config.rum.spec.js @@ -0,0 +1,173 @@ +jest.mock('~/cache/getLogStores'); + +const mockGetAppConfig = jest.fn(); +jest.mock('~/server/services/Config/app', () => ({ + getAppConfig: (...args) => mockGetAppConfig(...args), +})); + +jest.mock('~/server/services/Config/ldap', () => ({ + getLdapConfig: jest.fn(() => null), +})); + +jest.mock('~/server/middleware/roles/capabilities', () => ({ + hasCapability: jest.fn(), +})); + +jest.mock('@librechat/data-schemas', () => ({ + ...jest.requireActual('@librechat/data-schemas'), + getTenantId: jest.fn(() => undefined), +})); + +jest.mock('@librechat/api', () => ({ + ...jest.requireActual('@librechat/api'), + getCloudFrontConfig: jest.fn(() => null), +})); + +const request = require('supertest'); +const express = require('express'); +const configRoute = require('../config'); + +function createApp(user) { + const app = express(); + app.disable('x-powered-by'); + if (user) { + app.use((req, _res, next) => { + req.user = user; + next(); + }); + } + app.use('/api/config', configRoute); + return app; +} + +const baseAppConfig = { + registration: { socialLogins: ['google', 'github'] }, + interfaceConfig: { modelSelect: true }, + turnstileConfig: { siteKey: 'test-key' }, + modelSpecs: { list: [{ name: 'test-spec' }] }, +}; + +const mockUser = { + id: 'user123', + role: 'USER', + tenantId: undefined, +}; + +afterEach(() => { + jest.resetAllMocks(); + delete process.env.RUM_ENABLED; + delete process.env.RUM_PROVIDER; + delete process.env.RUM_URL; + delete process.env.RUM_SERVICE_NAME; + delete process.env.RUM_AUTH_MODE; + delete process.env.RUM_AUTH_HEADER_SCHEME; + delete process.env.RUM_PUBLIC_TOKEN; + delete process.env.RUM_TRACE_PROPAGATION_TARGETS; + delete process.env.RUM_CONSOLE_CAPTURE; + delete process.env.RUM_DISABLE_REPLAY; + delete process.env.RUM_ADVANCED_NETWORK_CAPTURE; + delete process.env.RUM_SAMPLE_RATE; + delete process.env.RUM_ENVIRONMENT; +}); + +describe('GET /api/config RUM config', () => { + it('includes public-token RUM config when enabled with valid env', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'https://rum.example.com'; + process.env.RUM_PUBLIC_TOKEN = 'public-token'; + process.env.RUM_TRACE_PROPAGATION_TARGETS = + 'https://app.example.com,https://api.openai.com,*,http://api.example.com'; + process.env.RUM_SAMPLE_RATE = '0.25'; + process.env.RUM_ENVIRONMENT = 'test'; + const app = createApp(null); + + const response = await request(app).get('/api/config'); + + expect(response.body.rum).toEqual({ + provider: 'hyperdx', + enabled: true, + url: 'https://rum.example.com', + serviceName: 'librechat-web', + authMode: 'publicToken', + publicToken: 'public-token', + tracePropagationTargets: ['https://app.example.com', 'https://api.openai.com'], + consoleCapture: false, + disableReplay: true, + advancedNetworkCapture: false, + sampleRate: 0.25, + environment: 'test', + }); + }); + + it('omits malformed RUM config', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'not a url'; + process.env.RUM_PUBLIC_TOKEN = 'public-token'; + const app = createApp(null); + + const response = await request(app).get('/api/config'); + + expect(response.body).not.toHaveProperty('rum'); + }); + + it('omits RUM config when the URL contains credentials', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'https://user:password@rum.example.com'; + process.env.RUM_PUBLIC_TOKEN = 'public-token'; + const app = createApp(null); + + const response = await request(app).get('/api/config'); + + expect(response.body).not.toHaveProperty('rum'); + }); + + it('allows IPv6 localhost HTTP RUM URLs in public-token mode', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'http://[::1]:4318'; + process.env.RUM_PUBLIC_TOKEN = 'public-token'; + const app = createApp(null); + + const response = await request(app).get('/api/config'); + + expect(response.body.rum?.url).toBe('http://[::1]:4318'); + }); + + it('includes userJwt RUM config for authenticated users', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'https://rum.example.com'; + process.env.RUM_AUTH_MODE = 'userJwt'; + process.env.RUM_AUTH_HEADER_SCHEME = 'Basic'; + const app = createApp(mockUser); + + const response = await request(app).get('/api/config'); + + expect(response.body.rum).toEqual({ + provider: 'hyperdx', + enabled: true, + url: 'https://rum.example.com', + serviceName: 'librechat-web', + authMode: 'userJwt', + authHeaderScheme: 'Basic', + consoleCapture: false, + disableReplay: true, + advancedNetworkCapture: false, + }); + }); + + it('omits userJwt RUM config for unauthenticated users', async () => { + mockGetAppConfig.mockResolvedValue(baseAppConfig); + process.env.RUM_ENABLED = 'true'; + process.env.RUM_URL = 'https://rum.example.com'; + process.env.RUM_AUTH_MODE = 'userJwt'; + const app = createApp(null); + + const response = await request(app).get('/api/config'); + + expect(response.body).not.toHaveProperty('rum'); + }); +}); diff --git a/api/server/routes/config.js b/api/server/routes/config.js index 28bdd762f702..8141bae97aab 100644 --- a/api/server/routes/config.js +++ b/api/server/routes/config.js @@ -10,6 +10,7 @@ const { defaultSocialLogins } = require('librechat-data-provider'); const { logger, getTenantId, SystemCapabilities } = require('@librechat/data-schemas'); const { hasCapability } = require('~/server/middleware/roles/capabilities'); const { getLdapConfig } = require('~/server/services/Config/ldap'); +const { getRumConfig } = require('~/server/services/Config/rum'); const { getAppConfig } = require('~/server/services/Config/app'); const router = express.Router(); @@ -169,6 +170,7 @@ router.get('/', async function (req, res) { try { const sharedPayload = buildSharedPayload(); const cloudFront = buildCloudFrontStartupConfig(); + const rum = getRumConfig(req.user); if (!req.user) { const tenantId = getTenantId(); @@ -180,6 +182,7 @@ router.get('/', async function (req, res) { socialLogins: baseConfig?.registration?.socialLogins ?? defaultSocialLogins, turnstile: baseConfig?.turnstileConfig, ...(cloudFront ? { cloudFront } : {}), + ...(rum ? { rum } : {}), }; const interfaceConfig = baseConfig?.interfaceConfig; @@ -231,6 +234,7 @@ router.get('/', async function (req, res) { ? parseInt(process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES, 10) : 0, ...(cloudFront ? { cloudFront } : {}), + ...(rum ? { rum } : {}), }; const webSearch = buildWebSearchConfig(appConfig); diff --git a/api/server/services/Config/rum.js b/api/server/services/Config/rum.js new file mode 100644 index 000000000000..7dcb176b72c2 --- /dev/null +++ b/api/server/services/Config/rum.js @@ -0,0 +1,156 @@ +const { isEnabled } = require('@librechat/api'); +const { logger } = require('@librechat/data-schemas'); + +const DEFAULT_RUM_SERVICE_NAME = 'librechat-web'; +let hasWarnedUserJwtAuth = false; + +function parseBooleanEnv(value, defaultValue = false) { + if (value == null || value === '') { + return defaultValue; + } + + return isEnabled(value); +} + +function parseNumberEnv(value) { + if (value == null || value === '') { + return undefined; + } + + const parsed = Number(value); + return Number.isFinite(parsed) ? parsed : undefined; +} + +function parseCsvEnv(value) { + if (!value) { + return []; + } + + return value + .split(',') + .map((item) => item.trim()) + .filter(Boolean); +} + +function parseUrl(value) { + try { + return new URL(value); + } catch { + return undefined; + } +} + +function isLocalhost(url) { + return url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]'; +} + +function isSafeRumUrl(url, authMode) { + if (url.username || url.password) { + return false; + } + + if (url.protocol === 'https:') { + return true; + } + + return authMode === 'publicToken' && url.protocol === 'http:' && isLocalhost(url); +} + +function isSafeTraceTarget(target) { + if (target.includes('*')) { + return false; + } + + const url = parseUrl(target); + if (!url || url.protocol !== 'https:') { + return false; + } + + return true; +} + +function warnOnceForUserJwtAuth() { + if (hasWarnedUserJwtAuth) { + return; + } + + hasWarnedUserJwtAuth = true; + logger.warn( + '[config] RUM userJwt mode sends the active LibreChat user JWT to RUM_URL; use only with a trusted HTTPS collector that will not log authorization headers', + ); +} + +function getRumConfig(user) { + if (!parseBooleanEnv(process.env.RUM_ENABLED)) { + return undefined; + } + + const provider = process.env.RUM_PROVIDER || 'hyperdx'; + if (provider !== 'hyperdx') { + logger.warn(`[config] Unsupported RUM provider "${provider}", disabling RUM`); + return undefined; + } + + const authMode = process.env.RUM_AUTH_MODE === 'userJwt' ? 'userJwt' : 'publicToken'; + const rumUrl = process.env.RUM_URL; + const parsedUrl = rumUrl ? parseUrl(rumUrl) : undefined; + + if (!parsedUrl || !isSafeRumUrl(parsedUrl, authMode)) { + logger.warn('[config] Invalid RUM_URL, disabling RUM'); + return undefined; + } + + if (authMode === 'userJwt' && !user) { + return undefined; + } + + if (authMode === 'userJwt') { + warnOnceForUserJwtAuth(); + } + + if (authMode === 'publicToken' && !process.env.RUM_PUBLIC_TOKEN) { + logger.warn('[config] RUM publicToken mode requires RUM_PUBLIC_TOKEN, disabling RUM'); + return undefined; + } + + const rawTracePropagationTargets = parseCsvEnv(process.env.RUM_TRACE_PROPAGATION_TARGETS); + const tracePropagationTargets = rawTracePropagationTargets.filter(isSafeTraceTarget); + if (rawTracePropagationTargets.length !== tracePropagationTargets.length) { + logger.info('[config] Ignored unsafe RUM trace propagation targets'); + } + + const configuredSampleRate = parseNumberEnv(process.env.RUM_SAMPLE_RATE); + const sampleRate = + configuredSampleRate != null && configuredSampleRate >= 0 && configuredSampleRate <= 1 + ? configuredSampleRate + : undefined; + const authHeaderScheme = process.env.RUM_AUTH_HEADER_SCHEME === 'Basic' ? 'Basic' : 'Bearer'; + const consoleCapture = parseBooleanEnv(process.env.RUM_CONSOLE_CAPTURE); + const advancedNetworkCapture = parseBooleanEnv(process.env.RUM_ADVANCED_NETWORK_CAPTURE); + + if (consoleCapture) { + logger.warn('[config] RUM console capture is enabled and may collect sensitive browser logs'); + } + + if (advancedNetworkCapture) { + logger.warn('[config] RUM advanced network capture is enabled and may collect payload data'); + } + + return { + provider: 'hyperdx', + enabled: true, + url: parsedUrl.href.replace(/\/$/, ''), + serviceName: process.env.RUM_SERVICE_NAME || DEFAULT_RUM_SERVICE_NAME, + authMode, + ...(authMode === 'userJwt' ? { authHeaderScheme } : {}), + ...(authMode === 'publicToken' ? { publicToken: process.env.RUM_PUBLIC_TOKEN } : {}), + ...(tracePropagationTargets.length > 0 ? { tracePropagationTargets } : {}), + consoleCapture, + disableReplay: parseBooleanEnv(process.env.RUM_DISABLE_REPLAY, true), + advancedNetworkCapture, + ...(sampleRate != null ? { sampleRate } : {}), + ...(process.env.RUM_ENVIRONMENT ? { environment: process.env.RUM_ENVIRONMENT } : {}), + }; +} + +module.exports = { getRumConfig }; diff --git a/client/package.json b/client/package.json index 80b46c2b4cfd..520d6ed5cc74 100644 --- a/client/package.json +++ b/client/package.json @@ -35,6 +35,7 @@ "@dicebear/collection": "^9.4.1", "@dicebear/core": "^9.4.1", "@headlessui/react": "^2.1.2", + "@hyperdx/browser": "^0.22.1", "@librechat/client": "*", "@marsidev/react-turnstile": "^1.1.0", "@mcp-ui/client": "^5.7.0", diff --git a/client/src/lib/rum/WithRum.tsx b/client/src/lib/rum/WithRum.tsx new file mode 100644 index 000000000000..59beb35c48a7 --- /dev/null +++ b/client/src/lib/rum/WithRum.tsx @@ -0,0 +1,8 @@ +import type { ReactNode } from 'react'; +import useRum from './useRum'; + +export default function WithRum({ children }: { children: ReactNode }) { + useRum(); + + return <>{children}; +} diff --git a/client/src/lib/rum/early.spec.ts b/client/src/lib/rum/early.spec.ts new file mode 100644 index 000000000000..52f65b9b5d25 --- /dev/null +++ b/client/src/lib/rum/early.spec.ts @@ -0,0 +1,152 @@ +describe('RUM early interceptor', () => { + const originalFetch = window.fetch; + const OriginalXMLHttpRequest = window.XMLHttpRequest; + + beforeEach(() => { + jest.resetModules(); + window.fetch = jest.fn(() => Promise.resolve({} as Response)) as unknown as typeof fetch; + window.XMLHttpRequest = OriginalXMLHttpRequest; + }); + + afterEach(() => { + window.fetch = originalFetch; + window.XMLHttpRequest = OriginalXMLHttpRequest; + window.__libreChatRumInterceptor?.clear(); + delete window.__libreChatRumInterceptor; + }); + + it('adds auth only to the configured RUM origin and path', async () => { + await import('./early'); + + window.__libreChatRumInterceptor?.configure({ + url: 'https://rum.example.com/ingest', + authHeaderScheme: 'Bearer', + tokenProvider: () => 'token-123', + }); + + await fetch('https://rum.example.com/ingest/v1/traces'); + await fetch('https://rum.example.com.attacker.com/ingest/v1/traces'); + await fetch('https://rum.example.com/other'); + + const calls = (window.fetch as jest.MockedFunction).mock.calls; + expect(new Headers(calls[0][1]?.headers).get('authorization')).toBe('Bearer token-123'); + expect(calls[1][1]?.headers).toBeUndefined(); + expect(calls[2][1]?.headers).toBeUndefined(); + }); + + it('supports Basic auth when configured', async () => { + await import('./early'); + + window.__libreChatRumInterceptor?.configure({ + url: 'https://rum.example.com', + authHeaderScheme: 'Basic', + tokenProvider: () => 'token-123', + }); + + await fetch('https://rum.example.com/v1/traces'); + + const calls = (window.fetch as jest.MockedFunction).mock.calls; + expect(new Headers(calls[0][1]?.headers).get('authorization')).toBe('Basic token-123'); + }); + + it('leaves requests unchanged when token is unavailable', async () => { + await import('./early'); + + window.__libreChatRumInterceptor?.configure({ + url: 'https://rum.example.com', + tokenProvider: () => undefined, + }); + + await fetch('https://rum.example.com/v1/traces'); + + const calls = (window.fetch as jest.MockedFunction).mock.calls; + expect(calls[0][1]?.headers).toBeUndefined(); + }); + + it('preserves XMLHttpRequest constructor constants', async () => { + await import('./early'); + + expect(window.XMLHttpRequest.DONE).toBe(OriginalXMLHttpRequest.DONE); + expect(window.XMLHttpRequest.prototype).toBe(OriginalXMLHttpRequest.prototype); + }); + + it('falls back to SDK-set XHR auth when the token provider is empty', async () => { + const instances: Array<{ headers: Map }> = []; + + class FakeXMLHttpRequest { + static DONE = 4; + headers = new Map(); + + constructor() { + instances.push(this); + } + + open() { + return undefined; + } + + setRequestHeader(name: string, value: string) { + this.headers.set(name.toLowerCase(), value); + } + + send() { + return undefined; + } + } + + window.XMLHttpRequest = FakeXMLHttpRequest as unknown as typeof XMLHttpRequest; + await import('./early'); + + window.__libreChatRumInterceptor?.configure({ + url: 'https://rum.example.com/ingest', + tokenProvider: () => undefined, + }); + + const xhr = new XMLHttpRequest(); + xhr.open('POST', 'https://rum.example.com/ingest/v1/traces'); + xhr.setRequestHeader('authorization', 'Bearer sdk-key'); + xhr.send(); + + expect(instances[0].headers.get('authorization')).toBe('Bearer sdk-key'); + }); + + it('preserves XHR credentials when async is omitted', async () => { + const openCalls: unknown[][] = []; + + class FakeXMLHttpRequest { + static DONE = 4; + + open(...args: unknown[]) { + openCalls.push(args); + } + + setRequestHeader() { + return undefined; + } + + send() { + return undefined; + } + } + + window.XMLHttpRequest = FakeXMLHttpRequest as unknown as typeof XMLHttpRequest; + await import('./early'); + + const xhr = new XMLHttpRequest(); + (xhr.open as unknown as (...args: unknown[]) => void)( + 'GET', + 'https://api.example.com/resource', + undefined, + 'user', + 'password', + ); + + expect(openCalls[0]).toEqual([ + 'GET', + 'https://api.example.com/resource', + true, + 'user', + 'password', + ]); + }); +}); diff --git a/client/src/lib/rum/early.ts b/client/src/lib/rum/early.ts new file mode 100644 index 000000000000..ea7bffe20af7 --- /dev/null +++ b/client/src/lib/rum/early.ts @@ -0,0 +1,163 @@ +type TokenProvider = () => string | undefined; + +type RumInterceptorConfig = { + url?: string; + tokenProvider?: TokenProvider; + authHeaderScheme?: 'Bearer' | 'Basic'; +}; + +declare global { + interface Window { + __libreChatRumInterceptor?: { + configure: (config: RumInterceptorConfig) => void; + clear: () => void; + }; + } +} + +let rumUrl: URL | undefined; +let tokenProvider: TokenProvider | undefined; +let authHeaderScheme: 'Bearer' | 'Basic' = 'Bearer'; + +const originalFetch = window.fetch.bind(window); +const OriginalXMLHttpRequest = window.XMLHttpRequest; + +function isRequest(input: RequestInfo | URL): input is Request { + return typeof Request !== 'undefined' && input instanceof Request; +} + +function parseUrl(value: string | URL): URL | undefined { + try { + return value instanceof URL ? value : new URL(value, window.location.origin); + } catch { + return undefined; + } +} + +function matchesRumUrl(value: string | URL): boolean { + if (!rumUrl) { + return false; + } + + const requestUrl = parseUrl(value); + if (!requestUrl || requestUrl.origin !== rumUrl.origin) { + return false; + } + + const basePath = rumUrl.pathname.endsWith('/') ? rumUrl.pathname : `${rumUrl.pathname}/`; + return requestUrl.pathname === rumUrl.pathname || requestUrl.pathname.startsWith(basePath); +} + +function getAuthorization(): string | undefined { + const token = tokenProvider?.(); + return token ? `${authHeaderScheme} ${token}` : undefined; +} + +const interceptedFetch = function interceptedFetch( + input: RequestInfo | URL, + init?: RequestInit, +): Promise { + const requestUrl = isRequest(input) ? input.url : input; + + if (!matchesRumUrl(requestUrl)) { + return originalFetch(input, init); + } + + const authorization = getAuthorization(); + if (!authorization) { + return originalFetch(input, init); + } + + const headers = new Headers(isRequest(input) ? input.headers : init?.headers); + headers.set('authorization', authorization); + + return originalFetch(input, { + ...init, + headers, + }); +}; + +window.fetch = Object.assign(interceptedFetch, window.fetch); + +function InterceptedXMLHttpRequest(): XMLHttpRequest { + const xhr = new OriginalXMLHttpRequest(); + const originalOpen = xhr.open; + const originalSend = xhr.send; + const originalSetRequestHeader = xhr.setRequestHeader; + let isRumRequest = false; + let rumSdkAuthorization: string | undefined; + + xhr.open = function open( + method: string, + url: string | URL, + async?: boolean, + username?: string | null, + password?: string | null, + ): void { + isRumRequest = matchesRumUrl(url); + + if (arguments.length >= 5) { + originalOpen.call( + this, + method, + url, + async ?? true, + username ?? undefined, + password ?? undefined, + ); + return; + } + + if (arguments.length === 4) { + originalOpen.call(this, method, url, async ?? true, username ?? undefined); + return; + } + + if (arguments.length === 3) { + originalOpen.call(this, method, url, async ?? true); + return; + } + + originalOpen.call(this, method, url); + }; + + xhr.setRequestHeader = function setRequestHeader(name: string, value: string): void { + if (isRumRequest && name.toLowerCase() === 'authorization') { + // HyperDX sets its own API key header; userJwt mode replaces it with the LibreChat auth token. + rumSdkAuthorization = value; + return; + } + + originalSetRequestHeader.call(this, name, value); + }; + + xhr.send = function send(body?: Document | XMLHttpRequestBodyInit | null): void { + const authorization = isRumRequest ? (getAuthorization() ?? rumSdkAuthorization) : undefined; + if (authorization) { + originalSetRequestHeader.call(this, 'authorization', authorization); + } + + originalSend.call(this, body); + }; + + return xhr; +} + +Object.setPrototypeOf(InterceptedXMLHttpRequest, OriginalXMLHttpRequest); +InterceptedXMLHttpRequest.prototype = OriginalXMLHttpRequest.prototype; +window.XMLHttpRequest = InterceptedXMLHttpRequest as unknown as typeof XMLHttpRequest; + +window.__libreChatRumInterceptor = { + configure(config: RumInterceptorConfig) { + rumUrl = config.url ? parseUrl(config.url) : undefined; + tokenProvider = config.tokenProvider; + authHeaderScheme = config.authHeaderScheme ?? 'Bearer'; + }, + clear() { + rumUrl = undefined; + tokenProvider = undefined; + authHeaderScheme = 'Bearer'; + }, +}; + +export {}; diff --git a/client/src/lib/rum/routes.spec.ts b/client/src/lib/rum/routes.spec.ts new file mode 100644 index 000000000000..c1777aa80a1c --- /dev/null +++ b/client/src/lib/rum/routes.spec.ts @@ -0,0 +1,19 @@ +import { normalizeRumPath } from './routes'; + +describe('normalizeRumPath', () => { + it('normalizes dynamic LibreChat route identifiers', () => { + expect(normalizeRumPath('/c/65a5e0a7d1c2b3a4f5e6d789')).toBe('/c/:conversationId'); + expect(normalizeRumPath('/share/65a5e0a7d1c2b3a4f5e6d789')).toBe('/share/:shareId'); + expect(normalizeRumPath('/assistants/asst_123')).toBe('/assistants/:assistantId'); + }); + + it('normalizes generic UUID and ObjectId path segments', () => { + expect(normalizeRumPath('/files/550e8400-e29b-41d4-a716-446655440000')).toBe('/files/:id'); + expect(normalizeRumPath('/files/65a5e0a7d1c2b3a4f5e6d789/preview')).toBe('/files/:id/preview'); + }); + + it('preserves static routes', () => { + expect(normalizeRumPath('/search')).toBe('/search'); + expect(normalizeRumPath('/')).toBe('/'); + }); +}); diff --git a/client/src/lib/rum/routes.ts b/client/src/lib/rum/routes.ts new file mode 100644 index 000000000000..2388d72f0ef6 --- /dev/null +++ b/client/src/lib/rum/routes.ts @@ -0,0 +1,31 @@ +const OBJECT_ID = /^[0-9a-f]{24}$/i; +const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + +function normalizeSegment(segment: string, previous: string | undefined): string { + if (previous === 'c') { + return ':conversationId'; + } + + if (previous === 'share') { + return ':shareId'; + } + + if (previous === 'assistants') { + return ':assistantId'; + } + + if (UUID.test(segment) || OBJECT_ID.test(segment)) { + return ':id'; + } + + return segment; +} + +export function normalizeRumPath(pathname: string): string { + const segments = pathname.split('/').filter(Boolean); + if (segments.length === 0) { + return '/'; + } + + return `/${segments.map((segment, index) => normalizeSegment(segment, segments[index - 1])).join('/')}`; +} diff --git a/client/src/lib/rum/useRum.spec.tsx b/client/src/lib/rum/useRum.spec.tsx new file mode 100644 index 000000000000..74543a7fd5c2 --- /dev/null +++ b/client/src/lib/rum/useRum.spec.tsx @@ -0,0 +1,123 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import useRum from './useRum'; + +const mockInit = jest.fn(); +const mockSetGlobalAttributes = jest.fn(); +const mockUseGetStartupConfig = jest.fn(); +const mockUseAuthContext = jest.fn(); +const mockUseLocation = jest.fn(); + +jest.mock('@hyperdx/browser', () => ({ + __esModule: true, + default: { + init: (...args: unknown[]) => mockInit(...args), + setGlobalAttributes: (...args: unknown[]) => mockSetGlobalAttributes(...args), + }, +})); + +jest.mock('~/data-provider', () => ({ + useGetStartupConfig: () => mockUseGetStartupConfig(), +})); + +jest.mock('~/hooks/AuthContext', () => ({ + useAuthContext: () => mockUseAuthContext(), +})); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useLocation: () => mockUseLocation(), +})); + +describe('useRum', () => { + beforeEach(() => { + mockUseLocation.mockReturnValue({ pathname: '/c/conversation-123' }); + mockUseAuthContext.mockReturnValue({ + isAuthenticated: true, + token: 'jwt-token', + user: { + id: 'user-123', + role: 'USER', + tenantId: 'org-123', + email: 'user@example.com', + }, + }); + delete window.__libreChatRumInterceptor; + }); + + it('initializes HyperDX public-token RUM with privacy defaults and safe attributes', async () => { + mockUseGetStartupConfig.mockReturnValue({ + data: { + rum: { + provider: 'hyperdx', + enabled: true, + url: 'https://rum.example.com', + serviceName: 'librechat-web', + authMode: 'publicToken', + publicToken: 'public-token', + tracePropagationTargets: ['https://librechat.example.com'], + }, + }, + }); + + renderHook(() => useRum()); + + await waitFor(() => { + expect(mockInit).toHaveBeenCalledWith({ + advancedNetworkCapture: false, + apiKey: 'public-token', + consoleCapture: false, + disableReplay: true, + service: 'librechat-web', + tracePropagationTargets: ['https://librechat.example.com'], + url: 'https://rum.example.com', + }); + }); + + expect(mockSetGlobalAttributes).toHaveBeenCalledWith({ + route: '/c/:conversationId', + role: 'USER', + userId: 'user-123', + orgId: 'org-123', + serviceName: 'librechat-web', + }); + expect(mockSetGlobalAttributes).not.toHaveBeenCalledWith( + expect.objectContaining({ email: 'user@example.com' }), + ); + }); + + it('configures the early interceptor and uses a placeholder api key for userJwt mode', async () => { + const configure = jest.fn(); + const clear = jest.fn(); + window.__libreChatRumInterceptor = { configure, clear }; + mockUseGetStartupConfig.mockReturnValue({ + data: { + rum: { + provider: 'hyperdx', + enabled: true, + url: 'https://rum.example.com/ingest', + serviceName: 'librechat-web', + authMode: 'userJwt', + authHeaderScheme: 'Basic', + }, + }, + }); + + renderHook(() => useRum()); + + expect(configure).toHaveBeenCalledWith({ + url: 'https://rum.example.com/ingest', + authHeaderScheme: 'Basic', + tokenProvider: expect.any(Function), + }); + expect(configure.mock.calls[0][0].tokenProvider()).toBe('jwt-token'); + + await waitFor(() => { + expect(mockInit).toHaveBeenCalledWith( + expect.objectContaining({ + apiKey: 'placeholder', + url: 'https://rum.example.com/ingest', + }), + ); + }); + }); +}); diff --git a/client/src/lib/rum/useRum.ts b/client/src/lib/rum/useRum.ts new file mode 100644 index 000000000000..d7cefd798920 --- /dev/null +++ b/client/src/lib/rum/useRum.ts @@ -0,0 +1,163 @@ +import { useEffect, useMemo, useRef } from 'react'; +import { useLocation } from 'react-router-dom'; +import type { TRumConfig, TUser } from 'librechat-data-provider'; +import { useGetStartupConfig } from '~/data-provider'; +import { useAuthContext } from '~/hooks/AuthContext'; +import { normalizeRumPath } from './routes'; + +type HyperDXBrowser = { + init: (config: { + advancedNetworkCapture: boolean; + apiKey: string; + consoleCapture: boolean; + disableReplay: boolean; + service: string; + tracePropagationTargets?: string[]; + url: string; + }) => void; + setGlobalAttributes: (attributes: Record) => void; +}; + +function shouldInitializeRum(config: TRumConfig | undefined, token: string | undefined): boolean { + if (!config?.enabled || config.provider !== 'hyperdx' || !config.url || !config.serviceName) { + return false; + } + + if (config.authMode === 'publicToken') { + return !!config.publicToken; + } + + return !!token; +} + +function getApiKey(config: TRumConfig): string { + return config.authMode === 'publicToken' ? (config.publicToken ?? '') : 'placeholder'; +} + +function buildGlobalAttributes( + user: TUser | undefined, + config: TRumConfig, + route: string, +): Record { + return Object.fromEntries( + Object.entries({ + route, + role: user?.role, + userId: user?.id, + orgId: user?.tenantId, + serviceName: config.serviceName, + environment: config.environment, + }).filter( + (entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1] !== '', + ), + ); +} + +async function loadHyperDX(): Promise { + const module = await import('@hyperdx/browser'); + return module.default; +} + +export default function useRum(): void { + const { data: startupConfig } = useGetStartupConfig(); + const { isAuthenticated, token, user } = useAuthContext(); + const location = useLocation(); + const initializedKeyRef = useRef(undefined); + const sampledInitKeyRef = useRef(undefined); + const sampledInRef = useRef(true); + const hyperDxRef = useRef(undefined); + const tokenRef = useRef(token); + const rumConfig = startupConfig?.rum; + const route = useMemo(() => normalizeRumPath(location.pathname), [location.pathname]); + const routeRef = useRef(route); + + useEffect(() => { + tokenRef.current = token; + }, [token]); + + useEffect(() => { + routeRef.current = route; + }, [route]); + + useEffect(() => { + if (!rumConfig || rumConfig.authMode !== 'userJwt') { + window.__libreChatRumInterceptor?.clear(); + return; + } + + window.__libreChatRumInterceptor?.configure({ + url: rumConfig.url, + authHeaderScheme: rumConfig.authHeaderScheme, + tokenProvider: () => tokenRef.current, + }); + + return () => { + window.__libreChatRumInterceptor?.clear(); + }; + }, [rumConfig]); + + useEffect(() => { + if (!rumConfig) { + return; + } + + if ( + !shouldInitializeRum(rumConfig, token) || + (rumConfig.authMode === 'userJwt' && !isAuthenticated) + ) { + return; + } + + const config = rumConfig; + + const initKey = [config.url, config.serviceName, config.authMode, config.publicToken].join(':'); + + if (initializedKeyRef.current === initKey) { + return; + } + + if (sampledInitKeyRef.current !== initKey) { + sampledInitKeyRef.current = initKey; + sampledInRef.current = + typeof config.sampleRate === 'number' ? Math.random() < config.sampleRate : true; + } + + if (!sampledInRef.current) { + return; + } + + let cancelled = false; + + loadHyperDX() + .then((HyperDX) => { + if (cancelled || initializedKeyRef.current === initKey) { + return; + } + + HyperDX.init({ + advancedNetworkCapture: config.advancedNetworkCapture ?? false, + apiKey: getApiKey(config), + consoleCapture: config.consoleCapture ?? false, + disableReplay: config.disableReplay ?? true, + service: config.serviceName, + tracePropagationTargets: config.tracePropagationTargets, + url: config.url, + }); + + hyperDxRef.current = HyperDX; + initializedKeyRef.current = initKey; + HyperDX.setGlobalAttributes(buildGlobalAttributes(user, config, routeRef.current)); + }) + .catch(() => undefined); + + return () => { + cancelled = true; + }; + }, [isAuthenticated, rumConfig, token, user]); + + useEffect(() => { + hyperDxRef.current?.setGlobalAttributes( + rumConfig ? buildGlobalAttributes(user, rumConfig, route) : { route }, + ); + }, [route, rumConfig, user]); +} diff --git a/client/src/main.jsx b/client/src/main.jsx index 53b483f8d20d..ad2f105efea9 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,3 +1,4 @@ +import './lib/rum/early'; import 'regenerator-runtime/runtime'; import { createRoot } from 'react-dom/client'; import './locales/i18n'; diff --git a/client/src/routes/index.tsx b/client/src/routes/index.tsx index 3a120fba3dd5..363762254699 100644 --- a/client/src/routes/index.tsx +++ b/client/src/routes/index.tsx @@ -12,6 +12,7 @@ import { MarketplaceProvider } from '~/components/Agents/MarketplaceContext'; import AgentMarketplace from '~/components/Agents/Marketplace'; import { OAuthSuccess, OAuthError } from '~/components/OAuth'; import { AuthContextProvider } from '~/hooks/AuthContext'; +import WithRum from '~/lib/rum/WithRum'; import RouteErrorBoundary from './RouteErrorBoundary'; import StartupLayout from './Layouts/Startup'; import LoginLayout from './Layouts/Login'; @@ -23,7 +24,9 @@ import Root from './Root'; const AuthLayout = () => ( - + + + ); diff --git a/client/vite.config.ts b/client/vite.config.ts index 3c0886ec1804..9d0335df742b 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -82,7 +82,7 @@ export default defineConfig(({ command }) => ({ 'assets/maskable-icon.png', 'manifest.webmanifest', ], - globIgnores: ['images/**/*', '**/*.map', 'index.html'], + globIgnores: ['images/**/*', '**/*.map', 'index.html', 'assets/rum.*.js'], maximumFileSizeToCacheInBytes: 4 * 1024 * 1024, navigateFallbackDenylist: [/^\/oauth/, /^\/api/], }, @@ -139,7 +139,9 @@ export default defineConfig(({ command }) => ({ manualChunks(id: string) { const normalizedId = id.replace(/\\/g, '/'); if (normalizedId.includes('node_modules')) { - // High-impact chunking for large libraries + if (normalizedId.includes('@hyperdx/')) { + return 'rum'; + } // IMPORTANT: mermaid and ALL its dependencies must be in the same chunk // to avoid initialization order issues. This includes chevrotain, langium, diff --git a/eslint.config.mjs b/eslint.config.mjs index 59c348374d3d..adf52b44a618 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -25,7 +25,6 @@ const compat = new FlatCompat({ export default [ { ignores: [ - 'client/vite.config.ts', 'client/dist/**/*', 'client/public/**/*', 'client/coverage/**/*', @@ -170,12 +169,15 @@ export default [ }, }, { - files: ['**/rollup.config.js', '**/.eslintrc.js', '**/jest.config.js'], + files: ['**/rollup.config.js', '**/.eslintrc.js', '**/jest.config.js', 'client/vite.config.ts'], languageOptions: { globals: { ...globals.node, }, }, + rules: { + 'import/no-cycle': 'off', + }, }, { files: [ @@ -217,7 +219,7 @@ export default [ })), { files: ['**/*.ts', '**/*.tsx'], - ignores: ['packages/**/*'], + ignores: ['packages/**/*', 'client/vite.config.ts'], plugins: { '@typescript-eslint': typescriptEslintEslintPlugin, jest: fixupPluginRules(jest), diff --git a/package-lock.json b/package-lock.json index d2d74def486e..7353a9ee038e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -416,6 +416,7 @@ "@dicebear/collection": "^9.4.1", "@dicebear/core": "^9.4.1", "@headlessui/react": "^2.1.2", + "@hyperdx/browser": "^0.22.1", "@librechat/client": "*", "@marsidev/react-turnstile": "^1.1.0", "@mcp-ui/client": "^5.7.0", @@ -10395,6 +10396,861 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@hyperdx/browser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@hyperdx/browser/-/browser-0.22.1.tgz", + "integrity": "sha512-iroRagQRT8JOZDl/8jdmDUHLPMQqizGKdY3jdQ9cGPxmgINTqYEDDfV9gEYjVGd5rMXNas/aSCJHB0BEUBKHMA==", + "license": "Apache-2.0", + "dependencies": { + "@hyperdx/otel-web": "0.16.4", + "@hyperdx/otel-web-session-recorder": "0.16.2" + } + }, + "node_modules/@hyperdx/instrumentation-exception": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@hyperdx/instrumentation-exception/-/instrumentation-exception-0.1.0.tgz", + "integrity": "sha512-Jgk7JY5J07Mq9fgXApGVhSkS4+WdzzRcWLReAZhxgo46KShxE6w614mFqUSnuo+z6ghlehsy4ForViUfxrFyew==", + "license": "Apache-2.0", + "dependencies": { + "@hyperdx/instrumentation-sentry-node": "^0.1.0", + "@opentelemetry/core": "^1.24.1", + "@opentelemetry/instrumentation": "^0.51.1", + "@opentelemetry/semantic-conventions": "^1.24.1", + "@sentry/core": "^8.7.0", + "@sentry/types": "^8.7.0", + "@sentry/utils": "^8.7.0", + "json-stringify-safe": "^5.0.1", + "shimmer": "^1.2.1", + "tslib": "^2.5.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@hyperdx/instrumentation-exception/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@hyperdx/instrumentation-sentry-node/-/instrumentation-sentry-node-0.1.0.tgz", + "integrity": "sha512-n8d/K/8M2owL2w4FNfV+lSVW6yoznEj5SdRCysV/ZIfyrZwpijiiSn7gkRcrOfKHmrxrupyp7DVg5L19cGuH6A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.24.1", + "@opentelemetry/instrumentation": "^0.51.1", + "@opentelemetry/semantic-conventions": "^1.24.1", + "json-stringify-safe": "^5.0.1", + "shimmer": "^1.2.1", + "tslib": "^2.5.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@hyperdx/instrumentation-sentry-node/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@hyperdx/otel-web": { + "version": "0.16.4", + "resolved": "https://registry.npmjs.org/@hyperdx/otel-web/-/otel-web-0.16.4.tgz", + "integrity": "sha512-oRdvxClx4ZNHOZuIDWQezQSpk1QpPK7X0u3IpFgJEinA/mhGFuReoS14tTqI12d4Zh6H+k68hAtAn8T3DCZkiw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@hyperdx/instrumentation-exception": "^0.1.0", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.24.1", + "@opentelemetry/exporter-trace-otlp-http": "^0.51.1", + "@opentelemetry/instrumentation": "^0.51.1", + "@opentelemetry/instrumentation-document-load": "^0.38.0", + "@opentelemetry/instrumentation-fetch": "^0.51.1", + "@opentelemetry/instrumentation-user-interaction": "^0.38.0", + "@opentelemetry/instrumentation-xml-http-request": "^0.51.1", + "@opentelemetry/resources": "^1.24.1", + "@opentelemetry/sdk-trace-base": "~1.24.1", + "@opentelemetry/sdk-trace-web": "~1.24.1", + "@opentelemetry/semantic-conventions": "^1.24.1", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.23", + "shimmer": "^1.2.1", + "web-vitals": "^3.3.2" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@hyperdx/otel-web-session-recorder/-/otel-web-session-recorder-0.16.2.tgz", + "integrity": "sha512-VbvhLNempi44tbESbfFohSEFgTIRiCXdSd7OiqKPFWQdr9s/VDrNh52S5VEn27AI6wn4xBy+Ird46Rd4gHKwSg==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "~7.18.3", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.24.1", + "@opentelemetry/resources": "^1.24.1", + "fflate": "0.7.4", + "long": "^5.2.3", + "protobufjs": "~6.11.2", + "rrweb": "1.1.3", + "type-fest": "4.20.1" + }, + "peerDependencies": { + "@hyperdx/otel-web": "^0.16.2" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/@babel/runtime": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/protobufjs": { + "version": "6.11.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", + "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/protobufjs/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/@hyperdx/otel-web-session-recorder/node_modules/type-fest": { + "version": "4.20.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz", + "integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.51.1.tgz", + "integrity": "sha512-n+LhLPsX07URh+HhV2SHVSvz1t4G/l/CE5BjpmhAPqeTceFac1VpyQkavWEJbvnK5bUEXijWt4LxAxFpt2fXyw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/otlp-exporter-base": "0.51.1", + "@opentelemetry/otlp-transformer": "0.51.1", + "@opentelemetry/resources": "1.24.1", + "@opentelemetry/sdk-trace-base": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.51.1.tgz", + "integrity": "sha512-UYlnOYyDdzo1Gw559EHCzru0RwhvuXCwoH8jGo9J4gO1TE58GjnEmIjomMsKBCym3qWNJfIQXw+9SZCV0DdQNg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-transformer": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.51.1.tgz", + "integrity": "sha512-OppYOXwV9LQqqtYUCywqoOqX/JT9LQ5/FMuPZ//eTkvuHdUC4ZMwz2c6uSoT2R90GWvvGnF1iEqTGyTT3xAt2Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1", + "@opentelemetry/sdk-logs": "0.51.1", + "@opentelemetry/sdk-metrics": "1.24.1", + "@opentelemetry/sdk-trace-base": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.51.1.tgz", + "integrity": "sha512-ULQQtl82b673PpZc5/0EtH4V+BrwVOgKJZEB7tYZnGTG3I98tQVk89S9/JSixomDr++F4ih+LSJTCqIKBz+MQQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.9.0", + "@opentelemetry/api-logs": ">=0.39.1" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-metrics": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.24.1.tgz", + "integrity": "sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz", + "integrity": "sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.24.1.tgz", + "integrity": "sha512-0w+aKRai9VREeo3VrtW+hcbrE2Fl/uKL7G+oXgRNf6pI9QLaEGuEzUTX+oxXVPBadzjOd+5dqCHYdX7UeVjzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/sdk-trace-base": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@hyperdx/otel-web/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@hyperdx/otel-web/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@iconify/types": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", @@ -13242,6 +14098,146 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-document-load": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.38.0.tgz", + "integrity": "sha512-X/AOG8sDcVp/bVGRWDDG7MCRjcmuQwZqG2B2C6/oj8V4koXPNRNDvW2GEIGJhF5/WxJxZsTRIGPG+yeJ52QOww==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.51.0", + "@opentelemetry/sdk-trace-base": "^1.0.0", + "@opentelemetry/sdk-trace-web": "^1.15.0", + "@opentelemetry/semantic-conventions": "^1.22.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-document-load/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation-express": { "version": "0.56.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.56.0.tgz", @@ -13259,6 +14255,162 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-fetch": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.51.1.tgz", + "integrity": "sha512-LzciqAnJmmYaXWo2hlrN99NMbYbExo6n6lBKBeMHAi7X/ddhCSOsgSNVbF3kDB7P++PJhjYqLT3hy6SU4AFHcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/instrumentation": "0.51.1", + "@opentelemetry/sdk-trace-web": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.24.1.tgz", + "integrity": "sha512-0w+aKRai9VREeo3VrtW+hcbrE2Fl/uKL7G+oXgRNf6pI9QLaEGuEzUTX+oxXVPBadzjOd+5dqCHYdX7UeVjzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/sdk-trace-base": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz", + "integrity": "sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-fetch/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation-http": { "version": "0.207.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.207.0.tgz", @@ -13356,6 +14508,268 @@ "@opentelemetry/api": "^1.7.0" } }, + "node_modules/@opentelemetry/instrumentation-user-interaction": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-user-interaction/-/instrumentation-user-interaction-0.38.0.tgz", + "integrity": "sha512-/UZT7zZUpi3WavRW6GmxKSa3d3PQ1ApM9nG9PKq95d4w/zhXBaYiqGT/wzcyXefW4TL2oAq4sjJvt1rZpOlImA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.51.0", + "@opentelemetry/sdk-trace-web": "^1.8.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0", + "zone.js": "^0.11.4 || ^0.13.0 || ^0.14.0" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-user-interaction/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.51.1.tgz", + "integrity": "sha512-CrQZxADNFr9M3aCgjM3/KXDz12lBrZA5LW+btfgNb78hsLNwqxThtFvXOHr86UsOzJt+h9m4yDeH6YLEvCTBbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/instrumentation": "0.51.1", + "@opentelemetry/sdk-trace-web": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/api-logs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz", + "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz", + "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/instrumentation": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz", + "integrity": "sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.51.1", + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.7.4", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.24.1.tgz", + "integrity": "sha512-0w+aKRai9VREeo3VrtW+hcbrE2Fl/uKL7G+oXgRNf6pI9QLaEGuEzUTX+oxXVPBadzjOd+5dqCHYdX7UeVjzwA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/sdk-trace-base": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz", + "integrity": "sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/resources": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", + "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.24.1", + "@opentelemetry/semantic-conventions": "1.24.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", + "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "license": "MIT" + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/import-in-the-middle": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz", + "integrity": "sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, + "node_modules/@opentelemetry/instrumentation-xml-http-request/node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs": { "version": "0.207.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", @@ -13647,6 +15061,80 @@ "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, + "node_modules/@opentelemetry/sdk-trace-web": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.30.1.tgz", + "integrity": "sha512-AUo2e+1uyTGMB36VlbvBqnCogVzQhpC7dRcVVdCrt+cFHLpFRRJcd45J2obGTgs0XiAwNLyq5bhkW3JF2NZA+A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-web/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/semantic-conventions": { "version": "1.39.0", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", @@ -18329,6 +19817,39 @@ "hasInstallScript": true, "license": "Apache-2.0" }, + "node_modules/@sentry/core": { + "version": "8.55.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.55.2.tgz", + "integrity": "sha512-YlEBwybUcOQ/KjMHDmof1vwweVnBtBxYlQp7DE3fOdtW4pqqdHWTnTntQs4VgYfxzjJYgtkd9LHlGtg8qy+JVQ==", + "license": "MIT", + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/types": { + "version": "8.55.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.55.2.tgz", + "integrity": "sha512-6MH7sKopaAY1XAIoOirjkkhHZfH3TBuIyErtUH29jvHcdHQFQPk42vX82jBL6csGB8wbsHCWjrBh6y2KqtaknA==", + "license": "MIT", + "dependencies": { + "@sentry/core": "8.55.2" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/@sentry/utils": { + "version": "8.55.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.55.2.tgz", + "integrity": "sha512-biW6W+/KGaNkNnNlw8yExGM1uQ1+PI+L9Rb99LzJcavm1TGHpmSfGOzqj6y08P6Iw/+JmM2Dj2hvmns2fIwTWw==", + "license": "MIT", + "dependencies": { + "@sentry/core": "8.55.2" + }, + "engines": { + "node": ">=14.18" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -19843,6 +21364,12 @@ "@types/node": "*" } }, + "node_modules/@types/css-font-loading-module": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", + "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==", + "license": "MIT" + }, "node_modules/@types/d3": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", @@ -20274,6 +21801,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -20430,6 +21963,12 @@ "@types/send": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "license": "MIT" + }, "node_modules/@types/sinon": { "version": "17.0.4", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", @@ -21102,6 +22641,12 @@ "node": ">=10.0.0" } }, + "node_modules/@xstate/fsm": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz", + "integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==", + "license": "MIT" + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -22137,6 +23682,15 @@ "bare-path": "^3.0.0" } }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -26677,6 +28231,12 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -30710,6 +32270,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -31558,8 +33124,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -33471,6 +35036,12 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mitt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", + "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", + "license": "MIT" + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -39170,6 +40741,20 @@ "node": ">= 18" } }, + "node_modules/rrweb": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/rrweb/-/rrweb-1.1.3.tgz", + "integrity": "sha512-F2qp8LteJLyycsv+lCVJqtVpery63L3U+/ogqMA0da8R7Jx57o6gT+HpjrzdeeGMIBZR7kKNaKyJwDupTTu5KA==", + "license": "MIT", + "dependencies": { + "@types/css-font-loading-module": "0.0.7", + "@xstate/fsm": "^1.4.0", + "base64-arraybuffer": "^1.0.1", + "fflate": "^0.4.4", + "mitt": "^1.1.3", + "rrweb-snapshot": "^1.1.14" + } + }, "node_modules/rrweb-cssom": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", @@ -39177,6 +40762,18 @@ "dev": true, "license": "MIT" }, + "node_modules/rrweb-snapshot": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-1.1.14.tgz", + "integrity": "sha512-eP5pirNjP5+GewQfcOQY4uBiDnpqxNRc65yKPW0eSoU1XamDfc4M8oqpXGMyUyvLyxFDB0q0+DChuxxiU2FXBQ==", + "license": "MIT" + }, + "node_modules/rrweb/node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==", + "license": "MIT" + }, "node_modules/run-applescript": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", @@ -39587,6 +41184,12 @@ "node": ">=8" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "license": "BSD-2-Clause" + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -42310,6 +43913,12 @@ "node": ">= 8" } }, + "node_modules/web-vitals": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -43465,6 +45074,13 @@ "zod": "^3.25 || ^4" } }, + "node_modules/zone.js": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.10.tgz", + "integrity": "sha512-YGAhaO7J5ywOXW6InXNlLmfU194F8lVgu7bRntUF3TiG8Y3nBK0x1UJJuHUP/e8IyihkjCYqhCScpSwnlaSRkQ==", + "license": "MIT", + "peer": true + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", @@ -44197,6 +45813,7 @@ "typescript": "^5.0.4" }, "peerDependencies": { + "@aws-sdk/credential-providers": "^3.1025.0", "jsonwebtoken": "^9.0.2", "klona": "^2.0.6", "librechat-data-provider": "*", diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index fae3bcd83b7a..0c2afa22b017 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -1058,6 +1058,22 @@ export const turnstileSchema = z.object({ export type TTurnstileConfig = z.infer; +export type TRumConfig = { + provider: 'hyperdx'; + enabled: boolean; + url: string; + serviceName: string; + authMode: 'publicToken' | 'userJwt'; + authHeaderScheme?: 'Bearer' | 'Basic'; + publicToken?: string; + tracePropagationTargets?: string[]; + consoleCapture?: boolean; + disableReplay?: boolean; + advancedNetworkCapture?: boolean; + sampleRate?: number; + environment?: string; +}; + export type TStartupConfig = { appTitle: string; socialLogins?: string[]; @@ -1098,6 +1114,7 @@ export type TStartupConfig = { sharedLinksEnabled: boolean; publicSharedLinksEnabled: boolean; analyticsGtmId?: string; + rum?: TRumConfig; bundlerURL?: string; staticBundlerURL?: string; sharePointFilePickerEnabled?: boolean;