@sentry/core 10.50.0 → 10.52.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 (347) hide show
  1. package/build/cjs/client.js +33 -5
  2. package/build/cjs/client.js.map +1 -1
  3. package/build/cjs/envelope.js +4 -1
  4. package/build/cjs/envelope.js.map +1 -1
  5. package/build/cjs/fetch.js +7 -4
  6. package/build/cjs/fetch.js.map +1 -1
  7. package/build/cjs/index.js +37 -13
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/instrument/console.js +3 -1
  10. package/build/cjs/instrument/console.js.map +1 -1
  11. package/build/cjs/instrument/fetch.js +6 -2
  12. package/build/cjs/instrument/fetch.js.map +1 -1
  13. package/build/cjs/instrument/handlers.js +11 -1
  14. package/build/cjs/instrument/handlers.js.map +1 -1
  15. package/build/cjs/integrations/console.js +3 -1
  16. package/build/cjs/integrations/console.js.map +1 -1
  17. package/build/cjs/integrations/express/index.js +2 -4
  18. package/build/cjs/integrations/express/index.js.map +1 -1
  19. package/build/cjs/integrations/express/utils.js +0 -7
  20. package/build/cjs/integrations/express/utils.js.map +1 -1
  21. package/build/cjs/integrations/extraerrordata.js +2 -2
  22. package/build/cjs/integrations/extraerrordata.js.map +1 -1
  23. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js +43 -0
  24. package/build/cjs/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  25. package/build/cjs/integrations/http/client-patch.js +113 -0
  26. package/build/cjs/integrations/http/client-patch.js.map +1 -0
  27. package/build/cjs/integrations/http/client-subscriptions.js +166 -0
  28. package/build/cjs/integrations/http/client-subscriptions.js.map +1 -0
  29. package/build/cjs/integrations/http/constants.js +10 -0
  30. package/build/cjs/integrations/http/constants.js.map +1 -0
  31. package/build/cjs/integrations/http/double-wrap-warning.js +29 -0
  32. package/build/cjs/integrations/http/double-wrap-warning.js.map +1 -0
  33. package/build/cjs/integrations/http/get-outgoing-span-data.js +88 -0
  34. package/build/cjs/integrations/http/get-outgoing-span-data.js.map +1 -0
  35. package/build/cjs/integrations/http/get-request-url.js +54 -0
  36. package/build/cjs/integrations/http/get-request-url.js.map +1 -0
  37. package/build/cjs/integrations/http/inject-trace-propagation-headers.js +81 -0
  38. package/build/cjs/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  39. package/build/cjs/integrations/postgresjs.js +10 -1
  40. package/build/cjs/integrations/postgresjs.js.map +1 -1
  41. package/build/cjs/integrations/requestdata.js +92 -6
  42. package/build/cjs/integrations/requestdata.js.map +1 -1
  43. package/build/cjs/integrations/supabase.js +39 -12
  44. package/build/cjs/integrations/supabase.js.map +1 -1
  45. package/build/cjs/logs/console-integration.js +3 -1
  46. package/build/cjs/logs/console-integration.js.map +1 -1
  47. package/build/cjs/logs/envelope.js +12 -2
  48. package/build/cjs/logs/envelope.js.map +1 -1
  49. package/build/cjs/logs/internal.js +7 -1
  50. package/build/cjs/logs/internal.js.map +1 -1
  51. package/build/cjs/metrics/envelope.js +15 -2
  52. package/build/cjs/metrics/envelope.js.map +1 -1
  53. package/build/cjs/metrics/internal.js +7 -1
  54. package/build/cjs/metrics/internal.js.map +1 -1
  55. package/build/cjs/server-runtime-client.js +20 -2
  56. package/build/cjs/server-runtime-client.js.map +1 -1
  57. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  58. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  59. package/build/cjs/tracing/idleSpan.js +7 -1
  60. package/build/cjs/tracing/idleSpan.js.map +1 -1
  61. package/build/cjs/tracing/langchain/index.js +43 -8
  62. package/build/cjs/tracing/langchain/index.js.map +1 -1
  63. package/build/cjs/tracing/langchain/utils.js +44 -10
  64. package/build/cjs/tracing/langchain/utils.js.map +1 -1
  65. package/build/cjs/tracing/langgraph/index.js +105 -2
  66. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  67. package/build/cjs/tracing/langgraph/utils.js +168 -0
  68. package/build/cjs/tracing/langgraph/utils.js.map +1 -1
  69. package/build/cjs/tracing/spans/captureSpan.js +169 -9
  70. package/build/cjs/tracing/spans/captureSpan.js.map +1 -1
  71. package/build/cjs/tracing/spans/envelope.js +13 -3
  72. package/build/cjs/tracing/spans/envelope.js.map +1 -1
  73. package/build/cjs/tracing/trace.js +2 -0
  74. package/build/cjs/tracing/trace.js.map +1 -1
  75. package/build/cjs/tracing/vercel-ai/constants.js +8 -0
  76. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  77. package/build/cjs/tracing/vercel-ai/index.js +93 -14
  78. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  79. package/build/cjs/trpc.js +2 -3
  80. package/build/cjs/trpc.js.map +1 -1
  81. package/build/cjs/utils/baggage.js +73 -0
  82. package/build/cjs/utils/baggage.js.map +1 -1
  83. package/build/cjs/utils/chain-and-copy-promiselike.js +1 -0
  84. package/build/cjs/utils/chain-and-copy-promiselike.js.map +1 -1
  85. package/build/cjs/utils/get-default-export.js +32 -0
  86. package/build/cjs/utils/get-default-export.js.map +1 -0
  87. package/build/cjs/utils/isSentryRequestUrl.js +9 -1
  88. package/build/cjs/utils/isSentryRequestUrl.js.map +1 -1
  89. package/build/cjs/utils/normalizationHints.js +38 -0
  90. package/build/cjs/utils/normalizationHints.js.map +1 -0
  91. package/build/cjs/utils/normalize.js +7 -11
  92. package/build/cjs/utils/normalize.js.map +1 -1
  93. package/build/cjs/utils/object.js +1 -1
  94. package/build/cjs/utils/object.js.map +1 -1
  95. package/build/cjs/utils/request.js +192 -12
  96. package/build/cjs/utils/request.js.map +1 -1
  97. package/build/cjs/utils/should-ignore-span.js +27 -8
  98. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  99. package/build/cjs/utils/spanUtils.js +1 -1
  100. package/build/cjs/utils/spanUtils.js.map +1 -1
  101. package/build/cjs/utils/version.js +1 -1
  102. package/build/esm/client.js +33 -5
  103. package/build/esm/client.js.map +1 -1
  104. package/build/esm/envelope.js +4 -1
  105. package/build/esm/envelope.js.map +1 -1
  106. package/build/esm/fetch.js +7 -4
  107. package/build/esm/fetch.js.map +1 -1
  108. package/build/esm/index.js +11 -5
  109. package/build/esm/index.js.map +1 -1
  110. package/build/esm/instrument/console.js +3 -1
  111. package/build/esm/instrument/console.js.map +1 -1
  112. package/build/esm/instrument/fetch.js +6 -2
  113. package/build/esm/instrument/fetch.js.map +1 -1
  114. package/build/esm/instrument/handlers.js +11 -1
  115. package/build/esm/instrument/handlers.js.map +1 -1
  116. package/build/esm/integrations/console.js +3 -1
  117. package/build/esm/integrations/console.js.map +1 -1
  118. package/build/esm/integrations/express/index.js +3 -5
  119. package/build/esm/integrations/express/index.js.map +1 -1
  120. package/build/esm/integrations/express/utils.js +1 -7
  121. package/build/esm/integrations/express/utils.js.map +1 -1
  122. package/build/esm/integrations/extraerrordata.js +2 -2
  123. package/build/esm/integrations/extraerrordata.js.map +1 -1
  124. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js +41 -0
  125. package/build/esm/integrations/http/add-outgoing-request-breadcrumb.js.map +1 -0
  126. package/build/esm/integrations/http/client-patch.js +111 -0
  127. package/build/esm/integrations/http/client-patch.js.map +1 -0
  128. package/build/esm/integrations/http/client-subscriptions.js +164 -0
  129. package/build/esm/integrations/http/client-subscriptions.js.map +1 -0
  130. package/build/esm/integrations/http/constants.js +6 -0
  131. package/build/esm/integrations/http/constants.js.map +1 -0
  132. package/build/esm/integrations/http/double-wrap-warning.js +26 -0
  133. package/build/esm/integrations/http/double-wrap-warning.js.map +1 -0
  134. package/build/esm/integrations/http/get-outgoing-span-data.js +85 -0
  135. package/build/esm/integrations/http/get-outgoing-span-data.js.map +1 -0
  136. package/build/esm/integrations/http/get-request-url.js +49 -0
  137. package/build/esm/integrations/http/get-request-url.js.map +1 -0
  138. package/build/esm/integrations/http/inject-trace-propagation-headers.js +79 -0
  139. package/build/esm/integrations/http/inject-trace-propagation-headers.js.map +1 -0
  140. package/build/esm/integrations/postgresjs.js +10 -1
  141. package/build/esm/integrations/postgresjs.js.map +1 -1
  142. package/build/esm/integrations/requestdata.js +92 -6
  143. package/build/esm/integrations/requestdata.js.map +1 -1
  144. package/build/esm/integrations/supabase.js +39 -12
  145. package/build/esm/integrations/supabase.js.map +1 -1
  146. package/build/esm/logs/console-integration.js +3 -1
  147. package/build/esm/logs/console-integration.js.map +1 -1
  148. package/build/esm/logs/envelope.js +12 -2
  149. package/build/esm/logs/envelope.js.map +1 -1
  150. package/build/esm/logs/internal.js +7 -1
  151. package/build/esm/logs/internal.js.map +1 -1
  152. package/build/esm/metrics/envelope.js +15 -2
  153. package/build/esm/metrics/envelope.js.map +1 -1
  154. package/build/esm/metrics/internal.js +7 -1
  155. package/build/esm/metrics/internal.js.map +1 -1
  156. package/build/esm/package.json +1 -1
  157. package/build/esm/server-runtime-client.js +20 -2
  158. package/build/esm/server-runtime-client.js.map +1 -1
  159. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  160. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  161. package/build/esm/tracing/idleSpan.js +7 -1
  162. package/build/esm/tracing/idleSpan.js.map +1 -1
  163. package/build/esm/tracing/langchain/index.js +45 -10
  164. package/build/esm/tracing/langchain/index.js.map +1 -1
  165. package/build/esm/tracing/langchain/utils.js +44 -12
  166. package/build/esm/tracing/langchain/utils.js.map +1 -1
  167. package/build/esm/tracing/langgraph/index.js +107 -5
  168. package/build/esm/tracing/langgraph/index.js.map +1 -1
  169. package/build/esm/tracing/langgraph/utils.js +166 -2
  170. package/build/esm/tracing/langgraph/utils.js.map +1 -1
  171. package/build/esm/tracing/spans/captureSpan.js +170 -11
  172. package/build/esm/tracing/spans/captureSpan.js.map +1 -1
  173. package/build/esm/tracing/spans/envelope.js +13 -3
  174. package/build/esm/tracing/spans/envelope.js.map +1 -1
  175. package/build/esm/tracing/trace.js +2 -1
  176. package/build/esm/tracing/trace.js.map +1 -1
  177. package/build/esm/tracing/vercel-ai/constants.js +8 -1
  178. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  179. package/build/esm/tracing/vercel-ai/index.js +95 -17
  180. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  181. package/build/esm/trpc.js +2 -3
  182. package/build/esm/trpc.js.map +1 -1
  183. package/build/esm/utils/baggage.js +73 -1
  184. package/build/esm/utils/baggage.js.map +1 -1
  185. package/build/esm/utils/chain-and-copy-promiselike.js +1 -0
  186. package/build/esm/utils/chain-and-copy-promiselike.js.map +1 -1
  187. package/build/esm/utils/get-default-export.js +30 -0
  188. package/build/esm/utils/get-default-export.js.map +1 -0
  189. package/build/esm/utils/isSentryRequestUrl.js +9 -1
  190. package/build/esm/utils/isSentryRequestUrl.js.map +1 -1
  191. package/build/esm/utils/normalizationHints.js +33 -0
  192. package/build/esm/utils/normalizationHints.js.map +1 -0
  193. package/build/esm/utils/normalize.js +7 -11
  194. package/build/esm/utils/normalize.js.map +1 -1
  195. package/build/esm/utils/object.js +1 -1
  196. package/build/esm/utils/object.js.map +1 -1
  197. package/build/esm/utils/request.js +190 -13
  198. package/build/esm/utils/request.js.map +1 -1
  199. package/build/esm/utils/should-ignore-span.js +27 -8
  200. package/build/esm/utils/should-ignore-span.js.map +1 -1
  201. package/build/esm/utils/spanUtils.js +1 -1
  202. package/build/esm/utils/spanUtils.js.map +1 -1
  203. package/build/esm/utils/version.js +1 -1
  204. package/build/types/client.d.ts +12 -1
  205. package/build/types/client.d.ts.map +1 -1
  206. package/build/types/envelope.d.ts.map +1 -1
  207. package/build/types/fetch.d.ts.map +1 -1
  208. package/build/types/index.d.ts +17 -6
  209. package/build/types/index.d.ts.map +1 -1
  210. package/build/types/instrument/console.d.ts +2 -1
  211. package/build/types/instrument/console.d.ts.map +1 -1
  212. package/build/types/instrument/fetch.d.ts +4 -2
  213. package/build/types/instrument/fetch.d.ts.map +1 -1
  214. package/build/types/instrument/handlers.d.ts +2 -2
  215. package/build/types/instrument/handlers.d.ts.map +1 -1
  216. package/build/types/integrations/console.d.ts.map +1 -1
  217. package/build/types/integrations/express/index.d.ts.map +1 -1
  218. package/build/types/integrations/express/utils.d.ts +1 -5
  219. package/build/types/integrations/express/utils.d.ts.map +1 -1
  220. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  221. package/build/types/integrations/http/add-outgoing-request-breadcrumb.d.ts.map +1 -0
  222. package/build/types/integrations/http/client-patch.d.ts +46 -0
  223. package/build/types/integrations/http/client-patch.d.ts.map +1 -0
  224. package/build/types/integrations/http/client-subscriptions.d.ts +21 -0
  225. package/build/types/integrations/http/client-subscriptions.d.ts.map +1 -0
  226. package/build/types/integrations/http/constants.d.ts +6 -0
  227. package/build/types/integrations/http/constants.d.ts.map +1 -0
  228. package/build/types/integrations/http/double-wrap-warning.d.ts +4 -0
  229. package/build/types/integrations/http/double-wrap-warning.d.ts.map +1 -0
  230. package/build/types/integrations/http/get-outgoing-span-data.d.ts +13 -0
  231. package/build/types/integrations/http/get-outgoing-span-data.d.ts.map +1 -0
  232. package/build/types/integrations/http/get-request-url.d.ts +10 -0
  233. package/build/types/integrations/http/get-request-url.d.ts.map +1 -0
  234. package/build/types/integrations/http/index.d.ts +4 -0
  235. package/build/types/integrations/http/index.d.ts.map +1 -0
  236. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  237. package/build/types/integrations/http/inject-trace-propagation-headers.d.ts.map +1 -0
  238. package/build/types/integrations/http/types.d.ts +249 -0
  239. package/build/types/integrations/http/types.d.ts.map +1 -0
  240. package/build/types/integrations/postgresjs.d.ts.map +1 -1
  241. package/build/types/integrations/requestdata.d.ts.map +1 -1
  242. package/build/types/integrations/supabase.d.ts.map +1 -1
  243. package/build/types/logs/console-integration.d.ts.map +1 -1
  244. package/build/types/logs/envelope.d.ts +5 -2
  245. package/build/types/logs/envelope.d.ts.map +1 -1
  246. package/build/types/logs/internal.d.ts.map +1 -1
  247. package/build/types/metrics/envelope.d.ts +5 -2
  248. package/build/types/metrics/envelope.d.ts.map +1 -1
  249. package/build/types/metrics/internal.d.ts.map +1 -1
  250. package/build/types/server-runtime-client.d.ts +5 -0
  251. package/build/types/server-runtime-client.d.ts.map +1 -1
  252. package/build/types/tracing/idleSpan.d.ts.map +1 -1
  253. package/build/types/tracing/index.d.ts +1 -1
  254. package/build/types/tracing/index.d.ts.map +1 -1
  255. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  256. package/build/types/tracing/langchain/types.d.ts +8 -0
  257. package/build/types/tracing/langchain/types.d.ts.map +1 -1
  258. package/build/types/tracing/langchain/utils.d.ts +2 -0
  259. package/build/types/tracing/langchain/utils.d.ts.map +1 -1
  260. package/build/types/tracing/langgraph/index.d.ts +4 -0
  261. package/build/types/tracing/langgraph/index.d.ts.map +1 -1
  262. package/build/types/tracing/langgraph/utils.d.ts +18 -2
  263. package/build/types/tracing/langgraph/utils.d.ts.map +1 -1
  264. package/build/types/tracing/spans/captureSpan.d.ts +13 -3
  265. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -1
  266. package/build/types/tracing/spans/envelope.d.ts.map +1 -1
  267. package/build/types/tracing/trace.d.ts +1 -0
  268. package/build/types/tracing/trace.d.ts.map +1 -1
  269. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  270. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  271. package/build/types/tracing/vercel-ai/index.d.ts +9 -0
  272. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  273. package/build/types/trpc.d.ts.map +1 -1
  274. package/build/types/types-hoist/feedback/config.d.ts +20 -0
  275. package/build/types/types-hoist/feedback/config.d.ts.map +1 -1
  276. package/build/types/types-hoist/feedback/index.d.ts +2 -2
  277. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  278. package/build/types/types-hoist/feedback/sendFeedback.d.ts +3 -0
  279. package/build/types/types-hoist/feedback/sendFeedback.d.ts.map +1 -1
  280. package/build/types/types-hoist/log.d.ts +5 -0
  281. package/build/types/types-hoist/log.d.ts.map +1 -1
  282. package/build/types/types-hoist/metric.d.ts +5 -0
  283. package/build/types/types-hoist/metric.d.ts.map +1 -1
  284. package/build/types/types-hoist/options.d.ts +37 -2
  285. package/build/types/types-hoist/options.d.ts.map +1 -1
  286. package/build/types/types-hoist/span.d.ts +5 -0
  287. package/build/types/types-hoist/span.d.ts.map +1 -1
  288. package/build/types/types-hoist/webfetchapi.d.ts +2 -0
  289. package/build/types/types-hoist/webfetchapi.d.ts.map +1 -1
  290. package/build/types/utils/baggage.d.ts +13 -0
  291. package/build/types/utils/baggage.d.ts.map +1 -1
  292. package/build/types/utils/get-default-export.d.ts +22 -0
  293. package/build/types/utils/get-default-export.d.ts.map +1 -0
  294. package/build/types/utils/normalizationHints.d.ts +9 -0
  295. package/build/types/utils/normalizationHints.d.ts.map +1 -0
  296. package/build/types/utils/normalize.d.ts.map +1 -1
  297. package/build/types/utils/object.d.ts +1 -1
  298. package/build/types/utils/object.d.ts.map +1 -1
  299. package/build/types/utils/request.d.ts +30 -0
  300. package/build/types/utils/request.d.ts.map +1 -1
  301. package/build/types/utils/should-ignore-span.d.ts +3 -1
  302. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  303. package/build/types/utils/spanUtils.d.ts +1 -1
  304. package/build/types-ts3.8/client.d.ts +12 -1
  305. package/build/types-ts3.8/index.d.ts +17 -6
  306. package/build/types-ts3.8/instrument/console.d.ts +2 -1
  307. package/build/types-ts3.8/instrument/fetch.d.ts +4 -2
  308. package/build/types-ts3.8/instrument/handlers.d.ts +2 -2
  309. package/build/types-ts3.8/integrations/express/utils.d.ts +1 -5
  310. package/build/types-ts3.8/integrations/http/add-outgoing-request-breadcrumb.d.ts +6 -0
  311. package/build/types-ts3.8/integrations/http/client-patch.d.ts +46 -0
  312. package/build/types-ts3.8/integrations/http/client-subscriptions.d.ts +21 -0
  313. package/build/types-ts3.8/integrations/http/constants.d.ts +6 -0
  314. package/build/types-ts3.8/integrations/http/double-wrap-warning.d.ts +4 -0
  315. package/build/types-ts3.8/integrations/http/get-outgoing-span-data.d.ts +13 -0
  316. package/build/types-ts3.8/integrations/http/get-request-url.d.ts +10 -0
  317. package/build/types-ts3.8/integrations/http/index.d.ts +4 -0
  318. package/build/types-ts3.8/integrations/http/inject-trace-propagation-headers.d.ts +12 -0
  319. package/build/types-ts3.8/integrations/http/types.d.ts +252 -0
  320. package/build/types-ts3.8/logs/envelope.d.ts +5 -2
  321. package/build/types-ts3.8/metrics/envelope.d.ts +5 -2
  322. package/build/types-ts3.8/server-runtime-client.d.ts +5 -0
  323. package/build/types-ts3.8/tracing/index.d.ts +1 -1
  324. package/build/types-ts3.8/tracing/langchain/types.d.ts +8 -0
  325. package/build/types-ts3.8/tracing/langchain/utils.d.ts +2 -0
  326. package/build/types-ts3.8/tracing/langgraph/index.d.ts +4 -0
  327. package/build/types-ts3.8/tracing/langgraph/utils.d.ts +18 -2
  328. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +13 -3
  329. package/build/types-ts3.8/tracing/trace.d.ts +1 -0
  330. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  331. package/build/types-ts3.8/tracing/vercel-ai/index.d.ts +9 -0
  332. package/build/types-ts3.8/types-hoist/feedback/config.d.ts +20 -0
  333. package/build/types-ts3.8/types-hoist/feedback/index.d.ts +2 -2
  334. package/build/types-ts3.8/types-hoist/feedback/sendFeedback.d.ts +3 -0
  335. package/build/types-ts3.8/types-hoist/log.d.ts +5 -0
  336. package/build/types-ts3.8/types-hoist/metric.d.ts +5 -0
  337. package/build/types-ts3.8/types-hoist/options.d.ts +37 -2
  338. package/build/types-ts3.8/types-hoist/span.d.ts +5 -0
  339. package/build/types-ts3.8/types-hoist/webfetchapi.d.ts +2 -0
  340. package/build/types-ts3.8/utils/baggage.d.ts +13 -0
  341. package/build/types-ts3.8/utils/get-default-export.d.ts +22 -0
  342. package/build/types-ts3.8/utils/normalizationHints.d.ts +9 -0
  343. package/build/types-ts3.8/utils/object.d.ts +1 -1
  344. package/build/types-ts3.8/utils/request.d.ts +30 -0
  345. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -1
  346. package/build/types-ts3.8/utils/spanUtils.d.ts +1 -1
  347. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-outgoing-span-data.js","sources":["../../../../src/integrations/http/get-outgoing-span-data.ts"],"sourcesContent":["import type { Span, SpanAttributes } from '../../types-hoist/span';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../../semanticAttributes';\nimport { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../utils/url';\nimport type { HttpClientRequest, HttpIncomingMessage } from './types';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { StartSpanOptions } from '../../types-hoist/startSpanOptions';\n\n/**\n * Build the initial span name and attributes for an outgoing HTTP request.\n * This is called before the span is created, to get the initial details.\n */\nexport function getOutgoingRequestSpanData(request: HttpClientRequest): StartSpanOptions {\n const url = getRequestUrlFromClientRequest(request);\n const [name, attributes] = getHttpSpanDetailsFromUrlObject(\n parseStringToURLObject(url),\n 'client',\n 'auto.http.client',\n request,\n );\n\n const userAgent = request.getHeader('user-agent');\n\n return {\n name,\n attributes: {\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n 'otel.kind': 'CLIENT',\n 'http.url': url,\n 'http.method': request.method,\n 'http.target': request.path || '/',\n 'net.peer.name': request.host,\n 'http.host': request.getHeader('host') as string | undefined,\n ...(userAgent ? { 'user_agent.original': userAgent as string } : {}),\n ...attributes,\n },\n onlyIfParent: true,\n };\n}\n\n/**\n * Add span attributes once the response is received.\n */\nexport function setIncomingResponseSpanData(response: HttpIncomingMessage, span: Span): void {\n const { statusCode, statusMessage, httpVersion, socket } = response;\n const transport = httpVersion?.toUpperCase() !== 'QUIC' ? 'ip_tcp' : 'ip_udp';\n\n span.setAttributes({\n 'http.response.status_code': statusCode,\n 'network.protocol.version': httpVersion,\n // TODO(v11): Update these to the Sentry semantic attributes for urls.\n // https://getsentry.github.io/sentry-conventions/attributes/\n 'http.flavor': httpVersion,\n 'network.transport': transport,\n 'net.transport': transport,\n 'http.status_text': statusMessage?.toUpperCase(),\n 'http.status_code': statusCode,\n ...getResponseContentLengthAttributes(response),\n ...getSocketAttrs(socket),\n });\n}\n\nfunction getSocketAttrs(socket: HttpIncomingMessage['socket']): SpanAttributes {\n if (!socket) return {};\n const { remoteAddress, remotePort } = socket;\n return {\n 'network.peer.address': remoteAddress,\n 'network.peer.port': remotePort,\n 'net.peer.ip': remoteAddress,\n 'net.peer.port': remotePort,\n };\n}\n\nfunction getResponseContentLengthAttributes(response: HttpIncomingMessage): SpanAttributes {\n const { headers } = response;\n const contentLengthHeader = headers['content-length'];\n const length = contentLengthHeader ? parseInt(String(contentLengthHeader), 10) : -1;\n const encoding = headers['content-encoding'];\n return length >= 0\n ? encoding && encoding !== 'identity'\n ? { 'http.response_content_length': length }\n : { 'http.response_content_length_uncompressed': length }\n : {};\n}\n"],"names":[],"mappings":";;;;AAOA;AACA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAuC;AACzF,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAA,GAAI,+BAA+B;AAC5D,IAAI,sBAAsB,CAAC,GAAG,CAAC;AAC/B,IAAI,QAAQ;AACZ,IAAI,kBAAkB;AACtB,IAAI,OAAO;AACX,GAAG;;AAEH,EAAE,MAAM,YAAY,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC;;AAEnD,EAAE,OAAO;AACT,IAAI,IAAI;AACR,IAAI,UAAU,EAAE;AAChB;AACA;AACA,MAAM,CAAC,4BAA4B,GAAG,aAAa;AACnD,MAAM,WAAW,EAAE,QAAQ;AAC3B,MAAM,UAAU,EAAE,GAAG;AACrB,MAAM,aAAa,EAAE,OAAO,CAAC,MAAM;AACnC,MAAM,aAAa,EAAE,OAAO,CAAC,IAAA,IAAQ,GAAG;AACxC,MAAM,eAAe,EAAE,OAAO,CAAC,IAAI;AACnC,MAAM,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAA;AAC3C,MAAM,IAAI,SAAA,GAAY,EAAE,qBAAqB,EAAE,SAAA,GAAoB,GAAI,EAAE,CAAC;AAC1E,MAAM,GAAG,UAAU;AACnB,KAAK;AACL,IAAI,YAAY,EAAE,IAAI;AACtB,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,2BAA2B,CAAC,QAAQ,EAAuB,IAAI,EAAc;AAC7F,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAA,EAAO,GAAI,QAAQ;AACrE,EAAE,MAAM,SAAA,GAAY,WAAW,EAAE,WAAW,EAAC,KAAM,MAAA,GAAS,QAAA,GAAW,QAAQ;;AAE/E,EAAE,IAAI,CAAC,aAAa,CAAC;AACrB,IAAI,2BAA2B,EAAE,UAAU;AAC3C,IAAI,0BAA0B,EAAE,WAAW;AAC3C;AACA;AACA,IAAI,aAAa,EAAE,WAAW;AAC9B,IAAI,mBAAmB,EAAE,SAAS;AAClC,IAAI,eAAe,EAAE,SAAS;AAC9B,IAAI,kBAAkB,EAAE,aAAa,EAAE,WAAW,EAAE;AACpD,IAAI,kBAAkB,EAAE,UAAU;AAClC,IAAI,GAAG,kCAAkC,CAAC,QAAQ,CAAC;AACnD,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC;AAC7B,GAAG,CAAC;AACJ;;AAEA,SAAS,cAAc,CAAC,MAAM,EAAiD;AAC/E,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AACxB,EAAE,MAAM,EAAE,aAAa,EAAE,UAAA,EAAW,GAAI,MAAM;AAC9C,EAAE,OAAO;AACT,IAAI,sBAAsB,EAAE,aAAa;AACzC,IAAI,mBAAmB,EAAE,UAAU;AACnC,IAAI,aAAa,EAAE,aAAa;AAChC,IAAI,eAAe,EAAE,UAAU;AAC/B,GAAG;AACH;;AAEA,SAAS,kCAAkC,CAAC,QAAQ,EAAuC;AAC3F,EAAE,MAAM,EAAE,OAAA,EAAQ,GAAI,QAAQ;AAC9B,EAAE,MAAM,mBAAA,GAAsB,OAAO,CAAC,gBAAgB,CAAC;AACvD,EAAE,MAAM,MAAA,GAAS,mBAAA,GAAsB,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAA,GAAI,EAAE;AACrF,EAAE,MAAM,QAAA,GAAW,OAAO,CAAC,kBAAkB,CAAC;AAC9C,EAAE,OAAO,UAAU;AACnB,MAAM,QAAA,IAAY,QAAA,KAAa;AAC/B,QAAQ,EAAE,8BAA8B,EAAE,MAAA;AAC1C,QAAQ,EAAE,2CAA2C,EAAE,MAAA;AACvD,MAAM,EAAE;AACR;;;;"}
@@ -0,0 +1,49 @@
1
+ /** Convert an outgoing request to request options. */
2
+ function getRequestOptions(request) {
3
+ // request.host may be 'hostname:port' when the caller passed
4
+ // { host: 'hostname:port' } to http.request(). Split it so that
5
+ // `hostname` is always port-free (matching the http.RequestOptions contract)
6
+ // and the port is not lost when request.port is undefined.
7
+ const hostWithPort = request.host || '';
8
+ const portInHost = /^(.*):(\d+)$/.exec(hostWithPort);
9
+ const hostname = portInHost ? portInHost[1] : hostWithPort;
10
+ const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);
11
+
12
+ return {
13
+ method: request.method,
14
+ port,
15
+ protocol: request.protocol,
16
+ host: request.host,
17
+ hostname,
18
+ path: request.path,
19
+ headers: request.getHeaders(),
20
+ };
21
+ }
22
+
23
+ function getRequestUrl(requestOptions) {
24
+ return String(getRequestUrlObject(requestOptions));
25
+ }
26
+
27
+ function getRequestUrlObject(requestOptions) {
28
+ const protocol = requestOptions.protocol || 'http:';
29
+ const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);
30
+ const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';
31
+ // Don't log standard :80 (http) and :443 (https) ports to reduce the noise
32
+ // Also don't add port if the hostname already includes a port
33
+ const port =
34
+ !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname)
35
+ ? ''
36
+ : `:${requestOptions.port}`;
37
+ const path = requestOptions.path ? requestOptions.path : '/';
38
+ return new URL(path, `${protocol}//${hostname}${port}`);
39
+ }
40
+
41
+ /**
42
+ * Build the full URL string from a Node.js ClientRequest.
43
+ */
44
+ function getRequestUrlFromClientRequest(request) {
45
+ return String(getRequestUrl(getRequestOptions(request)));
46
+ }
47
+
48
+ export { getRequestOptions, getRequestUrl, getRequestUrlFromClientRequest, getRequestUrlObject };
49
+ //# sourceMappingURL=get-request-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-request-url.js","sources":["../../../../src/integrations/http/get-request-url.ts"],"sourcesContent":["import type { HttpClientRequest, HttpRequestOptions } from './types';\n\n/** Convert an outgoing request to request options. */\nexport function getRequestOptions(request: HttpClientRequest): HttpRequestOptions {\n // request.host may be 'hostname:port' when the caller passed\n // { host: 'hostname:port' } to http.request(). Split it so that\n // `hostname` is always port-free (matching the http.RequestOptions contract)\n // and the port is not lost when request.port is undefined.\n const hostWithPort = request.host || '';\n const portInHost = /^(.*):(\\d+)$/.exec(hostWithPort);\n const hostname = portInHost ? portInHost[1] : hostWithPort;\n const port = request.port ?? (portInHost ? Number(portInHost[2]) : undefined);\n\n return {\n method: request.method,\n port,\n protocol: request.protocol,\n host: request.host,\n hostname,\n path: request.path,\n headers: request.getHeaders(),\n };\n}\n\nexport function getRequestUrl(requestOptions: HttpRequestOptions): string {\n return String(getRequestUrlObject(requestOptions));\n}\n\nexport function getRequestUrlObject(requestOptions: HttpRequestOptions): URL {\n const protocol = requestOptions.protocol || 'http:';\n const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);\n const hostname = hostHeader || requestOptions.hostname || requestOptions.host || '';\n // Don't log standard :80 (http) and :443 (https) ports to reduce the noise\n // Also don't add port if the hostname already includes a port\n const port =\n !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\\d+)$/.test(hostname)\n ? ''\n : `:${requestOptions.port}`;\n const path = requestOptions.path ? requestOptions.path : '/';\n return new URL(path, `${protocol}//${hostname}${port}`);\n}\n\n/**\n * Build the full URL string from a Node.js ClientRequest.\n */\nexport function getRequestUrlFromClientRequest(request: HttpClientRequest): string {\n return String(getRequestUrl(getRequestOptions(request)));\n}\n"],"names":[],"mappings":"AAEA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAAyC;AAClF;AACA;AACA;AACA;AACA,EAAE,MAAM,YAAA,GAAe,OAAO,CAAC,IAAA,IAAQ,EAAE;AACzC,EAAE,MAAM,aAAa,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;AACtD,EAAE,MAAM,QAAA,GAAW,UAAA,GAAa,UAAU,CAAC,CAAC,CAAA,GAAI,YAAY;AAC5D,EAAE,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,KAAS,UAAA,GAAa,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA,GAAI,SAAS,CAAC;;AAE/E,EAAE,OAAO;AACT,IAAI,MAAM,EAAE,OAAO,CAAC,MAAM;AAC1B,IAAI,IAAI;AACR,IAAI,QAAQ,EAAE,OAAO,CAAC,QAAQ;AAC9B,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,QAAQ;AACZ,IAAI,IAAI,EAAE,OAAO,CAAC,IAAI;AACtB,IAAI,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;AACjC,GAAG;AACH;;AAEO,SAAS,aAAa,CAAC,cAAc,EAA8B;AAC1E,EAAE,OAAO,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;AACpD;;AAEO,SAAS,mBAAmB,CAAC,cAAc,EAA2B;AAC7E,EAAE,MAAM,QAAA,GAAW,cAAc,CAAC,QAAA,IAAY,OAAO;AACrD,EAAE,MAAM,UAAA,GAAa,cAAc,CAAC,OAAO,EAAE,IAAA,IAAQ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;AACzF,EAAE,MAAM,QAAA,GAAW,UAAA,IAAc,cAAc,CAAC,QAAA,IAAY,cAAc,CAAC,IAAA,IAAQ,EAAE;AACrF;AACA;AACA,EAAE,MAAM,IAAA;AACR,IAAI,CAAC,cAAc,CAAC,IAAA,IAAQ,cAAc,CAAC,SAAS,EAAA,IAAM,cAAc,CAAC,SAAS,GAAA,IAAO,cAAc,CAAC,IAAI,CAAC,QAAQ;AACrH,QAAQ;AACR,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAA;AACA,EAAA,MAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,cAAA,CAAA,IAAA,GAAA,GAAA;AACA,EAAA,OAAA,IAAA,GAAA,CAAA,IAAA,EAAA,CAAA,EAAA,QAAA,CAAA,EAAA,EAAA,QAAA,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,8BAAA,CAAA,OAAA,EAAA;AACA,EAAA,OAAA,MAAA,CAAA,aAAA,CAAA,iBAAA,CAAA,OAAA,CAAA,CAAA,CAAA;AACA;;;;"}
@@ -0,0 +1,79 @@
1
+ import { getClient } from '../../currentScopes.js';
2
+ import { DEBUG_BUILD } from '../../debug-build.js';
3
+ import { debug } from '../../utils/debug-logger.js';
4
+ import { isError } from '../../utils/is.js';
5
+ import { getTraceData } from '../../utils/traceData.js';
6
+ import { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets.js';
7
+ import { LOG_PREFIX } from './constants.js';
8
+ import { getRequestUrlFromClientRequest } from './get-request-url.js';
9
+ import { mergeBaggageHeaders } from '../../utils/baggage.js';
10
+
11
+ /**
12
+ * Inject Sentry trace-propagation headers into an outgoing request if the
13
+ * target URL matches the configured `tracePropagationTargets`.
14
+ *
15
+ * Note: this must be called *before* calling `request.end()` (or firing the
16
+ * `http.client.request.start` diagnostics channel), because at that point,
17
+ * the headers have already been sent, and cannot be modified.
18
+ */
19
+ function injectTracePropagationHeaders(
20
+ request,
21
+ propagationDecisionMap,
22
+ ) {
23
+ const url = getRequestUrlFromClientRequest(request);
24
+ const clientOptions = getClient()?.getOptions();
25
+ const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};
26
+
27
+ if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {
28
+ return;
29
+ }
30
+
31
+ const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');
32
+
33
+ if (hasExistingSentryTraceHeader) {
34
+ // add nothing if there's already a sentry-trace header,
35
+ // or else baggage can be sent twice.
36
+ return;
37
+ }
38
+
39
+ const traceData = getTraceData({ propagateTraceparent });
40
+ if (!traceData) return;
41
+
42
+ const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;
43
+
44
+ if (sentryTrace) {
45
+ try {
46
+ request.setHeader('sentry-trace', sentryTrace);
47
+ DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');
48
+ } catch (e) {
49
+ DEBUG_BUILD &&
50
+ debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');
51
+ }
52
+ }
53
+
54
+ if (traceparent && !request.getHeader('traceparent')) {
55
+ try {
56
+ request.setHeader('traceparent', traceparent);
57
+ DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');
58
+ } catch (e) {
59
+ DEBUG_BUILD &&
60
+ debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');
61
+ }
62
+ }
63
+
64
+ if (baggage) {
65
+ const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);
66
+ if (merged) {
67
+ try {
68
+ request.setHeader('baggage', merged);
69
+ DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');
70
+ } catch (e) {
71
+ DEBUG_BUILD &&
72
+ debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ export { injectTracePropagationHeaders };
79
+ //# sourceMappingURL=inject-trace-propagation-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-trace-propagation-headers.js","sources":["../../../../src/integrations/http/inject-trace-propagation-headers.ts"],"sourcesContent":["import type { LRUMap } from '../../utils/lru';\nimport { getClient } from '../../currentScopes';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { debug } from '../../utils/debug-logger';\nimport { isError } from '../../utils/is';\nimport { getTraceData } from '../../utils/traceData';\nimport { shouldPropagateTraceForUrl } from '../../utils/tracePropagationTargets';\nimport { LOG_PREFIX } from './constants';\nimport { getRequestUrlFromClientRequest } from './get-request-url';\nimport type { HttpClientRequest } from './types';\nimport { mergeBaggageHeaders } from '../../utils/baggage';\n\n/**\n * Inject Sentry trace-propagation headers into an outgoing request if the\n * target URL matches the configured `tracePropagationTargets`.\n *\n * Note: this must be called *before* calling `request.end()` (or firing the\n * `http.client.request.start` diagnostics channel), because at that point,\n * the headers have already been sent, and cannot be modified.\n */\nexport function injectTracePropagationHeaders(\n request: HttpClientRequest,\n propagationDecisionMap: LRUMap<string, boolean>,\n): void {\n const url = getRequestUrlFromClientRequest(request);\n const clientOptions = getClient()?.getOptions();\n const { tracePropagationTargets, propagateTraceparent } = clientOptions ?? {};\n\n if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)) {\n return;\n }\n\n const hasExistingSentryTraceHeader = !!request.getHeader('sentry-trace');\n\n if (hasExistingSentryTraceHeader) {\n // add nothing if there's already a sentry-trace header,\n // or else baggage can be sent twice.\n return;\n }\n\n const traceData = getTraceData({ propagateTraceparent });\n if (!traceData) return;\n\n const { 'sentry-trace': sentryTrace, baggage, traceparent } = traceData;\n\n if (sentryTrace) {\n try {\n request.setHeader('sentry-trace', sentryTrace);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added sentry-trace header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set sentry-trace header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (traceparent && !request.getHeader('traceparent')) {\n try {\n request.setHeader('traceparent', traceparent);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added traceparent header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set traceparent header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n\n if (baggage) {\n const merged = mergeBaggageHeaders(request.getHeader('baggage'), baggage);\n if (merged) {\n try {\n request.setHeader('baggage', merged);\n DEBUG_BUILD && debug.log(LOG_PREFIX, 'Added baggage header');\n } catch (e) {\n DEBUG_BUILD &&\n debug.error(LOG_PREFIX, 'Failed to set baggage header:', isError(e) ? e.message : 'Unknown error');\n }\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,6BAA6B;AAC7C,EAAE,OAAO;AACT,EAAE,sBAAsB;AACxB,EAAQ;AACR,EAAE,MAAM,GAAA,GAAM,8BAA8B,CAAC,OAAO,CAAC;AACrD,EAAE,MAAM,gBAAgB,SAAS,EAAE,EAAE,UAAU,EAAE;AACjD,EAAE,MAAM,EAAE,uBAAuB,EAAE,oBAAA,KAAyB,aAAA,IAAiB,EAAE;;AAE/E,EAAE,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,EAAE;AACzF,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,4BAAA,GAA+B,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC;;AAE1E,EAAE,IAAI,4BAA4B,EAAE;AACpC;AACA;AACA,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,YAAY,YAAY,CAAC,EAAE,oBAAA,EAAsB,CAAC;AAC1D,EAAE,IAAI,CAAC,SAAS,EAAE;;AAElB,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,WAAA,EAAY,GAAI,SAAS;;AAEzE,EAAE,IAAI,WAAW,EAAE;AACnB,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC;AACpD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,2BAA2B,CAAC;AACvE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,oCAAoC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC/G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,WAAA,IAAe,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE;AACxD,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,WAAW,CAAC;AACnD,MAAM,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,0BAA0B,CAAC;AACtE,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,WAAA;AACN,QAAQ,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,mCAAmC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC9G,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,MAAM,MAAA,GAAS,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;AAC7E,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,IAAI;AACV,QAAQ,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;AAC5C,QAAQ,WAAA,IAAe,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,sBAAsB,CAAC;AACpE,MAAM,CAAA,CAAE,OAAO,CAAC,EAAE;AAClB,QAAQ,WAAA;AACR,UAAU,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,+BAA+B,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAA,GAAU,eAAe,CAAC;AAC5G,MAAM;AACN,IAAI;AACJ,EAAE;AACF;;;;"}
@@ -321,6 +321,8 @@ function _reconstructQuery(strings) {
321
321
  return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');
322
322
  }
323
323
 
324
+ let integerLiteralRE;
325
+
324
326
  /**
325
327
  * Sanitize SQL query as per the OTEL semantic conventions
326
328
  * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext
@@ -335,6 +337,13 @@ function _sanitizeSqlQuery(sqlQuery) {
335
337
  return 'Unknown SQL Query';
336
338
  }
337
339
 
340
+ // Lazy init: constructing this at module scope would evaluate the lookbehind
341
+ // on import and crash Safari <16.4 browser bundles that reach this file via
342
+ // the core barrel. Building it on first call keeps the cost off the import path.
343
+ if (!integerLiteralRE) {
344
+ integerLiteralRE = new RegExp('(?<!\\$)-?\\b\\d+\\b', 'g');
345
+ }
346
+
338
347
  return (
339
348
  sqlQuery
340
349
  // Remove comments first (they may contain newlines and extra spaces)
@@ -357,7 +366,7 @@ function _sanitizeSqlQuery(sqlQuery) {
357
366
  .replace(/-?\b\d+\.?\d*[eE][+-]?\d+\b/g, '?') // Scientific notation
358
367
  .replace(/-?\b\d+\.\d+\b/g, '?') // Decimals
359
368
  .replace(/-?\.\d+\b/g, '?') // Decimals starting with dot
360
- .replace(/(?<!\$)-?\b\d+\b/g, '?') // Integers (NOT $n placeholders)
369
+ .replace(integerLiteralRE, '?') // Integers (NOT $n placeholders)
361
370
  // Collapse IN clauses for cardinality (both ? and $n variants)
362
371
  .replace(/\bIN\b\s*\(\s*\?(?:\s*,\s*\?)*\s*\)/gi, 'IN (?)')
363
372
  .replace(/\bIN\b\s*\(\s*\$\d+(?:\s*,\s*\$\d+)*\s*\)/gi, 'IN ($?)')
@@ -1 +1 @@
1
- {"version":3,"file":"postgresjs.js","sources":["../../../src/integrations/postgresjs.ts"],"sourcesContent":["// Portable instrumentation for https://github.com/porsager/postgres\n// This can be used in any environment (Node.js, Cloudflare Workers, etc.)\n// without depending on OpenTelemetry module hooking.\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes';\nimport { SPAN_STATUS_ERROR, startSpanManual } from '../tracing';\nimport type { Span } from '../types-hoist/span';\nimport { debug } from '../utils/debug-logger';\nimport { getActiveSpan } from '../utils/spanUtils';\n\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string;\n ATTR_SERVER_ADDRESS?: string;\n ATTR_SERVER_PORT?: string;\n};\n\ninterface PostgresJsSqlInstrumentationOptions {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n}\n\nconst CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');\n\n// Use the same Symbol.for() markers as the Node.js OTel instrumentation\n// so that both approaches recognize each other and prevent double-wrapping.\nconst INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');\n// Marker to track if a query was created from an instrumented sql instance.\n// This prevents double-spanning when both the wrapper and the Node.js Query.prototype\n// fallback patch are active simultaneously.\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\n/**\n * Instruments a postgres.js `sql` instance with Sentry tracing.\n *\n * This is a portable instrumentation function that works in any environment\n * (Node.js, Cloudflare Workers, etc.) without depending on OpenTelemetry.\n *\n * @example\n * ```javascript\n * import postgres from 'postgres';\n * import * as Sentry from '@sentry/cloudflare'; // or '@sentry/deno'\n *\n * const sql = Sentry.instrumentPostgresJsSql(\n * postgres({ host: 'localhost', database: 'mydb' })\n * );\n *\n * // All queries now create Sentry spans\n * await sql`SELECT * FROM users WHERE id = ${userId}`;\n * ```\n */\nexport function instrumentPostgresJsSql<T>(sql: T, options?: PostgresJsSqlInstrumentationOptions): T {\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('instrumentPostgresJsSql: provided value is not a valid postgres.js sql instance');\n return sql;\n }\n\n return _instrumentSqlInstance(sql, { requireParentSpan: true, ...options }) as T;\n}\n\n/**\n * Instruments a sql instance by wrapping its query execution methods.\n */\nfunction _instrumentSqlInstance(\n sql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n parentConnectionContext?: PostgresConnectionContext,\n): unknown {\n // Check if already instrumented to prevent double-wrapping\n // Using Symbol.for() ensures the marker survives proxying\n if ((sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER]) {\n return sql;\n }\n\n // Wrap the sql function to intercept query creation\n const proxiedSql: unknown = new Proxy(sql as (...args: unknown[]) => unknown, {\n apply(target, thisArg, argumentsList: unknown[]) {\n const query = Reflect.apply(target, thisArg, argumentsList);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n },\n get(target, prop) {\n const original = (target as unknown as Record<string | symbol, unknown>)[prop];\n\n if (typeof prop !== 'string' || typeof original !== 'function') {\n return original;\n }\n\n // Wrap methods that return PendingQuery objects (unsafe, file)\n if (prop === 'unsafe' || prop === 'file') {\n return _wrapQueryMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n // Wrap begin and reserve (not savepoint to avoid duplicate spans)\n if (prop === 'begin' || prop === 'reserve') {\n return _wrapCallbackMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n return original;\n },\n });\n\n // Use provided parent context if available, otherwise extract from sql.options\n if (parentConnectionContext) {\n (proxiedSql as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;\n } else {\n _attachConnectionContext(sql, proxiedSql as Record<symbol, unknown>);\n }\n\n // Mark both the original and proxy as instrumented to prevent double-wrapping\n (sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n (proxiedSql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n\n return proxiedSql;\n}\n\n/**\n * Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.\n */\nfunction _wrapQueryMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n proxiedSql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n const query = Reflect.apply(original, target, args);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n };\n}\n\n/**\n * Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.\n * Note: These methods can also be used as tagged templates, which we pass through unchanged.\n *\n * Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.\n * Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.\n */\nfunction _wrapCallbackMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n parentSqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n // Extract parent context to propagate to child instances\n const parentContext = (parentSqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined;\n\n // Check if this is a callback-based call by verifying the last argument is a function\n const isCallbackBased = typeof args[args.length - 1] === 'function';\n\n if (!isCallbackBased) {\n // Not a callback-based call - could be tagged template or promise-based\n const result = Reflect.apply(original, target, args);\n // If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((sqlInstance: unknown) => {\n return _instrumentSqlInstance(sqlInstance, options, parentContext);\n });\n }\n return result;\n }\n\n // Callback-based call: wrap the callback to instrument the Sql instance\n const callback = (args.length === 1 ? args[0] : args[1]) as (sql: unknown) => unknown;\n const wrappedCallback = function (sqlInstance: unknown): unknown {\n const instrumentedSql = _instrumentSqlInstance(sqlInstance, options, parentContext);\n return callback(instrumentedSql);\n };\n\n const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];\n return Reflect.apply(original, target, newArgs);\n };\n}\n\n/**\n * Wraps a single query's handle method to create spans.\n */\nfunction _wrapSingleQueryHandle(\n query: { handle: unknown; strings?: string[]; __sentryWrapped?: boolean },\n sqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): void {\n // Prevent double wrapping - check if the handle itself is already wrapped\n if ((query.handle as { __sentryWrapped?: boolean })?.__sentryWrapped) {\n return;\n }\n\n // Mark this query as coming from an instrumented sql instance.\n // This prevents the Node.js Query.prototype fallback patch from double-spanning.\n (query as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL] = true;\n\n const originalHandle = query.handle as (...args: unknown[]) => Promise<unknown>;\n\n // IMPORTANT: We must replace the handle function directly, not use a Proxy,\n // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.\n const wrappedHandle = async function (this: unknown, ...args: unknown[]): Promise<unknown> {\n if (!_shouldCreateSpans(options)) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = _reconstructQuery(query.strings);\n const sanitizedSqlQuery = _sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.postgresjs');\n\n span.setAttributes({\n 'db.system.name': 'postgres',\n 'db.query.text': sanitizedSqlQuery,\n });\n\n const connectionContext = sqlInstance\n ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined)\n : undefined;\n\n _setConnectionAttributes(span, connectionContext);\n\n if (options.requestHook) {\n try {\n options.requestHook(span, sanitizedSqlQuery, connectionContext);\n } catch (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error('Error in requestHook for PostgresJs instrumentation:', e);\n }\n }\n\n const queryWithCallbacks = this as {\n resolve: unknown;\n reject: unknown;\n };\n\n queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n _setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n\n span.setAttribute('db.response.status_code', rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute('error.type', rejectArgs?.[0]?.name || 'unknown');\n\n _setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n // Handle synchronous errors that might occur before promise is created\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n (wrappedHandle as { __sentryWrapped?: boolean }).__sentryWrapped = true;\n query.handle = wrappedHandle;\n}\n\n/**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the options, a span will\n * only be created if there is a parent span available.\n */\nfunction _shouldCreateSpans(options: PostgresJsSqlInstrumentationOptions): boolean {\n const hasParentSpan = getActiveSpan() !== undefined;\n return hasParentSpan || !options.requireParentSpan;\n}\n\n/**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n *\n * @internal Exported for testing only\n */\nexport function _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n}\n\n/**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n *\n * @internal Exported for testing only\n */\nexport function _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(/(?<!\\$)-?\\b\\d+\\b/g, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n}\n\n/**\n * Sets connection context attributes on a span.\n */\nfunction _setConnectionAttributes(span: Span, connectionContext: PostgresConnectionContext | undefined): void {\n if (!connectionContext) {\n return;\n }\n if (connectionContext.ATTR_DB_NAMESPACE) {\n span.setAttribute('db.namespace', connectionContext.ATTR_DB_NAMESPACE);\n }\n if (connectionContext.ATTR_SERVER_ADDRESS) {\n span.setAttribute('server.address', connectionContext.ATTR_SERVER_ADDRESS);\n }\n if (connectionContext.ATTR_SERVER_PORT !== undefined) {\n // Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,\n // but semantic conventions expect port as a number for span attributes\n const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);\n if (!isNaN(portNumber)) {\n span.setAttribute('server.port', portNumber);\n }\n }\n}\n\n/**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\nfunction _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute('db.operation.name', command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute('db.operation.name', operationMatch[1].toUpperCase());\n }\n}\n\n/**\n * Extracts and stores connection context from sql.options.\n */\nfunction _attachConnectionContext(sql: unknown, proxiedSql: Record<symbol, unknown>): void {\n const sqlInstance = sql as { options?: { host?: string[]; port?: number[]; database?: string } };\n if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {\n return;\n }\n\n const opts = sqlInstance.options;\n // postgres.js stores parsed options with host and port as arrays\n // The library defaults to 'localhost' and 5432 if not specified, but we're defensive here\n const host = opts.host?.[0] || 'localhost';\n const port = opts.port?.[0] || 5432;\n\n const connectionContext: PostgresConnectionContext = {\n ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,\n ATTR_SERVER_ADDRESS: host,\n ATTR_SERVER_PORT: String(port),\n };\n\n proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgresjs.js","sources":["../../../src/integrations/postgresjs.ts"],"sourcesContent":["// Portable instrumentation for https://github.com/porsager/postgres\n// This can be used in any environment (Node.js, Cloudflare Workers, etc.)\n// without depending on OpenTelemetry module hooking.\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes';\nimport { SPAN_STATUS_ERROR, startSpanManual } from '../tracing';\nimport type { Span } from '../types-hoist/span';\nimport { debug } from '../utils/debug-logger';\nimport { getActiveSpan } from '../utils/spanUtils';\n\nconst SQL_OPERATION_REGEX = /^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i;\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string;\n ATTR_SERVER_ADDRESS?: string;\n ATTR_SERVER_PORT?: string;\n};\n\ninterface PostgresJsSqlInstrumentationOptions {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n}\n\nconst CONNECTION_CONTEXT_SYMBOL = Symbol('sentryPostgresConnectionContext');\n\n// Use the same Symbol.for() markers as the Node.js OTel instrumentation\n// so that both approaches recognize each other and prevent double-wrapping.\nconst INSTRUMENTED_MARKER = Symbol.for('sentry.instrumented.postgresjs');\n// Marker to track if a query was created from an instrumented sql instance.\n// This prevents double-spanning when both the wrapper and the Node.js Query.prototype\n// fallback patch are active simultaneously.\nconst QUERY_FROM_INSTRUMENTED_SQL = Symbol.for('sentry.query.from.instrumented.sql');\n\n/**\n * Instruments a postgres.js `sql` instance with Sentry tracing.\n *\n * This is a portable instrumentation function that works in any environment\n * (Node.js, Cloudflare Workers, etc.) without depending on OpenTelemetry.\n *\n * @example\n * ```javascript\n * import postgres from 'postgres';\n * import * as Sentry from '@sentry/cloudflare'; // or '@sentry/deno'\n *\n * const sql = Sentry.instrumentPostgresJsSql(\n * postgres({ host: 'localhost', database: 'mydb' })\n * );\n *\n * // All queries now create Sentry spans\n * await sql`SELECT * FROM users WHERE id = ${userId}`;\n * ```\n */\nexport function instrumentPostgresJsSql<T>(sql: T, options?: PostgresJsSqlInstrumentationOptions): T {\n if (!sql || typeof sql !== 'function') {\n DEBUG_BUILD && debug.warn('instrumentPostgresJsSql: provided value is not a valid postgres.js sql instance');\n return sql;\n }\n\n return _instrumentSqlInstance(sql, { requireParentSpan: true, ...options }) as T;\n}\n\n/**\n * Instruments a sql instance by wrapping its query execution methods.\n */\nfunction _instrumentSqlInstance(\n sql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n parentConnectionContext?: PostgresConnectionContext,\n): unknown {\n // Check if already instrumented to prevent double-wrapping\n // Using Symbol.for() ensures the marker survives proxying\n if ((sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER]) {\n return sql;\n }\n\n // Wrap the sql function to intercept query creation\n const proxiedSql: unknown = new Proxy(sql as (...args: unknown[]) => unknown, {\n apply(target, thisArg, argumentsList: unknown[]) {\n const query = Reflect.apply(target, thisArg, argumentsList);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n },\n get(target, prop) {\n const original = (target as unknown as Record<string | symbol, unknown>)[prop];\n\n if (typeof prop !== 'string' || typeof original !== 'function') {\n return original;\n }\n\n // Wrap methods that return PendingQuery objects (unsafe, file)\n if (prop === 'unsafe' || prop === 'file') {\n return _wrapQueryMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n // Wrap begin and reserve (not savepoint to avoid duplicate spans)\n if (prop === 'begin' || prop === 'reserve') {\n return _wrapCallbackMethod(original as (...args: unknown[]) => unknown, target, proxiedSql, options);\n }\n\n return original;\n },\n });\n\n // Use provided parent context if available, otherwise extract from sql.options\n if (parentConnectionContext) {\n (proxiedSql as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] = parentConnectionContext;\n } else {\n _attachConnectionContext(sql, proxiedSql as Record<symbol, unknown>);\n }\n\n // Mark both the original and proxy as instrumented to prevent double-wrapping\n (sql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n (proxiedSql as Record<symbol, unknown>)[INSTRUMENTED_MARKER] = true;\n\n return proxiedSql;\n}\n\n/**\n * Wraps query-returning methods (unsafe, file) to ensure their queries are instrumented.\n */\nfunction _wrapQueryMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n proxiedSql: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n const query = Reflect.apply(original, target, args);\n\n if (query && typeof query === 'object' && 'handle' in query) {\n _wrapSingleQueryHandle(query as { handle: unknown; strings?: string[] }, proxiedSql, options);\n }\n\n return query;\n };\n}\n\n/**\n * Wraps callback-based methods (begin, reserve) to recursively instrument Sql instances.\n * Note: These methods can also be used as tagged templates, which we pass through unchanged.\n *\n * Savepoint is not wrapped to avoid complex nested transaction instrumentation issues.\n * Queries within savepoint callbacks are still instrumented through the parent transaction's Sql instance.\n */\nfunction _wrapCallbackMethod(\n original: (...args: unknown[]) => unknown,\n target: unknown,\n parentSqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): (...args: unknown[]) => unknown {\n return function (this: unknown, ...args: unknown[]): unknown {\n // Extract parent context to propagate to child instances\n const parentContext = (parentSqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined;\n\n // Check if this is a callback-based call by verifying the last argument is a function\n const isCallbackBased = typeof args[args.length - 1] === 'function';\n\n if (!isCallbackBased) {\n // Not a callback-based call - could be tagged template or promise-based\n const result = Reflect.apply(original, target, args);\n // If result is a Promise (e.g., reserve() without callback), instrument the resolved Sql instance\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n return (result as Promise<unknown>).then((sqlInstance: unknown) => {\n return _instrumentSqlInstance(sqlInstance, options, parentContext);\n });\n }\n return result;\n }\n\n // Callback-based call: wrap the callback to instrument the Sql instance\n const callback = (args.length === 1 ? args[0] : args[1]) as (sql: unknown) => unknown;\n const wrappedCallback = function (sqlInstance: unknown): unknown {\n const instrumentedSql = _instrumentSqlInstance(sqlInstance, options, parentContext);\n return callback(instrumentedSql);\n };\n\n const newArgs = args.length === 1 ? [wrappedCallback] : [args[0], wrappedCallback];\n return Reflect.apply(original, target, newArgs);\n };\n}\n\n/**\n * Wraps a single query's handle method to create spans.\n */\nfunction _wrapSingleQueryHandle(\n query: { handle: unknown; strings?: string[]; __sentryWrapped?: boolean },\n sqlInstance: unknown,\n options: PostgresJsSqlInstrumentationOptions,\n): void {\n // Prevent double wrapping - check if the handle itself is already wrapped\n if ((query.handle as { __sentryWrapped?: boolean })?.__sentryWrapped) {\n return;\n }\n\n // Mark this query as coming from an instrumented sql instance.\n // This prevents the Node.js Query.prototype fallback patch from double-spanning.\n (query as Record<symbol, unknown>)[QUERY_FROM_INSTRUMENTED_SQL] = true;\n\n const originalHandle = query.handle as (...args: unknown[]) => Promise<unknown>;\n\n // IMPORTANT: We must replace the handle function directly, not use a Proxy,\n // because Query.then() internally calls this.handle(), which would bypass a Proxy wrapper.\n const wrappedHandle = async function (this: unknown, ...args: unknown[]): Promise<unknown> {\n if (!_shouldCreateSpans(options)) {\n return originalHandle.apply(this, args);\n }\n\n const fullQuery = _reconstructQuery(query.strings);\n const sanitizedSqlQuery = _sanitizeSqlQuery(fullQuery);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.postgresjs');\n\n span.setAttributes({\n 'db.system.name': 'postgres',\n 'db.query.text': sanitizedSqlQuery,\n });\n\n const connectionContext = sqlInstance\n ? ((sqlInstance as Record<symbol, unknown>)[CONNECTION_CONTEXT_SYMBOL] as\n | PostgresConnectionContext\n | undefined)\n : undefined;\n\n _setConnectionAttributes(span, connectionContext);\n\n if (options.requestHook) {\n try {\n options.requestHook(span, sanitizedSqlQuery, connectionContext);\n } catch (e) {\n span.setAttribute('sentry.hook.error', 'requestHook failed');\n DEBUG_BUILD && debug.error('Error in requestHook for PostgresJs instrumentation:', e);\n }\n }\n\n const queryWithCallbacks = this as {\n resolve: unknown;\n reject: unknown;\n };\n\n queryWithCallbacks.resolve = new Proxy(queryWithCallbacks.resolve as (...args: unknown[]) => unknown, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n try {\n _setOperationName(span, sanitizedSqlQuery, resolveArgs?.[0]?.command);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in resolve callback:', e);\n }\n\n return Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n },\n });\n\n queryWithCallbacks.reject = new Proxy(queryWithCallbacks.reject as (...args: unknown[]) => unknown, {\n apply: (rejectTarget, rejectThisArg, rejectArgs: { message?: string; code?: string; name?: string }[]) => {\n try {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: rejectArgs?.[0]?.message || 'unknown_error',\n });\n\n span.setAttribute('db.response.status_code', rejectArgs?.[0]?.code || 'unknown');\n span.setAttribute('error.type', rejectArgs?.[0]?.name || 'unknown');\n\n _setOperationName(span, sanitizedSqlQuery);\n span.end();\n } catch (e) {\n DEBUG_BUILD && debug.error('Error ending span in reject callback:', e);\n }\n return Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n },\n });\n\n // Handle synchronous errors that might occur before promise is created\n try {\n return originalHandle.apply(this, args);\n } catch (e) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n message: e instanceof Error ? e.message : 'unknown_error',\n });\n span.end();\n throw e;\n }\n },\n );\n };\n\n (wrappedHandle as { __sentryWrapped?: boolean }).__sentryWrapped = true;\n query.handle = wrappedHandle;\n}\n\n/**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the options, a span will\n * only be created if there is a parent span available.\n */\nfunction _shouldCreateSpans(options: PostgresJsSqlInstrumentationOptions): boolean {\n const hasParentSpan = getActiveSpan() !== undefined;\n return hasParentSpan || !options.requireParentSpan;\n}\n\n/**\n * Reconstructs the full SQL query from template strings with PostgreSQL placeholders.\n *\n * For sql`SELECT * FROM users WHERE id = ${123} AND name = ${'foo'}`:\n * strings = [\"SELECT * FROM users WHERE id = \", \" AND name = \", \"\"]\n * returns: \"SELECT * FROM users WHERE id = $1 AND name = $2\"\n *\n * @internal Exported for testing only\n */\nexport function _reconstructQuery(strings: string[] | undefined): string | undefined {\n if (!strings?.length) {\n return undefined;\n }\n if (strings.length === 1) {\n return strings[0] || undefined;\n }\n // Join template parts with PostgreSQL placeholders ($1, $2, etc.)\n return strings.reduce((acc, str, i) => (i === 0 ? str : `${acc}$${i}${str}`), '');\n}\n\nlet integerLiteralRE: RegExp | undefined;\n\n/**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n *\n * PostgreSQL $n placeholders are preserved per OTEL spec - they're parameterized queries,\n * not sensitive literals. Only actual values (strings, numbers, booleans) are sanitized.\n *\n * @internal Exported for testing only\n */\nexport function _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n // Lazy init: constructing this at module scope would evaluate the lookbehind\n // on import and crash Safari <16.4 browser bundles that reach this file via\n // the core barrel. Building it on first call keeps the cost off the import path.\n if (!integerLiteralRE) {\n integerLiteralRE = new RegExp('(?<!\\\\$)-?\\\\b\\\\d+\\\\b', 'g');\n }\n\n return (\n sqlQuery\n // Remove comments first (they may contain newlines and extra spaces)\n .replace(/--.*$/gm, '') // Single line comments (multiline mode)\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n // Collapse whitespace to a single space (after removing comments)\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces and trim\n // Sanitize hex/binary literals before string literals\n .replace(/\\bX'[0-9A-Fa-f]*'/gi, '?') // Hex string literals\n .replace(/\\bB'[01]*'/gi, '?') // Binary string literals\n // Sanitize string literals (handles escaped quotes)\n .replace(/'(?:[^']|'')*'/g, '?')\n // Sanitize hex numbers\n .replace(/\\b0x[0-9A-Fa-f]+/gi, '?')\n // Sanitize boolean literals\n .replace(/\\b(?:TRUE|FALSE)\\b/gi, '?')\n // Sanitize numeric literals (preserve $n placeholders via negative lookbehind)\n .replace(/-?\\b\\d+\\.?\\d*[eE][+-]?\\d+\\b/g, '?') // Scientific notation\n .replace(/-?\\b\\d+\\.\\d+\\b/g, '?') // Decimals\n .replace(/-?\\.\\d+\\b/g, '?') // Decimals starting with dot\n .replace(integerLiteralRE, '?') // Integers (NOT $n placeholders)\n // Collapse IN clauses for cardinality (both ? and $n variants)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/gi, 'IN (?)')\n .replace(/\\bIN\\b\\s*\\(\\s*\\$\\d+(?:\\s*,\\s*\\$\\d+)*\\s*\\)/gi, 'IN ($?)')\n );\n}\n\n/**\n * Sets connection context attributes on a span.\n */\nfunction _setConnectionAttributes(span: Span, connectionContext: PostgresConnectionContext | undefined): void {\n if (!connectionContext) {\n return;\n }\n if (connectionContext.ATTR_DB_NAMESPACE) {\n span.setAttribute('db.namespace', connectionContext.ATTR_DB_NAMESPACE);\n }\n if (connectionContext.ATTR_SERVER_ADDRESS) {\n span.setAttribute('server.address', connectionContext.ATTR_SERVER_ADDRESS);\n }\n if (connectionContext.ATTR_SERVER_PORT !== undefined) {\n // Port is stored as string in PostgresConnectionContext for requestHook backwards compatibility,\n // but semantic conventions expect port as a number for span attributes\n const portNumber = parseInt(connectionContext.ATTR_SERVER_PORT, 10);\n if (!isNaN(portNumber)) {\n span.setAttribute('server.port', portNumber);\n }\n }\n}\n\n/**\n * Extracts DB operation name from SQL query and sets it on the span.\n */\nfunction _setOperationName(span: Span, sanitizedQuery: string | undefined, command?: string): void {\n if (command) {\n span.setAttribute('db.operation.name', command);\n return;\n }\n // Fallback: extract operation from the SQL query\n const operationMatch = sanitizedQuery?.match(SQL_OPERATION_REGEX);\n if (operationMatch?.[1]) {\n span.setAttribute('db.operation.name', operationMatch[1].toUpperCase());\n }\n}\n\n/**\n * Extracts and stores connection context from sql.options.\n */\nfunction _attachConnectionContext(sql: unknown, proxiedSql: Record<symbol, unknown>): void {\n const sqlInstance = sql as { options?: { host?: string[]; port?: number[]; database?: string } };\n if (!sqlInstance.options || typeof sqlInstance.options !== 'object') {\n return;\n }\n\n const opts = sqlInstance.options;\n // postgres.js stores parsed options with host and port as arrays\n // The library defaults to 'localhost' and 5432 if not specified, but we're defensive here\n const host = opts.host?.[0] || 'localhost';\n const port = opts.port?.[0] || 5432;\n\n const connectionContext: PostgresConnectionContext = {\n ATTR_DB_NAMESPACE: typeof opts.database === 'string' && opts.database !== '' ? opts.database : undefined,\n ATTR_SERVER_ADDRESS: host,\n ATTR_SERVER_PORT: String(port),\n };\n\n proxiedSql[CONNECTION_CONTEXT_SYMBOL] = connectionContext;\n}\n"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;;;AASA,MAAM,mBAAA,GAAsB,mDAAmD;;AAuB/E,MAAM,yBAAA,GAA4B,MAAM,CAAC,iCAAiC,CAAC;;AAE3E;AACA;AACA,MAAM,sBAAsB,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC;AACxE;AACA;AACA;AACA,MAAM,8BAA8B,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC;;AAEpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAI,GAAG,EAAK,OAAO,EAA2C;AACrG,EAAE,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,EAAE;AACzC,IAAI,eAAe,KAAK,CAAC,IAAI,CAAC,iFAAiF,CAAC;AAChH,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF,EAAE,OAAO,sBAAsB,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,OAAA,EAAS,CAAA;AAC5E;;AAEA;AACA;AACA;AACA,SAAS,sBAAsB;AAC/B,EAAE,GAAG;AACL,EAAE,OAAO;AACT,EAAE,uBAAuB;AACzB,EAAW;AACX;AACA;AACA,EAAE,IAAI,CAAC,GAAA,GAAgC,mBAAmB,CAAC,EAAE;AAC7D,IAAI,OAAO,GAAG;AACd,EAAE;;AAEF;AACA,EAAE,MAAM,UAAU,GAAY,IAAI,KAAK,CAAC,MAAwC;AAChF,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAa;AACrD,MAAM,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC;;AAEjE,MAAM,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACnE,QAAQ,sBAAsB,CAAC,KAAA,GAAkD,UAAU,EAAE,OAAO,CAAC;AACrG,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE;AACtB,MAAM,MAAM,WAAW,CAAC,SAAuD,IAAI,CAAC;;AAEpF,MAAM,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,QAAA,KAAa,UAAU,EAAE;AACtE,QAAQ,OAAO,QAAQ;AACvB,MAAM;;AAEN;AACA,MAAM,IAAI,IAAA,KAAS,YAAY,IAAA,KAAS,MAAM,EAAE;AAChD,QAAQ,OAAO,gBAAgB,CAAC,QAAA,GAA6C,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC;AACzG,MAAM;;AAEN;AACA,MAAM,IAAI,IAAA,KAAS,WAAW,IAAA,KAAS,SAAS,EAAE;AAClD,QAAQ,OAAO,mBAAmB,CAAC,QAAA,GAA6C,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC;AAC5G,MAAM;;AAEN,MAAM,OAAO,QAAQ;AACrB,IAAI,CAAC;AACL,GAAG,CAAC;;AAEJ;AACA,EAAE,IAAI,uBAAuB,EAAE;AAC/B,IAAI,CAAC,UAAA,GAAuC,yBAAyB,CAAA,GAAI,uBAAuB;AAChG,EAAE,OAAO;AACT,IAAI,wBAAwB,CAAC,GAAG,EAAE,YAAsC;AACxE,EAAE;;AAEF;AACA,EAAE,CAAC,GAAA,GAAgC,mBAAmB,CAAA,GAAI,IAAI;AAC9D,EAAE,CAAC,UAAA,GAAuC,mBAAmB,CAAA,GAAI,IAAI;;AAErE,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA,SAAS,gBAAgB;AACzB,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,UAAU;AACZ,EAAE,OAAO;AACT,EAAmC;AACnC,EAAE,OAAO,WAAyB,GAAG,IAAI,EAAsB;AAC/D,IAAI,MAAM,KAAA,GAAQ,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;;AAEvD,IAAI,IAAI,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,IAAY,QAAA,IAAY,KAAK,EAAE;AACjE,MAAM,sBAAsB,CAAC,KAAA,GAAkD,UAAU,EAAE,OAAO,CAAC;AACnG,IAAI;;AAEJ,IAAI,OAAO,KAAK;AAChB,EAAE,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB;AAC5B,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,iBAAiB;AACnB,EAAE,OAAO;AACT,EAAmC;AACnC,EAAE,OAAO,WAAyB,GAAG,IAAI,EAAsB;AAC/D;AACA,IAAI,MAAM,gBAAgB,CAAC,oBAA8C,yBAAyB;;AAE5F;;AAEN;AACA,IAAI,MAAM,eAAA,GAAkB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAA,GAAS,CAAC,CAAA,KAAM,UAAU;;AAEvE,IAAI,IAAI,CAAC,eAAe,EAAE;AAC1B;AACA,MAAM,MAAM,MAAA,GAAS,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC;AAC1D;AACA,MAAM,IAAI,MAAA,IAAU,OAAO,CAAC,MAAA,GAA4B,IAAA,KAAS,UAAU,EAAE;AAC7E,QAAQ,OAAO,CAAC,MAAA,GAA4B,IAAI,CAAC,CAAC,WAAW,KAAc;AAC3E,UAAU,OAAO,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC;AAC5E,QAAQ,CAAC,CAAC;AACV,MAAM;AACN,MAAM,OAAO,MAAM;AACnB,IAAI;;AAEJ;AACA,IAAI,MAAM,QAAA,IAAY,IAAI,CAAC,WAAW,CAAA,GAAI,IAAI,CAAC,CAAC,CAAA,GAAI,IAAI,CAAC,CAAC,CAAC,CAAA;AAC3D,IAAI,MAAM,eAAA,GAAkB,UAAU,WAAW,EAAoB;AACrE,MAAM,MAAM,eAAA,GAAkB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,CAAC;AACzF,MAAM,OAAO,QAAQ,CAAC,eAAe,CAAC;AACtC,IAAI,CAAC;;AAEL,IAAI,MAAM,UAAU,IAAI,CAAC,MAAA,KAAW,IAAI,CAAC,eAAe,CAAA,GAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;AACtF,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC;AACnD,EAAE,CAAC;AACH;;AAEA;AACA;AACA;AACA,SAAS,sBAAsB;AAC/B,EAAE,KAAK;AACP,EAAE,WAAW;AACb,EAAE,OAAO;AACT,EAAQ;AACR;AACA,EAAE,IAAI,CAAC,KAAK,CAAC,MAAA,IAA0C,eAAe,EAAE;AACxE,IAAI;AACJ,EAAE;;AAEF;AACA;AACA,EAAE,CAAC,KAAA,GAAkC,2BAA2B,CAAA,GAAI,IAAI;;AAExE,EAAE,MAAM,cAAA,GAAiB,KAAK,CAAC,MAAA;;AAE/B;AACA;AACA,EAAE,MAAM,aAAA,GAAgB,iBAA+B,GAAG,IAAI,EAA+B;AAC7F,IAAI,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE;AACtC,MAAM,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAC7C,IAAI;;AAEJ,IAAI,MAAM,YAAY,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC;AACtD,IAAI,MAAM,iBAAA,GAAoB,iBAAiB,CAAC,SAAS,CAAC;;AAE1D,IAAI,OAAO,eAAe;AAC1B,MAAM;AACN,QAAQ,IAAI,EAAE,iBAAA,IAAqB,kBAAkB;AACrD,QAAQ,EAAE,EAAE,IAAI;AAChB,OAAO;AACP,MAAM,CAAC,IAAI,KAAW;AACtB,QAAQ,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,oBAAoB,CAAC;;AAEjF,QAAQ,IAAI,CAAC,aAAa,CAAC;AAC3B,UAAU,gBAAgB,EAAE,UAAU;AACtC,UAAU,eAAe,EAAE,iBAAiB;AAC5C,SAAS,CAAC;;AAEV,QAAQ,MAAM,oBAAoB;AAClC,aAAa,CAAC,cAAwC,yBAAyB;;AAEjE;AACd,YAAY,SAAS;;AAErB,QAAQ,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,CAAC;;AAEzD,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE;AACjC,UAAU,IAAI;AACd,YAAY,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;AAC3E,UAAU,CAAA,CAAE,OAAO,CAAC,EAAE;AACtB,YAAY,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;AACxE,YAAY,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,sDAAsD,EAAE,CAAC,CAAC;AACjG,UAAU;AACV,QAAQ;;AAER,QAAQ,MAAM,kBAAA,GAAqB;;AAG3B;;AAER,QAAQ,kBAAkB,CAAC,OAAA,GAAU,IAAI,KAAK,CAAC,kBAAkB,CAAC,OAAA,GAA4C;AAC9G,UAAU,KAAK,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,KAA6B;AACzF,YAAY,IAAI;AAChB,cAAc,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,EAAE,WAAW,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;AACnF,cAAc,IAAI,CAAC,GAAG,EAAE;AACxB,YAAY,CAAA,CAAE,OAAO,CAAC,EAAE;AACxB,cAAc,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,wCAAwC,EAAE,CAAC,CAAC;AACrF,YAAY;;AAEZ,YAAY,OAAO,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC;AAC5E,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV,QAAQ,kBAAkB,CAAC,MAAA,GAAS,IAAI,KAAK,CAAC,kBAAkB,CAAC,MAAA,GAA2C;AAC5G,UAAU,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,KAA2D;AACpH,YAAY,IAAI;AAChB,cAAc,IAAI,CAAC,SAAS,CAAC;AAC7B,gBAAgB,IAAI,EAAE,iBAAiB;AACvC,gBAAgB,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,OAAA,IAAW,eAAe;AACpE,eAAe,CAAC;;AAEhB,cAAc,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;AAC9F,cAAc,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,IAAA,IAAQ,SAAS,CAAC;;AAEjF,cAAc,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,CAAC;AACxD,cAAc,IAAI,CAAC,GAAG,EAAE;AACxB,YAAY,CAAA,CAAE,OAAO,CAAC,EAAE;AACxB,cAAc,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,uCAAuC,EAAE,CAAC,CAAC;AACpF,YAAY;AACZ,YAAY,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,CAAC;AACzE,UAAU,CAAC;AACX,SAAS,CAAC;;AAEV;AACA,QAAQ,IAAI;AACZ,UAAU,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AACjD,QAAQ,CAAA,CAAE,OAAO,CAAC,EAAE;AACpB,UAAU,IAAI,CAAC,SAAS,CAAC;AACzB,YAAY,IAAI,EAAE,iBAAiB;AACnC,YAAY,OAAO,EAAE,CAAA,YAAa,KAAA,GAAQ,CAAC,CAAC,OAAA,GAAU,eAAe;AACrE,WAAW,CAAC;AACZ,UAAU,IAAI,CAAC,GAAG,EAAE;AACpB,UAAU,MAAM,CAAC;AACjB,QAAQ;AACR,MAAM,CAAC;AACP,KAAK;AACL,EAAE,CAAC;;AAEH,EAAE,CAAC,aAAA,GAAgD,eAAA,GAAkB,IAAI;AACzE,EAAE,KAAK,CAAC,MAAA,GAAS,aAAa;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,OAAO,EAAgD;AACnF,EAAE,MAAM,aAAA,GAAgB,aAAa,EAAC,KAAM,SAAS;AACrD,EAAE,OAAO,aAAA,IAAiB,CAAC,OAAO,CAAC,iBAAiB;AACpD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAA4C;AACrF,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE;AACxB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,IAAI,OAAO,CAAC,MAAA,KAAW,CAAC,EAAE;AAC5B,IAAI,OAAO,OAAO,CAAC,CAAC,CAAA,IAAK,SAAS;AAClC,EAAE;AACF;AACA,EAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAA,KAAM,IAAI,GAAA,GAAM,CAAC,EAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA;AACA;;AAEA,IAAA,gBAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA,CAAA,QAAA,EAAA;AACA,EAAA,IAAA,CAAA,QAAA,EAAA;AACA,IAAA,OAAA,mBAAA;AACA,EAAA;;AAEA;AACA;AACA;AACA,EAAA,IAAA,CAAA,gBAAA,EAAA;AACA,IAAA,gBAAA,GAAA,IAAA,MAAA,CAAA,sBAAA,EAAA,GAAA,CAAA;AACA,EAAA;;AAEA,EAAA;AACA,IAAA;AACA;AACA,OAAA,OAAA,CAAA,SAAA,EAAA,EAAA,CAAA;AACA,OAAA,OAAA,CAAA,mBAAA,EAAA,EAAA,CAAA;AACA,OAAA,OAAA,CAAA,OAAA,EAAA,EAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,MAAA,EAAA,GAAA;AACA,OAAA,IAAA,EAAA;AACA;AACA,OAAA,OAAA,CAAA,qBAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,cAAA,EAAA,GAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,iBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,oBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,sBAAA,EAAA,GAAA;AACA;AACA,OAAA,OAAA,CAAA,8BAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,iBAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,YAAA,EAAA,GAAA,CAAA;AACA,OAAA,OAAA,CAAA,gBAAA,EAAA,GAAA,CAAA;AACA;AACA,OAAA,OAAA,CAAA,uCAAA,EAAA,QAAA;AACA,OAAA,OAAA,CAAA,6CAAA,EAAA,SAAA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAA,wBAAA,CAAA,IAAA,EAAA,iBAAA,EAAA;AACA,EAAA,IAAA,CAAA,iBAAA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,iBAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,cAAA,EAAA,iBAAA,CAAA,iBAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,mBAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,gBAAA,EAAA,iBAAA,CAAA,mBAAA,CAAA;AACA,EAAA;AACA,EAAA,IAAA,iBAAA,CAAA,gBAAA,KAAA,SAAA,EAAA;AACA;AACA;AACA,IAAA,MAAA,UAAA,GAAA,QAAA,CAAA,iBAAA,CAAA,gBAAA,EAAA,EAAA,CAAA;AACA,IAAA,IAAA,CAAA,KAAA,CAAA,UAAA,CAAA,EAAA;AACA,MAAA,IAAA,CAAA,YAAA,CAAA,aAAA,EAAA,UAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,iBAAA,CAAA,IAAA,EAAA,cAAA,EAAA,OAAA,EAAA;AACA,EAAA,IAAA,OAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,mBAAA,EAAA,OAAA,CAAA;AACA,IAAA;AACA,EAAA;AACA;AACA,EAAA,MAAA,cAAA,GAAA,cAAA,EAAA,KAAA,CAAA,mBAAA,CAAA;AACA,EAAA,IAAA,cAAA,GAAA,CAAA,CAAA,EAAA;AACA,IAAA,IAAA,CAAA,YAAA,CAAA,mBAAA,EAAA,cAAA,CAAA,CAAA,CAAA,CAAA,WAAA,EAAA,CAAA;AACA,EAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,wBAAA,CAAA,GAAA,EAAA,UAAA,EAAA;AACA,EAAA,MAAA,WAAA,GAAA,GAAA;AACA,EAAA,IAAA,CAAA,WAAA,CAAA,OAAA,IAAA,OAAA,WAAA,CAAA,OAAA,KAAA,QAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,MAAA,IAAA,GAAA,WAAA,CAAA,OAAA;AACA;AACA;AACA,EAAA,MAAA,IAAA,GAAA,IAAA,CAAA,IAAA,GAAA,CAAA,CAAA,IAAA,WAAA;AACA,EAAA,MAAA,IAAA,GAAA,IAAA,CAAA,IAAA,GAAA,CAAA,CAAA,IAAA,IAAA;;AAEA,EAAA,MAAA,iBAAA,GAAA;AACA,IAAA,iBAAA,EAAA,OAAA,IAAA,CAAA,QAAA,KAAA,QAAA,IAAA,IAAA,CAAA,QAAA,KAAA,EAAA,GAAA,IAAA,CAAA,QAAA,GAAA,SAAA;AACA,IAAA,mBAAA,EAAA,IAAA;AACA,IAAA,gBAAA,EAAA,MAAA,CAAA,IAAA,CAAA;AACA,GAAA;;AAEA,EAAA,UAAA,CAAA,yBAAA,CAAA,GAAA,iBAAA;AACA;;;;"}
@@ -1,6 +1,10 @@
1
+ import { getIsolationScope } from '../currentScopes.js';
1
2
  import { defineIntegration } from '../integration.js';
3
+ import { SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS } from '../semanticAttributes.js';
2
4
  import { parseCookie } from '../utils/cookie.js';
5
+ import { httpHeadersToSpanAttributes } from '../utils/request.js';
3
6
  import { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress.js';
7
+ import { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan.js';
4
8
 
5
9
  // TODO(v11): Change defaults based on `sendDefaultPii`
6
10
  const DEFAULT_INCLUDE = {
@@ -36,6 +40,22 @@ const _requestDataIntegration = ((options = {}) => {
36
40
 
37
41
  return event;
38
42
  },
43
+ processSegmentSpan(span, client) {
44
+ const { sdkProcessingMetadata = {} } = getIsolationScope().getScopeData();
45
+ const { normalizedRequest, ipAddress } = sdkProcessingMetadata;
46
+
47
+ if (!normalizedRequest) {
48
+ return;
49
+ }
50
+
51
+ const { sendDefaultPii } = client.getOptions();
52
+ const includeWithDefaultPiiApplied = {
53
+ ...include,
54
+ ip: include.ip ?? sendDefaultPii,
55
+ };
56
+
57
+ addNormalizedRequestDataToSpan(span, normalizedRequest, ipAddress, includeWithDefaultPiiApplied, sendDefaultPii);
58
+ },
39
59
  };
40
60
  }) ;
41
61
 
@@ -72,6 +92,60 @@ function addNormalizedRequestDataToEvent(
72
92
  }
73
93
  }
74
94
 
95
+ function addNormalizedRequestDataToSpan(
96
+ span,
97
+ normalizedRequest,
98
+ ipAddress,
99
+ include,
100
+ sendDefaultPii,
101
+ ) {
102
+ const requestData = extractNormalizedRequestData(normalizedRequest, include);
103
+ const attributes = {};
104
+
105
+ if (requestData.url) {
106
+ attributes['url.full'] = requestData.url;
107
+ }
108
+
109
+ if (requestData.method) {
110
+ attributes['http.request.method'] = requestData.method;
111
+ }
112
+
113
+ if (requestData.query_string) {
114
+ attributes['url.query'] = normalizeQueryString(requestData.query_string);
115
+ }
116
+
117
+ safeSetSpanJSONAttributes(span, attributes);
118
+
119
+ // Process cookies before headers so normalizedRequest.cookies takes precedence
120
+ // over the raw cookie header (matching the processEvent path).
121
+ if (requestData.cookies && Object.keys(requestData.cookies).length > 0) {
122
+ const cookieString = Object.entries(requestData.cookies)
123
+ .map(([name, value]) => `${name}=${value}`)
124
+ .join('; ');
125
+ const cookieAttributes = httpHeadersToSpanAttributes({ cookie: cookieString }, sendDefaultPii ?? false, 'request');
126
+ safeSetSpanJSONAttributes(span, cookieAttributes);
127
+ }
128
+
129
+ if (requestData.headers) {
130
+ const headerAttributes = httpHeadersToSpanAttributes(requestData.headers, sendDefaultPii ?? false, 'request');
131
+ safeSetSpanJSONAttributes(span, headerAttributes);
132
+ }
133
+
134
+ if (requestData.data != null) {
135
+ const serialized = typeof requestData.data === 'string' ? requestData.data : JSON.stringify(requestData.data);
136
+ if (serialized) {
137
+ safeSetSpanJSONAttributes(span, { 'http.request.body.data': serialized });
138
+ }
139
+ }
140
+
141
+ if (include.ip) {
142
+ const ip = (normalizedRequest.headers && getClientIPAddress(normalizedRequest.headers)) || ipAddress || undefined;
143
+ if (ip) {
144
+ safeSetSpanJSONAttributes(span, { [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: ip });
145
+ }
146
+ }
147
+ }
148
+
75
149
  function extractNormalizedRequestData(
76
150
  normalizedRequest,
77
151
  include,
@@ -82,17 +156,18 @@ function extractNormalizedRequestData(
82
156
  if (include.headers) {
83
157
  requestData.headers = headers;
84
158
 
85
- // Remove the Cookie header in case cookie data should not be included in the event
86
159
  if (!include.cookies) {
87
160
  delete (headers ).cookie;
88
161
  }
89
162
 
90
- // Remove IP headers in case IP data should not be included in the event
91
163
  if (!include.ip) {
92
- ipHeaderNames.forEach(ipHeaderName => {
93
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
94
- delete (headers )[ipHeaderName];
95
- });
164
+ const ipHeaderNamesLower = new Set(ipHeaderNames.map(name => name.toLowerCase()));
165
+ for (const key of Object.keys(headers)) {
166
+ if (ipHeaderNamesLower.has(key.toLowerCase())) {
167
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
168
+ delete (headers )[key];
169
+ }
170
+ }
96
171
  }
97
172
  }
98
173
 
@@ -118,5 +193,16 @@ function extractNormalizedRequestData(
118
193
  return requestData;
119
194
  }
120
195
 
196
+ function normalizeQueryString(queryString) {
197
+ if (typeof queryString === 'string') {
198
+ return queryString || undefined;
199
+ }
200
+
201
+ const pairs = Array.isArray(queryString) ? queryString : Object.entries(queryString);
202
+ const result = pairs.map(([key, value]) => `${key}=${value}`).join('&');
203
+
204
+ return result || undefined;
205
+ }
206
+
121
207
  export { requestDataIntegration };
122
208
  //# sourceMappingURL=requestdata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"requestdata.js","sources":["../../../src/integrations/requestdata.ts"],"sourcesContent":["import { defineIntegration } from '../integration';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { RequestEventData } from '../types-hoist/request';\nimport { parseCookie } from '../utils/cookie';\nimport { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress';\n\ninterface RequestDataIncludeOptions {\n cookies?: boolean;\n data?: boolean;\n headers?: boolean;\n ip?: boolean;\n query_string?: boolean;\n url?: boolean;\n}\n\ntype RequestDataIntegrationOptions = {\n /**\n * Controls what data is pulled from the request and added to the event.\n */\n include?: RequestDataIncludeOptions;\n};\n\n// TODO(v11): Change defaults based on `sendDefaultPii`\nconst DEFAULT_INCLUDE: RequestDataIncludeOptions = {\n cookies: true,\n data: true,\n headers: true,\n query_string: true,\n url: true,\n};\n\nconst INTEGRATION_NAME = 'RequestData';\n\nconst _requestDataIntegration = ((options: RequestDataIntegrationOptions = {}) => {\n const include = {\n ...DEFAULT_INCLUDE,\n ...options.include,\n };\n\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const { sdkProcessingMetadata = {} } = event;\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? client.getOptions().sendDefaultPii,\n };\n\n if (normalizedRequest) {\n addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied);\n }\n\n return event;\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/core`\n * so it can be used in cross-platform SDKs like `@sentry/nextjs`.\n */\nexport const requestDataIntegration = defineIntegration(_requestDataIntegration);\n\n/**\n * Add already normalized request data to an event.\n * This mutates the passed in event.\n */\nfunction addNormalizedRequestDataToEvent(\n event: Event,\n req: RequestEventData,\n // Data that should not go into `event.request` but is somehow related to requests\n additionalData: { ipAddress?: string },\n include: RequestDataIncludeOptions,\n): void {\n event.request = {\n ...event.request,\n ...extractNormalizedRequestData(req, include),\n };\n\n if (include.ip) {\n const ip = (req.headers && getClientIPAddress(req.headers)) || additionalData.ipAddress;\n if (ip) {\n event.user = {\n ...event.user,\n ip_address: ip,\n };\n }\n }\n}\n\nfunction extractNormalizedRequestData(\n normalizedRequest: RequestEventData,\n include: RequestDataIncludeOptions,\n): RequestEventData {\n const requestData: RequestEventData = {};\n const headers = { ...normalizedRequest.headers };\n\n if (include.headers) {\n requestData.headers = headers;\n\n // Remove the Cookie header in case cookie data should not be included in the event\n if (!include.cookies) {\n delete (headers as { cookie?: string }).cookie;\n }\n\n // Remove IP headers in case IP data should not be included in the event\n if (!include.ip) {\n ipHeaderNames.forEach(ipHeaderName => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (headers as Record<string, unknown>)[ipHeaderName];\n });\n }\n }\n\n requestData.method = normalizedRequest.method;\n\n if (include.url) {\n requestData.url = normalizedRequest.url;\n }\n\n if (include.cookies) {\n const cookies = normalizedRequest.cookies || (headers?.cookie ? parseCookie(headers.cookie) : undefined);\n requestData.cookies = cookies || {};\n }\n\n if (include.query_string) {\n requestData.query_string = normalizedRequest.query_string;\n }\n\n if (include.data) {\n requestData.data = normalizedRequest.data;\n }\n\n return requestData;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"requestdata.js","sources":["../../../src/integrations/requestdata.ts"],"sourcesContent":["import { getIsolationScope } from '../currentScopes';\nimport { defineIntegration } from '../integration';\nimport { SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS } from '../semanticAttributes';\nimport type { Event } from '../types-hoist/event';\nimport type { IntegrationFn } from '../types-hoist/integration';\nimport type { QueryParams, RequestEventData } from '../types-hoist/request';\nimport type { StreamedSpanJSON } from '../types-hoist/span';\nimport { parseCookie } from '../utils/cookie';\nimport { httpHeadersToSpanAttributes } from '../utils/request';\nimport { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress';\nimport { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan';\n\ninterface RequestDataIncludeOptions {\n cookies?: boolean;\n data?: boolean;\n headers?: boolean;\n ip?: boolean;\n query_string?: boolean;\n url?: boolean;\n}\n\ntype RequestDataIntegrationOptions = {\n /**\n * Controls what data is pulled from the request and added to the event.\n */\n include?: RequestDataIncludeOptions;\n};\n\n// TODO(v11): Change defaults based on `sendDefaultPii`\nconst DEFAULT_INCLUDE: RequestDataIncludeOptions = {\n cookies: true,\n data: true,\n headers: true,\n query_string: true,\n url: true,\n};\n\nconst INTEGRATION_NAME = 'RequestData';\n\nconst _requestDataIntegration = ((options: RequestDataIntegrationOptions = {}) => {\n const include = {\n ...DEFAULT_INCLUDE,\n ...options.include,\n };\n\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const { sdkProcessingMetadata = {} } = event;\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? client.getOptions().sendDefaultPii,\n };\n\n if (normalizedRequest) {\n addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied);\n }\n\n return event;\n },\n processSegmentSpan(span, client) {\n const { sdkProcessingMetadata = {} } = getIsolationScope().getScopeData();\n const { normalizedRequest, ipAddress } = sdkProcessingMetadata;\n\n if (!normalizedRequest) {\n return;\n }\n\n const { sendDefaultPii } = client.getOptions();\n const includeWithDefaultPiiApplied: RequestDataIncludeOptions = {\n ...include,\n ip: include.ip ?? sendDefaultPii,\n };\n\n addNormalizedRequestDataToSpan(span, normalizedRequest, ipAddress, includeWithDefaultPiiApplied, sendDefaultPii);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Add data about a request to an event. Primarily for use in Node-based SDKs, but included in `@sentry/core`\n * so it can be used in cross-platform SDKs like `@sentry/nextjs`.\n */\nexport const requestDataIntegration = defineIntegration(_requestDataIntegration);\n\n/**\n * Add already normalized request data to an event.\n * This mutates the passed in event.\n */\nfunction addNormalizedRequestDataToEvent(\n event: Event,\n req: RequestEventData,\n // Data that should not go into `event.request` but is somehow related to requests\n additionalData: { ipAddress?: string },\n include: RequestDataIncludeOptions,\n): void {\n event.request = {\n ...event.request,\n ...extractNormalizedRequestData(req, include),\n };\n\n if (include.ip) {\n const ip = (req.headers && getClientIPAddress(req.headers)) || additionalData.ipAddress;\n if (ip) {\n event.user = {\n ...event.user,\n ip_address: ip,\n };\n }\n }\n}\n\nfunction addNormalizedRequestDataToSpan(\n span: StreamedSpanJSON,\n normalizedRequest: RequestEventData,\n ipAddress: string | undefined,\n include: RequestDataIncludeOptions,\n sendDefaultPii: boolean | undefined,\n): void {\n const requestData = extractNormalizedRequestData(normalizedRequest, include);\n const attributes: Record<string, unknown> = {};\n\n if (requestData.url) {\n attributes['url.full'] = requestData.url;\n }\n\n if (requestData.method) {\n attributes['http.request.method'] = requestData.method;\n }\n\n if (requestData.query_string) {\n attributes['url.query'] = normalizeQueryString(requestData.query_string);\n }\n\n safeSetSpanJSONAttributes(span, attributes);\n\n // Process cookies before headers so normalizedRequest.cookies takes precedence\n // over the raw cookie header (matching the processEvent path).\n if (requestData.cookies && Object.keys(requestData.cookies).length > 0) {\n const cookieString = Object.entries(requestData.cookies)\n .map(([name, value]) => `${name}=${value}`)\n .join('; ');\n const cookieAttributes = httpHeadersToSpanAttributes({ cookie: cookieString }, sendDefaultPii ?? false, 'request');\n safeSetSpanJSONAttributes(span, cookieAttributes);\n }\n\n if (requestData.headers) {\n const headerAttributes = httpHeadersToSpanAttributes(requestData.headers, sendDefaultPii ?? false, 'request');\n safeSetSpanJSONAttributes(span, headerAttributes);\n }\n\n if (requestData.data != null) {\n const serialized = typeof requestData.data === 'string' ? requestData.data : JSON.stringify(requestData.data);\n if (serialized) {\n safeSetSpanJSONAttributes(span, { 'http.request.body.data': serialized });\n }\n }\n\n if (include.ip) {\n const ip = (normalizedRequest.headers && getClientIPAddress(normalizedRequest.headers)) || ipAddress || undefined;\n if (ip) {\n safeSetSpanJSONAttributes(span, { [SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: ip });\n }\n }\n}\n\nfunction extractNormalizedRequestData(\n normalizedRequest: RequestEventData,\n include: RequestDataIncludeOptions,\n): RequestEventData {\n const requestData: RequestEventData = {};\n const headers = { ...normalizedRequest.headers };\n\n if (include.headers) {\n requestData.headers = headers;\n\n if (!include.cookies) {\n delete (headers as { cookie?: string }).cookie;\n }\n\n if (!include.ip) {\n const ipHeaderNamesLower = new Set(ipHeaderNames.map(name => name.toLowerCase()));\n for (const key of Object.keys(headers)) {\n if (ipHeaderNamesLower.has(key.toLowerCase())) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (headers as Record<string, unknown>)[key];\n }\n }\n }\n }\n\n requestData.method = normalizedRequest.method;\n\n if (include.url) {\n requestData.url = normalizedRequest.url;\n }\n\n if (include.cookies) {\n const cookies = normalizedRequest.cookies || (headers?.cookie ? parseCookie(headers.cookie) : undefined);\n requestData.cookies = cookies || {};\n }\n\n if (include.query_string) {\n requestData.query_string = normalizedRequest.query_string;\n }\n\n if (include.data) {\n requestData.data = normalizedRequest.data;\n }\n\n return requestData;\n}\n\nfunction normalizeQueryString(queryString: QueryParams): string | undefined {\n if (typeof queryString === 'string') {\n return queryString || undefined;\n }\n\n const pairs = Array.isArray(queryString) ? queryString : Object.entries(queryString);\n const result = pairs.map(([key, value]) => `${key}=${value}`).join('&');\n\n return result || undefined;\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { addBreadcrumb } from '../breadcrumbs.js';
2
+ import { getClient } from '../currentScopes.js';
2
3
  import { DEBUG_BUILD } from '../debug-build.js';
3
4
  import { captureException } from '../exports.js';
4
5
  import { defineIntegration } from '../integration.js';
@@ -83,6 +84,25 @@ function isInstrumented(fn) {
83
84
  }
84
85
  }
85
86
 
87
+ /**
88
+ * Plain-object bodies are copied into `plainBody`; array inserts (and other non-plain shapes) stay only on `rawBody`.
89
+ * Returns a payload suitable for span attributes / breadcrumbs when the client has `sendDefaultPii` enabled.
90
+ */
91
+ function getMutationBodyPayloadForTelemetry(rawBody, plainBody) {
92
+ if (Object.keys(plainBody).length > 0) {
93
+ return plainBody;
94
+ }
95
+ if (Array.isArray(rawBody) && rawBody.length > 0) {
96
+ return rawBody;
97
+ }
98
+ return undefined;
99
+ }
100
+
101
+ /** True when the PostgREST builder carries a mutation body (for `insert(...)`, etc. in span descriptions). */
102
+ function hasMutationBodyForDescription(rawBody, plainBody) {
103
+ return getMutationBodyPayloadForTelemetry(rawBody, plainBody) !== undefined;
104
+ }
105
+
86
106
  /**
87
107
  * Extracts the database operation type from the HTTP method and headers
88
108
  * @param method - The HTTP method of the request
@@ -296,12 +316,19 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder) {
296
316
  }
297
317
  }
298
318
 
319
+ const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);
320
+ const bodyPayload = getMutationBodyPayloadForTelemetry(typedThis.body, body);
321
+
299
322
  // Adding operation to the beginning of the description if it's not a `select` operation
300
323
  // For example, it can be an `insert` or `update` operation but the query can be `select(...)`
301
324
  // For `select` operations, we don't need repeat it in the description
302
- const description = `${operation === 'select' ? '' : `${operation}${body ? '(...) ' : ''}`}${queryItems.join(
303
- ' ',
304
- )} from(${table})`;
325
+ const mutationPart =
326
+ operation === 'select'
327
+ ? ''
328
+ : `${operation}${hasMutationBodyForDescription(typedThis.body, body) ? '(...) ' : ''}`;
329
+ const queryPart = sendDefaultPii ? queryItems.join(' ') : queryItems.length > 0 ? '[redacted]' : '';
330
+ const descriptionMiddle = [mutationPart.trimEnd(), queryPart].filter(Boolean).join(' ');
331
+ const description = descriptionMiddle ? `${descriptionMiddle} from(${table})` : `from(${table})`;
305
332
 
306
333
  const attributes = {
307
334
  'db.table': table,
@@ -314,12 +341,12 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder) {
314
341
  [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db',
315
342
  };
316
343
 
317
- if (queryItems.length) {
344
+ if (queryItems.length && sendDefaultPii) {
318
345
  attributes['db.query'] = queryItems;
319
346
  }
320
347
 
321
- if (Object.keys(body).length) {
322
- attributes['db.body'] = body;
348
+ if (bodyPayload !== undefined && sendDefaultPii) {
349
+ attributes['db.body'] = bodyPayload;
323
350
  }
324
351
 
325
352
  return startSpan(
@@ -348,11 +375,11 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder) {
348
375
  }
349
376
 
350
377
  const supabaseContext = {};
351
- if (queryItems.length) {
378
+ if (queryItems.length && sendDefaultPii) {
352
379
  supabaseContext.query = queryItems;
353
380
  }
354
- if (Object.keys(body).length) {
355
- supabaseContext.body = body;
381
+ if (bodyPayload !== undefined && sendDefaultPii) {
382
+ supabaseContext.body = bodyPayload;
356
383
  }
357
384
 
358
385
  captureException(err, scope => {
@@ -379,12 +406,12 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder) {
379
406
 
380
407
  const data = {};
381
408
 
382
- if (queryItems.length) {
409
+ if (queryItems.length && sendDefaultPii) {
383
410
  data.query = queryItems;
384
411
  }
385
412
 
386
- if (Object.keys(body).length) {
387
- data.body = body;
413
+ if (bodyPayload !== undefined && sendDefaultPii) {
414
+ data.body = bodyPayload;
388
415
  }
389
416
 
390
417
  if (Object.keys(data).length) {