@sentry/node 10.23.0 → 10.25.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 (107) hide show
  1. package/build/cjs/integrations/featureFlagShims/launchDarkly.js.map +1 -1
  2. package/build/cjs/integrations/featureFlagShims/openFeature.js.map +1 -1
  3. package/build/cjs/integrations/featureFlagShims/statsig.js.map +1 -1
  4. package/build/cjs/integrations/featureFlagShims/unleash.js.map +1 -1
  5. package/build/cjs/integrations/fs.js.map +1 -1
  6. package/build/cjs/integrations/http.js.map +1 -1
  7. package/build/cjs/integrations/node-fetch.js.map +1 -1
  8. package/build/cjs/integrations/tracing/amqplib.js.map +1 -1
  9. package/build/cjs/integrations/tracing/anthropic-ai/index.js.map +1 -1
  10. package/build/cjs/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
  11. package/build/cjs/integrations/tracing/connect.js.map +1 -1
  12. package/build/cjs/integrations/tracing/dataloader.js.map +1 -1
  13. package/build/cjs/integrations/tracing/express.js.map +1 -1
  14. package/build/cjs/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
  15. package/build/cjs/integrations/tracing/fastify/index.js.map +1 -1
  16. package/build/cjs/integrations/tracing/fastify/v3/instrumentation.js.map +1 -1
  17. package/build/cjs/integrations/tracing/fastify/v3/utils.js.map +1 -1
  18. package/build/cjs/integrations/tracing/firebase/firebase.js.map +1 -1
  19. package/build/cjs/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
  20. package/build/cjs/integrations/tracing/firebase/otel/patches/firestore.js.map +1 -1
  21. package/build/cjs/integrations/tracing/firebase/otel/patches/functions.js.map +1 -1
  22. package/build/cjs/integrations/tracing/genericPool.js.map +1 -1
  23. package/build/cjs/integrations/tracing/google-genai/index.js.map +1 -1
  24. package/build/cjs/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  25. package/build/cjs/integrations/tracing/graphql.js.map +1 -1
  26. package/build/cjs/integrations/tracing/hapi/index.js.map +1 -1
  27. package/build/cjs/integrations/tracing/hono/index.js.map +1 -1
  28. package/build/cjs/integrations/tracing/hono/instrumentation.js.map +1 -1
  29. package/build/cjs/integrations/tracing/kafka.js.map +1 -1
  30. package/build/cjs/integrations/tracing/knex.js.map +1 -1
  31. package/build/cjs/integrations/tracing/koa.js.map +1 -1
  32. package/build/cjs/integrations/tracing/langchain/index.js.map +1 -1
  33. package/build/cjs/integrations/tracing/langchain/instrumentation.js.map +1 -1
  34. package/build/cjs/integrations/tracing/lrumemoizer.js.map +1 -1
  35. package/build/cjs/integrations/tracing/mongo.js.map +1 -1
  36. package/build/cjs/integrations/tracing/mongoose.js.map +1 -1
  37. package/build/cjs/integrations/tracing/mysql.js.map +1 -1
  38. package/build/cjs/integrations/tracing/mysql2.js.map +1 -1
  39. package/build/cjs/integrations/tracing/openai/index.js.map +1 -1
  40. package/build/cjs/integrations/tracing/openai/instrumentation.js.map +1 -1
  41. package/build/cjs/integrations/tracing/postgres.js.map +1 -1
  42. package/build/cjs/integrations/tracing/postgresjs.js.map +1 -1
  43. package/build/cjs/integrations/tracing/prisma.js.map +1 -1
  44. package/build/cjs/integrations/tracing/redis.js +18 -7
  45. package/build/cjs/integrations/tracing/redis.js.map +1 -1
  46. package/build/cjs/integrations/tracing/tedious.js.map +1 -1
  47. package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
  48. package/build/cjs/integrations/tracing/vercelai/instrumentation.js.map +1 -1
  49. package/build/cjs/sdk/index.js.map +1 -1
  50. package/build/cjs/sdk/initOtel.js.map +1 -1
  51. package/build/cjs/utils/redisCache.js.map +1 -1
  52. package/build/esm/integrations/featureFlagShims/launchDarkly.js.map +1 -1
  53. package/build/esm/integrations/featureFlagShims/openFeature.js.map +1 -1
  54. package/build/esm/integrations/featureFlagShims/statsig.js.map +1 -1
  55. package/build/esm/integrations/featureFlagShims/unleash.js.map +1 -1
  56. package/build/esm/integrations/fs.js.map +1 -1
  57. package/build/esm/integrations/http.js.map +1 -1
  58. package/build/esm/integrations/node-fetch.js.map +1 -1
  59. package/build/esm/integrations/tracing/amqplib.js.map +1 -1
  60. package/build/esm/integrations/tracing/anthropic-ai/index.js.map +1 -1
  61. package/build/esm/integrations/tracing/anthropic-ai/instrumentation.js.map +1 -1
  62. package/build/esm/integrations/tracing/connect.js.map +1 -1
  63. package/build/esm/integrations/tracing/dataloader.js.map +1 -1
  64. package/build/esm/integrations/tracing/express.js.map +1 -1
  65. package/build/esm/integrations/tracing/fastify/fastify-otel/index.js.map +1 -1
  66. package/build/esm/integrations/tracing/fastify/index.js.map +1 -1
  67. package/build/esm/integrations/tracing/fastify/v3/instrumentation.js.map +1 -1
  68. package/build/esm/integrations/tracing/fastify/v3/utils.js.map +1 -1
  69. package/build/esm/integrations/tracing/firebase/firebase.js.map +1 -1
  70. package/build/esm/integrations/tracing/firebase/otel/firebaseInstrumentation.js.map +1 -1
  71. package/build/esm/integrations/tracing/firebase/otel/patches/firestore.js.map +1 -1
  72. package/build/esm/integrations/tracing/firebase/otel/patches/functions.js.map +1 -1
  73. package/build/esm/integrations/tracing/genericPool.js.map +1 -1
  74. package/build/esm/integrations/tracing/google-genai/index.js.map +1 -1
  75. package/build/esm/integrations/tracing/google-genai/instrumentation.js.map +1 -1
  76. package/build/esm/integrations/tracing/graphql.js.map +1 -1
  77. package/build/esm/integrations/tracing/hapi/index.js.map +1 -1
  78. package/build/esm/integrations/tracing/hono/index.js.map +1 -1
  79. package/build/esm/integrations/tracing/hono/instrumentation.js.map +1 -1
  80. package/build/esm/integrations/tracing/kafka.js.map +1 -1
  81. package/build/esm/integrations/tracing/knex.js.map +1 -1
  82. package/build/esm/integrations/tracing/koa.js.map +1 -1
  83. package/build/esm/integrations/tracing/langchain/index.js.map +1 -1
  84. package/build/esm/integrations/tracing/langchain/instrumentation.js.map +1 -1
  85. package/build/esm/integrations/tracing/lrumemoizer.js.map +1 -1
  86. package/build/esm/integrations/tracing/mongo.js.map +1 -1
  87. package/build/esm/integrations/tracing/mongoose.js.map +1 -1
  88. package/build/esm/integrations/tracing/mysql.js.map +1 -1
  89. package/build/esm/integrations/tracing/mysql2.js.map +1 -1
  90. package/build/esm/integrations/tracing/openai/index.js.map +1 -1
  91. package/build/esm/integrations/tracing/openai/instrumentation.js.map +1 -1
  92. package/build/esm/integrations/tracing/postgres.js.map +1 -1
  93. package/build/esm/integrations/tracing/postgresjs.js.map +1 -1
  94. package/build/esm/integrations/tracing/prisma.js.map +1 -1
  95. package/build/esm/integrations/tracing/redis.js +13 -3
  96. package/build/esm/integrations/tracing/redis.js.map +1 -1
  97. package/build/esm/integrations/tracing/tedious.js.map +1 -1
  98. package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
  99. package/build/esm/integrations/tracing/vercelai/instrumentation.js.map +1 -1
  100. package/build/esm/package.json +1 -1
  101. package/build/esm/sdk/index.js.map +1 -1
  102. package/build/esm/sdk/initOtel.js.map +1 -1
  103. package/build/esm/utils/redisCache.js.map +1 -1
  104. package/build/types/integrations/tracing/redis.d.ts +16 -0
  105. package/build/types/integrations/tracing/redis.d.ts.map +1 -1
  106. package/build/types-ts3.8/integrations/tracing/redis.d.ts +16 -0
  107. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langchain/instrumentation.ts"],"sourcesContent":["import {\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { LangChainOptions } from '@sentry/core';\nimport { createLangChainCallbackHandler, getClient, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.1.0 <1.0.0'];\n\ntype LangChainInstrumentationOptions = InstrumentationConfig & LangChainOptions;\n\n/**\n * Represents the patched shape of LangChain provider package exports\n */\ninterface PatchedLangChainExports {\n [key: string]: unknown;\n}\n\n/**\n * Augments a callback handler list with Sentry's handler if not already present\n */\nfunction augmentCallbackHandlers(handlers: unknown, sentryHandler: unknown): unknown {\n // Handle null/undefined - return array with just our handler\n if (!handlers) {\n return [sentryHandler];\n }\n\n // If handlers is already an array\n if (Array.isArray(handlers)) {\n // Check if our handler is already in the list\n if (handlers.includes(sentryHandler)) {\n return handlers;\n }\n // Add our handler to the list\n return [...handlers, sentryHandler];\n }\n\n // If it's a single handler object, convert to array\n if (typeof handlers === 'object') {\n return [handlers, sentryHandler];\n }\n\n // Unknown type - return original\n return handlers;\n}\n\n/**\n * Wraps Runnable methods (invoke, stream, batch) to inject Sentry callbacks at request time\n * Uses a Proxy to intercept method calls and augment the options.callbacks\n */\nfunction wrapRunnableMethod(\n originalMethod: (...args: unknown[]) => unknown,\n sentryHandler: unknown,\n _methodName: string,\n): (...args: unknown[]) => unknown {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: unknown[]): unknown {\n // LangChain Runnable method signatures:\n // invoke(input, options?) - options contains callbacks\n // stream(input, options?) - options contains callbacks\n // batch(inputs, options?) - options contains callbacks\n\n // Options is typically the second argument\n const optionsIndex = 1;\n let options = args[optionsIndex] as Record<string, unknown> | undefined;\n\n // If options don't exist or aren't an object, create them\n if (!options || typeof options !== 'object' || Array.isArray(options)) {\n options = {};\n args[optionsIndex] = options;\n }\n\n // Inject our callback handler into options.callbacks (request time callbacks)\n const existingCallbacks = options.callbacks;\n const augmentedCallbacks = augmentCallbackHandlers(existingCallbacks, sentryHandler);\n options.callbacks = augmentedCallbacks;\n\n // Call original method with augmented options\n return Reflect.apply(target, thisArg, args);\n },\n }) as (...args: unknown[]) => unknown;\n}\n\n/**\n * Sentry LangChain instrumentation using OpenTelemetry.\n */\nexport class SentryLangChainInstrumentation extends InstrumentationBase<LangChainInstrumentationOptions> {\n public constructor(config: LangChainInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langchain', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n * We patch the BaseChatModel class methods to inject callbacks\n *\n * We hook into provider packages (@langchain/anthropic, @langchain/openai, etc.)\n * because @langchain/core is often bundled and not loaded as a separate module\n */\n public init(): InstrumentationModuleDefinition | InstrumentationModuleDefinition[] {\n const modules: InstrumentationModuleDefinition[] = [];\n\n // Hook into common LangChain provider packages\n const providerPackages = [\n '@langchain/anthropic',\n '@langchain/openai',\n '@langchain/google-genai',\n '@langchain/mistralai',\n '@langchain/google-vertexai',\n '@langchain/groq',\n ];\n\n for (const packageName of providerPackages) {\n // In CJS, LangChain packages re-export from dist/index.cjs files.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n modules.push(\n new InstrumentationNodeModuleDefinition(\n packageName,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n `${packageName}/dist/index.cjs`,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n }\n\n return modules;\n }\n\n /**\n * Core patch logic - patches chat model methods to inject Sentry callbacks\n * This is called when a LangChain provider package is loaded\n */\n private _patch(exports: PatchedLangChainExports): PatchedLangChainExports | void {\n const client = getClient();\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const config = this.getConfig();\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordInputs = config?.recordInputs ?? defaultPii;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordOutputs = config?.recordOutputs ?? defaultPii;\n\n // Create a shared handler instance\n const sentryHandler = createLangChainCallbackHandler({\n recordInputs,\n recordOutputs,\n });\n\n // Patch Runnable methods to inject callbacks at request time\n // This directly manipulates options.callbacks that LangChain uses\n this._patchRunnableMethods(exports, sentryHandler);\n\n return exports;\n }\n\n /**\n * Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks\n * Finds a chat model class from the provider package exports and patches its prototype methods\n */\n private _patchRunnableMethods(exports: PatchedLangChainExports, sentryHandler: unknown): void {\n // Known chat model class names for each provider\n const knownChatModelNames = [\n 'ChatAnthropic',\n 'ChatOpenAI',\n 'ChatGoogleGenerativeAI',\n 'ChatMistralAI',\n 'ChatVertexAI',\n 'ChatGroq',\n ];\n\n // Find a chat model class in the exports by checking known class names\n const chatModelClass = Object.values(exports).find(exp => {\n if (typeof exp !== 'function') {\n return false;\n }\n return knownChatModelNames.includes(exp.name);\n }) as { prototype: unknown; name: string } | undefined;\n\n if (!chatModelClass) {\n return;\n }\n\n // Patch directly on chatModelClass.prototype\n const targetProto = chatModelClass.prototype as Record<string, unknown>;\n\n // Patch the methods (invoke, stream, batch)\n // All chat model instances will inherit these patched methods\n const methodsToPatch = ['invoke', 'stream', 'batch'] as const;\n\n for (const methodName of methodsToPatch) {\n const method = targetProto[methodName];\n if (typeof method === 'function') {\n targetProto[methodName] = wrapRunnableMethod(\n method as (...args: unknown[]) => unknown,\n sentryHandler,\n methodName,\n );\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/langchain/instrumentation.ts"],"sourcesContent":["import {\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n} from '@opentelemetry/instrumentation';\nimport type { LangChainOptions } from '@sentry/core';\nimport { createLangChainCallbackHandler, getClient, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=0.1.0 <1.0.0'];\n\ntype LangChainInstrumentationOptions = InstrumentationConfig & LangChainOptions;\n\n/**\n * Represents the patched shape of LangChain provider package exports\n */\ninterface PatchedLangChainExports {\n [key: string]: unknown;\n}\n\n/**\n * Augments a callback handler list with Sentry's handler if not already present\n */\nfunction augmentCallbackHandlers(handlers: unknown, sentryHandler: unknown): unknown {\n // Handle null/undefined - return array with just our handler\n if (!handlers) {\n return [sentryHandler];\n }\n\n // If handlers is already an array\n if (Array.isArray(handlers)) {\n // Check if our handler is already in the list\n if (handlers.includes(sentryHandler)) {\n return handlers;\n }\n // Add our handler to the list\n return [...handlers, sentryHandler];\n }\n\n // If it's a single handler object, convert to array\n if (typeof handlers === 'object') {\n return [handlers, sentryHandler];\n }\n\n // Unknown type - return original\n return handlers;\n}\n\n/**\n * Wraps Runnable methods (invoke, stream, batch) to inject Sentry callbacks at request time\n * Uses a Proxy to intercept method calls and augment the options.callbacks\n */\nfunction wrapRunnableMethod(\n originalMethod: (...args: unknown[]) => unknown,\n sentryHandler: unknown,\n _methodName: string,\n): (...args: unknown[]) => unknown {\n return new Proxy(originalMethod, {\n apply(target, thisArg, args: unknown[]): unknown {\n // LangChain Runnable method signatures:\n // invoke(input, options?) - options contains callbacks\n // stream(input, options?) - options contains callbacks\n // batch(inputs, options?) - options contains callbacks\n\n // Options is typically the second argument\n const optionsIndex = 1;\n let options = args[optionsIndex] as Record<string, unknown> | undefined;\n\n // If options don't exist or aren't an object, create them\n if (!options || typeof options !== 'object' || Array.isArray(options)) {\n options = {};\n args[optionsIndex] = options;\n }\n\n // Inject our callback handler into options.callbacks (request time callbacks)\n const existingCallbacks = options.callbacks;\n const augmentedCallbacks = augmentCallbackHandlers(existingCallbacks, sentryHandler);\n options.callbacks = augmentedCallbacks;\n\n // Call original method with augmented options\n return Reflect.apply(target, thisArg, args);\n },\n }) as (...args: unknown[]) => unknown;\n}\n\n/**\n * Sentry LangChain instrumentation using OpenTelemetry.\n */\nexport class SentryLangChainInstrumentation extends InstrumentationBase<LangChainInstrumentationOptions> {\n public constructor(config: LangChainInstrumentationOptions = {}) {\n super('@sentry/instrumentation-langchain', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n * We patch the BaseChatModel class methods to inject callbacks\n *\n * We hook into provider packages (@langchain/anthropic, @langchain/openai, etc.)\n * because @langchain/core is often bundled and not loaded as a separate module\n */\n public init(): InstrumentationModuleDefinition | InstrumentationModuleDefinition[] {\n const modules: InstrumentationModuleDefinition[] = [];\n\n // Hook into common LangChain provider packages\n const providerPackages = [\n '@langchain/anthropic',\n '@langchain/openai',\n '@langchain/google-genai',\n '@langchain/mistralai',\n '@langchain/google-vertexai',\n '@langchain/groq',\n ];\n\n for (const packageName of providerPackages) {\n // In CJS, LangChain packages re-export from dist/index.cjs files.\n // Patching only the root module sometimes misses the real implementation or\n // gets overwritten when that file is loaded. We add a file-level patch so that\n // _patch runs again on the concrete implementation\n modules.push(\n new InstrumentationNodeModuleDefinition(\n packageName,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n [\n new InstrumentationNodeModuleFile(\n `${packageName}/dist/index.cjs`,\n supportedVersions,\n this._patch.bind(this),\n exports => exports,\n ),\n ],\n ),\n );\n }\n\n return modules;\n }\n\n /**\n * Core patch logic - patches chat model methods to inject Sentry callbacks\n * This is called when a LangChain provider package is loaded\n */\n private _patch(exports: PatchedLangChainExports): PatchedLangChainExports | void {\n const client = getClient();\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const config = this.getConfig();\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordInputs = config?.recordInputs ?? defaultPii;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const recordOutputs = config?.recordOutputs ?? defaultPii;\n\n // Create a shared handler instance\n const sentryHandler = createLangChainCallbackHandler({\n recordInputs,\n recordOutputs,\n });\n\n // Patch Runnable methods to inject callbacks at request time\n // This directly manipulates options.callbacks that LangChain uses\n this._patchRunnableMethods(exports, sentryHandler);\n\n return exports;\n }\n\n /**\n * Patches chat model methods (invoke, stream, batch) to inject Sentry callbacks\n * Finds a chat model class from the provider package exports and patches its prototype methods\n */\n private _patchRunnableMethods(exports: PatchedLangChainExports, sentryHandler: unknown): void {\n // Known chat model class names for each provider\n const knownChatModelNames = [\n 'ChatAnthropic',\n 'ChatOpenAI',\n 'ChatGoogleGenerativeAI',\n 'ChatMistralAI',\n 'ChatVertexAI',\n 'ChatGroq',\n ];\n\n // Find a chat model class in the exports by checking known class names\n const chatModelClass = Object.values(exports).find(exp => {\n if (typeof exp !== 'function') {\n return false;\n }\n return knownChatModelNames.includes(exp.name);\n }) as { prototype: unknown; name: string } | undefined;\n\n if (!chatModelClass) {\n return;\n }\n\n // Patch directly on chatModelClass.prototype\n const targetProto = chatModelClass.prototype as Record<string, unknown>;\n\n // Patch the methods (invoke, stream, batch)\n // All chat model instances will inherit these patched methods\n const methodsToPatch = ['invoke', 'stream', 'batch'] as const;\n\n for (const methodName of methodsToPatch) {\n const method = targetProto[methodName];\n if (typeof method === 'function') {\n targetProto[methodName] = wrapRunnableMethod(\n method as (...args: unknown[]) => unknown,\n sentryHandler,\n methodName,\n );\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lrumemoizer.js","sources":["../../../../src/integrations/tracing/lrumemoizer.ts"],"sourcesContent":["import { LruMemoizerInstrumentation } from '@opentelemetry/instrumentation-lru-memoizer';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'LruMemoizer';\n\nexport const instrumentLruMemoizer = generateInstrumentOnce(INTEGRATION_NAME, () => new LruMemoizerInstrumentation());\n\nconst _lruMemoizerIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentLruMemoizer();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [lru-memoizer](https://www.npmjs.com/package/lru-memoizer) library.\n *\n * For more information, see the [`lruMemoizerIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/lrumemoizer/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.lruMemoizerIntegration()],\n * });\n */\nexport const lruMemoizerIntegration = defineIntegration(_lruMemoizerIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,aAAa;;AAE/B,MAAM,qBAAA,GAAwB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,0BAA0B,EAAE;;AAEpH,MAAM,uBAAA,IAA2B,MAAM;AACvC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,qBAAqB,EAAE;AAC7B,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,sBAAA,GAAyB,iBAAiB,CAAC,uBAAuB;;;;"}
1
+ {"version":3,"file":"lrumemoizer.js","sources":["../../../../src/integrations/tracing/lrumemoizer.ts"],"sourcesContent":["import { LruMemoizerInstrumentation } from '@opentelemetry/instrumentation-lru-memoizer';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'LruMemoizer';\n\nexport const instrumentLruMemoizer = generateInstrumentOnce(INTEGRATION_NAME, () => new LruMemoizerInstrumentation());\n\nconst _lruMemoizerIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentLruMemoizer();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [lru-memoizer](https://www.npmjs.com/package/lru-memoizer) library.\n *\n * For more information, see the [`lruMemoizerIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/lrumemoizer/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.lruMemoizerIntegration()],\n * });\n */\nexport const lruMemoizerIntegration = defineIntegration(_lruMemoizerIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,aAAa;;AAE/B,MAAM,qBAAA,GAAwB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,0BAA0B,EAAE;;AAEpH,MAAM,uBAAA,IAA2B,MAAM;AACvC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,qBAAqB,EAAE;AAC7B,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,sBAAA,GAAyB,iBAAiB,CAAC,uBAAuB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"mongo.js","sources":["../../../../src/integrations/tracing/mongo.ts"],"sourcesContent":["import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mongo';\n\nexport const instrumentMongo = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MongoDBInstrumentation({\n dbStatementSerializer: _defaultDbStatementSerializer,\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mongo');\n },\n }),\n);\n\n/**\n * Replaces values in document with '?', hiding PII and helping grouping.\n */\nexport function _defaultDbStatementSerializer(commandObj: Record<string, unknown>): string {\n const resultObj = _scrubStatement(commandObj);\n return JSON.stringify(resultObj);\n}\n\nfunction _scrubStatement(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(element => _scrubStatement(element));\n }\n\n if (isCommandObj(value)) {\n const initial: Record<string, unknown> = {};\n return Object.entries(value)\n .map(([key, element]) => [key, _scrubStatement(element)])\n .reduce((prev, current) => {\n if (isCommandEntry(current)) {\n prev[current[0]] = current[1];\n }\n return prev;\n }, initial);\n }\n\n // A value like string or number, possible contains PII, scrub it\n return '?';\n}\n\nfunction isCommandObj(value: Record<string, unknown> | unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !isBuffer(value);\n}\n\nfunction isBuffer(value: unknown): boolean {\n let isBuffer = false;\n if (typeof Buffer !== 'undefined') {\n isBuffer = Buffer.isBuffer(value);\n }\n return isBuffer;\n}\n\nfunction isCommandEntry(value: [string, unknown] | unknown): value is [string, unknown] {\n return Array.isArray(value);\n}\n\nconst _mongoIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMongo();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mongodb](https://www.npmjs.com/package/mongodb) library.\n *\n * For more information, see the [`mongoIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mongo/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mongoIntegration()],\n * });\n * ```\n */\nexport const mongoIntegration = defineIntegration(_mongoIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,OAAO;;AAEzB,MAAM,eAAA,GAAkB,sBAAsB;AACrD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,sBAAsB,CAAC;AAC/B,MAAM,qBAAqB,EAAE,6BAA6B;AAC1D,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,oBAAoB,CAAC;AACnD,OAAO;AACP,KAAK,CAAC;AACN;;AAEA;AACA;AACA;AACO,SAAS,6BAA6B,CAAC,UAAU,EAAmC;AAC3F,EAAE,MAAM,SAAA,GAAY,eAAe,CAAC,UAAU,CAAC;AAC/C,EAAE,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;AAClC;;AAEA,SAAS,eAAe,CAAC,KAAK,EAAoB;AAClD,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC5B,IAAI,OAAO,KAAK,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,OAAO,CAAC,CAAC;AACzD;;AAEA,EAAE,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;AAC3B,IAAI,MAAM,OAAO,GAA4B,EAAE;AAC/C,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK;AAC/B,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;AAC9D,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK;AACjC,QAAQ,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE;AACrC,UAAU,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,GAAI,OAAO,CAAC,CAAC,CAAC;AACvC;AACA,QAAQ,OAAO,IAAI;AACnB,OAAO,EAAE,OAAO,CAAC;AACjB;;AAEA;AACA,EAAE,OAAO,GAAG;AACZ;;AAEA,SAAS,YAAY,CAAC,KAAK,EAAuE;AAClG,EAAE,OAAO,OAAO,KAAA,KAAU,YAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxE;;AAEA,SAAS,QAAQ,CAAC,KAAK,EAAoB;AAC3C,EAAE,IAAI,QAAA,GAAW,KAAK;AACtB,EAAE,IAAI,OAAO,MAAA,KAAW,WAAW,EAAE;AACrC,IAAI,WAAW,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;AACrC;AACA,EAAE,OAAO,QAAQ;AACjB;;AAEA,SAAS,cAAc,CAAC,KAAK,EAA2D;AACxF,EAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAC7B;;AAEA,MAAM,iBAAA,IAAqB,MAAM;AACjC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,eAAe,EAAE;AACvB,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,gBAAA,GAAmB,iBAAiB,CAAC,iBAAiB;;;;"}
1
+ {"version":3,"file":"mongo.js","sources":["../../../../src/integrations/tracing/mongo.ts"],"sourcesContent":["import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mongo';\n\nexport const instrumentMongo = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MongoDBInstrumentation({\n dbStatementSerializer: _defaultDbStatementSerializer,\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mongo');\n },\n }),\n);\n\n/**\n * Replaces values in document with '?', hiding PII and helping grouping.\n */\nexport function _defaultDbStatementSerializer(commandObj: Record<string, unknown>): string {\n const resultObj = _scrubStatement(commandObj);\n return JSON.stringify(resultObj);\n}\n\nfunction _scrubStatement(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(element => _scrubStatement(element));\n }\n\n if (isCommandObj(value)) {\n const initial: Record<string, unknown> = {};\n return Object.entries(value)\n .map(([key, element]) => [key, _scrubStatement(element)])\n .reduce((prev, current) => {\n if (isCommandEntry(current)) {\n prev[current[0]] = current[1];\n }\n return prev;\n }, initial);\n }\n\n // A value like string or number, possible contains PII, scrub it\n return '?';\n}\n\nfunction isCommandObj(value: Record<string, unknown> | unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !isBuffer(value);\n}\n\nfunction isBuffer(value: unknown): boolean {\n let isBuffer = false;\n if (typeof Buffer !== 'undefined') {\n isBuffer = Buffer.isBuffer(value);\n }\n return isBuffer;\n}\n\nfunction isCommandEntry(value: [string, unknown] | unknown): value is [string, unknown] {\n return Array.isArray(value);\n}\n\nconst _mongoIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMongo();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mongodb](https://www.npmjs.com/package/mongodb) library.\n *\n * For more information, see the [`mongoIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mongo/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mongoIntegration()],\n * });\n * ```\n */\nexport const mongoIntegration = defineIntegration(_mongoIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,OAAO;;AAEzB,MAAM,eAAA,GAAkB,sBAAsB;AACrD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,sBAAsB,CAAC;AAC/B,MAAM,qBAAqB,EAAE,6BAA6B;AAC1D,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,oBAAoB,CAAC;AACnD,MAAM,CAAC;AACP,KAAK,CAAC;AACN;;AAEA;AACA;AACA;AACO,SAAS,6BAA6B,CAAC,UAAU,EAAmC;AAC3F,EAAE,MAAM,SAAA,GAAY,eAAe,CAAC,UAAU,CAAC;AAC/C,EAAE,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;AAClC;;AAEA,SAAS,eAAe,CAAC,KAAK,EAAoB;AAClD,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC5B,IAAI,OAAO,KAAK,CAAC,GAAG,CAAC,OAAA,IAAW,eAAe,CAAC,OAAO,CAAC,CAAC;AACzD,EAAE;;AAEF,EAAE,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;AAC3B,IAAI,MAAM,OAAO,GAA4B,EAAE;AAC/C,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK;AAC/B,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;AAC9D,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK;AACjC,QAAQ,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE;AACrC,UAAU,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,GAAI,OAAO,CAAC,CAAC,CAAC;AACvC,QAAQ;AACR,QAAQ,OAAO,IAAI;AACnB,MAAM,CAAC,EAAE,OAAO,CAAC;AACjB,EAAE;;AAEF;AACA,EAAE,OAAO,GAAG;AACZ;;AAEA,SAAS,YAAY,CAAC,KAAK,EAAuE;AAClG,EAAE,OAAO,OAAO,KAAA,KAAU,YAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;AACxE;;AAEA,SAAS,QAAQ,CAAC,KAAK,EAAoB;AAC3C,EAAE,IAAI,QAAA,GAAW,KAAK;AACtB,EAAE,IAAI,OAAO,MAAA,KAAW,WAAW,EAAE;AACrC,IAAI,WAAW,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;AACrC,EAAE;AACF,EAAE,OAAO,QAAQ;AACjB;;AAEA,SAAS,cAAc,CAAC,KAAK,EAA2D;AACxF,EAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAC7B;;AAEA,MAAM,iBAAA,IAAqB,MAAM;AACjC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,eAAe,EAAE;AACvB,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,gBAAA,GAAmB,iBAAiB,CAAC,iBAAiB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"mongoose.js","sources":["../../../../src/integrations/tracing/mongoose.ts"],"sourcesContent":["import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mongoose';\n\nexport const instrumentMongoose = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MongooseInstrumentation({\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mongoose');\n },\n }),\n);\n\nconst _mongooseIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMongoose();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mongoose](https://www.npmjs.com/package/mongoose) library.\n *\n * For more information, see the [`mongooseIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mongoose/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mongooseIntegration()],\n * });\n * ```\n */\nexport const mongooseIntegration = defineIntegration(_mongooseIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,UAAU;;AAE5B,MAAM,kBAAA,GAAqB,sBAAsB;AACxD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,uBAAuB,CAAC;AAChC,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,uBAAuB,CAAC;AACtD,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
1
+ {"version":3,"file":"mongoose.js","sources":["../../../../src/integrations/tracing/mongoose.ts"],"sourcesContent":["import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mongoose';\n\nexport const instrumentMongoose = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MongooseInstrumentation({\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mongoose');\n },\n }),\n);\n\nconst _mongooseIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMongoose();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mongoose](https://www.npmjs.com/package/mongoose) library.\n *\n * For more information, see the [`mongooseIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mongoose/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mongooseIntegration()],\n * });\n * ```\n */\nexport const mongooseIntegration = defineIntegration(_mongooseIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,UAAU;;AAE5B,MAAM,kBAAA,GAAqB,sBAAsB;AACxD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,uBAAuB,CAAC;AAChC,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,uBAAuB,CAAC;AACtD,MAAM,CAAC;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.js","sources":["../../../../src/integrations/tracing/mysql.ts"],"sourcesContent":["import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mysql';\n\nexport const instrumentMysql = generateInstrumentOnce(INTEGRATION_NAME, () => new MySQLInstrumentation({}));\n\nconst _mysqlIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMysql();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mysql](https://www.npmjs.com/package/mysql) library.\n *\n * For more information, see the [`mysqlIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mysql/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mysqlIntegration()],\n * });\n * ```\n */\nexport const mysqlIntegration = defineIntegration(_mysqlIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,OAAO;;MAEnB,eAAA,GAAkB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,oBAAoB,CAAC,EAAE,CAAC;;AAE1G,MAAM,iBAAA,IAAqB,MAAM;AACjC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,eAAe,EAAE;AACvB,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,gBAAA,GAAmB,iBAAiB,CAAC,iBAAiB;;;;"}
1
+ {"version":3,"file":"mysql.js","sources":["../../../../src/integrations/tracing/mysql.ts"],"sourcesContent":["import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mysql';\n\nexport const instrumentMysql = generateInstrumentOnce(INTEGRATION_NAME, () => new MySQLInstrumentation({}));\n\nconst _mysqlIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMysql();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mysql](https://www.npmjs.com/package/mysql) library.\n *\n * For more information, see the [`mysqlIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mysql/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mysqlIntegration()],\n * });\n * ```\n */\nexport const mysqlIntegration = defineIntegration(_mysqlIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,OAAO;;MAEnB,eAAA,GAAkB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,oBAAoB,CAAC,EAAE,CAAC;;AAE1G,MAAM,iBAAA,IAAqB,MAAM;AACjC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,eAAe,EAAE;AACvB,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,gBAAA,GAAmB,iBAAiB,CAAC,iBAAiB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"mysql2.js","sources":["../../../../src/integrations/tracing/mysql2.ts"],"sourcesContent":["import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mysql2';\n\nexport const instrumentMysql2 = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MySQL2Instrumentation({\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mysql2');\n },\n }),\n);\n\nconst _mysql2Integration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMysql2();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mysql2](https://www.npmjs.com/package/mysql2) library.\n *\n * For more information, see the [`mysql2Integration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mysql2/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mysqlIntegration()],\n * });\n * ```\n */\nexport const mysql2Integration = defineIntegration(_mysql2Integration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,QAAQ;;AAE1B,MAAM,gBAAA,GAAmB,sBAAsB;AACtD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,qBAAqB,CAAC;AAC9B,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,qBAAqB,CAAC;AACpD,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,kBAAA,IAAsB,MAAM;AAClC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,gBAAgB,EAAE;AACxB,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,iBAAA,GAAoB,iBAAiB,CAAC,kBAAkB;;;;"}
1
+ {"version":3,"file":"mysql2.js","sources":["../../../../src/integrations/tracing/mysql2.ts"],"sourcesContent":["import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Mysql2';\n\nexport const instrumentMysql2 = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new MySQL2Instrumentation({\n responseHook(span) {\n addOriginToSpan(span, 'auto.db.otel.mysql2');\n },\n }),\n);\n\nconst _mysql2Integration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentMysql2();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [mysql2](https://www.npmjs.com/package/mysql2) library.\n *\n * For more information, see the [`mysql2Integration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/mysql2/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.mysqlIntegration()],\n * });\n * ```\n */\nexport const mysql2Integration = defineIntegration(_mysql2Integration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,QAAQ;;AAE1B,MAAM,gBAAA,GAAmB,sBAAsB;AACtD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,qBAAqB,CAAC;AAC9B,MAAM,YAAY,CAAC,IAAI,EAAE;AACzB,QAAQ,eAAe,CAAC,IAAI,EAAE,qBAAqB,CAAC;AACpD,MAAM,CAAC;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,kBAAA,IAAsB,MAAM;AAClC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,gBAAgB,EAAE;AACxB,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,iBAAA,GAAoB,iBAAiB,CAAC,kBAAkB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/openai/index.ts"],"sourcesContent":["import type { IntegrationFn, OpenAiOptions } from '@sentry/core';\nimport { defineIntegration, OPENAI_INTEGRATION_NAME } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { SentryOpenAiInstrumentation } from './instrumentation';\n\nexport const instrumentOpenAi = generateInstrumentOnce(\n OPENAI_INTEGRATION_NAME,\n () => new SentryOpenAiInstrumentation({}),\n);\n\nconst _openAiIntegration = ((options: OpenAiOptions = {}) => {\n return {\n name: OPENAI_INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentOpenAi();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the OpenAI SDK.\n *\n * This integration is enabled by default.\n *\n * When configured, this integration automatically instruments OpenAI SDK client instances\n * to capture telemetry data following OpenTelemetry Semantic Conventions for Generative AI.\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/node';\n *\n * Sentry.init({\n * integrations: [Sentry.openAIIntegration()],\n * });\n * ```\n *\n * ## Options\n *\n * - `recordInputs`: Whether to record prompt messages (default: respects `sendDefaultPii` client option)\n * - `recordOutputs`: Whether to record response text (default: respects `sendDefaultPii` client option)\n *\n * ### Default Behavior\n *\n * By default, the integration will:\n * - Record inputs and outputs ONLY if `sendDefaultPii` is set to `true` in your Sentry client options\n * - Otherwise, inputs and outputs are NOT recorded unless explicitly enabled\n *\n * @example\n * ```javascript\n * // Record inputs and outputs when sendDefaultPii is false\n * Sentry.init({\n * integrations: [\n * Sentry.openAIIntegration({\n * recordInputs: true,\n * recordOutputs: true\n * })\n * ],\n * });\n *\n * // Never record inputs/outputs regardless of sendDefaultPii\n * Sentry.init({\n * sendDefaultPii: true,\n * integrations: [\n * Sentry.openAIIntegration({\n * recordInputs: false,\n * recordOutputs: false\n * })\n * ],\n * });\n * ```\n *\n */\nexport const openAIIntegration = defineIntegration(_openAiIntegration);\n"],"names":[],"mappings":";;;;AAKO,MAAM,gBAAA,GAAmB,sBAAsB;AACtD,EAAE,uBAAuB;AACzB,EAAE,MAAM,IAAI,2BAA2B,CAAC,EAAE,CAAC;AAC3C;;AAEA,MAAM,kBAAA,IAAsB,CAAC,OAAO,GAAkB,EAAE,KAAK;AAC7D,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,uBAAuB;AACjC,IAAI,OAAO;AACX,IAAI,SAAS,GAAG;AAChB,MAAM,gBAAgB,EAAE;AACxB,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,iBAAA,GAAoB,iBAAiB,CAAC,kBAAkB;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/openai/index.ts"],"sourcesContent":["import type { IntegrationFn, OpenAiOptions } from '@sentry/core';\nimport { defineIntegration, OPENAI_INTEGRATION_NAME } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport { SentryOpenAiInstrumentation } from './instrumentation';\n\nexport const instrumentOpenAi = generateInstrumentOnce(\n OPENAI_INTEGRATION_NAME,\n () => new SentryOpenAiInstrumentation({}),\n);\n\nconst _openAiIntegration = ((options: OpenAiOptions = {}) => {\n return {\n name: OPENAI_INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentOpenAi();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the OpenAI SDK.\n *\n * This integration is enabled by default.\n *\n * When configured, this integration automatically instruments OpenAI SDK client instances\n * to capture telemetry data following OpenTelemetry Semantic Conventions for Generative AI.\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/node';\n *\n * Sentry.init({\n * integrations: [Sentry.openAIIntegration()],\n * });\n * ```\n *\n * ## Options\n *\n * - `recordInputs`: Whether to record prompt messages (default: respects `sendDefaultPii` client option)\n * - `recordOutputs`: Whether to record response text (default: respects `sendDefaultPii` client option)\n *\n * ### Default Behavior\n *\n * By default, the integration will:\n * - Record inputs and outputs ONLY if `sendDefaultPii` is set to `true` in your Sentry client options\n * - Otherwise, inputs and outputs are NOT recorded unless explicitly enabled\n *\n * @example\n * ```javascript\n * // Record inputs and outputs when sendDefaultPii is false\n * Sentry.init({\n * integrations: [\n * Sentry.openAIIntegration({\n * recordInputs: true,\n * recordOutputs: true\n * })\n * ],\n * });\n *\n * // Never record inputs/outputs regardless of sendDefaultPii\n * Sentry.init({\n * sendDefaultPii: true,\n * integrations: [\n * Sentry.openAIIntegration({\n * recordInputs: false,\n * recordOutputs: false\n * })\n * ],\n * });\n * ```\n *\n */\nexport const openAIIntegration = defineIntegration(_openAiIntegration);\n"],"names":[],"mappings":";;;;AAKO,MAAM,gBAAA,GAAmB,sBAAsB;AACtD,EAAE,uBAAuB;AACzB,EAAE,MAAM,IAAI,2BAA2B,CAAC,EAAE,CAAC;AAC3C;;AAEA,MAAM,kBAAA,IAAsB,CAAC,OAAO,GAAkB,EAAE,KAAK;AAC7D,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,uBAAuB;AACjC,IAAI,OAAO;AACX,IAAI,SAAS,GAAG;AAChB,MAAM,gBAAgB,EAAE;AACxB,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,iBAAA,GAAoB,iBAAiB,CAAC,kBAAkB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/openai/instrumentation.ts"],"sourcesContent":["import {\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { Integration, OpenAiClient, OpenAiOptions } from '@sentry/core';\nimport { getClient, instrumentOpenAiClient, OPENAI_INTEGRATION_NAME, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=4.0.0 <6'];\n\nexport interface OpenAiIntegration extends Integration {\n options: OpenAiOptions;\n}\n\n/**\n * Represents the patched shape of the OpenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n OpenAI: abstract new (...args: unknown[]) => OpenAiClient;\n}\n\n/**\n * Determines telemetry recording settings.\n */\nfunction determineRecordingSettings(\n integrationOptions: OpenAiOptions | undefined,\n defaultEnabled: boolean,\n): { recordInputs: boolean; recordOutputs: boolean } {\n const recordInputs = integrationOptions?.recordInputs ?? defaultEnabled;\n const recordOutputs = integrationOptions?.recordOutputs ?? defaultEnabled;\n return { recordInputs, recordOutputs };\n}\n\n/**\n * Sentry OpenAI instrumentation using OpenTelemetry.\n */\nexport class SentryOpenAiInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('@sentry/instrumentation-openai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('openai', supportedVersions, this._patch.bind(this));\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the OpenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.OpenAI;\n\n const WrappedOpenAI = function (this: unknown, ...args: unknown[]) {\n const instance = Reflect.construct(Original, args);\n const client = getClient();\n const integration = client?.getIntegrationByName<OpenAiIntegration>(OPENAI_INTEGRATION_NAME);\n const integrationOpts = integration?.options;\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const { recordInputs, recordOutputs } = determineRecordingSettings(integrationOpts, defaultPii);\n\n return instrumentOpenAiClient(instance as OpenAiClient, {\n recordInputs,\n recordOutputs,\n });\n } as unknown as abstract new (...args: unknown[]) => OpenAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedOpenAI, Original);\n Object.setPrototypeOf(WrappedOpenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedOpenAI, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n try {\n exports.OpenAI = WrappedOpenAI;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'OpenAI', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedOpenAI;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/openai/instrumentation.ts"],"sourcesContent":["import {\n type InstrumentationConfig,\n type InstrumentationModuleDefinition,\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n} from '@opentelemetry/instrumentation';\nimport type { Integration, OpenAiClient, OpenAiOptions } from '@sentry/core';\nimport { getClient, instrumentOpenAiClient, OPENAI_INTEGRATION_NAME, SDK_VERSION } from '@sentry/core';\n\nconst supportedVersions = ['>=4.0.0 <6'];\n\nexport interface OpenAiIntegration extends Integration {\n options: OpenAiOptions;\n}\n\n/**\n * Represents the patched shape of the OpenAI module export.\n */\ninterface PatchedModuleExports {\n [key: string]: unknown;\n OpenAI: abstract new (...args: unknown[]) => OpenAiClient;\n}\n\n/**\n * Determines telemetry recording settings.\n */\nfunction determineRecordingSettings(\n integrationOptions: OpenAiOptions | undefined,\n defaultEnabled: boolean,\n): { recordInputs: boolean; recordOutputs: boolean } {\n const recordInputs = integrationOptions?.recordInputs ?? defaultEnabled;\n const recordOutputs = integrationOptions?.recordOutputs ?? defaultEnabled;\n return { recordInputs, recordOutputs };\n}\n\n/**\n * Sentry OpenAI instrumentation using OpenTelemetry.\n */\nexport class SentryOpenAiInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('@sentry/instrumentation-openai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('openai', supportedVersions, this._patch.bind(this));\n return module;\n }\n\n /**\n * Core patch logic applying instrumentation to the OpenAI client constructor.\n */\n private _patch(exports: PatchedModuleExports): PatchedModuleExports | void {\n const Original = exports.OpenAI;\n\n const WrappedOpenAI = function (this: unknown, ...args: unknown[]) {\n const instance = Reflect.construct(Original, args);\n const client = getClient();\n const integration = client?.getIntegrationByName<OpenAiIntegration>(OPENAI_INTEGRATION_NAME);\n const integrationOpts = integration?.options;\n const defaultPii = Boolean(client?.getOptions().sendDefaultPii);\n\n const { recordInputs, recordOutputs } = determineRecordingSettings(integrationOpts, defaultPii);\n\n return instrumentOpenAiClient(instance as OpenAiClient, {\n recordInputs,\n recordOutputs,\n });\n } as unknown as abstract new (...args: unknown[]) => OpenAiClient;\n\n // Preserve static and prototype chains\n Object.setPrototypeOf(WrappedOpenAI, Original);\n Object.setPrototypeOf(WrappedOpenAI.prototype, Original.prototype);\n\n for (const key of Object.getOwnPropertyNames(Original)) {\n if (!['length', 'name', 'prototype'].includes(key)) {\n const descriptor = Object.getOwnPropertyDescriptor(Original, key);\n if (descriptor) {\n Object.defineProperty(WrappedOpenAI, key, descriptor);\n }\n }\n }\n\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n try {\n exports.OpenAI = WrappedOpenAI;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'OpenAI', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Wrap the default export if it points to the original constructor\n // Constructor replacement - handle read-only properties\n // The OpenAI property might have only a getter, so use defineProperty\n if (exports.default === Original) {\n try {\n exports.default = WrappedOpenAI;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, 'default', {\n value: WrappedOpenAI,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n return exports;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.js","sources":["../../../../src/integrations/tracing/postgres.ts"],"sourcesContent":["import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Postgres';\n\nexport const instrumentPostgres = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new PgInstrumentation({\n requireParentSpan: true,\n requestHook(span) {\n addOriginToSpan(span, 'auto.db.otel.postgres');\n },\n }),\n);\n\nconst _postgresIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgres();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [pg](https://www.npmjs.com/package/pg) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresIntegration()],\n * });\n * ```\n */\nexport const postgresIntegration = defineIntegration(_postgresIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,UAAU;;AAE5B,MAAM,kBAAA,GAAqB,sBAAsB;AACxD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,iBAAiB,CAAC;AAC1B,MAAM,iBAAiB,EAAE,IAAI;AAC7B,MAAM,WAAW,CAAC,IAAI,EAAE;AACxB,QAAQ,eAAe,CAAC,IAAI,EAAE,uBAAuB,CAAC;AACtD,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
1
+ {"version":3,"file":"postgres.js","sources":["../../../../src/integrations/tracing/postgres.ts"],"sourcesContent":["import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration } from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'Postgres';\n\nexport const instrumentPostgres = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new PgInstrumentation({\n requireParentSpan: true,\n requestHook(span) {\n addOriginToSpan(span, 'auto.db.otel.postgres');\n },\n }),\n);\n\nconst _postgresIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgres();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [pg](https://www.npmjs.com/package/pg) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresIntegration()],\n * });\n * ```\n */\nexport const postgresIntegration = defineIntegration(_postgresIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,UAAU;;AAE5B,MAAM,kBAAA,GAAqB,sBAAsB;AACxD,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,iBAAiB,CAAC;AAC1B,MAAM,iBAAiB,EAAE,IAAI;AAC7B,MAAM,WAAW,CAAC,IAAI,EAAE;AACxB,QAAQ,eAAe,CAAC,IAAI,EAAE,uBAAuB,CAAC;AACtD,MAAM,CAAC;AACP,KAAK,CAAC;AACN;;AAEA,MAAM,oBAAA,IAAwB,MAAM;AACpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,kBAAkB,EAAE;AAC1B,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["// Instrumentation for https://github.com/porsager/postgres\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getCurrentScope,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes,\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation.\n */\n public init(): InstrumentationNodeModuleDefinition[] {\n const instrumentationModule = new InstrumentationNodeModuleDefinition('postgres', SUPPORTED_VERSIONS);\n\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n instrumentationModule.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/connection.js`,\n ['*'],\n this._patchConnection.bind(this),\n this._unwrap.bind(this),\n ),\n );\n\n instrumentationModule.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQuery.bind(this),\n this._unwrap.bind(this),\n ),\n );\n });\n\n return [instrumentationModule];\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Patches the reject method of the Query class to set the span status and end it\n */\n private _patchReject(rejectTarget: any, span: Span): any {\n return new Proxy(rejectTarget, {\n apply: (\n rejectTarget,\n rejectThisArg,\n rejectArgs: {\n message?: string;\n code?: string;\n name?: string;\n }[],\n ) => {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n // This message is the error message from the rejectArgs, when available\n // e.g \"relation 'User' does not exist\"\n message: rejectArgs?.[0]?.message || 'internal_error',\n });\n\n const result = Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n\n // This status code is PG error code, e.g. '42P01' for \"relation does not exist\"\n // https://www.postgresql.org/docs/current/errcodes-appendix.html\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'Unknown error');\n // This is the error type, e.g. 'PostgresError' for a Postgres error\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'Unknown error');\n\n span.end();\n return result;\n },\n });\n }\n\n /**\n * Patches the resolve method of the Query class to end the span when the query is resolved.\n */\n private _patchResolve(resolveTarget: any, span: Span): any {\n return new Proxy(resolveTarget, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n const result = Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n const sqlCommand = resolveArgs?.[0]?.command;\n\n if (sqlCommand) {\n // SQL command is only available when the query is resolved successfully\n span.setAttribute(ATTR_DB_OPERATION_NAME, sqlCommand);\n }\n span.end();\n return result;\n },\n });\n }\n\n /**\n * Patches the Query class to instrument the handle method.\n */\n private _patchQuery(moduleExports: {\n Query: {\n prototype: {\n handle: any;\n };\n };\n }): any {\n moduleExports.Query.prototype.handle = new Proxy(moduleExports.Query.prototype.handle, {\n apply: async (\n handleTarget,\n handleThisArg: {\n resolve: any;\n reject: any;\n strings?: string[];\n },\n handleArgs,\n ) => {\n if (!this._shouldCreateSpans()) {\n // If we don't need to create spans, just call the original method\n return Reflect.apply(handleTarget, handleThisArg, handleArgs);\n }\n\n const sanitizedSqlQuery = this._sanitizeSqlQuery(handleThisArg.strings?.[0]);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n const scope = getCurrentScope();\n const postgresConnectionContext = scope.getScopeData().contexts['postgresjsConnection'] as\n | PostgresConnectionContext\n | undefined;\n\n addOriginToSpan(span, 'auto.db.otel.postgres');\n\n const { requestHook } = this.getConfig();\n\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, postgresConnectionContext),\n error => {\n if (error) {\n debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, error);\n }\n },\n );\n }\n\n // ATTR_DB_NAMESPACE is used to indicate the database name and the schema name\n // It's only the database name as we don't have the schema information\n const databaseName = postgresConnectionContext?.ATTR_DB_NAMESPACE || '<unknown database>';\n const databaseHost = postgresConnectionContext?.ATTR_SERVER_ADDRESS || '<unknown host>';\n const databasePort = postgresConnectionContext?.ATTR_SERVER_PORT || '<unknown port>';\n\n span.setAttribute(ATTR_DB_SYSTEM_NAME, 'postgres');\n span.setAttribute(ATTR_DB_NAMESPACE, databaseName);\n span.setAttribute(ATTR_SERVER_ADDRESS, databaseHost);\n span.setAttribute(ATTR_SERVER_PORT, databasePort);\n span.setAttribute(ATTR_DB_QUERY_TEXT, sanitizedSqlQuery);\n\n handleThisArg.resolve = this._patchResolve(handleThisArg.resolve, span);\n handleThisArg.reject = this._patchReject(handleThisArg.reject, span);\n\n try {\n return Reflect.apply(handleTarget, handleThisArg, handleArgs);\n } catch (error) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n });\n span.end();\n throw error; // Re-throw the error to propagate it\n }\n },\n );\n },\n });\n\n return moduleExports;\n }\n\n /**\n * Patches the Connection class to set the database, host, and port attributes\n * when a new connection is created.\n */\n private _patchConnection(Connection: any): any {\n return new Proxy(Connection, {\n apply: (connectionTarget, thisArg, connectionArgs: { database: string; host: string[]; port: number[] }[]) => {\n const databaseName = connectionArgs[0]?.database || '<unknown database>';\n const databaseHost = connectionArgs[0]?.host?.[0] || '<unknown host>';\n const databasePort = connectionArgs[0]?.port?.[0] || '<unknown port>';\n\n const scope = getCurrentScope();\n scope.setContext('postgresjsConnection', {\n ATTR_DB_NAMESPACE: databaseName,\n ATTR_SERVER_ADDRESS: databaseHost,\n ATTR_SERVER_PORT: databasePort,\n });\n\n return Reflect.apply(connectionTarget, thisArg, connectionArgs);\n },\n });\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces including newlines and trim\n .substring(0, 1024) // Truncate to 1024 characters\n .replace(/--.*?(\\r?\\n|$)/g, '') // Single line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n .replace(/\\b\\d+\\b/g, '?') // Replace standalone numbers\n // Collapse whitespace to a single space\n .replace(/\\s+/g, ' ')\n // Collapse IN and in clauses\n // eg. IN (?, ?, ?, ?) to IN (?)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/g, 'IN (?)')\n );\n }\n}\n\nconst _postgresJsIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgresjs.js","sources":["../../../../src/integrations/tracing/postgresjs.ts"],"sourcesContent":["// Instrumentation for https://github.com/porsager/postgres\nimport { context, trace } from '@opentelemetry/api';\nimport type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_NAMESPACE,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_RESPONSE_STATUS_CODE,\n ATTR_DB_SYSTEM_NAME,\n ATTR_ERROR_TYPE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport type { IntegrationFn, Span } from '@sentry/core';\nimport {\n debug,\n defineIntegration,\n getCurrentScope,\n SDK_VERSION,\n SPAN_STATUS_ERROR,\n startSpanManual,\n} from '@sentry/core';\nimport { addOriginToSpan, generateInstrumentOnce } from '@sentry/node-core';\n\nconst INTEGRATION_NAME = 'PostgresJs';\nconst SUPPORTED_VERSIONS = ['>=3.0.0 <4'];\n\ntype PostgresConnectionContext = {\n ATTR_DB_NAMESPACE?: string; // Database name\n ATTR_SERVER_ADDRESS?: string; // Hostname or IP address of the database server\n ATTR_SERVER_PORT?: string; // Port number of the database server\n};\n\ntype PostgresJsInstrumentationConfig = InstrumentationConfig & {\n /**\n * Whether to require a parent span for the instrumentation.\n * If set to true, the instrumentation will only create spans if there is a parent span\n * available in the current scope.\n * @default true\n */\n requireParentSpan?: boolean;\n /**\n * Hook to modify the span before it is started.\n * This can be used to set additional attributes or modify the span in any way.\n */\n requestHook?: (span: Span, sanitizedSqlQuery: string, postgresConnectionContext?: PostgresConnectionContext) => void;\n};\n\nexport const instrumentPostgresJs = generateInstrumentOnce(\n INTEGRATION_NAME,\n (options?: PostgresJsInstrumentationConfig) =>\n new PostgresJsInstrumentation({\n requireParentSpan: options?.requireParentSpan ?? true,\n requestHook: options?.requestHook,\n }),\n);\n\n/**\n * Instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n * This instrumentation captures postgresjs queries and their attributes,\n */\nexport class PostgresJsInstrumentation extends InstrumentationBase<PostgresJsInstrumentationConfig> {\n public constructor(config: PostgresJsInstrumentationConfig) {\n super('sentry-postgres-js', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation.\n */\n public init(): InstrumentationNodeModuleDefinition[] {\n const instrumentationModule = new InstrumentationNodeModuleDefinition('postgres', SUPPORTED_VERSIONS);\n\n ['src', 'cf/src', 'cjs/src'].forEach(path => {\n instrumentationModule.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/connection.js`,\n ['*'],\n this._patchConnection.bind(this),\n this._unwrap.bind(this),\n ),\n );\n\n instrumentationModule.files.push(\n new InstrumentationNodeModuleFile(\n `postgres/${path}/query.js`,\n SUPPORTED_VERSIONS,\n this._patchQuery.bind(this),\n this._unwrap.bind(this),\n ),\n );\n });\n\n return [instrumentationModule];\n }\n\n /**\n * Determines whether a span should be created based on the current context.\n * If `requireParentSpan` is set to true in the configuration, a span will\n * only be created if there is a parent span available.\n */\n private _shouldCreateSpans(): boolean {\n const config = this.getConfig();\n const hasParentSpan = trace.getSpan(context.active()) !== undefined;\n return hasParentSpan || !config.requireParentSpan;\n }\n\n /**\n * Patches the reject method of the Query class to set the span status and end it\n */\n private _patchReject(rejectTarget: any, span: Span): any {\n return new Proxy(rejectTarget, {\n apply: (\n rejectTarget,\n rejectThisArg,\n rejectArgs: {\n message?: string;\n code?: string;\n name?: string;\n }[],\n ) => {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n // This message is the error message from the rejectArgs, when available\n // e.g \"relation 'User' does not exist\"\n message: rejectArgs?.[0]?.message || 'internal_error',\n });\n\n const result = Reflect.apply(rejectTarget, rejectThisArg, rejectArgs);\n\n // This status code is PG error code, e.g. '42P01' for \"relation does not exist\"\n // https://www.postgresql.org/docs/current/errcodes-appendix.html\n span.setAttribute(ATTR_DB_RESPONSE_STATUS_CODE, rejectArgs?.[0]?.code || 'Unknown error');\n // This is the error type, e.g. 'PostgresError' for a Postgres error\n span.setAttribute(ATTR_ERROR_TYPE, rejectArgs?.[0]?.name || 'Unknown error');\n\n span.end();\n return result;\n },\n });\n }\n\n /**\n * Patches the resolve method of the Query class to end the span when the query is resolved.\n */\n private _patchResolve(resolveTarget: any, span: Span): any {\n return new Proxy(resolveTarget, {\n apply: (resolveTarget, resolveThisArg, resolveArgs: [{ command?: string }]) => {\n const result = Reflect.apply(resolveTarget, resolveThisArg, resolveArgs);\n const sqlCommand = resolveArgs?.[0]?.command;\n\n if (sqlCommand) {\n // SQL command is only available when the query is resolved successfully\n span.setAttribute(ATTR_DB_OPERATION_NAME, sqlCommand);\n }\n span.end();\n return result;\n },\n });\n }\n\n /**\n * Patches the Query class to instrument the handle method.\n */\n private _patchQuery(moduleExports: {\n Query: {\n prototype: {\n handle: any;\n };\n };\n }): any {\n moduleExports.Query.prototype.handle = new Proxy(moduleExports.Query.prototype.handle, {\n apply: async (\n handleTarget,\n handleThisArg: {\n resolve: any;\n reject: any;\n strings?: string[];\n },\n handleArgs,\n ) => {\n if (!this._shouldCreateSpans()) {\n // If we don't need to create spans, just call the original method\n return Reflect.apply(handleTarget, handleThisArg, handleArgs);\n }\n\n const sanitizedSqlQuery = this._sanitizeSqlQuery(handleThisArg.strings?.[0]);\n\n return startSpanManual(\n {\n name: sanitizedSqlQuery || 'postgresjs.query',\n op: 'db',\n },\n (span: Span) => {\n const scope = getCurrentScope();\n const postgresConnectionContext = scope.getScopeData().contexts['postgresjsConnection'] as\n | PostgresConnectionContext\n | undefined;\n\n addOriginToSpan(span, 'auto.db.otel.postgres');\n\n const { requestHook } = this.getConfig();\n\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, sanitizedSqlQuery, postgresConnectionContext),\n error => {\n if (error) {\n debug.error(`Error in requestHook for ${INTEGRATION_NAME} integration:`, error);\n }\n },\n );\n }\n\n // ATTR_DB_NAMESPACE is used to indicate the database name and the schema name\n // It's only the database name as we don't have the schema information\n const databaseName = postgresConnectionContext?.ATTR_DB_NAMESPACE || '<unknown database>';\n const databaseHost = postgresConnectionContext?.ATTR_SERVER_ADDRESS || '<unknown host>';\n const databasePort = postgresConnectionContext?.ATTR_SERVER_PORT || '<unknown port>';\n\n span.setAttribute(ATTR_DB_SYSTEM_NAME, 'postgres');\n span.setAttribute(ATTR_DB_NAMESPACE, databaseName);\n span.setAttribute(ATTR_SERVER_ADDRESS, databaseHost);\n span.setAttribute(ATTR_SERVER_PORT, databasePort);\n span.setAttribute(ATTR_DB_QUERY_TEXT, sanitizedSqlQuery);\n\n handleThisArg.resolve = this._patchResolve(handleThisArg.resolve, span);\n handleThisArg.reject = this._patchReject(handleThisArg.reject, span);\n\n try {\n return Reflect.apply(handleTarget, handleThisArg, handleArgs);\n } catch (error) {\n span.setStatus({\n code: SPAN_STATUS_ERROR,\n });\n span.end();\n throw error; // Re-throw the error to propagate it\n }\n },\n );\n },\n });\n\n return moduleExports;\n }\n\n /**\n * Patches the Connection class to set the database, host, and port attributes\n * when a new connection is created.\n */\n private _patchConnection(Connection: any): any {\n return new Proxy(Connection, {\n apply: (connectionTarget, thisArg, connectionArgs: { database: string; host: string[]; port: number[] }[]) => {\n const databaseName = connectionArgs[0]?.database || '<unknown database>';\n const databaseHost = connectionArgs[0]?.host?.[0] || '<unknown host>';\n const databasePort = connectionArgs[0]?.port?.[0] || '<unknown port>';\n\n const scope = getCurrentScope();\n scope.setContext('postgresjsConnection', {\n ATTR_DB_NAMESPACE: databaseName,\n ATTR_SERVER_ADDRESS: databaseHost,\n ATTR_SERVER_PORT: databasePort,\n });\n\n return Reflect.apply(connectionTarget, thisArg, connectionArgs);\n },\n });\n }\n\n /**\n * Sanitize SQL query as per the OTEL semantic conventions\n * https://opentelemetry.io/docs/specs/semconv/database/database-spans/#sanitization-of-dbquerytext\n */\n private _sanitizeSqlQuery(sqlQuery: string | undefined): string {\n if (!sqlQuery) {\n return 'Unknown SQL Query';\n }\n\n return (\n sqlQuery\n .replace(/\\s+/g, ' ')\n .trim() // Remove extra spaces including newlines and trim\n .substring(0, 1024) // Truncate to 1024 characters\n .replace(/--.*?(\\r?\\n|$)/g, '') // Single line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Multi-line comments\n .replace(/;\\s*$/, '') // Remove trailing semicolons\n .replace(/\\b\\d+\\b/g, '?') // Replace standalone numbers\n // Collapse whitespace to a single space\n .replace(/\\s+/g, ' ')\n // Collapse IN and in clauses\n // eg. IN (?, ?, ?, ?) to IN (?)\n .replace(/\\bIN\\b\\s*\\(\\s*\\?(?:\\s*,\\s*\\?)*\\s*\\)/g, 'IN (?)')\n );\n }\n}\n\nconst _postgresJsIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPostgresJs();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [postgres](https://www.npmjs.com/package/postgres) library.\n *\n * For more information, see the [`postgresIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/postgres/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.postgresJsIntegration()],\n * });\n * ```\n */\n\nexport const postgresJsIntegration = defineIntegration(_postgresJsIntegration);\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.js","sources":["../../../../src/integrations/tracing/prisma.ts"],"sourcesContent":["import type { Link, Tracer } from '@opentelemetry/api';\nimport { context, SpanKind, trace, TraceFlags } from '@opentelemetry/api';\nimport type { Instrumentation } from '@opentelemetry/instrumentation';\nimport type { IdGenerator } from '@opentelemetry/sdk-trace-base';\nimport { PrismaInstrumentation } from '@prisma/instrumentation';\nimport { consoleSandbox, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport type { PrismaV5TracingHelper } from './prisma/vendor/v5-tracing-helper';\nimport type { PrismaV6TracingHelper } from './prisma/vendor/v6-tracing-helper';\n\nconst INTEGRATION_NAME = 'Prisma';\n\ntype CompatibilityLayerTraceHelper = PrismaV5TracingHelper & PrismaV6TracingHelper;\n\n// Vendored in from @prisma/instrumentation v5:\ntype V5EngineSpanEvent = {\n span: boolean;\n spans: V5EngineSpan[];\n};\n\ntype V5EngineSpanKind = 'client' | 'internal';\n\ntype V5EngineSpan = {\n span: boolean;\n name: string;\n trace_id: string;\n span_id: string;\n parent_span_id: string;\n start_time: [number, number];\n end_time: [number, number];\n attributes?: Record<string, string>;\n links?: { trace_id: string; span_id: string }[];\n kind: V5EngineSpanKind;\n};\n\nfunction isPrismaV6TracingHelper(helper: unknown): helper is PrismaV6TracingHelper {\n return !!helper && typeof helper === 'object' && 'dispatchEngineSpans' in helper;\n}\n\nfunction getPrismaTracingHelper(): unknown | undefined {\n const prismaInstrumentationObject = (globalThis as Record<string, unknown>).PRISMA_INSTRUMENTATION;\n const prismaTracingHelper =\n prismaInstrumentationObject &&\n typeof prismaInstrumentationObject === 'object' &&\n 'helper' in prismaInstrumentationObject\n ? prismaInstrumentationObject.helper\n : undefined;\n\n return prismaTracingHelper;\n}\n\ntype TracerWithIdGenerator = Tracer & {\n _idGenerator?: IdGenerator;\n};\n\ninterface PrismaOptions {\n /**\n * @deprecated This is no longer used, v5 works out of the box.\n */\n prismaInstrumentation?: Instrumentation;\n}\n\nclass SentryPrismaInteropInstrumentation extends PrismaInstrumentation {\n public constructor() {\n super();\n }\n\n public enable(): void {\n super.enable();\n\n // The PrismaIntegration (super class) defines a global variable `global[\"PRISMA_INSTRUMENTATION\"]` when `enable()` is called. This global variable holds a \"TracingHelper\" which Prisma uses internally to create tracing data. It's their way of not depending on OTEL with their main package. The sucky thing is, prisma broke the interface of the tracing helper with the v6 major update. This means that if you use Prisma 5 with the v6 instrumentation (or vice versa) Prisma just blows up, because tries to call methods on the helper that no longer exist.\n // Because we actually want to use the v6 instrumentation and not blow up in Prisma 5 user's faces, what we're doing here is backfilling the v5 method (`createEngineSpan`) with a noop so that no longer crashes when it attempts to call that function.\n const prismaTracingHelper = getPrismaTracingHelper();\n\n if (isPrismaV6TracingHelper(prismaTracingHelper)) {\n // Inspired & adjusted from https://github.com/prisma/prisma/tree/5.22.0/packages/instrumentation\n (prismaTracingHelper as CompatibilityLayerTraceHelper).createEngineSpan = (\n engineSpanEvent: V5EngineSpanEvent,\n ) => {\n const tracer = trace.getTracer('prismaV5Compatibility') as TracerWithIdGenerator;\n\n // Prisma v5 relies on being able to create spans with a specific span & trace ID\n // this is no longer possible in OTEL v2, there is no public API to do this anymore\n // So in order to kind of hack this possibility, we rely on the internal `_idGenerator` property\n // This is used to generate the random IDs, and we overwrite this temporarily to generate static IDs\n // This is flawed and may not work, e.g. if the code is bundled and the private property is renamed\n // in such cases, these spans will not be captured and some Prisma spans will be missing\n const initialIdGenerator = tracer._idGenerator;\n\n if (!initialIdGenerator) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Could not find _idGenerator on tracer, skipping Prisma v5 compatibility - some Prisma spans may be missing!',\n );\n });\n\n return;\n }\n\n try {\n engineSpanEvent.spans.forEach(engineSpan => {\n const kind = engineSpanKindToOTELSpanKind(engineSpan.kind);\n\n const parentSpanId = engineSpan.parent_span_id;\n const spanId = engineSpan.span_id;\n const traceId = engineSpan.trace_id;\n\n const links: Link[] | undefined = engineSpan.links?.map(link => {\n return {\n context: {\n traceId: link.trace_id,\n spanId: link.span_id,\n traceFlags: TraceFlags.SAMPLED,\n },\n };\n });\n\n const ctx = trace.setSpanContext(context.active(), {\n traceId,\n spanId: parentSpanId,\n traceFlags: TraceFlags.SAMPLED,\n });\n\n context.with(ctx, () => {\n const temporaryIdGenerator: IdGenerator = {\n generateTraceId: () => {\n return traceId;\n },\n generateSpanId: () => {\n return spanId;\n },\n };\n\n tracer._idGenerator = temporaryIdGenerator;\n\n const span = tracer.startSpan(engineSpan.name, {\n kind,\n links,\n startTime: engineSpan.start_time,\n attributes: engineSpan.attributes,\n });\n\n span.end(engineSpan.end_time);\n\n tracer._idGenerator = initialIdGenerator;\n });\n });\n } finally {\n // Ensure we always restore this at the end, even if something errors\n tracer._idGenerator = initialIdGenerator;\n }\n };\n }\n }\n}\n\nfunction engineSpanKindToOTELSpanKind(engineSpanKind: V5EngineSpanKind): SpanKind {\n switch (engineSpanKind) {\n case 'client':\n return SpanKind.CLIENT;\n case 'internal':\n default: // Other span kinds aren't currently supported\n return SpanKind.INTERNAL;\n }\n}\n\nexport const instrumentPrisma = generateInstrumentOnce<PrismaOptions>(INTEGRATION_NAME, _options => {\n return new SentryPrismaInteropInstrumentation();\n});\n\n/**\n * Adds Sentry tracing instrumentation for the [prisma](https://www.npmjs.com/package/prisma) library.\n * For more information, see the [`prismaIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/prisma/).\n *\n * NOTE: By default, this integration works with Prisma version 6.\n * To get performance instrumentation for other Prisma versions,\n * 1. Install the `@prisma/instrumentation` package with the desired version.\n * 1. Pass a `new PrismaInstrumentation()` instance as exported from `@prisma/instrumentation` to the `prismaInstrumentation` option of this integration:\n *\n * ```js\n * import { PrismaInstrumentation } from '@prisma/instrumentation'\n *\n * Sentry.init({\n * integrations: [\n * prismaIntegration({\n * // Override the default instrumentation that Sentry uses\n * prismaInstrumentation: new PrismaInstrumentation()\n * })\n * ]\n * })\n * ```\n *\n * The passed instrumentation instance will override the default instrumentation instance the integration would use, while the `prismaIntegration` will still ensure data compatibility for the various Prisma versions.\n * 1. Depending on your Prisma version (prior to version 6), add `previewFeatures = [\"tracing\"]` to the client generator block of your Prisma schema:\n *\n * ```\n * generator client {\n * provider = \"prisma-client-js\"\n * previewFeatures = [\"tracing\"]\n * }\n * ```\n */\nexport const prismaIntegration = defineIntegration((_options?: PrismaOptions) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPrisma();\n },\n setup(client) {\n // If no tracing helper exists, we skip any work here\n // this means that prisma is not being used\n if (!getPrismaTracingHelper()) {\n return;\n }\n\n client.on('spanStart', span => {\n const spanJSON = spanToJSON(span);\n if (spanJSON.description?.startsWith('prisma:')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');\n }\n\n // Make sure we use the query text as the span name, for ex. SELECT * FROM \"User\" WHERE \"id\" = $1\n if (spanJSON.description === 'prisma:engine:db_query' && spanJSON.data['db.query.text']) {\n span.updateName(spanJSON.data['db.query.text'] as string);\n }\n\n // In Prisma v5.22+, the `db.system` attribute is automatically set\n // On older versions, this is missing, so we add it here\n if (spanJSON.description === 'prisma:engine:db_query' && !spanJSON.data['db.system']) {\n span.setAttribute('db.system', 'prisma');\n }\n });\n },\n };\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prisma.js","sources":["../../../../src/integrations/tracing/prisma.ts"],"sourcesContent":["import type { Link, Tracer } from '@opentelemetry/api';\nimport { context, SpanKind, trace, TraceFlags } from '@opentelemetry/api';\nimport type { Instrumentation } from '@opentelemetry/instrumentation';\nimport type { IdGenerator } from '@opentelemetry/sdk-trace-base';\nimport { PrismaInstrumentation } from '@prisma/instrumentation';\nimport { consoleSandbox, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport type { PrismaV5TracingHelper } from './prisma/vendor/v5-tracing-helper';\nimport type { PrismaV6TracingHelper } from './prisma/vendor/v6-tracing-helper';\n\nconst INTEGRATION_NAME = 'Prisma';\n\ntype CompatibilityLayerTraceHelper = PrismaV5TracingHelper & PrismaV6TracingHelper;\n\n// Vendored in from @prisma/instrumentation v5:\ntype V5EngineSpanEvent = {\n span: boolean;\n spans: V5EngineSpan[];\n};\n\ntype V5EngineSpanKind = 'client' | 'internal';\n\ntype V5EngineSpan = {\n span: boolean;\n name: string;\n trace_id: string;\n span_id: string;\n parent_span_id: string;\n start_time: [number, number];\n end_time: [number, number];\n attributes?: Record<string, string>;\n links?: { trace_id: string; span_id: string }[];\n kind: V5EngineSpanKind;\n};\n\nfunction isPrismaV6TracingHelper(helper: unknown): helper is PrismaV6TracingHelper {\n return !!helper && typeof helper === 'object' && 'dispatchEngineSpans' in helper;\n}\n\nfunction getPrismaTracingHelper(): unknown | undefined {\n const prismaInstrumentationObject = (globalThis as Record<string, unknown>).PRISMA_INSTRUMENTATION;\n const prismaTracingHelper =\n prismaInstrumentationObject &&\n typeof prismaInstrumentationObject === 'object' &&\n 'helper' in prismaInstrumentationObject\n ? prismaInstrumentationObject.helper\n : undefined;\n\n return prismaTracingHelper;\n}\n\ntype TracerWithIdGenerator = Tracer & {\n _idGenerator?: IdGenerator;\n};\n\ninterface PrismaOptions {\n /**\n * @deprecated This is no longer used, v5 works out of the box.\n */\n prismaInstrumentation?: Instrumentation;\n}\n\nclass SentryPrismaInteropInstrumentation extends PrismaInstrumentation {\n public constructor() {\n super();\n }\n\n public enable(): void {\n super.enable();\n\n // The PrismaIntegration (super class) defines a global variable `global[\"PRISMA_INSTRUMENTATION\"]` when `enable()` is called. This global variable holds a \"TracingHelper\" which Prisma uses internally to create tracing data. It's their way of not depending on OTEL with their main package. The sucky thing is, prisma broke the interface of the tracing helper with the v6 major update. This means that if you use Prisma 5 with the v6 instrumentation (or vice versa) Prisma just blows up, because tries to call methods on the helper that no longer exist.\n // Because we actually want to use the v6 instrumentation and not blow up in Prisma 5 user's faces, what we're doing here is backfilling the v5 method (`createEngineSpan`) with a noop so that no longer crashes when it attempts to call that function.\n const prismaTracingHelper = getPrismaTracingHelper();\n\n if (isPrismaV6TracingHelper(prismaTracingHelper)) {\n // Inspired & adjusted from https://github.com/prisma/prisma/tree/5.22.0/packages/instrumentation\n (prismaTracingHelper as CompatibilityLayerTraceHelper).createEngineSpan = (\n engineSpanEvent: V5EngineSpanEvent,\n ) => {\n const tracer = trace.getTracer('prismaV5Compatibility') as TracerWithIdGenerator;\n\n // Prisma v5 relies on being able to create spans with a specific span & trace ID\n // this is no longer possible in OTEL v2, there is no public API to do this anymore\n // So in order to kind of hack this possibility, we rely on the internal `_idGenerator` property\n // This is used to generate the random IDs, and we overwrite this temporarily to generate static IDs\n // This is flawed and may not work, e.g. if the code is bundled and the private property is renamed\n // in such cases, these spans will not be captured and some Prisma spans will be missing\n const initialIdGenerator = tracer._idGenerator;\n\n if (!initialIdGenerator) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] Could not find _idGenerator on tracer, skipping Prisma v5 compatibility - some Prisma spans may be missing!',\n );\n });\n\n return;\n }\n\n try {\n engineSpanEvent.spans.forEach(engineSpan => {\n const kind = engineSpanKindToOTELSpanKind(engineSpan.kind);\n\n const parentSpanId = engineSpan.parent_span_id;\n const spanId = engineSpan.span_id;\n const traceId = engineSpan.trace_id;\n\n const links: Link[] | undefined = engineSpan.links?.map(link => {\n return {\n context: {\n traceId: link.trace_id,\n spanId: link.span_id,\n traceFlags: TraceFlags.SAMPLED,\n },\n };\n });\n\n const ctx = trace.setSpanContext(context.active(), {\n traceId,\n spanId: parentSpanId,\n traceFlags: TraceFlags.SAMPLED,\n });\n\n context.with(ctx, () => {\n const temporaryIdGenerator: IdGenerator = {\n generateTraceId: () => {\n return traceId;\n },\n generateSpanId: () => {\n return spanId;\n },\n };\n\n tracer._idGenerator = temporaryIdGenerator;\n\n const span = tracer.startSpan(engineSpan.name, {\n kind,\n links,\n startTime: engineSpan.start_time,\n attributes: engineSpan.attributes,\n });\n\n span.end(engineSpan.end_time);\n\n tracer._idGenerator = initialIdGenerator;\n });\n });\n } finally {\n // Ensure we always restore this at the end, even if something errors\n tracer._idGenerator = initialIdGenerator;\n }\n };\n }\n }\n}\n\nfunction engineSpanKindToOTELSpanKind(engineSpanKind: V5EngineSpanKind): SpanKind {\n switch (engineSpanKind) {\n case 'client':\n return SpanKind.CLIENT;\n case 'internal':\n default: // Other span kinds aren't currently supported\n return SpanKind.INTERNAL;\n }\n}\n\nexport const instrumentPrisma = generateInstrumentOnce<PrismaOptions>(INTEGRATION_NAME, _options => {\n return new SentryPrismaInteropInstrumentation();\n});\n\n/**\n * Adds Sentry tracing instrumentation for the [prisma](https://www.npmjs.com/package/prisma) library.\n * For more information, see the [`prismaIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/prisma/).\n *\n * NOTE: By default, this integration works with Prisma version 6.\n * To get performance instrumentation for other Prisma versions,\n * 1. Install the `@prisma/instrumentation` package with the desired version.\n * 1. Pass a `new PrismaInstrumentation()` instance as exported from `@prisma/instrumentation` to the `prismaInstrumentation` option of this integration:\n *\n * ```js\n * import { PrismaInstrumentation } from '@prisma/instrumentation'\n *\n * Sentry.init({\n * integrations: [\n * prismaIntegration({\n * // Override the default instrumentation that Sentry uses\n * prismaInstrumentation: new PrismaInstrumentation()\n * })\n * ]\n * })\n * ```\n *\n * The passed instrumentation instance will override the default instrumentation instance the integration would use, while the `prismaIntegration` will still ensure data compatibility for the various Prisma versions.\n * 1. Depending on your Prisma version (prior to version 6), add `previewFeatures = [\"tracing\"]` to the client generator block of your Prisma schema:\n *\n * ```\n * generator client {\n * provider = \"prisma-client-js\"\n * previewFeatures = [\"tracing\"]\n * }\n * ```\n */\nexport const prismaIntegration = defineIntegration((_options?: PrismaOptions) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPrisma();\n },\n setup(client) {\n // If no tracing helper exists, we skip any work here\n // this means that prisma is not being used\n if (!getPrismaTracingHelper()) {\n return;\n }\n\n client.on('spanStart', span => {\n const spanJSON = spanToJSON(span);\n if (spanJSON.description?.startsWith('prisma:')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');\n }\n\n // Make sure we use the query text as the span name, for ex. SELECT * FROM \"User\" WHERE \"id\" = $1\n if (spanJSON.description === 'prisma:engine:db_query' && spanJSON.data['db.query.text']) {\n span.updateName(spanJSON.data['db.query.text'] as string);\n }\n\n // In Prisma v5.22+, the `db.system` attribute is automatically set\n // On older versions, this is missing, so we add it here\n if (spanJSON.description === 'prisma:engine:db_query' && !spanJSON.data['db.system']) {\n span.setAttribute('db.system', 'prisma');\n }\n });\n },\n };\n});\n"],"names":[],"mappings":"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"}
@@ -6,9 +6,16 @@ import { getCacheKeySafely, getCacheOperation, shouldConsiderForCache, calculate
6
6
 
7
7
  const INTEGRATION_NAME = 'Redis';
8
8
 
9
+ /* Only exported for testing purposes */
9
10
  let _redisOptions = {};
10
11
 
11
- const cacheResponseHook = (span, redisCommand, cmdArgs, response) => {
12
+ /* Only exported for testing purposes */
13
+ const cacheResponseHook = (
14
+ span,
15
+ redisCommand,
16
+ cmdArgs,
17
+ response,
18
+ ) => {
12
19
  span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.redis');
13
20
 
14
21
  const safeKey = getCacheKeySafely(redisCommand, cmdArgs);
@@ -47,9 +54,12 @@ const cacheResponseHook = (span, redisCommand, cmdArgs, response) => {
47
54
  [SEMANTIC_ATTRIBUTE_CACHE_KEY]: safeKey,
48
55
  });
49
56
 
57
+ // todo: change to string[] once EAP supports it
50
58
  const spanDescription = safeKey.join(', ');
51
59
 
52
- span.updateName(truncate(spanDescription, 1024));
60
+ span.updateName(
61
+ _redisOptions.maxCacheKeyLength ? truncate(spanDescription, _redisOptions.maxCacheKeyLength) : spanDescription,
62
+ );
53
63
  };
54
64
 
55
65
  const instrumentIORedis = generateInstrumentOnce(`${INTEGRATION_NAME}.IORedis`, () => {
@@ -103,5 +113,5 @@ const _redisIntegration = ((options = {}) => {
103
113
  */
104
114
  const redisIntegration = defineIntegration(_redisIntegration);
105
115
 
106
- export { instrumentRedis, redisIntegration };
116
+ export { _redisOptions, cacheResponseHook, instrumentRedis, redisIntegration };
107
117
  //# sourceMappingURL=redis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redis.js","sources":["../../../../src/integrations/tracing/redis.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport type { RedisResponseCustomAttributeFunction } from '@opentelemetry/instrumentation-ioredis';\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';\nimport { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';\nimport type { IntegrationFn } from '@sentry/core';\nimport {\n defineIntegration,\n SEMANTIC_ATTRIBUTE_CACHE_HIT,\n SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE,\n SEMANTIC_ATTRIBUTE_CACHE_KEY,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n truncate,\n} from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport {\n calculateCacheItemSize,\n GET_COMMANDS,\n getCacheKeySafely,\n getCacheOperation,\n isInCommands,\n shouldConsiderForCache,\n} from '../../utils/redisCache';\n\ninterface RedisOptions {\n cachePrefixes?: string[];\n}\n\nconst INTEGRATION_NAME = 'Redis';\n\nlet _redisOptions: RedisOptions = {};\n\nconst cacheResponseHook: RedisResponseCustomAttributeFunction = (span: Span, redisCommand, cmdArgs, response) => {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.redis');\n\n const safeKey = getCacheKeySafely(redisCommand, cmdArgs);\n const cacheOperation = getCacheOperation(redisCommand);\n\n if (\n !safeKey ||\n !cacheOperation ||\n !_redisOptions.cachePrefixes ||\n !shouldConsiderForCache(redisCommand, safeKey, _redisOptions.cachePrefixes)\n ) {\n // not relevant for cache\n return;\n }\n\n // otel/ioredis seems to be using the old standard, as there was a change to those params: https://github.com/open-telemetry/opentelemetry-specification/issues/3199\n // We are using params based on the docs: https://opentelemetry.io/docs/specs/semconv/attributes-registry/network/\n const networkPeerAddress = spanToJSON(span).data['net.peer.name'];\n const networkPeerPort = spanToJSON(span).data['net.peer.port'];\n if (networkPeerPort && networkPeerAddress) {\n span.setAttributes({ 'network.peer.address': networkPeerAddress, 'network.peer.port': networkPeerPort });\n }\n\n const cacheItemSize = calculateCacheItemSize(response);\n\n if (cacheItemSize) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, cacheItemSize);\n }\n\n if (isInCommands(GET_COMMANDS, redisCommand) && cacheItemSize !== undefined) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, cacheItemSize > 0);\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: cacheOperation,\n [SEMANTIC_ATTRIBUTE_CACHE_KEY]: safeKey,\n });\n\n const spanDescription = safeKey.join(', ');\n\n span.updateName(truncate(spanDescription, 1024));\n};\n\nconst instrumentIORedis = generateInstrumentOnce(`${INTEGRATION_NAME}.IORedis`, () => {\n return new IORedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\nconst instrumentRedisModule = generateInstrumentOnce(`${INTEGRATION_NAME}.Redis`, () => {\n return new RedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\n/** To be able to preload all Redis OTel instrumentations with just one ID (\"Redis\"), all the instrumentations are generated in this one function */\nexport const instrumentRedis = Object.assign(\n (): void => {\n instrumentIORedis();\n instrumentRedisModule();\n\n // todo: implement them gradually\n // new LegacyRedisInstrumentation({}),\n },\n { id: INTEGRATION_NAME },\n);\n\nconst _redisIntegration = ((options: RedisOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _redisOptions = options;\n instrumentRedis();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [redis](https://www.npmjs.com/package/redis) and\n * [ioredis](https://www.npmjs.com/package/ioredis) libraries.\n *\n * For more information, see the [`redisIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/redis/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.redisIntegration()],\n * });\n * ```\n */\nexport const redisIntegration = defineIntegration(_redisIntegration);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redis.js","sources":["../../../../src/integrations/tracing/redis.ts"],"sourcesContent":["import type { Span } from '@opentelemetry/api';\nimport type { RedisResponseCustomAttributeFunction } from '@opentelemetry/instrumentation-ioredis';\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';\nimport { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';\nimport type { IntegrationFn } from '@sentry/core';\nimport {\n defineIntegration,\n SEMANTIC_ATTRIBUTE_CACHE_HIT,\n SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE,\n SEMANTIC_ATTRIBUTE_CACHE_KEY,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n spanToJSON,\n truncate,\n} from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node-core';\nimport {\n calculateCacheItemSize,\n GET_COMMANDS,\n getCacheKeySafely,\n getCacheOperation,\n isInCommands,\n shouldConsiderForCache,\n} from '../../utils/redisCache';\n\ninterface RedisOptions {\n /**\n * Define cache prefixes for cache keys that should be captured as a cache span.\n *\n * Setting this to, for example, `['user:']` will capture cache keys that start with `user:`.\n */\n cachePrefixes?: string[];\n /**\n * Maximum length of the cache key added to the span description. If the key exceeds this length, it will be truncated.\n *\n * Passing `0` will use the full cache key without truncation.\n *\n * By default, the full cache key is used.\n */\n maxCacheKeyLength?: number;\n}\n\nconst INTEGRATION_NAME = 'Redis';\n\n/* Only exported for testing purposes */\nexport let _redisOptions: RedisOptions = {};\n\n/* Only exported for testing purposes */\nexport const cacheResponseHook: RedisResponseCustomAttributeFunction = (\n span: Span,\n redisCommand,\n cmdArgs,\n response,\n) => {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.redis');\n\n const safeKey = getCacheKeySafely(redisCommand, cmdArgs);\n const cacheOperation = getCacheOperation(redisCommand);\n\n if (\n !safeKey ||\n !cacheOperation ||\n !_redisOptions.cachePrefixes ||\n !shouldConsiderForCache(redisCommand, safeKey, _redisOptions.cachePrefixes)\n ) {\n // not relevant for cache\n return;\n }\n\n // otel/ioredis seems to be using the old standard, as there was a change to those params: https://github.com/open-telemetry/opentelemetry-specification/issues/3199\n // We are using params based on the docs: https://opentelemetry.io/docs/specs/semconv/attributes-registry/network/\n const networkPeerAddress = spanToJSON(span).data['net.peer.name'];\n const networkPeerPort = spanToJSON(span).data['net.peer.port'];\n if (networkPeerPort && networkPeerAddress) {\n span.setAttributes({ 'network.peer.address': networkPeerAddress, 'network.peer.port': networkPeerPort });\n }\n\n const cacheItemSize = calculateCacheItemSize(response);\n\n if (cacheItemSize) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, cacheItemSize);\n }\n\n if (isInCommands(GET_COMMANDS, redisCommand) && cacheItemSize !== undefined) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, cacheItemSize > 0);\n }\n\n span.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: cacheOperation,\n [SEMANTIC_ATTRIBUTE_CACHE_KEY]: safeKey,\n });\n\n // todo: change to string[] once EAP supports it\n const spanDescription = safeKey.join(', ');\n\n span.updateName(\n _redisOptions.maxCacheKeyLength ? truncate(spanDescription, _redisOptions.maxCacheKeyLength) : spanDescription,\n );\n};\n\nconst instrumentIORedis = generateInstrumentOnce(`${INTEGRATION_NAME}.IORedis`, () => {\n return new IORedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\nconst instrumentRedisModule = generateInstrumentOnce(`${INTEGRATION_NAME}.Redis`, () => {\n return new RedisInstrumentation({\n responseHook: cacheResponseHook,\n });\n});\n\n/** To be able to preload all Redis OTel instrumentations with just one ID (\"Redis\"), all the instrumentations are generated in this one function */\nexport const instrumentRedis = Object.assign(\n (): void => {\n instrumentIORedis();\n instrumentRedisModule();\n\n // todo: implement them gradually\n // new LegacyRedisInstrumentation({}),\n },\n { id: INTEGRATION_NAME },\n);\n\nconst _redisIntegration = ((options: RedisOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n _redisOptions = options;\n instrumentRedis();\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [redis](https://www.npmjs.com/package/redis) and\n * [ioredis](https://www.npmjs.com/package/ioredis) libraries.\n *\n * For more information, see the [`redisIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/redis/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.redisIntegration()],\n * });\n * ```\n */\nexport const redisIntegration = defineIntegration(_redisIntegration);\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tedious.js","sources":["../../../../src/integrations/tracing/tedious.ts"],"sourcesContent":["import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce, instrumentWhenWrapped } from '@sentry/node-core';\n\nconst TEDIUS_INSTRUMENTED_METHODS = new Set([\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n]);\n\nconst INTEGRATION_NAME = 'Tedious';\n\nexport const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));\n\nconst _tediousIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentTedious();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n instrumentationWrappedCallback?.(() =>\n client.on('spanStart', span => {\n const { description, data } = spanToJSON(span);\n // Tedius integration always set a span name and `db.system` attribute to `mssql`.\n if (!description || data['db.system'] !== 'mssql') {\n return;\n }\n\n const operation = description.split(' ')[0] || '';\n if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');\n }\n }),\n );\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [tedious](https://www.npmjs.com/package/tedious) library.\n *\n * For more information, see the [`tediousIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/tedious/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.tediousIntegration()],\n * });\n * ```\n */\nexport const tediousIntegration = defineIntegration(_tediousIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,2BAAA,GAA8B,IAAI,GAAG,CAAC;AAC5C,EAAE,eAAe;AACjB,EAAE,SAAS;AACX,EAAE,cAAc;AAChB,EAAE,cAAc;AAChB,EAAE,SAAS;AACX,EAAE,SAAS;AACX,CAAC,CAAC;;AAEF,MAAM,gBAAA,GAAmB,SAAS;;MAErB,iBAAA,GAAoB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,sBAAsB,CAAC,EAAE,CAAC;;AAE9G,MAAM,mBAAA,IAAuB,MAAM;AACnC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,iBAAiB,EAAE;AACjD,MAAM,8BAAA,GAAiC,qBAAqB,CAAC,eAAe,CAAC;AAC7E,KAAK;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,8BAA8B,GAAG;AACvC,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,EAAE,WAAW,EAAE,IAAA,KAAS,UAAU,CAAC,IAAI,CAAC;AACxD;AACA,UAAU,IAAI,CAAC,WAAA,IAAe,IAAI,CAAC,WAAW,CAAA,KAAM,OAAO,EAAE;AAC7D,YAAY;AACZ;;AAEA,UAAU,MAAM,SAAA,GAAY,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE;AAC3D,UAAU,IAAI,2BAA2B,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AAC1D,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,sBAAsB,CAAC;AACvF;AACA,SAAS,CAAC;AACV,OAAO;AACP,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,kBAAA,GAAqB,iBAAiB,CAAC,mBAAmB;;;;"}
1
+ {"version":3,"file":"tedious.js","sources":["../../../../src/integrations/tracing/tedious.ts"],"sourcesContent":["import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';\nimport type { IntegrationFn } from '@sentry/core';\nimport { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce, instrumentWhenWrapped } from '@sentry/node-core';\n\nconst TEDIUS_INSTRUMENTED_METHODS = new Set([\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n]);\n\nconst INTEGRATION_NAME = 'Tedious';\n\nexport const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));\n\nconst _tediousIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentTedious();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n instrumentationWrappedCallback?.(() =>\n client.on('spanStart', span => {\n const { description, data } = spanToJSON(span);\n // Tedius integration always set a span name and `db.system` attribute to `mssql`.\n if (!description || data['db.system'] !== 'mssql') {\n return;\n }\n\n const operation = description.split(' ')[0] || '';\n if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');\n }\n }),\n );\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [tedious](https://www.npmjs.com/package/tedious) library.\n *\n * For more information, see the [`tediousIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/tedious/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.tediousIntegration()],\n * });\n * ```\n */\nexport const tediousIntegration = defineIntegration(_tediousIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,2BAAA,GAA8B,IAAI,GAAG,CAAC;AAC5C,EAAE,eAAe;AACjB,EAAE,SAAS;AACX,EAAE,cAAc;AAChB,EAAE,cAAc;AAChB,EAAE,SAAS;AACX,EAAE,SAAS;AACX,CAAC,CAAC;;AAEF,MAAM,gBAAA,GAAmB,SAAS;;MAErB,iBAAA,GAAoB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,sBAAsB,CAAC,EAAE,CAAC;;AAE9G,MAAM,mBAAA,IAAuB,MAAM;AACnC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,iBAAiB,EAAE;AACjD,MAAM,8BAAA,GAAiC,qBAAqB,CAAC,eAAe,CAAC;AAC7E,IAAI,CAAC;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,8BAA8B,GAAG;AACvC,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,EAAE,WAAW,EAAE,IAAA,KAAS,UAAU,CAAC,IAAI,CAAC;AACxD;AACA,UAAU,IAAI,CAAC,WAAA,IAAe,IAAI,CAAC,WAAW,CAAA,KAAM,OAAO,EAAE;AAC7D,YAAY;AACZ,UAAU;;AAEV,UAAU,MAAM,SAAA,GAAY,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE;AAC3D,UAAU,IAAI,2BAA2B,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AAC1D,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,sBAAsB,CAAC;AACvF,UAAU;AACV,QAAQ,CAAC,CAAC;AACV,OAAO;AACP,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,kBAAA,GAAqB,iBAAiB,CAAC,mBAAmB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/vercelai/index.ts"],"sourcesContent":["import type { Client, IntegrationFn } from '@sentry/core';\nimport { addVercelAiProcessors, defineIntegration } from '@sentry/core';\nimport { type modulesIntegration, generateInstrumentOnce } from '@sentry/node-core';\nimport { INTEGRATION_NAME } from './constants';\nimport { SentryVercelAiInstrumentation } from './instrumentation';\nimport type { VercelAiOptions } from './types';\n\nexport const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () => new SentryVercelAiInstrumentation({}));\n\n/**\n * Determines if the integration should be forced based on environment and package availability.\n * Returns true if the 'ai' package is available.\n */\nfunction shouldForceIntegration(client: Client): boolean {\n const modules = client.getIntegrationByName<ReturnType<typeof modulesIntegration>>('Modules');\n return !!modules?.getModules?.()?.ai;\n}\n\nconst _vercelAIIntegration = ((options: VercelAiOptions = {}) => {\n let instrumentation: undefined | SentryVercelAiInstrumentation;\n\n return {\n name: INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentation = instrumentVercelAi();\n },\n afterAllSetup(client) {\n // Auto-detect if we should force the integration when running with 'ai' package available\n // Note that this can only be detected if the 'Modules' integration is available, and running in CJS mode\n const shouldForce = options.force ?? shouldForceIntegration(client);\n\n if (shouldForce) {\n addVercelAiProcessors(client);\n } else {\n instrumentation?.callWhenPatched(() => addVercelAiProcessors(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [ai](https://www.npmjs.com/package/ai) library.\n * This integration is not enabled by default, you need to manually add it.\n *\n * For more information, see the [`ai` documentation](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.vercelAIIntegration()],\n * });\n * ```\n *\n * This integration adds tracing support to all `ai` function calls.\n * You need to opt-in to collecting spans for a specific call,\n * you can do so by setting `experimental_telemetry.isEnabled` to `true` in the first argument of the function call.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true },\n * });\n * ```\n *\n * If you want to collect inputs and outputs for a specific call, you must specifically opt-in to each\n * function call by setting `experimental_telemetry.recordInputs` and `experimental_telemetry.recordOutputs`\n * to `true`.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true },\n * });\n */\nexport const vercelAIIntegration = defineIntegration(_vercelAIIntegration);\n"],"names":[],"mappings":";;;;;MAOa,kBAAA,GAAqB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,6BAA6B,CAAC,EAAE,CAAC;;AAEtH;AACA;AACA;AACA;AACA,SAAS,sBAAsB,CAAC,MAAM,EAAmB;AACzD,EAAE,MAAM,UAAU,MAAM,CAAC,oBAAoB,CAAwC,SAAS,CAAC;AAC/F,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,EAAE;AACtC;;AAEA,MAAM,oBAAA,IAAwB,CAAC,OAAO,GAAoB,EAAE,KAAK;AACjE,EAAE,IAAI,eAAe;;AAErB,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,OAAO;AACX,IAAI,SAAS,GAAG;AAChB,MAAM,eAAA,GAAkB,kBAAkB,EAAE;AAC5C,KAAK;AACL,IAAI,aAAa,CAAC,MAAM,EAAE;AAC1B;AACA;AACA,MAAM,MAAM,WAAA,GAAc,OAAO,CAAC,SAAS,sBAAsB,CAAC,MAAM,CAAC;;AAEzE,MAAM,IAAI,WAAW,EAAE;AACvB,QAAQ,qBAAqB,CAAC,MAAM,CAAC;AACrC,aAAa;AACb,QAAQ,eAAe,EAAE,eAAe,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC7E;AACA,KAAK;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/integrations/tracing/vercelai/index.ts"],"sourcesContent":["import type { Client, IntegrationFn } from '@sentry/core';\nimport { addVercelAiProcessors, defineIntegration } from '@sentry/core';\nimport { type modulesIntegration, generateInstrumentOnce } from '@sentry/node-core';\nimport { INTEGRATION_NAME } from './constants';\nimport { SentryVercelAiInstrumentation } from './instrumentation';\nimport type { VercelAiOptions } from './types';\n\nexport const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () => new SentryVercelAiInstrumentation({}));\n\n/**\n * Determines if the integration should be forced based on environment and package availability.\n * Returns true if the 'ai' package is available.\n */\nfunction shouldForceIntegration(client: Client): boolean {\n const modules = client.getIntegrationByName<ReturnType<typeof modulesIntegration>>('Modules');\n return !!modules?.getModules?.()?.ai;\n}\n\nconst _vercelAIIntegration = ((options: VercelAiOptions = {}) => {\n let instrumentation: undefined | SentryVercelAiInstrumentation;\n\n return {\n name: INTEGRATION_NAME,\n options,\n setupOnce() {\n instrumentation = instrumentVercelAi();\n },\n afterAllSetup(client) {\n // Auto-detect if we should force the integration when running with 'ai' package available\n // Note that this can only be detected if the 'Modules' integration is available, and running in CJS mode\n const shouldForce = options.force ?? shouldForceIntegration(client);\n\n if (shouldForce) {\n addVercelAiProcessors(client);\n } else {\n instrumentation?.callWhenPatched(() => addVercelAiProcessors(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [ai](https://www.npmjs.com/package/ai) library.\n * This integration is not enabled by default, you need to manually add it.\n *\n * For more information, see the [`ai` documentation](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.vercelAIIntegration()],\n * });\n * ```\n *\n * This integration adds tracing support to all `ai` function calls.\n * You need to opt-in to collecting spans for a specific call,\n * you can do so by setting `experimental_telemetry.isEnabled` to `true` in the first argument of the function call.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true },\n * });\n * ```\n *\n * If you want to collect inputs and outputs for a specific call, you must specifically opt-in to each\n * function call by setting `experimental_telemetry.recordInputs` and `experimental_telemetry.recordOutputs`\n * to `true`.\n *\n * ```javascript\n * const result = await generateText({\n * model: openai('gpt-4-turbo'),\n * experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true },\n * });\n */\nexport const vercelAIIntegration = defineIntegration(_vercelAIIntegration);\n"],"names":[],"mappings":";;;;;MAOa,kBAAA,GAAqB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,6BAA6B,CAAC,EAAE,CAAC;;AAEtH;AACA;AACA;AACA;AACA,SAAS,sBAAsB,CAAC,MAAM,EAAmB;AACzD,EAAE,MAAM,UAAU,MAAM,CAAC,oBAAoB,CAAwC,SAAS,CAAC;AAC/F,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,EAAE;AACtC;;AAEA,MAAM,oBAAA,IAAwB,CAAC,OAAO,GAAoB,EAAE,KAAK;AACjE,EAAE,IAAI,eAAe;;AAErB,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,OAAO;AACX,IAAI,SAAS,GAAG;AAChB,MAAM,eAAA,GAAkB,kBAAkB,EAAE;AAC5C,IAAI,CAAC;AACL,IAAI,aAAa,CAAC,MAAM,EAAE;AAC1B;AACA;AACA,MAAM,MAAM,WAAA,GAAc,OAAO,CAAC,SAAS,sBAAsB,CAAC,MAAM,CAAC;;AAEzE,MAAM,IAAI,WAAW,EAAE;AACvB,QAAQ,qBAAqB,CAAC,MAAM,CAAC;AACrC,MAAM,OAAO;AACb,QAAQ,eAAe,EAAE,eAAe,CAAC,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC7E,MAAM;AACN,IAAI,CAAC;AACL,GAAG;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,mBAAA,GAAsB,iBAAiB,CAAC,oBAAoB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/vercelai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig, InstrumentationModuleDefinition } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport type { Span } from '@sentry/core';\nimport {\n _INTERNAL_cleanupToolCallSpan,\n _INTERNAL_getSpanForToolCallId,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n getClient,\n handleCallbackErrors,\n SDK_VERSION,\n withScope,\n} from '@sentry/core';\nimport { INTEGRATION_NAME } from './constants';\nimport type { TelemetrySettings, VercelAiIntegration } from './types';\n\n// List of patched methods\n// From: https://sdk.vercel.ai/docs/ai-sdk-core/telemetry#collected-data\nconst INSTRUMENTED_METHODS = [\n 'generateText',\n 'streamText',\n 'generateObject',\n 'streamObject',\n 'embed',\n 'embedMany',\n] as const;\n\ninterface MethodFirstArg extends Record<string, unknown> {\n experimental_telemetry?: TelemetrySettings;\n}\n\ntype MethodArgs = [MethodFirstArg, ...unknown[]];\n\ntype PatchedModuleExports = Record<(typeof INSTRUMENTED_METHODS)[number], (...args: MethodArgs) => unknown> &\n Record<string, unknown>;\n\ninterface RecordingOptions {\n recordInputs?: boolean;\n recordOutputs?: boolean;\n}\n\ninterface ToolError {\n type: 'tool-error' | 'tool-result' | 'tool-call';\n toolCallId: string;\n toolName: string;\n input?: {\n [key: string]: unknown;\n };\n error: Error;\n dynamic?: boolean;\n}\n\nfunction isToolError(obj: unknown): obj is ToolError {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n const candidate = obj as Record<string, unknown>;\n return (\n 'type' in candidate &&\n 'error' in candidate &&\n 'toolName' in candidate &&\n 'toolCallId' in candidate &&\n candidate.type === 'tool-error' &&\n candidate.error instanceof Error\n );\n}\n\n/**\n * Check for tool errors in the result and capture them\n * Tool errors are not rejected in Vercel V5, it is added as metadata to the result content\n */\nfunction checkResultForToolErrors(result: unknown): void {\n if (typeof result !== 'object' || result === null || !('content' in result)) {\n return;\n }\n\n const resultObj = result as { content: Array<object> };\n if (!Array.isArray(resultObj.content)) {\n return;\n }\n\n for (const item of resultObj.content) {\n if (isToolError(item)) {\n // Try to get the span associated with this tool call ID\n const associatedSpan = _INTERNAL_getSpanForToolCallId(item.toolCallId) as Span;\n\n if (associatedSpan) {\n // We have the span, so link the error using span and trace IDs from the span\n const spanContext = associatedSpan.spanContext();\n\n withScope(scope => {\n // Set the span and trace context for proper linking\n scope.setContext('trace', {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n });\n\n scope.setTag('vercel.ai.tool.name', item.toolName);\n scope.setTag('vercel.ai.tool.callId', item.toolCallId);\n\n scope.setLevel('error');\n\n captureException(item.error, {\n mechanism: {\n type: 'auto.vercelai.otel',\n handled: false,\n },\n });\n });\n\n // Clean up the span mapping since we've processed this tool error\n // We won't get multiple { type: 'tool-error' } parts for the same toolCallId.\n _INTERNAL_cleanupToolCallSpan(item.toolCallId);\n } else {\n // Fallback: capture without span linking\n withScope(scope => {\n scope.setTag('vercel.ai.tool.name', item.toolName);\n scope.setTag('vercel.ai.tool.callId', item.toolCallId);\n scope.setLevel('error');\n\n captureException(item.error, {\n mechanism: {\n type: 'auto.vercelai.otel',\n handled: false,\n },\n });\n });\n }\n }\n }\n}\n\n/**\n * Determines whether to record inputs and outputs for Vercel AI telemetry based on the configuration hierarchy.\n *\n * The order of precedence is:\n * 1. The vercel ai integration options\n * 2. The experimental_telemetry options in the vercel ai method calls\n * 3. When telemetry is explicitly enabled (isEnabled: true), default to recording\n * 4. Otherwise, use the sendDefaultPii option from client options\n */\nexport function determineRecordingSettings(\n integrationRecordingOptions: RecordingOptions | undefined,\n methodTelemetryOptions: RecordingOptions,\n telemetryExplicitlyEnabled: boolean | undefined,\n defaultRecordingEnabled: boolean,\n): { recordInputs: boolean; recordOutputs: boolean } {\n const recordInputs =\n integrationRecordingOptions?.recordInputs !== undefined\n ? integrationRecordingOptions.recordInputs\n : methodTelemetryOptions.recordInputs !== undefined\n ? methodTelemetryOptions.recordInputs\n : telemetryExplicitlyEnabled === true\n ? true // When telemetry is explicitly enabled, default to recording inputs\n : defaultRecordingEnabled;\n\n const recordOutputs =\n integrationRecordingOptions?.recordOutputs !== undefined\n ? integrationRecordingOptions.recordOutputs\n : methodTelemetryOptions.recordOutputs !== undefined\n ? methodTelemetryOptions.recordOutputs\n : telemetryExplicitlyEnabled === true\n ? true // When telemetry is explicitly enabled, default to recording inputs\n : defaultRecordingEnabled;\n\n return { recordInputs, recordOutputs };\n}\n\n/**\n * This detects is added by the Sentry Vercel AI Integration to detect if the integration should\n * be enabled.\n *\n * It also patches the `ai` module to enable Vercel AI telemetry automatically for all methods.\n */\nexport class SentryVercelAiInstrumentation extends InstrumentationBase {\n private _isPatched = false;\n private _callbacks: (() => void)[] = [];\n\n public constructor(config: InstrumentationConfig = {}) {\n super('@sentry/instrumentation-vercel-ai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('ai', ['>=3.0.0 <6'], this._patch.bind(this));\n return module;\n }\n\n /**\n * Call the provided callback when the module is patched.\n * If it has already been patched, the callback will be called immediately.\n */\n public callWhenPatched(callback: () => void): void {\n if (this._isPatched) {\n callback();\n } else {\n this._callbacks.push(callback);\n }\n }\n\n /**\n * Patches module exports to enable Vercel AI telemetry.\n */\n private _patch(moduleExports: PatchedModuleExports): unknown {\n this._isPatched = true;\n\n this._callbacks.forEach(callback => callback());\n this._callbacks = [];\n\n const generatePatch = <T extends (...args: MethodArgs) => unknown>(originalMethod: T): T => {\n return new Proxy(originalMethod, {\n apply: (target, thisArg, args: MethodArgs) => {\n const existingExperimentalTelemetry = args[0].experimental_telemetry || {};\n const isEnabled = existingExperimentalTelemetry.isEnabled;\n\n const client = getClient();\n const integration = client?.getIntegrationByName<VercelAiIntegration>(INTEGRATION_NAME);\n const integrationOptions = integration?.options;\n const shouldRecordInputsAndOutputs = integration ? Boolean(client?.getOptions().sendDefaultPii) : false;\n\n const { recordInputs, recordOutputs } = determineRecordingSettings(\n integrationOptions,\n existingExperimentalTelemetry,\n isEnabled,\n shouldRecordInputsAndOutputs,\n );\n\n args[0].experimental_telemetry = {\n ...existingExperimentalTelemetry,\n isEnabled: isEnabled !== undefined ? isEnabled : true,\n recordInputs,\n recordOutputs,\n };\n\n return handleCallbackErrors(\n () => Reflect.apply(target, thisArg, args),\n error => {\n // This error bubbles up to unhandledrejection handler (if not handled before),\n // where we do not know the active span anymore\n // So to circumvent this, we set the active span on the error object\n // which is picked up by the unhandledrejection handler\n if (error && typeof error === 'object') {\n addNonEnumerableProperty(error, '_sentry_active_span', getActiveSpan());\n }\n },\n () => {},\n result => {\n checkResultForToolErrors(result);\n },\n );\n },\n });\n };\n\n // Is this an ESM module?\n // https://tc39.es/ecma262/#sec-module-namespace-objects\n if (Object.prototype.toString.call(moduleExports) === '[object Module]') {\n // In ESM we take the usual route and just replace the exports we want to instrument\n for (const method of INSTRUMENTED_METHODS) {\n moduleExports[method] = generatePatch(moduleExports[method]);\n }\n\n return moduleExports;\n } else {\n // In CJS we can't replace the exports in the original module because they\n // don't have setters, so we create a new object with the same properties\n const patchedModuleExports = INSTRUMENTED_METHODS.reduce((acc, curr) => {\n acc[curr] = generatePatch(moduleExports[curr]);\n return acc;\n }, {} as PatchedModuleExports);\n\n return { ...moduleExports, ...patchedModuleExports };\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.js","sources":["../../../../../src/integrations/tracing/vercelai/instrumentation.ts"],"sourcesContent":["import type { InstrumentationConfig, InstrumentationModuleDefinition } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport type { Span } from '@sentry/core';\nimport {\n _INTERNAL_cleanupToolCallSpan,\n _INTERNAL_getSpanForToolCallId,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n getClient,\n handleCallbackErrors,\n SDK_VERSION,\n withScope,\n} from '@sentry/core';\nimport { INTEGRATION_NAME } from './constants';\nimport type { TelemetrySettings, VercelAiIntegration } from './types';\n\n// List of patched methods\n// From: https://sdk.vercel.ai/docs/ai-sdk-core/telemetry#collected-data\nconst INSTRUMENTED_METHODS = [\n 'generateText',\n 'streamText',\n 'generateObject',\n 'streamObject',\n 'embed',\n 'embedMany',\n] as const;\n\ninterface MethodFirstArg extends Record<string, unknown> {\n experimental_telemetry?: TelemetrySettings;\n}\n\ntype MethodArgs = [MethodFirstArg, ...unknown[]];\n\ntype PatchedModuleExports = Record<(typeof INSTRUMENTED_METHODS)[number], (...args: MethodArgs) => unknown> &\n Record<string, unknown>;\n\ninterface RecordingOptions {\n recordInputs?: boolean;\n recordOutputs?: boolean;\n}\n\ninterface ToolError {\n type: 'tool-error' | 'tool-result' | 'tool-call';\n toolCallId: string;\n toolName: string;\n input?: {\n [key: string]: unknown;\n };\n error: Error;\n dynamic?: boolean;\n}\n\nfunction isToolError(obj: unknown): obj is ToolError {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n const candidate = obj as Record<string, unknown>;\n return (\n 'type' in candidate &&\n 'error' in candidate &&\n 'toolName' in candidate &&\n 'toolCallId' in candidate &&\n candidate.type === 'tool-error' &&\n candidate.error instanceof Error\n );\n}\n\n/**\n * Check for tool errors in the result and capture them\n * Tool errors are not rejected in Vercel V5, it is added as metadata to the result content\n */\nfunction checkResultForToolErrors(result: unknown): void {\n if (typeof result !== 'object' || result === null || !('content' in result)) {\n return;\n }\n\n const resultObj = result as { content: Array<object> };\n if (!Array.isArray(resultObj.content)) {\n return;\n }\n\n for (const item of resultObj.content) {\n if (isToolError(item)) {\n // Try to get the span associated with this tool call ID\n const associatedSpan = _INTERNAL_getSpanForToolCallId(item.toolCallId) as Span;\n\n if (associatedSpan) {\n // We have the span, so link the error using span and trace IDs from the span\n const spanContext = associatedSpan.spanContext();\n\n withScope(scope => {\n // Set the span and trace context for proper linking\n scope.setContext('trace', {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n });\n\n scope.setTag('vercel.ai.tool.name', item.toolName);\n scope.setTag('vercel.ai.tool.callId', item.toolCallId);\n\n scope.setLevel('error');\n\n captureException(item.error, {\n mechanism: {\n type: 'auto.vercelai.otel',\n handled: false,\n },\n });\n });\n\n // Clean up the span mapping since we've processed this tool error\n // We won't get multiple { type: 'tool-error' } parts for the same toolCallId.\n _INTERNAL_cleanupToolCallSpan(item.toolCallId);\n } else {\n // Fallback: capture without span linking\n withScope(scope => {\n scope.setTag('vercel.ai.tool.name', item.toolName);\n scope.setTag('vercel.ai.tool.callId', item.toolCallId);\n scope.setLevel('error');\n\n captureException(item.error, {\n mechanism: {\n type: 'auto.vercelai.otel',\n handled: false,\n },\n });\n });\n }\n }\n }\n}\n\n/**\n * Determines whether to record inputs and outputs for Vercel AI telemetry based on the configuration hierarchy.\n *\n * The order of precedence is:\n * 1. The vercel ai integration options\n * 2. The experimental_telemetry options in the vercel ai method calls\n * 3. When telemetry is explicitly enabled (isEnabled: true), default to recording\n * 4. Otherwise, use the sendDefaultPii option from client options\n */\nexport function determineRecordingSettings(\n integrationRecordingOptions: RecordingOptions | undefined,\n methodTelemetryOptions: RecordingOptions,\n telemetryExplicitlyEnabled: boolean | undefined,\n defaultRecordingEnabled: boolean,\n): { recordInputs: boolean; recordOutputs: boolean } {\n const recordInputs =\n integrationRecordingOptions?.recordInputs !== undefined\n ? integrationRecordingOptions.recordInputs\n : methodTelemetryOptions.recordInputs !== undefined\n ? methodTelemetryOptions.recordInputs\n : telemetryExplicitlyEnabled === true\n ? true // When telemetry is explicitly enabled, default to recording inputs\n : defaultRecordingEnabled;\n\n const recordOutputs =\n integrationRecordingOptions?.recordOutputs !== undefined\n ? integrationRecordingOptions.recordOutputs\n : methodTelemetryOptions.recordOutputs !== undefined\n ? methodTelemetryOptions.recordOutputs\n : telemetryExplicitlyEnabled === true\n ? true // When telemetry is explicitly enabled, default to recording inputs\n : defaultRecordingEnabled;\n\n return { recordInputs, recordOutputs };\n}\n\n/**\n * This detects is added by the Sentry Vercel AI Integration to detect if the integration should\n * be enabled.\n *\n * It also patches the `ai` module to enable Vercel AI telemetry automatically for all methods.\n */\nexport class SentryVercelAiInstrumentation extends InstrumentationBase {\n private _isPatched = false;\n private _callbacks: (() => void)[] = [];\n\n public constructor(config: InstrumentationConfig = {}) {\n super('@sentry/instrumentation-vercel-ai', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the modules to be patched.\n */\n public init(): InstrumentationModuleDefinition {\n const module = new InstrumentationNodeModuleDefinition('ai', ['>=3.0.0 <6'], this._patch.bind(this));\n return module;\n }\n\n /**\n * Call the provided callback when the module is patched.\n * If it has already been patched, the callback will be called immediately.\n */\n public callWhenPatched(callback: () => void): void {\n if (this._isPatched) {\n callback();\n } else {\n this._callbacks.push(callback);\n }\n }\n\n /**\n * Patches module exports to enable Vercel AI telemetry.\n */\n private _patch(moduleExports: PatchedModuleExports): unknown {\n this._isPatched = true;\n\n this._callbacks.forEach(callback => callback());\n this._callbacks = [];\n\n const generatePatch = <T extends (...args: MethodArgs) => unknown>(originalMethod: T): T => {\n return new Proxy(originalMethod, {\n apply: (target, thisArg, args: MethodArgs) => {\n const existingExperimentalTelemetry = args[0].experimental_telemetry || {};\n const isEnabled = existingExperimentalTelemetry.isEnabled;\n\n const client = getClient();\n const integration = client?.getIntegrationByName<VercelAiIntegration>(INTEGRATION_NAME);\n const integrationOptions = integration?.options;\n const shouldRecordInputsAndOutputs = integration ? Boolean(client?.getOptions().sendDefaultPii) : false;\n\n const { recordInputs, recordOutputs } = determineRecordingSettings(\n integrationOptions,\n existingExperimentalTelemetry,\n isEnabled,\n shouldRecordInputsAndOutputs,\n );\n\n args[0].experimental_telemetry = {\n ...existingExperimentalTelemetry,\n isEnabled: isEnabled !== undefined ? isEnabled : true,\n recordInputs,\n recordOutputs,\n };\n\n return handleCallbackErrors(\n () => Reflect.apply(target, thisArg, args),\n error => {\n // This error bubbles up to unhandledrejection handler (if not handled before),\n // where we do not know the active span anymore\n // So to circumvent this, we set the active span on the error object\n // which is picked up by the unhandledrejection handler\n if (error && typeof error === 'object') {\n addNonEnumerableProperty(error, '_sentry_active_span', getActiveSpan());\n }\n },\n () => {},\n result => {\n checkResultForToolErrors(result);\n },\n );\n },\n });\n };\n\n // Is this an ESM module?\n // https://tc39.es/ecma262/#sec-module-namespace-objects\n if (Object.prototype.toString.call(moduleExports) === '[object Module]') {\n // In ESM we take the usual route and just replace the exports we want to instrument\n for (const method of INSTRUMENTED_METHODS) {\n moduleExports[method] = generatePatch(moduleExports[method]);\n }\n\n return moduleExports;\n } else {\n // In CJS we can't replace the exports in the original module because they\n // don't have setters, so we create a new object with the same properties\n const patchedModuleExports = INSTRUMENTED_METHODS.reduce((acc, curr) => {\n acc[curr] = generatePatch(moduleExports[curr]);\n return acc;\n }, {} as PatchedModuleExports);\n\n return { ...moduleExports, ...patchedModuleExports };\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.23.0","sideEffects":false}
1
+ {"type":"module","version":"10.25.0","sideEffects":false}