@sentry/core 10.47.0 → 10.48.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 (316) hide show
  1. package/build/cjs/attributes.js +43 -0
  2. package/build/cjs/attributes.js.map +1 -1
  3. package/build/cjs/client.js +13 -6
  4. package/build/cjs/client.js.map +1 -1
  5. package/build/cjs/envelope.js +4 -3
  6. package/build/cjs/envelope.js.map +1 -1
  7. package/build/cjs/index.js +44 -13
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/integration.js +6 -0
  10. package/build/cjs/integration.js.map +1 -1
  11. package/build/cjs/integrations/express/index.js +206 -0
  12. package/build/cjs/integrations/express/index.js.map +1 -0
  13. package/build/cjs/integrations/express/patch-layer.js +251 -0
  14. package/build/cjs/integrations/express/patch-layer.js.map +1 -0
  15. package/build/cjs/integrations/express/request-layer-store.js +25 -0
  16. package/build/cjs/integrations/express/request-layer-store.js.map +1 -0
  17. package/build/cjs/integrations/express/set-sdk-processing-metadata.js +17 -0
  18. package/build/cjs/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  19. package/build/cjs/integrations/express/types.js +17 -0
  20. package/build/cjs/integrations/express/types.js.map +1 -0
  21. package/build/cjs/integrations/express/utils.js +238 -0
  22. package/build/cjs/integrations/express/utils.js.map +1 -0
  23. package/build/cjs/integrations/mcp-server/correlation.js +5 -1
  24. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  25. package/build/cjs/integrations/mcp-server/handlers.js +18 -10
  26. package/build/cjs/integrations/mcp-server/handlers.js.map +1 -1
  27. package/build/cjs/integrations/mcp-server/index.js +2 -1
  28. package/build/cjs/integrations/mcp-server/index.js.map +1 -1
  29. package/build/cjs/integrations/mcp-server/transport.js +1 -1
  30. package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
  31. package/build/cjs/integrations/mcp-server/validation.js +7 -5
  32. package/build/cjs/integrations/mcp-server/validation.js.map +1 -1
  33. package/build/cjs/integrations/spanStreaming.js +48 -0
  34. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  35. package/build/cjs/semanticAttributes.js +35 -3
  36. package/build/cjs/semanticAttributes.js.map +1 -1
  37. package/build/cjs/tracing/ai/gen-ai-attributes.js +9 -65
  38. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  39. package/build/cjs/tracing/ai/utils.js +50 -0
  40. package/build/cjs/tracing/ai/utils.js.map +1 -1
  41. package/build/cjs/tracing/anthropic-ai/index.js +1 -12
  42. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  43. package/build/cjs/tracing/anthropic-ai/streaming.js +2 -100
  44. package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
  45. package/build/cjs/tracing/dynamicSamplingContext.js +2 -1
  46. package/build/cjs/tracing/dynamicSamplingContext.js.map +1 -1
  47. package/build/cjs/tracing/google-genai/constants.js +1 -6
  48. package/build/cjs/tracing/google-genai/constants.js.map +1 -1
  49. package/build/cjs/tracing/google-genai/index.js +24 -30
  50. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  51. package/build/cjs/tracing/google-genai/streaming.js +2 -23
  52. package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
  53. package/build/cjs/tracing/langchain/embeddings.js +132 -0
  54. package/build/cjs/tracing/langchain/embeddings.js.map +1 -0
  55. package/build/cjs/tracing/langchain/index.js.map +1 -1
  56. package/build/cjs/tracing/openai/index.js +2 -29
  57. package/build/cjs/tracing/openai/index.js.map +1 -1
  58. package/build/cjs/tracing/openai/streaming.js +3 -34
  59. package/build/cjs/tracing/openai/streaming.js.map +1 -1
  60. package/build/cjs/tracing/openai/utils.js +78 -204
  61. package/build/cjs/tracing/openai/utils.js.map +1 -1
  62. package/build/cjs/tracing/sentryNonRecordingSpan.js +7 -0
  63. package/build/cjs/tracing/sentryNonRecordingSpan.js.map +1 -1
  64. package/build/cjs/tracing/sentrySpan.js +39 -0
  65. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  66. package/build/cjs/tracing/spans/beforeSendSpan.js +43 -0
  67. package/build/cjs/tracing/spans/beforeSendSpan.js.map +1 -0
  68. package/build/cjs/tracing/spans/captureSpan.js +126 -0
  69. package/build/cjs/tracing/spans/captureSpan.js.map +1 -0
  70. package/build/cjs/tracing/spans/envelope.js +38 -0
  71. package/build/cjs/tracing/spans/envelope.js.map +1 -0
  72. package/build/cjs/tracing/spans/estimateSize.js +41 -0
  73. package/build/cjs/tracing/spans/estimateSize.js.map +1 -0
  74. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js +11 -0
  75. package/build/cjs/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  76. package/build/cjs/tracing/spans/spanBuffer.js +158 -0
  77. package/build/cjs/tracing/spans/spanBuffer.js.map +1 -0
  78. package/build/cjs/tracing/trace.js +83 -13
  79. package/build/cjs/tracing/trace.js.map +1 -1
  80. package/build/cjs/tracing/vercel-ai/utils.js +1 -4
  81. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  82. package/build/cjs/utils/featureFlags.js +6 -0
  83. package/build/cjs/utils/featureFlags.js.map +1 -1
  84. package/build/cjs/utils/object.js +33 -0
  85. package/build/cjs/utils/object.js.map +1 -1
  86. package/build/cjs/utils/spanUtils.js +116 -13
  87. package/build/cjs/utils/spanUtils.js.map +1 -1
  88. package/build/cjs/utils/stacktrace.js +3 -1
  89. package/build/cjs/utils/stacktrace.js.map +1 -1
  90. package/build/cjs/utils/string.js +3 -0
  91. package/build/cjs/utils/string.js.map +1 -1
  92. package/build/cjs/utils/version.js +1 -1
  93. package/build/esm/attributes.js +43 -1
  94. package/build/esm/attributes.js.map +1 -1
  95. package/build/esm/client.js +8 -1
  96. package/build/esm/client.js.map +1 -1
  97. package/build/esm/envelope.js +2 -1
  98. package/build/esm/envelope.js.map +1 -1
  99. package/build/esm/index.js +10 -2
  100. package/build/esm/index.js.map +1 -1
  101. package/build/esm/integration.js +6 -0
  102. package/build/esm/integration.js.map +1 -1
  103. package/build/esm/integrations/express/index.js +202 -0
  104. package/build/esm/integrations/express/index.js.map +1 -0
  105. package/build/esm/integrations/express/patch-layer.js +249 -0
  106. package/build/esm/integrations/express/patch-layer.js.map +1 -0
  107. package/build/esm/integrations/express/request-layer-store.js +22 -0
  108. package/build/esm/integrations/express/request-layer-store.js.map +1 -0
  109. package/build/esm/integrations/express/set-sdk-processing-metadata.js +15 -0
  110. package/build/esm/integrations/express/set-sdk-processing-metadata.js.map +1 -0
  111. package/build/esm/integrations/express/types.js +10 -0
  112. package/build/esm/integrations/express/types.js.map +1 -0
  113. package/build/esm/integrations/express/utils.js +225 -0
  114. package/build/esm/integrations/express/utils.js.map +1 -0
  115. package/build/esm/integrations/mcp-server/correlation.js +5 -1
  116. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  117. package/build/esm/integrations/mcp-server/handlers.js +18 -10
  118. package/build/esm/integrations/mcp-server/handlers.js.map +1 -1
  119. package/build/esm/integrations/mcp-server/index.js +2 -1
  120. package/build/esm/integrations/mcp-server/index.js.map +1 -1
  121. package/build/esm/integrations/mcp-server/transport.js +1 -1
  122. package/build/esm/integrations/mcp-server/transport.js.map +1 -1
  123. package/build/esm/integrations/mcp-server/validation.js +7 -5
  124. package/build/esm/integrations/mcp-server/validation.js.map +1 -1
  125. package/build/esm/integrations/spanStreaming.js +46 -0
  126. package/build/esm/integrations/spanStreaming.js.map +1 -0
  127. package/build/esm/package.json +1 -1
  128. package/build/esm/semanticAttributes.js +26 -4
  129. package/build/esm/semanticAttributes.js.map +1 -1
  130. package/build/esm/tracing/ai/gen-ai-attributes.js +8 -56
  131. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  132. package/build/esm/tracing/ai/utils.js +51 -2
  133. package/build/esm/tracing/ai/utils.js.map +1 -1
  134. package/build/esm/tracing/anthropic-ai/index.js +2 -13
  135. package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
  136. package/build/esm/tracing/anthropic-ai/streaming.js +3 -101
  137. package/build/esm/tracing/anthropic-ai/streaming.js.map +1 -1
  138. package/build/esm/tracing/dynamicSamplingContext.js +2 -1
  139. package/build/esm/tracing/dynamicSamplingContext.js.map +1 -1
  140. package/build/esm/tracing/google-genai/constants.js +2 -5
  141. package/build/esm/tracing/google-genai/constants.js.map +1 -1
  142. package/build/esm/tracing/google-genai/index.js +25 -31
  143. package/build/esm/tracing/google-genai/index.js.map +1 -1
  144. package/build/esm/tracing/google-genai/streaming.js +2 -23
  145. package/build/esm/tracing/google-genai/streaming.js.map +1 -1
  146. package/build/esm/tracing/langchain/embeddings.js +129 -0
  147. package/build/esm/tracing/langchain/embeddings.js.map +1 -0
  148. package/build/esm/tracing/langchain/index.js.map +1 -1
  149. package/build/esm/tracing/openai/index.js +3 -30
  150. package/build/esm/tracing/openai/index.js.map +1 -1
  151. package/build/esm/tracing/openai/streaming.js +4 -35
  152. package/build/esm/tracing/openai/streaming.js.map +1 -1
  153. package/build/esm/tracing/openai/utils.js +79 -196
  154. package/build/esm/tracing/openai/utils.js.map +1 -1
  155. package/build/esm/tracing/sentryNonRecordingSpan.js +7 -0
  156. package/build/esm/tracing/sentryNonRecordingSpan.js.map +1 -1
  157. package/build/esm/tracing/sentrySpan.js +40 -1
  158. package/build/esm/tracing/sentrySpan.js.map +1 -1
  159. package/build/esm/tracing/spans/beforeSendSpan.js +40 -0
  160. package/build/esm/tracing/spans/beforeSendSpan.js.map +1 -0
  161. package/build/esm/tracing/spans/captureSpan.js +122 -0
  162. package/build/esm/tracing/spans/captureSpan.js.map +1 -0
  163. package/build/esm/tracing/spans/envelope.js +36 -0
  164. package/build/esm/tracing/spans/envelope.js.map +1 -0
  165. package/build/esm/tracing/spans/estimateSize.js +39 -0
  166. package/build/esm/tracing/spans/estimateSize.js.map +1 -0
  167. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js +9 -0
  168. package/build/esm/tracing/spans/hasSpanStreamingEnabled.js.map +1 -0
  169. package/build/esm/tracing/spans/spanBuffer.js +156 -0
  170. package/build/esm/tracing/spans/spanBuffer.js.map +1 -0
  171. package/build/esm/tracing/trace.js +84 -14
  172. package/build/esm/tracing/trace.js.map +1 -1
  173. package/build/esm/tracing/vercel-ai/utils.js +2 -5
  174. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  175. package/build/esm/utils/featureFlags.js +6 -0
  176. package/build/esm/utils/featureFlags.js.map +1 -1
  177. package/build/esm/utils/object.js +33 -1
  178. package/build/esm/utils/object.js.map +1 -1
  179. package/build/esm/utils/spanUtils.js +112 -14
  180. package/build/esm/utils/spanUtils.js.map +1 -1
  181. package/build/esm/utils/stacktrace.js +3 -1
  182. package/build/esm/utils/stacktrace.js.map +1 -1
  183. package/build/esm/utils/string.js +3 -0
  184. package/build/esm/utils/string.js.map +1 -1
  185. package/build/esm/utils/version.js +1 -1
  186. package/build/types/attributes.d.ts +5 -0
  187. package/build/types/attributes.d.ts.map +1 -1
  188. package/build/types/client.d.ts +35 -1
  189. package/build/types/client.d.ts.map +1 -1
  190. package/build/types/envelope.d.ts.map +1 -1
  191. package/build/types/index.d.ts +12 -4
  192. package/build/types/index.d.ts.map +1 -1
  193. package/build/types/integration.d.ts.map +1 -1
  194. package/build/types/integrations/express/index.d.ts +75 -0
  195. package/build/types/integrations/express/index.d.ts.map +1 -0
  196. package/build/types/integrations/express/patch-layer.d.ts +32 -0
  197. package/build/types/integrations/express/patch-layer.d.ts.map +1 -0
  198. package/build/types/integrations/express/request-layer-store.d.ts +32 -0
  199. package/build/types/integrations/express/request-layer-store.d.ts.map +1 -0
  200. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  201. package/build/types/integrations/express/set-sdk-processing-metadata.d.ts.map +1 -0
  202. package/build/types/integrations/express/types.d.ts +154 -0
  203. package/build/types/integrations/express/types.d.ts.map +1 -0
  204. package/build/types/integrations/express/utils.d.ts +93 -0
  205. package/build/types/integrations/express/utils.d.ts.map +1 -0
  206. package/build/types/integrations/mcp-server/correlation.d.ts +2 -1
  207. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  208. package/build/types/integrations/mcp-server/handlers.d.ts +9 -4
  209. package/build/types/integrations/mcp-server/handlers.d.ts.map +1 -1
  210. package/build/types/integrations/mcp-server/index.d.ts +2 -1
  211. package/build/types/integrations/mcp-server/index.d.ts.map +1 -1
  212. package/build/types/integrations/mcp-server/types.d.ts +40 -7
  213. package/build/types/integrations/mcp-server/types.d.ts.map +1 -1
  214. package/build/types/integrations/mcp-server/validation.d.ts +4 -1
  215. package/build/types/integrations/mcp-server/validation.d.ts.map +1 -1
  216. package/build/types/integrations/spanStreaming.d.ts +2 -0
  217. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  218. package/build/types/semanticAttributes.d.ts +23 -3
  219. package/build/types/semanticAttributes.d.ts.map +1 -1
  220. package/build/types/tracing/ai/gen-ai-attributes.d.ts +6 -38
  221. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  222. package/build/types/tracing/ai/utils.d.ts +21 -2
  223. package/build/types/tracing/ai/utils.d.ts.map +1 -1
  224. package/build/types/tracing/anthropic-ai/index.d.ts.map +1 -1
  225. package/build/types/tracing/anthropic-ai/streaming.d.ts.map +1 -1
  226. package/build/types/tracing/dynamicSamplingContext.d.ts.map +1 -1
  227. package/build/types/tracing/google-genai/constants.d.ts +1 -3
  228. package/build/types/tracing/google-genai/constants.d.ts.map +1 -1
  229. package/build/types/tracing/google-genai/index.d.ts.map +1 -1
  230. package/build/types/tracing/google-genai/streaming.d.ts.map +1 -1
  231. package/build/types/tracing/index.d.ts +1 -0
  232. package/build/types/tracing/index.d.ts.map +1 -1
  233. package/build/types/tracing/langchain/embeddings.d.ts +27 -0
  234. package/build/types/tracing/langchain/embeddings.d.ts.map +1 -0
  235. package/build/types/tracing/langchain/index.d.ts +1 -0
  236. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  237. package/build/types/tracing/openai/index.d.ts.map +1 -1
  238. package/build/types/tracing/openai/streaming.d.ts.map +1 -1
  239. package/build/types/tracing/openai/utils.d.ts +4 -49
  240. package/build/types/tracing/openai/utils.d.ts.map +1 -1
  241. package/build/types/tracing/sentryNonRecordingSpan.d.ts +12 -1
  242. package/build/types/tracing/sentryNonRecordingSpan.d.ts.map +1 -1
  243. package/build/types/tracing/sentrySpan.d.ts +10 -1
  244. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  245. package/build/types/tracing/spans/beforeSendSpan.d.ts +35 -0
  246. package/build/types/tracing/spans/beforeSendSpan.d.ts.map +1 -0
  247. package/build/types/tracing/spans/captureSpan.d.ts +26 -0
  248. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -0
  249. package/build/types/tracing/spans/envelope.d.ts +8 -0
  250. package/build/types/tracing/spans/envelope.d.ts.map +1 -0
  251. package/build/types/tracing/spans/estimateSize.d.ts +12 -0
  252. package/build/types/tracing/spans/estimateSize.d.ts.map +1 -0
  253. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  254. package/build/types/tracing/spans/hasSpanStreamingEnabled.d.ts.map +1 -0
  255. package/build/types/tracing/spans/spanBuffer.d.ts +60 -0
  256. package/build/types/tracing/spans/spanBuffer.d.ts.map +1 -0
  257. package/build/types/tracing/trace.d.ts.map +1 -1
  258. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  259. package/build/types/types-hoist/envelope.d.ts +22 -2
  260. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  261. package/build/types/types-hoist/integration.d.ts +8 -0
  262. package/build/types/types-hoist/integration.d.ts.map +1 -1
  263. package/build/types/types-hoist/link.d.ts +2 -2
  264. package/build/types/types-hoist/link.d.ts.map +1 -1
  265. package/build/types/types-hoist/options.d.ts +26 -2
  266. package/build/types/types-hoist/options.d.ts.map +1 -1
  267. package/build/types/types-hoist/span.d.ts +35 -0
  268. package/build/types/types-hoist/span.d.ts.map +1 -1
  269. package/build/types/utils/featureFlags.d.ts.map +1 -1
  270. package/build/types/utils/object.d.ts +10 -0
  271. package/build/types/utils/object.d.ts.map +1 -1
  272. package/build/types/utils/spanUtils.d.ts +27 -2
  273. package/build/types/utils/spanUtils.d.ts.map +1 -1
  274. package/build/types/utils/stacktrace.d.ts.map +1 -1
  275. package/build/types/utils/string.d.ts +2 -2
  276. package/build/types/utils/string.d.ts.map +1 -1
  277. package/build/types-ts3.8/attributes.d.ts +5 -0
  278. package/build/types-ts3.8/client.d.ts +35 -1
  279. package/build/types-ts3.8/index.d.ts +12 -4
  280. package/build/types-ts3.8/integrations/express/index.d.ts +75 -0
  281. package/build/types-ts3.8/integrations/express/patch-layer.d.ts +32 -0
  282. package/build/types-ts3.8/integrations/express/request-layer-store.d.ts +32 -0
  283. package/build/types-ts3.8/integrations/express/set-sdk-processing-metadata.d.ts +35 -0
  284. package/build/types-ts3.8/integrations/express/types.d.ts +154 -0
  285. package/build/types-ts3.8/integrations/express/utils.d.ts +96 -0
  286. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -1
  287. package/build/types-ts3.8/integrations/mcp-server/handlers.d.ts +9 -4
  288. package/build/types-ts3.8/integrations/mcp-server/index.d.ts +2 -1
  289. package/build/types-ts3.8/integrations/mcp-server/types.d.ts +40 -7
  290. package/build/types-ts3.8/integrations/mcp-server/validation.d.ts +4 -1
  291. package/build/types-ts3.8/integrations/spanStreaming.d.ts +2 -0
  292. package/build/types-ts3.8/semanticAttributes.d.ts +23 -3
  293. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +6 -38
  294. package/build/types-ts3.8/tracing/ai/utils.d.ts +21 -2
  295. package/build/types-ts3.8/tracing/google-genai/constants.d.ts +1 -3
  296. package/build/types-ts3.8/tracing/index.d.ts +1 -0
  297. package/build/types-ts3.8/tracing/langchain/embeddings.d.ts +27 -0
  298. package/build/types-ts3.8/tracing/langchain/index.d.ts +1 -0
  299. package/build/types-ts3.8/tracing/openai/utils.d.ts +4 -49
  300. package/build/types-ts3.8/tracing/sentryNonRecordingSpan.d.ts +12 -1
  301. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  302. package/build/types-ts3.8/tracing/spans/beforeSendSpan.d.ts +35 -0
  303. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +26 -0
  304. package/build/types-ts3.8/tracing/spans/envelope.d.ts +8 -0
  305. package/build/types-ts3.8/tracing/spans/estimateSize.d.ts +12 -0
  306. package/build/types-ts3.8/tracing/spans/hasSpanStreamingEnabled.d.ts +6 -0
  307. package/build/types-ts3.8/tracing/spans/spanBuffer.d.ts +60 -0
  308. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  309. package/build/types-ts3.8/types-hoist/integration.d.ts +8 -0
  310. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  311. package/build/types-ts3.8/types-hoist/options.d.ts +26 -2
  312. package/build/types-ts3.8/types-hoist/span.d.ts +35 -0
  313. package/build/types-ts3.8/utils/object.d.ts +10 -0
  314. package/build/types-ts3.8/utils/spanUtils.d.ts +27 -2
  315. package/build/types-ts3.8/utils/string.d.ts +2 -2
  316. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const index = require('../asyncContext/index.js');
4
+ const attributes = require('../attributes.js');
4
5
  const carrier = require('../carrier.js');
5
6
  const currentScopes = require('../currentScopes.js');
6
7
  const semanticAttributes = require('../semanticAttributes.js');
@@ -97,6 +98,26 @@ function convertSpanLinksForEnvelope(links) {
97
98
  }
98
99
  }
99
100
 
101
+ /**
102
+ * Converts the span links array to a flattened version with serialized attributes for V2 spans.
103
+ *
104
+ * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.
105
+ */
106
+ function getStreamedSpanLinks(
107
+ links,
108
+ ) {
109
+ if (links?.length) {
110
+ return links.map(({ context: { spanId, traceId, traceFlags }, attributes }) => ({
111
+ span_id: spanId,
112
+ trace_id: traceId,
113
+ sampled: traceFlags === TRACE_FLAG_SAMPLED,
114
+ attributes,
115
+ }));
116
+ } else {
117
+ return undefined;
118
+ }
119
+ }
120
+
100
121
  /**
101
122
  * Convert a span time input into a timestamp in seconds.
102
123
  */
@@ -142,23 +163,12 @@ function spanToJSON(span) {
142
163
  if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {
143
164
  const { attributes, startTime, name, endTime, status, links } = span;
144
165
 
145
- // In preparation for the next major of OpenTelemetry, we want to support
146
- // looking up the parent span id according to the new API
147
- // In OTel v1, the parent span id is accessed as `parentSpanId`
148
- // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`
149
- const parentSpanId =
150
- 'parentSpanId' in span
151
- ? span.parentSpanId
152
- : 'parentSpanContext' in span
153
- ? (span.parentSpanContext )?.spanId
154
- : undefined;
155
-
156
166
  return {
157
167
  span_id,
158
168
  trace_id,
159
169
  data: attributes,
160
170
  description: name,
161
- parent_span_id: parentSpanId,
171
+ parent_span_id: getOtelParentSpanId(span),
162
172
  start_timestamp: spanTimeInputToSeconds(startTime),
163
173
  // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time
164
174
  timestamp: spanTimeInputToSeconds(endTime) || undefined,
@@ -179,6 +189,77 @@ function spanToJSON(span) {
179
189
  };
180
190
  }
181
191
 
192
+ /**
193
+ * Convert a span to the intermediate {@link StreamedSpanJSON} representation.
194
+ */
195
+ function spanToStreamedSpanJSON(span) {
196
+ if (spanIsSentrySpan(span)) {
197
+ return span.getStreamedSpanJSON();
198
+ }
199
+
200
+ const { spanId: span_id, traceId: trace_id } = span.spanContext();
201
+
202
+ // Handle a span from @opentelemetry/sdk-base-trace's `Span` class
203
+ if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {
204
+ const { attributes, startTime, name, endTime, status, links } = span;
205
+
206
+ return {
207
+ name,
208
+ span_id,
209
+ trace_id,
210
+ parent_span_id: getOtelParentSpanId(span),
211
+ start_timestamp: spanTimeInputToSeconds(startTime),
212
+ end_timestamp: spanTimeInputToSeconds(endTime),
213
+ is_segment: span === INTERNAL_getSegmentSpan(span),
214
+ status: getSimpleStatusMessage(status),
215
+ attributes,
216
+ links: getStreamedSpanLinks(links),
217
+ };
218
+ }
219
+
220
+ // Finally, as a fallback, at least we have `spanContext()`....
221
+ // This should not actually happen in reality, but we need to handle it for type safety.
222
+ return {
223
+ span_id,
224
+ trace_id,
225
+ start_timestamp: 0,
226
+ name: '',
227
+ end_timestamp: 0,
228
+ status: 'ok',
229
+ is_segment: span === INTERNAL_getSegmentSpan(span),
230
+ };
231
+ }
232
+
233
+ /**
234
+ * In preparation for the next major of OpenTelemetry, we want to support
235
+ * looking up the parent span id according to the new API
236
+ * In OTel v1, the parent span id is accessed as `parentSpanId`
237
+ * In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`
238
+ */
239
+ function getOtelParentSpanId(span) {
240
+ return 'parentSpanId' in span
241
+ ? span.parentSpanId
242
+ : 'parentSpanContext' in span
243
+ ? (span.parentSpanContext )?.spanId
244
+ : undefined;
245
+ }
246
+
247
+ /**
248
+ * Converts a {@link StreamedSpanJSON} to a {@link SerializedSpan}.
249
+ * This is the final serialized span format that is sent to Sentry.
250
+ * The returned serilaized spans must not be consumed by users or SDK integrations.
251
+ */
252
+ function streamedSpanJsonToSerializedSpan(spanJson) {
253
+ return {
254
+ ...spanJson,
255
+ attributes: attributes.serializeAttributes(spanJson.attributes),
256
+ links: spanJson.links?.map(link => ({
257
+ ...link,
258
+ attributes: attributes.serializeAttributes(link.attributes),
259
+ })),
260
+ };
261
+ }
262
+
182
263
  function spanIsOpenTelemetrySdkTraceBaseSpan(span) {
183
264
  const castSpan = span ;
184
265
  return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;
@@ -220,6 +301,18 @@ function getStatusMessage(status) {
220
301
  return status.message || 'internal_error';
221
302
  }
222
303
 
304
+ /**
305
+ * Convert the various statuses to the simple onces expected by Sentry for steamed spans ('ok' is default).
306
+ */
307
+ function getSimpleStatusMessage(status) {
308
+ return !status ||
309
+ status.code === spanstatus.SPAN_STATUS_OK ||
310
+ status.code === spanstatus.SPAN_STATUS_UNSET ||
311
+ status.message === 'cancelled'
312
+ ? 'ok'
313
+ : 'error';
314
+ }
315
+
223
316
  const CHILD_SPANS_FIELD = '_sentryChildSpans';
224
317
  const ROOT_SPAN_FIELD = '_sentryRootSpan';
225
318
 
@@ -276,7 +369,12 @@ function getSpanDescendants(span) {
276
369
  /**
277
370
  * Returns the root span of a given span.
278
371
  */
279
- function getRootSpan(span) {
372
+ const getRootSpan = INTERNAL_getSegmentSpan;
373
+
374
+ /**
375
+ * Returns the segment span of a given span.
376
+ */
377
+ function INTERNAL_getSegmentSpan(span) {
280
378
  return span[ROOT_SPAN_FIELD] || span;
281
379
  }
282
380
 
@@ -332,22 +430,27 @@ function updateSpanName(span, name) {
332
430
  });
333
431
  }
334
432
 
433
+ exports.INTERNAL_getSegmentSpan = INTERNAL_getSegmentSpan;
335
434
  exports.TRACE_FLAG_NONE = TRACE_FLAG_NONE;
336
435
  exports.TRACE_FLAG_SAMPLED = TRACE_FLAG_SAMPLED;
337
436
  exports.addChildSpanToSpan = addChildSpanToSpan;
338
437
  exports.convertSpanLinksForEnvelope = convertSpanLinksForEnvelope;
339
438
  exports.getActiveSpan = getActiveSpan;
340
439
  exports.getRootSpan = getRootSpan;
440
+ exports.getSimpleStatusMessage = getSimpleStatusMessage;
341
441
  exports.getSpanDescendants = getSpanDescendants;
342
442
  exports.getStatusMessage = getStatusMessage;
443
+ exports.getStreamedSpanLinks = getStreamedSpanLinks;
343
444
  exports.removeChildSpanFromSpan = removeChildSpanFromSpan;
344
445
  exports.showSpanDropWarning = showSpanDropWarning;
345
446
  exports.spanIsSampled = spanIsSampled;
346
447
  exports.spanTimeInputToSeconds = spanTimeInputToSeconds;
347
448
  exports.spanToJSON = spanToJSON;
449
+ exports.spanToStreamedSpanJSON = spanToStreamedSpanJSON;
348
450
  exports.spanToTraceContext = spanToTraceContext;
349
451
  exports.spanToTraceHeader = spanToTraceHeader;
350
452
  exports.spanToTraceparentHeader = spanToTraceparentHeader;
351
453
  exports.spanToTransactionTraceContext = spanToTransactionTraceContext;
454
+ exports.streamedSpanJsonToSerializedSpan = streamedSpanJsonToSerializedSpan;
352
455
  exports.updateSpanName = updateSpanName;
353
456
  //# sourceMappingURL=spanUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spanUtils.js","sources":["../../../src/utils/spanUtils.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport { getCurrentScope } from '../currentScopes';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type { SentrySpan } from '../tracing/sentrySpan';\nimport { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus';\nimport { getCapturedScopesOnSpan } from '../tracing/utils';\nimport type { TraceContext } from '../types-hoist/context';\nimport type { SpanLink, SpanLinkJSON } from '../types-hoist/link';\nimport type { Span, SpanAttributes, SpanJSON, SpanOrigin, SpanTimeInput } from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { addNonEnumerableProperty } from '../utils/object';\nimport { generateSpanId } from '../utils/propagationContext';\nimport { timestampInSeconds } from '../utils/time';\nimport { generateSentryTraceHeader, generateTraceparentHeader } from '../utils/tracing';\nimport { consoleSandbox } from './debug-logger';\nimport { _getSpanForScope } from './spanOnScope';\n\n// These are aligned with OpenTelemetry trace flags\nexport const TRACE_FLAG_NONE = 0x0;\nexport const TRACE_FLAG_SAMPLED = 0x1;\n\nlet hasShownSpanDropWarning = false;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nexport function spanToTransactionTraceContext(span: Span): TraceContext {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { data, op, parent_span_id, status, origin, links } = spanToJSON(span);\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n data,\n op,\n status,\n origin,\n links,\n };\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nexport function spanToTraceContext(span: Span): TraceContext {\n const { spanId, traceId: trace_id, isRemote } = span.spanContext();\n\n // If the span is remote, we use a random/virtual span as span_id to the trace context,\n // and the remote span as parent_span_id\n const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id;\n const scope = getCapturedScopesOnSpan(span).scope;\n\n const span_id = isRemote ? scope?.getPropagationContext().propagationSpanId || generateSpanId() : spanId;\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n };\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nexport function spanToTraceHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a Span to a W3C traceparent header.\n */\nexport function spanToTraceparentHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateTraceparentHeader(traceId, spanId, sampled);\n}\n\n/**\n * Converts the span links array to a flattened version to be sent within an envelope.\n *\n * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.\n */\nexport function convertSpanLinksForEnvelope(links?: SpanLink[]): SpanLinkJSON[] | undefined {\n if (links && links.length > 0) {\n return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n attributes,\n ...restContext,\n }));\n } else {\n return undefined;\n }\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nexport function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number {\n if (typeof input === 'number') {\n return ensureTimestampInSeconds(input);\n }\n\n if (Array.isArray(input)) {\n // See {@link HrTime} for the array-based time format\n return input[0] + input[1] / 1e9;\n }\n\n if (input instanceof Date) {\n return ensureTimestampInSeconds(input.getTime());\n }\n\n return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp: number): number {\n const isMs = timestamp > 9999999999;\n return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nexport function spanToJSON(span: Span): SpanJSON {\n if (spanIsSentrySpan(span)) {\n return span.getSpanJSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n // In preparation for the next major of OpenTelemetry, we want to support\n // looking up the parent span id according to the new API\n // In OTel v1, the parent span id is accessed as `parentSpanId`\n // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`\n const parentSpanId =\n 'parentSpanId' in span\n ? span.parentSpanId\n : 'parentSpanContext' in span\n ? (span.parentSpanContext as { spanId?: string } | undefined)?.spanId\n : undefined;\n\n return {\n span_id,\n trace_id,\n data: attributes,\n description: name,\n parent_span_id: parentSpanId,\n start_timestamp: spanTimeInputToSeconds(startTime),\n // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n timestamp: spanTimeInputToSeconds(endTime) || undefined,\n status: getStatusMessage(status),\n op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n links: convertSpanLinksForEnvelope(links),\n };\n }\n\n // Finally, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n data: {},\n };\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span: Span): span is OpenTelemetrySdkTraceBaseSpan {\n const castSpan = span as Partial<OpenTelemetrySdkTraceBaseSpan>;\n return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\nexport interface OpenTelemetrySdkTraceBaseSpan extends Span {\n attributes: SpanAttributes;\n startTime: SpanTimeInput;\n name: string;\n status: SpanStatus;\n endTime: SpanTimeInput;\n parentSpanId?: string;\n links?: SpanLink[];\n}\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span: Span): span is SentrySpan {\n return typeof (span as SentrySpan).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nexport function spanIsSampled(span: Span): boolean {\n // We align our trace flags with the ones OpenTelemetry use\n // So we also check for sampled the same way they do.\n const { traceFlags } = span.spanContext();\n return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nexport function getStatusMessage(status: SpanStatus | undefined): string | undefined {\n if (!status || status.code === SPAN_STATUS_UNSET) {\n return undefined;\n }\n\n if (status.code === SPAN_STATUS_OK) {\n return 'ok';\n }\n\n return status.message || 'internal_error';\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\ntype SpanWithPotentialChildren = Span & {\n [CHILD_SPANS_FIELD]?: Set<Span>;\n [ROOT_SPAN_FIELD]?: Span;\n};\n\n/**\n * Adds an opaque child span reference to a span.\n */\nexport function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n // We store the root span reference on the child span\n // We need this for `getRootSpan()` to work\n const rootSpan = span[ROOT_SPAN_FIELD] || span;\n addNonEnumerableProperty(childSpan as SpanWithPotentialChildren, ROOT_SPAN_FIELD, rootSpan);\n\n // We store a list of child spans on the parent span\n // We need this for `getSpanDescendants()` to work\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].add(childSpan);\n } else {\n addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n }\n}\n\n/** This is only used internally by Idle Spans. */\nexport function removeChildSpanFromSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].delete(childSpan);\n }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nexport function getSpanDescendants(span: SpanWithPotentialChildren): Span[] {\n const resultSet = new Set<Span>();\n\n function addSpanChildren(span: SpanWithPotentialChildren): void {\n // This exit condition is required to not infinitely loop in case of a circular dependency.\n if (resultSet.has(span)) {\n return;\n // We want to ignore unsampled spans (e.g. non recording spans)\n } else if (spanIsSampled(span)) {\n resultSet.add(span);\n const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n for (const childSpan of childSpans) {\n addSpanChildren(childSpan);\n }\n }\n }\n\n addSpanChildren(span);\n\n return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nexport function getRootSpan(span: SpanWithPotentialChildren): Span {\n return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nexport function getActiveSpan(): Span | undefined {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getActiveSpan) {\n return acs.getActiveSpan();\n }\n\n return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Logs a warning once if `beforeSendSpan` is used to drop spans.\n */\nexport function showSpanDropWarning(): void {\n if (!hasShownSpanDropWarning) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.',\n );\n });\n hasShownSpanDropWarning = true;\n }\n}\n\n/**\n * Updates the name of the given span and ensures that the span name is not\n * overwritten by the Sentry SDK.\n *\n * Use this function instead of `span.updateName()` if you want to make sure that\n * your name is kept. For some spans, for example root `http.server` spans the\n * Sentry SDK would otherwise overwrite the span name with a high-quality name\n * it infers when the span ends.\n *\n * Use this function in server code or when your span is started on the server\n * and on the client (browser). If you only update a span name on the client,\n * you can also use `span.updateName()` the SDK does not overwrite the name.\n *\n * @param span - The span to update the name of.\n * @param name - The name to set on the span.\n */\nexport function updateSpanName(span: Span, name: string): void {\n span.updateName(name);\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name,\n });\n}\n"],"names":["getCapturedScopesOnSpan","generateSpanId","generateSentryTraceHeader","generateTraceparentHeader","timestampInSeconds","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SPAN_STATUS_UNSET","SPAN_STATUS_OK","addNonEnumerableProperty","carrier","getMainCarrier","getAsyncContextStrategy","_getSpanForScope","getCurrentScope","consoleSandbox","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME"],"mappings":"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"}
1
+ {"version":3,"file":"spanUtils.js","sources":["../../../src/utils/spanUtils.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport type { RawAttributes } from '../attributes';\nimport { serializeAttributes } from '../attributes';\nimport { getMainCarrier } from '../carrier';\nimport { getCurrentScope } from '../currentScopes';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type { SentrySpan } from '../tracing/sentrySpan';\nimport { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus';\nimport { getCapturedScopesOnSpan } from '../tracing/utils';\nimport type { TraceContext } from '../types-hoist/context';\nimport type { SpanLink, SpanLinkJSON } from '../types-hoist/link';\nimport type {\n SerializedStreamedSpan,\n Span,\n SpanAttributes,\n SpanJSON,\n SpanOrigin,\n SpanTimeInput,\n StreamedSpanJSON,\n} from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { addNonEnumerableProperty } from '../utils/object';\nimport { generateSpanId } from '../utils/propagationContext';\nimport { timestampInSeconds } from '../utils/time';\nimport { generateSentryTraceHeader, generateTraceparentHeader } from '../utils/tracing';\nimport { consoleSandbox } from './debug-logger';\nimport { _getSpanForScope } from './spanOnScope';\n\n// These are aligned with OpenTelemetry trace flags\nexport const TRACE_FLAG_NONE = 0x0;\nexport const TRACE_FLAG_SAMPLED = 0x1;\n\nlet hasShownSpanDropWarning = false;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nexport function spanToTransactionTraceContext(span: Span): TraceContext {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { data, op, parent_span_id, status, origin, links } = spanToJSON(span);\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n data,\n op,\n status,\n origin,\n links,\n };\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nexport function spanToTraceContext(span: Span): TraceContext {\n const { spanId, traceId: trace_id, isRemote } = span.spanContext();\n\n // If the span is remote, we use a random/virtual span as span_id to the trace context,\n // and the remote span as parent_span_id\n const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id;\n const scope = getCapturedScopesOnSpan(span).scope;\n\n const span_id = isRemote ? scope?.getPropagationContext().propagationSpanId || generateSpanId() : spanId;\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n };\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nexport function spanToTraceHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a Span to a W3C traceparent header.\n */\nexport function spanToTraceparentHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateTraceparentHeader(traceId, spanId, sampled);\n}\n\n/**\n * Converts the span links array to a flattened version to be sent within an envelope.\n *\n * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.\n */\nexport function convertSpanLinksForEnvelope(links?: SpanLink[]): SpanLinkJSON[] | undefined {\n if (links && links.length > 0) {\n return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n attributes,\n ...restContext,\n }));\n } else {\n return undefined;\n }\n}\n\n/**\n * Converts the span links array to a flattened version with serialized attributes for V2 spans.\n *\n * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.\n */\nexport function getStreamedSpanLinks(\n links?: SpanLink[],\n): SpanLinkJSON<RawAttributes<Record<string, unknown>>>[] | undefined {\n if (links?.length) {\n return links.map(({ context: { spanId, traceId, traceFlags }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n attributes,\n }));\n } else {\n return undefined;\n }\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nexport function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number {\n if (typeof input === 'number') {\n return ensureTimestampInSeconds(input);\n }\n\n if (Array.isArray(input)) {\n // See {@link HrTime} for the array-based time format\n return input[0] + input[1] / 1e9;\n }\n\n if (input instanceof Date) {\n return ensureTimestampInSeconds(input.getTime());\n }\n\n return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp: number): number {\n const isMs = timestamp > 9999999999;\n return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nexport function spanToJSON(span: Span): SpanJSON {\n if (spanIsSentrySpan(span)) {\n return span.getSpanJSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n return {\n span_id,\n trace_id,\n data: attributes,\n description: name,\n parent_span_id: getOtelParentSpanId(span),\n start_timestamp: spanTimeInputToSeconds(startTime),\n // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n timestamp: spanTimeInputToSeconds(endTime) || undefined,\n status: getStatusMessage(status),\n op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n links: convertSpanLinksForEnvelope(links),\n };\n }\n\n // Finally, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n data: {},\n };\n}\n\n/**\n * Convert a span to the intermediate {@link StreamedSpanJSON} representation.\n */\nexport function spanToStreamedSpanJSON(span: Span): StreamedSpanJSON {\n if (spanIsSentrySpan(span)) {\n return span.getStreamedSpanJSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n return {\n name,\n span_id,\n trace_id,\n parent_span_id: getOtelParentSpanId(span),\n start_timestamp: spanTimeInputToSeconds(startTime),\n end_timestamp: spanTimeInputToSeconds(endTime),\n is_segment: span === INTERNAL_getSegmentSpan(span),\n status: getSimpleStatusMessage(status),\n attributes,\n links: getStreamedSpanLinks(links),\n };\n }\n\n // Finally, as a fallback, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n name: '',\n end_timestamp: 0,\n status: 'ok',\n is_segment: span === INTERNAL_getSegmentSpan(span),\n };\n}\n\n/**\n * In preparation for the next major of OpenTelemetry, we want to support\n * looking up the parent span id according to the new API\n * In OTel v1, the parent span id is accessed as `parentSpanId`\n * In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`\n */\nfunction getOtelParentSpanId(span: OpenTelemetrySdkTraceBaseSpan): string | undefined {\n return 'parentSpanId' in span\n ? span.parentSpanId\n : 'parentSpanContext' in span\n ? (span.parentSpanContext as { spanId?: string } | undefined)?.spanId\n : undefined;\n}\n\n/**\n * Converts a {@link StreamedSpanJSON} to a {@link SerializedSpan}.\n * This is the final serialized span format that is sent to Sentry.\n * The returned serilaized spans must not be consumed by users or SDK integrations.\n */\nexport function streamedSpanJsonToSerializedSpan(spanJson: StreamedSpanJSON): SerializedStreamedSpan {\n return {\n ...spanJson,\n attributes: serializeAttributes(spanJson.attributes),\n links: spanJson.links?.map(link => ({\n ...link,\n attributes: serializeAttributes(link.attributes),\n })),\n };\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span: Span): span is OpenTelemetrySdkTraceBaseSpan {\n const castSpan = span as Partial<OpenTelemetrySdkTraceBaseSpan>;\n return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\nexport interface OpenTelemetrySdkTraceBaseSpan extends Span {\n attributes: SpanAttributes;\n startTime: SpanTimeInput;\n name: string;\n status: SpanStatus;\n endTime: SpanTimeInput;\n parentSpanId?: string;\n links?: SpanLink[];\n}\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span: Span): span is SentrySpan {\n return typeof (span as SentrySpan).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nexport function spanIsSampled(span: Span): boolean {\n // We align our trace flags with the ones OpenTelemetry use\n // So we also check for sampled the same way they do.\n const { traceFlags } = span.spanContext();\n return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nexport function getStatusMessage(status: SpanStatus | undefined): string | undefined {\n if (!status || status.code === SPAN_STATUS_UNSET) {\n return undefined;\n }\n\n if (status.code === SPAN_STATUS_OK) {\n return 'ok';\n }\n\n return status.message || 'internal_error';\n}\n\n/**\n * Convert the various statuses to the simple onces expected by Sentry for steamed spans ('ok' is default).\n */\nexport function getSimpleStatusMessage(status: SpanStatus | undefined): 'ok' | 'error' {\n return !status ||\n status.code === SPAN_STATUS_OK ||\n status.code === SPAN_STATUS_UNSET ||\n status.message === 'cancelled'\n ? 'ok'\n : 'error';\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\ntype SpanWithPotentialChildren = Span & {\n [CHILD_SPANS_FIELD]?: Set<Span>;\n [ROOT_SPAN_FIELD]?: Span;\n};\n\n/**\n * Adds an opaque child span reference to a span.\n */\nexport function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n // We store the root span reference on the child span\n // We need this for `getRootSpan()` to work\n const rootSpan = span[ROOT_SPAN_FIELD] || span;\n addNonEnumerableProperty(childSpan as SpanWithPotentialChildren, ROOT_SPAN_FIELD, rootSpan);\n\n // We store a list of child spans on the parent span\n // We need this for `getSpanDescendants()` to work\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].add(childSpan);\n } else {\n addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n }\n}\n\n/** This is only used internally by Idle Spans. */\nexport function removeChildSpanFromSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].delete(childSpan);\n }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nexport function getSpanDescendants(span: SpanWithPotentialChildren): Span[] {\n const resultSet = new Set<Span>();\n\n function addSpanChildren(span: SpanWithPotentialChildren): void {\n // This exit condition is required to not infinitely loop in case of a circular dependency.\n if (resultSet.has(span)) {\n return;\n // We want to ignore unsampled spans (e.g. non recording spans)\n } else if (spanIsSampled(span)) {\n resultSet.add(span);\n const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n for (const childSpan of childSpans) {\n addSpanChildren(childSpan);\n }\n }\n }\n\n addSpanChildren(span);\n\n return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nexport const getRootSpan = INTERNAL_getSegmentSpan;\n\n/**\n * Returns the segment span of a given span.\n */\nexport function INTERNAL_getSegmentSpan(span: SpanWithPotentialChildren): Span {\n return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nexport function getActiveSpan(): Span | undefined {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getActiveSpan) {\n return acs.getActiveSpan();\n }\n\n return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Logs a warning once if `beforeSendSpan` is used to drop spans.\n */\nexport function showSpanDropWarning(): void {\n if (!hasShownSpanDropWarning) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.',\n );\n });\n hasShownSpanDropWarning = true;\n }\n}\n\n/**\n * Updates the name of the given span and ensures that the span name is not\n * overwritten by the Sentry SDK.\n *\n * Use this function instead of `span.updateName()` if you want to make sure that\n * your name is kept. For some spans, for example root `http.server` spans the\n * Sentry SDK would otherwise overwrite the span name with a high-quality name\n * it infers when the span ends.\n *\n * Use this function in server code or when your span is started on the server\n * and on the client (browser). If you only update a span name on the client,\n * you can also use `span.updateName()` the SDK does not overwrite the name.\n *\n * @param span - The span to update the name of.\n * @param name - The name to set on the span.\n */\nexport function updateSpanName(span: Span, name: string): void {\n span.updateName(name);\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name,\n });\n}\n"],"names":["getCapturedScopesOnSpan","generateSpanId","generateSentryTraceHeader","generateTraceparentHeader","timestampInSeconds","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","serializeAttributes","SPAN_STATUS_UNSET","SPAN_STATUS_OK","addNonEnumerableProperty","carrier","getMainCarrier","getAsyncContextStrategy","_getSpanForScope","getCurrentScope","consoleSandbox","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME"],"mappings":"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"}
@@ -36,7 +36,9 @@ function createStackParser(...parsers) {
36
36
 
37
37
  // https://github.com/getsentry/sentry-javascript/issues/7813
38
38
  // Skip Error: lines
39
- if (cleanedLine.match(/\S*Error: /)) {
39
+ // Using includes() instead of a regex to avoid O() backtracking on long lines
40
+ // https://github.com/getsentry/sentry-javascript/issues/20052
41
+ if (cleanedLine.includes('Error: ')) {
40
42
  continue;
41
43
  }
42
44
 
@@ -1 +1 @@
1
- {"version":3,"file":"stacktrace.js","sources":["../../../src/utils/stacktrace.ts"],"sourcesContent":["import type { Event } from '../types-hoist/event';\nimport type { StackFrame } from '../types-hoist/stackframe';\nimport type { StackLineParser, StackParser } from '../types-hoist/stacktrace';\nimport type { VNode, VueViewModel } from '../types-hoist/vue';\n\nconst STACKTRACE_FRAME_LIMIT = 50;\nexport const UNKNOWN_FUNCTION = '?';\n// Used to sanitize webpack (error: *) wrapped stack errors\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STRIP_FRAME_REGEXP = /captureMessage|captureException/;\n\n/**\n * Creates a stack parser with the supplied line parsers\n *\n * StackFrames are returned in the correct order for Sentry Exception\n * frames and with Sentry SDK internal frames removed from the top and bottom\n *\n */\nexport function createStackParser(...parsers: StackLineParser[]): StackParser {\n const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);\n\n return (stack: string, skipFirstLines: number = 0, framesToPop: number = 0): StackFrame[] => {\n const frames: StackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (let i = skipFirstLines; i < lines.length; i++) {\n let line = lines[i] as string;\n // Truncate lines over 1kb because many of the regular expressions use\n // backtracking which results in run time that increases exponentially\n // with input size. Huge strings can result in hangs/Denial of Service:\n // https://github.com/getsentry/sentry-javascript/issues/2286\n if (line.length > 1024) {\n line = line.slice(0, 1024);\n }\n\n // https://github.com/getsentry/sentry-javascript/issues/5459\n // Remove webpack (error: *) wrappers\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n\n // https://github.com/getsentry/sentry-javascript/issues/7813\n // Skip Error: lines\n if (cleanedLine.match(/\\S*Error: /)) {\n continue;\n }\n\n for (const parser of sortedParsers) {\n const frame = parser(cleanedLine);\n\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n\n if (frames.length >= STACKTRACE_FRAME_LIMIT + framesToPop) {\n break;\n }\n }\n\n return stripSentryFramesAndReverse(frames.slice(framesToPop));\n };\n}\n\n/**\n * Gets a stack parser implementation from Options.stackParser\n * @see Options\n *\n * If options contains an array of line parsers, it is converted into a parser\n */\nexport function stackParserFromStackParserOptions(stackParser: StackParser | StackLineParser[]): StackParser {\n if (Array.isArray(stackParser)) {\n return createStackParser(...stackParser);\n }\n return stackParser;\n}\n\n/**\n * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.\n * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the\n * function that caused the crash is the last frame in the array.\n * @hidden\n */\nexport function stripSentryFramesAndReverse(stack: ReadonlyArray<StackFrame>): StackFrame[] {\n if (!stack.length) {\n return [];\n }\n\n const localStack = Array.from(stack);\n\n // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)\n if (/sentryWrapped/.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n\n // Reversing in the middle of the procedure allows us to just pop the values off the stack\n localStack.reverse();\n\n // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n\n // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')`\n // is produced within the scope itself, making it:\n //\n // Sentry.captureException()\n // scope.captureException()\n //\n // instead of just the top `Sentry` call itself.\n // This forces us to possibly strip an additional frame in the exact same was as above.\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n }\n\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION,\n }));\n}\n\nfunction getLastStackFrame(arr: StackFrame[]): StackFrame {\n return arr[arr.length - 1] || {};\n}\n\nconst defaultFunctionName = '<anonymous>';\n\n/**\n * Safely extract function name from itself\n */\nexport function getFunctionName(fn: unknown): string {\n try {\n if (!fn || typeof fn !== 'function') {\n return defaultFunctionName;\n }\n return fn.name || defaultFunctionName;\n } catch {\n // Just accessing custom props in some Selenium environments\n // can cause a \"Permission denied\" exception (see raven-js#495).\n return defaultFunctionName;\n }\n}\n\n/**\n * Get's stack frames from an event without needing to check for undefined properties.\n */\nexport function getFramesFromEvent(event: Event): StackFrame[] | undefined {\n const exception = event.exception;\n\n if (exception) {\n const frames: StackFrame[] = [];\n try {\n // @ts-expect-error Object could be undefined\n exception.values.forEach(value => {\n // @ts-expect-error Value could be undefined\n if (value.stacktrace.frames) {\n // @ts-expect-error Value could be undefined\n frames.push(...value.stacktrace.frames);\n }\n });\n return frames;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n/**\n * Get the internal name of an internal Vue value, to represent it in a stacktrace.\n *\n * @param value The value to get the internal name of.\n */\nexport function getVueInternalName(value: VueViewModel | VNode): string {\n // Check if it's a VNode (has __v_isVNode) or a component instance (has _isVue/__isVue)\n const isVNode = '__v_isVNode' in value && value.__v_isVNode;\n\n return isVNode ? '[VueVNode]' : '[VueViewModel]';\n}\n\n/**\n * Normalizes stack line paths by removing file:// prefix and leading slashes for Windows paths\n */\nexport function normalizeStackTracePath(path: string | undefined): string | undefined {\n let filename = path?.startsWith('file://') ? path.slice(7) : path;\n // If it's a Windows path, trim the leading slash so that `/C:/foo` becomes `C:/foo`\n if (filename?.match(/\\/[A-Z]:/)) {\n filename = filename.slice(1);\n }\n return filename;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stacktrace.js","sources":["../../../src/utils/stacktrace.ts"],"sourcesContent":["import type { Event } from '../types-hoist/event';\nimport type { StackFrame } from '../types-hoist/stackframe';\nimport type { StackLineParser, StackParser } from '../types-hoist/stacktrace';\nimport type { VNode, VueViewModel } from '../types-hoist/vue';\n\nconst STACKTRACE_FRAME_LIMIT = 50;\nexport const UNKNOWN_FUNCTION = '?';\n// Used to sanitize webpack (error: *) wrapped stack errors\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STRIP_FRAME_REGEXP = /captureMessage|captureException/;\n\n/**\n * Creates a stack parser with the supplied line parsers\n *\n * StackFrames are returned in the correct order for Sentry Exception\n * frames and with Sentry SDK internal frames removed from the top and bottom\n *\n */\nexport function createStackParser(...parsers: StackLineParser[]): StackParser {\n const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);\n\n return (stack: string, skipFirstLines: number = 0, framesToPop: number = 0): StackFrame[] => {\n const frames: StackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (let i = skipFirstLines; i < lines.length; i++) {\n let line = lines[i] as string;\n // Truncate lines over 1kb because many of the regular expressions use\n // backtracking which results in run time that increases exponentially\n // with input size. Huge strings can result in hangs/Denial of Service:\n // https://github.com/getsentry/sentry-javascript/issues/2286\n if (line.length > 1024) {\n line = line.slice(0, 1024);\n }\n\n // https://github.com/getsentry/sentry-javascript/issues/5459\n // Remove webpack (error: *) wrappers\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n\n // https://github.com/getsentry/sentry-javascript/issues/7813\n // Skip Error: lines\n // Using includes() instead of a regex to avoid O(n²) backtracking on long lines\n // https://github.com/getsentry/sentry-javascript/issues/20052\n if (cleanedLine.includes('Error: ')) {\n continue;\n }\n\n for (const parser of sortedParsers) {\n const frame = parser(cleanedLine);\n\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n\n if (frames.length >= STACKTRACE_FRAME_LIMIT + framesToPop) {\n break;\n }\n }\n\n return stripSentryFramesAndReverse(frames.slice(framesToPop));\n };\n}\n\n/**\n * Gets a stack parser implementation from Options.stackParser\n * @see Options\n *\n * If options contains an array of line parsers, it is converted into a parser\n */\nexport function stackParserFromStackParserOptions(stackParser: StackParser | StackLineParser[]): StackParser {\n if (Array.isArray(stackParser)) {\n return createStackParser(...stackParser);\n }\n return stackParser;\n}\n\n/**\n * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.\n * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the\n * function that caused the crash is the last frame in the array.\n * @hidden\n */\nexport function stripSentryFramesAndReverse(stack: ReadonlyArray<StackFrame>): StackFrame[] {\n if (!stack.length) {\n return [];\n }\n\n const localStack = Array.from(stack);\n\n // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)\n if (/sentryWrapped/.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n\n // Reversing in the middle of the procedure allows us to just pop the values off the stack\n localStack.reverse();\n\n // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n\n // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')`\n // is produced within the scope itself, making it:\n //\n // Sentry.captureException()\n // scope.captureException()\n //\n // instead of just the top `Sentry` call itself.\n // This forces us to possibly strip an additional frame in the exact same was as above.\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n }\n\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION,\n }));\n}\n\nfunction getLastStackFrame(arr: StackFrame[]): StackFrame {\n return arr[arr.length - 1] || {};\n}\n\nconst defaultFunctionName = '<anonymous>';\n\n/**\n * Safely extract function name from itself\n */\nexport function getFunctionName(fn: unknown): string {\n try {\n if (!fn || typeof fn !== 'function') {\n return defaultFunctionName;\n }\n return fn.name || defaultFunctionName;\n } catch {\n // Just accessing custom props in some Selenium environments\n // can cause a \"Permission denied\" exception (see raven-js#495).\n return defaultFunctionName;\n }\n}\n\n/**\n * Get's stack frames from an event without needing to check for undefined properties.\n */\nexport function getFramesFromEvent(event: Event): StackFrame[] | undefined {\n const exception = event.exception;\n\n if (exception) {\n const frames: StackFrame[] = [];\n try {\n // @ts-expect-error Object could be undefined\n exception.values.forEach(value => {\n // @ts-expect-error Value could be undefined\n if (value.stacktrace.frames) {\n // @ts-expect-error Value could be undefined\n frames.push(...value.stacktrace.frames);\n }\n });\n return frames;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\n/**\n * Get the internal name of an internal Vue value, to represent it in a stacktrace.\n *\n * @param value The value to get the internal name of.\n */\nexport function getVueInternalName(value: VueViewModel | VNode): string {\n // Check if it's a VNode (has __v_isVNode) or a component instance (has _isVue/__isVue)\n const isVNode = '__v_isVNode' in value && value.__v_isVNode;\n\n return isVNode ? '[VueVNode]' : '[VueViewModel]';\n}\n\n/**\n * Normalizes stack line paths by removing file:// prefix and leading slashes for Windows paths\n */\nexport function normalizeStackTracePath(path: string | undefined): string | undefined {\n let filename = path?.startsWith('file://') ? path.slice(7) : path;\n // If it's a Windows path, trim the leading slash so that `/C:/foo` becomes `C:/foo`\n if (filename?.match(/\\/[A-Z]:/)) {\n filename = filename.slice(1);\n }\n return filename;\n}\n"],"names":[],"mappings":"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"}
@@ -117,6 +117,9 @@ function isMatchingPattern(
117
117
  if (is.isString(pattern)) {
118
118
  return requireExactStringMatch ? value === pattern : value.includes(pattern);
119
119
  }
120
+ if (typeof pattern === 'function') {
121
+ return pattern(value);
122
+ }
120
123
 
121
124
  return false;
122
125
  }
@@ -1 +1 @@
1
- {"version":3,"file":"string.js","sources":["../../../src/utils/string.ts"],"sourcesContent":["import { isRegExp, isString, isVueViewModel } from './is';\nimport { getVueInternalName } from './stacktrace';\n\nexport { escapeStringForRegex } from '../vendor/escapeStringForRegex';\n\n/**\n * Truncates given string to the maximum characters count\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string (0 = unlimited)\n * @returns string Encoded\n */\nexport function truncate(str: string, max: number = 0): string {\n if (typeof str !== 'string' || max === 0) {\n return str;\n }\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\n\n/**\n * This is basically just `trim_line` from\n * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string\n * @returns string Encoded\n */\nexport function snipLine(line: string, colno: number): string {\n let newLine = line;\n const lineLength = newLine.length;\n if (lineLength <= 150) {\n return newLine;\n }\n if (colno > lineLength) {\n // eslint-disable-next-line no-param-reassign\n colno = lineLength;\n }\n\n let start = Math.max(colno - 60, 0);\n if (start < 5) {\n start = 0;\n }\n\n let end = Math.min(start + 140, lineLength);\n if (end > lineLength - 5) {\n end = lineLength;\n }\n if (end === lineLength) {\n start = Math.max(end - 140, 0);\n }\n\n newLine = newLine.slice(start, end);\n if (start > 0) {\n newLine = `'{snip} ${newLine}`;\n }\n if (end < lineLength) {\n newLine += ' {snip}';\n }\n\n return newLine;\n}\n\n/**\n * Join values in array\n * @param input array of values to be joined together\n * @param delimiter string to be placed in-between values\n * @returns Joined values\n */\nexport function safeJoin(input: unknown[], delimiter?: string): string {\n if (!Array.isArray(input)) {\n return '';\n }\n\n const output = [];\n // eslint-disable-next-line typescript/prefer-for-of\n for (let i = 0; i < input.length; i++) {\n const value = input[i];\n try {\n // This is a hack to fix a Vue3-specific bug that causes an infinite loop of\n // console warnings. This happens when a Vue template is rendered with\n // an undeclared variable, which we try to stringify, ultimately causing\n // Vue to issue another warning which repeats indefinitely.\n // see: https://github.com/getsentry/sentry-javascript/pull/8981\n if (isVueViewModel(value)) {\n output.push(getVueInternalName(value));\n } else {\n output.push(String(value));\n }\n } catch {\n output.push('[value cannot be serialized]');\n }\n }\n\n return output.join(delimiter);\n}\n\n/**\n * Checks if the given value matches a regex or string\n *\n * @param value The string to test\n * @param pattern Either a regex or a string against which `value` will be matched\n * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match\n * `pattern` if it contains `pattern`. Only applies to string-type patterns.\n */\nexport function isMatchingPattern(\n value: string,\n pattern: RegExp | string,\n requireExactStringMatch: boolean = false,\n): boolean {\n if (!isString(value)) {\n return false;\n }\n\n if (isRegExp(pattern)) {\n return pattern.test(value);\n }\n if (isString(pattern)) {\n return requireExactStringMatch ? value === pattern : value.includes(pattern);\n }\n\n return false;\n}\n\n/**\n * Test the given string against an array of strings and regexes. By default, string matching is done on a\n * substring-inclusion basis rather than a strict equality basis\n *\n * @param testString The string to test\n * @param patterns The patterns against which to test the string\n * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to\n * count. If false, `testString` will match a string pattern if it contains that pattern.\n * @returns\n */\nexport function stringMatchesSomePattern(\n testString: string,\n patterns: Array<string | RegExp> = [],\n requireExactStringMatch: boolean = false,\n): boolean {\n return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));\n}\n"],"names":["isVueViewModel","getVueInternalName","isString","isRegExp"],"mappings":"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"}
1
+ {"version":3,"file":"string.js","sources":["../../../src/utils/string.ts"],"sourcesContent":["import { isRegExp, isString, isVueViewModel } from './is';\nimport { getVueInternalName } from './stacktrace';\n\nexport { escapeStringForRegex } from '../vendor/escapeStringForRegex';\n\n/**\n * Truncates given string to the maximum characters count\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string (0 = unlimited)\n * @returns string Encoded\n */\nexport function truncate(str: string, max: number = 0): string {\n if (typeof str !== 'string' || max === 0) {\n return str;\n }\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\n\n/**\n * This is basically just `trim_line` from\n * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string\n * @returns string Encoded\n */\nexport function snipLine(line: string, colno: number): string {\n let newLine = line;\n const lineLength = newLine.length;\n if (lineLength <= 150) {\n return newLine;\n }\n if (colno > lineLength) {\n // eslint-disable-next-line no-param-reassign\n colno = lineLength;\n }\n\n let start = Math.max(colno - 60, 0);\n if (start < 5) {\n start = 0;\n }\n\n let end = Math.min(start + 140, lineLength);\n if (end > lineLength - 5) {\n end = lineLength;\n }\n if (end === lineLength) {\n start = Math.max(end - 140, 0);\n }\n\n newLine = newLine.slice(start, end);\n if (start > 0) {\n newLine = `'{snip} ${newLine}`;\n }\n if (end < lineLength) {\n newLine += ' {snip}';\n }\n\n return newLine;\n}\n\n/**\n * Join values in array\n * @param input array of values to be joined together\n * @param delimiter string to be placed in-between values\n * @returns Joined values\n */\nexport function safeJoin(input: unknown[], delimiter?: string): string {\n if (!Array.isArray(input)) {\n return '';\n }\n\n const output = [];\n // eslint-disable-next-line typescript/prefer-for-of\n for (let i = 0; i < input.length; i++) {\n const value = input[i];\n try {\n // This is a hack to fix a Vue3-specific bug that causes an infinite loop of\n // console warnings. This happens when a Vue template is rendered with\n // an undeclared variable, which we try to stringify, ultimately causing\n // Vue to issue another warning which repeats indefinitely.\n // see: https://github.com/getsentry/sentry-javascript/pull/8981\n if (isVueViewModel(value)) {\n output.push(getVueInternalName(value));\n } else {\n output.push(String(value));\n }\n } catch {\n output.push('[value cannot be serialized]');\n }\n }\n\n return output.join(delimiter);\n}\n\n/**\n * Checks if the given value matches a regex or string\n *\n * @param value The string to test\n * @param pattern Either a regex or a string against which `value` will be matched\n * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match\n * `pattern` if it contains `pattern`. Only applies to string-type patterns.\n */\nexport function isMatchingPattern(\n value: string,\n pattern: RegExp | string | ((value: string) => boolean),\n requireExactStringMatch: boolean = false,\n): boolean {\n if (!isString(value)) {\n return false;\n }\n\n if (isRegExp(pattern)) {\n return pattern.test(value);\n }\n if (isString(pattern)) {\n return requireExactStringMatch ? value === pattern : value.includes(pattern);\n }\n if (typeof pattern === 'function') {\n return pattern(value);\n }\n\n return false;\n}\n\n/**\n * Test the given string against an array of strings and regexes. By default, string matching is done on a\n * substring-inclusion basis rather than a strict equality basis\n *\n * @param testString The string to test\n * @param patterns The patterns against which to test the string\n * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to\n * count. If false, `testString` will match a string pattern if it contains that pattern.\n * @returns\n */\nexport function stringMatchesSomePattern(\n testString: string,\n patterns: Array<string | RegExp | ((value: string) => boolean)> = [],\n requireExactStringMatch: boolean = false,\n): boolean {\n return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));\n}\n"],"names":["isVueViewModel","getVueInternalName","isString","isRegExp"],"mappings":"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"}
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  // This is a magic string replaced by rollup
4
4
 
5
- const SDK_VERSION = "10.47.0" ;
5
+ const SDK_VERSION = "10.48.0" ;
6
6
 
7
7
  exports.SDK_VERSION = SDK_VERSION;
8
8
  //# sourceMappingURL=version.js.map
@@ -1,3 +1,5 @@
1
+ import { isPrimitive } from './utils/is.js';
2
+
1
3
  /**
2
4
  * Type-guard: The attribute object has the shape the official attribute object (value, type, unit).
3
5
  * https://develop.sentry.dev/sdk/telemetry/scopes/#setting-attributes
@@ -77,6 +79,46 @@ function serializeAttributes(
77
79
  return serializedAttributes;
78
80
  }
79
81
 
82
+ /**
83
+ * Estimates the serialized byte size of {@link Attributes},
84
+ * with a couple of heuristics for performance.
85
+ */
86
+ function estimateTypedAttributesSizeInBytes(attributes) {
87
+ if (!attributes) {
88
+ return 0;
89
+ }
90
+ let weight = 0;
91
+ for (const [key, attr] of Object.entries(attributes)) {
92
+ weight += key.length * 2;
93
+ weight += attr.type.length * 2;
94
+ weight += (attr.unit?.length ?? 0) * 2;
95
+ const val = attr.value;
96
+
97
+ if (Array.isArray(val)) {
98
+ // Assumption: Individual array items have the same type and roughly the same size
99
+ // probably not always true but allows us to cut down on runtime
100
+ weight += estimatePrimitiveSizeInBytes(val[0]) * val.length;
101
+ } else if (isPrimitive(val)) {
102
+ weight += estimatePrimitiveSizeInBytes(val);
103
+ } else {
104
+ // default fallback for anything else (objects)
105
+ weight += 100;
106
+ }
107
+ }
108
+ return weight;
109
+ }
110
+
111
+ function estimatePrimitiveSizeInBytes(value) {
112
+ if (typeof value === 'string') {
113
+ return value.length * 2;
114
+ } else if (typeof value === 'boolean') {
115
+ return 4;
116
+ } else if (typeof value === 'number') {
117
+ return 8;
118
+ }
119
+ return 0;
120
+ }
121
+
80
122
  /**
81
123
  * NOTE: We intentionally do not return anything for non-primitive values:
82
124
  * - array support will come in the future but if we stringify arrays now,
@@ -110,5 +152,5 @@ function getTypedAttributeValue(value) {
110
152
  }
111
153
  }
112
154
 
113
- export { attributeValueToTypedAttributeValue, isAttributeObject, serializeAttributes };
155
+ export { attributeValueToTypedAttributeValue, estimateTypedAttributesSizeInBytes, isAttributeObject, serializeAttributes };
114
156
  //# sourceMappingURL=attributes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attributes.js","sources":["../../src/attributes.ts"],"sourcesContent":["import type { DurationUnit, FractionUnit, InformationUnit } from './types-hoist/measurement';\n\nexport type RawAttributes<T> = T & ValidatedAttributes<T>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RawAttribute<T> = T extends { value: any } | { unit: any } ? AttributeObject : T;\n\nexport type Attributes = Record<string, TypedAttributeValue>;\n\nexport type AttributeValueType = string | number | boolean | Array<string> | Array<number> | Array<boolean>;\n\ntype AttributeTypeMap = {\n string: string;\n integer: number;\n double: number;\n boolean: boolean;\n 'string[]': Array<string>;\n 'integer[]': Array<number>;\n 'double[]': Array<number>;\n 'boolean[]': Array<boolean>;\n};\n\n/* Generates a type from the AttributeTypeMap like:\n | { value: string; type: 'string' }\n | { value: number; type: 'integer' }\n | { value: number; type: 'double' }\n */\ntype AttributeUnion = {\n [K in keyof AttributeTypeMap]: {\n value: AttributeTypeMap[K];\n type: K;\n };\n}[keyof AttributeTypeMap];\n\nexport type TypedAttributeValue = AttributeUnion & { unit?: AttributeUnit };\n\nexport type AttributeObject = {\n value: unknown;\n unit?: AttributeUnit;\n};\n\n// Unfortunately, we loose type safety if we did something like Exclude<MeasurementUnit, string>\n// so therefore we unionize between the three supported unit categories.\ntype AttributeUnit = DurationUnit | InformationUnit | FractionUnit;\n\n/* If an attribute has either a 'value' or 'unit' property, we use the ValidAttributeObject type. */\nexport type ValidatedAttributes<T> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in keyof T]: T[K] extends { value: any } | { unit: any } ? AttributeObject : unknown;\n};\n\n/**\n * Type-guard: The attribute object has the shape the official attribute object (value, type, unit).\n * https://develop.sentry.dev/sdk/telemetry/scopes/#setting-attributes\n */\nexport function isAttributeObject(maybeObj: unknown): maybeObj is AttributeObject {\n return (\n typeof maybeObj === 'object' &&\n maybeObj != null &&\n !Array.isArray(maybeObj) &&\n Object.keys(maybeObj).includes('value')\n );\n}\n\n/**\n * Converts an attribute value to a typed attribute value.\n *\n * For now, we intentionally only support primitive values and attribute objects with primitive values.\n * If @param useFallback is true, we stringify non-primitive values to a string attribute value. Otherwise\n * we return `undefined` for unsupported values.\n *\n * @param value - The value of the passed attribute.\n * @param useFallback - If true, unsupported values will be stringified to a string attribute value.\n * Defaults to false. In this case, `undefined` is returned for unsupported values.\n * @returns The typed attribute.\n */\nexport function attributeValueToTypedAttributeValue(\n rawValue: unknown,\n useFallback?: boolean | 'skip-undefined',\n): TypedAttributeValue | void {\n const { value, unit } = isAttributeObject(rawValue) ? rawValue : { value: rawValue, unit: undefined };\n const attributeValue = getTypedAttributeValue(value);\n const checkedUnit = unit && typeof unit === 'string' ? { unit } : {};\n if (attributeValue) {\n return { ...attributeValue, ...checkedUnit };\n }\n\n if (!useFallback || (useFallback === 'skip-undefined' && value === undefined)) {\n return;\n }\n\n // Fallback: stringify the value\n // TODO(v11): be smarter here and use String constructor if stringify fails\n // (this is a breaking change for already existing attribute values)\n let stringValue = '';\n try {\n stringValue = JSON.stringify(value) ?? '';\n } catch {\n // Do nothing\n }\n return {\n value: stringValue,\n type: 'string',\n ...checkedUnit,\n };\n}\n\n/**\n * Serializes raw attributes to typed attributes as expected in our envelopes.\n *\n * @param attributes The raw attributes to serialize.\n * @param fallback If true, unsupported values will be stringified to a string attribute value.\n * Defaults to false. In this case, `undefined` is returned for unsupported values.\n *\n * @returns The serialized attributes.\n */\nexport function serializeAttributes<T>(\n attributes: RawAttributes<T> | undefined,\n fallback: boolean | 'skip-undefined' = false,\n): Attributes {\n const serializedAttributes: Attributes = {};\n for (const [key, value] of Object.entries(attributes ?? {})) {\n const typedValue = attributeValueToTypedAttributeValue(value, fallback);\n if (typedValue) {\n serializedAttributes[key] = typedValue;\n }\n }\n return serializedAttributes;\n}\n\n/**\n * NOTE: We intentionally do not return anything for non-primitive values:\n * - array support will come in the future but if we stringify arrays now,\n * sending arrays (unstringified) later will be a subtle breaking change.\n * - Objects are not supported yet and product support is still TBD.\n * - We still keep the type signature for TypedAttributeValue wider to avoid a\n * breaking change once we add support for non-primitive values.\n * - Once we go back to supporting arrays and stringifying all other values,\n * we already implemented the serialization logic here:\n * https://github.com/getsentry/sentry-javascript/pull/18165\n */\nfunction getTypedAttributeValue(value: unknown): TypedAttributeValue | void {\n const primitiveType =\n typeof value === 'string'\n ? 'string'\n : typeof value === 'boolean'\n ? 'boolean'\n : typeof value === 'number' && !Number.isNaN(value)\n ? Number.isInteger(value)\n ? 'integer'\n : 'double'\n : null;\n if (primitiveType) {\n // @ts-expect-error - TS complains because {@link TypedAttributeValue} is strictly typed to\n // avoid setting the wrong `type` on the attribute value.\n // In this case, getPrimitiveType already does the check but TS doesn't know that.\n // The \"clean\" alternative is to return an object per `typeof value` case\n // but that would require more bundle size\n // Therefore, we ignore it.\n return { value, type: primitiveType };\n }\n}\n"],"names":[],"mappings":"AAkDA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,QAAQ,EAAwC;AAClF,EAAE;AACF,IAAI,OAAO,QAAA,KAAa,QAAA;AACxB,IAAI,QAAA,IAAY,IAAA;AAChB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAA;AAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO;AAC1C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mCAAmC;AACnD,EAAE,QAAQ;AACV,EAAE,WAAW;AACb,EAA8B;AAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,MAAK,GAAI,iBAAiB,CAAC,QAAQ,CAAA,GAAI,QAAA,GAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAA,EAAW;AACvG,EAAE,MAAM,cAAA,GAAiB,sBAAsB,CAAC,KAAK,CAAC;AACtD,EAAE,MAAM,WAAA,GAAc,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,EAAK,GAAI,EAAE;AACtE,EAAE,IAAI,cAAc,EAAE;AACtB,IAAI,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa;AAChD,EAAE;;AAEF,EAAE,IAAI,CAAC,WAAA,KAAgB,WAAA,KAAgB,gBAAA,IAAoB,KAAA,KAAU,SAAS,CAAC,EAAE;AACjF,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,EAAE,IAAI,WAAA,GAAc,EAAE;AACtB,EAAE,IAAI;AACN,IAAI,WAAA,GAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA,IAAK,EAAE;AAC7C,EAAE,EAAE,MAAM;AACV;AACA,EAAE;AACF,EAAE,OAAO;AACT,IAAI,KAAK,EAAE,WAAW;AACtB,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,GAAG,WAAW;AAClB,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB;AACnC,EAAE,UAAU;AACZ,EAAE,QAAQ,GAA+B,KAAK;AAC9C,EAAc;AACd,EAAE,MAAM,oBAAoB,GAAe,EAAE;AAC7C,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAA,IAAK,MAAM,CAAC,OAAO,CAAC,UAAA,IAAc,EAAE,CAAC,EAAE;AAC/D,IAAI,MAAM,aAAa,mCAAmC,CAAC,KAAK,EAAE,QAAQ,CAAC;AAC3E,IAAI,IAAI,UAAU,EAAE;AACpB,MAAM,oBAAoB,CAAC,GAAG,CAAA,GAAI,UAAU;AAC5C,IAAI;AACJ,EAAE;AACF,EAAE,OAAO,oBAAoB;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,sBAAsB,CAAC,KAAK,EAAuC;AAC5E,EAAE,MAAM,aAAA;AACR,IAAI,OAAO,UAAU;AACrB,QAAQ;AACR,QAAQ,OAAO,KAAA,KAAU;AACzB,UAAU;AACV,UAAU,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;AAC1D,YAAY,MAAM,CAAC,SAAS,CAAC,KAAK;AAClC,cAAc;AACd,cAAc;AACd,YAAY,IAAI;AAChB,EAAE,IAAI,aAAa,EAAE;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe;AACzC,EAAE;AACF;;;;"}
1
+ {"version":3,"file":"attributes.js","sources":["../../src/attributes.ts"],"sourcesContent":["import type { DurationUnit, FractionUnit, InformationUnit } from './types-hoist/measurement';\nimport type { Primitive } from './types-hoist/misc';\nimport { isPrimitive } from './utils/is';\n\nexport type RawAttributes<T> = T & ValidatedAttributes<T>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RawAttribute<T> = T extends { value: any } | { unit: any } ? AttributeObject : T;\n\nexport type Attributes = Record<string, TypedAttributeValue>;\n\nexport type AttributeValueType = string | number | boolean | Array<string> | Array<number> | Array<boolean>;\n\ntype AttributeTypeMap = {\n string: string;\n integer: number;\n double: number;\n boolean: boolean;\n 'string[]': Array<string>;\n 'integer[]': Array<number>;\n 'double[]': Array<number>;\n 'boolean[]': Array<boolean>;\n};\n\n/* Generates a type from the AttributeTypeMap like:\n | { value: string; type: 'string' }\n | { value: number; type: 'integer' }\n | { value: number; type: 'double' }\n */\ntype AttributeUnion = {\n [K in keyof AttributeTypeMap]: {\n value: AttributeTypeMap[K];\n type: K;\n };\n}[keyof AttributeTypeMap];\n\nexport type TypedAttributeValue = AttributeUnion & { unit?: AttributeUnit };\n\nexport type AttributeObject = {\n value: unknown;\n unit?: AttributeUnit;\n};\n\n// Unfortunately, we loose type safety if we did something like Exclude<MeasurementUnit, string>\n// so therefore we unionize between the three supported unit categories.\ntype AttributeUnit = DurationUnit | InformationUnit | FractionUnit;\n\n/* If an attribute has either a 'value' or 'unit' property, we use the ValidAttributeObject type. */\nexport type ValidatedAttributes<T> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in keyof T]: T[K] extends { value: any } | { unit: any } ? AttributeObject : unknown;\n};\n\n/**\n * Type-guard: The attribute object has the shape the official attribute object (value, type, unit).\n * https://develop.sentry.dev/sdk/telemetry/scopes/#setting-attributes\n */\nexport function isAttributeObject(maybeObj: unknown): maybeObj is AttributeObject {\n return (\n typeof maybeObj === 'object' &&\n maybeObj != null &&\n !Array.isArray(maybeObj) &&\n Object.keys(maybeObj).includes('value')\n );\n}\n\n/**\n * Converts an attribute value to a typed attribute value.\n *\n * For now, we intentionally only support primitive values and attribute objects with primitive values.\n * If @param useFallback is true, we stringify non-primitive values to a string attribute value. Otherwise\n * we return `undefined` for unsupported values.\n *\n * @param value - The value of the passed attribute.\n * @param useFallback - If true, unsupported values will be stringified to a string attribute value.\n * Defaults to false. In this case, `undefined` is returned for unsupported values.\n * @returns The typed attribute.\n */\nexport function attributeValueToTypedAttributeValue(\n rawValue: unknown,\n useFallback?: boolean | 'skip-undefined',\n): TypedAttributeValue | void {\n const { value, unit } = isAttributeObject(rawValue) ? rawValue : { value: rawValue, unit: undefined };\n const attributeValue = getTypedAttributeValue(value);\n const checkedUnit = unit && typeof unit === 'string' ? { unit } : {};\n if (attributeValue) {\n return { ...attributeValue, ...checkedUnit };\n }\n\n if (!useFallback || (useFallback === 'skip-undefined' && value === undefined)) {\n return;\n }\n\n // Fallback: stringify the value\n // TODO(v11): be smarter here and use String constructor if stringify fails\n // (this is a breaking change for already existing attribute values)\n let stringValue = '';\n try {\n stringValue = JSON.stringify(value) ?? '';\n } catch {\n // Do nothing\n }\n return {\n value: stringValue,\n type: 'string',\n ...checkedUnit,\n };\n}\n\n/**\n * Serializes raw attributes to typed attributes as expected in our envelopes.\n *\n * @param attributes The raw attributes to serialize.\n * @param fallback If true, unsupported values will be stringified to a string attribute value.\n * Defaults to false. In this case, `undefined` is returned for unsupported values.\n *\n * @returns The serialized attributes.\n */\nexport function serializeAttributes<T>(\n attributes: RawAttributes<T> | undefined,\n fallback: boolean | 'skip-undefined' = false,\n): Attributes {\n const serializedAttributes: Attributes = {};\n for (const [key, value] of Object.entries(attributes ?? {})) {\n const typedValue = attributeValueToTypedAttributeValue(value, fallback);\n if (typedValue) {\n serializedAttributes[key] = typedValue;\n }\n }\n return serializedAttributes;\n}\n\n/**\n * Estimates the serialized byte size of {@link Attributes},\n * with a couple of heuristics for performance.\n */\nexport function estimateTypedAttributesSizeInBytes(attributes: Attributes | undefined): number {\n if (!attributes) {\n return 0;\n }\n let weight = 0;\n for (const [key, attr] of Object.entries(attributes)) {\n weight += key.length * 2;\n weight += attr.type.length * 2;\n weight += (attr.unit?.length ?? 0) * 2;\n const val = attr.value;\n\n if (Array.isArray(val)) {\n // Assumption: Individual array items have the same type and roughly the same size\n // probably not always true but allows us to cut down on runtime\n weight += estimatePrimitiveSizeInBytes(val[0]) * val.length;\n } else if (isPrimitive(val)) {\n weight += estimatePrimitiveSizeInBytes(val);\n } else {\n // default fallback for anything else (objects)\n weight += 100;\n }\n }\n return weight;\n}\n\nfunction estimatePrimitiveSizeInBytes(value: Primitive): number {\n if (typeof value === 'string') {\n return value.length * 2;\n } else if (typeof value === 'boolean') {\n return 4;\n } else if (typeof value === 'number') {\n return 8;\n }\n return 0;\n}\n\n/**\n * NOTE: We intentionally do not return anything for non-primitive values:\n * - array support will come in the future but if we stringify arrays now,\n * sending arrays (unstringified) later will be a subtle breaking change.\n * - Objects are not supported yet and product support is still TBD.\n * - We still keep the type signature for TypedAttributeValue wider to avoid a\n * breaking change once we add support for non-primitive values.\n * - Once we go back to supporting arrays and stringifying all other values,\n * we already implemented the serialization logic here:\n * https://github.com/getsentry/sentry-javascript/pull/18165\n */\nfunction getTypedAttributeValue(value: unknown): TypedAttributeValue | void {\n const primitiveType =\n typeof value === 'string'\n ? 'string'\n : typeof value === 'boolean'\n ? 'boolean'\n : typeof value === 'number' && !Number.isNaN(value)\n ? Number.isInteger(value)\n ? 'integer'\n : 'double'\n : null;\n if (primitiveType) {\n // @ts-expect-error - TS complains because {@link TypedAttributeValue} is strictly typed to\n // avoid setting the wrong `type` on the attribute value.\n // In this case, getPrimitiveType already does the check but TS doesn't know that.\n // The \"clean\" alternative is to return an object per `typeof value` case\n // but that would require more bundle size\n // Therefore, we ignore it.\n return { value, type: primitiveType };\n }\n}\n"],"names":[],"mappings":";;AAoDA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,QAAQ,EAAwC;AAClF,EAAE;AACF,IAAI,OAAO,QAAA,KAAa,QAAA;AACxB,IAAI,QAAA,IAAY,IAAA;AAChB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAA;AAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO;AAC1C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mCAAmC;AACnD,EAAE,QAAQ;AACV,EAAE,WAAW;AACb,EAA8B;AAC9B,EAAE,MAAM,EAAE,KAAK,EAAE,MAAK,GAAI,iBAAiB,CAAC,QAAQ,CAAA,GAAI,QAAA,GAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAA,EAAW;AACvG,EAAE,MAAM,cAAA,GAAiB,sBAAsB,CAAC,KAAK,CAAC;AACtD,EAAE,MAAM,WAAA,GAAc,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,EAAK,GAAI,EAAE;AACtE,EAAE,IAAI,cAAc,EAAE;AACtB,IAAI,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa;AAChD,EAAE;;AAEF,EAAE,IAAI,CAAC,WAAA,KAAgB,WAAA,KAAgB,gBAAA,IAAoB,KAAA,KAAU,SAAS,CAAC,EAAE;AACjF,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,EAAE,IAAI,WAAA,GAAc,EAAE;AACtB,EAAE,IAAI;AACN,IAAI,WAAA,GAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA,IAAK,EAAE;AAC7C,EAAE,EAAE,MAAM;AACV;AACA,EAAE;AACF,EAAE,OAAO;AACT,IAAI,KAAK,EAAE,WAAW;AACtB,IAAI,IAAI,EAAE,QAAQ;AAClB,IAAI,GAAG,WAAW;AAClB,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB;AACnC,EAAE,UAAU;AACZ,EAAE,QAAQ,GAA+B,KAAK;AAC9C,EAAc;AACd,EAAE,MAAM,oBAAoB,GAAe,EAAE;AAC7C,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAA,IAAK,MAAM,CAAC,OAAO,CAAC,UAAA,IAAc,EAAE,CAAC,EAAE;AAC/D,IAAI,MAAM,aAAa,mCAAmC,CAAC,KAAK,EAAE,QAAQ,CAAC;AAC3E,IAAI,IAAI,UAAU,EAAE;AACpB,MAAM,oBAAoB,CAAC,GAAG,CAAA,GAAI,UAAU;AAC5C,IAAI;AACJ,EAAE;AACF,EAAE,OAAO,oBAAoB;AAC7B;;AAEA;AACA;AACA;AACA;AACO,SAAS,kCAAkC,CAAC,UAAU,EAAkC;AAC/F,EAAE,IAAI,CAAC,UAAU,EAAE;AACnB,IAAI,OAAO,CAAC;AACZ,EAAE;AACF,EAAE,IAAI,MAAA,GAAS,CAAC;AAChB,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAA,IAAK,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;AACxD,IAAI,UAAU,GAAG,CAAC,MAAA,GAAS,CAAC;AAC5B,IAAI,MAAA,IAAU,IAAI,CAAC,IAAI,CAAC,MAAA,GAAS,CAAC;AAClC,IAAI,MAAA,IAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAA,IAAU,CAAC,IAAI,CAAC;AAC1C,IAAI,MAAM,GAAA,GAAM,IAAI,CAAC,KAAK;;AAE1B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AAC5B;AACA;AACA,MAAM,MAAA,IAAU,4BAA4B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA,GAAI,GAAG,CAAC,MAAM;AACjE,IAAI,CAAA,MAAO,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE;AACjC,MAAM,MAAA,IAAU,4BAA4B,CAAC,GAAG,CAAC;AACjD,IAAI,OAAO;AACX;AACA,MAAM,MAAA,IAAU,GAAG;AACnB,IAAI;AACJ,EAAE;AACF,EAAE,OAAO,MAAM;AACf;;AAEA,SAAS,4BAA4B,CAAC,KAAK,EAAqB;AAChE,EAAE,IAAI,OAAO,KAAA,KAAU,QAAQ,EAAE;AACjC,IAAI,OAAO,KAAK,CAAC,MAAA,GAAS,CAAC;AAC3B,EAAE,CAAA,MAAO,IAAI,OAAO,KAAA,KAAU,SAAS,EAAE;AACzC,IAAI,OAAO,CAAC;AACZ,EAAE,CAAA,MAAO,IAAI,OAAO,KAAA,KAAU,QAAQ,EAAE;AACxC,IAAI,OAAO,CAAC;AACZ,EAAE;AACF,EAAE,OAAO,CAAC;AACV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,sBAAsB,CAAC,KAAK,EAAuC;AAC5E,EAAE,MAAM,aAAA;AACR,IAAI,OAAO,UAAU;AACrB,QAAQ;AACR,QAAQ,OAAO,KAAA,KAAU;AACzB,UAAU;AACV,UAAU,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;AAC1D,YAAY,MAAM,CAAC,SAAS,CAAC,KAAK;AAClC,cAAc;AACd,cAAc;AACd,YAAY,IAAI;AAChB,EAAE,IAAI,aAAa,EAAE;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe;AACzC,EAAE;AACF;;;;"}
@@ -8,6 +8,7 @@ import { _INTERNAL_flushLogsBuffer } from './logs/internal.js';
8
8
  import { _INTERNAL_flushMetricsBuffer } from './metrics/internal.js';
9
9
  import { updateSession } from './session.js';
10
10
  import { getDynamicSamplingContextFromScope } from './tracing/dynamicSamplingContext.js';
11
+ import { isStreamedBeforeSendSpanCallback } from './tracing/spans/beforeSendSpan.js';
11
12
  import { DEFAULT_TRANSPORT_BUFFER_SIZE } from './transports/base.js';
12
13
  import { createClientReportEnvelope } from './utils/clientreport.js';
13
14
  import { debug } from './utils/debug-logger.js';
@@ -455,6 +456,10 @@ class Client {
455
456
  addIntegration(integration) {
456
457
  const isAlreadyInstalled = this._integrations[integration.name];
457
458
 
459
+ if (!isAlreadyInstalled && integration.beforeSetup) {
460
+ integration.beforeSetup(this);
461
+ }
462
+
458
463
  // This hook takes care of only installing if not already installed
459
464
  setupIntegration(this, integration, this._integrations);
460
465
  // Here we need to check manually to make sure to not run this multiple times
@@ -999,7 +1004,9 @@ function processBeforeSend(
999
1004
  event,
1000
1005
  hint,
1001
1006
  ) {
1002
- const { beforeSend, beforeSendTransaction, beforeSendSpan, ignoreSpans } = options;
1007
+ const { beforeSend, beforeSendTransaction, ignoreSpans } = options;
1008
+ const beforeSendSpan = !isStreamedBeforeSendSpanCallback(options.beforeSendSpan) && options.beforeSendSpan;
1009
+
1003
1010
  let processedEvent = event;
1004
1011
 
1005
1012
  if (isErrorEvent(processedEvent) && beforeSend) {