@sentry/core 10.50.0-alpha.0 → 10.51.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 (227) hide show
  1. package/build/cjs/client.js +27 -12
  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/index.js +10 -5
  6. package/build/cjs/index.js.map +1 -1
  7. package/build/cjs/instrument/console.js +4 -3
  8. package/build/cjs/instrument/console.js.map +1 -1
  9. package/build/cjs/instrument/fetch.js +6 -2
  10. package/build/cjs/instrument/fetch.js.map +1 -1
  11. package/build/cjs/instrument/handlers.js +11 -1
  12. package/build/cjs/instrument/handlers.js.map +1 -1
  13. package/build/cjs/integrations/console.js +3 -1
  14. package/build/cjs/integrations/console.js.map +1 -1
  15. package/build/cjs/integrations/extraerrordata.js +2 -2
  16. package/build/cjs/integrations/extraerrordata.js.map +1 -1
  17. package/build/cjs/integrations/postgresjs.js +10 -1
  18. package/build/cjs/integrations/postgresjs.js.map +1 -1
  19. package/build/cjs/integrations/requestdata.js +9 -5
  20. package/build/cjs/integrations/requestdata.js.map +1 -1
  21. package/build/cjs/integrations/supabase.js +39 -12
  22. package/build/cjs/integrations/supabase.js.map +1 -1
  23. package/build/cjs/logs/console-integration.js +3 -1
  24. package/build/cjs/logs/console-integration.js.map +1 -1
  25. package/build/cjs/server-runtime-client.js +20 -2
  26. package/build/cjs/server-runtime-client.js.map +1 -1
  27. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  28. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  29. package/build/cjs/tracing/ai/utils.js +4 -4
  30. package/build/cjs/tracing/ai/utils.js.map +1 -1
  31. package/build/cjs/tracing/idleSpan.js +7 -1
  32. package/build/cjs/tracing/idleSpan.js.map +1 -1
  33. package/build/cjs/tracing/langchain/index.js +43 -8
  34. package/build/cjs/tracing/langchain/index.js.map +1 -1
  35. package/build/cjs/tracing/langchain/utils.js +44 -10
  36. package/build/cjs/tracing/langchain/utils.js.map +1 -1
  37. package/build/cjs/tracing/langgraph/index.js +105 -2
  38. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  39. package/build/cjs/tracing/langgraph/utils.js +168 -0
  40. package/build/cjs/tracing/langgraph/utils.js.map +1 -1
  41. package/build/cjs/tracing/sentrySpan.js +0 -5
  42. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  43. package/build/cjs/tracing/spans/captureSpan.js +125 -0
  44. package/build/cjs/tracing/spans/captureSpan.js.map +1 -1
  45. package/build/cjs/tracing/spans/envelope.js +13 -3
  46. package/build/cjs/tracing/spans/envelope.js.map +1 -1
  47. package/build/cjs/tracing/trace.js +1 -0
  48. package/build/cjs/tracing/trace.js.map +1 -1
  49. package/build/cjs/tracing/vercel-ai/index.js +0 -9
  50. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  51. package/build/cjs/trpc.js +2 -3
  52. package/build/cjs/trpc.js.map +1 -1
  53. package/build/cjs/utils/isSentryRequestUrl.js +9 -1
  54. package/build/cjs/utils/isSentryRequestUrl.js.map +1 -1
  55. package/build/cjs/utils/normalizationHints.js +38 -0
  56. package/build/cjs/utils/normalizationHints.js.map +1 -0
  57. package/build/cjs/utils/normalize.js +7 -11
  58. package/build/cjs/utils/normalize.js.map +1 -1
  59. package/build/cjs/utils/object.js +1 -1
  60. package/build/cjs/utils/object.js.map +1 -1
  61. package/build/cjs/utils/request.js +63 -12
  62. package/build/cjs/utils/request.js.map +1 -1
  63. package/build/cjs/utils/should-ignore-span.js +27 -8
  64. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  65. package/build/cjs/utils/version.js +1 -1
  66. package/build/cjs/utils/version.js.map +1 -1
  67. package/build/esm/client.js +27 -12
  68. package/build/esm/client.js.map +1 -1
  69. package/build/esm/envelope.js +4 -1
  70. package/build/esm/envelope.js.map +1 -1
  71. package/build/esm/index.js +3 -2
  72. package/build/esm/index.js.map +1 -1
  73. package/build/esm/instrument/console.js +4 -3
  74. package/build/esm/instrument/console.js.map +1 -1
  75. package/build/esm/instrument/fetch.js +6 -2
  76. package/build/esm/instrument/fetch.js.map +1 -1
  77. package/build/esm/instrument/handlers.js +11 -1
  78. package/build/esm/instrument/handlers.js.map +1 -1
  79. package/build/esm/integrations/console.js +3 -1
  80. package/build/esm/integrations/console.js.map +1 -1
  81. package/build/esm/integrations/extraerrordata.js +2 -2
  82. package/build/esm/integrations/extraerrordata.js.map +1 -1
  83. package/build/esm/integrations/postgresjs.js +10 -1
  84. package/build/esm/integrations/postgresjs.js.map +1 -1
  85. package/build/esm/integrations/requestdata.js +9 -5
  86. package/build/esm/integrations/requestdata.js.map +1 -1
  87. package/build/esm/integrations/supabase.js +39 -12
  88. package/build/esm/integrations/supabase.js.map +1 -1
  89. package/build/esm/logs/console-integration.js +3 -1
  90. package/build/esm/logs/console-integration.js.map +1 -1
  91. package/build/esm/package.json +1 -1
  92. package/build/esm/server-runtime-client.js +20 -2
  93. package/build/esm/server-runtime-client.js.map +1 -1
  94. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  95. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  96. package/build/esm/tracing/ai/utils.js +4 -4
  97. package/build/esm/tracing/ai/utils.js.map +1 -1
  98. package/build/esm/tracing/idleSpan.js +7 -1
  99. package/build/esm/tracing/idleSpan.js.map +1 -1
  100. package/build/esm/tracing/langchain/index.js +45 -10
  101. package/build/esm/tracing/langchain/index.js.map +1 -1
  102. package/build/esm/tracing/langchain/utils.js +44 -12
  103. package/build/esm/tracing/langchain/utils.js.map +1 -1
  104. package/build/esm/tracing/langgraph/index.js +107 -5
  105. package/build/esm/tracing/langgraph/index.js.map +1 -1
  106. package/build/esm/tracing/langgraph/utils.js +166 -2
  107. package/build/esm/tracing/langgraph/utils.js.map +1 -1
  108. package/build/esm/tracing/sentrySpan.js +0 -5
  109. package/build/esm/tracing/sentrySpan.js.map +1 -1
  110. package/build/esm/tracing/spans/captureSpan.js +126 -2
  111. package/build/esm/tracing/spans/captureSpan.js.map +1 -1
  112. package/build/esm/tracing/spans/envelope.js +13 -3
  113. package/build/esm/tracing/spans/envelope.js.map +1 -1
  114. package/build/esm/tracing/trace.js +1 -0
  115. package/build/esm/tracing/trace.js.map +1 -1
  116. package/build/esm/tracing/vercel-ai/index.js +0 -9
  117. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  118. package/build/esm/trpc.js +2 -3
  119. package/build/esm/trpc.js.map +1 -1
  120. package/build/esm/utils/isSentryRequestUrl.js +9 -1
  121. package/build/esm/utils/isSentryRequestUrl.js.map +1 -1
  122. package/build/esm/utils/normalizationHints.js +33 -0
  123. package/build/esm/utils/normalizationHints.js.map +1 -0
  124. package/build/esm/utils/normalize.js +7 -11
  125. package/build/esm/utils/normalize.js.map +1 -1
  126. package/build/esm/utils/object.js +1 -1
  127. package/build/esm/utils/object.js.map +1 -1
  128. package/build/esm/utils/request.js +63 -12
  129. package/build/esm/utils/request.js.map +1 -1
  130. package/build/esm/utils/should-ignore-span.js +27 -8
  131. package/build/esm/utils/should-ignore-span.js.map +1 -1
  132. package/build/esm/utils/version.js +1 -1
  133. package/build/esm/utils/version.js.map +1 -1
  134. package/build/types/client.d.ts +12 -1
  135. package/build/types/client.d.ts.map +1 -1
  136. package/build/types/envelope.d.ts.map +1 -1
  137. package/build/types/index.d.ts +6 -3
  138. package/build/types/index.d.ts.map +1 -1
  139. package/build/types/instrument/console.d.ts +2 -1
  140. package/build/types/instrument/console.d.ts.map +1 -1
  141. package/build/types/instrument/fetch.d.ts +4 -2
  142. package/build/types/instrument/fetch.d.ts.map +1 -1
  143. package/build/types/instrument/handlers.d.ts +2 -2
  144. package/build/types/instrument/handlers.d.ts.map +1 -1
  145. package/build/types/integrations/console.d.ts.map +1 -1
  146. package/build/types/integrations/postgresjs.d.ts.map +1 -1
  147. package/build/types/integrations/supabase.d.ts.map +1 -1
  148. package/build/types/logs/console-integration.d.ts.map +1 -1
  149. package/build/types/server-runtime-client.d.ts +5 -0
  150. package/build/types/server-runtime-client.d.ts.map +1 -1
  151. package/build/types/tracing/ai/utils.d.ts +1 -3
  152. package/build/types/tracing/ai/utils.d.ts.map +1 -1
  153. package/build/types/tracing/google-genai/types.d.ts +5 -2
  154. package/build/types/tracing/google-genai/types.d.ts.map +1 -1
  155. package/build/types/tracing/idleSpan.d.ts.map +1 -1
  156. package/build/types/tracing/langchain/index.d.ts.map +1 -1
  157. package/build/types/tracing/langchain/types.d.ts +8 -0
  158. package/build/types/tracing/langchain/types.d.ts.map +1 -1
  159. package/build/types/tracing/langchain/utils.d.ts +2 -0
  160. package/build/types/tracing/langchain/utils.d.ts.map +1 -1
  161. package/build/types/tracing/langgraph/index.d.ts +4 -0
  162. package/build/types/tracing/langgraph/index.d.ts.map +1 -1
  163. package/build/types/tracing/langgraph/utils.d.ts +18 -2
  164. package/build/types/tracing/langgraph/utils.d.ts.map +1 -1
  165. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  166. package/build/types/tracing/spans/captureSpan.d.ts +10 -0
  167. package/build/types/tracing/spans/captureSpan.d.ts.map +1 -1
  168. package/build/types/tracing/spans/envelope.d.ts.map +1 -1
  169. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  170. package/build/types/trpc.d.ts.map +1 -1
  171. package/build/types/types-hoist/envelope.d.ts +1 -1
  172. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  173. package/build/types/types-hoist/feedback/config.d.ts +20 -0
  174. package/build/types/types-hoist/feedback/config.d.ts.map +1 -1
  175. package/build/types/types-hoist/feedback/index.d.ts +2 -2
  176. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  177. package/build/types/types-hoist/feedback/sendFeedback.d.ts +3 -0
  178. package/build/types/types-hoist/feedback/sendFeedback.d.ts.map +1 -1
  179. package/build/types/types-hoist/options.d.ts +37 -2
  180. package/build/types/types-hoist/options.d.ts.map +1 -1
  181. package/build/types/types-hoist/span.d.ts +5 -0
  182. package/build/types/types-hoist/span.d.ts.map +1 -1
  183. package/build/types/utils/normalizationHints.d.ts +9 -0
  184. package/build/types/utils/normalizationHints.d.ts.map +1 -0
  185. package/build/types/utils/normalize.d.ts.map +1 -1
  186. package/build/types/utils/object.d.ts +1 -1
  187. package/build/types/utils/object.d.ts.map +1 -1
  188. package/build/types/utils/request.d.ts.map +1 -1
  189. package/build/types/utils/should-ignore-span.d.ts +3 -1
  190. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  191. package/build/types-ts3.8/client.d.ts +12 -1
  192. package/build/types-ts3.8/index.d.ts +6 -3
  193. package/build/types-ts3.8/instrument/console.d.ts +2 -1
  194. package/build/types-ts3.8/instrument/fetch.d.ts +4 -2
  195. package/build/types-ts3.8/instrument/handlers.d.ts +2 -2
  196. package/build/types-ts3.8/server-runtime-client.d.ts +5 -0
  197. package/build/types-ts3.8/tracing/ai/utils.d.ts +1 -3
  198. package/build/types-ts3.8/tracing/google-genai/types.d.ts +5 -2
  199. package/build/types-ts3.8/tracing/langchain/types.d.ts +8 -0
  200. package/build/types-ts3.8/tracing/langchain/utils.d.ts +2 -0
  201. package/build/types-ts3.8/tracing/langgraph/index.d.ts +4 -0
  202. package/build/types-ts3.8/tracing/langgraph/utils.d.ts +18 -2
  203. package/build/types-ts3.8/tracing/spans/captureSpan.d.ts +10 -0
  204. package/build/types-ts3.8/types-hoist/envelope.d.ts +1 -1
  205. package/build/types-ts3.8/types-hoist/feedback/config.d.ts +20 -0
  206. package/build/types-ts3.8/types-hoist/feedback/index.d.ts +2 -2
  207. package/build/types-ts3.8/types-hoist/feedback/sendFeedback.d.ts +3 -0
  208. package/build/types-ts3.8/types-hoist/options.d.ts +37 -2
  209. package/build/types-ts3.8/types-hoist/span.d.ts +5 -0
  210. package/build/types-ts3.8/utils/normalizationHints.d.ts +9 -0
  211. package/build/types-ts3.8/utils/object.d.ts +1 -1
  212. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -1
  213. package/package.json +1 -1
  214. package/build/cjs/tracing/spans/extractGenAiSpans.js +0 -50
  215. package/build/cjs/tracing/spans/extractGenAiSpans.js.map +0 -1
  216. package/build/cjs/tracing/spans/spanJsonToStreamedSpan.js +0 -26
  217. package/build/cjs/tracing/spans/spanJsonToStreamedSpan.js.map +0 -1
  218. package/build/esm/tracing/spans/extractGenAiSpans.js +0 -48
  219. package/build/esm/tracing/spans/extractGenAiSpans.js.map +0 -1
  220. package/build/esm/tracing/spans/spanJsonToStreamedSpan.js +0 -24
  221. package/build/esm/tracing/spans/spanJsonToStreamedSpan.js.map +0 -1
  222. package/build/types/tracing/spans/extractGenAiSpans.d.ts +0 -15
  223. package/build/types/tracing/spans/extractGenAiSpans.d.ts.map +0 -1
  224. package/build/types/tracing/spans/spanJsonToStreamedSpan.d.ts +0 -6
  225. package/build/types/tracing/spans/spanJsonToStreamedSpan.d.ts.map +0 -1
  226. package/build/types-ts3.8/tracing/spans/extractGenAiSpans.d.ts +0 -15
  227. package/build/types-ts3.8/tracing/spans/spanJsonToStreamedSpan.d.ts +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { getClient } from '../../currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { shouldEnableTruncation } from '../ai/utils';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap } from './constants';\nimport type { TokenSummary } from './types';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n const client = getClient();\n const integration = client?.getIntegrationByName('VercelAI') as\n | { options?: { enableTruncation?: boolean } }\n | undefined;\n const enableTruncation = shouldEnableTruncation(integration?.options?.enableTruncation);\n\n processGenerateSpan(span, name, attributes, enableTruncation);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n // The Vercel AI SDK sets span status to raw error message strings.\n // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.\n if (span.status && span.status !== 'ok') {\n span.status = 'internal_error';\n }\n\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n // V6+ sets ai.operationId to the bare operation (e.g. \"ai.streamText\") while\n // operation.name appends functionId (e.g. \"ai.streamText myAgent\").\n // When ai.operationId is present, use it for correct mapping.\n const rawOperationName = attributes[AI_OPERATION_ID_ATTRIBUTE]\n ? (attributes[AI_OPERATION_ID_ATTRIBUTE] as string)\n : (attributes[OPERATION_NAME_ATTRIBUTE] as string);\n const operationName = SPAN_TO_OPERATION_NAME.get(rawOperationName) ?? rawOperationName;\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n\n // JSON-stringify any array-valued attributes so they survive v2 span serialization.\n // The v2 serializer currently drops array values. Can be removed once span streaming\n // supports arrays natively.\n for (const [key, value] of Object.entries(attributes)) {\n if (Array.isArray(value)) {\n attributes[key] = JSON.stringify(value);\n }\n }\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes, enableTruncation: boolean): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes, enableTruncation);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the operation name registry\n const operationName = SPAN_TO_OPERATION_NAME.get(name);\n if (operationName) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `gen_ai.${operationName}`);\n } else if (name.startsWith('ai.stream')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run');\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (operationName === 'invoke_agent') {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId && operationName) {\n span.updateName(`${operationName} ${modelId}`);\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n}\n\nfunction addProviderMetadataToAttributes(attributes: SpanAttributes): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n if (!attributes['gen_ai.conversation.id']) {\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/tracing/vercel-ai/index.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Client } from '../../client';\nimport { getClient } from '../../currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes';\nimport { shouldEnableTruncation } from '../ai/utils';\nimport type { Event } from '../../types-hoist/event';\nimport type { Span, SpanAttributes, SpanAttributeValue, SpanJSON } from '../../types-hoist/span';\nimport { spanToJSON } from '../../utils/spanUtils';\nimport {\n GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE,\n GEN_AI_INPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_OPERATION_NAME_ATTRIBUTE,\n GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE,\n GEN_AI_REQUEST_MODEL_ATTRIBUTE,\n GEN_AI_RESPONSE_MODEL_ATTRIBUTE,\n GEN_AI_TOOL_CALL_ID_ATTRIBUTE,\n GEN_AI_TOOL_INPUT_ATTRIBUTE,\n GEN_AI_TOOL_NAME_ATTRIBUTE,\n GEN_AI_TOOL_OUTPUT_ATTRIBUTE,\n GEN_AI_TOOL_TYPE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE,\n GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE,\n} from '../ai/gen-ai-attributes';\nimport { SPAN_TO_OPERATION_NAME, toolCallSpanContextMap } from './constants';\nimport type { TokenSummary } from './types';\nimport {\n accumulateTokensForParent,\n applyAccumulatedTokens,\n applyToolDescriptionsAndTokens,\n convertAvailableToolsToJsonString,\n requestMessagesFromPrompt,\n} from './utils';\nimport type { OpenAiProviderMetadata, ProviderMetadata } from './vercel-ai-attributes';\nimport {\n AI_MODEL_ID_ATTRIBUTE,\n AI_OPERATION_ID_ATTRIBUTE,\n AI_PROMPT_MESSAGES_ATTRIBUTE,\n AI_PROMPT_TOOLS_ATTRIBUTE,\n AI_RESPONSE_FINISH_REASON_ATTRIBUTE,\n AI_RESPONSE_OBJECT_ATTRIBUTE,\n AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE,\n AI_RESPONSE_TEXT_ATTRIBUTE,\n AI_RESPONSE_TOOL_CALLS_ATTRIBUTE,\n AI_SCHEMA_ATTRIBUTE,\n AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE,\n AI_TOOL_CALL_ARGS_ATTRIBUTE,\n AI_TOOL_CALL_ID_ATTRIBUTE,\n AI_TOOL_CALL_NAME_ATTRIBUTE,\n AI_TOOL_CALL_RESULT_ATTRIBUTE,\n AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE,\n AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE,\n AI_USAGE_PROMPT_TOKENS_ATTRIBUTE,\n AI_USAGE_TOKENS_ATTRIBUTE,\n AI_VALUES_ATTRIBUTE,\n OPERATION_NAME_ATTRIBUTE,\n} from './vercel-ai-attributes';\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n * This is supposed to be used in `client.on('spanStart', ...)\n */\nfunction onVercelAiSpanStart(span: Span): void {\n const { data: attributes, description: name } = spanToJSON(span);\n\n if (!name) {\n return;\n }\n\n // Tool call spans\n // https://ai-sdk.dev/docs/ai-sdk-core/telemetry#tool-call-spans\n if (attributes[AI_TOOL_CALL_NAME_ATTRIBUTE] && attributes[AI_TOOL_CALL_ID_ATTRIBUTE] && name === 'ai.toolCall') {\n processToolCallSpan(span, attributes);\n return;\n }\n\n // V6+ Check if this is a Vercel AI span by checking if the operation ID attribute is present.\n // V5+ Check if this is a Vercel AI span by name pattern.\n if (!attributes[AI_OPERATION_ID_ATTRIBUTE] && !name.startsWith('ai.')) {\n return;\n }\n\n const client = getClient();\n const integration = client?.getIntegrationByName('VercelAI') as\n | { options?: { enableTruncation?: boolean } }\n | undefined;\n const enableTruncation = shouldEnableTruncation(integration?.options?.enableTruncation);\n\n processGenerateSpan(span, name, attributes, enableTruncation);\n}\n\nfunction vercelAiEventProcessor(event: Event): Event {\n if (event.type === 'transaction' && event.spans) {\n // Map to accumulate token data by parent span ID\n const tokenAccumulator: Map<string, TokenSummary> = new Map();\n\n // First pass: process all spans and accumulate token data\n for (const span of event.spans) {\n processEndedVercelAiSpan(span);\n\n // Accumulate token data for parent spans\n accumulateTokensForParent(span, tokenAccumulator);\n }\n\n // Second pass: apply tool descriptions and accumulated tokens\n applyToolDescriptionsAndTokens(event.spans, tokenAccumulator);\n\n // Also apply to root when it is the invoke_agent pipeline\n const trace = event.contexts?.trace;\n if (trace?.op === 'gen_ai.invoke_agent') {\n applyAccumulatedTokens(trace, tokenAccumulator);\n }\n }\n\n return event;\n}\n\n/**\n * Tool call structure from Vercel AI SDK\n * Note: V5/V6 use 'input' for arguments, V4 and earlier use 'args'\n */\ninterface VercelToolCall {\n toolCallId: string;\n toolName: string;\n input?: Record<string, unknown> | string; // V5/V6\n args?: string; // V4 and earlier\n}\n\n/**\n * Normalize finish reason to match OpenTelemetry semantic conventions.\n * Valid values: \"stop\", \"length\", \"content_filter\", \"tool_call\", \"error\"\n *\n * Vercel AI SDK uses \"tool-calls\" (plural, with hyphen) which we map to \"tool_call\".\n */\nfunction normalizeFinishReason(finishReason: unknown): string {\n if (typeof finishReason !== 'string') {\n return 'stop';\n }\n\n // Map Vercel AI SDK finish reasons to OpenTelemetry semantic convention values\n switch (finishReason) {\n case 'tool-calls':\n return 'tool_call';\n case 'stop':\n case 'length':\n case 'content_filter':\n case 'error':\n return finishReason;\n default:\n // For unknown values, return as-is (schema allows arbitrary strings)\n return finishReason;\n }\n}\n\n/**\n * Build gen_ai.output.messages from ai.response.text and/or ai.response.toolCalls\n *\n * Format follows OpenTelemetry semantic conventions:\n * [{\"role\": \"assistant\", \"parts\": [...], \"finish_reason\": \"stop\"}]\n *\n * Parts can be:\n * - {\"type\": \"text\", \"content\": \"...\"}\n * - {\"type\": \"tool_call\", \"id\": \"...\", \"name\": \"...\", \"arguments\": \"...\"}\n */\nfunction buildOutputMessages(attributes: Record<string, unknown>): void {\n const responseText = attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n const responseToolCalls = attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n const finishReason = attributes[AI_RESPONSE_FINISH_REASON_ATTRIBUTE];\n\n // Skip if neither text nor tool calls are present\n if (responseText == null && responseToolCalls == null) {\n return;\n }\n\n const parts: Array<Record<string, unknown>> = [];\n\n // Add text part if present\n if (typeof responseText === 'string' && responseText.length > 0) {\n parts.push({\n type: 'text',\n content: responseText,\n });\n }\n\n // Add tool call parts if present\n if (responseToolCalls != null) {\n try {\n // Tool calls can be a string (JSON) or already parsed array\n const toolCalls: VercelToolCall[] =\n typeof responseToolCalls === 'string' ? JSON.parse(responseToolCalls) : responseToolCalls;\n\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n // V5/V6 use 'input', V4 and earlier use 'args'\n const args = toolCall.input ?? toolCall.args;\n parts.push({\n type: 'tool_call',\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n // Handle undefined args: JSON.stringify(undefined) returns undefined, not a string,\n // which would cause the property to be omitted from the final JSON output\n arguments: typeof args === 'string' ? args : JSON.stringify(args ?? {}),\n });\n }\n // Only delete tool calls attribute if we successfully processed them\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TOOL_CALLS_ATTRIBUTE];\n }\n } catch {\n // Ignore parsing errors - tool calls attribute is preserved\n }\n }\n\n // Only set output messages and delete text attribute if we have parts\n if (parts.length > 0) {\n const outputMessage = {\n role: 'assistant',\n parts,\n finish_reason: normalizeFinishReason(finishReason),\n };\n\n attributes[GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE] = JSON.stringify([outputMessage]);\n\n // Remove the text attribute since it's now captured in gen_ai.output.messages\n // Note: tool calls attribute is deleted above only if successfully parsed\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[AI_RESPONSE_TEXT_ATTRIBUTE];\n }\n}\n\n/**\n * Post-process spans emitted by the Vercel AI SDK.\n */\nfunction processEndedVercelAiSpan(span: SpanJSON): void {\n const { data: attributes, origin } = span;\n\n if (origin !== 'auto.vercelai.otel') {\n return;\n }\n\n // The Vercel AI SDK sets span status to raw error message strings.\n // Any such value should be normalized to a SpanStatusType value. We pick internal_error as it is the most generic.\n if (span.status && span.status !== 'ok') {\n span.status = 'internal_error';\n }\n\n renameAttributeKey(attributes, AI_USAGE_COMPLETION_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_PROMPT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, AI_USAGE_CACHED_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE);\n\n // Parent spans (ai.streamText, ai.streamObject, etc.) use inputTokens/outputTokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, 'ai.usage.inputTokens', GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n renameAttributeKey(attributes, 'ai.usage.outputTokens', GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE);\n\n // Embedding spans use ai.usage.tokens instead of promptTokens/completionTokens\n renameAttributeKey(attributes, AI_USAGE_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE);\n\n // AI SDK uses avgOutputTokensPerSecond, map to our expected attribute name\n renameAttributeKey(attributes, 'ai.response.avgOutputTokensPerSecond', 'ai.response.avgCompletionTokensPerSecond');\n\n // Input tokens is the sum of prompt tokens and cached input tokens\n if (\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number' &&\n typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE] === 'number'\n ) {\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] =\n attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] + attributes[GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE];\n }\n\n // Compute total tokens from input + output (embeddings may only have input tokens)\n if (typeof attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] === 'number') {\n const outputTokens =\n typeof attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] === 'number'\n ? attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]\n : 0;\n attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = outputTokens + attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE];\n }\n\n // Convert the available tools array to a JSON string\n if (attributes[AI_PROMPT_TOOLS_ATTRIBUTE] && Array.isArray(attributes[AI_PROMPT_TOOLS_ATTRIBUTE])) {\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] = convertAvailableToolsToJsonString(\n attributes[AI_PROMPT_TOOLS_ATTRIBUTE] as unknown[],\n );\n }\n\n // Rename AI SDK attributes to standardized gen_ai attributes\n // Map operation.name to OpenTelemetry semantic convention values\n if (attributes[OPERATION_NAME_ATTRIBUTE]) {\n // V6+ sets ai.operationId to the bare operation (e.g. \"ai.streamText\") while\n // operation.name appends functionId (e.g. \"ai.streamText myAgent\").\n // When ai.operationId is present, use it for correct mapping.\n const rawOperationName = attributes[AI_OPERATION_ID_ATTRIBUTE]\n ? (attributes[AI_OPERATION_ID_ATTRIBUTE] as string)\n : (attributes[OPERATION_NAME_ATTRIBUTE] as string);\n const operationName = SPAN_TO_OPERATION_NAME.get(rawOperationName) ?? rawOperationName;\n attributes[GEN_AI_OPERATION_NAME_ATTRIBUTE] = operationName;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[OPERATION_NAME_ATTRIBUTE];\n }\n renameAttributeKey(attributes, AI_PROMPT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE);\n\n // Build gen_ai.output.messages from response text and/or tool calls\n // Note: buildOutputMessages also removes the source attributes when output is successfully generated\n buildOutputMessages(attributes);\n\n renameAttributeKey(attributes, AI_RESPONSE_OBJECT_ATTRIBUTE, 'gen_ai.response.object');\n renameAttributeKey(attributes, AI_PROMPT_TOOLS_ATTRIBUTE, 'gen_ai.request.available_tools');\n\n renameAttributeKey(attributes, AI_TOOL_CALL_ARGS_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_RESULT_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE);\n\n renameAttributeKey(attributes, AI_SCHEMA_ATTRIBUTE, 'gen_ai.request.schema');\n renameAttributeKey(attributes, AI_MODEL_ID_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE);\n\n // Map embedding input: ai.values → gen_ai.embeddings.input\n // Vercel AI SDK JSON-stringifies each value individually, so we parse each element back.\n // Single embed gets unwrapped to a plain value; batch embedMany stays as a JSON array.\n if (Array.isArray(attributes[AI_VALUES_ATTRIBUTE])) {\n const parsed = (attributes[AI_VALUES_ATTRIBUTE] as string[]).map(v => {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n });\n attributes[GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE] = parsed.length === 1 ? parsed[0] : JSON.stringify(parsed);\n }\n\n addProviderMetadataToAttributes(attributes);\n\n // Change attributes namespaced with `ai.X` to `vercel.ai.X`\n for (const key of Object.keys(attributes)) {\n if (key.startsWith('ai.')) {\n renameAttributeKey(attributes, key, `vercel.${key}`);\n }\n }\n}\n\n/**\n * Renames an attribute key in the provided attributes object if the old key exists.\n * This function safely handles null and undefined values.\n */\nfunction renameAttributeKey(attributes: Record<string, unknown>, oldKey: string, newKey: string): void {\n if (attributes[oldKey] != null) {\n attributes[newKey] = attributes[oldKey];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete attributes[oldKey];\n }\n}\n\nfunction processToolCallSpan(span: Span, attributes: SpanAttributes): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'gen_ai.execute_tool');\n span.setAttribute(GEN_AI_OPERATION_NAME_ATTRIBUTE, 'execute_tool');\n renameAttributeKey(attributes, AI_TOOL_CALL_NAME_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE);\n renameAttributeKey(attributes, AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE);\n\n // Store the span context in our global map using the tool call ID.\n // This allows us to capture tool errors and link them to the correct span\n // without retaining the full Span object in memory.\n const toolCallId = attributes[GEN_AI_TOOL_CALL_ID_ATTRIBUTE];\n\n if (typeof toolCallId === 'string') {\n toolCallSpanContextMap.set(toolCallId, span.spanContext());\n }\n\n // https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/#gen-ai-tool-type\n if (!attributes[GEN_AI_TOOL_TYPE_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_TOOL_TYPE_ATTRIBUTE, 'function');\n }\n const toolName = attributes[GEN_AI_TOOL_NAME_ATTRIBUTE];\n if (toolName) {\n span.updateName(`execute_tool ${toolName}`);\n }\n}\n\nfunction processGenerateSpan(span: Span, name: string, attributes: SpanAttributes, enableTruncation: boolean): void {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.vercelai.otel');\n\n const nameWthoutAi = name.replace('ai.', '');\n span.setAttribute('ai.pipeline.name', nameWthoutAi);\n span.updateName(nameWthoutAi);\n\n const functionId = attributes[AI_TELEMETRY_FUNCTION_ID_ATTRIBUTE];\n if (functionId && typeof functionId === 'string') {\n span.setAttribute('gen_ai.function_id', functionId);\n }\n\n requestMessagesFromPrompt(span, attributes, enableTruncation);\n\n if (attributes[AI_MODEL_ID_ATTRIBUTE] && !attributes[GEN_AI_RESPONSE_MODEL_ATTRIBUTE]) {\n span.setAttribute(GEN_AI_RESPONSE_MODEL_ATTRIBUTE, attributes[AI_MODEL_ID_ATTRIBUTE]);\n }\n span.setAttribute('ai.streaming', name.includes('stream'));\n\n // Set the op based on the operation name registry\n const operationName = SPAN_TO_OPERATION_NAME.get(name);\n if (operationName) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `gen_ai.${operationName}`);\n } else if (name.startsWith('ai.stream')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run');\n }\n\n // For invoke_agent pipeline spans, use 'invoke_agent' as the description\n // to be consistent with other AI integrations (e.g. LangGraph)\n if (operationName === 'invoke_agent') {\n if (functionId && typeof functionId === 'string') {\n span.updateName(`invoke_agent ${functionId}`);\n } else {\n span.updateName('invoke_agent');\n }\n return;\n }\n\n const modelId = attributes[AI_MODEL_ID_ATTRIBUTE];\n if (modelId && operationName) {\n span.updateName(`${operationName} ${modelId}`);\n }\n}\n\n/**\n * Add event processors to the given client to process Vercel AI spans.\n */\nexport function addVercelAiProcessors(client: Client): void {\n client.on('spanStart', onVercelAiSpanStart);\n // Note: We cannot do this on `spanEnd`, because the span cannot be mutated anymore at this point\n client.addEventProcessor(Object.assign(vercelAiEventProcessor, { id: 'VercelAiEventProcessor' }));\n}\n\nfunction addProviderMetadataToAttributes(attributes: SpanAttributes): void {\n const providerMetadata = attributes[AI_RESPONSE_PROVIDER_METADATA_ATTRIBUTE] as string | undefined;\n if (providerMetadata) {\n try {\n const providerMetadataObject = JSON.parse(providerMetadata) as ProviderMetadata;\n\n // Handle OpenAI metadata (v5 uses 'openai', v6 Azure Responses API uses 'azure')\n const openaiMetadata: OpenAiProviderMetadata | undefined =\n providerMetadataObject.openai ?? providerMetadataObject.azure;\n if (openaiMetadata) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n openaiMetadata.cachedPromptTokens,\n );\n setAttributeIfDefined(attributes, 'gen_ai.usage.output_tokens.reasoning', openaiMetadata.reasoningTokens);\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_accepted',\n openaiMetadata.acceptedPredictionTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.output_tokens.prediction_rejected',\n openaiMetadata.rejectedPredictionTokens,\n );\n if (!attributes['gen_ai.conversation.id']) {\n setAttributeIfDefined(attributes, 'gen_ai.conversation.id', openaiMetadata.responseId);\n }\n }\n\n if (providerMetadataObject.anthropic) {\n const cachedInputTokens =\n providerMetadataObject.anthropic.usage?.cache_read_input_tokens ??\n providerMetadataObject.anthropic.cacheReadInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, cachedInputTokens);\n\n const cacheWriteInputTokens =\n providerMetadataObject.anthropic.usage?.cache_creation_input_tokens ??\n providerMetadataObject.anthropic.cacheCreationInputTokens;\n setAttributeIfDefined(attributes, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, cacheWriteInputTokens);\n }\n\n if (providerMetadataObject.bedrock?.usage) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheReadInputTokens,\n );\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE,\n providerMetadataObject.bedrock.usage.cacheWriteInputTokens,\n );\n }\n\n if (providerMetadataObject.deepseek) {\n setAttributeIfDefined(\n attributes,\n GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE,\n providerMetadataObject.deepseek.promptCacheHitTokens,\n );\n setAttributeIfDefined(\n attributes,\n 'gen_ai.usage.input_tokens.cache_miss',\n providerMetadataObject.deepseek.promptCacheMissTokens,\n );\n }\n } catch {\n // Ignore\n }\n }\n}\n\n/**\n * Sets an attribute only if the value is not null or undefined.\n */\nfunction setAttributeIfDefined(attributes: SpanAttributes, key: string, value: SpanAttributeValue | undefined): void {\n if (value != null) {\n attributes[key] = value;\n }\n}\n"],"names":[],"mappings":"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"}
package/build/esm/trpc.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { getClient, withIsolationScope } from './currentScopes.js';
2
2
  import { captureException } from './exports.js';
3
3
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes.js';
4
- import { addNonEnumerableProperty } from './utils/object.js';
5
4
  import { normalize } from './utils/normalize.js';
6
5
  import { startSpanManual } from './tracing/trace.js';
6
+ import { setNormalizationDepthOverrideHint } from './utils/normalizationHints.js';
7
7
 
8
8
  const trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };
9
9
 
@@ -37,9 +37,8 @@ function trpcMiddleware(options = {}) {
37
37
  procedure_type: type,
38
38
  };
39
39
 
40
- addNonEnumerableProperty(
40
+ setNormalizationDepthOverrideHint(
41
41
  trpcContext,
42
- '__sentry_override_normalization_depth__',
43
42
  1 + // 1 for context.input + the normal normalization depth
44
43
  (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth
45
44
  );
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.js","sources":["../../src/trpc.ts"],"sourcesContent":["import { getClient, withIsolationScope } from './currentScopes';\nimport { captureException } from './exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport { startSpanManual } from './tracing';\nimport { normalize } from './utils/normalize';\nimport { addNonEnumerableProperty } from './utils/object';\n\ninterface SentryTrpcMiddlewareOptions {\n /** Whether to include procedure inputs in reported events. Defaults to `false`. */\n attachRpcInput?: boolean;\n forceTransaction?: boolean;\n}\n\nexport interface SentryTrpcMiddlewareArguments<T> {\n path?: unknown;\n type?: unknown;\n next: () => T;\n rawInput?: unknown;\n getRawInput?: () => Promise<unknown>;\n}\n\nconst trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };\n\nfunction captureIfError(nextResult: unknown): void {\n // TODO: Set span status based on what TRPCError was encountered\n if (\n typeof nextResult === 'object' &&\n nextResult !== null &&\n 'ok' in nextResult &&\n !nextResult.ok &&\n 'error' in nextResult\n ) {\n captureException(nextResult.error, trpcCaptureContext);\n }\n}\n\ntype SentryTrpcMiddleware<T> = T extends Promise<unknown> ? T : Promise<T>;\n\n/**\n * Sentry tRPC middleware that captures errors and creates spans for tRPC procedures.\n */\nexport function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return async function <T>(opts: SentryTrpcMiddlewareArguments<T>): SentryTrpcMiddleware<T> {\n const { path, type, next, rawInput, getRawInput } = opts;\n\n const client = getClient();\n const clientOptions = client?.getOptions();\n\n const trpcContext: Record<string, unknown> = {\n procedure_path: path,\n procedure_type: type,\n };\n\n addNonEnumerableProperty(\n trpcContext,\n '__sentry_override_normalization_depth__',\n 1 + // 1 for context.input + the normal normalization depth\n (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth\n );\n\n if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {\n if (rawInput !== undefined) {\n trpcContext.input = normalize(rawInput);\n }\n\n if (getRawInput !== undefined && typeof getRawInput === 'function') {\n try {\n const rawRes = await getRawInput();\n\n trpcContext.input = normalize(rawRes);\n } catch {\n // noop\n }\n }\n }\n\n return withIsolationScope(scope => {\n scope.setContext('trpc', trpcContext);\n return startSpanManual(\n {\n name: `trpc/${path}`,\n op: 'rpc.server',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.rpc.trpc',\n },\n forceTransaction: !!options.forceTransaction,\n },\n async span => {\n try {\n const nextResult = await next();\n captureIfError(nextResult);\n span.end();\n return nextResult;\n } catch (e) {\n captureException(e, trpcCaptureContext);\n span.end();\n throw e;\n }\n },\n ) as SentryTrpcMiddleware<T>;\n });\n };\n}\n"],"names":[],"mappings":";;;;;;;AAqBA,MAAM,kBAAA,GAAqB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,0BAAA,IAA8B;;AAE9F,SAAS,cAAc,CAAC,UAAU,EAAiB;AACnD;AACA,EAAE;AACF,IAAI,OAAO,UAAA,KAAe,QAAA;AAC1B,IAAI,UAAA,KAAe,IAAA;AACnB,IAAI,IAAA,IAAQ,UAAA;AACZ,IAAI,CAAC,UAAU,CAAC,EAAA;AAChB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC;AAC1D,EAAE;AACF;;AAIA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,GAAgC,EAAE,EAAE;AAC1E;AACA;AACA,EAAE,OAAO,gBAAmB,IAAI,EAA6D;AAC7F,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAA,EAAY,GAAI,IAAI;;AAE5D,IAAI,MAAM,MAAA,GAAS,SAAS,EAAE;AAC9B,IAAI,MAAM,aAAA,GAAgB,MAAM,EAAE,UAAU,EAAE;;AAE9C,IAAI,MAAM,WAAW,GAA4B;AACjD,MAAM,cAAc,EAAE,IAAI;AAC1B,MAAM,cAAc,EAAE,IAAI;AAC1B,KAAK;;AAEL,IAAI,wBAAwB;AAC5B,MAAM,WAAW;AACjB,MAAM,yCAAyC;AAC/C,MAAM,CAAA;AACN,SAAS,aAAa,EAAE,cAAA,IAAkB,CAAC,CAAC;AAC5C,KAAK;;AAEL,IAAI,IAAI,OAAO,CAAC,mBAAmB,SAAA,GAAY,OAAO,CAAC,cAAA,GAAiB,aAAa,EAAE,cAAc,EAAE;AACvG,MAAM,IAAI,QAAA,KAAa,SAAS,EAAE;AAClC,QAAQ,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,QAAQ,CAAC;AAC/C,MAAM;;AAEN,MAAM,IAAI,WAAA,KAAgB,SAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,EAAE;AAC1E,QAAQ,IAAI;AACZ,UAAU,MAAM,MAAA,GAAS,MAAM,WAAW,EAAE;;AAE5C,UAAU,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,MAAM,CAAC;AAC/C,QAAQ,EAAE,MAAM;AAChB;AACA,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ,IAAI,OAAO,kBAAkB,CAAC,KAAA,IAAS;AACvC,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC;AAC3C,MAAM,OAAO,eAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACA,UAAA,EAAA,EAAA,YAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,OAAA;AACA,YAAA,CAAA,gCAAA,GAAA,eAAA;AACA,WAAA;AACA,UAAA,gBAAA,EAAA,CAAA,CAAA,OAAA,CAAA,gBAAA;AACA,SAAA;AACA,QAAA,MAAA,IAAA,IAAA;AACA,UAAA,IAAA;AACA,YAAA,MAAA,UAAA,GAAA,MAAA,IAAA,EAAA;AACA,YAAA,cAAA,CAAA,UAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,OAAA,UAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,gBAAA,CAAA,CAAA,EAAA,kBAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,CAAA;AACA,EAAA,CAAA;AACA;;;;"}
1
+ {"version":3,"file":"trpc.js","sources":["../../src/trpc.ts"],"sourcesContent":["import { getClient, withIsolationScope } from './currentScopes';\nimport { captureException } from './exports';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from './semanticAttributes';\nimport { startSpanManual } from './tracing';\nimport { normalize } from './utils/normalize';\nimport { setNormalizationDepthOverrideHint } from './utils/normalizationHints';\n\ninterface SentryTrpcMiddlewareOptions {\n /** Whether to include procedure inputs in reported events. Defaults to `false`. */\n attachRpcInput?: boolean;\n forceTransaction?: boolean;\n}\n\nexport interface SentryTrpcMiddlewareArguments<T> {\n path?: unknown;\n type?: unknown;\n next: () => T;\n rawInput?: unknown;\n getRawInput?: () => Promise<unknown>;\n}\n\nconst trpcCaptureContext = { mechanism: { handled: false, type: 'auto.rpc.trpc.middleware' } };\n\nfunction captureIfError(nextResult: unknown): void {\n // TODO: Set span status based on what TRPCError was encountered\n if (\n typeof nextResult === 'object' &&\n nextResult !== null &&\n 'ok' in nextResult &&\n !nextResult.ok &&\n 'error' in nextResult\n ) {\n captureException(nextResult.error, trpcCaptureContext);\n }\n}\n\ntype SentryTrpcMiddleware<T> = T extends Promise<unknown> ? T : Promise<T>;\n\n/**\n * Sentry tRPC middleware that captures errors and creates spans for tRPC procedures.\n */\nexport function trpcMiddleware(options: SentryTrpcMiddlewareOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return async function <T>(opts: SentryTrpcMiddlewareArguments<T>): SentryTrpcMiddleware<T> {\n const { path, type, next, rawInput, getRawInput } = opts;\n\n const client = getClient();\n const clientOptions = client?.getOptions();\n\n const trpcContext: Record<string, unknown> = {\n procedure_path: path,\n procedure_type: type,\n };\n\n setNormalizationDepthOverrideHint(\n trpcContext,\n 1 + // 1 for context.input + the normal normalization depth\n (clientOptions?.normalizeDepth ?? 5), // 5 is a sane depth\n );\n\n if (options.attachRpcInput !== undefined ? options.attachRpcInput : clientOptions?.sendDefaultPii) {\n if (rawInput !== undefined) {\n trpcContext.input = normalize(rawInput);\n }\n\n if (getRawInput !== undefined && typeof getRawInput === 'function') {\n try {\n const rawRes = await getRawInput();\n\n trpcContext.input = normalize(rawRes);\n } catch {\n // noop\n }\n }\n }\n\n return withIsolationScope(scope => {\n scope.setContext('trpc', trpcContext);\n return startSpanManual(\n {\n name: `trpc/${path}`,\n op: 'rpc.server',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.rpc.trpc',\n },\n forceTransaction: !!options.forceTransaction,\n },\n async span => {\n try {\n const nextResult = await next();\n captureIfError(nextResult);\n span.end();\n return nextResult;\n } catch (e) {\n captureException(e, trpcCaptureContext);\n span.end();\n throw e;\n }\n },\n ) as SentryTrpcMiddleware<T>;\n });\n };\n}\n"],"names":[],"mappings":";;;;;;;AAqBA,MAAM,kBAAA,GAAqB,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,0BAAA,IAA8B;;AAE9F,SAAS,cAAc,CAAC,UAAU,EAAiB;AACnD;AACA,EAAE;AACF,IAAI,OAAO,UAAA,KAAe,QAAA;AAC1B,IAAI,UAAA,KAAe,IAAA;AACnB,IAAI,IAAA,IAAQ,UAAA;AACZ,IAAI,CAAC,UAAU,CAAC,EAAA;AAChB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC;AAC1D,EAAE;AACF;;AAIA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,GAAgC,EAAE,EAAE;AAC1E;AACA;AACA,EAAE,OAAO,gBAAmB,IAAI,EAA6D;AAC7F,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAA,EAAY,GAAI,IAAI;;AAE5D,IAAI,MAAM,MAAA,GAAS,SAAS,EAAE;AAC9B,IAAI,MAAM,aAAA,GAAgB,MAAM,EAAE,UAAU,EAAE;;AAE9C,IAAI,MAAM,WAAW,GAA4B;AACjD,MAAM,cAAc,EAAE,IAAI;AAC1B,MAAM,cAAc,EAAE,IAAI;AAC1B,KAAK;;AAEL,IAAI,iCAAiC;AACrC,MAAM,WAAW;AACjB,MAAM,CAAA;AACN,SAAS,aAAa,EAAE,cAAA,IAAkB,CAAC,CAAC;AAC5C,KAAK;;AAEL,IAAI,IAAI,OAAO,CAAC,mBAAmB,SAAA,GAAY,OAAO,CAAC,cAAA,GAAiB,aAAa,EAAE,cAAc,EAAE;AACvG,MAAM,IAAI,QAAA,KAAa,SAAS,EAAE;AAClC,QAAQ,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,QAAQ,CAAC;AAC/C,MAAM;;AAEN,MAAM,IAAI,WAAA,KAAgB,SAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,EAAE;AAC1E,QAAQ,IAAI;AACZ,UAAU,MAAM,MAAA,GAAS,MAAM,WAAW,EAAE;;AAE5C,UAAU,WAAW,CAAC,KAAA,GAAQ,SAAS,CAAC,MAAM,CAAC;AAC/C,QAAQ,EAAE,MAAM;AAChB;AACA,QAAQ;AACR,MAAM;AACN,IAAI;;AAEJ,IAAI,OAAO,kBAAkB,CAAC,KAAA,IAAS;AACvC,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC;AAC3C,MAAM,OAAO,eAAe;AAC5B,QAAQ;AACR,UAAU,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACA,UAAA,EAAA,EAAA,YAAA;AACA,UAAA,UAAA,EAAA;AACA,YAAA,CAAA,gCAAA,GAAA,OAAA;AACA,YAAA,CAAA,gCAAA,GAAA,eAAA;AACA,WAAA;AACA,UAAA,gBAAA,EAAA,CAAA,CAAA,OAAA,CAAA,gBAAA;AACA,SAAA;AACA,QAAA,MAAA,IAAA,IAAA;AACA,UAAA,IAAA;AACA,YAAA,MAAA,UAAA,GAAA,MAAA,IAAA,EAAA;AACA,YAAA,cAAA,CAAA,UAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,OAAA,UAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,gBAAA,CAAA,CAAA,EAAA,kBAAA,CAAA;AACA,YAAA,IAAA,CAAA,GAAA,EAAA;AACA,YAAA,MAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA,CAAA;AACA,EAAA,CAAA;AACA;;;;"}
@@ -30,7 +30,15 @@ function checkDsn(url, dsn) {
30
30
  return false;
31
31
  }
32
32
 
33
- return dsn ? urlParts.host.includes(dsn.host) && /(^|&|\?)sentry_key=/.test(urlParts.search) : false;
33
+ if (!dsn) {
34
+ return false;
35
+ }
36
+
37
+ return hostnameMatchesDsnHost(urlParts.hostname, dsn.host) && /(^|&|\?)sentry_key=/.test(urlParts.search);
38
+ }
39
+
40
+ function hostnameMatchesDsnHost(hostname, dsnHost) {
41
+ return hostname === dsnHost || (dsnHost.length > 0 && hostname.endsWith(`.${dsnHost}`));
34
42
  }
35
43
 
36
44
  function removeTrailingSlash(str) {
@@ -1 +1 @@
1
- {"version":3,"file":"isSentryRequestUrl.js","sources":["../../../src/utils/isSentryRequestUrl.ts"],"sourcesContent":["import type { Client } from '../client';\nimport type { DsnComponents } from '../types-hoist/dsn';\nimport { isURLObjectRelative, parseStringToURLObject } from './url';\n\n/**\n * Checks whether given url points to Sentry server\n *\n * @param url url to verify\n */\nexport function isSentryRequestUrl(url: string, client: Client | undefined): boolean {\n const dsn = client?.getDsn();\n const tunnel = client?.getOptions().tunnel;\n return checkDsn(url, dsn) || checkTunnel(url, tunnel);\n}\n\nfunction checkTunnel(url: string, tunnel: string | undefined): boolean {\n if (!tunnel) {\n return false;\n }\n\n return removeTrailingSlash(url) === removeTrailingSlash(tunnel);\n}\n\nfunction checkDsn(url: string, dsn: DsnComponents | undefined): boolean {\n // Requests to Sentry's ingest endpoint must have a `sentry_key` in the query string\n // This is equivalent to the public_key which is required in the DSN\n // see https://develop.sentry.dev/sdk/overview/#parsing-the-dsn\n // Therefore, a request to the same host and with a `sentry_key` in the query string\n // can be considered a request to the ingest endpoint.\n const urlParts = parseStringToURLObject(url);\n if (!urlParts || isURLObjectRelative(urlParts)) {\n return false;\n }\n\n return dsn ? urlParts.host.includes(dsn.host) && /(^|&|\\?)sentry_key=/.test(urlParts.search) : false;\n}\n\nfunction removeTrailingSlash(str: string): string {\n return str[str.length - 1] === '/' ? str.slice(0, -1) : str;\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,GAAG,EAAU,MAAM,EAA+B;AACrF,EAAE,MAAM,GAAA,GAAM,MAAM,EAAE,MAAM,EAAE;AAC9B,EAAE,MAAM,SAAS,MAAM,EAAE,UAAU,EAAE,CAAC,MAAM;AAC5C,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA,IAAK,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC;AACvD;;AAEA,SAAS,WAAW,CAAC,GAAG,EAAU,MAAM,EAA+B;AACvE,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,OAAO,mBAAmB,CAAC,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC;AACjE;;AAEA,SAAS,QAAQ,CAAC,GAAG,EAAU,GAAG,EAAsC;AACxE;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,QAAA,GAAW,sBAAsB,CAAC,GAAG,CAAC;AAC9C,EAAE,IAAI,CAAC,QAAA,IAAY,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAClD,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAA,IAAK,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA,GAAI,KAAK;AACtG;;AAEA,SAAS,mBAAmB,CAAC,GAAG,EAAkB;AAClD,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,MAAA,GAAS,CAAC,CAAA,KAAM,GAAA,GAAM,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAA,GAAI,GAAG;AAC7D;;;;"}
1
+ {"version":3,"file":"isSentryRequestUrl.js","sources":["../../../src/utils/isSentryRequestUrl.ts"],"sourcesContent":["import type { Client } from '../client';\nimport type { DsnComponents } from '../types-hoist/dsn';\nimport { isURLObjectRelative, parseStringToURLObject } from './url';\n\n/**\n * Checks whether given url points to Sentry server\n *\n * @param url url to verify\n */\nexport function isSentryRequestUrl(url: string, client: Client | undefined): boolean {\n const dsn = client?.getDsn();\n const tunnel = client?.getOptions().tunnel;\n return checkDsn(url, dsn) || checkTunnel(url, tunnel);\n}\n\nfunction checkTunnel(url: string, tunnel: string | undefined): boolean {\n if (!tunnel) {\n return false;\n }\n\n return removeTrailingSlash(url) === removeTrailingSlash(tunnel);\n}\n\nfunction checkDsn(url: string, dsn: DsnComponents | undefined): boolean {\n // Requests to Sentry's ingest endpoint must have a `sentry_key` in the query string\n // This is equivalent to the public_key which is required in the DSN\n // see https://develop.sentry.dev/sdk/overview/#parsing-the-dsn\n // Therefore, a request to the same host and with a `sentry_key` in the query string\n // can be considered a request to the ingest endpoint.\n const urlParts = parseStringToURLObject(url);\n if (!urlParts || isURLObjectRelative(urlParts)) {\n return false;\n }\n\n if (!dsn) {\n return false;\n }\n\n return hostnameMatchesDsnHost(urlParts.hostname, dsn.host) && /(^|&|\\?)sentry_key=/.test(urlParts.search);\n}\n\nfunction hostnameMatchesDsnHost(hostname: string, dsnHost: string): boolean {\n return hostname === dsnHost || (dsnHost.length > 0 && hostname.endsWith(`.${dsnHost}`));\n}\n\nfunction removeTrailingSlash(str: string): string {\n return str[str.length - 1] === '/' ? str.slice(0, -1) : str;\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,GAAG,EAAU,MAAM,EAA+B;AACrF,EAAE,MAAM,GAAA,GAAM,MAAM,EAAE,MAAM,EAAE;AAC9B,EAAE,MAAM,SAAS,MAAM,EAAE,UAAU,EAAE,CAAC,MAAM;AAC5C,EAAE,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA,IAAK,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC;AACvD;;AAEA,SAAS,WAAW,CAAC,GAAG,EAAU,MAAM,EAA+B;AACvE,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,OAAO,mBAAmB,CAAC,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC;AACjE;;AAEA,SAAS,QAAQ,CAAC,GAAG,EAAU,GAAG,EAAsC;AACxE;AACA;AACA;AACA;AACA;AACA,EAAE,MAAM,QAAA,GAAW,sBAAsB,CAAC,GAAG,CAAC;AAC9C,EAAE,IAAI,CAAC,QAAA,IAAY,mBAAmB,CAAC,QAAQ,CAAC,EAAE;AAClD,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,IAAI,CAAC,GAAG,EAAE;AACZ,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,OAAO,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAA,IAAK,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC3G;;AAEA,SAAS,sBAAsB,CAAC,QAAQ,EAAU,OAAO,EAAmB;AAC5E,EAAE,OAAO,aAAa,OAAA,KAAY,OAAO,CAAC,MAAA,GAAS,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA,CAAA,CAAA;AACA;;AAEA,SAAA,mBAAA,CAAA,GAAA,EAAA;AACA,EAAA,OAAA,GAAA,CAAA,GAAA,CAAA,MAAA,GAAA,CAAA,CAAA,KAAA,GAAA,GAAA,GAAA,CAAA,KAAA,CAAA,CAAA,EAAA,EAAA,CAAA,GAAA,GAAA;AACA;;;;"}
@@ -0,0 +1,33 @@
1
+ import { addNonEnumerableProperty } from './object.js';
2
+
3
+ /**
4
+ * Internal symbols for normalization behavior. JSON and other structured user payloads cannot
5
+ * carry these keys, so they cannot spoof SDK-only normalization hints.
6
+ * We use Symbol.for to ensure that the symbols are the same across different modules/files.
7
+ */
8
+ const SENTRY_SKIP_NORMALIZATION = Symbol.for('sentry.skipNormalization');
9
+ const SENTRY_OVERRIDE_NORMALIZATION_DEPTH = Symbol.for('sentry.overrideNormalizationDepth');
10
+
11
+ /** Marks an object so `normalize` returns it unchanged (already-normalized SDK data). */
12
+ function setSkipNormalizationHint(obj) {
13
+ addNonEnumerableProperty(obj, SENTRY_SKIP_NORMALIZATION, true);
14
+ }
15
+
16
+ /** Overrides remaining normalization depth from this object downward (e.g. Redux / Pinia state). */
17
+ function setNormalizationDepthOverrideHint(obj, depth) {
18
+ addNonEnumerableProperty(obj, SENTRY_OVERRIDE_NORMALIZATION_DEPTH, depth);
19
+ }
20
+
21
+ /** @internal */
22
+ function hasSkipNormalizationHint(value) {
23
+ return Boolean((value )[SENTRY_SKIP_NORMALIZATION]);
24
+ }
25
+
26
+ /** @internal */
27
+ function getNormalizationDepthOverrideHint(value) {
28
+ const v = (value )[SENTRY_OVERRIDE_NORMALIZATION_DEPTH];
29
+ return typeof v === 'number' ? v : undefined;
30
+ }
31
+
32
+ export { getNormalizationDepthOverrideHint, hasSkipNormalizationHint, setNormalizationDepthOverrideHint, setSkipNormalizationHint };
33
+ //# sourceMappingURL=normalizationHints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizationHints.js","sources":["../../../src/utils/normalizationHints.ts"],"sourcesContent":["import { addNonEnumerableProperty } from './object';\n\n/**\n * Internal symbols for normalization behavior. JSON and other structured user payloads cannot\n * carry these keys, so they cannot spoof SDK-only normalization hints.\n * We use Symbol.for to ensure that the symbols are the same across different modules/files.\n */\nconst SENTRY_SKIP_NORMALIZATION = Symbol.for('sentry.skipNormalization');\nconst SENTRY_OVERRIDE_NORMALIZATION_DEPTH = Symbol.for('sentry.overrideNormalizationDepth');\n\n/** Marks an object so `normalize` returns it unchanged (already-normalized SDK data). */\nexport function setSkipNormalizationHint(obj: object): void {\n addNonEnumerableProperty(obj, SENTRY_SKIP_NORMALIZATION, true);\n}\n\n/** Overrides remaining normalization depth from this object downward (e.g. Redux / Pinia state). */\nexport function setNormalizationDepthOverrideHint(obj: object, depth: number): void {\n addNonEnumerableProperty(obj, SENTRY_OVERRIDE_NORMALIZATION_DEPTH, depth);\n}\n\n/** @internal */\nexport function hasSkipNormalizationHint(value: object) {\n return Boolean((value as Record<symbol, unknown>)[SENTRY_SKIP_NORMALIZATION]);\n}\n\n/** @internal */\nexport function getNormalizationDepthOverrideHint(value: object): number | undefined {\n const v = (value as Record<symbol, unknown>)[SENTRY_OVERRIDE_NORMALIZATION_DEPTH];\n return typeof v === 'number' ? v : undefined;\n}\n"],"names":[],"mappings":";;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM,4BAA4B,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC;AACxE,MAAM,sCAAsC,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC;;AAE3F;AACO,SAAS,wBAAwB,CAAC,GAAG,EAAgB;AAC5D,EAAE,wBAAwB,CAAC,GAAG,EAAE,yBAAyB,EAAE,IAAI,CAAC;AAChE;;AAEA;AACO,SAAS,iCAAiC,CAAC,GAAG,EAAU,KAAK,EAAgB;AACpF,EAAE,wBAAwB,CAAC,GAAG,EAAE,mCAAmC,EAAE,KAAK,CAAC;AAC3E;;AAEA;AACO,SAAS,wBAAwB,CAAC,KAAK,EAAU;AACxD,EAAE,OAAO,OAAO,CAAC,CAAC,QAAkC,yBAAyB,CAAC,CAAC;AAC/E;;AAEA;AACO,SAAS,iCAAiC,CAAC,KAAK,EAA8B;AACrF,EAAE,MAAM,IAAI,CAAC,QAAkC,mCAAmC,CAAC;AACnF,EAAE,OAAO,OAAO,CAAA,KAAM,WAAW,CAAA,GAAI,SAAS;AAC9C;;;;"}
@@ -1,4 +1,5 @@
1
1
  import { isVueViewModel, isSyntheticEvent } from './is.js';
2
+ import { hasSkipNormalizationHint, getNormalizationDepthOverrideHint } from './normalizationHints.js';
2
3
  import { convertToPlainObject } from './object.js';
3
4
  import { getVueInternalName, getFunctionName } from './stacktrace.js';
4
5
 
@@ -86,20 +87,15 @@ function visit(
86
87
 
87
88
  // From here on, we can assert that `value` is either an object or an array.
88
89
 
89
- // Do not normalize objects that we know have already been normalized. As a general rule, the
90
- // "__sentry_skip_normalization__" property should only be used sparingly and only should only be set on objects that
91
- // have already been normalized.
92
- if ((value )['__sentry_skip_normalization__']) {
90
+ // Do not normalize objects that we know have already been normalized. Hints use internal symbols
91
+ // (see normalizationHints.ts) so user-controlled JSON cannot spoof them.
92
+ if (hasSkipNormalizationHint(value)) {
93
93
  return value ;
94
94
  }
95
95
 
96
- // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there
97
- // We keep a certain amount of depth.
98
- // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.
99
- const remainingDepth =
100
- typeof (value )['__sentry_override_normalization_depth__'] === 'number'
101
- ? ((value )['__sentry_override_normalization_depth__'] )
102
- : depth;
96
+ // Override remaining depth from this node (e.g. Redux / Pinia state). Set via setNormalizationDepthOverrideHint.
97
+ const overrideDepth = getNormalizationDepthOverrideHint(value);
98
+ const remainingDepth = overrideDepth !== undefined ? overrideDepth : depth;
103
99
 
104
100
  // We're also done if we've reached the max depth
105
101
  if (remainingDepth === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","sources":["../../../src/utils/normalize.ts"],"sourcesContent":["import type { Primitive } from '../types-hoist/misc';\nimport { isSyntheticEvent, isVueViewModel } from './is';\nimport { convertToPlainObject } from './object';\nimport { getFunctionName, getVueInternalName } from './stacktrace';\n\ntype Prototype = { constructor?: (...args: unknown[]) => unknown };\n// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we\n// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this\n// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them\n// might be arrays.\ntype ObjOrArray<T> = { [key: string]: T };\n\ntype MemoFunc = [\n // memoize\n (obj: object) => boolean,\n // unmemoize\n (obj: object) => void,\n];\n\n/**\n * Recursively normalizes the given object.\n *\n * - Creates a copy to prevent original input mutation\n * - Skips non-enumerable properties\n * - When stringifying, calls `toJSON` if implemented\n * - Removes circular references\n * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format\n * - Translates known global objects/classes to a string representations\n * - Takes care of `Error` object serialization\n * - Optionally limits depth of final output\n * - Optionally limits number of properties/elements included in any single object/array\n *\n * @param input The object to be normalized.\n * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)\n * @param maxProperties The max number of elements or properties to be included in any single array or\n * object in the normalized output.\n * @returns A normalized version of the object, or `\"**non-serializable**\"` if any errors are thrown during normalization.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function normalize(input: unknown, depth: number = 100, maxProperties: number = +Infinity): any {\n try {\n // since we're at the outermost level, we don't provide a key\n return visit('', input, depth, maxProperties);\n } catch (err) {\n return { ERROR: `**non-serializable** (${err})` };\n }\n}\n\n/** JSDoc */\nexport function normalizeToSize<T>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n object: { [key: string]: any },\n // Default Node.js REPL depth\n depth: number = 3,\n // 100kB, as 200kB is max payload size, so half sounds reasonable\n maxSize: number = 100 * 1024,\n): T {\n const normalized = normalize(object, depth);\n\n if (jsonSize(normalized) > maxSize) {\n return normalizeToSize(object, depth - 1, maxSize);\n }\n\n return normalized as T;\n}\n\n/**\n * Visits a node to perform normalization on it\n *\n * @param key The key corresponding to the given node\n * @param value The node to be visited\n * @param depth Optional number indicating the maximum recursion depth\n * @param maxProperties Optional maximum number of properties/elements included in any single object/array\n * @param memo Optional Memo class handling decycling\n */\nfunction visit(\n key: string,\n value: unknown,\n depth: number = +Infinity,\n maxProperties: number = +Infinity,\n memo = memoBuilder(),\n): Primitive | ObjOrArray<unknown> {\n const [memoize, unmemoize] = memo;\n\n // Get the simple cases out of the way first\n if (\n value == null || // this matches null and undefined -> eqeq not eqeqeq\n ['boolean', 'string'].includes(typeof value) ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n return value as Primitive;\n }\n\n const stringified = stringifyValue(key, value);\n\n // Anything we could potentially dig into more (objects or arrays) will have come back as `\"[object XXXX]\"`.\n // Everything else will have already been serialized, so if we don't see that pattern, we're done.\n if (!stringified.startsWith('[object ')) {\n return stringified;\n }\n\n // From here on, we can assert that `value` is either an object or an array.\n\n // Do not normalize objects that we know have already been normalized. As a general rule, the\n // \"__sentry_skip_normalization__\" property should only be used sparingly and only should only be set on objects that\n // have already been normalized.\n if ((value as ObjOrArray<unknown>)['__sentry_skip_normalization__']) {\n return value as ObjOrArray<unknown>;\n }\n\n // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there\n // We keep a certain amount of depth.\n // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.\n const remainingDepth =\n typeof (value as ObjOrArray<unknown>)['__sentry_override_normalization_depth__'] === 'number'\n ? ((value as ObjOrArray<unknown>)['__sentry_override_normalization_depth__'] as number)\n : depth;\n\n // We're also done if we've reached the max depth\n if (remainingDepth === 0) {\n // At this point we know `serialized` is a string of the form `\"[object XXXX]\"`. Clean it up so it's just `\"[XXXX]\"`.\n return stringified.replace('object ', '');\n }\n\n // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.\n if (memoize(value)) {\n return '[Circular ~]';\n }\n\n // If the value has a `toJSON` method, we call it to extract more information\n const valueWithToJSON = value as unknown & { toJSON?: () => unknown };\n if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {\n try {\n const jsonValue = valueWithToJSON.toJSON();\n // We need to normalize the return value of `.toJSON()` in case it has circular references\n return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);\n } catch {\n // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)\n }\n }\n\n // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse\n // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each\n // property/entry, and keep track of the number of items we add to it.\n const normalized = (Array.isArray(value) ? [] : {}) as ObjOrArray<unknown>;\n let numAdded = 0;\n\n // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant\n // properties are non-enumerable and otherwise would get missed.\n const visitable = convertToPlainObject(value as ObjOrArray<unknown>);\n\n for (const visitKey in visitable) {\n // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.\n if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {\n continue;\n }\n\n if (numAdded >= maxProperties) {\n normalized[visitKey] = '[MaxProperties ~]';\n break;\n }\n\n // Recursively visit all the child nodes\n const visitValue = visitable[visitKey];\n normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);\n\n numAdded++;\n }\n\n // Once we've visited all the branches, remove the parent from memo storage\n unmemoize(value);\n\n // Return accumulated values\n return normalized;\n}\n\n/* eslint-disable complexity */\n/**\n * Stringify the given value. Handles various known special values and types.\n *\n * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn\n * the number 1231 into \"[Object Number]\", nor on `null`, as it will throw.\n *\n * @param value The value to stringify\n * @returns A stringified representation of the given value\n */\nfunction stringifyValue(\n key: unknown,\n // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for\n // our internal use, it'll do\n value: Exclude<unknown, string | number | boolean | null>,\n): string {\n try {\n if (key === 'domain' && value && typeof value === 'object' && (value as { _events: unknown })._events) {\n return '[Domain]';\n }\n\n if (key === 'domainEmitter') {\n return '[DomainEmitter]';\n }\n\n // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first\n // which won't throw if they are not present.\n\n if (typeof global !== 'undefined' && value === global) {\n return '[Global]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof window !== 'undefined' && value === window) {\n return '[Window]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof document !== 'undefined' && value === document) {\n return '[Document]';\n }\n\n if (isVueViewModel(value)) {\n return getVueInternalName(value);\n }\n\n // React's SyntheticEvent thingy\n if (isSyntheticEvent(value)) {\n return '[SyntheticEvent]';\n }\n\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return `[${value}]`;\n }\n\n if (typeof value === 'function') {\n return `[Function: ${getFunctionName(value)}]`;\n }\n\n if (typeof value === 'symbol') {\n return `[${String(value)}]`;\n }\n\n // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion\n if (typeof value === 'bigint') {\n return `[BigInt: ${String(value)}]`;\n }\n\n // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting\n // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as\n // `\"[object Object]\"`. If we instead look at the constructor's name (which is the same as the name of the class),\n // we can make sure that only plain objects come out that way.\n const objName = getConstructorName(value);\n\n // Handle HTML Elements\n if (/^HTML(\\w*)Element$/.test(objName)) {\n return `[HTMLElement: ${objName}]`;\n }\n\n return `[object ${objName}]`;\n } catch (err) {\n return `**non-serializable** (${err})`;\n }\n}\n/* eslint-enable complexity */\n\nfunction getConstructorName(value: unknown): string {\n const prototype: Prototype | null = Object.getPrototypeOf(value);\n\n return prototype?.constructor ? prototype.constructor.name : 'null prototype';\n}\n\n/** Calculates bytes size of input string */\nfunction utf8Length(value: string): number {\n // eslint-disable-next-line no-bitwise\n return ~-encodeURI(value).split(/%..|./).length;\n}\n\n/** Calculates bytes size of input object */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSize(value: any): number {\n return utf8Length(JSON.stringify(value));\n}\n\n/**\n * Normalizes URLs in exceptions and stacktraces to a base path so Sentry can fingerprint\n * across platforms and working directory.\n *\n * @param url The URL to be normalized.\n * @param basePath The application base path.\n * @returns The normalized URL.\n */\nexport function normalizeUrlToBase(url: string, basePath: string): string {\n const escapedBase = basePath\n // Backslash to forward\n .replace(/\\\\/g, '/')\n // Escape RegExp special characters\n .replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');\n\n let newUrl = url;\n try {\n newUrl = decodeURI(url);\n } catch {\n // Sometime this breaks\n }\n return (\n newUrl\n .replace(/\\\\/g, '/')\n .replace(/webpack:\\/?/g, '') // Remove intermediate base path\n // oxlint-disable-next-line sdk/no-regexp-constructor\n .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///')\n );\n}\n\n/**\n * Helper to decycle json objects\n */\nfunction memoBuilder(): MemoFunc {\n const inner = new WeakSet<object>();\n function memoize(obj: object): boolean {\n if (inner.has(obj)) {\n return true;\n }\n inner.add(obj);\n return false;\n }\n\n function unmemoize(obj: object): void {\n inner.delete(obj);\n }\n return [memoize, unmemoize];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"normalize.js","sources":["../../../src/utils/normalize.ts"],"sourcesContent":["import type { Primitive } from '../types-hoist/misc';\nimport { isSyntheticEvent, isVueViewModel } from './is';\nimport { getNormalizationDepthOverrideHint, hasSkipNormalizationHint } from './normalizationHints';\nimport { convertToPlainObject } from './object';\nimport { getFunctionName, getVueInternalName } from './stacktrace';\n\ntype Prototype = { constructor?: (...args: unknown[]) => unknown };\n// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we\n// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this\n// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them\n// might be arrays.\ntype ObjOrArray<T> = { [key: string]: T };\n\ntype MemoFunc = [\n // memoize\n (obj: object) => boolean,\n // unmemoize\n (obj: object) => void,\n];\n\n/**\n * Recursively normalizes the given object.\n *\n * - Creates a copy to prevent original input mutation\n * - Skips non-enumerable properties\n * - When stringifying, calls `toJSON` if implemented\n * - Removes circular references\n * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format\n * - Translates known global objects/classes to a string representations\n * - Takes care of `Error` object serialization\n * - Optionally limits depth of final output\n * - Optionally limits number of properties/elements included in any single object/array\n *\n * @param input The object to be normalized.\n * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)\n * @param maxProperties The max number of elements or properties to be included in any single array or\n * object in the normalized output.\n * @returns A normalized version of the object, or `\"**non-serializable**\"` if any errors are thrown during normalization.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function normalize(input: unknown, depth: number = 100, maxProperties: number = +Infinity): any {\n try {\n // since we're at the outermost level, we don't provide a key\n return visit('', input, depth, maxProperties);\n } catch (err) {\n return { ERROR: `**non-serializable** (${err})` };\n }\n}\n\n/** JSDoc */\nexport function normalizeToSize<T>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n object: { [key: string]: any },\n // Default Node.js REPL depth\n depth: number = 3,\n // 100kB, as 200kB is max payload size, so half sounds reasonable\n maxSize: number = 100 * 1024,\n): T {\n const normalized = normalize(object, depth);\n\n if (jsonSize(normalized) > maxSize) {\n return normalizeToSize(object, depth - 1, maxSize);\n }\n\n return normalized as T;\n}\n\n/**\n * Visits a node to perform normalization on it\n *\n * @param key The key corresponding to the given node\n * @param value The node to be visited\n * @param depth Optional number indicating the maximum recursion depth\n * @param maxProperties Optional maximum number of properties/elements included in any single object/array\n * @param memo Optional Memo class handling decycling\n */\nfunction visit(\n key: string,\n value: unknown,\n depth: number = +Infinity,\n maxProperties: number = +Infinity,\n memo = memoBuilder(),\n): Primitive | ObjOrArray<unknown> {\n const [memoize, unmemoize] = memo;\n\n // Get the simple cases out of the way first\n if (\n value == null || // this matches null and undefined -> eqeq not eqeqeq\n ['boolean', 'string'].includes(typeof value) ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n return value as Primitive;\n }\n\n const stringified = stringifyValue(key, value);\n\n // Anything we could potentially dig into more (objects or arrays) will have come back as `\"[object XXXX]\"`.\n // Everything else will have already been serialized, so if we don't see that pattern, we're done.\n if (!stringified.startsWith('[object ')) {\n return stringified;\n }\n\n // From here on, we can assert that `value` is either an object or an array.\n\n // Do not normalize objects that we know have already been normalized. Hints use internal symbols\n // (see normalizationHints.ts) so user-controlled JSON cannot spoof them.\n if (hasSkipNormalizationHint(value)) {\n return value as ObjOrArray<unknown>;\n }\n\n // Override remaining depth from this node (e.g. Redux / Pinia state). Set via setNormalizationDepthOverrideHint.\n const overrideDepth = getNormalizationDepthOverrideHint(value);\n const remainingDepth = overrideDepth !== undefined ? overrideDepth : depth;\n\n // We're also done if we've reached the max depth\n if (remainingDepth === 0) {\n // At this point we know `serialized` is a string of the form `\"[object XXXX]\"`. Clean it up so it's just `\"[XXXX]\"`.\n return stringified.replace('object ', '');\n }\n\n // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.\n if (memoize(value)) {\n return '[Circular ~]';\n }\n\n // If the value has a `toJSON` method, we call it to extract more information\n const valueWithToJSON = value as unknown & { toJSON?: () => unknown };\n if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {\n try {\n const jsonValue = valueWithToJSON.toJSON();\n // We need to normalize the return value of `.toJSON()` in case it has circular references\n return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);\n } catch {\n // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)\n }\n }\n\n // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse\n // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each\n // property/entry, and keep track of the number of items we add to it.\n const normalized = (Array.isArray(value) ? [] : {}) as ObjOrArray<unknown>;\n let numAdded = 0;\n\n // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant\n // properties are non-enumerable and otherwise would get missed.\n const visitable = convertToPlainObject(value as ObjOrArray<unknown>);\n\n for (const visitKey in visitable) {\n // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.\n if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {\n continue;\n }\n\n if (numAdded >= maxProperties) {\n normalized[visitKey] = '[MaxProperties ~]';\n break;\n }\n\n // Recursively visit all the child nodes\n const visitValue = visitable[visitKey];\n normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);\n\n numAdded++;\n }\n\n // Once we've visited all the branches, remove the parent from memo storage\n unmemoize(value);\n\n // Return accumulated values\n return normalized;\n}\n\n/* eslint-disable complexity */\n/**\n * Stringify the given value. Handles various known special values and types.\n *\n * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn\n * the number 1231 into \"[Object Number]\", nor on `null`, as it will throw.\n *\n * @param value The value to stringify\n * @returns A stringified representation of the given value\n */\nfunction stringifyValue(\n key: unknown,\n // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for\n // our internal use, it'll do\n value: Exclude<unknown, string | number | boolean | null>,\n): string {\n try {\n if (key === 'domain' && value && typeof value === 'object' && (value as { _events: unknown })._events) {\n return '[Domain]';\n }\n\n if (key === 'domainEmitter') {\n return '[DomainEmitter]';\n }\n\n // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first\n // which won't throw if they are not present.\n\n if (typeof global !== 'undefined' && value === global) {\n return '[Global]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof window !== 'undefined' && value === window) {\n return '[Window]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof document !== 'undefined' && value === document) {\n return '[Document]';\n }\n\n if (isVueViewModel(value)) {\n return getVueInternalName(value);\n }\n\n // React's SyntheticEvent thingy\n if (isSyntheticEvent(value)) {\n return '[SyntheticEvent]';\n }\n\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return `[${value}]`;\n }\n\n if (typeof value === 'function') {\n return `[Function: ${getFunctionName(value)}]`;\n }\n\n if (typeof value === 'symbol') {\n return `[${String(value)}]`;\n }\n\n // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion\n if (typeof value === 'bigint') {\n return `[BigInt: ${String(value)}]`;\n }\n\n // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting\n // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as\n // `\"[object Object]\"`. If we instead look at the constructor's name (which is the same as the name of the class),\n // we can make sure that only plain objects come out that way.\n const objName = getConstructorName(value);\n\n // Handle HTML Elements\n if (/^HTML(\\w*)Element$/.test(objName)) {\n return `[HTMLElement: ${objName}]`;\n }\n\n return `[object ${objName}]`;\n } catch (err) {\n return `**non-serializable** (${err})`;\n }\n}\n/* eslint-enable complexity */\n\nfunction getConstructorName(value: unknown): string {\n const prototype: Prototype | null = Object.getPrototypeOf(value);\n\n return prototype?.constructor ? prototype.constructor.name : 'null prototype';\n}\n\n/** Calculates bytes size of input string */\nfunction utf8Length(value: string): number {\n // eslint-disable-next-line no-bitwise\n return ~-encodeURI(value).split(/%..|./).length;\n}\n\n/** Calculates bytes size of input object */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSize(value: any): number {\n return utf8Length(JSON.stringify(value));\n}\n\n/**\n * Normalizes URLs in exceptions and stacktraces to a base path so Sentry can fingerprint\n * across platforms and working directory.\n *\n * @param url The URL to be normalized.\n * @param basePath The application base path.\n * @returns The normalized URL.\n */\nexport function normalizeUrlToBase(url: string, basePath: string): string {\n const escapedBase = basePath\n // Backslash to forward\n .replace(/\\\\/g, '/')\n // Escape RegExp special characters\n .replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');\n\n let newUrl = url;\n try {\n newUrl = decodeURI(url);\n } catch {\n // Sometime this breaks\n }\n return (\n newUrl\n .replace(/\\\\/g, '/')\n .replace(/webpack:\\/?/g, '') // Remove intermediate base path\n // oxlint-disable-next-line sdk/no-regexp-constructor\n .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///')\n );\n}\n\n/**\n * Helper to decycle json objects\n */\nfunction memoBuilder(): MemoFunc {\n const inner = new WeakSet<object>();\n function memoize(obj: object): boolean {\n if (inner.has(obj)) {\n return true;\n }\n inner.add(obj);\n return false;\n }\n\n function unmemoize(obj: object): void {\n inner.delete(obj);\n }\n return [memoize, unmemoize];\n}\n"],"names":[],"mappings":";;;;;AAoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,KAAK,EAAW,KAAK,GAAW,GAAG,EAAE,aAAa,GAAW,CAAC,QAAQ,EAAO;AACvG,EAAE,IAAI;AACN;AACA,IAAI,OAAO,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC;AACjD,EAAE,CAAA,CAAE,OAAO,GAAG,EAAE;AAChB,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAA,EAAG;AACrD,EAAE;AACF;;AAEA;AACO,SAAS,eAAe;AAC/B;AACA,EAAE,MAAM;AACR;AACA,EAAE,KAAK,GAAW,CAAC;AACnB;AACA,EAAE,OAAO,GAAW,GAAA,GAAM,IAAI;AAC9B,EAAK;AACL,EAAE,MAAM,aAAa,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;;AAE7C,EAAE,IAAI,QAAQ,CAAC,UAAU,CAAA,GAAI,OAAO,EAAE;AACtC,IAAI,OAAO,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;AACtD,EAAE;;AAEF,EAAE,OAAO,UAAA;AACT;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,KAAK;AACd,EAAE,GAAG;AACL,EAAE,KAAK;AACP,EAAE,KAAK,GAAW,CAAC,QAAQ;AAC3B,EAAE,aAAa,GAAW,CAAC,QAAQ;AACnC,EAAE,IAAA,GAAO,WAAW,EAAE;AACtB,EAAmC;AACnC,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAAA,GAAI,IAAI;;AAEnC;AACA,EAAE;AACF,IAAI,KAAA,IAAS,IAAA;AACb,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAA;AAC/C,KAAK,OAAO,KAAA,KAAU,QAAA,IAAY,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxD,IAAI;AACJ,IAAI,OAAO,KAAA;AACX,EAAE;;AAEF,EAAE,MAAM,cAAc,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC;;AAEhD;AACA;AACA,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;AAC3C,IAAI,OAAO,WAAW;AACtB,EAAE;;AAEF;;AAEA;AACA;AACA,EAAE,IAAI,wBAAwB,CAAC,KAAK,CAAC,EAAE;AACvC,IAAI,OAAO,KAAA;AACX,EAAE;;AAEF;AACA,EAAE,MAAM,aAAA,GAAgB,iCAAiC,CAAC,KAAK,CAAC;AAChE,EAAE,MAAM,iBAAiB,aAAA,KAAkB,SAAA,GAAY,aAAA,GAAgB,KAAK;;AAE5E;AACA,EAAE,IAAI,cAAA,KAAmB,CAAC,EAAE;AAC5B;AACA,IAAI,OAAO,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;AAC7C,EAAE;;AAEF;AACA,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;AACtB,IAAI,OAAO,cAAc;AACzB,EAAE;;AAEF;AACA,EAAE,MAAM,eAAA,GAAkB,KAAA;AAC1B,EAAE,IAAI,eAAA,IAAmB,OAAO,eAAe,CAAC,MAAA,KAAW,UAAU,EAAE;AACvE,IAAI,IAAI;AACR,MAAM,MAAM,SAAA,GAAY,eAAe,CAAC,MAAM,EAAE;AAChD;AACA,MAAM,OAAO,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,cAAA,GAAiB,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC;AAC1E,IAAI,EAAE,MAAM;AACZ;AACA,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,EAAE,MAAM,UAAA,IAAc,KAAK,CAAC,OAAO,CAAC,KAAK,CAAA,GAAI,EAAC,GAAI,EAAE,CAAA;AACpD,EAAE,IAAI,QAAA,GAAW,CAAC;;AAElB;AACA;AACA,EAAE,MAAM,SAAA,GAAY,oBAAoB,CAAC,OAA6B;;AAEtE,EAAE,KAAK,MAAM,QAAA,IAAY,SAAS,EAAE;AACpC;AACA,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;AACpE,MAAM;AACN,IAAI;;AAEJ,IAAI,IAAI,QAAA,IAAY,aAAa,EAAE;AACnC,MAAM,UAAU,CAAC,QAAQ,CAAA,GAAI,mBAAmB;AAChD,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,MAAM,UAAA,GAAa,SAAS,CAAC,QAAQ,CAAC;AAC1C,IAAI,UAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,iBAAiB,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC;;AAE/F,IAAI,QAAQ,EAAE;AACd,EAAE;;AAEF;AACA,EAAE,SAAS,CAAC,KAAK,CAAC;;AAElB;AACA,EAAE,OAAO,UAAU;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;AACvB,EAAE,GAAG;AACL;AACA;AACA,EAAE,KAAK;AACP,EAAU;AACV,EAAE,IAAI;AACN,IAAI,IAAI,GAAA,KAAQ,QAAA,IAAY,SAAS,OAAO,KAAA,KAAU,YAAY,CAAC,QAA+B,OAAO,EAAE;AAC3G,MAAM,OAAO,UAAU;AACvB,IAAI;;AAEJ,IAAI,IAAI,GAAA,KAAQ,eAAe,EAAE;AACjC,MAAM,OAAO,iBAAiB;AAC9B,IAAI;;AAEJ;AACA;;AAEA,IAAI,IAAI,OAAO,MAAA,KAAW,eAAe,KAAA,KAAU,MAAM,EAAE;AAC3D,MAAM,OAAO,UAAU;AACvB,IAAI;;AAEJ;AACA,IAAI,IAAI,OAAO,MAAA,KAAW,eAAe,KAAA,KAAU,MAAM,EAAE;AAC3D,MAAM,OAAO,UAAU;AACvB,IAAI;;AAEJ;AACA,IAAI,IAAI,OAAO,QAAA,KAAa,eAAe,KAAA,KAAU,QAAQ,EAAE;AAC/D,MAAM,OAAO,YAAY;AACzB,IAAI;;AAEJ,IAAI,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE;AAC/B,MAAM,OAAO,kBAAkB,CAAC,KAAK,CAAC;AACtC,IAAI;;AAEJ;AACA,IAAI,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;AACjC,MAAM,OAAO,kBAAkB;AAC/B,IAAI;;AAEJ,IAAI,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC9D,MAAM,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACzB,IAAI;;AAEJ,IAAI,IAAI,OAAO,KAAA,KAAU,UAAU,EAAE;AACrC,MAAM,OAAO,CAAC,WAAW,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,IAAI;;AAEJ,IAAI,IAAI,OAAO,KAAA,KAAU,QAAQ,EAAE;AACnC,MAAM,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjC,IAAI;;AAEJ;AACA,IAAI,IAAI,OAAO,KAAA,KAAU,QAAQ,EAAE;AACnC,MAAM,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzC,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI,MAAM,OAAA,GAAU,kBAAkB,CAAC,KAAK,CAAC;;AAE7C;AACA,IAAI,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AAC5C,MAAM,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;AACxC,IAAI;;AAEJ,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAChC,EAAE,CAAA,CAAE,OAAO,GAAG,EAAE;AAChB,IAAI,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1C,EAAE;AACF;AACA;;AAEA,SAAS,kBAAkB,CAAC,KAAK,EAAmB;AACpD,EAAE,MAAM,SAAS,GAAqB,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC;;AAElE,EAAE,OAAO,SAAS,EAAE,WAAA,GAAc,SAAS,CAAC,WAAW,CAAC,IAAA,GAAO,gBAAgB;AAC/E;;AAEA;AACA,SAAS,UAAU,CAAC,KAAK,EAAkB;AAC3C;AACA,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM;AACjD;;AAEA;AACA;AACA,SAAS,QAAQ,CAAC,KAAK,EAAe;AACtC,EAAE,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,kBAAkB,CAAC,GAAG,EAAU,QAAQ,EAAkB;AAC1E,EAAE,MAAM,cAAc;AACtB;AACA,KAAK,OAAO,CAAC,KAAK,EAAE,GAAG;AACvB;AACA,KAAK,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;;AAE3C,EAAE,IAAI,MAAA,GAAS,GAAG;AAClB,EAAE,IAAI;AACN,IAAI,MAAA,GAAS,SAAS,CAAC,GAAG,CAAC;AAC3B,EAAE,EAAE,MAAM;AACV;AACA,EAAE;AACF,EAAE;AACF,IAAI;AACJ,OAAO,OAAO,CAAC,KAAK,EAAE,GAAG;AACzB,OAAO,OAAO,CAAC,cAAc,EAAE,EAAE,CAAA;AACjC;AACA,OAAO,OAAO,CAAC,IAAI,MAAM,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAC1E;AACA;;AAEA;AACA;AACA;AACA,SAAS,WAAW,GAAa;AACjC,EAAE,MAAM,KAAA,GAAQ,IAAI,OAAO,EAAU;AACrC,EAAE,SAAS,OAAO,CAAC,GAAG,EAAmB;AACzC,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACxB,MAAM,OAAO,IAAI;AACjB,IAAI;AACJ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;AAClB,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,SAAS,SAAS,CAAC,GAAG,EAAgB;AACxC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC;AACrB,EAAE;AACF,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;AAC7B;;;;"}
@@ -62,7 +62,7 @@ function addNonEnumerableProperty(obj, name, value) {
62
62
  configurable: true,
63
63
  });
64
64
  } catch {
65
- DEBUG_BUILD && debug.log(`Failed to add non-enumerable property "${name}" to object`, obj);
65
+ DEBUG_BUILD && debug.log(`Failed to add non-enumerable property "${String(name)}" to object`, obj);
66
66
  }
67
67
  }
68
68
 
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","sources":["../../../src/utils/object.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { WrappedFunction } from '../types-hoist/wrappedfunction';\nimport { htmlTreeAsString } from './browser';\nimport { debug } from './debug-logger';\nimport { isElement, isError, isEvent, isInstanceOf, isPrimitive } from './is';\n\n/**\n * Replace a method in an object with a wrapped version of itself.\n *\n * If the method on the passed object is not a function, the wrapper will not be applied.\n *\n * @param source An object that contains a method to be wrapped.\n * @param name The name of the method to be wrapped.\n * @param replacementFactory A higher-order function that takes the original version of the given method and returns a\n * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to\n * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other\n * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.\n * @returns void\n */\n\nexport function fill(source: { [key: string]: any }, name: string, replacementFactory: (...args: any[]) => any): void {\n if (!(name in source)) {\n return;\n }\n\n // explicitly casting to unknown because we don't know the type of the method initially at all\n const original = source[name] as unknown;\n\n if (typeof original !== 'function') {\n return;\n }\n\n const wrapped = replacementFactory(original) as WrappedFunction;\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n markFunctionWrapped(wrapped, original);\n }\n\n try {\n source[name] = wrapped;\n } catch {\n DEBUG_BUILD && debug.log(`Failed to replace method \"${name}\" in object`, source);\n }\n}\n\n/**\n * Defines a non-enumerable property on the given object.\n *\n * @param obj The object on which to set the property\n * @param name The name of the property to be set\n * @param value The value to which to set the property\n */\nexport function addNonEnumerableProperty(obj: object, name: string, value: unknown): void {\n try {\n Object.defineProperty(obj, name, {\n // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it\n value,\n writable: true,\n configurable: true,\n });\n } catch {\n DEBUG_BUILD && debug.log(`Failed to add non-enumerable property \"${name}\" to object`, obj);\n }\n}\n\n/**\n * Remembers the original function on the wrapped function and\n * patches up the prototype.\n *\n * @param wrapped the wrapper function\n * @param original the original function that gets wrapped\n */\nexport function markFunctionWrapped(wrapped: WrappedFunction, original: WrappedFunction): void {\n try {\n const proto = original.prototype || {};\n wrapped.prototype = original.prototype = proto;\n addNonEnumerableProperty(wrapped, '__sentry_original__', original);\n } catch {} // eslint-disable-line no-empty\n}\n\n/**\n * Wrap a method on an object by name, only if it is not already wrapped.\n *\n * Note: to set the wrapped method as a non-enumerable property, pass\n * false as the `enumerable` argument. This could be detected, but only\n * by either walking up the prototype chain, or iterating over all fields\n * in a `for(in)` loop. Neither are an acceptable performance impact for\n * the rare case where we might patch a non-enumerable method.\n */\nexport function wrapMethod<O extends {}, T extends string & keyof O>(\n obj: O,\n field: T,\n wrapped: WrappedFunction,\n enumerable: boolean = true,\n): void {\n const original = obj[field];\n if (typeof original !== 'function') {\n throw new Error(`Cannot wrap method: ${field} is not a function`);\n }\n if (getOriginalFunction(original)) {\n throw new Error(`Attempting to wrap method ${field} multiple times`);\n }\n markFunctionWrapped(wrapped, original);\n Object.defineProperty(obj, field, {\n writable: true,\n configurable: true,\n enumerable,\n value: wrapped,\n });\n}\n\n/**\n * This extracts the original function if available. See\n * `markFunctionWrapped` for more information.\n *\n * @param func the function to unwrap\n * @returns the unwrapped version of the function if available.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function getOriginalFunction<T extends Function>(func: WrappedFunction<T>): T | undefined {\n return func.__sentry_original__;\n}\n\n/**\n * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their\n * non-enumerable properties attached.\n *\n * @param value Initial source that we have to transform in order for it to be usable by the serializer\n * @returns An Event or Error turned into an object - or the value argument itself, when value is neither an Event nor\n * an Error.\n */\nexport function convertToPlainObject<V>(value: V):\n | {\n [ownProps: string]: unknown;\n type: string;\n target: string;\n currentTarget: string;\n detail?: unknown;\n }\n | {\n [ownProps: string]: unknown;\n message: string;\n name: string;\n stack?: string;\n }\n | V {\n if (isError(value)) {\n return {\n message: value.message,\n name: value.name,\n stack: value.stack,\n ...getOwnProperties(value),\n };\n } else if (isEvent(value)) {\n const newObj: {\n [ownProps: string]: unknown;\n type: string;\n target: string;\n currentTarget: string;\n detail?: unknown;\n } = {\n type: value.type,\n target: serializeEventTarget(value.target),\n currentTarget: serializeEventTarget(value.currentTarget),\n ...getOwnProperties(value),\n };\n\n if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {\n newObj.detail = value.detail;\n }\n\n return newObj;\n } else {\n return value;\n }\n}\n\n/** Creates a string representation of the target of an `Event` object */\nfunction serializeEventTarget(target: unknown): string {\n try {\n return isElement(target) ? htmlTreeAsString(target) : Object.prototype.toString.call(target);\n } catch {\n return '<unknown>';\n }\n}\n\n/** Filters out all but an object's own properties */\nfunction getOwnProperties(obj: unknown): { [key: string]: unknown } {\n if (typeof obj === 'object' && obj !== null) {\n return Object.fromEntries(Object.entries(obj));\n }\n return {};\n}\n\n/**\n * Given any captured exception, extract its keys and create a sorted\n * and truncated list that will be used inside the event message.\n * eg. `Non-error exception captured with keys: foo, bar, baz`\n */\nexport function extractExceptionKeysForMessage(exception: Record<string, unknown>): string {\n const keys = Object.keys(convertToPlainObject(exception));\n keys.sort();\n\n return !keys[0] ? '[object has no keys]' : keys.join(', ');\n}\n\n/**\n * Given any object, return a new object having removed all fields whose value was `undefined`.\n * Works recursively on objects and arrays.\n *\n * Attention: This function keeps circular references in the returned object.\n *\n * @deprecated This function is no longer used by the SDK and will be removed in a future major version.\n */\nexport function dropUndefinedKeys<T>(inputValue: T): T {\n // This map keeps track of what already visited nodes map to.\n // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular\n // references as the input object.\n const memoizationMap = new Map<unknown, unknown>();\n\n // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API\n return _dropUndefinedKeys(inputValue, memoizationMap);\n}\n\nfunction _dropUndefinedKeys<T>(inputValue: T, memoizationMap: Map<unknown, unknown>): T {\n // Early return for primitive values\n if (inputValue === null || typeof inputValue !== 'object') {\n return inputValue;\n }\n\n // Check memo map first for all object types\n const memoVal = memoizationMap.get(inputValue);\n if (memoVal !== undefined) {\n return memoVal as T;\n }\n\n // handle arrays\n if (Array.isArray(inputValue)) {\n const returnValue: unknown[] = [];\n // Store mapping to handle circular references\n memoizationMap.set(inputValue, returnValue);\n\n inputValue.forEach(value => {\n returnValue.push(_dropUndefinedKeys(value, memoizationMap));\n });\n\n return returnValue as unknown as T;\n }\n\n if (isPojo(inputValue)) {\n const returnValue: { [key: string]: unknown } = {};\n // Store mapping to handle circular references\n memoizationMap.set(inputValue, returnValue);\n\n const keys = Object.keys(inputValue);\n\n keys.forEach(key => {\n const val = inputValue[key];\n if (val !== undefined) {\n returnValue[key] = _dropUndefinedKeys(val, memoizationMap);\n }\n });\n\n return returnValue as T;\n }\n\n // For other object types, return as is\n return inputValue;\n}\n\nfunction isPojo(input: unknown): input is Record<string, unknown> {\n // Plain objects have Object as constructor or no constructor\n const constructor = (input as object).constructor;\n return constructor === Object || constructor === undefined;\n}\n\n/**\n * Ensure that something is an object.\n *\n * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper\n * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.\n *\n * @param wat The subject of the objectification\n * @returns A version of `wat` which can safely be used with `Object` class methods\n */\nexport function objectify(wat: unknown): typeof Object {\n let objectified;\n switch (true) {\n // this will catch both undefined and null\n case wat == undefined:\n objectified = new String(wat);\n break;\n\n // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason\n // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as\n // an object in order to wrap it.\n case typeof wat === 'symbol' || typeof wat === 'bigint':\n objectified = Object(wat);\n break;\n\n // this will catch the remaining primitives: `String`, `Number`, and `Boolean`\n case isPrimitive(wat):\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n objectified = new (wat as any).constructor(wat);\n break;\n\n // by process of elimination, at this point we know that `wat` must already be an object\n default:\n objectified = wat;\n break;\n }\n return objectified;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"object.js","sources":["../../../src/utils/object.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { WrappedFunction } from '../types-hoist/wrappedfunction';\nimport { htmlTreeAsString } from './browser';\nimport { debug } from './debug-logger';\nimport { isElement, isError, isEvent, isInstanceOf, isPrimitive } from './is';\n\n/**\n * Replace a method in an object with a wrapped version of itself.\n *\n * If the method on the passed object is not a function, the wrapper will not be applied.\n *\n * @param source An object that contains a method to be wrapped.\n * @param name The name of the method to be wrapped.\n * @param replacementFactory A higher-order function that takes the original version of the given method and returns a\n * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to\n * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other\n * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.\n * @returns void\n */\n\nexport function fill(source: { [key: string]: any }, name: string, replacementFactory: (...args: any[]) => any): void {\n if (!(name in source)) {\n return;\n }\n\n // explicitly casting to unknown because we don't know the type of the method initially at all\n const original = source[name] as unknown;\n\n if (typeof original !== 'function') {\n return;\n }\n\n const wrapped = replacementFactory(original) as WrappedFunction;\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n markFunctionWrapped(wrapped, original);\n }\n\n try {\n source[name] = wrapped;\n } catch {\n DEBUG_BUILD && debug.log(`Failed to replace method \"${name}\" in object`, source);\n }\n}\n\n/**\n * Defines a non-enumerable property on the given object.\n *\n * @param obj The object on which to set the property\n * @param name The name of the property to be set\n * @param value The value to which to set the property\n */\nexport function addNonEnumerableProperty(obj: object, name: string | symbol, value: unknown): void {\n try {\n Object.defineProperty(obj, name, {\n // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it\n value,\n writable: true,\n configurable: true,\n });\n } catch {\n DEBUG_BUILD && debug.log(`Failed to add non-enumerable property \"${String(name)}\" to object`, obj);\n }\n}\n\n/**\n * Remembers the original function on the wrapped function and\n * patches up the prototype.\n *\n * @param wrapped the wrapper function\n * @param original the original function that gets wrapped\n */\nexport function markFunctionWrapped(wrapped: WrappedFunction, original: WrappedFunction): void {\n try {\n const proto = original.prototype || {};\n wrapped.prototype = original.prototype = proto;\n addNonEnumerableProperty(wrapped, '__sentry_original__', original);\n } catch {} // eslint-disable-line no-empty\n}\n\n/**\n * Wrap a method on an object by name, only if it is not already wrapped.\n *\n * Note: to set the wrapped method as a non-enumerable property, pass\n * false as the `enumerable` argument. This could be detected, but only\n * by either walking up the prototype chain, or iterating over all fields\n * in a `for(in)` loop. Neither are an acceptable performance impact for\n * the rare case where we might patch a non-enumerable method.\n */\nexport function wrapMethod<O extends {}, T extends string & keyof O>(\n obj: O,\n field: T,\n wrapped: WrappedFunction,\n enumerable: boolean = true,\n): void {\n const original = obj[field];\n if (typeof original !== 'function') {\n throw new Error(`Cannot wrap method: ${field} is not a function`);\n }\n if (getOriginalFunction(original)) {\n throw new Error(`Attempting to wrap method ${field} multiple times`);\n }\n markFunctionWrapped(wrapped, original);\n Object.defineProperty(obj, field, {\n writable: true,\n configurable: true,\n enumerable,\n value: wrapped,\n });\n}\n\n/**\n * This extracts the original function if available. See\n * `markFunctionWrapped` for more information.\n *\n * @param func the function to unwrap\n * @returns the unwrapped version of the function if available.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function getOriginalFunction<T extends Function>(func: WrappedFunction<T>): T | undefined {\n return func.__sentry_original__;\n}\n\n/**\n * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their\n * non-enumerable properties attached.\n *\n * @param value Initial source that we have to transform in order for it to be usable by the serializer\n * @returns An Event or Error turned into an object - or the value argument itself, when value is neither an Event nor\n * an Error.\n */\nexport function convertToPlainObject<V>(value: V):\n | {\n [ownProps: string]: unknown;\n type: string;\n target: string;\n currentTarget: string;\n detail?: unknown;\n }\n | {\n [ownProps: string]: unknown;\n message: string;\n name: string;\n stack?: string;\n }\n | V {\n if (isError(value)) {\n return {\n message: value.message,\n name: value.name,\n stack: value.stack,\n ...getOwnProperties(value),\n };\n } else if (isEvent(value)) {\n const newObj: {\n [ownProps: string]: unknown;\n type: string;\n target: string;\n currentTarget: string;\n detail?: unknown;\n } = {\n type: value.type,\n target: serializeEventTarget(value.target),\n currentTarget: serializeEventTarget(value.currentTarget),\n ...getOwnProperties(value),\n };\n\n if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {\n newObj.detail = value.detail;\n }\n\n return newObj;\n } else {\n return value;\n }\n}\n\n/** Creates a string representation of the target of an `Event` object */\nfunction serializeEventTarget(target: unknown): string {\n try {\n return isElement(target) ? htmlTreeAsString(target) : Object.prototype.toString.call(target);\n } catch {\n return '<unknown>';\n }\n}\n\n/** Filters out all but an object's own properties */\nfunction getOwnProperties(obj: unknown): { [key: string]: unknown } {\n if (typeof obj === 'object' && obj !== null) {\n return Object.fromEntries(Object.entries(obj));\n }\n return {};\n}\n\n/**\n * Given any captured exception, extract its keys and create a sorted\n * and truncated list that will be used inside the event message.\n * eg. `Non-error exception captured with keys: foo, bar, baz`\n */\nexport function extractExceptionKeysForMessage(exception: Record<string, unknown>): string {\n const keys = Object.keys(convertToPlainObject(exception));\n keys.sort();\n\n return !keys[0] ? '[object has no keys]' : keys.join(', ');\n}\n\n/**\n * Given any object, return a new object having removed all fields whose value was `undefined`.\n * Works recursively on objects and arrays.\n *\n * Attention: This function keeps circular references in the returned object.\n *\n * @deprecated This function is no longer used by the SDK and will be removed in a future major version.\n */\nexport function dropUndefinedKeys<T>(inputValue: T): T {\n // This map keeps track of what already visited nodes map to.\n // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular\n // references as the input object.\n const memoizationMap = new Map<unknown, unknown>();\n\n // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API\n return _dropUndefinedKeys(inputValue, memoizationMap);\n}\n\nfunction _dropUndefinedKeys<T>(inputValue: T, memoizationMap: Map<unknown, unknown>): T {\n // Early return for primitive values\n if (inputValue === null || typeof inputValue !== 'object') {\n return inputValue;\n }\n\n // Check memo map first for all object types\n const memoVal = memoizationMap.get(inputValue);\n if (memoVal !== undefined) {\n return memoVal as T;\n }\n\n // handle arrays\n if (Array.isArray(inputValue)) {\n const returnValue: unknown[] = [];\n // Store mapping to handle circular references\n memoizationMap.set(inputValue, returnValue);\n\n inputValue.forEach(value => {\n returnValue.push(_dropUndefinedKeys(value, memoizationMap));\n });\n\n return returnValue as unknown as T;\n }\n\n if (isPojo(inputValue)) {\n const returnValue: { [key: string]: unknown } = {};\n // Store mapping to handle circular references\n memoizationMap.set(inputValue, returnValue);\n\n const keys = Object.keys(inputValue);\n\n keys.forEach(key => {\n const val = inputValue[key];\n if (val !== undefined) {\n returnValue[key] = _dropUndefinedKeys(val, memoizationMap);\n }\n });\n\n return returnValue as T;\n }\n\n // For other object types, return as is\n return inputValue;\n}\n\nfunction isPojo(input: unknown): input is Record<string, unknown> {\n // Plain objects have Object as constructor or no constructor\n const constructor = (input as object).constructor;\n return constructor === Object || constructor === undefined;\n}\n\n/**\n * Ensure that something is an object.\n *\n * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper\n * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.\n *\n * @param wat The subject of the objectification\n * @returns A version of `wat` which can safely be used with `Object` class methods\n */\nexport function objectify(wat: unknown): typeof Object {\n let objectified;\n switch (true) {\n // this will catch both undefined and null\n case wat == undefined:\n objectified = new String(wat);\n break;\n\n // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason\n // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as\n // an object in order to wrap it.\n case typeof wat === 'symbol' || typeof wat === 'bigint':\n objectified = Object(wat);\n break;\n\n // this will catch the remaining primitives: `String`, `Number`, and `Boolean`\n case isPrimitive(wat):\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n objectified = new (wat as any).constructor(wat);\n break;\n\n // by process of elimination, at this point we know that `wat` must already be an object\n default:\n objectified = wat;\n break;\n }\n return objectified;\n}\n"],"names":[],"mappings":"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"}