{"version":3,"file":"spotlight.js","sources":["../../../src/integrations/spotlight.ts"],"sourcesContent":["import * as http from 'node:http';\nimport { defineIntegration } from '@sentry/core';\nimport type { Client, Envelope, IntegrationFn } from '@sentry/types';\nimport { logger, serializeEnvelope } from '@sentry/utils';\n\ntype SpotlightConnectionOptions = {\n /**\n * Set this if the Spotlight Sidecar is not running on localhost:8969\n * By default, the Url is set to http://localhost:8969/stream\n */\n sidecarUrl?: string;\n};\n\nexport const INTEGRATION_NAME = 'Spotlight';\n\nconst _spotlightIntegration = ((options: Partial = {}) => {\n const _options = {\n sidecarUrl: options.sidecarUrl || 'http://localhost:8969/stream',\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n if (typeof process === 'object' && process.env && process.env.NODE_ENV !== 'development') {\n logger.warn(\"[Spotlight] It seems you're not in dev mode. Do you really want to have Spotlight enabled?\");\n }\n connectToSpotlight(client, _options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Use this integration to send errors and transactions to Spotlight.\n *\n * Learn more about spotlight at https://spotlightjs.com\n *\n * Important: This integration only works with Node 18 or newer.\n */\nexport const spotlightIntegration = defineIntegration(_spotlightIntegration);\n\nfunction connectToSpotlight(client: Client, options: Required): void {\n const spotlightUrl = parseSidecarUrl(options.sidecarUrl);\n if (!spotlightUrl) {\n return;\n }\n\n let failedRequests = 0;\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (failedRequests > 3) {\n logger.warn('[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests');\n return;\n }\n\n const serializedEnvelope = serializeEnvelope(envelope);\n\n const request = getNativeHttpRequest();\n const req = request(\n {\n method: 'POST',\n path: spotlightUrl.pathname,\n hostname: spotlightUrl.hostname,\n port: spotlightUrl.port,\n headers: {\n 'Content-Type': 'application/x-sentry-envelope',\n },\n },\n res => {\n if (res.statusCode && res.statusCode >= 200 && res.statusCode < 400) {\n // Reset failed requests counter on success\n failedRequests = 0;\n }\n res.on('data', () => {\n // Drain socket\n });\n\n res.on('end', () => {\n // Drain socket\n });\n res.setEncoding('utf8');\n },\n );\n\n req.on('error', () => {\n failedRequests++;\n logger.warn('[Spotlight] Failed to send envelope to Spotlight Sidecar');\n });\n req.write(serializedEnvelope);\n req.end();\n });\n}\n\nfunction parseSidecarUrl(url: string): URL | undefined {\n try {\n return new URL(`${url}`);\n } catch {\n logger.warn(`[Spotlight] Invalid sidecar URL: ${url}`);\n return undefined;\n }\n}\n\ntype HttpRequestImpl = typeof http.request;\ntype WrappedHttpRequest = HttpRequestImpl & { __sentry_original__: HttpRequestImpl };\n\n/**\n * We want to get an unpatched http request implementation to avoid capturing our own calls.\n */\nexport function getNativeHttpRequest(): HttpRequestImpl {\n const { request } = http;\n if (isWrapped(request)) {\n return request.__sentry_original__;\n }\n\n return request;\n}\n\nfunction isWrapped(impl: HttpRequestImpl): impl is WrappedHttpRequest {\n return '__sentry_original__' in impl;\n}\n"],"names":[],"mappings":"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"}