@sentry/core 10.30.0 → 10.32.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/build/cjs/attributes.js +98 -0
  2. package/build/cjs/attributes.js.map +1 -0
  3. package/build/cjs/client.js +11 -6
  4. package/build/cjs/client.js.map +1 -1
  5. package/build/cjs/envelope.js +41 -7
  6. package/build/cjs/envelope.js.map +1 -1
  7. package/build/cjs/index.js +30 -0
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/integrations/eventFilters.js +1 -1
  10. package/build/cjs/integrations/eventFilters.js.map +1 -1
  11. package/build/cjs/integrations/mcp-server/correlation.js +17 -3
  12. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  13. package/build/cjs/integrations/mcp-server/sessionExtraction.js +44 -0
  14. package/build/cjs/integrations/mcp-server/sessionExtraction.js.map +1 -1
  15. package/build/cjs/integrations/mcp-server/transport.js +17 -3
  16. package/build/cjs/integrations/mcp-server/transport.js.map +1 -1
  17. package/build/cjs/integrations/requestdata.js +72 -6
  18. package/build/cjs/integrations/requestdata.js.map +1 -1
  19. package/build/cjs/integrations/serverSpanStreaming.js +51 -0
  20. package/build/cjs/integrations/serverSpanStreaming.js.map +1 -0
  21. package/build/cjs/semanticAttributes.js +36 -0
  22. package/build/cjs/semanticAttributes.js.map +1 -1
  23. package/build/cjs/spans/captureSpan.js +107 -0
  24. package/build/cjs/spans/captureSpan.js.map +1 -0
  25. package/build/cjs/spans/spanBuffer.js +117 -0
  26. package/build/cjs/spans/spanBuffer.js.map +1 -0
  27. package/build/cjs/spans/spanFirstUtils.js +187 -0
  28. package/build/cjs/spans/spanFirstUtils.js.map +1 -0
  29. package/build/cjs/tracing/ai/messageTruncation.js +120 -11
  30. package/build/cjs/tracing/ai/messageTruncation.js.map +1 -1
  31. package/build/cjs/tracing/google-genai/index.js +31 -14
  32. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  33. package/build/cjs/tracing/google-genai/utils.js +24 -5
  34. package/build/cjs/tracing/google-genai/utils.js.map +1 -1
  35. package/build/cjs/tracing/sentrySpan.js +31 -0
  36. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  37. package/build/cjs/tracing/trace.js +1 -0
  38. package/build/cjs/tracing/trace.js.map +1 -1
  39. package/build/cjs/tracing/vercel-ai/index.js +4 -5
  40. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  41. package/build/cjs/tracing/vercel-ai/vercel-ai-attributes.js +0 -10
  42. package/build/cjs/tracing/vercel-ai/vercel-ai-attributes.js.map +1 -1
  43. package/build/cjs/utils/applyScopeDataToEvent.js +5 -0
  44. package/build/cjs/utils/applyScopeDataToEvent.js.map +1 -1
  45. package/build/cjs/utils/beforeSendSpan.js +36 -0
  46. package/build/cjs/utils/beforeSendSpan.js.map +1 -0
  47. package/build/cjs/utils/featureFlags.js +1 -0
  48. package/build/cjs/utils/featureFlags.js.map +1 -1
  49. package/build/cjs/utils/request.js +75 -12
  50. package/build/cjs/utils/request.js.map +1 -1
  51. package/build/cjs/utils/should-ignore-span.js +31 -9
  52. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  53. package/build/cjs/utils/spanUtils.js +101 -2
  54. package/build/cjs/utils/spanUtils.js.map +1 -1
  55. package/build/cjs/utils/traceData.js +1 -4
  56. package/build/cjs/utils/traceData.js.map +1 -1
  57. package/build/cjs/utils/version.js +1 -1
  58. package/build/cjs/utils/version.js.map +1 -1
  59. package/build/esm/attributes.js +95 -0
  60. package/build/esm/attributes.js.map +1 -0
  61. package/build/esm/client.js +6 -1
  62. package/build/esm/client.js.map +1 -1
  63. package/build/esm/envelope.js +41 -8
  64. package/build/esm/envelope.js.map +1 -1
  65. package/build/esm/index.js +10 -4
  66. package/build/esm/index.js.map +1 -1
  67. package/build/esm/integrations/eventFilters.js +1 -1
  68. package/build/esm/integrations/eventFilters.js.map +1 -1
  69. package/build/esm/integrations/mcp-server/correlation.js +17 -3
  70. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  71. package/build/esm/integrations/mcp-server/sessionExtraction.js +43 -1
  72. package/build/esm/integrations/mcp-server/sessionExtraction.js.map +1 -1
  73. package/build/esm/integrations/mcp-server/transport.js +18 -4
  74. package/build/esm/integrations/mcp-server/transport.js.map +1 -1
  75. package/build/esm/integrations/requestdata.js +72 -6
  76. package/build/esm/integrations/requestdata.js.map +1 -1
  77. package/build/esm/integrations/serverSpanStreaming.js +49 -0
  78. package/build/esm/integrations/serverSpanStreaming.js.map +1 -0
  79. package/build/esm/package.json +1 -1
  80. package/build/esm/semanticAttributes.js +26 -1
  81. package/build/esm/semanticAttributes.js.map +1 -1
  82. package/build/esm/spans/captureSpan.js +105 -0
  83. package/build/esm/spans/captureSpan.js.map +1 -0
  84. package/build/esm/spans/spanBuffer.js +115 -0
  85. package/build/esm/spans/spanBuffer.js.map +1 -0
  86. package/build/esm/spans/spanFirstUtils.js +183 -0
  87. package/build/esm/spans/spanFirstUtils.js.map +1 -0
  88. package/build/esm/tracing/ai/messageTruncation.js +121 -11
  89. package/build/esm/tracing/ai/messageTruncation.js.map +1 -1
  90. package/build/esm/tracing/google-genai/index.js +34 -17
  91. package/build/esm/tracing/google-genai/index.js.map +1 -1
  92. package/build/esm/tracing/google-genai/utils.js +24 -6
  93. package/build/esm/tracing/google-genai/utils.js.map +1 -1
  94. package/build/esm/tracing/sentrySpan.js +32 -1
  95. package/build/esm/tracing/sentrySpan.js.map +1 -1
  96. package/build/esm/tracing/trace.js +1 -0
  97. package/build/esm/tracing/trace.js.map +1 -1
  98. package/build/esm/tracing/vercel-ai/index.js +5 -6
  99. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  100. package/build/esm/tracing/vercel-ai/vercel-ai-attributes.js +1 -10
  101. package/build/esm/tracing/vercel-ai/vercel-ai-attributes.js.map +1 -1
  102. package/build/esm/utils/applyScopeDataToEvent.js +5 -0
  103. package/build/esm/utils/applyScopeDataToEvent.js.map +1 -1
  104. package/build/esm/utils/beforeSendSpan.js +33 -0
  105. package/build/esm/utils/beforeSendSpan.js.map +1 -0
  106. package/build/esm/utils/featureFlags.js +1 -0
  107. package/build/esm/utils/featureFlags.js.map +1 -1
  108. package/build/esm/utils/request.js +76 -13
  109. package/build/esm/utils/request.js.map +1 -1
  110. package/build/esm/utils/should-ignore-span.js +31 -9
  111. package/build/esm/utils/should-ignore-span.js.map +1 -1
  112. package/build/esm/utils/spanUtils.js +97 -3
  113. package/build/esm/utils/spanUtils.js.map +1 -1
  114. package/build/esm/utils/traceData.js +1 -4
  115. package/build/esm/utils/traceData.js.map +1 -1
  116. package/build/esm/utils/version.js +1 -1
  117. package/build/esm/utils/version.js.map +1 -1
  118. package/build/types/attributes.d.ts +2 -2
  119. package/build/types/attributes.d.ts.map +1 -1
  120. package/build/types/client.d.ts +40 -2
  121. package/build/types/client.d.ts.map +1 -1
  122. package/build/types/envelope.d.ts +6 -1
  123. package/build/types/envelope.d.ts.map +1 -1
  124. package/build/types/index.d.ts +12 -5
  125. package/build/types/index.d.ts.map +1 -1
  126. package/build/types/integrations/mcp-server/correlation.d.ts +2 -2
  127. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  128. package/build/types/integrations/mcp-server/sessionExtraction.d.ts +13 -1
  129. package/build/types/integrations/mcp-server/sessionExtraction.d.ts.map +1 -1
  130. package/build/types/integrations/mcp-server/transport.d.ts.map +1 -1
  131. package/build/types/integrations/requestdata.d.ts.map +1 -1
  132. package/build/types/integrations/serverSpanStreaming.d.ts +8 -0
  133. package/build/types/integrations/serverSpanStreaming.d.ts.map +1 -0
  134. package/build/types/semanticAttributes.d.ts +21 -0
  135. package/build/types/semanticAttributes.d.ts.map +1 -1
  136. package/build/types/spans/captureSpan.d.ts +10 -0
  137. package/build/types/spans/captureSpan.d.ts.map +1 -0
  138. package/build/types/spans/spanBuffer.d.ts +31 -0
  139. package/build/types/spans/spanBuffer.d.ts.map +1 -0
  140. package/build/types/spans/spanFirstUtils.d.ts +20 -0
  141. package/build/types/spans/spanFirstUtils.d.ts.map +1 -0
  142. package/build/types/tracing/ai/messageTruncation.d.ts +0 -20
  143. package/build/types/tracing/ai/messageTruncation.d.ts.map +1 -1
  144. package/build/types/tracing/google-genai/index.d.ts.map +1 -1
  145. package/build/types/tracing/google-genai/utils.d.ts +25 -0
  146. package/build/types/tracing/google-genai/utils.d.ts.map +1 -1
  147. package/build/types/tracing/sentrySpan.d.ts +10 -1
  148. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  149. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  150. package/build/types/types-hoist/attributes.d.ts +19 -0
  151. package/build/types/types-hoist/attributes.d.ts.map +1 -0
  152. package/build/types/types-hoist/envelope.d.ts +22 -2
  153. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  154. package/build/types/types-hoist/link.d.ts +2 -2
  155. package/build/types/types-hoist/link.d.ts.map +1 -1
  156. package/build/types/types-hoist/options.d.ts +31 -2
  157. package/build/types/types-hoist/options.d.ts.map +1 -1
  158. package/build/types/types-hoist/span.d.ts +27 -0
  159. package/build/types/types-hoist/span.d.ts.map +1 -1
  160. package/build/types/utils/applyScopeDataToEvent.d.ts.map +1 -1
  161. package/build/types/utils/beforeSendSpan.d.ts +22 -0
  162. package/build/types/utils/beforeSendSpan.d.ts.map +1 -0
  163. package/build/types/utils/featureFlags.d.ts.map +1 -1
  164. package/build/types/utils/request.d.ts +1 -1
  165. package/build/types/utils/request.d.ts.map +1 -1
  166. package/build/types/utils/should-ignore-span.d.ts +3 -3
  167. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  168. package/build/types/utils/spanUtils.d.ts +26 -2
  169. package/build/types/utils/spanUtils.d.ts.map +1 -1
  170. package/build/types/utils/traceData.d.ts.map +1 -1
  171. package/build/types-ts3.8/attributes.d.ts +2 -2
  172. package/build/types-ts3.8/client.d.ts +40 -2
  173. package/build/types-ts3.8/envelope.d.ts +6 -1
  174. package/build/types-ts3.8/index.d.ts +12 -5
  175. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +2 -2
  176. package/build/types-ts3.8/integrations/mcp-server/sessionExtraction.d.ts +13 -1
  177. package/build/types-ts3.8/integrations/serverSpanStreaming.d.ts +8 -0
  178. package/build/types-ts3.8/semanticAttributes.d.ts +21 -0
  179. package/build/types-ts3.8/spans/captureSpan.d.ts +10 -0
  180. package/build/types-ts3.8/spans/spanBuffer.d.ts +31 -0
  181. package/build/types-ts3.8/spans/spanFirstUtils.d.ts +20 -0
  182. package/build/types-ts3.8/tracing/ai/messageTruncation.d.ts +0 -20
  183. package/build/types-ts3.8/tracing/google-genai/utils.d.ts +25 -0
  184. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  185. package/build/types-ts3.8/types-hoist/attributes.d.ts +19 -0
  186. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  187. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  188. package/build/types-ts3.8/types-hoist/options.d.ts +31 -2
  189. package/build/types-ts3.8/types-hoist/span.d.ts +27 -0
  190. package/build/types-ts3.8/utils/beforeSendSpan.d.ts +22 -0
  191. package/build/types-ts3.8/utils/request.d.ts +1 -1
  192. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -3
  193. package/build/types-ts3.8/utils/spanUtils.d.ts +26 -2
  194. package/package.json +1 -1
@@ -113,21 +113,29 @@ function getAbsoluteUrl({
113
113
  return undefined;
114
114
  }
115
115
 
116
- // "-user" because otherwise it would match "user-agent"
117
116
  const SENSITIVE_HEADER_SNIPPETS = [
118
117
  'auth',
119
118
  'token',
120
119
  'secret',
121
- 'cookie',
122
- '-user',
120
+ 'session', // for the user_session cookie
123
121
  'password',
122
+ 'passwd',
123
+ 'pwd',
124
124
  'key',
125
125
  'jwt',
126
126
  'bearer',
127
127
  'sso',
128
128
  'saml',
129
+ 'csrf',
130
+ 'xsrf',
131
+ 'credentials',
132
+ // Always treat cookie headers as sensitive in case individual key-value cookie pairs cannot properly be extracted
133
+ 'set-cookie',
134
+ 'cookie',
129
135
  ];
130
136
 
137
+ const PII_HEADER_SNIPPETS = ['x-forwarded-', '-user'];
138
+
131
139
  /**
132
140
  * Converts incoming HTTP request headers to OpenTelemetry span attributes following semantic conventions.
133
141
  * Header names are converted to the format: http.request.header.<key>
@@ -137,6 +145,7 @@ const SENSITIVE_HEADER_SNIPPETS = [
137
145
  */
138
146
  function httpHeadersToSpanAttributes(
139
147
  headers,
148
+ sendDefaultPii = false,
140
149
  ) {
141
150
  const spanAttributes = {};
142
151
 
@@ -146,16 +155,29 @@ function httpHeadersToSpanAttributes(
146
155
  return;
147
156
  }
148
157
 
149
- const lowerCasedKey = key.toLowerCase();
150
- const isSensitive = SENSITIVE_HEADER_SNIPPETS.some(snippet => lowerCasedKey.includes(snippet));
151
- const normalizedKey = `http.request.header.${lowerCasedKey.replace(/-/g, '_')}`;
152
-
153
- if (isSensitive) {
154
- spanAttributes[normalizedKey] = '[Filtered]';
155
- } else if (Array.isArray(value)) {
156
- spanAttributes[normalizedKey] = value.map(v => (v != null ? String(v) : v)).join(';');
157
- } else if (typeof value === 'string') {
158
- spanAttributes[normalizedKey] = value;
158
+ const lowerCasedHeaderKey = key.toLowerCase();
159
+ const isCookieHeader = lowerCasedHeaderKey === 'cookie' || lowerCasedHeaderKey === 'set-cookie';
160
+
161
+ if (isCookieHeader && typeof value === 'string' && value !== '') {
162
+ // Set-Cookie: single cookie with attributes ("name=value; HttpOnly; Secure")
163
+ // Cookie: multiple cookies separated by "; " ("cookie1=value1; cookie2=value2")
164
+ const isSetCookie = lowerCasedHeaderKey === 'set-cookie';
165
+ const semicolonIndex = value.indexOf(';');
166
+ const cookieString = isSetCookie && semicolonIndex !== -1 ? value.substring(0, semicolonIndex) : value;
167
+ const cookies = isSetCookie ? [cookieString] : cookieString.split('; ');
168
+
169
+ for (const cookie of cookies) {
170
+ // Split only at the first '=' to preserve '=' characters in cookie values
171
+ const equalSignIndex = cookie.indexOf('=');
172
+ const cookieKey = equalSignIndex !== -1 ? cookie.substring(0, equalSignIndex) : cookie;
173
+ const cookieValue = equalSignIndex !== -1 ? cookie.substring(equalSignIndex + 1) : '';
174
+
175
+ const lowerCasedCookieKey = cookieKey.toLowerCase();
176
+
177
+ addSpanAttribute(spanAttributes, lowerCasedHeaderKey, lowerCasedCookieKey, cookieValue, sendDefaultPii);
178
+ }
179
+ } else {
180
+ addSpanAttribute(spanAttributes, lowerCasedHeaderKey, '', value, sendDefaultPii);
159
181
  }
160
182
  });
161
183
  } catch {
@@ -165,6 +187,47 @@ function httpHeadersToSpanAttributes(
165
187
  return spanAttributes;
166
188
  }
167
189
 
190
+ function normalizeAttributeKey(key) {
191
+ return key.replace(/-/g, '_');
192
+ }
193
+
194
+ function addSpanAttribute(
195
+ spanAttributes,
196
+ headerKey,
197
+ cookieKey,
198
+ value,
199
+ sendPii,
200
+ ) {
201
+ const normalizedKey = cookieKey
202
+ ? `http.request.header.${normalizeAttributeKey(headerKey)}.${normalizeAttributeKey(cookieKey)}`
203
+ : `http.request.header.${normalizeAttributeKey(headerKey)}`;
204
+
205
+ const headerValue = handleHttpHeader(cookieKey || headerKey, value, sendPii);
206
+ if (headerValue !== undefined) {
207
+ spanAttributes[normalizedKey] = headerValue;
208
+ }
209
+ }
210
+
211
+ function handleHttpHeader(
212
+ lowerCasedKey,
213
+ value,
214
+ sendPii,
215
+ ) {
216
+ const isSensitive = sendPii
217
+ ? SENSITIVE_HEADER_SNIPPETS.some(snippet => lowerCasedKey.includes(snippet))
218
+ : [...PII_HEADER_SNIPPETS, ...SENSITIVE_HEADER_SNIPPETS].some(snippet => lowerCasedKey.includes(snippet));
219
+
220
+ if (isSensitive) {
221
+ return '[Filtered]';
222
+ } else if (Array.isArray(value)) {
223
+ return value.map(v => (v != null ? String(v) : v)).join(';');
224
+ } else if (typeof value === 'string') {
225
+ return value;
226
+ }
227
+
228
+ return undefined;
229
+ }
230
+
168
231
  /** Extract the query params from an URL. */
169
232
  function extractQueryParamsFromUrl(url) {
170
233
  // url is path and query string
@@ -1 +1 @@
1
- {"version":3,"file":"request.js","sources":["../../../src/utils/request.ts"],"sourcesContent":["import type { PolymorphicRequest } from '../types-hoist/polymorphics';\nimport type { RequestEventData } from '../types-hoist/request';\nimport type { WebFetchHeaders, WebFetchRequest } from '../types-hoist/webfetchapi';\n\n/**\n * Transforms a `Headers` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into a simple key-value dict.\n * The header keys will be lower case: e.g. A \"Content-Type\" header will be stored as \"content-type\".\n */\nexport function winterCGHeadersToDict(winterCGHeaders: WebFetchHeaders): Record<string, string> {\n const headers: Record<string, string> = {};\n try {\n winterCGHeaders.forEach((value, key) => {\n if (typeof value === 'string') {\n // We check that value is a string even though it might be redundant to make sure prototype pollution is not possible.\n headers[key] = value;\n }\n });\n } catch {\n // just return the empty headers\n }\n\n return headers;\n}\n\n/**\n * Convert common request headers to a simple dictionary.\n */\nexport function headersToDict(reqHeaders: Record<string, string | string[] | undefined>): Record<string, string> {\n const headers: Record<string, string> = Object.create(null);\n\n try {\n Object.entries(reqHeaders).forEach(([key, value]) => {\n if (typeof value === 'string') {\n headers[key] = value;\n }\n });\n } catch {\n // just return the empty headers\n }\n\n return headers;\n}\n\n/**\n * Converts a `Request` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into the format that the `RequestData` integration understands.\n */\nexport function winterCGRequestToRequestData(req: WebFetchRequest): RequestEventData {\n const headers = winterCGHeadersToDict(req.headers);\n\n return {\n method: req.method,\n url: req.url,\n query_string: extractQueryParamsFromUrl(req.url),\n headers,\n // TODO: Can we extract body data from the request?\n };\n}\n\n/**\n * Convert a HTTP request object to RequestEventData to be passed as normalizedRequest.\n * Instead of allowing `PolymorphicRequest` to be passed,\n * we want to be more specific and generally require a http.IncomingMessage-like object.\n */\nexport function httpRequestToRequestData(request: {\n method?: string;\n url?: string;\n headers?: {\n [key: string]: string | string[] | undefined;\n };\n protocol?: string;\n socket?: {\n encrypted?: boolean;\n remoteAddress?: string;\n };\n}): RequestEventData {\n const headers = request.headers || {};\n\n // Check for x-forwarded-host first, then fall back to host header\n const forwardedHost = typeof headers['x-forwarded-host'] === 'string' ? headers['x-forwarded-host'] : undefined;\n const host = forwardedHost || (typeof headers.host === 'string' ? headers.host : undefined);\n\n // Check for x-forwarded-proto first, then fall back to existing protocol detection\n const forwardedProto = typeof headers['x-forwarded-proto'] === 'string' ? headers['x-forwarded-proto'] : undefined;\n const protocol = forwardedProto || request.protocol || (request.socket?.encrypted ? 'https' : 'http');\n\n const url = request.url || '';\n\n const absoluteUrl = getAbsoluteUrl({\n url,\n host,\n protocol,\n });\n\n // This is non-standard, but may be sometimes set\n // It may be overwritten later by our own body handling\n const data = (request as PolymorphicRequest).body || undefined;\n\n // This is non-standard, but may be set on e.g. Next.js or Express requests\n const cookies = (request as PolymorphicRequest).cookies;\n\n return {\n url: absoluteUrl,\n method: request.method,\n query_string: extractQueryParamsFromUrl(url),\n headers: headersToDict(headers),\n cookies,\n data,\n };\n}\n\nfunction getAbsoluteUrl({\n url,\n protocol,\n host,\n}: {\n url?: string;\n protocol: string;\n host?: string;\n}): string | undefined {\n if (url?.startsWith('http')) {\n return url;\n }\n\n if (url && host) {\n return `${protocol}://${host}${url}`;\n }\n\n return undefined;\n}\n\n// \"-user\" because otherwise it would match \"user-agent\"\nconst SENSITIVE_HEADER_SNIPPETS = [\n 'auth',\n 'token',\n 'secret',\n 'cookie',\n '-user',\n 'password',\n 'key',\n 'jwt',\n 'bearer',\n 'sso',\n 'saml',\n];\n\n/**\n * Converts incoming HTTP request headers to OpenTelemetry span attributes following semantic conventions.\n * Header names are converted to the format: http.request.header.<key>\n * where <key> is the header name in lowercase with dashes converted to underscores.\n *\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/#http-request-header\n */\nexport function httpHeadersToSpanAttributes(\n headers: Record<string, string | string[] | undefined>,\n): Record<string, string> {\n const spanAttributes: Record<string, string> = {};\n\n try {\n Object.entries(headers).forEach(([key, value]) => {\n if (value == null) {\n return;\n }\n\n const lowerCasedKey = key.toLowerCase();\n const isSensitive = SENSITIVE_HEADER_SNIPPETS.some(snippet => lowerCasedKey.includes(snippet));\n const normalizedKey = `http.request.header.${lowerCasedKey.replace(/-/g, '_')}`;\n\n if (isSensitive) {\n spanAttributes[normalizedKey] = '[Filtered]';\n } else if (Array.isArray(value)) {\n spanAttributes[normalizedKey] = value.map(v => (v != null ? String(v) : v)).join(';');\n } else if (typeof value === 'string') {\n spanAttributes[normalizedKey] = value;\n }\n });\n } catch {\n // Return empty object if there's an error\n }\n\n return spanAttributes;\n}\n\n/** Extract the query params from an URL. */\nexport function extractQueryParamsFromUrl(url: string): string | undefined {\n // url is path and query string\n if (!url) {\n return;\n }\n\n try {\n // The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and\n // hostname as the base. Since the point here is just to grab the query string, it doesn't matter what we use.\n const queryParams = new URL(url, 'http://s.io').search.slice(1);\n return queryParams.length ? queryParams : undefined;\n } catch {\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request.js","sources":["../../../src/utils/request.ts"],"sourcesContent":["import type { PolymorphicRequest } from '../types-hoist/polymorphics';\nimport type { RequestEventData } from '../types-hoist/request';\nimport type { WebFetchHeaders, WebFetchRequest } from '../types-hoist/webfetchapi';\n\n/**\n * Transforms a `Headers` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into a simple key-value dict.\n * The header keys will be lower case: e.g. A \"Content-Type\" header will be stored as \"content-type\".\n */\nexport function winterCGHeadersToDict(winterCGHeaders: WebFetchHeaders): Record<string, string> {\n const headers: Record<string, string> = {};\n try {\n winterCGHeaders.forEach((value, key) => {\n if (typeof value === 'string') {\n // We check that value is a string even though it might be redundant to make sure prototype pollution is not possible.\n headers[key] = value;\n }\n });\n } catch {\n // just return the empty headers\n }\n\n return headers;\n}\n\n/**\n * Convert common request headers to a simple dictionary.\n */\nexport function headersToDict(reqHeaders: Record<string, string | string[] | undefined>): Record<string, string> {\n const headers: Record<string, string> = Object.create(null);\n\n try {\n Object.entries(reqHeaders).forEach(([key, value]) => {\n if (typeof value === 'string') {\n headers[key] = value;\n }\n });\n } catch {\n // just return the empty headers\n }\n\n return headers;\n}\n\n/**\n * Converts a `Request` object that implements the `Web Fetch API` (https://developer.mozilla.org/en-US/docs/Web/API/Headers) into the format that the `RequestData` integration understands.\n */\nexport function winterCGRequestToRequestData(req: WebFetchRequest): RequestEventData {\n const headers = winterCGHeadersToDict(req.headers);\n\n return {\n method: req.method,\n url: req.url,\n query_string: extractQueryParamsFromUrl(req.url),\n headers,\n // TODO: Can we extract body data from the request?\n };\n}\n\n/**\n * Convert a HTTP request object to RequestEventData to be passed as normalizedRequest.\n * Instead of allowing `PolymorphicRequest` to be passed,\n * we want to be more specific and generally require a http.IncomingMessage-like object.\n */\nexport function httpRequestToRequestData(request: {\n method?: string;\n url?: string;\n headers?: {\n [key: string]: string | string[] | undefined;\n };\n protocol?: string;\n socket?: {\n encrypted?: boolean;\n remoteAddress?: string;\n };\n}): RequestEventData {\n const headers = request.headers || {};\n\n // Check for x-forwarded-host first, then fall back to host header\n const forwardedHost = typeof headers['x-forwarded-host'] === 'string' ? headers['x-forwarded-host'] : undefined;\n const host = forwardedHost || (typeof headers.host === 'string' ? headers.host : undefined);\n\n // Check for x-forwarded-proto first, then fall back to existing protocol detection\n const forwardedProto = typeof headers['x-forwarded-proto'] === 'string' ? headers['x-forwarded-proto'] : undefined;\n const protocol = forwardedProto || request.protocol || (request.socket?.encrypted ? 'https' : 'http');\n\n const url = request.url || '';\n\n const absoluteUrl = getAbsoluteUrl({\n url,\n host,\n protocol,\n });\n\n // This is non-standard, but may be sometimes set\n // It may be overwritten later by our own body handling\n const data = (request as PolymorphicRequest).body || undefined;\n\n // This is non-standard, but may be set on e.g. Next.js or Express requests\n const cookies = (request as PolymorphicRequest).cookies;\n\n return {\n url: absoluteUrl,\n method: request.method,\n query_string: extractQueryParamsFromUrl(url),\n headers: headersToDict(headers),\n cookies,\n data,\n };\n}\n\nfunction getAbsoluteUrl({\n url,\n protocol,\n host,\n}: {\n url?: string;\n protocol: string;\n host?: string;\n}): string | undefined {\n if (url?.startsWith('http')) {\n return url;\n }\n\n if (url && host) {\n return `${protocol}://${host}${url}`;\n }\n\n return undefined;\n}\n\nconst SENSITIVE_HEADER_SNIPPETS = [\n 'auth',\n 'token',\n 'secret',\n 'session', // for the user_session cookie\n 'password',\n 'passwd',\n 'pwd',\n 'key',\n 'jwt',\n 'bearer',\n 'sso',\n 'saml',\n 'csrf',\n 'xsrf',\n 'credentials',\n // Always treat cookie headers as sensitive in case individual key-value cookie pairs cannot properly be extracted\n 'set-cookie',\n 'cookie',\n];\n\nconst PII_HEADER_SNIPPETS = ['x-forwarded-', '-user'];\n\n/**\n * Converts incoming HTTP request headers to OpenTelemetry span attributes following semantic conventions.\n * Header names are converted to the format: http.request.header.<key>\n * where <key> is the header name in lowercase with dashes converted to underscores.\n *\n * @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/#http-request-header\n */\nexport function httpHeadersToSpanAttributes(\n headers: Record<string, string | string[] | undefined>,\n sendDefaultPii: boolean = false,\n): Record<string, string> {\n const spanAttributes: Record<string, string> = {};\n\n try {\n Object.entries(headers).forEach(([key, value]) => {\n if (value == null) {\n return;\n }\n\n const lowerCasedHeaderKey = key.toLowerCase();\n const isCookieHeader = lowerCasedHeaderKey === 'cookie' || lowerCasedHeaderKey === 'set-cookie';\n\n if (isCookieHeader && typeof value === 'string' && value !== '') {\n // Set-Cookie: single cookie with attributes (\"name=value; HttpOnly; Secure\")\n // Cookie: multiple cookies separated by \"; \" (\"cookie1=value1; cookie2=value2\")\n const isSetCookie = lowerCasedHeaderKey === 'set-cookie';\n const semicolonIndex = value.indexOf(';');\n const cookieString = isSetCookie && semicolonIndex !== -1 ? value.substring(0, semicolonIndex) : value;\n const cookies = isSetCookie ? [cookieString] : cookieString.split('; ');\n\n for (const cookie of cookies) {\n // Split only at the first '=' to preserve '=' characters in cookie values\n const equalSignIndex = cookie.indexOf('=');\n const cookieKey = equalSignIndex !== -1 ? cookie.substring(0, equalSignIndex) : cookie;\n const cookieValue = equalSignIndex !== -1 ? cookie.substring(equalSignIndex + 1) : '';\n\n const lowerCasedCookieKey = cookieKey.toLowerCase();\n\n addSpanAttribute(spanAttributes, lowerCasedHeaderKey, lowerCasedCookieKey, cookieValue, sendDefaultPii);\n }\n } else {\n addSpanAttribute(spanAttributes, lowerCasedHeaderKey, '', value, sendDefaultPii);\n }\n });\n } catch {\n // Return empty object if there's an error\n }\n\n return spanAttributes;\n}\n\nfunction normalizeAttributeKey(key: string): string {\n return key.replace(/-/g, '_');\n}\n\nfunction addSpanAttribute(\n spanAttributes: Record<string, string>,\n headerKey: string,\n cookieKey: string,\n value: string | string[] | undefined,\n sendPii: boolean,\n): void {\n const normalizedKey = cookieKey\n ? `http.request.header.${normalizeAttributeKey(headerKey)}.${normalizeAttributeKey(cookieKey)}`\n : `http.request.header.${normalizeAttributeKey(headerKey)}`;\n\n const headerValue = handleHttpHeader(cookieKey || headerKey, value, sendPii);\n if (headerValue !== undefined) {\n spanAttributes[normalizedKey] = headerValue;\n }\n}\n\nfunction handleHttpHeader(\n lowerCasedKey: string,\n value: string | string[] | undefined,\n sendPii: boolean,\n): string | undefined {\n const isSensitive = sendPii\n ? SENSITIVE_HEADER_SNIPPETS.some(snippet => lowerCasedKey.includes(snippet))\n : [...PII_HEADER_SNIPPETS, ...SENSITIVE_HEADER_SNIPPETS].some(snippet => lowerCasedKey.includes(snippet));\n\n if (isSensitive) {\n return '[Filtered]';\n } else if (Array.isArray(value)) {\n return value.map(v => (v != null ? String(v) : v)).join(';');\n } else if (typeof value === 'string') {\n return value;\n }\n\n return undefined;\n}\n\n/** Extract the query params from an URL. */\nexport function extractQueryParamsFromUrl(url: string): string | undefined {\n // url is path and query string\n if (!url) {\n return;\n }\n\n try {\n // The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and\n // hostname as the base. Since the point here is just to grab the query string, it doesn't matter what we use.\n const queryParams = new URL(url, 'http://s.io').search.slice(1);\n return queryParams.length ? queryParams : undefined;\n } catch {\n return undefined;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import { DEBUG_BUILD } from '../debug-build.js';
2
+ import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../semanticAttributes.js';
2
3
  import { debug } from './debug-logger.js';
3
4
  import { isMatchingPattern } from './string.js';
4
5
 
5
- function logIgnoredSpan(droppedSpan) {
6
- debug.log(`Ignoring span ${droppedSpan.op} - ${droppedSpan.description} because it matches \`ignoreSpans\`.`);
6
+ function logIgnoredSpan(spanName, spanOp) {
7
+ debug.log(`Ignoring span ${spanOp ? `${spanOp} - ` : ''}${spanName} because it matches \`ignoreSpans\`.`);
7
8
  }
8
9
 
9
10
  /**
@@ -13,14 +14,32 @@ function shouldIgnoreSpan(
13
14
  span,
14
15
  ignoreSpans,
15
16
  ) {
16
- if (!ignoreSpans?.length || !span.description) {
17
+ if (!ignoreSpans?.length) {
18
+ return false;
19
+ }
20
+
21
+ const { spanName, spanOp: spanOpAttributeOrString } =
22
+ 'description' in span
23
+ ? { spanName: span.description, spanOp: span.op }
24
+ : 'name' in span
25
+ ? { spanName: span.name, spanOp: span.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_OP] }
26
+ : { spanName: '', spanOp: '' };
27
+
28
+ const spanOp =
29
+ typeof spanOpAttributeOrString === 'string'
30
+ ? spanOpAttributeOrString
31
+ : spanOpAttributeOrString?.type === 'string'
32
+ ? spanOpAttributeOrString.value
33
+ : undefined;
34
+
35
+ if (!spanName) {
17
36
  return false;
18
37
  }
19
38
 
20
39
  for (const pattern of ignoreSpans) {
21
40
  if (isStringOrRegExp(pattern)) {
22
- if (isMatchingPattern(span.description, pattern)) {
23
- DEBUG_BUILD && logIgnoredSpan(span);
41
+ if (isMatchingPattern(spanName, pattern)) {
42
+ DEBUG_BUILD && logIgnoredSpan(spanName, spanOp);
24
43
  return true;
25
44
  }
26
45
  continue;
@@ -30,15 +49,15 @@ function shouldIgnoreSpan(
30
49
  continue;
31
50
  }
32
51
 
33
- const nameMatches = pattern.name ? isMatchingPattern(span.description, pattern.name) : true;
34
- const opMatches = pattern.op ? span.op && isMatchingPattern(span.op, pattern.op) : true;
52
+ const nameMatches = pattern.name ? isMatchingPattern(spanName, pattern.name) : true;
53
+ const opMatches = pattern.op ? spanOp && isMatchingPattern(spanOp, pattern.op) : true;
35
54
 
36
55
  // This check here is only correct because we can guarantee that we ran `isMatchingPattern`
37
56
  // for at least one of `nameMatches` and `opMatches`. So in contrary to how this looks,
38
57
  // not both op and name actually have to match. This is the most efficient way to check
39
58
  // for all combinations of name and op patterns.
40
59
  if (nameMatches && opMatches) {
41
- DEBUG_BUILD && logIgnoredSpan(span);
60
+ DEBUG_BUILD && logIgnoredSpan(spanName, spanOp);
42
61
  return true;
43
62
  }
44
63
  }
@@ -50,7 +69,10 @@ function shouldIgnoreSpan(
50
69
  * Takes a list of spans, and a span that was dropped, and re-parents the child spans of the dropped span to the parent of the dropped span, if possible.
51
70
  * This mutates the spans array in place!
52
71
  */
53
- function reparentChildSpans(spans, dropSpan) {
72
+ function reparentChildSpans(
73
+ spans,
74
+ dropSpan,
75
+ ) {
54
76
  const droppedSpanParentId = dropSpan.parent_span_id;
55
77
  const droppedSpanId = dropSpan.span_id;
56
78
 
@@ -1 +1 @@
1
- {"version":3,"file":"should-ignore-span.js","sources":["../../../src/utils/should-ignore-span.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { SpanJSON } from '../types-hoist/span';\nimport { debug } from './debug-logger';\nimport { isMatchingPattern } from './string';\n\nfunction logIgnoredSpan(droppedSpan: Pick<SpanJSON, 'description' | 'op'>): void {\n debug.log(`Ignoring span ${droppedSpan.op} - ${droppedSpan.description} because it matches \\`ignoreSpans\\`.`);\n}\n\n/**\n * Check if a span should be ignored based on the ignoreSpans configuration.\n */\nexport function shouldIgnoreSpan(\n span: Pick<SpanJSON, 'description' | 'op'>,\n ignoreSpans: Required<ClientOptions>['ignoreSpans'],\n): boolean {\n if (!ignoreSpans?.length || !span.description) {\n return false;\n }\n\n for (const pattern of ignoreSpans) {\n if (isStringOrRegExp(pattern)) {\n if (isMatchingPattern(span.description, pattern)) {\n DEBUG_BUILD && logIgnoredSpan(span);\n return true;\n }\n continue;\n }\n\n if (!pattern.name && !pattern.op) {\n continue;\n }\n\n const nameMatches = pattern.name ? isMatchingPattern(span.description, pattern.name) : true;\n const opMatches = pattern.op ? span.op && isMatchingPattern(span.op, pattern.op) : true;\n\n // This check here is only correct because we can guarantee that we ran `isMatchingPattern`\n // for at least one of `nameMatches` and `opMatches`. So in contrary to how this looks,\n // not both op and name actually have to match. This is the most efficient way to check\n // for all combinations of name and op patterns.\n if (nameMatches && opMatches) {\n DEBUG_BUILD && logIgnoredSpan(span);\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Takes a list of spans, and a span that was dropped, and re-parents the child spans of the dropped span to the parent of the dropped span, if possible.\n * This mutates the spans array in place!\n */\nexport function reparentChildSpans(spans: SpanJSON[], dropSpan: SpanJSON): void {\n const droppedSpanParentId = dropSpan.parent_span_id;\n const droppedSpanId = dropSpan.span_id;\n\n // This should generally not happen, as we do not apply this on root spans\n // but to be safe, we just bail in this case\n if (!droppedSpanParentId) {\n return;\n }\n\n for (const span of spans) {\n if (span.parent_span_id === droppedSpanId) {\n span.parent_span_id = droppedSpanParentId;\n }\n }\n}\n\nfunction isStringOrRegExp(value: unknown): value is string | RegExp {\n return typeof value === 'string' || value instanceof RegExp;\n}\n"],"names":[],"mappings":";;;;AAMA,SAAS,cAAc,CAAC,WAAW,EAA8C;AACjF,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;AAC/G;;AAEA;AACA;AACA;AACO,SAAS,gBAAgB;AAChC,EAAE,IAAI;AACN,EAAE,WAAW;AACb,EAAW;AACX,EAAE,IAAI,CAAC,WAAW,EAAE,MAAA,IAAU,CAAC,IAAI,CAAC,WAAW,EAAE;AACjD,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,KAAK,MAAM,OAAA,IAAW,WAAW,EAAE;AACrC,IAAI,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE;AACnC,MAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AACxD,QAAQ,WAAA,IAAe,cAAc,CAAC,IAAI,CAAC;AAC3C,QAAQ,OAAO,IAAI;AACnB,MAAM;AACN,MAAM;AACN,IAAI;;AAEJ,IAAI,IAAI,CAAC,OAAO,CAAC,IAAA,IAAQ,CAAC,OAAO,CAAC,EAAE,EAAE;AACtC,MAAM;AACN,IAAI;;AAEJ,IAAI,MAAM,WAAA,GAAc,OAAO,CAAC,IAAA,GAAO,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAA,GAAI,IAAI;AAC/F,IAAI,MAAM,YAAY,OAAO,CAAC,EAAA,GAAK,IAAI,CAAC,EAAA,IAAM,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAA,GAAI,IAAI;;AAE3F;AACA;AACA;AACA;AACA,IAAI,IAAI,WAAA,IAAe,SAAS,EAAE;AAClC,MAAM,WAAA,IAAe,cAAc,CAAC,IAAI,CAAC;AACzC,MAAM,OAAO,IAAI;AACjB,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,KAAK,EAAc,QAAQ,EAAkB;AAChF,EAAE,MAAM,mBAAA,GAAsB,QAAQ,CAAC,cAAc;AACrD,EAAE,MAAM,aAAA,GAAgB,QAAQ,CAAC,OAAO;;AAExC;AACA;AACA,EAAE,IAAI,CAAC,mBAAmB,EAAE;AAC5B,IAAI;AACJ,EAAE;;AAEF,EAAE,KAAK,MAAM,IAAA,IAAQ,KAAK,EAAE;AAC5B,IAAI,IAAI,IAAI,CAAC,cAAA,KAAmB,aAAa,EAAE;AAC/C,MAAM,IAAI,CAAC,cAAA,GAAiB,mBAAmB;AAC/C,IAAI;AACJ,EAAE;AACF;;AAEA,SAAS,gBAAgB,CAAC,KAAK,EAAqC;AACpE,EAAE,OAAO,OAAO,KAAA,KAAU,YAAY,KAAA,YAAiB,MAAM;AAC7D;;;;"}
1
+ {"version":3,"file":"should-ignore-span.js","sources":["../../../src/utils/should-ignore-span.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../semanticAttributes';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { SpanJSON, SpanV2JSON } from '../types-hoist/span';\nimport { debug } from './debug-logger';\nimport { isMatchingPattern } from './string';\n\nfunction logIgnoredSpan(spanName: string, spanOp: string | undefined): void {\n debug.log(`Ignoring span ${spanOp ? `${spanOp} - ` : ''}${spanName} because it matches \\`ignoreSpans\\`.`);\n}\n\n/**\n * Check if a span should be ignored based on the ignoreSpans configuration.\n */\nexport function shouldIgnoreSpan(\n span: Pick<SpanJSON, 'description' | 'op'> | Pick<SpanV2JSON, 'name' | 'attributes'>,\n ignoreSpans: Required<ClientOptions>['ignoreSpans'],\n): boolean {\n if (!ignoreSpans?.length) {\n return false;\n }\n\n const { spanName, spanOp: spanOpAttributeOrString } =\n 'description' in span\n ? { spanName: span.description, spanOp: span.op }\n : 'name' in span\n ? { spanName: span.name, spanOp: span.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_OP] }\n : { spanName: '', spanOp: '' };\n\n const spanOp =\n typeof spanOpAttributeOrString === 'string'\n ? spanOpAttributeOrString\n : spanOpAttributeOrString?.type === 'string'\n ? spanOpAttributeOrString.value\n : undefined;\n\n if (!spanName) {\n return false;\n }\n\n for (const pattern of ignoreSpans) {\n if (isStringOrRegExp(pattern)) {\n if (isMatchingPattern(spanName, pattern)) {\n DEBUG_BUILD && logIgnoredSpan(spanName, spanOp);\n return true;\n }\n continue;\n }\n\n if (!pattern.name && !pattern.op) {\n continue;\n }\n\n const nameMatches = pattern.name ? isMatchingPattern(spanName, pattern.name) : true;\n const opMatches = pattern.op ? spanOp && isMatchingPattern(spanOp, pattern.op) : true;\n\n // This check here is only correct because we can guarantee that we ran `isMatchingPattern`\n // for at least one of `nameMatches` and `opMatches`. So in contrary to how this looks,\n // not both op and name actually have to match. This is the most efficient way to check\n // for all combinations of name and op patterns.\n if (nameMatches && opMatches) {\n DEBUG_BUILD && logIgnoredSpan(spanName, spanOp);\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Takes a list of spans, and a span that was dropped, and re-parents the child spans of the dropped span to the parent of the dropped span, if possible.\n * This mutates the spans array in place!\n */\nexport function reparentChildSpans(\n spans: Pick<SpanV2JSON, 'parent_span_id' | 'span_id'>[],\n dropSpan: Pick<SpanV2JSON, 'parent_span_id' | 'span_id'>,\n): void {\n const droppedSpanParentId = dropSpan.parent_span_id;\n const droppedSpanId = dropSpan.span_id;\n\n // This should generally not happen, as we do not apply this on root spans\n // but to be safe, we just bail in this case\n if (!droppedSpanParentId) {\n return;\n }\n\n for (const span of spans) {\n if (span.parent_span_id === droppedSpanId) {\n span.parent_span_id = droppedSpanParentId;\n }\n }\n}\n\nfunction isStringOrRegExp(value: unknown): value is string | RegExp {\n return typeof value === 'string' || value instanceof RegExp;\n}\n"],"names":[],"mappings":";;;;;AAOA,SAAS,cAAc,CAAC,QAAQ,EAAU,MAAM,EAA4B;AAC5E,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,MAAA,GAAS,CAAC,EAAA,MAAA,CAAA,GAAA,CAAA,GAAA,EAAA,CAAA,EAAA,QAAA,CAAA,oCAAA,CAAA,CAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,gBAAA;AACA,EAAA,IAAA;AACA,EAAA,WAAA;AACA,EAAA;AACA,EAAA,IAAA,CAAA,WAAA,EAAA,MAAA,EAAA;AACA,IAAA,OAAA,KAAA;AACA,EAAA;;AAEA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,uBAAA,EAAA;AACA,IAAA,aAAA,IAAA;AACA,QAAA,EAAA,QAAA,EAAA,IAAA,CAAA,WAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA;AACA,QAAA,MAAA,IAAA;AACA,UAAA,EAAA,QAAA,EAAA,IAAA,CAAA,IAAA,EAAA,MAAA,EAAA,IAAA,CAAA,UAAA,GAAA,4BAAA,CAAA;AACA,UAAA,EAAA,QAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,EAAA;;AAEA,EAAA,MAAA,MAAA;AACA,IAAA,OAAA,uBAAA,KAAA;AACA,QAAA;AACA,QAAA,uBAAA,EAAA,IAAA,KAAA;AACA,UAAA,uBAAA,CAAA;AACA,UAAA,SAAA;;AAEA,EAAA,IAAA,CAAA,QAAA,EAAA;AACA,IAAA,OAAA,KAAA;AACA,EAAA;;AAEA,EAAA,KAAA,MAAA,OAAA,IAAA,WAAA,EAAA;AACA,IAAA,IAAA,gBAAA,CAAA,OAAA,CAAA,EAAA;AACA,MAAA,IAAA,iBAAA,CAAA,QAAA,EAAA,OAAA,CAAA,EAAA;AACA,QAAA,WAAA,IAAA,cAAA,CAAA,QAAA,EAAA,MAAA,CAAA;AACA,QAAA,OAAA,IAAA;AACA,MAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,IAAA,CAAA,OAAA,CAAA,IAAA,IAAA,CAAA,OAAA,CAAA,EAAA,EAAA;AACA,MAAA;AACA,IAAA;;AAEA,IAAA,MAAA,WAAA,GAAA,OAAA,CAAA,IAAA,GAAA,iBAAA,CAAA,QAAA,EAAA,OAAA,CAAA,IAAA,CAAA,GAAA,IAAA;AACA,IAAA,MAAA,SAAA,GAAA,OAAA,CAAA,EAAA,GAAA,MAAA,IAAA,iBAAA,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,GAAA,IAAA;;AAEA;AACA;AACA;AACA;AACA,IAAA,IAAA,WAAA,IAAA,SAAA,EAAA;AACA,MAAA,WAAA,IAAA,cAAA,CAAA,QAAA,EAAA,MAAA,CAAA;AACA,MAAA,OAAA,IAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,OAAA,KAAA;AACA;;AAEA;AACA;AACA;AACA;AACA,SAAA,kBAAA;AACA,EAAA,KAAA;AACA,EAAA,QAAA;AACA,EAAA;AACA,EAAA,MAAA,mBAAA,GAAA,QAAA,CAAA,cAAA;AACA,EAAA,MAAA,aAAA,GAAA,QAAA,CAAA,OAAA;;AAEA;AACA;AACA,EAAA,IAAA,CAAA,mBAAA,EAAA;AACA,IAAA;AACA,EAAA;;AAEA,EAAA,KAAA,MAAA,IAAA,IAAA,KAAA,EAAA;AACA,IAAA,IAAA,IAAA,CAAA,cAAA,KAAA,aAAA,EAAA;AACA,MAAA,IAAA,CAAA,cAAA,GAAA,mBAAA;AACA,IAAA;AACA,EAAA;AACA;;AAEA,SAAA,gBAAA,CAAA,KAAA,EAAA;AACA,EAAA,OAAA,OAAA,KAAA,KAAA,QAAA,IAAA,KAAA,YAAA,MAAA;AACA;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { getAsyncContextStrategy } from '../asyncContext/index.js';
2
+ import { attributeValueToTypedAttributeValue } from '../attributes.js';
2
3
  import { getMainCarrier } from '../carrier.js';
3
4
  import { getCurrentScope } from '../currentScopes.js';
4
5
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes.js';
@@ -82,7 +83,7 @@ function spanToTraceparentHeader(span) {
82
83
  * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.
83
84
  */
84
85
  function convertSpanLinksForEnvelope(links) {
85
- if (links && links.length > 0) {
86
+ if (links?.length) {
86
87
  return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({
87
88
  span_id: spanId,
88
89
  trace_id: traceId,
@@ -94,6 +95,24 @@ function convertSpanLinksForEnvelope(links) {
94
95
  return undefined;
95
96
  }
96
97
  }
98
+ /**
99
+ *
100
+ * @param links
101
+ * @returns
102
+ */
103
+ function getV2SpanLinks(links) {
104
+ if (links?.length) {
105
+ return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({
106
+ span_id: spanId,
107
+ trace_id: traceId,
108
+ sampled: traceFlags === TRACE_FLAG_SAMPLED,
109
+ ...(attributes && { attributes: getV2Attributes(attributes) }),
110
+ ...restContext,
111
+ }));
112
+ } else {
113
+ return undefined;
114
+ }
115
+ }
97
116
 
98
117
  /**
99
118
  * Convert a span time input into a timestamp in seconds.
@@ -177,6 +196,59 @@ function spanToJSON(span) {
177
196
  };
178
197
  }
179
198
 
199
+ /**
200
+ * Convert a span to a SpanV2JSON representation.
201
+ * @returns
202
+ */
203
+ function spanToV2JSON(span) {
204
+ if (spanIsSentrySpan(span)) {
205
+ return span.getSpanV2JSON();
206
+ }
207
+
208
+ const { spanId: span_id, traceId: trace_id } = span.spanContext();
209
+
210
+ // Handle a span from @opentelemetry/sdk-base-trace's `Span` class
211
+ if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {
212
+ const { attributes, startTime, name, endTime, status, links } = span;
213
+
214
+ // In preparation for the next major of OpenTelemetry, we want to support
215
+ // looking up the parent span id according to the new API
216
+ // In OTel v1, the parent span id is accessed as `parentSpanId`
217
+ // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`
218
+ const parentSpanId =
219
+ 'parentSpanId' in span
220
+ ? span.parentSpanId
221
+ : 'parentSpanContext' in span
222
+ ? (span.parentSpanContext )?.spanId
223
+ : undefined;
224
+
225
+ return {
226
+ name,
227
+ span_id,
228
+ trace_id,
229
+ parent_span_id: parentSpanId,
230
+ start_timestamp: spanTimeInputToSeconds(startTime),
231
+ end_timestamp: spanTimeInputToSeconds(endTime),
232
+ is_segment: span === INTERNAL_getSegmentSpan(span),
233
+ status: getV2StatusMessage(status),
234
+ attributes: getV2Attributes(attributes),
235
+ links: getV2SpanLinks(links),
236
+ };
237
+ }
238
+
239
+ // Finally, as a fallback, at least we have `spanContext()`....
240
+ // This should not actually happen in reality, but we need to handle it for type safety.
241
+ return {
242
+ span_id,
243
+ trace_id,
244
+ start_timestamp: 0,
245
+ name: '',
246
+ end_timestamp: 0,
247
+ status: 'ok',
248
+ is_segment: span === INTERNAL_getSegmentSpan(span),
249
+ };
250
+ }
251
+
180
252
  function spanIsOpenTelemetrySdkTraceBaseSpan(span) {
181
253
  const castSpan = span ;
182
254
  return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;
@@ -218,6 +290,23 @@ function getStatusMessage(status) {
218
290
  return status.message || 'internal_error';
219
291
  }
220
292
 
293
+ /**
294
+ * Convert the various statuses to the ones expected by Sentry ('ok' is default)
295
+ */
296
+ function getV2StatusMessage(status) {
297
+ return !status || status.code === SPAN_STATUS_OK || status.code === SPAN_STATUS_UNSET ? 'ok' : 'error';
298
+ }
299
+
300
+ /**
301
+ * Convert the attributes to the ones expected by Sentry, including the type annotation
302
+ */
303
+ function getV2Attributes(attributes) {
304
+ return Object.entries(attributes).reduce((acc, [key, value]) => {
305
+ acc[key] = attributeValueToTypedAttributeValue(value);
306
+ return acc;
307
+ }, {} );
308
+ }
309
+
221
310
  const CHILD_SPANS_FIELD = '_sentryChildSpans';
222
311
  const ROOT_SPAN_FIELD = '_sentryRootSpan';
223
312
 
@@ -274,7 +363,12 @@ function getSpanDescendants(span) {
274
363
  /**
275
364
  * Returns the root span of a given span.
276
365
  */
277
- function getRootSpan(span) {
366
+ const getRootSpan = INTERNAL_getSegmentSpan;
367
+
368
+ /**
369
+ * Returns the segment span of a given span.
370
+ */
371
+ function INTERNAL_getSegmentSpan(span) {
278
372
  return span[ROOT_SPAN_FIELD] || span;
279
373
  }
280
374
 
@@ -330,5 +424,5 @@ function updateSpanName(span, name) {
330
424
  });
331
425
  }
332
426
 
333
- export { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, addChildSpanToSpan, convertSpanLinksForEnvelope, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, removeChildSpanFromSpan, showSpanDropWarning, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, spanToTraceparentHeader, spanToTransactionTraceContext, updateSpanName };
427
+ export { INTERNAL_getSegmentSpan, TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, addChildSpanToSpan, convertSpanLinksForEnvelope, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, getV2Attributes, getV2SpanLinks, getV2StatusMessage, removeChildSpanFromSpan, showSpanDropWarning, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, spanToTraceparentHeader, spanToTransactionTraceContext, spanToV2JSON, updateSpanName };
334
428
  //# sourceMappingURL=spanUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spanUtils.js","sources":["../../../src/utils/spanUtils.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport { getCurrentScope } from '../currentScopes';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type { SentrySpan } from '../tracing/sentrySpan';\nimport { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus';\nimport { getCapturedScopesOnSpan } from '../tracing/utils';\nimport type { TraceContext } from '../types-hoist/context';\nimport type { SpanLink, SpanLinkJSON } from '../types-hoist/link';\nimport type { Span, SpanAttributes, SpanJSON, SpanOrigin, SpanTimeInput } from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { addNonEnumerableProperty } from '../utils/object';\nimport { generateSpanId } from '../utils/propagationContext';\nimport { timestampInSeconds } from '../utils/time';\nimport { generateSentryTraceHeader, generateTraceparentHeader } from '../utils/tracing';\nimport { consoleSandbox } from './debug-logger';\nimport { _getSpanForScope } from './spanOnScope';\n\n// These are aligned with OpenTelemetry trace flags\nexport const TRACE_FLAG_NONE = 0x0;\nexport const TRACE_FLAG_SAMPLED = 0x1;\n\nlet hasShownSpanDropWarning = false;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nexport function spanToTransactionTraceContext(span: Span): TraceContext {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { data, op, parent_span_id, status, origin, links } = spanToJSON(span);\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n data,\n op,\n status,\n origin,\n links,\n };\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nexport function spanToTraceContext(span: Span): TraceContext {\n const { spanId, traceId: trace_id, isRemote } = span.spanContext();\n\n // If the span is remote, we use a random/virtual span as span_id to the trace context,\n // and the remote span as parent_span_id\n const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id;\n const scope = getCapturedScopesOnSpan(span).scope;\n\n const span_id = isRemote ? scope?.getPropagationContext().propagationSpanId || generateSpanId() : spanId;\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n };\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nexport function spanToTraceHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a Span to a W3C traceparent header.\n */\nexport function spanToTraceparentHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateTraceparentHeader(traceId, spanId, sampled);\n}\n\n/**\n * Converts the span links array to a flattened version to be sent within an envelope.\n *\n * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.\n */\nexport function convertSpanLinksForEnvelope(links?: SpanLink[]): SpanLinkJSON[] | undefined {\n if (links && links.length > 0) {\n return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n attributes,\n ...restContext,\n }));\n } else {\n return undefined;\n }\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nexport function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number {\n if (typeof input === 'number') {\n return ensureTimestampInSeconds(input);\n }\n\n if (Array.isArray(input)) {\n // See {@link HrTime} for the array-based time format\n return input[0] + input[1] / 1e9;\n }\n\n if (input instanceof Date) {\n return ensureTimestampInSeconds(input.getTime());\n }\n\n return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp: number): number {\n const isMs = timestamp > 9999999999;\n return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nexport function spanToJSON(span: Span): SpanJSON {\n if (spanIsSentrySpan(span)) {\n return span.getSpanJSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n // In preparation for the next major of OpenTelemetry, we want to support\n // looking up the parent span id according to the new API\n // In OTel v1, the parent span id is accessed as `parentSpanId`\n // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`\n const parentSpanId =\n 'parentSpanId' in span\n ? span.parentSpanId\n : 'parentSpanContext' in span\n ? (span.parentSpanContext as { spanId?: string } | undefined)?.spanId\n : undefined;\n\n return {\n span_id,\n trace_id,\n data: attributes,\n description: name,\n parent_span_id: parentSpanId,\n start_timestamp: spanTimeInputToSeconds(startTime),\n // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n timestamp: spanTimeInputToSeconds(endTime) || undefined,\n status: getStatusMessage(status),\n op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n links: convertSpanLinksForEnvelope(links),\n };\n }\n\n // Finally, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n data: {},\n };\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span: Span): span is OpenTelemetrySdkTraceBaseSpan {\n const castSpan = span as Partial<OpenTelemetrySdkTraceBaseSpan>;\n return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\nexport interface OpenTelemetrySdkTraceBaseSpan extends Span {\n attributes: SpanAttributes;\n startTime: SpanTimeInput;\n name: string;\n status: SpanStatus;\n endTime: SpanTimeInput;\n parentSpanId?: string;\n links?: SpanLink[];\n}\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span: Span): span is SentrySpan {\n return typeof (span as SentrySpan).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nexport function spanIsSampled(span: Span): boolean {\n // We align our trace flags with the ones OpenTelemetry use\n // So we also check for sampled the same way they do.\n const { traceFlags } = span.spanContext();\n return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nexport function getStatusMessage(status: SpanStatus | undefined): string | undefined {\n if (!status || status.code === SPAN_STATUS_UNSET) {\n return undefined;\n }\n\n if (status.code === SPAN_STATUS_OK) {\n return 'ok';\n }\n\n return status.message || 'internal_error';\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\ntype SpanWithPotentialChildren = Span & {\n [CHILD_SPANS_FIELD]?: Set<Span>;\n [ROOT_SPAN_FIELD]?: Span;\n};\n\n/**\n * Adds an opaque child span reference to a span.\n */\nexport function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n // We store the root span reference on the child span\n // We need this for `getRootSpan()` to work\n const rootSpan = span[ROOT_SPAN_FIELD] || span;\n addNonEnumerableProperty(childSpan as SpanWithPotentialChildren, ROOT_SPAN_FIELD, rootSpan);\n\n // We store a list of child spans on the parent span\n // We need this for `getSpanDescendants()` to work\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].add(childSpan);\n } else {\n addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n }\n}\n\n/** This is only used internally by Idle Spans. */\nexport function removeChildSpanFromSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].delete(childSpan);\n }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nexport function getSpanDescendants(span: SpanWithPotentialChildren): Span[] {\n const resultSet = new Set<Span>();\n\n function addSpanChildren(span: SpanWithPotentialChildren): void {\n // This exit condition is required to not infinitely loop in case of a circular dependency.\n if (resultSet.has(span)) {\n return;\n // We want to ignore unsampled spans (e.g. non recording spans)\n } else if (spanIsSampled(span)) {\n resultSet.add(span);\n const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n for (const childSpan of childSpans) {\n addSpanChildren(childSpan);\n }\n }\n }\n\n addSpanChildren(span);\n\n return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nexport function getRootSpan(span: SpanWithPotentialChildren): Span {\n return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nexport function getActiveSpan(): Span | undefined {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getActiveSpan) {\n return acs.getActiveSpan();\n }\n\n return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Logs a warning once if `beforeSendSpan` is used to drop spans.\n */\nexport function showSpanDropWarning(): void {\n if (!hasShownSpanDropWarning) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.',\n );\n });\n hasShownSpanDropWarning = true;\n }\n}\n\n/**\n * Updates the name of the given span and ensures that the span name is not\n * overwritten by the Sentry SDK.\n *\n * Use this function instead of `span.updateName()` if you want to make sure that\n * your name is kept. For some spans, for example root `http.server` spans the\n * Sentry SDK would otherwise overwrite the span name with a high-quality name\n * it infers when the span ends.\n *\n * Use this function in server code or when your span is started on the server\n * and on the client (browser). If you only update a span name on the client,\n * you can also use `span.updateName()` the SDK does not overwrite the name.\n *\n * @param span - The span to update the name of.\n * @param name - The name to set on the span.\n */\nexport function updateSpanName(span: Span, name: string): void {\n span.updateName(name);\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name,\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spanUtils.js","sources":["../../../src/utils/spanUtils.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport type { TypedAttributes } from '../attributes';\nimport { attributeValueToTypedAttributeValue } from '../attributes';\nimport { getMainCarrier } from '../carrier';\nimport { getCurrentScope } from '../currentScopes';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type { SentrySpan } from '../tracing/sentrySpan';\nimport { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus';\nimport { getCapturedScopesOnSpan } from '../tracing/utils';\nimport type { TraceContext } from '../types-hoist/context';\nimport type { SpanLink, SpanLinkJSON } from '../types-hoist/link';\nimport type { Span, SpanAttributes, SpanJSON, SpanOrigin, SpanTimeInput, SpanV2JSON } from '../types-hoist/span';\nimport type { SpanStatus } from '../types-hoist/spanStatus';\nimport { addNonEnumerableProperty } from '../utils/object';\nimport { generateSpanId } from '../utils/propagationContext';\nimport { timestampInSeconds } from '../utils/time';\nimport { generateSentryTraceHeader, generateTraceparentHeader } from '../utils/tracing';\nimport { consoleSandbox } from './debug-logger';\nimport { _getSpanForScope } from './spanOnScope';\n\n// These are aligned with OpenTelemetry trace flags\nexport const TRACE_FLAG_NONE = 0x0;\nexport const TRACE_FLAG_SAMPLED = 0x1;\n\nlet hasShownSpanDropWarning = false;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nexport function spanToTransactionTraceContext(span: Span): TraceContext {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { data, op, parent_span_id, status, origin, links } = spanToJSON(span);\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n data,\n op,\n status,\n origin,\n links,\n };\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nexport function spanToTraceContext(span: Span): TraceContext {\n const { spanId, traceId: trace_id, isRemote } = span.spanContext();\n\n // If the span is remote, we use a random/virtual span as span_id to the trace context,\n // and the remote span as parent_span_id\n const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id;\n const scope = getCapturedScopesOnSpan(span).scope;\n\n const span_id = isRemote ? scope?.getPropagationContext().propagationSpanId || generateSpanId() : spanId;\n\n return {\n parent_span_id,\n span_id,\n trace_id,\n };\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nexport function spanToTraceHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a Span to a W3C traceparent header.\n */\nexport function spanToTraceparentHeader(span: Span): string {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateTraceparentHeader(traceId, spanId, sampled);\n}\n\n/**\n * Converts the span links array to a flattened version to be sent within an envelope.\n *\n * If the links array is empty, it returns `undefined` so the empty value can be dropped before it's sent.\n */\nexport function convertSpanLinksForEnvelope(links?: SpanLink[]): SpanLinkJSON[] | undefined {\n if (links?.length) {\n return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n attributes,\n ...restContext,\n }));\n } else {\n return undefined;\n }\n}\n/**\n *\n * @param links\n * @returns\n */\nexport function getV2SpanLinks(links?: SpanLink[]): SpanLinkJSON<TypedAttributes>[] | undefined {\n if (links?.length) {\n return links.map(({ context: { spanId, traceId, traceFlags, ...restContext }, attributes }) => ({\n span_id: spanId,\n trace_id: traceId,\n sampled: traceFlags === TRACE_FLAG_SAMPLED,\n ...(attributes && { attributes: getV2Attributes(attributes) }),\n ...restContext,\n }));\n } else {\n return undefined;\n }\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nexport function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number {\n if (typeof input === 'number') {\n return ensureTimestampInSeconds(input);\n }\n\n if (Array.isArray(input)) {\n // See {@link HrTime} for the array-based time format\n return input[0] + input[1] / 1e9;\n }\n\n if (input instanceof Date) {\n return ensureTimestampInSeconds(input.getTime());\n }\n\n return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp: number): number {\n const isMs = timestamp > 9999999999;\n return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nexport function spanToJSON(span: Span): SpanJSON {\n if (spanIsSentrySpan(span)) {\n return span.getSpanJSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n // In preparation for the next major of OpenTelemetry, we want to support\n // looking up the parent span id according to the new API\n // In OTel v1, the parent span id is accessed as `parentSpanId`\n // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`\n const parentSpanId =\n 'parentSpanId' in span\n ? span.parentSpanId\n : 'parentSpanContext' in span\n ? (span.parentSpanContext as { spanId?: string } | undefined)?.spanId\n : undefined;\n\n return {\n span_id,\n trace_id,\n data: attributes,\n description: name,\n parent_span_id: parentSpanId,\n start_timestamp: spanTimeInputToSeconds(startTime),\n // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n timestamp: spanTimeInputToSeconds(endTime) || undefined,\n status: getStatusMessage(status),\n op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n links: convertSpanLinksForEnvelope(links),\n };\n }\n\n // Finally, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n data: {},\n };\n}\n\n/**\n * Convert a span to a SpanV2JSON representation.\n * @returns\n */\nexport function spanToV2JSON(span: Span): SpanV2JSON {\n if (spanIsSentrySpan(span)) {\n return span.getSpanV2JSON();\n }\n\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, status, links } = span;\n\n // In preparation for the next major of OpenTelemetry, we want to support\n // looking up the parent span id according to the new API\n // In OTel v1, the parent span id is accessed as `parentSpanId`\n // In OTel v2, the parent span id is accessed as `spanId` on the `parentSpanContext`\n const parentSpanId =\n 'parentSpanId' in span\n ? span.parentSpanId\n : 'parentSpanContext' in span\n ? (span.parentSpanContext as { spanId?: string } | undefined)?.spanId\n : undefined;\n\n return {\n name,\n span_id,\n trace_id,\n parent_span_id: parentSpanId,\n start_timestamp: spanTimeInputToSeconds(startTime),\n end_timestamp: spanTimeInputToSeconds(endTime),\n is_segment: span === INTERNAL_getSegmentSpan(span),\n status: getV2StatusMessage(status),\n attributes: getV2Attributes(attributes),\n links: getV2SpanLinks(links),\n };\n }\n\n // Finally, as a fallback, at least we have `spanContext()`....\n // This should not actually happen in reality, but we need to handle it for type safety.\n return {\n span_id,\n trace_id,\n start_timestamp: 0,\n name: '',\n end_timestamp: 0,\n status: 'ok',\n is_segment: span === INTERNAL_getSegmentSpan(span),\n };\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span: Span): span is OpenTelemetrySdkTraceBaseSpan {\n const castSpan = span as Partial<OpenTelemetrySdkTraceBaseSpan>;\n return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\nexport interface OpenTelemetrySdkTraceBaseSpan extends Span {\n attributes: SpanAttributes;\n startTime: SpanTimeInput;\n name: string;\n status: SpanStatus;\n endTime: SpanTimeInput;\n parentSpanId?: string;\n links?: SpanLink[];\n}\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span: Span): span is SentrySpan {\n return typeof (span as SentrySpan).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nexport function spanIsSampled(span: Span): boolean {\n // We align our trace flags with the ones OpenTelemetry use\n // So we also check for sampled the same way they do.\n const { traceFlags } = span.spanContext();\n return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nexport function getStatusMessage(status: SpanStatus | undefined): string | undefined {\n if (!status || status.code === SPAN_STATUS_UNSET) {\n return undefined;\n }\n\n if (status.code === SPAN_STATUS_OK) {\n return 'ok';\n }\n\n return status.message || 'internal_error';\n}\n\n/**\n * Convert the various statuses to the ones expected by Sentry ('ok' is default)\n */\nexport function getV2StatusMessage(status: SpanStatus | undefined): 'ok' | 'error' {\n return !status || status.code === SPAN_STATUS_OK || status.code === SPAN_STATUS_UNSET ? 'ok' : 'error';\n}\n\n/**\n * Convert the attributes to the ones expected by Sentry, including the type annotation\n */\nexport function getV2Attributes(attributes: SpanAttributes): TypedAttributes {\n return Object.entries(attributes).reduce((acc, [key, value]) => {\n acc[key] = attributeValueToTypedAttributeValue(value);\n return acc;\n }, {} as TypedAttributes);\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\ntype SpanWithPotentialChildren = Span & {\n [CHILD_SPANS_FIELD]?: Set<Span>;\n [ROOT_SPAN_FIELD]?: Span;\n};\n\n/**\n * Adds an opaque child span reference to a span.\n */\nexport function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n // We store the root span reference on the child span\n // We need this for `getRootSpan()` to work\n const rootSpan = span[ROOT_SPAN_FIELD] || span;\n addNonEnumerableProperty(childSpan as SpanWithPotentialChildren, ROOT_SPAN_FIELD, rootSpan);\n\n // We store a list of child spans on the parent span\n // We need this for `getSpanDescendants()` to work\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].add(childSpan);\n } else {\n addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n }\n}\n\n/** This is only used internally by Idle Spans. */\nexport function removeChildSpanFromSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].delete(childSpan);\n }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nexport function getSpanDescendants(span: SpanWithPotentialChildren): Span[] {\n const resultSet = new Set<Span>();\n\n function addSpanChildren(span: SpanWithPotentialChildren): void {\n // This exit condition is required to not infinitely loop in case of a circular dependency.\n if (resultSet.has(span)) {\n return;\n // We want to ignore unsampled spans (e.g. non recording spans)\n } else if (spanIsSampled(span)) {\n resultSet.add(span);\n const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n for (const childSpan of childSpans) {\n addSpanChildren(childSpan);\n }\n }\n }\n\n addSpanChildren(span);\n\n return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nexport const getRootSpan = INTERNAL_getSegmentSpan;\n\n/**\n * Returns the segment span of a given span.\n */\nexport function INTERNAL_getSegmentSpan(span: SpanWithPotentialChildren): Span {\n return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nexport function getActiveSpan(): Span | undefined {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getActiveSpan) {\n return acs.getActiveSpan();\n }\n\n return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Logs a warning once if `beforeSendSpan` is used to drop spans.\n */\nexport function showSpanDropWarning(): void {\n if (!hasShownSpanDropWarning) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Returning null from `beforeSendSpan` is disallowed. To drop certain spans, configure the respective integrations directly or use `ignoreSpans`.',\n );\n });\n hasShownSpanDropWarning = true;\n }\n}\n\n/**\n * Updates the name of the given span and ensures that the span name is not\n * overwritten by the Sentry SDK.\n *\n * Use this function instead of `span.updateName()` if you want to make sure that\n * your name is kept. For some spans, for example root `http.server` spans the\n * Sentry SDK would otherwise overwrite the span name with a high-quality name\n * it infers when the span ends.\n *\n * Use this function in server code or when your span is started on the server\n * and on the client (browser). If you only update a span name on the client,\n * you can also use `span.updateName()` the SDK does not overwrite the name.\n *\n * @param span - The span to update the name of.\n * @param name - The name to set on the span.\n */\nexport function updateSpanName(span: Span, name: string): void {\n span.updateName(name);\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name,\n });\n}\n"],"names":[],"mappings":"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"}
@@ -54,10 +54,7 @@ function getTraceData(
54
54
  };
55
55
 
56
56
  if (options.propagateTraceparent) {
57
- const traceparent = span ? spanToTraceparentHeader(span) : scopeToTraceparentHeader(scope);
58
- if (traceparent) {
59
- traceData.traceparent = traceparent;
60
- }
57
+ traceData.traceparent = span ? spanToTraceparentHeader(span) : scopeToTraceparentHeader(scope);
61
58
  }
62
59
 
63
60
  return traceData;
@@ -1 +1 @@
1
- {"version":3,"file":"traceData.js","sources":["../../../src/utils/traceData.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport type { Client } from '../client';\nimport { getClient, getCurrentScope } from '../currentScopes';\nimport { isEnabled } from '../exports';\nimport type { Scope } from '../scope';\nimport { getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan } from '../tracing';\nimport type { Span } from '../types-hoist/span';\nimport type { SerializedTraceData } from '../types-hoist/tracing';\nimport { dynamicSamplingContextToSentryBaggageHeader } from './baggage';\nimport { debug } from './debug-logger';\nimport { getActiveSpan, spanToTraceHeader, spanToTraceparentHeader } from './spanUtils';\nimport { generateSentryTraceHeader, generateTraceparentHeader, TRACEPARENT_REGEXP } from './tracing';\n\n/**\n * Extracts trace propagation data from the current span or from the client's scope (via transaction or propagation\n * context) and serializes it to `sentry-trace` and `baggage` values. These values can be used to propagate\n * a trace via our tracing Http headers or Html `<meta>` tags.\n *\n * This function also applies some validation to the generated sentry-trace and baggage values to ensure that\n * only valid strings are returned.\n *\n * If (@param options.propagateTraceparent) is `true`, the function will also generate a `traceparent` value,\n * following the W3C traceparent header format.\n *\n * @returns an object with the tracing data values. The object keys are the name of the tracing key to be used as header\n * or meta tag name.\n */\nexport function getTraceData(\n options: { span?: Span; scope?: Scope; client?: Client; propagateTraceparent?: boolean } = {},\n): SerializedTraceData {\n const client = options.client || getClient();\n if (!isEnabled() || !client) {\n return {};\n }\n\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getTraceData) {\n return acs.getTraceData(options);\n }\n\n const scope = options.scope || getCurrentScope();\n const span = options.span || getActiveSpan();\n const sentryTrace = span ? spanToTraceHeader(span) : scopeToTraceHeader(scope);\n const dsc = span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromScope(client, scope);\n const baggage = dynamicSamplingContextToSentryBaggageHeader(dsc);\n\n const isValidSentryTraceHeader = TRACEPARENT_REGEXP.test(sentryTrace);\n if (!isValidSentryTraceHeader) {\n debug.warn('Invalid sentry-trace data. Cannot generate trace data');\n return {};\n }\n\n const traceData: SerializedTraceData = {\n 'sentry-trace': sentryTrace,\n baggage,\n };\n\n if (options.propagateTraceparent) {\n const traceparent = span ? spanToTraceparentHeader(span) : scopeToTraceparentHeader(scope);\n if (traceparent) {\n traceData.traceparent = traceparent;\n }\n }\n\n return traceData;\n}\n\n/**\n * Get a sentry-trace header value for the given scope.\n */\nfunction scopeToTraceHeader(scope: Scope): string {\n const { traceId, sampled, propagationSpanId } = scope.getPropagationContext();\n return generateSentryTraceHeader(traceId, propagationSpanId, sampled);\n}\n\nfunction scopeToTraceparentHeader(scope: Scope): string {\n const { traceId, sampled, propagationSpanId } = scope.getPropagationContext();\n return generateTraceparentHeader(traceId, propagationSpanId, sampled);\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY;AAC5B,EAAE,OAAO,GAAoF,EAAE;AAC/F,EAAuB;AACvB,EAAE,MAAM,SAAS,OAAO,CAAC,MAAA,IAAU,SAAS,EAAE;AAC9C,EAAE,IAAI,CAAC,SAAS,EAAC,IAAK,CAAC,MAAM,EAAE;AAC/B,IAAI,OAAO,EAAE;AACb,EAAE;;AAEF,EAAE,MAAM,OAAA,GAAU,cAAc,EAAE;AAClC,EAAE,MAAM,GAAA,GAAM,uBAAuB,CAAC,OAAO,CAAC;AAC9C,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE;AACxB,IAAI,OAAO,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;AACpC,EAAE;;AAEF,EAAE,MAAM,QAAQ,OAAO,CAAC,KAAA,IAAS,eAAe,EAAE;AAClD,EAAE,MAAM,OAAO,OAAO,CAAC,IAAA,IAAQ,aAAa,EAAE;AAC9C,EAAE,MAAM,WAAA,GAAc,IAAA,GAAO,iBAAiB,CAAC,IAAI,CAAA,GAAI,kBAAkB,CAAC,KAAK,CAAC;AAChF,EAAE,MAAM,GAAA,GAAM,IAAA,GAAO,iCAAiC,CAAC,IAAI,CAAA,GAAI,kCAAkC,CAAC,MAAM,EAAE,KAAK,CAAC;AAChH,EAAE,MAAM,OAAA,GAAU,2CAA2C,CAAC,GAAG,CAAC;;AAElE,EAAE,MAAM,2BAA2B,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC;AACvE,EAAE,IAAI,CAAC,wBAAwB,EAAE;AACjC,IAAI,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC;AACvE,IAAI,OAAO,EAAE;AACb,EAAE;;AAEF,EAAE,MAAM,SAAS,GAAwB;AACzC,IAAI,cAAc,EAAE,WAAW;AAC/B,IAAI,OAAO;AACX,GAAG;;AAEH,EAAE,IAAI,OAAO,CAAC,oBAAoB,EAAE;AACpC,IAAI,MAAM,WAAA,GAAc,IAAA,GAAO,uBAAuB,CAAC,IAAI,CAAA,GAAI,wBAAwB,CAAC,KAAK,CAAC;AAC9F,IAAI,IAAI,WAAW,EAAE;AACrB,MAAM,SAAS,CAAC,WAAA,GAAc,WAAW;AACzC,IAAI;AACJ,EAAE;;AAEF,EAAE,OAAO,SAAS;AAClB;;AAEA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,KAAK,EAAiB;AAClD,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAA,EAAkB,GAAI,KAAK,CAAC,qBAAqB,EAAE;AAC/E,EAAE,OAAO,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC;AACvE;;AAEA,SAAS,wBAAwB,CAAC,KAAK,EAAiB;AACxD,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAA,EAAkB,GAAI,KAAK,CAAC,qBAAqB,EAAE;AAC/E,EAAE,OAAO,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC;AACvE;;;;"}
1
+ {"version":3,"file":"traceData.js","sources":["../../../src/utils/traceData.ts"],"sourcesContent":["import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport type { Client } from '../client';\nimport { getClient, getCurrentScope } from '../currentScopes';\nimport { isEnabled } from '../exports';\nimport type { Scope } from '../scope';\nimport { getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan } from '../tracing';\nimport type { Span } from '../types-hoist/span';\nimport type { SerializedTraceData } from '../types-hoist/tracing';\nimport { dynamicSamplingContextToSentryBaggageHeader } from './baggage';\nimport { debug } from './debug-logger';\nimport { getActiveSpan, spanToTraceHeader, spanToTraceparentHeader } from './spanUtils';\nimport { generateSentryTraceHeader, generateTraceparentHeader, TRACEPARENT_REGEXP } from './tracing';\n\n/**\n * Extracts trace propagation data from the current span or from the client's scope (via transaction or propagation\n * context) and serializes it to `sentry-trace` and `baggage` values. These values can be used to propagate\n * a trace via our tracing Http headers or Html `<meta>` tags.\n *\n * This function also applies some validation to the generated sentry-trace and baggage values to ensure that\n * only valid strings are returned.\n *\n * If (@param options.propagateTraceparent) is `true`, the function will also generate a `traceparent` value,\n * following the W3C traceparent header format.\n *\n * @returns an object with the tracing data values. The object keys are the name of the tracing key to be used as header\n * or meta tag name.\n */\nexport function getTraceData(\n options: { span?: Span; scope?: Scope; client?: Client; propagateTraceparent?: boolean } = {},\n): SerializedTraceData {\n const client = options.client || getClient();\n if (!isEnabled() || !client) {\n return {};\n }\n\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getTraceData) {\n return acs.getTraceData(options);\n }\n\n const scope = options.scope || getCurrentScope();\n const span = options.span || getActiveSpan();\n const sentryTrace = span ? spanToTraceHeader(span) : scopeToTraceHeader(scope);\n const dsc = span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromScope(client, scope);\n const baggage = dynamicSamplingContextToSentryBaggageHeader(dsc);\n\n const isValidSentryTraceHeader = TRACEPARENT_REGEXP.test(sentryTrace);\n if (!isValidSentryTraceHeader) {\n debug.warn('Invalid sentry-trace data. Cannot generate trace data');\n return {};\n }\n\n const traceData: SerializedTraceData = {\n 'sentry-trace': sentryTrace,\n baggage,\n };\n\n if (options.propagateTraceparent) {\n traceData.traceparent = span ? spanToTraceparentHeader(span) : scopeToTraceparentHeader(scope);\n }\n\n return traceData;\n}\n\n/**\n * Get a sentry-trace header value for the given scope.\n */\nfunction scopeToTraceHeader(scope: Scope): string {\n const { traceId, sampled, propagationSpanId } = scope.getPropagationContext();\n return generateSentryTraceHeader(traceId, propagationSpanId, sampled);\n}\n\nfunction scopeToTraceparentHeader(scope: Scope): string {\n const { traceId, sampled, propagationSpanId } = scope.getPropagationContext();\n return generateTraceparentHeader(traceId, propagationSpanId, sampled);\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY;AAC5B,EAAE,OAAO,GAAoF,EAAE;AAC/F,EAAuB;AACvB,EAAE,MAAM,SAAS,OAAO,CAAC,MAAA,IAAU,SAAS,EAAE;AAC9C,EAAE,IAAI,CAAC,SAAS,EAAC,IAAK,CAAC,MAAM,EAAE;AAC/B,IAAI,OAAO,EAAE;AACb,EAAE;;AAEF,EAAE,MAAM,OAAA,GAAU,cAAc,EAAE;AAClC,EAAE,MAAM,GAAA,GAAM,uBAAuB,CAAC,OAAO,CAAC;AAC9C,EAAE,IAAI,GAAG,CAAC,YAAY,EAAE;AACxB,IAAI,OAAO,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;AACpC,EAAE;;AAEF,EAAE,MAAM,QAAQ,OAAO,CAAC,KAAA,IAAS,eAAe,EAAE;AAClD,EAAE,MAAM,OAAO,OAAO,CAAC,IAAA,IAAQ,aAAa,EAAE;AAC9C,EAAE,MAAM,WAAA,GAAc,IAAA,GAAO,iBAAiB,CAAC,IAAI,CAAA,GAAI,kBAAkB,CAAC,KAAK,CAAC;AAChF,EAAE,MAAM,GAAA,GAAM,IAAA,GAAO,iCAAiC,CAAC,IAAI,CAAA,GAAI,kCAAkC,CAAC,MAAM,EAAE,KAAK,CAAC;AAChH,EAAE,MAAM,OAAA,GAAU,2CAA2C,CAAC,GAAG,CAAC;;AAElE,EAAE,MAAM,2BAA2B,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC;AACvE,EAAE,IAAI,CAAC,wBAAwB,EAAE;AACjC,IAAI,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC;AACvE,IAAI,OAAO,EAAE;AACb,EAAE;;AAEF,EAAE,MAAM,SAAS,GAAwB;AACzC,IAAI,cAAc,EAAE,WAAW;AAC/B,IAAI,OAAO;AACX,GAAG;;AAEH,EAAE,IAAI,OAAO,CAAC,oBAAoB,EAAE;AACpC,IAAI,SAAS,CAAC,WAAA,GAAc,OAAO,uBAAuB,CAAC,IAAI,CAAA,GAAI,wBAAwB,CAAC,KAAK,CAAC;AAClG,EAAE;;AAEF,EAAE,OAAO,SAAS;AAClB;;AAEA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,KAAK,EAAiB;AAClD,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAA,EAAkB,GAAI,KAAK,CAAC,qBAAqB,EAAE;AAC/E,EAAE,OAAO,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC;AACvE;;AAEA,SAAS,wBAAwB,CAAC,KAAK,EAAiB;AACxD,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAA,EAAkB,GAAI,KAAK,CAAC,qBAAqB,EAAE;AAC/E,EAAE,OAAO,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC;AACvE;;;;"}
@@ -1,6 +1,6 @@
1
1
  // This is a magic string replaced by rollup
2
2
 
3
- const SDK_VERSION = "10.30.0" ;
3
+ const SDK_VERSION = "10.32.0-alpha.0" ;
4
4
 
5
5
  export { SDK_VERSION };
6
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../src/utils/version.ts"],"sourcesContent":["// This is a magic string replaced by rollup\ndeclare const __SENTRY_SDK_VERSION__: string;\n\nexport const SDK_VERSION = typeof __SENTRY_SDK_VERSION__ === 'string' ? __SENTRY_SDK_VERSION__ : '0.0.0-unknown.0';\n"],"names":[],"mappings":"AAAA;;AAGO,MAAM,WAAA,GAA2D,SAAA;;;;"}
1
+ {"version":3,"file":"version.js","sources":["../../../src/utils/version.ts"],"sourcesContent":["// This is a magic string replaced by rollup\ndeclare const __SENTRY_SDK_VERSION__: string;\n\nexport const SDK_VERSION = typeof __SENTRY_SDK_VERSION__ === 'string' ? __SENTRY_SDK_VERSION__ : '0.0.0-unknown.0';\n"],"names":[],"mappings":"AAAA;;AAGO,MAAM,WAAA,GAA2D,iBAAA;;;;"}
@@ -5,7 +5,7 @@ export type RawAttribute<T> = T extends {
5
5
  } | {
6
6
  unit: any;
7
7
  } ? AttributeObject : T;
8
- export type Attributes = Record<string, TypedAttributeValue>;
8
+ export type TypedAttributes = Record<string, TypedAttributeValue>;
9
9
  export type AttributeValueType = string | number | boolean | Array<string> | Array<number> | Array<boolean>;
10
10
  type AttributeTypeMap = {
11
11
  string: string;
@@ -30,7 +30,7 @@ export type AttributeObject = {
30
30
  value: unknown;
31
31
  unit?: AttributeUnit;
32
32
  };
33
- type AttributeUnit = DurationUnit | InformationUnit | FractionUnit;
33
+ export type AttributeUnit = DurationUnit | InformationUnit | FractionUnit;
34
34
  export type ValidatedAttributes<T> = {
35
35
  [K in keyof T]: T[K] extends {
36
36
  value: any;