@sentry/core 10.38.0 → 10.39.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/build/cjs/attributes.js.map +1 -1
  2. package/build/cjs/client.js +22 -12
  3. package/build/cjs/client.js.map +1 -1
  4. package/build/cjs/envelope.js +41 -7
  5. package/build/cjs/envelope.js.map +1 -1
  6. package/build/cjs/index.js +52 -0
  7. package/build/cjs/index.js.map +1 -1
  8. package/build/cjs/integration.js +12 -0
  9. package/build/cjs/integration.js.map +1 -1
  10. package/build/cjs/integrations/eventFilters.js +1 -1
  11. package/build/cjs/integrations/eventFilters.js.map +1 -1
  12. package/build/cjs/integrations/mcp-server/correlation.js +54 -10
  13. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  14. package/build/cjs/integrations/mcp-server/sessionManagement.js +50 -16
  15. package/build/cjs/integrations/mcp-server/sessionManagement.js.map +1 -1
  16. package/build/cjs/integrations/requestdata.js +72 -6
  17. package/build/cjs/integrations/requestdata.js.map +1 -1
  18. package/build/cjs/integrations/spanStreaming.js +54 -0
  19. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  20. package/build/cjs/metrics/public-api.js +3 -3
  21. package/build/cjs/metrics/public-api.js.map +1 -1
  22. package/build/cjs/scope.js +1 -1
  23. package/build/cjs/scope.js.map +1 -1
  24. package/build/cjs/semanticAttributes.js +84 -0
  25. package/build/cjs/semanticAttributes.js.map +1 -1
  26. package/build/cjs/spans/captureSpan.js +104 -0
  27. package/build/cjs/spans/captureSpan.js.map +1 -0
  28. package/build/cjs/spans/spanBuffer.js +121 -0
  29. package/build/cjs/spans/spanBuffer.js.map +1 -0
  30. package/build/cjs/spans/spanFirstUtils.js +186 -0
  31. package/build/cjs/spans/spanFirstUtils.js.map +1 -0
  32. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  33. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  34. package/build/cjs/tracing/openai/index.js +134 -51
  35. package/build/cjs/tracing/openai/index.js.map +1 -1
  36. package/build/cjs/tracing/sentrySpan.js +32 -0
  37. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  38. package/build/cjs/tracing/trace.js +1 -0
  39. package/build/cjs/tracing/trace.js.map +1 -1
  40. package/build/cjs/tracing/vercel-ai/constants.js +4 -0
  41. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  42. package/build/cjs/tracing/vercel-ai/index.js +14 -0
  43. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  44. package/build/cjs/tracing/vercel-ai/utils.js +71 -22
  45. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  46. package/build/cjs/transports/base.js +18 -2
  47. package/build/cjs/transports/base.js.map +1 -1
  48. package/build/cjs/transports/offline.js +16 -17
  49. package/build/cjs/transports/offline.js.map +1 -1
  50. package/build/cjs/utils/beforeSendSpan.js +36 -0
  51. package/build/cjs/utils/beforeSendSpan.js.map +1 -0
  52. package/build/cjs/utils/envToBool.js +32 -0
  53. package/build/cjs/utils/envToBool.js.map +1 -0
  54. package/build/cjs/utils/featureFlags.js +1 -0
  55. package/build/cjs/utils/featureFlags.js.map +1 -1
  56. package/build/cjs/utils/flushIfServerless.js.map +1 -1
  57. package/build/cjs/utils/hasSpanStreamingEnabled.js +21 -0
  58. package/build/cjs/utils/hasSpanStreamingEnabled.js.map +1 -0
  59. package/build/cjs/utils/prepareEvent.js +6 -1
  60. package/build/cjs/utils/prepareEvent.js.map +1 -1
  61. package/build/cjs/utils/promisebuffer.js +5 -3
  62. package/build/cjs/utils/promisebuffer.js.map +1 -1
  63. package/build/cjs/utils/scopeData.js +4 -0
  64. package/build/cjs/utils/scopeData.js.map +1 -1
  65. package/build/cjs/utils/sdkMetadata.js +7 -11
  66. package/build/cjs/utils/sdkMetadata.js.map +1 -1
  67. package/build/cjs/utils/should-ignore-span.js +31 -9
  68. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  69. package/build/cjs/utils/spanUtils.js +90 -2
  70. package/build/cjs/utils/spanUtils.js.map +1 -1
  71. package/build/cjs/utils/timer.js +20 -0
  72. package/build/cjs/utils/timer.js.map +1 -0
  73. package/build/cjs/utils/tracePropagationTargets.js +38 -0
  74. package/build/cjs/utils/tracePropagationTargets.js.map +1 -0
  75. package/build/cjs/utils/version.js +1 -1
  76. package/build/cjs/utils/version.js.map +1 -1
  77. package/build/esm/attributes.js.map +1 -1
  78. package/build/esm/client.js +18 -8
  79. package/build/esm/client.js.map +1 -1
  80. package/build/esm/envelope.js +41 -8
  81. package/build/esm/envelope.js.map +1 -1
  82. package/build/esm/index.js +12 -3
  83. package/build/esm/index.js.map +1 -1
  84. package/build/esm/integration.js +12 -1
  85. package/build/esm/integration.js.map +1 -1
  86. package/build/esm/integrations/eventFilters.js +1 -1
  87. package/build/esm/integrations/eventFilters.js.map +1 -1
  88. package/build/esm/integrations/mcp-server/correlation.js +54 -10
  89. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  90. package/build/esm/integrations/mcp-server/sessionManagement.js +50 -16
  91. package/build/esm/integrations/mcp-server/sessionManagement.js.map +1 -1
  92. package/build/esm/integrations/requestdata.js +72 -6
  93. package/build/esm/integrations/requestdata.js.map +1 -1
  94. package/build/esm/integrations/spanStreaming.js +52 -0
  95. package/build/esm/integrations/spanStreaming.js.map +1 -0
  96. package/build/esm/metrics/public-api.js +3 -3
  97. package/build/esm/metrics/public-api.js.map +1 -1
  98. package/build/esm/package.json +1 -1
  99. package/build/esm/scope.js +1 -1
  100. package/build/esm/scope.js.map +1 -1
  101. package/build/esm/semanticAttributes.js +57 -1
  102. package/build/esm/semanticAttributes.js.map +1 -1
  103. package/build/esm/spans/captureSpan.js +102 -0
  104. package/build/esm/spans/captureSpan.js.map +1 -0
  105. package/build/esm/spans/spanBuffer.js +119 -0
  106. package/build/esm/spans/spanBuffer.js.map +1 -0
  107. package/build/esm/spans/spanFirstUtils.js +182 -0
  108. package/build/esm/spans/spanFirstUtils.js.map +1 -0
  109. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  110. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  111. package/build/esm/tracing/openai/index.js +134 -51
  112. package/build/esm/tracing/openai/index.js.map +1 -1
  113. package/build/esm/tracing/sentrySpan.js +33 -1
  114. package/build/esm/tracing/sentrySpan.js.map +1 -1
  115. package/build/esm/tracing/trace.js +1 -0
  116. package/build/esm/tracing/trace.js.map +1 -1
  117. package/build/esm/tracing/vercel-ai/constants.js +4 -1
  118. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  119. package/build/esm/tracing/vercel-ai/index.js +15 -1
  120. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  121. package/build/esm/tracing/vercel-ai/utils.js +73 -24
  122. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  123. package/build/esm/transports/base.js +18 -2
  124. package/build/esm/transports/base.js.map +1 -1
  125. package/build/esm/transports/offline.js +16 -17
  126. package/build/esm/transports/offline.js.map +1 -1
  127. package/build/esm/utils/beforeSendSpan.js +33 -0
  128. package/build/esm/utils/beforeSendSpan.js.map +1 -0
  129. package/build/esm/utils/envToBool.js +28 -0
  130. package/build/esm/utils/envToBool.js.map +1 -0
  131. package/build/esm/utils/featureFlags.js +1 -0
  132. package/build/esm/utils/featureFlags.js.map +1 -1
  133. package/build/esm/utils/flushIfServerless.js.map +1 -1
  134. package/build/esm/utils/hasSpanStreamingEnabled.js +19 -0
  135. package/build/esm/utils/hasSpanStreamingEnabled.js.map +1 -0
  136. package/build/esm/utils/prepareEvent.js +6 -1
  137. package/build/esm/utils/prepareEvent.js.map +1 -1
  138. package/build/esm/utils/promisebuffer.js +5 -3
  139. package/build/esm/utils/promisebuffer.js.map +1 -1
  140. package/build/esm/utils/scopeData.js +4 -0
  141. package/build/esm/utils/scopeData.js.map +1 -1
  142. package/build/esm/utils/sdkMetadata.js +7 -11
  143. package/build/esm/utils/sdkMetadata.js.map +1 -1
  144. package/build/esm/utils/should-ignore-span.js +31 -9
  145. package/build/esm/utils/should-ignore-span.js.map +1 -1
  146. package/build/esm/utils/spanUtils.js +87 -3
  147. package/build/esm/utils/spanUtils.js.map +1 -1
  148. package/build/esm/utils/timer.js +18 -0
  149. package/build/esm/utils/timer.js.map +1 -0
  150. package/build/esm/utils/tracePropagationTargets.js +36 -0
  151. package/build/esm/utils/tracePropagationTargets.js.map +1 -0
  152. package/build/esm/utils/version.js +1 -1
  153. package/build/esm/utils/version.js.map +1 -1
  154. package/build/types/attributes.d.ts +1 -1
  155. package/build/types/attributes.d.ts.map +1 -1
  156. package/build/types/client.d.ts +40 -2
  157. package/build/types/client.d.ts.map +1 -1
  158. package/build/types/envelope.d.ts +6 -1
  159. package/build/types/envelope.d.ts.map +1 -1
  160. package/build/types/index.d.ts +13 -4
  161. package/build/types/index.d.ts.map +1 -1
  162. package/build/types/integration.d.ts +4 -0
  163. package/build/types/integration.d.ts.map +1 -1
  164. package/build/types/integrations/mcp-server/correlation.d.ts +6 -2
  165. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  166. package/build/types/integrations/mcp-server/sessionManagement.d.ts +8 -2
  167. package/build/types/integrations/mcp-server/sessionManagement.d.ts.map +1 -1
  168. package/build/types/integrations/requestdata.d.ts.map +1 -1
  169. package/build/types/integrations/spanStreaming.d.ts +11 -0
  170. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  171. package/build/types/metrics/public-api.d.ts +3 -3
  172. package/build/types/semanticAttributes.d.ts +38 -0
  173. package/build/types/semanticAttributes.d.ts.map +1 -1
  174. package/build/types/spans/captureSpan.d.ts +10 -0
  175. package/build/types/spans/captureSpan.d.ts.map +1 -0
  176. package/build/types/spans/spanBuffer.d.ts +35 -0
  177. package/build/types/spans/spanBuffer.d.ts.map +1 -0
  178. package/build/types/spans/spanFirstUtils.d.ts +20 -0
  179. package/build/types/spans/spanFirstUtils.d.ts.map +1 -0
  180. package/build/types/tracing/ai/gen-ai-attributes.d.ts +4 -0
  181. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  182. package/build/types/tracing/openai/index.d.ts.map +1 -1
  183. package/build/types/tracing/sentrySpan.d.ts +10 -1
  184. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  185. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  186. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  187. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  188. package/build/types/tracing/vercel-ai/utils.d.ts +2 -2
  189. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  190. package/build/types/transports/base.d.ts.map +1 -1
  191. package/build/types/transports/offline.d.ts.map +1 -1
  192. package/build/types/types-hoist/attributes.d.ts +19 -0
  193. package/build/types/types-hoist/attributes.d.ts.map +1 -0
  194. package/build/types/types-hoist/envelope.d.ts +22 -2
  195. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  196. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  197. package/build/types/types-hoist/integration.d.ts +7 -0
  198. package/build/types/types-hoist/integration.d.ts.map +1 -1
  199. package/build/types/types-hoist/link.d.ts +2 -2
  200. package/build/types/types-hoist/link.d.ts.map +1 -1
  201. package/build/types/types-hoist/options.d.ts +18 -2
  202. package/build/types/types-hoist/options.d.ts.map +1 -1
  203. package/build/types/types-hoist/span.d.ts +27 -0
  204. package/build/types/types-hoist/span.d.ts.map +1 -1
  205. package/build/types/utils/beforeSendSpan.d.ts +22 -0
  206. package/build/types/utils/beforeSendSpan.d.ts.map +1 -0
  207. package/build/types/utils/envToBool.d.ts +13 -0
  208. package/build/types/utils/envToBool.d.ts.map +1 -0
  209. package/build/types/utils/featureFlags.d.ts.map +1 -1
  210. package/build/types/utils/flushIfServerless.d.ts.map +1 -1
  211. package/build/types/utils/hasSpanStreamingEnabled.d.ts +9 -0
  212. package/build/types/utils/hasSpanStreamingEnabled.d.ts.map +1 -0
  213. package/build/types/utils/prepareEvent.d.ts.map +1 -1
  214. package/build/types/utils/promisebuffer.d.ts.map +1 -1
  215. package/build/types/utils/scopeData.d.ts.map +1 -1
  216. package/build/types/utils/sdkMetadata.d.ts.map +1 -1
  217. package/build/types/utils/should-ignore-span.d.ts +3 -3
  218. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  219. package/build/types/utils/spanUtils.d.ts +22 -2
  220. package/build/types/utils/spanUtils.d.ts.map +1 -1
  221. package/build/types/utils/timer.d.ts +11 -0
  222. package/build/types/utils/timer.d.ts.map +1 -0
  223. package/build/types/utils/tracePropagationTargets.d.ts +9 -0
  224. package/build/types/utils/tracePropagationTargets.d.ts.map +1 -0
  225. package/build/types-ts3.8/attributes.d.ts +1 -1
  226. package/build/types-ts3.8/client.d.ts +40 -2
  227. package/build/types-ts3.8/envelope.d.ts +6 -1
  228. package/build/types-ts3.8/index.d.ts +13 -4
  229. package/build/types-ts3.8/integration.d.ts +4 -0
  230. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +6 -2
  231. package/build/types-ts3.8/integrations/mcp-server/sessionManagement.d.ts +8 -2
  232. package/build/types-ts3.8/integrations/spanStreaming.d.ts +11 -0
  233. package/build/types-ts3.8/metrics/public-api.d.ts +3 -3
  234. package/build/types-ts3.8/semanticAttributes.d.ts +38 -0
  235. package/build/types-ts3.8/spans/captureSpan.d.ts +10 -0
  236. package/build/types-ts3.8/spans/spanBuffer.d.ts +35 -0
  237. package/build/types-ts3.8/spans/spanFirstUtils.d.ts +20 -0
  238. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +4 -0
  239. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  240. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  241. package/build/types-ts3.8/tracing/vercel-ai/utils.d.ts +2 -2
  242. package/build/types-ts3.8/types-hoist/attributes.d.ts +19 -0
  243. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  244. package/build/types-ts3.8/types-hoist/integration.d.ts +7 -0
  245. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  246. package/build/types-ts3.8/types-hoist/options.d.ts +18 -2
  247. package/build/types-ts3.8/types-hoist/span.d.ts +27 -0
  248. package/build/types-ts3.8/utils/beforeSendSpan.d.ts +22 -0
  249. package/build/types-ts3.8/utils/envToBool.d.ts +13 -0
  250. package/build/types-ts3.8/utils/hasSpanStreamingEnabled.d.ts +9 -0
  251. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -3
  252. package/build/types-ts3.8/utils/spanUtils.d.ts +22 -2
  253. package/build/types-ts3.8/utils/timer.d.ts +11 -0
  254. package/build/types-ts3.8/utils/tracePropagationTargets.d.ts +9 -0
  255. package/package.json +1 -1
@@ -9,8 +9,8 @@ export { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromScope
9
9
  export { setMeasurement, timedEventsToMeasurements } from './tracing/measurement.js';
10
10
  export { sampleSpan } from './tracing/sampling.js';
11
11
  export { logSpanEnd, logSpanStart } from './tracing/logSpans.js';
12
- export { GEN_AI_CONVERSATION_ID_ATTRIBUTE, SEMANTIC_ATTRIBUTE_CACHE_HIT, SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, SEMANTIC_ATTRIBUTE_CACHE_KEY, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_PROFILE_ID, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_URL_FULL, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE } from './semanticAttributes.js';
13
- export { createEventEnvelope, createSessionEnvelope, createSpanEnvelope } from './envelope.js';
12
+ export { GEN_AI_CONVERSATION_ID_ATTRIBUTE, SEMANTIC_ATTRIBUTE_BROWSER_CONNECTION_RTT, SEMANTIC_ATTRIBUTE_CACHE_HIT, SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, SEMANTIC_ATTRIBUTE_CACHE_KEY, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_TIME_TO_FIRST_BYTE, SEMANTIC_ATTRIBUTE_PROFILE_ID, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_RELEASE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID, SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_SPAN_SOURCE, SEMANTIC_ATTRIBUTE_URL_FULL, SEMANTIC_ATTRIBUTE_URL_QUERY, SEMANTIC_ATTRIBUTE_USER_EMAIL, SEMANTIC_ATTRIBUTE_USER_ID, SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, SEMANTIC_ATTRIBUTE_USER_USERNAME, SEMANTIC_ATTRIBUTE_WEB_VITAL_CLS_SOURCES, SEMANTIC_ATTRIBUTE_WEB_VITAL_CLS_VALUE, SEMANTIC_ATTRIBUTE_WEB_VITAL_FCP_VALUE, SEMANTIC_ATTRIBUTE_WEB_VITAL_FP_VALUE, SEMANTIC_ATTRIBUTE_WEB_VITAL_INP_VALUE, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_ELEMENT, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_ID, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_LOAD_TIME, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_RENDER_TIME, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_SIZE, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_URL, SEMANTIC_ATTRIBUTE_WEB_VITAL_LCP_VALUE, SEMANTIC_ATTRIBUTE_WEB_VITAL_TTFB_REQUEST_TIME, SEMANTIC_ATTRIBUTE_WEB_VITAL_TTFB_VALUE, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE } from './semanticAttributes.js';
13
+ export { createEventEnvelope, createSessionEnvelope, createSpanEnvelope, createSpanV2Envelope } from './envelope.js';
14
14
  export { addEventProcessor, captureCheckIn, captureEvent, captureException, captureMessage, captureSession, close, endSession, flush, isEnabled, isInitialized, lastEventId, setContext, setConversationId, setExtra, setExtras, setTag, setTags, setUser, startSession, withMonitor } from './exports.js';
15
15
  export { getClient, getCurrentScope, getGlobalScope, getIsolationScope, getTraceContextFromScope, withIsolationScope, withScope } from './currentScopes.js';
16
16
  export { getDefaultCurrentScope, getDefaultIsolationScope } from './defaultScopes.js';
@@ -28,19 +28,25 @@ export { makeOfflineTransport } from './transports/offline.js';
28
28
  export { MULTIPLEXED_TRANSPORT_EXTRA_KEY, makeMultiplexedTransport } from './transports/multiplexed.js';
29
29
  export { addIntegration, defineIntegration, getIntegrationsToSetup, installedIntegrations } from './integration.js';
30
30
  export { _INTERNAL_clearAiProviderSkips, _INTERNAL_shouldSkipAiProviderWrapping, _INTERNAL_skipAiProviderWrapping } from './utils/ai/providerSkip.js';
31
+ export { envToBool } from './utils/envToBool.js';
31
32
  export { applyScopeDataToEvent, getCombinedScopeData, mergeScopeData } from './utils/scopeData.js';
32
33
  export { prepareEvent } from './utils/prepareEvent.js';
33
34
  export { createCheckInEnvelope } from './checkin.js';
34
35
  export { hasSpansEnabled } from './utils/hasSpansEnabled.js';
36
+ export { hasSpanStreamingEnabled } from './utils/hasSpanStreamingEnabled.js';
35
37
  export { isSentryRequestUrl } from './utils/isSentryRequestUrl.js';
36
38
  export { handleCallbackErrors } from './utils/handleCallbackErrors.js';
37
39
  export { fmt, parameterize } from './utils/parameterize.js';
38
40
  export { addAutoIpAddressToSession, addAutoIpAddressToUser } from './utils/ipAddress.js';
39
- export { addChildSpanToSpan, convertSpanLinksForEnvelope, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, updateSpanName } from './utils/spanUtils.js';
41
+ export { INTERNAL_getSegmentSpan, addChildSpanToSpan, convertSpanLinksForEnvelope, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, showSpanDropWarning, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, spanToV2JSON, updateSpanName } from './utils/spanUtils.js';
42
+ export { captureSpan } from './spans/captureSpan.js';
43
+ export { safeSetSpanJSONAttributes } from './spans/spanFirstUtils.js';
44
+ export { SpanBuffer } from './spans/spanBuffer.js';
40
45
  export { _setSpanForScope as _INTERNAL_setSpanForScope } from './utils/spanOnScope.js';
41
46
  export { parseSampleRate } from './utils/parseSampleRate.js';
42
47
  export { applySdkMetadata } from './utils/sdkMetadata.js';
43
48
  export { getTraceData } from './utils/traceData.js';
49
+ export { shouldPropagateTraceForUrl } from './utils/tracePropagationTargets.js';
44
50
  export { getTraceMetaTags } from './utils/meta.js';
45
51
  export { debounce } from './utils/debounce.js';
46
52
  export { extractQueryParamsFromUrl, headersToDict, httpHeadersToSpanAttributes, httpRequestToRequestData, winterCGHeadersToDict, winterCGRequestToRequestData } from './utils/request.js';
@@ -62,6 +68,7 @@ export { consoleIntegration } from './integrations/console.js';
62
68
  export { featureFlagsIntegration } from './integrations/featureFlags/featureFlagsIntegration.js';
63
69
  export { growthbookIntegration } from './integrations/featureFlags/growthbook.js';
64
70
  export { conversationIdIntegration } from './integrations/conversationId.js';
71
+ export { spanStreamingIntegration } from './integrations/spanStreaming.js';
65
72
  export { profiler } from './profiling.js';
66
73
  export { instrumentFetchRequest } from './fetch.js';
67
74
  export { trpcMiddleware } from './trpc.js';
@@ -133,5 +140,7 @@ export { SDK_VERSION } from './utils/version.js';
133
140
  export { getDebugImagesForResources, getFilenameToDebugIdMap } from './utils/debug-ids.js';
134
141
  export { getFilenameToMetadataMap } from './metadata.js';
135
142
  export { escapeStringForRegex } from './vendor/escapeStringForRegex.js';
143
+ export { isV2BeforeSendSpanCallback, withStreamSpan } from './utils/beforeSendSpan.js';
144
+ export { reparentChildSpans, shouldIgnoreSpan } from './utils/should-ignore-span.js';
136
145
  export { safeDateNow as _INTERNAL_safeDateNow, safeMathRandom as _INTERNAL_safeMathRandom, withRandomSafeContext as _INTERNAL_withRandomSafeContext } from './utils/randomSafeContext.js';
137
146
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -77,6 +77,17 @@ function setupIntegrations(client, integrations) {
77
77
  return integrationIndex;
78
78
  }
79
79
 
80
+ /**
81
+ * Runs the `beforeSetup` hooks of the given integrations on the given client.
82
+ */
83
+ function beforeSetupIntegrations(client, integrations) {
84
+ for (const integration of integrations) {
85
+ if (integration?.beforeSetup) {
86
+ integration.beforeSetup(client);
87
+ }
88
+ }
89
+ }
90
+
80
91
  /**
81
92
  * Execute the `afterAllSetup` hooks of the given integrations.
82
93
  */
@@ -146,5 +157,5 @@ function defineIntegration(fn) {
146
157
  return fn;
147
158
  }
148
159
 
149
- export { addIntegration, afterSetupIntegrations, defineIntegration, getIntegrationsToSetup, installedIntegrations, setupIntegration, setupIntegrations };
160
+ export { addIntegration, afterSetupIntegrations, beforeSetupIntegrations, defineIntegration, getIntegrationsToSetup, installedIntegrations, setupIntegration, setupIntegrations };
150
161
  //# sourceMappingURL=integration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../src/integration.ts"],"sourcesContent":["import type { Client } from './client';\nimport { getClient } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { Integration, IntegrationFn } from './types-hoist/integration';\nimport type { CoreOptions } from './types-hoist/options';\nimport { debug } from './utils/debug-logger';\n\nexport const installedIntegrations: string[] = [];\n\n/** Map of integrations assigned to a client */\nexport type IntegrationIndex = {\n [key: string]: Integration;\n};\n\ntype IntegrationWithDefaultInstance = Integration & { isDefaultInstance?: true };\n\n/**\n * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to\n * preserve the order of integrations in the array.\n *\n * @private\n */\nfunction filterDuplicates(integrations: Integration[]): Integration[] {\n const integrationsByName: { [key: string]: Integration } = {};\n\n integrations.forEach((currentInstance: IntegrationWithDefaultInstance) => {\n const { name } = currentInstance;\n\n const existingInstance: IntegrationWithDefaultInstance | undefined = integrationsByName[name];\n\n // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a\n // default instance to overwrite an existing user instance\n if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {\n return;\n }\n\n integrationsByName[name] = currentInstance;\n });\n\n return Object.values(integrationsByName);\n}\n\n/** Gets integrations to install */\nexport function getIntegrationsToSetup(\n options: Pick<CoreOptions, 'defaultIntegrations' | 'integrations'>,\n): Integration[] {\n const defaultIntegrations = options.defaultIntegrations || [];\n const userIntegrations = options.integrations;\n\n // We flag default instances, so that later we can tell them apart from any user-created instances of the same class\n defaultIntegrations.forEach((integration: IntegrationWithDefaultInstance) => {\n integration.isDefaultInstance = true;\n });\n\n let integrations: Integration[];\n\n if (Array.isArray(userIntegrations)) {\n integrations = [...defaultIntegrations, ...userIntegrations];\n } else if (typeof userIntegrations === 'function') {\n const resolvedUserIntegrations = userIntegrations(defaultIntegrations);\n integrations = Array.isArray(resolvedUserIntegrations) ? resolvedUserIntegrations : [resolvedUserIntegrations];\n } else {\n integrations = defaultIntegrations;\n }\n\n return filterDuplicates(integrations);\n}\n\n/**\n * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default\n * integrations are added unless they were already provided before.\n * @param integrations array of integration instances\n * @param withDefault should enable default integrations\n */\nexport function setupIntegrations(client: Client, integrations: Integration[]): IntegrationIndex {\n const integrationIndex: IntegrationIndex = {};\n\n integrations.forEach((integration: Integration | undefined) => {\n // guard against empty provided integrations\n if (integration) {\n setupIntegration(client, integration, integrationIndex);\n }\n });\n\n return integrationIndex;\n}\n\n/**\n * Execute the `afterAllSetup` hooks of the given integrations.\n */\nexport function afterSetupIntegrations(client: Client, integrations: Integration[]): void {\n for (const integration of integrations) {\n // guard against empty provided integrations\n if (integration?.afterAllSetup) {\n integration.afterAllSetup(client);\n }\n }\n}\n\n/** Setup a single integration. */\nexport function setupIntegration(client: Client, integration: Integration, integrationIndex: IntegrationIndex): void {\n if (integrationIndex[integration.name]) {\n DEBUG_BUILD && debug.log(`Integration skipped because it was already installed: ${integration.name}`);\n return;\n }\n integrationIndex[integration.name] = integration;\n\n // `setupOnce` is only called the first time\n if (!installedIntegrations.includes(integration.name) && typeof integration.setupOnce === 'function') {\n integration.setupOnce();\n installedIntegrations.push(integration.name);\n }\n\n // `setup` is run for each client\n if (integration.setup && typeof integration.setup === 'function') {\n integration.setup(client);\n }\n\n if (typeof integration.preprocessEvent === 'function') {\n const callback = integration.preprocessEvent.bind(integration) as typeof integration.preprocessEvent;\n client.on('preprocessEvent', (event, hint) => callback(event, hint, client));\n }\n\n if (typeof integration.processEvent === 'function') {\n const callback = integration.processEvent.bind(integration) as typeof integration.processEvent;\n\n const processor = Object.assign((event: Event, hint: EventHint) => callback(event, hint, client), {\n id: integration.name,\n });\n\n client.addEventProcessor(processor);\n }\n\n DEBUG_BUILD && debug.log(`Integration installed: ${integration.name}`);\n}\n\n/** Add an integration to the current scope's client. */\nexport function addIntegration(integration: Integration): void {\n const client = getClient();\n\n if (!client) {\n DEBUG_BUILD && debug.warn(`Cannot add integration \"${integration.name}\" because no SDK Client is available.`);\n return;\n }\n\n client.addIntegration(integration);\n}\n\n/**\n * Define an integration function that can be used to create an integration instance.\n * Note that this by design hides the implementation details of the integration, as they are considered internal.\n */\nexport function defineIntegration<Fn extends IntegrationFn>(fn: Fn): (...args: Parameters<Fn>) => Integration {\n return fn;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration.js","sources":["../../src/integration.ts"],"sourcesContent":["import type { Client } from './client';\nimport { getClient } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { Integration, IntegrationFn } from './types-hoist/integration';\nimport type { CoreOptions } from './types-hoist/options';\nimport { debug } from './utils/debug-logger';\n\nexport const installedIntegrations: string[] = [];\n\n/** Map of integrations assigned to a client */\nexport type IntegrationIndex = {\n [key: string]: Integration;\n};\n\ntype IntegrationWithDefaultInstance = Integration & { isDefaultInstance?: true };\n\n/**\n * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to\n * preserve the order of integrations in the array.\n *\n * @private\n */\nfunction filterDuplicates(integrations: Integration[]): Integration[] {\n const integrationsByName: { [key: string]: Integration } = {};\n\n integrations.forEach((currentInstance: IntegrationWithDefaultInstance) => {\n const { name } = currentInstance;\n\n const existingInstance: IntegrationWithDefaultInstance | undefined = integrationsByName[name];\n\n // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a\n // default instance to overwrite an existing user instance\n if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {\n return;\n }\n\n integrationsByName[name] = currentInstance;\n });\n\n return Object.values(integrationsByName);\n}\n\n/** Gets integrations to install */\nexport function getIntegrationsToSetup(\n options: Pick<CoreOptions, 'defaultIntegrations' | 'integrations'>,\n): Integration[] {\n const defaultIntegrations = options.defaultIntegrations || [];\n const userIntegrations = options.integrations;\n\n // We flag default instances, so that later we can tell them apart from any user-created instances of the same class\n defaultIntegrations.forEach((integration: IntegrationWithDefaultInstance) => {\n integration.isDefaultInstance = true;\n });\n\n let integrations: Integration[];\n\n if (Array.isArray(userIntegrations)) {\n integrations = [...defaultIntegrations, ...userIntegrations];\n } else if (typeof userIntegrations === 'function') {\n const resolvedUserIntegrations = userIntegrations(defaultIntegrations);\n integrations = Array.isArray(resolvedUserIntegrations) ? resolvedUserIntegrations : [resolvedUserIntegrations];\n } else {\n integrations = defaultIntegrations;\n }\n\n return filterDuplicates(integrations);\n}\n\n/**\n * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default\n * integrations are added unless they were already provided before.\n * @param integrations array of integration instances\n * @param withDefault should enable default integrations\n */\nexport function setupIntegrations(client: Client, integrations: Integration[]): IntegrationIndex {\n const integrationIndex: IntegrationIndex = {};\n\n integrations.forEach((integration: Integration | undefined) => {\n // guard against empty provided integrations\n if (integration) {\n setupIntegration(client, integration, integrationIndex);\n }\n });\n\n return integrationIndex;\n}\n\n/**\n * Runs the `beforeSetup` hooks of the given integrations on the given client.\n */\nexport function beforeSetupIntegrations(client: Client, integrations: Integration[]): void {\n for (const integration of integrations) {\n if (integration?.beforeSetup) {\n integration.beforeSetup(client);\n }\n }\n}\n\n/**\n * Execute the `afterAllSetup` hooks of the given integrations.\n */\nexport function afterSetupIntegrations(client: Client, integrations: Integration[]): void {\n for (const integration of integrations) {\n // guard against empty provided integrations\n if (integration?.afterAllSetup) {\n integration.afterAllSetup(client);\n }\n }\n}\n\n/** Setup a single integration. */\nexport function setupIntegration(client: Client, integration: Integration, integrationIndex: IntegrationIndex): void {\n if (integrationIndex[integration.name]) {\n DEBUG_BUILD && debug.log(`Integration skipped because it was already installed: ${integration.name}`);\n return;\n }\n integrationIndex[integration.name] = integration;\n\n // `setupOnce` is only called the first time\n if (!installedIntegrations.includes(integration.name) && typeof integration.setupOnce === 'function') {\n integration.setupOnce();\n installedIntegrations.push(integration.name);\n }\n\n // `setup` is run for each client\n if (integration.setup && typeof integration.setup === 'function') {\n integration.setup(client);\n }\n\n if (typeof integration.preprocessEvent === 'function') {\n const callback = integration.preprocessEvent.bind(integration) as typeof integration.preprocessEvent;\n client.on('preprocessEvent', (event, hint) => callback(event, hint, client));\n }\n\n if (typeof integration.processEvent === 'function') {\n const callback = integration.processEvent.bind(integration) as typeof integration.processEvent;\n\n const processor = Object.assign((event: Event, hint: EventHint) => callback(event, hint, client), {\n id: integration.name,\n });\n\n client.addEventProcessor(processor);\n }\n\n DEBUG_BUILD && debug.log(`Integration installed: ${integration.name}`);\n}\n\n/** Add an integration to the current scope's client. */\nexport function addIntegration(integration: Integration): void {\n const client = getClient();\n\n if (!client) {\n DEBUG_BUILD && debug.warn(`Cannot add integration \"${integration.name}\" because no SDK Client is available.`);\n return;\n }\n\n client.addIntegration(integration);\n}\n\n/**\n * Define an integration function that can be used to create an integration instance.\n * Note that this by design hides the implementation details of the integration, as they are considered internal.\n */\nexport function defineIntegration<Fn extends IntegrationFn>(fn: Fn): (...args: Parameters<Fn>) => Integration {\n return fn;\n}\n"],"names":[],"mappings":"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"}
@@ -134,7 +134,7 @@ function _shouldDropEvent(event, options) {
134
134
  }
135
135
  } else if (event.type === 'transaction') {
136
136
  // Filter transactions
137
-
137
+ // TODO (span-streaming): replace with ignoreSpans defaults (if we have any)
138
138
  if (_isIgnoredTransaction(event, options.ignoreTransactions)) {
139
139
  DEBUG_BUILD &&
140
140
  debug.warn(
@@ -1 +1 @@
1
- {"version":3,"file":"eventFilters.js","sources":["../../../src/integrations/eventFilters.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport { defineIntegration } from '../integration';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { StackFrame } from '../types-hoist/stackframe';\nimport { debug } from '../utils/debug-logger';\nimport { getPossibleEventMessages } from '../utils/eventUtils';\nimport { getEventDescription } from '../utils/misc';\nimport { stringMatchesSomePattern } from '../utils/string';\n\n// \"Script error.\" is hard coded into browsers for errors that it can't read.\n// this is the result of a script being pulled in from an external domain and CORS.\nconst DEFAULT_IGNORE_ERRORS = [\n /^Script error\\.?$/,\n /^Javascript error: Script error\\.? on line 0$/,\n /^ResizeObserver loop completed with undelivered notifications.$/, // The browser logs this when a ResizeObserver handler takes a bit longer. Usually this is not an actual issue though. It indicates slowness.\n /^Cannot redefine property: googletag$/, // This is thrown when google tag manager is used in combination with an ad blocker\n /^Can't find variable: gmo$/, // Error from Google Search App https://issuetracker.google.com/issues/396043331\n /^undefined is not an object \\(evaluating 'a\\.[A-Z]'\\)$/, // Random error that happens but not actionable or noticeable to end-users.\n 'can\\'t redefine non-configurable property \"solana\"', // Probably a browser extension or custom browser (Brave) throwing this error\n \"vv().getRestrictions is not a function. (In 'vv().getRestrictions(1,a)', 'vv().getRestrictions' is undefined)\", // Error thrown by GTM, seemingly not affecting end-users\n \"Can't find variable: _AutofillCallbackHandler\", // Unactionable error in instagram webview https://developers.facebook.com/community/threads/320013549791141/\n /^Non-Error promise rejection captured with value: Object Not Found Matching Id:\\d+, MethodName:simulateEvent, ParamCount:\\d+$/, // unactionable error from CEFSharp, a .NET library that embeds chromium in .NET apps\n /^Java exception was raised during method invocation$/, // error from Facebook Mobile browser (https://github.com/getsentry/sentry-javascript/issues/15065)\n];\n\n/** Options for the EventFilters integration */\nexport interface EventFiltersOptions {\n allowUrls: Array<string | RegExp>;\n denyUrls: Array<string | RegExp>;\n ignoreErrors: Array<string | RegExp>;\n ignoreTransactions: Array<string | RegExp>;\n ignoreInternal: boolean;\n disableErrorDefaults: boolean;\n}\n\nconst INTEGRATION_NAME = 'EventFilters';\n\n/**\n * An integration that filters out events (errors and transactions) based on:\n *\n * - (Errors) A curated list of known low-value or irrelevant errors (see {@link DEFAULT_IGNORE_ERRORS})\n * - (Errors) A list of error messages or urls/filenames passed in via\n * - Top level Sentry.init options (`ignoreErrors`, `denyUrls`, `allowUrls`)\n * - The same options passed to the integration directly via @param options\n * - (Transactions/Spans) A list of root span (transaction) names passed in via\n * - Top level Sentry.init option (`ignoreTransactions`)\n * - The same option passed to the integration directly via @param options\n *\n * Events filtered by this integration will not be sent to Sentry.\n */\nexport const eventFiltersIntegration = defineIntegration((options: Partial<EventFiltersOptions> = {}) => {\n let mergedOptions: Partial<EventFiltersOptions> | undefined;\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const clientOptions = client.getOptions();\n mergedOptions = _mergeOptions(options, clientOptions);\n },\n processEvent(event, _hint, client) {\n if (!mergedOptions) {\n const clientOptions = client.getOptions();\n mergedOptions = _mergeOptions(options, clientOptions);\n }\n return _shouldDropEvent(event, mergedOptions) ? null : event;\n },\n };\n});\n\n/**\n * An integration that filters out events (errors and transactions) based on:\n *\n * - (Errors) A curated list of known low-value or irrelevant errors (see {@link DEFAULT_IGNORE_ERRORS})\n * - (Errors) A list of error messages or urls/filenames passed in via\n * - Top level Sentry.init options (`ignoreErrors`, `denyUrls`, `allowUrls`)\n * - The same options passed to the integration directly via @param options\n * - (Transactions/Spans) A list of root span (transaction) names passed in via\n * - Top level Sentry.init option (`ignoreTransactions`)\n * - The same option passed to the integration directly via @param options\n *\n * Events filtered by this integration will not be sent to Sentry.\n *\n * @deprecated this integration was renamed and will be removed in a future major version.\n * Use `eventFiltersIntegration` instead.\n */\nexport const inboundFiltersIntegration = defineIntegration(((options: Partial<EventFiltersOptions> = {}) => {\n return {\n ...eventFiltersIntegration(options),\n name: 'InboundFilters',\n };\n}) satisfies IntegrationFn);\n\nfunction _mergeOptions(\n internalOptions: Partial<EventFiltersOptions> = {},\n clientOptions: Partial<EventFiltersOptions> = {},\n): Partial<EventFiltersOptions> {\n return {\n allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],\n denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],\n ignoreErrors: [\n ...(internalOptions.ignoreErrors || []),\n ...(clientOptions.ignoreErrors || []),\n ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),\n ],\n ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],\n };\n}\n\nfunction _shouldDropEvent(event: Event, options: Partial<EventFiltersOptions>): boolean {\n if (!event.type) {\n // Filter errors\n if (_isIgnoredError(event, options.ignoreErrors)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`ignoreErrors\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n if (_isUselessError(event)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to not having an error message, error type or stacktrace.\\nEvent: ${getEventDescription(\n event,\n )}`,\n );\n return true;\n }\n if (_isDeniedUrl(event, options.denyUrls)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`denyUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n if (!_isAllowedUrl(event, options.allowUrls)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to not being matched by \\`allowUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n } else if (event.type === 'transaction') {\n // Filter transactions\n\n if (_isIgnoredTransaction(event, options.ignoreTransactions)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`ignoreTransactions\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n }\n return false;\n}\n\nfunction _isIgnoredError(event: Event, ignoreErrors?: Array<string | RegExp>): boolean {\n if (!ignoreErrors?.length) {\n return false;\n }\n\n return getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));\n}\n\nfunction _isIgnoredTransaction(event: Event, ignoreTransactions?: Array<string | RegExp>): boolean {\n if (!ignoreTransactions?.length) {\n return false;\n }\n\n const name = event.transaction;\n return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;\n}\n\nfunction _isDeniedUrl(event: Event, denyUrls?: Array<string | RegExp>): boolean {\n if (!denyUrls?.length) {\n return false;\n }\n const url = _getEventFilterUrl(event);\n return !url ? false : stringMatchesSomePattern(url, denyUrls);\n}\n\nfunction _isAllowedUrl(event: Event, allowUrls?: Array<string | RegExp>): boolean {\n if (!allowUrls?.length) {\n return true;\n }\n const url = _getEventFilterUrl(event);\n return !url ? true : stringMatchesSomePattern(url, allowUrls);\n}\n\nfunction _getLastValidUrl(frames: StackFrame[] = []): string | null {\n for (let i = frames.length - 1; i >= 0; i--) {\n const frame = frames[i];\n\n if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {\n return frame.filename || null;\n }\n }\n\n return null;\n}\n\nfunction _getEventFilterUrl(event: Event): string | null {\n try {\n // If there are linked exceptions or exception aggregates we only want to match against the top frame of the \"root\" (the main exception)\n // The root always comes last in linked exceptions\n const rootException = [...(event.exception?.values ?? [])]\n .reverse()\n .find(value => value.mechanism?.parent_id === undefined && value.stacktrace?.frames?.length);\n const frames = rootException?.stacktrace?.frames;\n return frames ? _getLastValidUrl(frames) : null;\n } catch {\n DEBUG_BUILD && debug.error(`Cannot extract url for event ${getEventDescription(event)}`);\n return null;\n }\n}\n\nfunction _isUselessError(event: Event): boolean {\n // We only want to consider events for dropping that actually have recorded exception values.\n if (!event.exception?.values?.length) {\n return false;\n }\n\n return (\n // No top-level message\n !event.message &&\n // There are no exception values that have a stacktrace, a non-generic-Error type or value\n !event.exception.values.some(value => value.stacktrace || (value.type && value.type !== 'Error') || value.value)\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eventFilters.js","sources":["../../../src/integrations/eventFilters.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport { defineIntegration } from '../integration';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { StackFrame } from '../types-hoist/stackframe';\nimport { debug } from '../utils/debug-logger';\nimport { getPossibleEventMessages } from '../utils/eventUtils';\nimport { getEventDescription } from '../utils/misc';\nimport { stringMatchesSomePattern } from '../utils/string';\n\n// \"Script error.\" is hard coded into browsers for errors that it can't read.\n// this is the result of a script being pulled in from an external domain and CORS.\nconst DEFAULT_IGNORE_ERRORS = [\n /^Script error\\.?$/,\n /^Javascript error: Script error\\.? on line 0$/,\n /^ResizeObserver loop completed with undelivered notifications.$/, // The browser logs this when a ResizeObserver handler takes a bit longer. Usually this is not an actual issue though. It indicates slowness.\n /^Cannot redefine property: googletag$/, // This is thrown when google tag manager is used in combination with an ad blocker\n /^Can't find variable: gmo$/, // Error from Google Search App https://issuetracker.google.com/issues/396043331\n /^undefined is not an object \\(evaluating 'a\\.[A-Z]'\\)$/, // Random error that happens but not actionable or noticeable to end-users.\n 'can\\'t redefine non-configurable property \"solana\"', // Probably a browser extension or custom browser (Brave) throwing this error\n \"vv().getRestrictions is not a function. (In 'vv().getRestrictions(1,a)', 'vv().getRestrictions' is undefined)\", // Error thrown by GTM, seemingly not affecting end-users\n \"Can't find variable: _AutofillCallbackHandler\", // Unactionable error in instagram webview https://developers.facebook.com/community/threads/320013549791141/\n /^Non-Error promise rejection captured with value: Object Not Found Matching Id:\\d+, MethodName:simulateEvent, ParamCount:\\d+$/, // unactionable error from CEFSharp, a .NET library that embeds chromium in .NET apps\n /^Java exception was raised during method invocation$/, // error from Facebook Mobile browser (https://github.com/getsentry/sentry-javascript/issues/15065)\n];\n\n/** Options for the EventFilters integration */\nexport interface EventFiltersOptions {\n allowUrls: Array<string | RegExp>;\n denyUrls: Array<string | RegExp>;\n ignoreErrors: Array<string | RegExp>;\n ignoreTransactions: Array<string | RegExp>;\n ignoreInternal: boolean;\n disableErrorDefaults: boolean;\n}\n\nconst INTEGRATION_NAME = 'EventFilters';\n\n/**\n * An integration that filters out events (errors and transactions) based on:\n *\n * - (Errors) A curated list of known low-value or irrelevant errors (see {@link DEFAULT_IGNORE_ERRORS})\n * - (Errors) A list of error messages or urls/filenames passed in via\n * - Top level Sentry.init options (`ignoreErrors`, `denyUrls`, `allowUrls`)\n * - The same options passed to the integration directly via @param options\n * - (Transactions/Spans) A list of root span (transaction) names passed in via\n * - Top level Sentry.init option (`ignoreTransactions`)\n * - The same option passed to the integration directly via @param options\n *\n * Events filtered by this integration will not be sent to Sentry.\n */\nexport const eventFiltersIntegration = defineIntegration((options: Partial<EventFiltersOptions> = {}) => {\n let mergedOptions: Partial<EventFiltersOptions> | undefined;\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const clientOptions = client.getOptions();\n mergedOptions = _mergeOptions(options, clientOptions);\n },\n processEvent(event, _hint, client) {\n if (!mergedOptions) {\n const clientOptions = client.getOptions();\n mergedOptions = _mergeOptions(options, clientOptions);\n }\n return _shouldDropEvent(event, mergedOptions) ? null : event;\n },\n };\n});\n\n/**\n * An integration that filters out events (errors and transactions) based on:\n *\n * - (Errors) A curated list of known low-value or irrelevant errors (see {@link DEFAULT_IGNORE_ERRORS})\n * - (Errors) A list of error messages or urls/filenames passed in via\n * - Top level Sentry.init options (`ignoreErrors`, `denyUrls`, `allowUrls`)\n * - The same options passed to the integration directly via @param options\n * - (Transactions/Spans) A list of root span (transaction) names passed in via\n * - Top level Sentry.init option (`ignoreTransactions`)\n * - The same option passed to the integration directly via @param options\n *\n * Events filtered by this integration will not be sent to Sentry.\n *\n * @deprecated this integration was renamed and will be removed in a future major version.\n * Use `eventFiltersIntegration` instead.\n */\nexport const inboundFiltersIntegration = defineIntegration(((options: Partial<EventFiltersOptions> = {}) => {\n return {\n ...eventFiltersIntegration(options),\n name: 'InboundFilters',\n };\n}) satisfies IntegrationFn);\n\nfunction _mergeOptions(\n internalOptions: Partial<EventFiltersOptions> = {},\n clientOptions: Partial<EventFiltersOptions> = {},\n): Partial<EventFiltersOptions> {\n return {\n allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],\n denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],\n ignoreErrors: [\n ...(internalOptions.ignoreErrors || []),\n ...(clientOptions.ignoreErrors || []),\n ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),\n ],\n ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],\n };\n}\n\nfunction _shouldDropEvent(event: Event, options: Partial<EventFiltersOptions>): boolean {\n if (!event.type) {\n // Filter errors\n if (_isIgnoredError(event, options.ignoreErrors)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`ignoreErrors\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n if (_isUselessError(event)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to not having an error message, error type or stacktrace.\\nEvent: ${getEventDescription(\n event,\n )}`,\n );\n return true;\n }\n if (_isDeniedUrl(event, options.denyUrls)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`denyUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n if (!_isAllowedUrl(event, options.allowUrls)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to not being matched by \\`allowUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n } else if (event.type === 'transaction') {\n // Filter transactions\n // TODO (span-streaming): replace with ignoreSpans defaults (if we have any)\n if (_isIgnoredTransaction(event, options.ignoreTransactions)) {\n DEBUG_BUILD &&\n debug.warn(\n `Event dropped due to being matched by \\`ignoreTransactions\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n }\n return false;\n}\n\nfunction _isIgnoredError(event: Event, ignoreErrors?: Array<string | RegExp>): boolean {\n if (!ignoreErrors?.length) {\n return false;\n }\n\n return getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));\n}\n\nfunction _isIgnoredTransaction(event: Event, ignoreTransactions?: Array<string | RegExp>): boolean {\n if (!ignoreTransactions?.length) {\n return false;\n }\n\n const name = event.transaction;\n return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;\n}\n\nfunction _isDeniedUrl(event: Event, denyUrls?: Array<string | RegExp>): boolean {\n if (!denyUrls?.length) {\n return false;\n }\n const url = _getEventFilterUrl(event);\n return !url ? false : stringMatchesSomePattern(url, denyUrls);\n}\n\nfunction _isAllowedUrl(event: Event, allowUrls?: Array<string | RegExp>): boolean {\n if (!allowUrls?.length) {\n return true;\n }\n const url = _getEventFilterUrl(event);\n return !url ? true : stringMatchesSomePattern(url, allowUrls);\n}\n\nfunction _getLastValidUrl(frames: StackFrame[] = []): string | null {\n for (let i = frames.length - 1; i >= 0; i--) {\n const frame = frames[i];\n\n if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {\n return frame.filename || null;\n }\n }\n\n return null;\n}\n\nfunction _getEventFilterUrl(event: Event): string | null {\n try {\n // If there are linked exceptions or exception aggregates we only want to match against the top frame of the \"root\" (the main exception)\n // The root always comes last in linked exceptions\n const rootException = [...(event.exception?.values ?? [])]\n .reverse()\n .find(value => value.mechanism?.parent_id === undefined && value.stacktrace?.frames?.length);\n const frames = rootException?.stacktrace?.frames;\n return frames ? _getLastValidUrl(frames) : null;\n } catch {\n DEBUG_BUILD && debug.error(`Cannot extract url for event ${getEventDescription(event)}`);\n return null;\n }\n}\n\nfunction _isUselessError(event: Event): boolean {\n // We only want to consider events for dropping that actually have recorded exception values.\n if (!event.exception?.values?.length) {\n return false;\n }\n\n return (\n // No top-level message\n !event.message &&\n // There are no exception values that have a stacktrace, a non-generic-Error type or value\n !event.exception.values.some(value => value.stacktrace || (value.type && value.type !== 'Error') || value.value)\n );\n}\n"],"names":[],"mappings":"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"}
@@ -7,28 +7,52 @@ import { extractSessionDataFromInitializeResponse, buildServerAttributesFromInfo
7
7
  * Request-span correlation system for MCP server instrumentation
8
8
  *
9
9
  * Handles mapping requestId to span data for correlation with handler execution.
10
- * Uses WeakMap to scope correlation maps per transport instance, preventing
11
- * request ID collisions between different MCP sessions.
10
+ *
11
+ * Uses sessionId as the primary key for stateful transports. This handles the wrapper
12
+ * transport pattern (e.g., NodeStreamableHTTPServerTransport wrapping WebStandardStreamableHTTPServerTransport)
13
+ * where onmessage and send may receive different `this` values but share the same sessionId.
14
+ *
15
+ * Falls back to WeakMap by transport instance for stateless transports (no sessionId).
12
16
  */
13
17
 
14
18
 
15
19
  /**
16
- * Transport-scoped correlation system that prevents collisions between different MCP sessions
17
- * @internal Each transport instance gets its own correlation map, eliminating request ID conflicts
20
+ * Session-scoped correlation for stateful transports (with sessionId)
21
+ * @internal Using sessionId as key handles wrapper transport patterns where
22
+ * different transport objects share the same logical session
18
23
  */
19
- const transportToSpanMap = new WeakMap();
24
+ const sessionToSpanMap = new Map();
20
25
 
21
26
  /**
22
- * Gets or creates the span map for a specific transport instance
27
+ * Transport-scoped correlation fallback for stateless transports (no sessionId)
28
+ * @internal WeakMap allows automatic cleanup when transport is garbage collected
29
+ */
30
+ const statelessSpanMap = new WeakMap();
31
+
32
+ /**
33
+ * Gets or creates the span map for a transport, using sessionId when available
23
34
  * @internal
24
35
  * @param transport - MCP transport instance
25
- * @returns Span map for the transport
36
+ * @returns Span map for the transport/session
26
37
  */
27
38
  function getOrCreateSpanMap(transport) {
28
- let spanMap = transportToSpanMap.get(transport);
39
+ const sessionId = transport.sessionId;
40
+
41
+ if (sessionId) {
42
+ // Stateful transport - use sessionId as key (handles wrapper pattern)
43
+ let spanMap = sessionToSpanMap.get(sessionId);
44
+ if (!spanMap) {
45
+ spanMap = new Map();
46
+ sessionToSpanMap.set(sessionId, spanMap);
47
+ }
48
+ return spanMap;
49
+ }
50
+
51
+ // Stateless fallback - use transport instance as key
52
+ let spanMap = statelessSpanMap.get(transport);
29
53
  if (!spanMap) {
30
54
  spanMap = new Map();
31
- transportToSpanMap.set(transport, spanMap);
55
+ statelessSpanMap.set(transport, spanMap);
32
56
  }
33
57
  return spanMap;
34
58
  }
@@ -98,7 +122,26 @@ function completeSpanWithResults(
98
122
  * @param transport - MCP transport instance
99
123
  */
100
124
  function cleanupPendingSpansForTransport(transport) {
101
- const spanMap = transportToSpanMap.get(transport);
125
+ const sessionId = transport.sessionId;
126
+
127
+ // Try sessionId-based cleanup first (for stateful transports)
128
+ if (sessionId) {
129
+ const spanMap = sessionToSpanMap.get(sessionId);
130
+ if (spanMap) {
131
+ for (const [, spanData] of spanMap) {
132
+ spanData.span.setStatus({
133
+ code: SPAN_STATUS_ERROR,
134
+ message: 'cancelled',
135
+ });
136
+ spanData.span.end();
137
+ }
138
+ sessionToSpanMap.delete(sessionId);
139
+ }
140
+ return;
141
+ }
142
+
143
+ // Fallback to transport-based cleanup (for stateless transports)
144
+ const spanMap = statelessSpanMap.get(transport);
102
145
  if (spanMap) {
103
146
  for (const [, spanData] of spanMap) {
104
147
  spanData.span.setStatus({
@@ -108,6 +151,7 @@ function cleanupPendingSpansForTransport(transport) {
108
151
  spanData.span.end();
109
152
  }
110
153
  spanMap.clear();
154
+ // Note: WeakMap entries are automatically cleaned up when transport is GC'd
111
155
  }
112
156
  }
113
157
 
@@ -1 +1 @@
1
- {"version":3,"file":"correlation.js","sources":["../../../../src/integrations/mcp-server/correlation.ts"],"sourcesContent":["/**\n * Request-span correlation system for MCP server instrumentation\n *\n * Handles mapping requestId to span data for correlation with handler execution.\n * Uses WeakMap to scope correlation maps per transport instance, preventing\n * request ID collisions between different MCP sessions.\n */\n\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span } from '../../types-hoist/span';\nimport { MCP_PROTOCOL_VERSION_ATTRIBUTE } from './attributes';\nimport { extractPromptResultAttributes, extractToolResultAttributes } from './resultExtraction';\nimport { buildServerAttributesFromInfo, extractSessionDataFromInitializeResponse } from './sessionExtraction';\nimport type { MCPTransport, RequestId, RequestSpanMapValue, ResolvedMcpOptions } from './types';\n\n/**\n * Transport-scoped correlation system that prevents collisions between different MCP sessions\n * @internal Each transport instance gets its own correlation map, eliminating request ID conflicts\n */\nconst transportToSpanMap = new WeakMap<MCPTransport, Map<RequestId, RequestSpanMapValue>>();\n\n/**\n * Gets or creates the span map for a specific transport instance\n * @internal\n * @param transport - MCP transport instance\n * @returns Span map for the transport\n */\nfunction getOrCreateSpanMap(transport: MCPTransport): Map<RequestId, RequestSpanMapValue> {\n let spanMap = transportToSpanMap.get(transport);\n if (!spanMap) {\n spanMap = new Map();\n transportToSpanMap.set(transport, spanMap);\n }\n return spanMap;\n}\n\n/**\n * Stores span context for later correlation with handler execution\n * @param transport - MCP transport instance\n * @param requestId - Request identifier\n * @param span - Active span to correlate\n * @param method - MCP method name\n */\nexport function storeSpanForRequest(transport: MCPTransport, requestId: RequestId, span: Span, method: string): void {\n const spanMap = getOrCreateSpanMap(transport);\n spanMap.set(requestId, {\n span,\n method,\n // eslint-disable-next-line @sentry-internal/sdk/no-unsafe-random-apis\n startTime: Date.now(),\n });\n}\n\n/**\n * Completes span with results and cleans up correlation\n * @param transport - MCP transport instance\n * @param requestId - Request identifier\n * @param result - Execution result for attribute extraction\n * @param options - Resolved MCP options\n */\nexport function completeSpanWithResults(\n transport: MCPTransport,\n requestId: RequestId,\n result: unknown,\n options: ResolvedMcpOptions,\n): void {\n const spanMap = getOrCreateSpanMap(transport);\n const spanData = spanMap.get(requestId);\n if (spanData) {\n const { span, method } = spanData;\n\n if (method === 'initialize') {\n const sessionData = extractSessionDataFromInitializeResponse(result);\n const serverAttributes = buildServerAttributesFromInfo(sessionData.serverInfo);\n\n const initAttributes: Record<string, string | number> = {\n ...serverAttributes,\n };\n if (sessionData.protocolVersion) {\n initAttributes[MCP_PROTOCOL_VERSION_ATTRIBUTE] = sessionData.protocolVersion;\n }\n\n span.setAttributes(initAttributes);\n } else if (method === 'tools/call') {\n const toolAttributes = extractToolResultAttributes(result, options.recordOutputs);\n span.setAttributes(toolAttributes);\n } else if (method === 'prompts/get') {\n const promptAttributes = extractPromptResultAttributes(result, options.recordOutputs);\n span.setAttributes(promptAttributes);\n }\n\n span.end();\n spanMap.delete(requestId);\n }\n}\n\n/**\n * Cleans up pending spans for a specific transport (when that transport closes)\n * @param transport - MCP transport instance\n */\nexport function cleanupPendingSpansForTransport(transport: MCPTransport): void {\n const spanMap = transportToSpanMap.get(transport);\n if (spanMap) {\n for (const [, spanData] of spanMap) {\n spanData.span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: 'cancelled',\n });\n spanData.span.end();\n }\n spanMap.clear();\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"correlation.js","sources":["../../../../src/integrations/mcp-server/correlation.ts"],"sourcesContent":["/**\n * Request-span correlation system for MCP server instrumentation\n *\n * Handles mapping requestId to span data for correlation with handler execution.\n *\n * Uses sessionId as the primary key for stateful transports. This handles the wrapper\n * transport pattern (e.g., NodeStreamableHTTPServerTransport wrapping WebStandardStreamableHTTPServerTransport)\n * where onmessage and send may receive different `this` values but share the same sessionId.\n *\n * Falls back to WeakMap by transport instance for stateless transports (no sessionId).\n */\n\nimport { SPAN_STATUS_ERROR } from '../../tracing';\nimport type { Span } from '../../types-hoist/span';\nimport { MCP_PROTOCOL_VERSION_ATTRIBUTE } from './attributes';\nimport { extractPromptResultAttributes, extractToolResultAttributes } from './resultExtraction';\nimport { buildServerAttributesFromInfo, extractSessionDataFromInitializeResponse } from './sessionExtraction';\nimport type { MCPTransport, RequestId, RequestSpanMapValue, ResolvedMcpOptions } from './types';\n\n/**\n * Session-scoped correlation for stateful transports (with sessionId)\n * @internal Using sessionId as key handles wrapper transport patterns where\n * different transport objects share the same logical session\n */\nconst sessionToSpanMap = new Map<string, Map<RequestId, RequestSpanMapValue>>();\n\n/**\n * Transport-scoped correlation fallback for stateless transports (no sessionId)\n * @internal WeakMap allows automatic cleanup when transport is garbage collected\n */\nconst statelessSpanMap = new WeakMap<MCPTransport, Map<RequestId, RequestSpanMapValue>>();\n\n/**\n * Gets or creates the span map for a transport, using sessionId when available\n * @internal\n * @param transport - MCP transport instance\n * @returns Span map for the transport/session\n */\nfunction getOrCreateSpanMap(transport: MCPTransport): Map<RequestId, RequestSpanMapValue> {\n const sessionId = transport.sessionId;\n\n if (sessionId) {\n // Stateful transport - use sessionId as key (handles wrapper pattern)\n let spanMap = sessionToSpanMap.get(sessionId);\n if (!spanMap) {\n spanMap = new Map();\n sessionToSpanMap.set(sessionId, spanMap);\n }\n return spanMap;\n }\n\n // Stateless fallback - use transport instance as key\n let spanMap = statelessSpanMap.get(transport);\n if (!spanMap) {\n spanMap = new Map();\n statelessSpanMap.set(transport, spanMap);\n }\n return spanMap;\n}\n\n/**\n * Stores span context for later correlation with handler execution\n * @param transport - MCP transport instance\n * @param requestId - Request identifier\n * @param span - Active span to correlate\n * @param method - MCP method name\n */\nexport function storeSpanForRequest(transport: MCPTransport, requestId: RequestId, span: Span, method: string): void {\n const spanMap = getOrCreateSpanMap(transport);\n spanMap.set(requestId, {\n span,\n method,\n // eslint-disable-next-line @sentry-internal/sdk/no-unsafe-random-apis\n startTime: Date.now(),\n });\n}\n\n/**\n * Completes span with results and cleans up correlation\n * @param transport - MCP transport instance\n * @param requestId - Request identifier\n * @param result - Execution result for attribute extraction\n * @param options - Resolved MCP options\n */\nexport function completeSpanWithResults(\n transport: MCPTransport,\n requestId: RequestId,\n result: unknown,\n options: ResolvedMcpOptions,\n): void {\n const spanMap = getOrCreateSpanMap(transport);\n const spanData = spanMap.get(requestId);\n if (spanData) {\n const { span, method } = spanData;\n\n if (method === 'initialize') {\n const sessionData = extractSessionDataFromInitializeResponse(result);\n const serverAttributes = buildServerAttributesFromInfo(sessionData.serverInfo);\n\n const initAttributes: Record<string, string | number> = {\n ...serverAttributes,\n };\n if (sessionData.protocolVersion) {\n initAttributes[MCP_PROTOCOL_VERSION_ATTRIBUTE] = sessionData.protocolVersion;\n }\n\n span.setAttributes(initAttributes);\n } else if (method === 'tools/call') {\n const toolAttributes = extractToolResultAttributes(result, options.recordOutputs);\n span.setAttributes(toolAttributes);\n } else if (method === 'prompts/get') {\n const promptAttributes = extractPromptResultAttributes(result, options.recordOutputs);\n span.setAttributes(promptAttributes);\n }\n\n span.end();\n spanMap.delete(requestId);\n }\n}\n\n/**\n * Cleans up pending spans for a specific transport (when that transport closes)\n * @param transport - MCP transport instance\n */\nexport function cleanupPendingSpansForTransport(transport: MCPTransport): void {\n const sessionId = transport.sessionId;\n\n // Try sessionId-based cleanup first (for stateful transports)\n if (sessionId) {\n const spanMap = sessionToSpanMap.get(sessionId);\n if (spanMap) {\n for (const [, spanData] of spanMap) {\n spanData.span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: 'cancelled',\n });\n spanData.span.end();\n }\n sessionToSpanMap.delete(sessionId);\n }\n return;\n }\n\n // Fallback to transport-based cleanup (for stateless transports)\n const spanMap = statelessSpanMap.get(transport);\n if (spanMap) {\n for (const [, spanData] of spanMap) {\n spanData.span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: 'cancelled',\n });\n spanData.span.end();\n }\n spanMap.clear();\n // Note: WeakMap entries are automatically cleaned up when transport is GC'd\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,30 +1,59 @@
1
1
  /**
2
- * Transport-scoped session data storage (only for transports with sessionId)
3
- * @internal Maps transport instances to session-level data
2
+ * Session-scoped data storage for stateful transports (with sessionId)
3
+ * @internal Using sessionId as key handles wrapper transport patterns
4
4
  */
5
- const transportToSessionData = new WeakMap();
5
+ const sessionToSessionData = new Map();
6
6
 
7
7
  /**
8
- * Stores session data for a transport with sessionId
8
+ * Transport-scoped data storage fallback for stateless transports (no sessionId)
9
+ * @internal WeakMap allows automatic cleanup when transport is garbage collected
10
+ */
11
+ const statelessSessionData = new WeakMap();
12
+
13
+ /**
14
+ * Gets session data for a transport, checking sessionId first then fallback
15
+ * @internal
16
+ */
17
+ function getSessionData(transport) {
18
+ const sessionId = transport.sessionId;
19
+ if (sessionId) {
20
+ return sessionToSessionData.get(sessionId);
21
+ }
22
+ return statelessSessionData.get(transport);
23
+ }
24
+
25
+ /**
26
+ * Sets session data for a transport, using sessionId when available
27
+ * @internal
28
+ */
29
+ function setSessionData(transport, data) {
30
+ const sessionId = transport.sessionId;
31
+ if (sessionId) {
32
+ sessionToSessionData.set(sessionId, data);
33
+ } else {
34
+ statelessSessionData.set(transport, data);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Stores session data for a transport
9
40
  * @param transport - MCP transport instance
10
41
  * @param sessionData - Session data to store
11
42
  */
12
43
  function storeSessionDataForTransport(transport, sessionData) {
13
- if (transport.sessionId) {
14
- transportToSessionData.set(transport, sessionData);
15
- }
44
+ // For stateful transports, always store (sessionId is the key)
45
+ // For stateless transports, also store (transport instance is the key)
46
+ setSessionData(transport, sessionData);
16
47
  }
17
48
 
18
49
  /**
19
- * Updates session data for a transport with sessionId (merges with existing data)
50
+ * Updates session data for a transport (merges with existing data)
20
51
  * @param transport - MCP transport instance
21
52
  * @param partialSessionData - Partial session data to merge with existing data
22
53
  */
23
54
  function updateSessionDataForTransport(transport, partialSessionData) {
24
- if (transport.sessionId) {
25
- const existingData = transportToSessionData.get(transport) || {};
26
- transportToSessionData.set(transport, { ...existingData, ...partialSessionData });
27
- }
55
+ const existingData = getSessionData(transport) || {};
56
+ setSessionData(transport, { ...existingData, ...partialSessionData });
28
57
  }
29
58
 
30
59
  /**
@@ -33,7 +62,7 @@ function updateSessionDataForTransport(transport, partialSessionData) {
33
62
  * @returns Client information if available
34
63
  */
35
64
  function getClientInfoForTransport(transport) {
36
- return transportToSessionData.get(transport)?.clientInfo;
65
+ return getSessionData(transport)?.clientInfo;
37
66
  }
38
67
 
39
68
  /**
@@ -42,7 +71,7 @@ function getClientInfoForTransport(transport) {
42
71
  * @returns Protocol version if available
43
72
  */
44
73
  function getProtocolVersionForTransport(transport) {
45
- return transportToSessionData.get(transport)?.protocolVersion;
74
+ return getSessionData(transport)?.protocolVersion;
46
75
  }
47
76
 
48
77
  /**
@@ -51,7 +80,7 @@ function getProtocolVersionForTransport(transport) {
51
80
  * @returns Complete session data if available
52
81
  */
53
82
  function getSessionDataForTransport(transport) {
54
- return transportToSessionData.get(transport);
83
+ return getSessionData(transport);
55
84
  }
56
85
 
57
86
  /**
@@ -59,7 +88,12 @@ function getSessionDataForTransport(transport) {
59
88
  * @param transport - MCP transport instance
60
89
  */
61
90
  function cleanupSessionDataForTransport(transport) {
62
- transportToSessionData.delete(transport);
91
+ const sessionId = transport.sessionId;
92
+ if (sessionId) {
93
+ sessionToSessionData.delete(sessionId);
94
+ }
95
+ // Note: WeakMap entries are automatically cleaned up when transport is GC'd
96
+ // No explicit delete needed for statelessSessionData
63
97
  }
64
98
 
65
99
  export { cleanupSessionDataForTransport, getClientInfoForTransport, getProtocolVersionForTransport, getSessionDataForTransport, storeSessionDataForTransport, updateSessionDataForTransport };
@@ -1 +1 @@
1
- {"version":3,"file":"sessionManagement.js","sources":["../../../../src/integrations/mcp-server/sessionManagement.ts"],"sourcesContent":["/**\n * Session data management for MCP server instrumentation\n */\n\nimport type { MCPTransport, PartyInfo, SessionData } from './types';\n\n/**\n * Transport-scoped session data storage (only for transports with sessionId)\n * @internal Maps transport instances to session-level data\n */\nconst transportToSessionData = new WeakMap<MCPTransport, SessionData>();\n\n/**\n * Stores session data for a transport with sessionId\n * @param transport - MCP transport instance\n * @param sessionData - Session data to store\n */\nexport function storeSessionDataForTransport(transport: MCPTransport, sessionData: SessionData): void {\n if (transport.sessionId) {\n transportToSessionData.set(transport, sessionData);\n }\n}\n\n/**\n * Updates session data for a transport with sessionId (merges with existing data)\n * @param transport - MCP transport instance\n * @param partialSessionData - Partial session data to merge with existing data\n */\nexport function updateSessionDataForTransport(transport: MCPTransport, partialSessionData: Partial<SessionData>): void {\n if (transport.sessionId) {\n const existingData = transportToSessionData.get(transport) || {};\n transportToSessionData.set(transport, { ...existingData, ...partialSessionData });\n }\n}\n\n/**\n * Retrieves client information for a transport\n * @param transport - MCP transport instance\n * @returns Client information if available\n */\nexport function getClientInfoForTransport(transport: MCPTransport): PartyInfo | undefined {\n return transportToSessionData.get(transport)?.clientInfo;\n}\n\n/**\n * Retrieves protocol version for a transport\n * @param transport - MCP transport instance\n * @returns Protocol version if available\n */\nexport function getProtocolVersionForTransport(transport: MCPTransport): string | undefined {\n return transportToSessionData.get(transport)?.protocolVersion;\n}\n\n/**\n * Retrieves full session data for a transport\n * @param transport - MCP transport instance\n * @returns Complete session data if available\n */\nexport function getSessionDataForTransport(transport: MCPTransport): SessionData | undefined {\n return transportToSessionData.get(transport);\n}\n\n/**\n * Cleans up session data for a specific transport (when that transport closes)\n * @param transport - MCP transport instance\n */\nexport function cleanupSessionDataForTransport(transport: MCPTransport): void {\n transportToSessionData.delete(transport);\n}\n"],"names":[],"mappings":"AAMA;AACA;AACA;AACA;AACA,MAAM,sBAAA,GAAyB,IAAI,OAAO,EAA6B;;AAEvE;AACA;AACA;AACA;AACA;AACO,SAAS,4BAA4B,CAAC,SAAS,EAAgB,WAAW,EAAqB;AACtG,EAAE,IAAI,SAAS,CAAC,SAAS,EAAE;AAC3B,IAAI,sBAAsB,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC;AACtD,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,6BAA6B,CAAC,SAAS,EAAgB,kBAAkB,EAA8B;AACvH,EAAE,IAAI,SAAS,CAAC,SAAS,EAAE;AAC3B,IAAI,MAAM,YAAA,GAAe,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAA,IAAK,EAAE;AACpE,IAAI,sBAAsB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,kBAAA,EAAoB,CAAC;AACrF,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB,CAAC,SAAS,EAAuC;AAC1F,EAAE,OAAO,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,UAAU;AAC1D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,SAAS,EAAoC;AAC5F,EAAE,OAAO,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,eAAe;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,SAAS,EAAyC;AAC7F,EAAE,OAAO,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9C;;AAEA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,SAAS,EAAsB;AAC9E,EAAE,sBAAsB,CAAC,MAAM,CAAC,SAAS,CAAC;AAC1C;;;;"}
1
+ {"version":3,"file":"sessionManagement.js","sources":["../../../../src/integrations/mcp-server/sessionManagement.ts"],"sourcesContent":["/**\n * Session data management for MCP server instrumentation\n *\n * Uses sessionId as the primary key for stateful transports. This handles the wrapper\n * transport pattern (e.g., NodeStreamableHTTPServerTransport wrapping WebStandardStreamableHTTPServerTransport)\n * where different methods may receive different `this` values but share the same sessionId.\n *\n * Falls back to WeakMap by transport instance for stateless transports (no sessionId).\n */\n\nimport type { MCPTransport, PartyInfo, SessionData } from './types';\n\n/**\n * Session-scoped data storage for stateful transports (with sessionId)\n * @internal Using sessionId as key handles wrapper transport patterns\n */\nconst sessionToSessionData = new Map<string, SessionData>();\n\n/**\n * Transport-scoped data storage fallback for stateless transports (no sessionId)\n * @internal WeakMap allows automatic cleanup when transport is garbage collected\n */\nconst statelessSessionData = new WeakMap<MCPTransport, SessionData>();\n\n/**\n * Gets session data for a transport, checking sessionId first then fallback\n * @internal\n */\nfunction getSessionData(transport: MCPTransport): SessionData | undefined {\n const sessionId = transport.sessionId;\n if (sessionId) {\n return sessionToSessionData.get(sessionId);\n }\n return statelessSessionData.get(transport);\n}\n\n/**\n * Sets session data for a transport, using sessionId when available\n * @internal\n */\nfunction setSessionData(transport: MCPTransport, data: SessionData): void {\n const sessionId = transport.sessionId;\n if (sessionId) {\n sessionToSessionData.set(sessionId, data);\n } else {\n statelessSessionData.set(transport, data);\n }\n}\n\n/**\n * Stores session data for a transport\n * @param transport - MCP transport instance\n * @param sessionData - Session data to store\n */\nexport function storeSessionDataForTransport(transport: MCPTransport, sessionData: SessionData): void {\n // For stateful transports, always store (sessionId is the key)\n // For stateless transports, also store (transport instance is the key)\n setSessionData(transport, sessionData);\n}\n\n/**\n * Updates session data for a transport (merges with existing data)\n * @param transport - MCP transport instance\n * @param partialSessionData - Partial session data to merge with existing data\n */\nexport function updateSessionDataForTransport(transport: MCPTransport, partialSessionData: Partial<SessionData>): void {\n const existingData = getSessionData(transport) || {};\n setSessionData(transport, { ...existingData, ...partialSessionData });\n}\n\n/**\n * Retrieves client information for a transport\n * @param transport - MCP transport instance\n * @returns Client information if available\n */\nexport function getClientInfoForTransport(transport: MCPTransport): PartyInfo | undefined {\n return getSessionData(transport)?.clientInfo;\n}\n\n/**\n * Retrieves protocol version for a transport\n * @param transport - MCP transport instance\n * @returns Protocol version if available\n */\nexport function getProtocolVersionForTransport(transport: MCPTransport): string | undefined {\n return getSessionData(transport)?.protocolVersion;\n}\n\n/**\n * Retrieves full session data for a transport\n * @param transport - MCP transport instance\n * @returns Complete session data if available\n */\nexport function getSessionDataForTransport(transport: MCPTransport): SessionData | undefined {\n return getSessionData(transport);\n}\n\n/**\n * Cleans up session data for a specific transport (when that transport closes)\n * @param transport - MCP transport instance\n */\nexport function cleanupSessionDataForTransport(transport: MCPTransport): void {\n const sessionId = transport.sessionId;\n if (sessionId) {\n sessionToSessionData.delete(sessionId);\n }\n // Note: WeakMap entries are automatically cleaned up when transport is GC'd\n // No explicit delete needed for statelessSessionData\n}\n"],"names":[],"mappings":"AAYA;AACA;AACA;AACA;AACA,MAAM,oBAAA,GAAuB,IAAI,GAAG,EAAuB;;AAE3D;AACA;AACA;AACA;AACA,MAAM,oBAAA,GAAuB,IAAI,OAAO,EAA6B;;AAErE;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,SAAS,EAAyC;AAC1E,EAAE,MAAM,SAAA,GAAY,SAAS,CAAC,SAAS;AACvC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9C,EAAE;AACF,EAAE,OAAO,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC;AAC5C;;AAEA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,SAAS,EAAgB,IAAI,EAAqB;AAC1E,EAAE,MAAM,SAAA,GAAY,SAAS,CAAC,SAAS;AACvC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,oBAAoB,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC;AAC7C,EAAE,OAAO;AACT,IAAI,oBAAoB,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC;AAC7C,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,4BAA4B,CAAC,SAAS,EAAgB,WAAW,EAAqB;AACtG;AACA;AACA,EAAE,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,6BAA6B,CAAC,SAAS,EAAgB,kBAAkB,EAA8B;AACvH,EAAE,MAAM,eAAe,cAAc,CAAC,SAAS,CAAA,IAAK,EAAE;AACtD,EAAE,cAAc,CAAC,SAAS,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,kBAAA,EAAoB,CAAC;AACvE;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB,CAAC,SAAS,EAAuC;AAC1F,EAAE,OAAO,cAAc,CAAC,SAAS,CAAC,EAAE,UAAU;AAC9C;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,SAAS,EAAoC;AAC5F,EAAE,OAAO,cAAc,CAAC,SAAS,CAAC,EAAE,eAAe;AACnD;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,SAAS,EAAyC;AAC7F,EAAE,OAAO,cAAc,CAAC,SAAS,CAAC;AAClC;;AAEA;AACA;AACA;AACA;AACO,SAAS,8BAA8B,CAAC,SAAS,EAAsB;AAC9E,EAAE,MAAM,SAAA,GAAY,SAAS,CAAC,SAAS;AACvC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC;AAC1C,EAAE;AACF;AACA;AACA;;;;"}
@@ -1,5 +1,8 @@
1
1
  import { defineIntegration } from '../integration.js';
2
+ import { SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS, SEMANTIC_ATTRIBUTE_URL_QUERY, SEMANTIC_ATTRIBUTE_URL_FULL, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD } from '../semanticAttributes.js';
3
+ import { safeSetSpanJSONAttributes } from '../spans/spanFirstUtils.js';
2
4
  import { parseCookie } from '../utils/cookie.js';
5
+ import { httpHeadersToSpanAttributes } from '../utils/request.js';
3
6
  import { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress.js';
4
7
 
5
8
  // TODO(v11): Change defaults based on `sendDefaultPii`
@@ -21,14 +24,67 @@ const _requestDataIntegration = ((options = {}) => {
21
24
 
22
25
  return {
23
26
  name: INTEGRATION_NAME,
27
+ setup(client) {
28
+ client.on('processSegmentSpan', (spanJSON, { scopeData }) => {
29
+ const { sdkProcessingMetadata = {} } = scopeData;
30
+ const { normalizedRequest, ipAddress } = sdkProcessingMetadata;
31
+
32
+ if (!normalizedRequest) {
33
+ return;
34
+ }
35
+
36
+ const includeWithDefaultPiiApplied = getIncludeWithDefaultPiiApplied(
37
+ include,
38
+ client,
39
+ );
40
+
41
+ // no need to check for include after calling `extractNormalizedRequestData`
42
+ // because it already internally only return what's permitted by `include`
43
+ const { method, url, query_string, headers, data, env } = extractNormalizedRequestData(
44
+ normalizedRequest,
45
+ includeWithDefaultPiiApplied,
46
+ );
47
+
48
+ safeSetSpanJSONAttributes(spanJSON, {
49
+ ...(method ? { [SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD]: method } : {}),
50
+ ...(url ? { [SEMANTIC_ATTRIBUTE_URL_FULL]: url } : {}),
51
+ ...(query_string ? { [SEMANTIC_ATTRIBUTE_URL_QUERY]: query_string } : {}),
52
+ ...(headers ? httpHeadersToSpanAttributes(headers, client.getOptions().sendDefaultPii) : {}),
53
+ // TODO: Apparently, Relay still needs Pii rule updates, so I'm leaving this out for now
54
+ // ...(cookies
55
+ // ? Object.keys(cookies).reduce(
56
+ // (acc, cookieName) => ({
57
+ // ...acc,
58
+ // [`http.request.header.cookie.${cookieName}`]: cookies[cookieName] ?? '',
59
+ // }),
60
+ // {} as Record<string, string>,
61
+ // )
62
+ // : {}),
63
+ ...(include.ip
64
+ ? {
65
+ [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]:
66
+ (normalizedRequest.headers && getClientIPAddress(normalizedRequest.headers)) || ipAddress,
67
+ }
68
+ : {}),
69
+ ...(data ? { 'http.request.body.content': data } : {}),
70
+ ...(env
71
+ ? {
72
+ 'http.request.env': Object.keys(env).reduce(
73
+ (acc, key) => ({ ...acc, [key]: env[key] ?? '' }),
74
+ {} ,
75
+ ),
76
+ }
77
+ : {}),
78
+ });
79
+ });
80
+ },
81
+ // TODO (span-streaming): probably fine to leave as-is for errors.
82
+ // For spans, we go through global context -> attribute conversion or omit this completely (TBD)
24
83
  processEvent(event, _hint, client) {
25
84
  const { sdkProcessingMetadata = {} } = event;
26
85
  const { normalizedRequest, ipAddress } = sdkProcessingMetadata;
27
86
 
28
- const includeWithDefaultPiiApplied = {
29
- ...include,
30
- ip: include.ip ?? client.getOptions().sendDefaultPii,
31
- };
87
+ const includeWithDefaultPiiApplied = getIncludeWithDefaultPiiApplied(include, client);
32
88
 
33
89
  if (normalizedRequest) {
34
90
  addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied);
@@ -45,6 +101,16 @@ const _requestDataIntegration = ((options = {}) => {
45
101
  */
46
102
  const requestDataIntegration = defineIntegration(_requestDataIntegration);
47
103
 
104
+ const getIncludeWithDefaultPiiApplied = (
105
+ include
106
+
107
+ ,
108
+ client,
109
+ ) => ({
110
+ ...include,
111
+ ip: include.ip ?? client.getOptions().sendDefaultPii,
112
+ });
113
+
48
114
  /**
49
115
  * Add already normalized request data to an event.
50
116
  * This mutates the passed in event.
@@ -84,14 +150,14 @@ function extractNormalizedRequestData(
84
150
 
85
151
  // Remove the Cookie header in case cookie data should not be included in the event
86
152
  if (!include.cookies) {
87
- delete (headers ).cookie;
153
+ delete headers.cookie;
88
154
  }
89
155
 
90
156
  // Remove IP headers in case IP data should not be included in the event
91
157
  if (!include.ip) {
92
158
  ipHeaderNames.forEach(ipHeaderName => {
93
159
  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
94
- delete (headers )[ipHeaderName];
160
+ delete headers[ipHeaderName];
95
161
  });
96
162
  }
97
163
  }